use of com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef in project cloudstack by apache.
the class LibvirtStorageAdaptor method getStoragePool.
@Override
public KVMStoragePool getStoragePool(String uuid, boolean refreshInfo) {
s_logger.info("Trying to fetch storage pool " + uuid + " from libvirt");
StoragePool storage = null;
try {
Connect conn = LibvirtConnection.getConnection();
storage = conn.storagePoolLookupByUUIDString(uuid);
if (storage.getInfo().state != StoragePoolState.VIR_STORAGE_POOL_RUNNING) {
s_logger.warn("Storage pool " + uuid + " is not in running state. Attempting to start it.");
storage.create(0);
}
LibvirtStoragePoolDef spd = getStoragePoolDef(conn, storage);
if (spd == null) {
throw new CloudRuntimeException("Unable to parse the storage pool definition for storage pool " + uuid);
}
StoragePoolType type = null;
if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.NETFS) {
type = StoragePoolType.NetworkFilesystem;
} else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.DIR) {
type = StoragePoolType.Filesystem;
} else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.RBD) {
type = StoragePoolType.RBD;
} else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.LOGICAL) {
type = StoragePoolType.CLVM;
} else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.GLUSTERFS) {
type = StoragePoolType.Gluster;
}
LibvirtStoragePool pool = new LibvirtStoragePool(uuid, storage.getName(), type, this, storage);
if (pool.getType() != StoragePoolType.RBD)
pool.setLocalPath(spd.getTargetPath());
else
pool.setLocalPath("");
if (pool.getType() == StoragePoolType.RBD || pool.getType() == StoragePoolType.Gluster) {
pool.setSourceHost(spd.getSourceHost());
pool.setSourcePort(spd.getSourcePort());
pool.setSourceDir(spd.getSourceDir());
String authUsername = spd.getAuthUserName();
if (authUsername != null) {
Secret secret = conn.secretLookupByUUIDString(spd.getSecretUUID());
String secretValue = new String(Base64.encodeBase64(secret.getByteValue()), Charset.defaultCharset());
pool.setAuthUsername(authUsername);
pool.setAuthSecret(secretValue);
}
}
/**
* On large (RBD) storage pools it can take up to a couple of minutes
* for libvirt to refresh the pool.
*
* Refreshing a storage pool means that libvirt will have to iterate the whole pool
* and fetch information of each volume in there
*
* It is not always required to refresh a pool. So we can control if we want to or not
*
* By default only the getStorageStats call in the LibvirtComputingResource will ask to
* refresh the pool
*/
if (refreshInfo) {
s_logger.info("Asking libvirt to refresh storage pool " + uuid);
pool.refresh();
}
pool.setCapacity(storage.getInfo().capacity);
pool.setUsed(storage.getInfo().allocation);
pool.setAvailable(storage.getInfo().available);
s_logger.debug("Succesfully refreshed pool " + uuid + " Capacity: " + storage.getInfo().capacity + " Used: " + storage.getInfo().allocation + " Available: " + storage.getInfo().available);
return pool;
} catch (LibvirtException e) {
s_logger.debug("Could not find storage pool " + uuid + " in libvirt");
throw new CloudRuntimeException(e.toString(), e);
}
}
use of com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef in project cloudstack by apache.
the class LibvirtStorageAdaptor method createRBDStoragePool.
private StoragePool createRBDStoragePool(Connect conn, String uuid, String host, int port, String userInfo, String path) {
LibvirtStoragePoolDef spd;
StoragePool sp = null;
Secret s = null;
String[] userInfoTemp = userInfo.split(":");
if (userInfoTemp.length == 2) {
LibvirtSecretDef sd = new LibvirtSecretDef(Usage.CEPH, uuid);
sd.setCephName(userInfoTemp[0] + "@" + host + ":" + port + "/" + path);
try {
s_logger.debug(sd.toString());
s = conn.secretDefineXML(sd.toString());
s.setValue(Base64.decodeBase64(userInfoTemp[1]));
} catch (LibvirtException e) {
s_logger.error("Failed to define the libvirt secret: " + e.toString());
if (s != null) {
try {
s.undefine();
s.free();
} catch (LibvirtException l) {
s_logger.error("Failed to undefine the libvirt secret: " + l.toString());
}
}
return null;
}
spd = new LibvirtStoragePoolDef(PoolType.RBD, uuid, uuid, host, port, path, userInfoTemp[0], AuthenticationType.CEPH, uuid);
} else {
spd = new LibvirtStoragePoolDef(PoolType.RBD, uuid, uuid, host, port, path, "");
}
try {
s_logger.debug(spd.toString());
sp = conn.storagePoolCreateXML(spd.toString(), 0);
return sp;
} catch (LibvirtException e) {
s_logger.error("Failed to create RBD storage pool: " + e.toString());
if (sp != null) {
try {
if (sp.isPersistent() == 1) {
sp.destroy();
sp.undefine();
} else {
sp.destroy();
}
sp.free();
} catch (LibvirtException l) {
s_logger.error("Failed to undefine RBD storage pool: " + l.toString());
}
}
if (s != null) {
try {
s_logger.error("Failed to create the RBD storage pool, cleaning up the libvirt secret");
s.undefine();
s.free();
} catch (LibvirtException se) {
s_logger.error("Failed to remove the libvirt secret: " + se.toString());
}
}
return null;
}
}
use of com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef in project cloudstack by apache.
the class LibvirtStorageAdaptor method createStoragePool.
@Override
public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type) {
s_logger.info("Attempting to create storage pool " + name + " (" + type.toString() + ") in libvirt");
StoragePool sp = null;
Connect conn = null;
try {
conn = LibvirtConnection.getConnection();
} catch (LibvirtException e) {
throw new CloudRuntimeException(e.toString());
}
try {
sp = conn.storagePoolLookupByUUIDString(name);
if (sp != null && sp.isActive() == 0) {
sp.undefine();
sp = null;
s_logger.info("Found existing defined storage pool " + name + ". It wasn't running, so we undefined it.");
}
if (sp != null) {
s_logger.info("Found existing defined storage pool " + name + ", using it.");
}
} catch (LibvirtException e) {
sp = null;
s_logger.warn("Storage pool " + name + " was not found running in libvirt. Need to create it.");
}
// existing paths
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
if (sp == null) {
// see if any existing pool by another name is using our storage path.
// if anyone is, undefine the pool so we can define it as requested.
// This should be safe since a pool in use can't be removed, and no
// volumes are affected by unregistering the pool with libvirt.
s_logger.info("Didn't find an existing storage pool " + name + " by UUID, checking for pools with duplicate paths");
try {
String[] poolnames = conn.listStoragePools();
for (String poolname : poolnames) {
s_logger.debug("Checking path of existing pool " + poolname + " against pool we want to create");
StoragePool p = conn.storagePoolLookupByName(poolname);
LibvirtStoragePoolDef pdef = getStoragePoolDef(conn, p);
String targetPath = pdef.getTargetPath();
if (targetPath != null && targetPath.equals(path)) {
s_logger.debug("Storage pool utilizing path '" + path + "' already exists as pool " + poolname + ", undefining so we can re-define with correct name " + name);
if (p.isPersistent() == 1) {
p.destroy();
p.undefine();
} else {
p.destroy();
}
}
}
} catch (LibvirtException e) {
s_logger.error("Failure in attempting to see if an existing storage pool might be using the path of the pool to be created:" + e);
}
s_logger.debug("Attempting to create storage pool " + name);
if (type == StoragePoolType.NetworkFilesystem) {
try {
sp = createNetfsStoragePool(PoolType.NETFS, conn, name, host, path);
} catch (LibvirtException e) {
s_logger.error("Failed to create netfs mount: " + host + ":" + path, e);
s_logger.error(e.getStackTrace());
throw new CloudRuntimeException(e.toString());
}
} else if (type == StoragePoolType.Gluster) {
try {
sp = createNetfsStoragePool(PoolType.GLUSTERFS, conn, name, host, path);
} catch (LibvirtException e) {
s_logger.error("Failed to create glusterfs mount: " + host + ":" + path, e);
s_logger.error(e.getStackTrace());
throw new CloudRuntimeException(e.toString());
}
} else if (type == StoragePoolType.SharedMountPoint || type == StoragePoolType.Filesystem) {
sp = createSharedStoragePool(conn, name, host, path);
} else if (type == StoragePoolType.RBD) {
sp = createRBDStoragePool(conn, name, host, port, userInfo, path);
} else if (type == StoragePoolType.CLVM) {
sp = createCLVMStoragePool(conn, name, host, path);
}
}
if (sp == null) {
throw new CloudRuntimeException("Failed to create storage pool: " + name);
}
try {
if (sp.isActive() == 0) {
s_logger.debug("Attempting to activate pool " + name);
sp.create(0);
}
return getStoragePool(name);
} catch (LibvirtException e) {
String error = e.toString();
if (error.contains("Storage source conflict")) {
throw new CloudRuntimeException("A pool matching this location already exists in libvirt, " + " but has a different UUID/Name. Cannot create new pool without first " + " removing it. Check for inactive pools via 'virsh pool-list --all'. " + error);
} else {
throw new CloudRuntimeException(error);
}
}
}
use of com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef in project cloudstack by apache.
the class LibvirtStorageAdaptor method createSharedStoragePool.
private StoragePool createSharedStoragePool(Connect conn, String uuid, String host, String path) {
String mountPoint = path;
if (!_storageLayer.exists(mountPoint)) {
s_logger.error(mountPoint + " does not exists. Check local.storage.path in agent.properties.");
return null;
}
LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(PoolType.DIR, uuid, uuid, host, path, path);
StoragePool sp = null;
try {
s_logger.debug(spd.toString());
sp = conn.storagePoolCreateXML(spd.toString(), 0);
return sp;
} catch (LibvirtException e) {
s_logger.error(e.toString());
if (sp != null) {
try {
if (sp.isPersistent() == 1) {
sp.destroy();
sp.undefine();
} else {
sp.destroy();
}
sp.free();
} catch (LibvirtException l) {
s_logger.debug("Failed to define shared mount point storage pool with: " + l.toString());
}
}
return null;
}
}
use of com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef in project cloudstack by apache.
the class LibvirtStorageAdaptor method createNetfsStoragePool.
private StoragePool createNetfsStoragePool(PoolType fsType, Connect conn, String uuid, String host, String path) throws LibvirtException {
String targetPath = _mountPoint + File.separator + uuid;
LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(fsType, uuid, uuid, host, path, targetPath);
_storageLayer.mkdir(targetPath);
StoragePool sp = null;
try {
s_logger.debug(spd.toString());
sp = conn.storagePoolCreateXML(spd.toString(), 0);
return sp;
} catch (LibvirtException e) {
s_logger.error(e.toString());
// if error is that pool is mounted, try to handle it
if (e.toString().contains("already mounted")) {
s_logger.error("Attempting to unmount old mount libvirt is unaware of at " + targetPath);
String result = Script.runSimpleBashScript("umount -l " + targetPath);
if (result == null) {
s_logger.error("Succeeded in unmounting " + targetPath);
try {
sp = conn.storagePoolCreateXML(spd.toString(), 0);
s_logger.error("Succeeded in redefining storage");
return sp;
} catch (LibvirtException l) {
s_logger.error("Target was already mounted, unmounted it but failed to redefine storage:" + l);
}
} else {
s_logger.error("Failed in unmounting and redefining storage");
}
} else {
s_logger.error("Internal error occurred when attempting to mount: specified path may be invalid");
throw e;
}
if (sp != null) {
try {
if (sp.isPersistent() == 1) {
sp.destroy();
sp.undefine();
} else {
sp.destroy();
}
sp.free();
} catch (LibvirtException l) {
s_logger.debug("Failed to undefine " + fsType.toString() + " storage pool with: " + l.toString());
}
}
return null;
}
}
Aggregations