Summary: Allow for custom storage adaptors based on pool type in KVM

Detail: Instead of using LibvirtStorageAdaptor for everything, you can create
your own storage adaptor and use it. We select storage adaptor based on storage
pool type, thus we needed to adjust LibvirtComputingResource to pass pool type
to everything in KVMStoragePoolManager. This in turn required that we pass the
info necessary to LibvirtComputingResource as well, so a few agent Commands were
modified.

Note this patch in and of itself shouldn't change any existing behavior, just
allow for new storage adaptors to be selected based on storage pool type.

Reviewed-by: Edison Su
Signed-off-by: Marcus Sorensen <marcus@betterservers.com> 1355769696 -0700
This commit is contained in:
Marcus Sorensen 2012-12-17 11:41:36 -07:00
parent 0be6e2e02b
commit 6ed1989133
20 changed files with 303 additions and 150 deletions

View File

@ -50,8 +50,7 @@ public class BackupSnapshotCommand extends SnapshotCommand {
* @param isFirstSnapshotOfRootVolume true if this is the first snapshot of a root volume. Set the parent of the backup to null.
* @param isVolumeInactive True if the volume belongs to a VM that is not running or is detached.
*/
public BackupSnapshotCommand(String primaryStoragePoolNameLabel,
String secondaryStoragePoolURL,
public BackupSnapshotCommand(String secondaryStoragePoolURL,
Long dcId,
Long accountId,
Long volumeId,
@ -66,17 +65,16 @@ public class BackupSnapshotCommand extends SnapshotCommand {
String vmName,
int wait)
{
super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, snapshotUuid, snapshotName, dcId, accountId, volumeId);
super(pool, secondaryStoragePoolURL, snapshotUuid, snapshotName, dcId, accountId, volumeId);
this.snapshotId = snapshotId;
this.prevSnapshotUuid = prevSnapshotUuid;
this.prevBackupUuid = prevBackupUuid;
this.isVolumeInactive = isVolumeInactive;
this.vmName = vmName;
this.pool = new StorageFilerTO(pool);
setVolumePath(volumePath);
setWait(wait);
}
public String getPrevSnapshotUuid() {
return prevSnapshotUuid;
}
@ -113,7 +111,4 @@ public class BackupSnapshotCommand extends SnapshotCommand {
return snapshotId;
}
public StorageFilerTO getPool() {
return pool;
}
}
}

View File

@ -16,6 +16,8 @@
// under the License.
package com.cloud.agent.api;
import com.cloud.storage.StoragePool;
/**
* This currently assumes that both primary and secondary storage are mounted on the XenServer.
*/
@ -40,7 +42,8 @@ public class CreatePrivateTemplateFromSnapshotCommand extends SnapshotCommand {
* It may not be the UUID of the base copy of the snapshot, if no data was written since last snapshot.
* @param origTemplateInstallPath The install path of the original template VHD on the secondary
*/
public CreatePrivateTemplateFromSnapshotCommand(String primaryStoragePoolNameLabel,
public CreatePrivateTemplateFromSnapshotCommand(StoragePool pool,
String secondaryStoragePoolURL,
Long dcId,
Long accountId,
@ -52,7 +55,7 @@ public class CreatePrivateTemplateFromSnapshotCommand extends SnapshotCommand {
String templateName,
int wait)
{
super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, backedUpSnapshotUuid, backedUpSnapshotName, dcId, accountId, volumeId);
super(pool, secondaryStoragePoolURL, backedUpSnapshotUuid, backedUpSnapshotName, dcId, accountId, volumeId);
this.origTemplateInstallPath = origTemplateInstallPath;
this.newTemplateId = newTemplateId;
this.templateName = templateName;
@ -76,4 +79,4 @@ public class CreatePrivateTemplateFromSnapshotCommand extends SnapshotCommand {
public String getTemplateName() {
return templateName;
}
}
}

View File

@ -16,6 +16,9 @@
// under the License.
package com.cloud.agent.api;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.storage.StoragePool;
public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand {
private String _vmName;
private String _volumePath;
@ -23,13 +26,14 @@ public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand {
private String _uniqueName;
private long _templateId;
private long _accountId;
StorageFilerTO _primaryPool;
// For XenServer
private String _secondaryStorageUrl;
public CreatePrivateTemplateFromVolumeCommand() {
}
public CreatePrivateTemplateFromVolumeCommand(String StoragePoolUUID, String secondaryStorageUrl, long templateId, long accountId, String userSpecifiedName, String uniqueName, String volumePath, String vmName, int wait) {
public CreatePrivateTemplateFromVolumeCommand(StoragePool pool, String secondaryStorageUrl, long templateId, long accountId, String userSpecifiedName, String uniqueName, String volumePath, String vmName, int wait) {
_secondaryStorageUrl = secondaryStorageUrl;
_templateId = templateId;
_accountId = accountId;
@ -37,7 +41,8 @@ public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand {
_uniqueName = uniqueName;
_volumePath = volumePath;
_vmName = vmName;
primaryStoragePoolNameLabel = StoragePoolUUID;
primaryStoragePoolNameLabel = pool.getUuid();
_primaryPool = new StorageFilerTO(pool);
setWait(wait);
}
@ -46,6 +51,10 @@ public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand {
return false;
}
public StorageFilerTO getPool() {
return _primaryPool;
}
public String getSecondaryStorageUrl() {
return _secondaryStorageUrl;
}

View File

@ -16,6 +16,8 @@
// under the License.
package com.cloud.agent.api;
import com.cloud.storage.StoragePool;
/**
* This currently assumes that both primary and secondary storage are mounted on the XenServer.
*/
@ -39,7 +41,8 @@ public class CreateVolumeFromSnapshotCommand extends SnapshotCommand {
* It may not be the UUID of the base copy of the snapshot, if no data was written since last snapshot.
* @param templatePath The install path of the template VHD on the secondary, if this a root volume
*/
public CreateVolumeFromSnapshotCommand(String primaryStoragePoolNameLabel,
public CreateVolumeFromSnapshotCommand(StoragePool pool,
String secondaryStoragePoolURL,
Long dcId,
Long accountId,
@ -48,7 +51,7 @@ public class CreateVolumeFromSnapshotCommand extends SnapshotCommand {
String backedUpSnapshotName,
int wait)
{
super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, backedUpSnapshotUuid, backedUpSnapshotName, dcId, accountId, volumeId);
super(pool, secondaryStoragePoolURL, backedUpSnapshotUuid, backedUpSnapshotName, dcId, accountId, volumeId);
setWait(wait);
}
}
}

View File

@ -33,7 +33,7 @@ public class DownloadSnapshotFromS3Command extends SnapshotCommand {
String secondaryStorageUrl, Long dcId, Long accountId,
Long volumeId, String backupUuid, int wait) {
super("", secondaryStorageUrl, backupUuid, "", dcId, accountId,
super(null, secondaryStorageUrl, backupUuid, "", dcId, accountId,
volumeId);
this.s3 = s3;

View File

@ -16,12 +16,16 @@
// under the License.
package com.cloud.agent.api;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.storage.StoragePool;
/**
* This currently assumes that both primary and secondary storage are mounted on
* the XenServer.
*/
public class SnapshotCommand extends Command {
protected String primaryStoragePoolNameLabel;
StorageFilerTO primaryPool;
private String snapshotUuid;
private String snapshotName;
private String secondaryStorageUrl;
@ -46,10 +50,11 @@ public class SnapshotCommand extends Command {
* is the value of that field If you have better ideas on how to
* get it, you are welcome.
*/
public SnapshotCommand(String primaryStoragePoolNameLabel,
public SnapshotCommand(StoragePool pool,
String secondaryStorageUrl, String snapshotUuid,
String snapshotName, Long dcId, Long accountId, Long volumeId) {
this.primaryStoragePoolNameLabel = primaryStoragePoolNameLabel;
this.primaryStoragePoolNameLabel = pool.getUuid();
this.primaryPool = new StorageFilerTO(pool);
this.snapshotUuid = snapshotUuid;
this.secondaryStorageUrl = secondaryStorageUrl;
this.dcId = dcId;
@ -65,6 +70,13 @@ public class SnapshotCommand extends Command {
return primaryStoragePoolNameLabel;
}
/**
* @return the primaryPool
*/
public StorageFilerTO getPool() {
return primaryPool;
}
/**
* @return the snapshotUuid
*/
@ -111,4 +123,4 @@ public class SnapshotCommand extends Command {
return false;
}
}
}

View File

@ -15,6 +15,8 @@
// specific language governing permissions and limitations
// under the License.
package com.cloud.agent.api;
import com.cloud.storage.StoragePool;
public class UpgradeSnapshotCommand extends SnapshotCommand {
private String version;
private Long templateId;
@ -30,7 +32,7 @@ public class UpgradeSnapshotCommand extends SnapshotCommand {
* @param snapshotUuid The UUID of the snapshot which is going to be upgraded
* @param _version version for this snapshot
*/
public UpgradeSnapshotCommand(String primaryStoragePoolNameLabel,
public UpgradeSnapshotCommand(StoragePool pool,
String secondaryStoragePoolURL,
Long dcId,
Long accountId,
@ -42,7 +44,7 @@ public class UpgradeSnapshotCommand extends SnapshotCommand {
String snapshotName,
String version)
{
super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, snapshotUuid, snapshotName, dcId, accountId, volumeId);
super(pool, secondaryStoragePoolURL, snapshotUuid, snapshotName, dcId, accountId, volumeId);
this.version = version;
this.templateId = templateId;
this.tmpltAccountId = tmpltAccountId;

View File

@ -34,7 +34,7 @@ public class downloadSnapshotFromSwiftCommand extends SnapshotCommand {
public downloadSnapshotFromSwiftCommand(SwiftTO swift, String secondaryStorageUrl, Long dcId, Long accountId, Long volumeId, String parent, String BackupUuid, int wait) {
super("", secondaryStorageUrl, BackupUuid, "", dcId, accountId, volumeId);
super(null, secondaryStorageUrl, BackupUuid, "", dcId, accountId, volumeId);
setParent(parent);
setSwift(swift);
setWait(wait);
@ -57,4 +57,4 @@ public class downloadSnapshotFromSwiftCommand extends SnapshotCommand {
this._parent = parent;
}
}
}

View File

@ -17,7 +17,8 @@
package com.cloud.agent.api.storage;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.storage.StoragePool;
/**
*
@ -26,6 +27,7 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand {
String localPath;
String poolUuid;
long poolId;
StorageFilerTO primaryPool;
String secondaryStorageUrl;
String primaryStorageUrl;
@ -33,10 +35,11 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand {
protected PrimaryStorageDownloadCommand() {
}
public PrimaryStorageDownloadCommand(String name, String url, ImageFormat format, long accountId, long poolId, String poolUuid, int wait) {
public PrimaryStorageDownloadCommand(String name, String url, ImageFormat format, long accountId, StoragePool pool, int wait) {
super(name, url, format, accountId);
this.poolId = poolId;
this.poolUuid = poolUuid;
this.poolId = pool.getId();
this.poolUuid = pool.getUuid();
this.primaryPool = new StorageFilerTO(pool);
setWait(wait);
}
@ -47,6 +50,10 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand {
public long getPoolId() {
return poolId;
}
public StorageFilerTO getPool() {
return primaryPool;
}
public void setLocalPath(String path) {
this.localPath = path;

View File

@ -36,7 +36,7 @@ public class BackupSnapshotAnswerTest {
StoragePool pool = Mockito.mock(StoragePool.class);
bsc = new BackupSnapshotCommand("primaryStoragePoolNameLabel",
bsc = new BackupSnapshotCommand(
"secondaryStoragePoolURL", 101L, 102L, 103L, 104L,
"volumePath", pool, "snapshotUuid", "snapshotName",
"prevSnapshotUuid", "prevBackupUuid", false, "vmName", 5);

View File

@ -116,14 +116,14 @@ public class BackupSnapshotCommandTest {
};
BackupSnapshotCommand bsc = new BackupSnapshotCommand(
"primaryStoragePoolNameLabel", "http://secondary.Storage.Url",
"http://secondary.Storage.Url",
101L, 102L, 103L, 104L, "vPath", pool,
"420fa39c-4ef1-a83c-fd93-46dc1ff515ae", "sName",
"9012793e-0657-11e2-bebc-0050568b0057",
"7167e0b2-f5b0-11e1-8414-0050568b0057", false, "vmName", 5);
BackupSnapshotCommand bsc1 = new BackupSnapshotCommand(
"primaryStoragePoolNameLabel", "http://secondary.Storage.Url",
"http://secondary.Storage.Url",
101L, 102L, 103L, 104L, "vPath", pool,
"420fa39c-4ef1-a83c-fd93-46dc1ff515ae", "sName",
"9012793e-0657-11e2-bebc-0050568b0057",
@ -132,7 +132,7 @@ public class BackupSnapshotCommandTest {
@Test
public void testGetPrimaryStoragePoolNameLabel() {
String label = bsc.getPrimaryStoragePoolNameLabel();
assertTrue(label.equals("primaryStoragePoolNameLabel"));
assertTrue(label.equals("bed9f83e-cac3-11e1-ac8a-0050568b007e"));
}
@Test

View File

@ -23,19 +23,109 @@ import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.cloud.agent.api.SnapshotCommand;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolStatus;
public class SnapshotCommandTest {
SnapshotCommand ssc = new SnapshotCommand("primaryStoragePoolNameLabel",
public StoragePool pool = new StoragePool() {
public long getId() {
return 1L;
};
public String getName() {
return "name";
};
public String getUuid() {
return "bed9f83e-cac3-11e1-ac8a-0050568b007e";
};
public StoragePoolType getPoolType() {
return StoragePoolType.Filesystem;
};
public Date getCreated() {
Date date = null;
try {
date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
.parse("01/01/1970 12:12:12");
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
public Date getUpdateTime() {
return new Date();
};
public long getDataCenterId() {
return 0L;
};
public long getCapacityBytes() {
return 0L;
};
public long getAvailableBytes() {
return 0L;
};
public Long getClusterId() {
return 0L;
};
public String getHostAddress() {
return "hostAddress";
};
public String getPath() {
return "path";
};
public String getUserInfo() {
return "userInfo";
};
public boolean isShared() {
return false;
};
public boolean isLocal() {
return false;
};
public StoragePoolStatus getStatus() {
return StoragePoolStatus.Up;
};
public int getPort() {
return 25;
};
public Long getPodId() {
return 0L;
};
};
SnapshotCommand ssc = new SnapshotCommand(pool,
"http://secondary.Storage.Url",
"420fa39c-4ef1-a83c-fd93-46dc1ff515ae", "snapshotName", 101L, 102L,
103L);
SnapshotCommand ssc1;
@Before
public void setUp() {
ssc1 = new SnapshotCommand("primaryStoragePoolNameLabel",
ssc1 = new SnapshotCommand(pool,
"secondaryStorageUrl", "snapshotUuid", "snapshotName", 101L,
102L, 103L);
}
@ -43,7 +133,7 @@ public class SnapshotCommandTest {
@Test
public void testGetPrimaryStoragePoolNameLabel() {
String label = ssc.getPrimaryStoragePoolNameLabel();
assertTrue(label.equals("primaryStoragePoolNameLabel"));
assertTrue(label.equals("bed9f83e-cac3-11e1-ac8a-0050568b007e"));
}
@Test

View File

@ -1104,8 +1104,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements
String secondaryStorageUrl = cmd.getSecondaryStorageURL();
KVMStoragePool secondaryStoragePool = null;
try {
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(pool
.getUuid());
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(
pool.getType(),
pool.getUuid());
String volumeName = UUID.randomUUID().toString();
if (copyToSecondary) {
@ -1114,20 +1115,21 @@ public class LibvirtComputingResource extends ServerResourceBase implements
.getVolumePath());
String volumeDestPath = "/volumes/" + cmd.getVolumeId()
+ File.separator;
secondaryStoragePool = _storagePoolMgr
.getStoragePoolByURI(secondaryStorageUrl);
secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(
secondaryStorageUrl);
secondaryStoragePool.createFolder(volumeDestPath);
secondaryStoragePool.delete();
secondaryStoragePool = _storagePoolMgr
.getStoragePoolByURI(secondaryStorageUrl
+ volumeDestPath);
_storagePoolMgr.copyPhysicalDisk(volume, destVolumeName,
secondaryStoragePool);
secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(
secondaryStorageUrl
+ volumeDestPath);
_storagePoolMgr.copyPhysicalDisk(volume,
destVolumeName,secondaryStoragePool);
return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
} else {
volumePath = "/volumes/" + cmd.getVolumeId() + File.separator;
secondaryStoragePool = _storagePoolMgr
.getStoragePoolByURI(secondaryStorageUrl + volumePath);
secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(
secondaryStorageUrl
+ volumePath);
KVMPhysicalDisk volume = secondaryStoragePool
.getPhysicalDisk(cmd.getVolumePath() + ".qcow2");
_storagePoolMgr.copyPhysicalDisk(volume, volumeName,
@ -1145,7 +1147,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
protected Answer execute(DeleteStoragePoolCommand cmd) {
try {
_storagePoolMgr.deleteStoragePool(cmd.getPool().getUuid());
_storagePoolMgr.deleteStoragePool(cmd.getPool().getType(),
cmd.getPool().getUuid());
return new Answer(cmd);
} catch (CloudRuntimeException e) {
return new Answer(cmd, false, e.toString());
@ -1186,7 +1189,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
KVMPhysicalDisk vol = null;
long disksize;
try {
primaryPool = _storagePoolMgr.getStoragePool(pool.getUuid());
primaryPool = _storagePoolMgr.getStoragePool(pool.getType(),
pool.getUuid());
disksize = dskch.getSize();
if (cmd.getTemplateUrl() != null) {
@ -1268,8 +1272,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements
VolumeTO vol = cmd.getVolume();
try {
KVMStoragePool pool = _storagePoolMgr.getStoragePool(vol
.getPoolUuid());
KVMStoragePool pool = _storagePoolMgr.getStoragePool(
vol.getPoolType(),
vol.getPoolUuid());
pool.deletePhysicalDisk(vol.getPath());
String vmName = cmd.getVmName();
String poolPath = pool.getLocalPath();
@ -1281,7 +1286,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements
File patchVbd = new File(poolPath + File.separator + vmName + "-patchdisk");
if(patchVbd.exists()){
try {
_storagePoolMgr.deleteVbdByPath(patchVbd.getAbsolutePath());
_storagePoolMgr.deleteVbdByPath(vol.getPoolType(),patchVbd.getAbsolutePath());
} catch(CloudRuntimeException e) {
s_logger.warn("unable to destroy patch disk '" + patchVbd.getAbsolutePath() +
"' while removing root disk for " + vmName + " : " + e);
@ -1643,8 +1648,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements
}
}
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd
.getPool().getUuid());
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(
cmd.getPool().getType(),
cmd.getPool().getUuid());
if (primaryPool.getType() == StoragePoolType.RBD) {
s_logger.debug("Snapshots are not supported on RBD volumes");
@ -1721,8 +1727,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
try {
Connect conn = LibvirtConnection.getConnection();
secondaryStoragePool = _storagePoolMgr
.getStoragePoolByURI(secondaryStoragePoolUrl);
secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(
secondaryStoragePoolUrl);
String ssPmountPath = secondaryStoragePool.getLocalPath();
snapshotRelPath = File.separator + "snapshots" + File.separator
@ -1732,8 +1738,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements
snapshotDestPath = ssPmountPath + File.separator + "snapshots"
+ File.separator + dcId + File.separator + accountId
+ File.separator + volumeId;
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd
.getPrimaryStoragePoolNameLabel());
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(
cmd.getPool().getType(),
cmd.getPrimaryStoragePoolNameLabel());
KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(cmd
.getVolumePath());
Script command = new Script(_manageSnapshotPath, _cmdsTimeout,
@ -1760,8 +1767,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements
}
}
KVMStoragePool primaryStorage = _storagePoolMgr.getStoragePool(cmd
.getPool().getUuid());
KVMStoragePool primaryStorage = _storagePoolMgr.getStoragePool(
cmd.getPool().getType(),
cmd.getPool().getUuid());
if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING
&& !primaryStorage.isExternalSnapshot()) {
String vmUuid = vm.getUUIDString();
@ -1845,7 +1853,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements
KVMStoragePool secondaryStoragePool = null;
try {
secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd
.getSecondaryStorageUrl());
.getSecondaryStorageUrl());
String ssPmountPath = secondaryStoragePool.getLocalPath();
String snapshotDestPath = ssPmountPath + File.separator
@ -1875,15 +1883,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements
String snapshotPath = cmd.getSnapshotUuid();
int index = snapshotPath.lastIndexOf("/");
snapshotPath = snapshotPath.substring(0, index);
KVMStoragePool secondaryPool = _storagePoolMgr
.getStoragePoolByURI(cmd.getSecondaryStorageUrl()
+ snapshotPath);
KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(
cmd.getSecondaryStorageUrl()
+ snapshotPath);
KVMPhysicalDisk snapshot = secondaryPool.getPhysicalDisk(cmd
.getSnapshotName());
String primaryUuid = cmd.getPrimaryStoragePoolNameLabel();
KVMStoragePool primaryPool = _storagePoolMgr
.getStoragePool(primaryUuid);
.getStoragePool(cmd.getPool().getType(),
primaryUuid);
String volUuid = UUID.randomUUID().toString();
KVMPhysicalDisk disk = _storagePoolMgr.copyPhysicalDisk(snapshot,
volUuid, primaryPool);
@ -1918,8 +1927,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
KVMPhysicalDisk snapshot = snapshotPool.getPhysicalDisk(cmd
.getSnapshotName());
secondaryPool = _storagePoolMgr.getStoragePoolByURI(cmd
.getSecondaryStorageUrl());
secondaryPool = _storagePoolMgr.getStoragePoolByURI(
cmd.getSecondaryStorageUrl());
String templatePath = secondaryPool.getLocalPath() + File.separator
+ templateInstallFolder;
@ -1968,8 +1977,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements
protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
try {
KVMStoragePool sp = _storagePoolMgr.getStoragePool(cmd
.getStorageId());
KVMStoragePool sp = _storagePoolMgr.getStoragePool(
cmd.getPooltype(),
cmd.getStorageId());
return new GetStorageStatsAnswer(cmd, sp.getCapacity(),
sp.getUsed());
} catch (CloudRuntimeException e) {
@ -1988,11 +1998,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements
+ cmd.getTemplateId() + File.separator;
String templateInstallFolder = "/template/tmpl/" + templateFolder;
secondaryStorage = _storagePoolMgr
.getStoragePoolByURI(secondaryStorageURL);
secondaryStorage = _storagePoolMgr.getStoragePoolByURI(
secondaryStorageURL);
KVMStoragePool primary = _storagePoolMgr.getStoragePool(cmd
.getPrimaryStoragePoolNameLabel());
KVMStoragePool primary = _storagePoolMgr.getStoragePool(
cmd.getPool().getType(),
cmd.getPrimaryStoragePoolNameLabel());
KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath());
String tmpltPath = secondaryStorage.getLocalPath() + File.separator
+ templateInstallFolder;
@ -2114,8 +2125,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements
}
/* Copy volume to primary storage */
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd
.getPoolUuid());
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(
cmd.getPool().getType(),
cmd.getPoolUuid());
KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(
tmplVol, UUID.randomUUID().toString(), primaryPool);
@ -2136,9 +2148,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements
}
protected Answer execute(ModifyStoragePoolCommand cmd) {
String poolType = cmd.getPool().getType().toString();
KVMStoragePool storagepool = _storagePoolMgr.createStoragePool(cmd
.getPool().getUuid(), cmd.getPool().getHost(), cmd.getPool().getPort(),
cmd.getPool().getPath(), cmd.getPool().getUserInfo(), cmd.getPool().getType());
.getPool().getUuid(), cmd.getPool().getHost(),
cmd.getPool().getPort(), cmd.getPool().getPath(),
cmd.getPool().getUserInfo(), cmd.getPool().getType());
if (storagepool == null) {
return new Answer(cmd, false, " Failed to create storage pool");
}
@ -2276,8 +2290,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements
private AttachVolumeAnswer execute(AttachVolumeCommand cmd) {
try {
Connect conn = LibvirtConnection.getConnection();
KVMStoragePool primary = _storagePoolMgr.getStoragePool(cmd
.getPoolUuid());
KVMStoragePool primary = _storagePoolMgr.getStoragePool(
cmd.getPooltype(),
cmd.getPoolUuid());
KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath());
attachOrDetachDisk(conn, cmd.getAttach(), cmd.getVmName(), disk,
cmd.getDeviceId().intValue());
@ -2924,8 +2939,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
int index = isoPath.lastIndexOf("/");
String path = isoPath.substring(0, index);
String name = isoPath.substring(index + 1);
KVMStoragePool secondaryPool = _storagePoolMgr
.getStoragePoolByURI(path);
KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(
path);
KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
return isoVol.getPath();
} else {
@ -2952,11 +2967,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements
int index = volPath.lastIndexOf("/");
String volDir = volPath.substring(0, index);
String volName = volPath.substring(index + 1);
KVMStoragePool secondaryStorage = _storagePoolMgr
.getStoragePoolByURI(volDir);
KVMStoragePool secondaryStorage = _storagePoolMgr.
getStoragePoolByURI(volDir);
physicalDisk = secondaryStorage.getPhysicalDisk(volName);
} else if (volume.getType() != Volume.Type.ISO) {
pool = _storagePoolMgr.getStoragePool(volume.getPoolUuid());
pool = _storagePoolMgr.getStoragePool(
volume.getPoolType(),
volume.getPoolUuid());
physicalDisk = pool.getPhysicalDisk(volume.getPath());
}
@ -3034,7 +3051,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements
DiskDef rootDisk = disks.get(0);
VolumeTO rootVol = getVolume(vmSpec, Volume.Type.ROOT);
String patchName = vmName + "-patchdisk";
KVMStoragePool pool = _storagePoolMgr.getStoragePool(rootVol.getPoolUuid());
KVMStoragePool pool = _storagePoolMgr.getStoragePool(
rootVol.getPoolType(),
rootVol.getPoolUuid());
String patchDiskPath = pool.getLocalPath() + "/" + patchName;
List<KVMPhysicalDisk> phyDisks = pool.listPhysicalDisks();
@ -3130,7 +3149,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
}
try {
KVMStoragePool pool = _storagePoolMgr.getStoragePool(poolUuid);
//we use libvirt since we passed a libvirt connection to cleanupDisk
KVMStoragePool pool = _storagePoolMgr.getStoragePool(null, poolUuid);
if (pool != null) {
pool.delete();
}
@ -3148,8 +3168,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
int index = isoPath.lastIndexOf("/");
String path = isoPath.substring(0, index);
String name = isoPath.substring(index + 1);
KVMStoragePool secondaryPool = _storagePoolMgr
.getStoragePoolByURI(path);
KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(
path);
KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
isoPath = isoVol.getPath();
@ -4416,4 +4436,5 @@ public class LibvirtComputingResource extends ServerResourceBase implements
return new Answer(cmd, success, "");
}
}

View File

@ -16,8 +16,12 @@
// under the License.
package com.cloud.hypervisor.kvm.storage;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.UUID;
import com.cloud.hypervisor.kvm.resource.KVMHABase;
import com.cloud.hypervisor.kvm.resource.KVMHABase.PoolType;
@ -25,11 +29,22 @@ import com.cloud.hypervisor.kvm.resource.KVMHAMonitor;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk.PhysicalDiskFormat;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StorageLayer;
import com.cloud.utils.exception.CloudRuntimeException;
public class KVMStoragePoolManager {
private StorageAdaptor _storageAdaptor;
private KVMHAMonitor _haMonitor;
private final Map<String, Object> _storagePools = new ConcurrentHashMap<String, Object>();
private final Map<String, StorageAdaptor> _storageMapper = new HashMap<String, StorageAdaptor>();
private StorageAdaptor getStorageAdaptor(StoragePoolType type) {
StorageAdaptor adaptor = _storageMapper.get(type.toString());
if (adaptor == null) {
// LibvirtStorageAdaptor is selected by default
adaptor = _storageMapper.get("libvirt");
}
return adaptor;
}
private void addStoragePool(String uuid) {
synchronized (_storagePools) {
@ -42,20 +57,49 @@ public class KVMStoragePoolManager {
public KVMStoragePoolManager(StorageLayer storagelayer, KVMHAMonitor monitor) {
this._storageAdaptor = new LibvirtStorageAdaptor(storagelayer);
this._haMonitor = monitor;
this._storageMapper.put("libvirt", new LibvirtStorageAdaptor(storagelayer));
// add other storage adaptors here
// this._storageMapper.put("newadaptor", new NewStorageAdaptor(storagelayer));
}
public KVMStoragePool getStoragePool(String uuid) {
return this._storageAdaptor.getStoragePool(uuid);
public KVMStoragePool getStoragePool(StoragePoolType type, String uuid) {
StorageAdaptor adaptor = getStorageAdaptor(type);
return adaptor.getStoragePool(uuid);
}
public KVMStoragePool getStoragePoolByURI(String uri) {
return this._storageAdaptor.getStoragePoolByURI(uri);
URI storageUri = null;
try {
storageUri = new URI(uri);
} catch (URISyntaxException e) {
throw new CloudRuntimeException(e.toString());
}
String sourcePath = null;
String uuid = null;
String sourceHost = "";
StoragePoolType protocol = null;
if (storageUri.getScheme().equalsIgnoreCase("nfs")) {
sourcePath = storageUri.getPath();
sourcePath = sourcePath.replace("//", "/");
sourceHost = storageUri.getHost();
uuid = UUID.nameUUIDFromBytes(
new String(sourceHost + sourcePath).getBytes()).toString();
protocol = StoragePoolType.NetworkFilesystem;
}
return createStoragePool(uuid, sourceHost, 0, sourcePath, "", protocol);
}
public KVMStoragePool createStoragePool(String name, String host, int port, String path,
String userInfo, StoragePoolType type) {
KVMStoragePool pool = this._storageAdaptor.createStoragePool(name,
public KVMStoragePool createStoragePool( String name, String host, int port,
String path, String userInfo,
StoragePoolType type) {
StorageAdaptor adaptor = getStorageAdaptor(type);
KVMStoragePool pool = adaptor.createStoragePool(name,
host, port, path, userInfo, type);
// LibvirtStorageAdaptor-specific statement
if (type == StoragePoolType.NetworkFilesystem) {
KVMHABase.NfsStoragePool nfspool = new KVMHABase.NfsStoragePool(
pool.getUuid(), host, path, pool.getLocalPath(),
@ -66,28 +110,33 @@ public class KVMStoragePoolManager {
return pool;
}
public boolean deleteStoragePool(String uuid) {
public boolean deleteStoragePool(StoragePoolType type, String uuid) {
StorageAdaptor adaptor = getStorageAdaptor(type);
_haMonitor.removeStoragePool(uuid);
this._storageAdaptor.deleteStoragePool(uuid);
adaptor.deleteStoragePool(uuid);
_storagePools.remove(uuid);
return true;
}
public boolean deleteVbdByPath(String diskPath) {
return this._storageAdaptor.deleteVbdByPath(diskPath);
public boolean deleteVbdByPath(StoragePoolType type, String diskPath) {
StorageAdaptor adaptor = getStorageAdaptor(type);
return adaptor.deleteVbdByPath(diskPath);
}
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name,
KVMStoragePool destPool) {
StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
// LibvirtStorageAdaptor-specific statement
if (destPool.getType() == StoragePoolType.RBD) {
return this._storageAdaptor.createDiskFromTemplate(template, name,
return adaptor.createDiskFromTemplate(template, name,
KVMPhysicalDisk.PhysicalDiskFormat.RAW, template.getSize(), destPool);
} else if (destPool.getType() == StoragePoolType.CLVM) {
return this._storageAdaptor.createDiskFromTemplate(template, name,
return adaptor.createDiskFromTemplate(template, name,
KVMPhysicalDisk.PhysicalDiskFormat.RAW, template.getSize(),
destPool);
} else {
return this._storageAdaptor.createDiskFromTemplate(template, name,
return adaptor.createDiskFromTemplate(template, name,
KVMPhysicalDisk.PhysicalDiskFormat.QCOW2,
template.getSize(), destPool);
}
@ -96,22 +145,22 @@ public class KVMStoragePoolManager {
public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk,
String name, PhysicalDiskFormat format, long size,
KVMStoragePool destPool) {
return this._storageAdaptor.createTemplateFromDisk(disk, name, format,
StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
return adaptor.createTemplateFromDisk(disk, name, format,
size, destPool);
}
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name,
KVMStoragePool destPool) {
return this._storageAdaptor.copyPhysicalDisk(disk, name, destPool);
StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
return adaptor.copyPhysicalDisk(disk, name, destPool);
}
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot,
String snapshotName, String name, KVMStoragePool destPool) {
return this._storageAdaptor.createDiskFromSnapshot(snapshot,
StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
return adaptor.createDiskFromSnapshot(snapshot,
snapshotName, name, destPool);
}
public KVMPhysicalDisk getPhysicalDiskFromUrl(String url) {
return this._storageAdaptor.getPhysicalDiskFromURI(url);
}
}

View File

@ -725,38 +725,6 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
return newDisk;
}
@Override
public KVMStoragePool getStoragePoolByURI(String uri) {
URI storageUri = null;
try {
storageUri = new URI(uri);
} catch (URISyntaxException e) {
throw new CloudRuntimeException(e.toString());
}
String sourcePath = null;
String uuid = null;
String sourceHost = "";
StoragePoolType protocal = null;
if (storageUri.getScheme().equalsIgnoreCase("nfs")) {
sourcePath = storageUri.getPath();
sourcePath = sourcePath.replace("//", "/");
sourceHost = storageUri.getHost();
uuid = UUID.nameUUIDFromBytes(
new String(sourceHost + sourcePath).getBytes()).toString();
protocal = StoragePoolType.NetworkFilesystem;
}
return createStoragePool(uuid, sourceHost, 0, sourcePath, "", protocal);
}
@Override
public KVMPhysicalDisk getPhysicalDiskFromURI(String uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot,
String snapshotName, String name, KVMStoragePool destPool) {

View File

@ -55,10 +55,6 @@ public interface StorageAdaptor {
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot,
String snapshotName, String name, KVMStoragePool destPool);
public KVMStoragePool getStoragePoolByURI(String uri);
public KVMPhysicalDisk getPhysicalDiskFromURI(String uri);
public boolean refresh(KVMStoragePool pool);
public boolean deleteStoragePool(KVMStoragePool pool);

View File

@ -669,7 +669,6 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
String vdiUUID = null;
Long snapshotId = snapshot.getId();
Long volumeId = snapshot.getVolumeId();
String primaryStoragePoolNameLabel = pool.getUuid(); // pool's uuid is actually the namelabel.
Long dcId = snapshot.getDataCenterId();
String secondaryStoragePoolUrl = _snapMgr.getSecondaryStorageURL(snapshot);
long accountId = snapshot.getAccountId();
@ -716,7 +715,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
} else if (snapshot.getS3Id() != null && snapshot.getS3Id() != 0) {
_snapshotMgr.downloadSnapshotsFromS3(snapshot);
}
CreateVolumeFromSnapshotCommand createVolumeFromSnapshotCommand = new CreateVolumeFromSnapshotCommand(primaryStoragePoolNameLabel, secondaryStoragePoolUrl, dcId, accountId, volumeId,
CreateVolumeFromSnapshotCommand createVolumeFromSnapshotCommand = new CreateVolumeFromSnapshotCommand(pool, secondaryStoragePoolUrl, dcId, accountId, volumeId,
backedUpSnapshotUuid, snapshot.getName(), _createVolumeFromSnapshotWait);
CreateVolumeFromSnapshotAnswer answer;
if (!_snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {

View File

@ -628,7 +628,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
long volumeId = snapshot.getVolumeId();
VolumeVO volume = _volsDao.lockRow(volumeId, true);
String primaryStoragePoolNameLabel = _storageMgr.getPrimaryStorageNameLabel(volume);
Long dcId = volume.getDataCenterId();
Long accountId = volume.getAccountId();
@ -666,7 +665,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
boolean isVolumeInactive = _storageMgr.volumeInactive(volume);
String vmName = _storageMgr.getVmNameOnVolume(volume);
StoragePoolVO srcPool = _storagePoolDao.findById(volume.getPoolId());
BackupSnapshotCommand backupSnapshotCommand = new BackupSnapshotCommand(primaryStoragePoolNameLabel, secondaryStoragePoolUrl, dcId, accountId, volumeId, snapshot.getId(), volume.getPath(), srcPool, snapshotUuid,
BackupSnapshotCommand backupSnapshotCommand = new BackupSnapshotCommand(secondaryStoragePoolUrl, dcId, accountId, volumeId, snapshot.getId(), volume.getPath(), srcPool, snapshotUuid,
snapshot.getName(), prevSnapshotUuid, prevBackupUuid, isVolumeInactive, vmName, _backupsnapshotwait);
if ( swift != null ) {

View File

@ -667,7 +667,7 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
}
String url = origUrl + "/" + templateHostRef.getInstallPath();
PrimaryStorageDownloadCommand dcmd = new PrimaryStorageDownloadCommand(template.getUniqueName(), url, template.getFormat(),
template.getAccountId(), pool.getId(), pool.getUuid(), _primaryStorageDownloadWait);
template.getAccountId(), pool, _primaryStorageDownloadWait);
HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId());
assert(secondaryStorageHost != null);
dcmd.setSecondaryStorageUrl(secondaryStorageHost.getStorageUrl());

View File

@ -1448,7 +1448,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
if( snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0 ) {
_snapshotMgr.downloadSnapshotsFromSwift(snapshot);
}
cmd = new CreatePrivateTemplateFromSnapshotCommand(pool.getUuid(), secondaryStorageURL, dcId, accountId, snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(),
cmd = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStorageURL, dcId, accountId, snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(),
origTemplateInstallPath, templateId, name, _createprivatetemplatefromsnapshotwait);
} else if (volumeId != null) {
VolumeVO volume = _volsDao.findById(volumeId);
@ -1470,7 +1470,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
secondaryStorageURL = secondaryStorageHost.getStorageUrl();
pool = _storagePoolDao.findById(volume.getPoolId());
cmd = new CreatePrivateTemplateFromVolumeCommand(pool.getUuid(), secondaryStorageURL, templateId, accountId, command.getTemplateName(), uniqueName, volume.getPath(), vmName, _createprivatetemplatefromvolumewait);
cmd = new CreatePrivateTemplateFromVolumeCommand(pool, secondaryStorageURL, templateId, accountId, command.getTemplateName(), uniqueName, volume.getPath(), vmName, _createprivatetemplatefromvolumewait);
} else {
throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");