bug 10330: finally merge Rommer's CLVM patch

status 10330: resolved fixed
This commit is contained in:
Edison Su 2011-11-02 18:02:00 -07:00
parent 1e86b5e1a6
commit 6841e265d3
31 changed files with 565 additions and 217 deletions

View File

@ -416,7 +416,7 @@ public class MockStorageManagerImpl implements MockStorageManager {
return new BackupSnapshotAnswer(cmd, false, "can't find snapshot" + snapshotPath, null, true);
}
String secStorageUrl = cmd.getSecondaryStoragePoolURL();
String secStorageUrl = cmd.getSecondaryStorageUrl();
MockSecStorageVO secStorage = _mockSecStorageDao.findByUrl(secStorageUrl);
if (secStorage == null) {
return new BackupSnapshotAnswer(cmd, false, "can't find sec storage" + snapshotPath, null, true);
@ -613,7 +613,7 @@ public class MockStorageManagerImpl implements MockStorageManager {
}
}
MockSecStorageVO sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStoragePoolURL());
MockSecStorageVO sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageUrl());
if (sec == null) {
return new CreatePrivateTemplateAnswer(cmd, false, "can't find secondary storage");
}
@ -654,7 +654,7 @@ public class MockStorageManagerImpl implements MockStorageManager {
return new CreatePrivateTemplateAnswer(cmd, false, "cant' find volume" + cmd.getVolumePath());
}
MockSecStorageVO sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStoragePoolURL());
MockSecStorageVO sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageUrl());
if (sec == null) {
return new CreatePrivateTemplateAnswer(cmd, false, "can't find secondary storage");
}

View File

@ -194,7 +194,7 @@ public class CloudZonesComputingResource extends LibvirtComputingResource {
// Attach each data volume to the VM, if there is a deferred attached disk
for (DiskDef disk : vm.getDevices().getDisks()) {
if (disk.isAttachDeferred()) {
attachOrDetachDisk(conn, true, vmName, disk.getDiskPath(), disk.getDiskSeq());
attachOrDetachDevice(conn, true, vmName, disk.toString());
}
}

View File

@ -168,6 +168,7 @@ import com.cloud.agent.resource.computing.LibvirtVMDef.SerialDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.TermPolicy;
import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
import com.cloud.agent.storage.KVMPhysicalDisk;
import com.cloud.agent.storage.KVMPhysicalDisk.PhysicalDiskFormat;
import com.cloud.agent.storage.KVMStoragePool;
import com.cloud.agent.storage.KVMStoragePoolManager;
import com.cloud.agent.storage.LibvirtStorageAdaptor;
@ -202,6 +203,7 @@ import com.cloud.vm.DiskProfile;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.VirtualMachineName;
import com.xensource.xenapi.Connection;
/**
@ -235,6 +237,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
private String _createTmplPath;
private String _heartBeatPath;
private String _securityGroupPath;
private String _networkUsagePath;
private String _host;
private String _dcId;
private String _pod;
@ -521,6 +524,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
throw new ConfigurationException("Unable to find the security_group.py");
}
_networkUsagePath = Script.findScript("scripts/network/domr/", "networkUsage.sh");
if (_networkUsagePath == null) {
throw new ConfigurationException("Unable to find the networkUsage.sh");
}
String value = (String)params.get("developer");
boolean isDeveloper = Boolean.parseBoolean(value);
@ -942,6 +950,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
String volumePath = cmd.getVolumePath();
StorageFilerTO pool = cmd.getPool();
String secondaryStorageUrl = cmd.getSecondaryStorageURL();
KVMStoragePool secondaryStoragePool = null;
try {
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(pool.getUuid());
String volumeName = UUID.randomUUID().toString();
@ -949,18 +958,22 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
if (copyToSecondary) {
KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(cmd.getVolumePath());
String volumeDestPath = "/volumes/" + cmd.getVolumeId() + File.separator;
KVMStoragePool secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumeDestPath);
secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumeDestPath);
_storagePoolMgr.copyPhysicalDisk(volume, volumeName, secondaryStoragePool);
return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
} else {
volumePath = "/volumes/" + cmd.getVolumeId() + File.separator + volumePath;
KVMStoragePool secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumePath);
secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumePath);
KVMPhysicalDisk volume = secondaryStoragePool.getPhysicalDisk(cmd.getVolumePath());
_storagePoolMgr.copyPhysicalDisk(volume, volumeName, primaryPool);
return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
}
} catch (CloudRuntimeException e) {
return new CopyVolumeAnswer(cmd, false, e.toString(), null, null);
} finally {
if (secondaryStoragePool != null) {
secondaryStoragePool.delete();
}
}
}
@ -1036,7 +1049,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
try {
KVMStoragePool pool = _storagePoolMgr.getStoragePool(vol.getPoolUuid());
pool.deletePhysicalDisk(vol.getName());
pool.deletePhysicalDisk(vol.getPath());
return new Answer(cmd, true, "Success");
} catch (CloudRuntimeException e) {
@ -1112,6 +1125,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
vlanAllocatedToVM.put(ip.getVlanId(), nicPos++);
}
nicNum = vlanAllocatedToVM.get(ip.getVlanId());
networkUsage(routerIp, "addVif", "eth" + nicNum);
result = _virtRouterResource.assignPublicIpAddress(routerName, routerIp, ip.getPublicIp(), ip.isAdd(),
ip.isFirstIP(), ip.isSourceNat(),
ip.getVlanId(), ip.getVlanGateway(), ip.getVlanNetmask(),
@ -1125,15 +1139,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
return new IpAssocAnswer(cmd, results);
} catch (LibvirtException e) {
return new ManageSnapshotAnswer(cmd, false, e.toString());
return new IpAssocAnswer(cmd, results);
} catch (InternalErrorException e) {
return new ManageSnapshotAnswer(cmd, false, e.toString());
return new IpAssocAnswer(cmd, results);
}
}
protected ManageSnapshotAnswer execute(final ManageSnapshotCommand cmd) {
String snapshotName = cmd.getSnapshotName();
String VolPath = cmd.getVolumePath();
String snapshotPath = cmd.getSnapshotPath();
String vmName = cmd.getVmName();
try {
@ -1150,6 +1163,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getUuid());
KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(cmd.getVolumePath());
if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) {
String vmUuid = vm.getUUIDString();
Object[] args = new Object[] {snapshotName, vmUuid};
@ -1169,10 +1183,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
vm.resume();
}
} else {
/*VM is not running, create a snapshot by ourself*/
final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
command.add("-c", VolPath);
command.add("-c", disk.getPath());
} else {
command.add("-d", snapshotPath);
}
@ -1184,11 +1199,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new ManageSnapshotAnswer(cmd, false, "Failed to manage snapshot: " + result);
}
}
return new ManageSnapshotAnswer(cmd, cmd.getSnapshotId(), disk.getPath() + File.separator + snapshotName, true, null);
} catch (LibvirtException e) {
s_logger.debug("Failed to manage snapshot: " + e.toString());
return new ManageSnapshotAnswer(cmd, false, "Failed to manage snapshot: " + e.toString());
}
return new ManageSnapshotAnswer(cmd, cmd.getSnapshotId(), cmd.getVolumePath() + File.separator + snapshotName, true, null);
}
protected BackupSnapshotAnswer execute(final BackupSnapshotCommand cmd) {
@ -1201,81 +1217,85 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
String snapshotDestPath = null;
String snapshotRelPath = null;
String vmName = cmd.getVmName();
KVMStoragePool secondaryStoragePool = null;
try {
Connect conn = LibvirtConnection.getConnection();
KVMStoragePool secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl);
secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl);
String ssPmountPath = secondaryStoragePool.getLocalPath();
snapshotRelPath = File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
String ssPmountPath = secondaryStoragePool.getLocalPath();
snapshotRelPath = File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
command.add("-b", snapshotPath);
command.add("-n", snapshotName);
command.add("-p", snapshotDestPath);
command.add("-t", snapshotName);
String result = command.execute();
if (result != null) {
s_logger.debug("Failed to backup snaptshot: " + result);
return new BackupSnapshotAnswer(cmd, false, result, null, true);
}
/*Delete the snapshot on primary*/
snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPrimaryStoragePoolNameLabel());
KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(cmd.getVolumePath());
Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
command.add("-b", snapshotDisk.getPath());
command.add("-n", snapshotName);
command.add("-p", snapshotDestPath);
command.add("-t", snapshotName);
String result = command.execute();
if (result != null) {
s_logger.debug("Failed to backup snaptshot: " + result);
return new BackupSnapshotAnswer(cmd, false, result, null, true);
}
/*Delete the snapshot on primary*/
DomainInfo.DomainState state = null;
Domain vm = null;
if (vmName != null) {
try {
vm = getDomain(conn, cmd.getVmName());
state = vm.getInfo().state;
} catch (LibvirtException e) {
DomainInfo.DomainState state = null;
Domain vm = null;
if (vmName != null) {
try {
vm = getDomain(conn, cmd.getVmName());
state = vm.getInfo().state;
} catch (LibvirtException e) {
}
}
}
}
KVMStoragePool primaryStorage = _storagePoolMgr.getStoragePool(cmd.getPool().getUuid());
if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) {
String vmUuid = vm.getUUIDString();
Object[] args = new Object[] {snapshotName, vmUuid};
String snapshot = SnapshotXML.format(args);
s_logger.debug(snapshot);
DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
snap.delete(0);
KVMStoragePool primaryStorage = _storagePoolMgr.getStoragePool(cmd.getPool().getUuid());
if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) {
String vmUuid = vm.getUUIDString();
Object[] args = new Object[] {snapshotName, vmUuid};
String snapshot = SnapshotXML.format(args);
s_logger.debug(snapshot);
DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
snap.delete(0);
/*libvirt on RHEL6 doesn't handle resume event emitted from qemu*/
vm = getDomain(conn, cmd.getVmName());
state = vm.getInfo().state;
if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
vm.resume();
}
} else {
command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
command.add("-d", snapshotPath);
command.add("-n", snapshotName);
result = command.execute();
if (result != null) {
s_logger.debug("Failed to backup snapshot: " + result);
return new BackupSnapshotAnswer(cmd, false, "Failed to backup snapshot: " + result, null, true);
}
}
} catch (LibvirtException e) {
return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true);
} catch (CloudRuntimeException e) {
return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true);
}
return new BackupSnapshotAnswer(cmd, true, null, snapshotRelPath + File.separator + snapshotName, true);
/*libvirt on RHEL6 doesn't handle resume event emitted from qemu*/
vm = getDomain(conn, cmd.getVmName());
state = vm.getInfo().state;
if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
vm.resume();
}
} else {
command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
command.add("-d", snapshotDisk.getPath());
command.add("-n", snapshotName);
result = command.execute();
if (result != null) {
s_logger.debug("Failed to backup snapshot: " + result);
return new BackupSnapshotAnswer(cmd, false, "Failed to backup snapshot: " + result, null, true);
}
}
} catch (LibvirtException e) {
return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true);
} catch (CloudRuntimeException e) {
return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true);
} finally {
if (secondaryStoragePool != null) {
secondaryStoragePool.delete();
}
}
return new BackupSnapshotAnswer(cmd, true, null, snapshotRelPath + File.separator + snapshotName, true);
}
protected DeleteSnapshotBackupAnswer execute(final DeleteSnapshotBackupCommand cmd) {
Long dcId = cmd.getDataCenterId();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
KVMStoragePool secondaryStoragePool = null;
try {
KVMStoragePool secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl());
secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl());
String ssPmountPath = secondaryStoragePool.getLocalPath();
String snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
@ -1287,6 +1307,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
command.execute();
} catch (CloudRuntimeException e) {
return new DeleteSnapshotBackupAnswer(cmd, false, e.toString());
} finally {
if (secondaryStoragePool != null) {
secondaryStoragePool.delete();
}
}
return new DeleteSnapshotBackupAnswer(cmd, true, null);
}
@ -1295,8 +1319,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
Long dcId = cmd.getDcId();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
KVMStoragePool secondaryStoragePool = null;
try {
KVMStoragePool secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl());
secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl());
String ssPmountPath = secondaryStoragePool.getLocalPath();
String snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
@ -1307,6 +1332,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
command.execute();
} catch (CloudRuntimeException e) {
return new Answer(cmd, false, e.toString());
} finally {
if (secondaryStoragePool != null) {
secondaryStoragePool.delete();
}
}
return new Answer(cmd, true, null);
}
@ -1323,8 +1353,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
String primaryUuid = cmd.getPrimaryStoragePoolNameLabel();
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(primaryUuid);
String volUuid = UUID.randomUUID().toString();
KVMPhysicalDisk disk = _storagePoolMgr.createDiskFromSnapshot(snapshot, cmd.getSnapshotName(), volUuid, primaryPool);
return new CreateVolumeFromSnapshotAnswer(cmd, true, "", disk.getPath());
KVMPhysicalDisk disk = _storagePoolMgr.copyPhysicalDisk(snapshot, volUuid, primaryPool);
return new CreateVolumeFromSnapshotAnswer(cmd, true, "", disk.getName());
} catch (CloudRuntimeException e) {
return new CreateVolumeFromSnapshotAnswer(cmd, false, e.toString(), null);
}
@ -1339,12 +1369,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromSnapshotCommand cmd) {
String templateFolder = cmd.getAccountId() + File.separator + cmd.getNewTemplateId();
String templateInstallFolder = "template/tmpl/" + templateFolder;
String snapshotPath = cmd.getSnapshotUuid();
String tmplName = UUID.randomUUID().toString();
String tmplFileName = tmplName + ".qcow2";
KVMStoragePool secondaryPool;
KVMStoragePool secondaryPool = null;
KVMStoragePool snapshotPool = null;
try {
String snapshotPath = cmd.getSnapshotUuid();
int index = snapshotPath.lastIndexOf("/");
snapshotPath = snapshotPath.substring(0, index);
snapshotPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl() + snapshotPath);
KVMPhysicalDisk snapshot = snapshotPool.getPhysicalDisk(cmd.getSnapshotName());
secondaryPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl());
@ -1356,7 +1390,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
Script command = new Script(_createTmplPath, _timeout, s_logger);
command.add("-t", templatePath);
command.add("-n", tmplFileName);
command.add("-f", snapshotPath);
command.add("-f", snapshot.getPath());
command.execute();
Map<String, Object> params = new HashMap<String, Object>();
@ -1379,6 +1413,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
} catch (CloudRuntimeException e) {
return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
} finally {
if (secondaryPool != null) {
secondaryPool.delete();
}
if (snapshotPool != null) {
snapshotPool.delete();
}
}
}
@ -1403,12 +1444,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
secondaryStorage = _storagePoolMgr.getStoragePoolByURI(secondaryStorageURL);
KVMStoragePool primary = _storagePoolMgr.getStoragePool(cmd.getPrimaryStoragePoolNameLabel());
KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath());
String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateInstallFolder;
_storage.mkdirs(tmpltPath);
Script command = new Script(_createTmplPath, _timeout, s_logger);
command.add("-f", cmd.getVolumePath());
command.add("-f", disk.getPath());
command.add("-t", tmpltPath);
command.add("-n", cmd.getUniqueName() + ".qcow2");
@ -1451,6 +1493,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new CreatePrivateTemplateAnswer(cmd, false, e.toString());
} catch (CloudRuntimeException e) {
return new CreatePrivateTemplateAnswer(cmd, false, e.toString());
} finally {
if (secondaryStorage != null) {
secondaryStorage.delete();
}
}
}
@ -1464,9 +1510,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
KVMPhysicalDisk tmplVol = null;
KVMStoragePool secondaryPool = null;
try {
KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(mountpoint);
secondaryPool = _storagePoolMgr.getStoragePoolByURI(mountpoint);
/*Get template vol*/
if (tmpltname == null) {
@ -1484,6 +1530,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
if (tmplVol == null) {
return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid());
}
} else {
tmplVol = secondaryPool.getPhysicalDisk(tmpltname);
}
/*Copy volume to primary storage*/
@ -1494,6 +1542,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new PrimaryStorageDownloadAnswer(primaryVol.getName(), primaryVol.getSize());
} catch (CloudRuntimeException e) {
return new PrimaryStorageDownloadAnswer(e.toString());
} finally {
if (secondaryPool != null) {
secondaryPool.delete();
}
}
}
@ -1627,7 +1679,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
private AttachVolumeAnswer execute(AttachVolumeCommand cmd) {
try {
Connect conn = LibvirtConnection.getConnection();
attachOrDetachDisk(conn, cmd.getAttach(), cmd.getVmName(), cmd.getVolumePath(), cmd.getDeviceId().intValue());
KVMStoragePool primary = _storagePoolMgr.getStoragePool(cmd.getPoolUuid());
KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath());
attachOrDetachDisk(conn, cmd.getAttach(), cmd.getVmName(), disk, cmd.getDeviceId().intValue());
} catch (LibvirtException e) {
return new AttachVolumeAnswer(cmd, e.toString());
} catch (InternalErrorException e) {
@ -1885,27 +1939,55 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new GetHostStatsAnswer(cmd, hostStats);
}
private Answer execute(NetworkUsageCommand cmd) {
String vmName = cmd.getDomRName();
try {
Connect conn = LibvirtConnection.getConnection();
Domain dm = getDomain(conn, vmName);
LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
String xml = dm.getXMLDesc(0);
parser.parseDomainXML(xml);
List<InterfaceDef> nics = parser.getInterfaces();
if (nics.size() != 3) {
return new Answer(cmd, false, vmName + " doesn't have public nic");
protected String networkUsage(final String privateIpAddress, final String option, final String vif) {
Script getUsage = new Script(_networkUsagePath, s_logger);
if (option.equals("get")) {
getUsage.add("-g");
} else if (option.equals("create")) {
getUsage.add("-c");
} else if (option.equals("reset")) {
getUsage.add("-r");
} else if (option.equals("addVif")) {
getUsage.add("-a", vif);
} else if (option.equals("deleteVif")) {
getUsage.add("-d", vif);
}
getUsage.add(" -i ", privateIpAddress);
final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser();
String result = getUsage.execute(usageParser);
if (result != null) {
s_logger.debug("Failed to execute networkUsage:" + result);
return null;
}
return usageParser.getLine();
}
protected long[] getNetworkStats(String privateIP) {
String result = networkUsage(privateIP, "get", null);
long[] stats = new long[2];
if (result != null) {
String[] splitResult = result.split(":");
int i = 0;
while (i < splitResult.length - 1) {
stats[0] += (new Long(splitResult[i++])).longValue();
stats[1] += (new Long(splitResult[i++])).longValue();
}
InterfaceDef pubNic = nics.get(2);
Pair<Double, Double> nicStats = getNicStats(pubNic.getBrName());
/*Note: received means bytes received by all the vms, but from host kernel's pov, it's tx*/
return new NetworkUsageAnswer(cmd, "", nicStats.first().longValue(), nicStats.second().longValue());
} catch (LibvirtException e) {
return new Answer(cmd, false, e.toString());
}
return stats;
}
private Answer execute(NetworkUsageCommand cmd) {
if(cmd.getOption()!=null && cmd.getOption().equals("create") ){
String result = networkUsage(cmd.getPrivateIP(), "create", null);
NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L);
return answer;
}
long[] stats = getNetworkStats(cmd.getPrivateIP());
NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]);
return answer;
}
private Answer execute(RebootCommand cmd) {
Long bytesReceived = null;
Long bytesSent = null;
@ -1939,9 +2021,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
protected Answer execute(RebootRouterCommand cmd) {
Long bytesSent = 0L;
Long bytesRcvd = 0L;
if (VirtualMachineName.isValidRouterName(cmd.getVmName())) {
long[] stats = getNetworkStats(cmd.getPrivateIpAddress());
bytesSent = stats[0];
bytesRcvd = stats[1];
}
RebootAnswer answer = (RebootAnswer) execute((RebootCommand) cmd);
answer.setBytesSent(bytesSent);
answer.setBytesReceived(bytesRcvd);
String result = _virtRouterResource.connect(cmd.getPrivateIpAddress());
if (result == null) {
networkUsage(cmd.getPrivateIpAddress(), "create", null);
return answer;
} else {
return new Answer(cmd, false, result);
@ -2189,7 +2281,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
// Attach each data volume to the VM, if there is a deferred attached disk
for (DiskDef disk : vm.getDevices().getDisks()) {
if (disk.isAttachDeferred()) {
attachOrDetachDisk(conn, true, vmName, disk.getDiskPath(), disk.getDiskSeq());
attachOrDetachDevice(conn, true, vmName, disk.toString());
}
}
@ -2237,12 +2329,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
String volName = volPath.substring(index + 1);
KVMStoragePool secondaryStorage = _storagePoolMgr.getStoragePoolByURI(volDir);
physicalDisk = secondaryStorage.getPhysicalDisk(volName);
} else {
} else if (volume.getType() != Volume.Type.ISO) {
pool = _storagePoolMgr.getStoragePool(volume.getPoolUuid());
physicalDisk = pool.getPhysicalDisk(volume.getPath());
}
String volPath = physicalDisk.getPath();
String volPath = null;
if (physicalDisk != null) {
volPath = physicalDisk.getPath();
}
DiskDef.diskBus diskBusType = getGuestDiskModel(vmSpec.getOs());
DiskDef disk = new DiskDef();
@ -2416,10 +2511,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return attachOrDetachDevice(conn, true, vmName, isoXml);
}
protected synchronized String attachOrDetachDisk(Connect conn, boolean attach, String vmName, String sourceFile, int devId) throws LibvirtException, InternalErrorException {
protected synchronized String attachOrDetachDisk(Connect conn, boolean attach, String vmName, KVMPhysicalDisk attachingDisk, int devId) throws LibvirtException, InternalErrorException {
List<DiskDef> disks = null;
Domain dm = null;
int deviceId = devId;
DiskDef diskdef = null;
try {
if (!attach) {
dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName.getBytes()));
@ -2428,24 +2523,26 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
parser.parseDomainXML(xml);
disks = parser.getDisks();
boolean diskAttached = false;
for (DiskDef disk : disks) {
String file = disk.getDiskPath();
if (file != null && file.equalsIgnoreCase(sourceFile)) {
deviceId = disk.getDiskSeq();
diskAttached = true;
if (file != null && file.equalsIgnoreCase(attachingDisk.getPath())) {
diskdef = disk;
break;
}
}
if (!diskAttached) {
throw new InternalErrorException("disk: " + sourceFile + " is not attached before");
if (diskdef == null) {
throw new InternalErrorException("disk: " + attachingDisk.getPath() + " is not attached before");
}
} else {
diskdef = new DiskDef();
if (attachingDisk.getFormat() == PhysicalDiskFormat.QCOW2) {
diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2);
} else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) {
diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, DiskDef.diskBus.VIRTIO);
}
}
DiskDef disk = new DiskDef();
disk.defFileBasedDisk(sourceFile, deviceId, DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2);
String xml = disk.toString();
String xml = diskdef.toString();
return attachOrDetachDevice(conn, attach, vmName, xml);
} finally {
if (dm != null) {
@ -2454,7 +2551,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
}
private synchronized String attachOrDetachDevice(Connect conn, boolean attach, String vmName, String xml) throws LibvirtException, InternalErrorException{
protected synchronized String attachOrDetachDevice(Connect conn, boolean attach, String vmName, String xml) throws LibvirtException, InternalErrorException{
Domain dm = null;
try {
dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes((vmName.getBytes())));

View File

@ -71,6 +71,8 @@ public class LibvirtDomainXMLParser {
Element disk = (Element)disks.item(i);
String diskFmtType = getAttrValue("driver", "type", disk);
String diskFile = getAttrValue("source", "file", disk);
String diskDev = getAttrValue("source", "dev", disk);
String diskLabel = getAttrValue("target", "dev", disk);
String bus = getAttrValue("target", "bus", disk);
String type = disk.getAttribute("type");
@ -87,6 +89,8 @@ public class LibvirtDomainXMLParser {
} else if (device.equalsIgnoreCase("cdrom")) {
def.defISODisk(diskFile);
}
} else if (type.equalsIgnoreCase("block")) {
def.defBlockBasedDisk(diskDev, diskLabel, DiskDef.diskBus.valueOf(bus.toUpperCase()));
}
diskDefs.add(def);
}

View File

@ -31,6 +31,18 @@ public class LibvirtStorageVolumeDef {
public String toString() {
return _format;
}
public static volFormat getFormat(String format) {
if (format == null) {
return null;
}
if (format.equalsIgnoreCase("raw")) {
return RAW;
} else if (format.equalsIgnoreCase("qcow2")) {
return QCOW2;
}
return null;
}
}
private String _volName;
private Long _volSize;

View File

@ -32,7 +32,7 @@ public class LibvirtStorageVolumeXMLParser{
Element target = (Element)rootElement.getElementsByTagName("target").item(0);
String format = getAttrValue("type", "format", target);
Long capacity = Long.parseLong(getTagValue("capacity", rootElement));
return new LibvirtStorageVolumeDef(VolName, capacity, LibvirtStorageVolumeDef.volFormat.QCOW2, null, null);
return new LibvirtStorageVolumeDef(VolName, capacity, LibvirtStorageVolumeDef.volFormat.getFormat(format), null, null);
} catch (ParserConfigurationException e) {
s_logger.debug(e.toString());
} catch (SAXException e) {

View File

@ -345,6 +345,14 @@ public class LibvirtVMDef {
_diskLabel = getDevLabel(devId, bus);
_bus = bus;
}
public void defBlockBasedDisk(String diskName, String diskLabel, diskBus bus) {
_diskType = diskType.BLOCK;
_deviceType = deviceType.DISK;
_diskFmtType = diskFmtType.RAW;
_sourcePath = diskName;
_diskLabel = diskLabel;
_bus = bus;
}
public void setReadonly() {
_readonly = true;
}

View File

@ -5,8 +5,15 @@ public class KVMPhysicalDisk {
private String name;
private KVMStoragePool pool;
public static enum PhysicalDiskFormat {
RAW,
QCOW2
RAW("raw"),
QCOW2("qcow2");
String format;
private PhysicalDiskFormat(String format) {
this.format = format;
}
public String toString() {
return this.format;
}
}
private PhysicalDiskFormat format;
private long size;

View File

@ -18,4 +18,6 @@ public interface KVMStoragePool {
public boolean isExternalSnapshot();
public String getLocalPath();
public StoragePoolType getType();
public boolean delete();
PhysicalDiskFormat getDefaultFormat();
}

View File

@ -74,4 +74,6 @@ public class KVMStoragePoolManager {
public KVMPhysicalDisk getPhysicalDiskFromUrl(String url) {
return this._storageAdaptor.getPhysicalDiskFromURI(url);
}
}

View File

@ -23,10 +23,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
@ -35,27 +32,17 @@ import org.libvirt.StoragePoolInfo;
import org.libvirt.StorageVol;
import org.libvirt.StoragePoolInfo.StoragePoolState;
import com.cloud.agent.api.GetStorageStatsAnswer;
import com.cloud.agent.api.StartupStorageCommand;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.agent.resource.computing.KVMHABase;
import com.cloud.agent.resource.computing.KVMHAMonitor;
import com.cloud.agent.resource.computing.LibvirtComputingResource;
import com.cloud.agent.api.ManageSnapshotCommand;
import com.cloud.agent.resource.computing.LibvirtConnection;
import com.cloud.agent.resource.computing.LibvirtStoragePoolDef;
import com.cloud.agent.resource.computing.LibvirtStoragePoolXMLParser;
import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef;
import com.cloud.agent.resource.computing.KVMHABase.NfsStoragePool;
import com.cloud.agent.resource.computing.KVMHABase.PoolType;
import com.cloud.agent.resource.computing.LibvirtStoragePoolDef.poolType;
import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef.volFormat;
import com.cloud.agent.resource.computing.LibvirtStorageVolumeXMLParser;
import com.cloud.agent.storage.KVMPhysicalDisk.PhysicalDiskFormat;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Storage;
import com.cloud.storage.StorageLayer;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.OutputInterpreter;
@ -65,12 +52,12 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
private static final Logger s_logger = Logger.getLogger(LibvirtStorageAdaptor.class);
private StorageLayer _storageLayer;
private String _mountPoint = "/mnt";
private String _manageSnapshotPath;
public LibvirtStorageAdaptor(StorageLayer storage
) {
_storageLayer = storage;
_manageSnapshotPath = Script.findScript("scripts/storage/qcow2/", "managesnapshot.sh");
}
@ -235,6 +222,33 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
}
}
private StoragePool createCLVMStoragePool(Connect conn, String uuid, String host, String path) {
String volgroupPath = "/dev/" + path;
LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(poolType.LOGICAL, uuid, uuid,
host, volgroupPath, volgroupPath);
StoragePool sp = null;
try {
s_logger.debug(spd.toString());
sp = conn.storagePoolDefineXML(spd.toString(), 0);
sp.create(0);
return sp;
} catch (LibvirtException e) {
s_logger.debug(e.toString());
if (sp != null) {
try {
sp.undefine();
sp.free();
} catch (LibvirtException l) {
s_logger.debug("Failed to define clvm storage pool with: " + l.toString());
}
}
return null;
}
}
public StorageVol copyVolume(StoragePool destPool, LibvirtStorageVolumeDef destVol, StorageVol srcVol, int timeout) throws LibvirtException {
StorageVol vol = destPool.storageVolCreateXML(destVol.toString(), 0);
String srcPath = srcVol.getKey();
@ -405,7 +419,9 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool);
disk.setSize(vol.getInfo().allocation);
disk.setVirtualSize(vol.getInfo().capacity);
if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.QCOW2) {
if (voldef.getFormat() == null) {
disk.setFormat(pool.getDefaultFormat());
} else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.QCOW2) {
disk.setFormat(KVMPhysicalDisk.PhysicalDiskFormat.QCOW2);
} else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.RAW) {
disk.setFormat(KVMPhysicalDisk.PhysicalDiskFormat.RAW);
@ -416,6 +432,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
}
}
@Override
public KVMStoragePool createStoragePool(String name, String host, String path, StoragePoolType type) {
StoragePool sp = null;
@ -437,6 +454,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
sp = createNfsStoragePool(conn, name, host, path);
} else if (type == StoragePoolType.SharedMountPoint || type == StoragePoolType.Filesystem) {
sp = CreateSharedStoragePool(conn, name, host, path);
} else if (type == StoragePoolType.CLVM) {
sp = createCLVMStoragePool(conn, name, host, path);
}
}
@ -534,18 +553,15 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
KVMPhysicalDisk disk = destPool.createPhysicalDisk(UUID.randomUUID().toString(), format, template.getVirtualSize());
if (format == PhysicalDiskFormat.QCOW2) {
Script.runSimpleBashScript("qemu-img create -f qcow2 -b " + template.getPath() + " " + disk.getPath());
} else {
Script.runSimpleBashScript("cp " + template.getPath() + " " + disk.getPath());
Script.runSimpleBashScript("qemu-img create -f " + template.getFormat() + " -b " + template.getPath() + " " + disk.getPath());
} else if (format == PhysicalDiskFormat.RAW) {
Script.runSimpleBashScript("qemu-img convert -f " + template.getFormat()+ " -O raw " + template.getPath() + " " + disk.getPath());
}
return disk;
}
@Override
public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk,
String name, PhysicalDiskFormat format, long size,
KVMStoragePool destPool) {
// TODO Auto-generated method stub
public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk, String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool) {
return null;
}
@ -572,7 +588,9 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
KVMPhysicalDisk newDisk = destPool.createPhysicalDisk(name, disk.getVirtualSize());
String sourcePath = disk.getPath();
String destPath = newDisk.getPath();
Script.runSimpleBashScript("qemu-img convert -f qcow2 -O qcow2 " + sourcePath + " " + destPath);
Script.runSimpleBashScript("qemu-img convert -f " + disk.getFormat() + " -O " + newDisk.getFormat() + " " + sourcePath + " " + destPath);
return newDisk;
}
@ -594,7 +612,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
sourcePath = storageUri.getPath();
sourcePath = sourcePath.replace("//", "/");
sourceHost = storageUri.getHost();
uuid = UUID.nameUUIDFromBytes(new String(sourceHost + sourcePath).getBytes()).toString();
uuid = UUID.randomUUID().toString();
protocal = StoragePoolType.NetworkFilesystem;
}
@ -610,7 +628,6 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
@Override
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot,
String snapshotName, String name, KVMStoragePool destPool) {
// TODO Auto-generated method stub
return null;
}
@ -627,4 +644,19 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
}
@Override
public boolean deleteStoragePool(KVMStoragePool pool) {
LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool;
StoragePool virtPool = libvirtPool.getPool();
try {
virtPool.destroy();
virtPool.undefine();
virtPool.free();
} catch (LibvirtException e) {
return false;
}
return true;
}
}

View File

@ -64,6 +64,7 @@ public class LibvirtStoragePool implements KVMStoragePool {
return this.uri;
}
@Override
public PhysicalDiskFormat getDefaultFormat() {
if (getStoragePoolType() == StoragePoolType.CLVM) {
return PhysicalDiskFormat.RAW;
@ -128,4 +129,9 @@ public class LibvirtStoragePool implements KVMStoragePool {
public StoragePool getPool() {
return this._pool;
}
@Override
public boolean delete() {
return this._storageAdaptor.deleteStoragePool(this);
}
}

View File

@ -20,6 +20,7 @@ public interface StorageAdaptor {
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool);
public KVMStoragePool getStoragePoolByUri(String uri);
public KVMPhysicalDisk getPhysicalDiskFromURI(String uri);
boolean refresh(KVMStoragePool pool);
public boolean refresh(KVMStoragePool pool);
public boolean deleteStoragePool(KVMStoragePool pool);
}

View File

@ -71,6 +71,8 @@ force.stop.instance.warning=Warning: Forcing a stop on this instance should be y
label.PreSetup=PreSetup
label.SR.name = SR Name-Label
label.SharedMountPoint=SharedMountPoint
label.clvm=CLVM
label.volgroup=Volume Group
label.VMFS.datastore=VMFS datastore
label.network.device=Network Device

View File

@ -71,6 +71,8 @@ force.stop.instance.warning=Advertencia: Obligar a una parada en este caso deber
label.PreSetup=PreSetup
label.SR.name = SR Nombre de etiqueta
label.SharedMountPoint = SharedMountPoint
label.clvm=CLVM
label.volgroup=Volume Group
label.VMFS.datastore=VMFS de datos tienda
label.network.device=De dispositivos de red

View File

@ -71,6 +71,8 @@ force.stop.instance.warning=警告:このインスタンスの停止を強制
label.PreSetup=PreSetup
label.SR.name=SR名-ラベル
label.SharedMountPoint = SharedMountPoint
label.clvm=CLVM
label.volgroup=Volume Group
label.VMFS.datastore=VMFSデータストア
label.network.device=ネットワークデバイス

View File

@ -71,6 +71,8 @@ force.stop.instance.warning=警告:强制停止在这个实例应该是你最
label.PreSetup=PreSetup
label.SR.name=简名称标签
label.SharedMountPoint = SharedMountPoint
label.clvm=CLVM
label.volgroup=Volume Group
label.VMFS.datastore=VMFS 数据存储
label.network.device=网络设备

View File

@ -858,7 +858,7 @@ public class VirtualRoutingResource implements Manager {
_getDomRVersionPath = findScript("getDomRVersion.sh");
if(_getDomRVersionPath == null) {
throw new ConfigurationException("Unable to find getRouterStatus.sh");
throw new ConfigurationException("Unable to find getDomRVersion.sh");
}
return true;

View File

@ -100,8 +100,11 @@ create_from_file() {
local tmpltfs=$1
local tmpltimg=$2
local tmpltname=$3
$qemu_img convert -f qcow2 -O qcow2 $tmpltimg /$tmpltfs/$tmpltname >& /dev/null
if [ -b $tmpltimg ]; then
$qemu-img convert -f raw -O qcow2 $tmpltimg /$tmpltfs/$tmpltname
else
$qemu_img convert -f qcow2 -O qcow2 $tmpltimg /$tmpltfs/$tmpltname >& /dev/null
fi
if [ "$cleanup" == "true" ]
then
@ -177,7 +180,7 @@ then
fi
fi
if [ ! -f $tmpltimg ]
if [ ! -f $tmpltimg -a ! -b $tmpltimg ]
then
printf "root disk file $tmpltimg doesn't exist\n"
exit 3

View File

@ -48,26 +48,79 @@ create_snapshot() {
local snapshotname=$2
local failed=0
if [ ! -f $disk ]
then
failed=1
printf "No disk $disk exist\n" >&2
return $failed
fi
if [ -b "${disk}" ] && lvm lvs "${disk}" >/dev/null 2>&1; then
local lv=$( lvm lvs --noheadings --unbuffered --separator=/ "${disk}" 2>/dev/null | sed 's|^[[:space:]]\+||' )
local lvname=$( echo "${lv}" | awk -F/ '{ print $1 }' )
local vgname=$( echo "${lv}" | awk -F/ '{ print $2 }' )
local lvdmname=$( echo "${lvname}" | sed 's|-|--|g' )
local vgdmname=$( echo "${vgname}" | sed 's|-|--|g' )
local blockdevname="/dev/mapper/${vgdmname}-${lvdmname}"
local blockdevsnap="/dev/mapper/${vgdmname}-${snapshotname}"
local blockdevsize=$( blockdev --getsz "${blockdevname}" )
$qemu_img snapshot -c $snapshotname $disk
lvm lvcreate --name "${snapshotname}-cow" --size "$(blockdev --getsize64 ${blockdevname})b" "${vgname}" >&2 || return 1
dmsetup suspend "${vgdmname}-${lvdmname}" >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
if dmsetup table | awk -v e=1 -v tbl="${vgdmname}-${lvdmname}-real:" '$1 == tbl { e=0 }; END { exit e }'; then
dmsetup create "${vgdmname}-${snapshotname}" --notable >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
if [ $? -gt 0 ]
then
failed=2
printf "***Failed to create snapshot $snapshotname for path $disk\n" >&2
$qemu_img snapshot -d $snapshotname $disk
echo "0 ${blockdevsize} snapshot ${blockdevname}-real ${blockdevsnap}--cow p 64" | \
dmsetup load "${vgdmname}-${snapshotname}" >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
if [ $? -gt 0 ]
then
printf "***Failed to delete snapshot $snapshotname for path $disk\n" >&2
fi
fi
dmsetup resume "${vgdmname}-${snapshotname}" >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
else
dmsetup create "${vgdmname}-${lvdmname}-real" --notable >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
dmsetup table "${vgdmname}-${lvdmname}" | dmsetup load "${vgdmname}-${lvdmname}-real" >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
dmsetup resume "${vgdmname}-${lvdmname}-real" >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
dmsetup create "${vgdmname}-${snapshotname}" --notable >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
echo "0 ${blockdevsize} snapshot ${blockdevname}-real ${blockdevsnap}--cow p 64" | \
dmsetup load "${vgdmname}-${snapshotname}" >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
echo "0 ${blockdevsize} snapshot-origin ${blockdevname}-real" | \
dmsetup load "${vgdmname}-${lvdmname}"
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
dmsetup resume "${vgdmname}-${snapshotname}" >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
fi
dmsetup resume "${vgdmname}-${lvdmname}" >&2
[ $? -ne 0 ] && destroy_snapshot "${disk}" "${snapshotname}" && return 1
elif [ -f "${disk}" ]; then
$qemu_img snapshot -c $snapshotname $disk
if [ $? -gt 0 ]
then
failed=2
printf "***Failed to create snapshot $snapshotname for path $disk\n" >&2
$qemu_img snapshot -d $snapshotname $disk
if [ $? -gt 0 ]
then
printf "***Failed to delete snapshot $snapshotname for path $disk\n" >&2
fi
fi
else
failed=3
printf "***Failed to create snapshot $snapshotname, undefined type $disk\n" >&2
fi
return $failed
}
@ -76,31 +129,34 @@ destroy_snapshot() {
local disk=$1
local snapshotname=$2
local failed=0
if [ -b ${disk} ]; then
local lvname=$( echo "${disk}" | awk -F/ '{ print $(NF) }' ) # '
local vgname=$( echo "${disk}" | awk -F/ '{ print $(NF-1) }' ) # '
local lvdmname=$( echo "${lvname}" | sed 's|-|--|g' )
local vgdmname=$( echo "${vgname}" | sed 's|-|--|g' )
if [ -d $disk ]
then
if [ -f $disk/$snapshotname ]
then
rm -rf $disk/$snapshotname >& /dev/null
if [ $( dmsetup --columns --noheadings --separator=: info "${vgdmname}-${lvdmname}-real" | awk -F: '{ print $5 }' ) -le 2 ]; then
dmsetup suspend "${vgdmname}-${lvdmname}" >&2
dmsetup table "${vgdmname}-${lvdmname}-real" | dmsetup load "${vgdmname}-${lvdmname}" >&2
dmsetup resume "${vgdmname}-${lvdmname}" >&2
dmsetup remove "${vgdmname}-${snapshotname}" >&2
dmsetup remove "${vgdmname}-${lvdmname}-real" >&2
else
dmsetup remove "${vgdmname}-${snapshotname}" >&2
fi
lvm lvremove -f "${vgname}/${snapshotname}-cow" >&2
return $failed
elif [ -f $disk ]; then
$qemu_img snapshot -d $snapshotname $disk
if [ $? -gt 0 ]
then
failed=2
printf "Failed to delete snapshot $snapshotname for path $disk\n" >&2
fi
else
failed=3
printf "***Failed to delete snapshot $snapshotname, undefined type $disk\n" >&2
fi
if [ ! -f $disk ]
then
failed=1
printf "No disk $disk exist\n" >&2
return $failed
fi
$qemu_img snapshot -d $snapshotname $disk
if [ $? -gt 0 ]
then
failed=2
printf "Failed to delete snapshot $snapshotname for path $disk\n" >&2
fi
return $failed
}
@ -135,19 +191,35 @@ backup_snapshot() {
fi
fi
# Does the snapshot exist?
$qemu_img snapshot -l $disk|grep -w "$snapshotname" >& /dev/null
if [ $? -gt 0 ]
then
printf "there is no $snapshotname on disk $disk" >&2
return 1
fi
if [ -b ${disk} ] && lvm lvs "${disk}" >/dev/null 2>&1; then
local lv=$( lvm lvs --noheadings --unbuffered --separator=/ "${disk}" 2>/dev/null | sed 's|^[[:space:]]\+||' )
local vgname=$( echo "${lv}" | awk -F/ '{ print $2 }' )
local vgdmname=$( echo "${vgname}" | sed 's|-|--|g' )
$qemu_img convert -f qcow2 -O qcow2 -s $snapshotname $disk $destPath/$destName >& /dev/null
if [ $? -gt 0 ]
then
printf "Failed to backup $snapshotname for disk $disk to $destPath" >&2
return 2
if [ -x "$( dirname $0 )/raw2qcow2.sh" ]; then
"$( dirname $0 )/raw2qcow2.sh" "/dev/mapper/${vgdmname}-${snapshotname}" "${destPath}/${destName}"
else
$qemu_img convert -f raw -O qcow2 "/dev/mapper/${vgdmname}-${snapshotname}" "${destPath}/${destName}"
fi
return 0
elif [ -f ${disk} ]; then
# Does the snapshot exist?
$qemu_img snapshot -l $disk|grep -w "$snapshotname" >& /dev/null
if [ $? -gt 0 ]
then
printf "there is no $snapshotname on disk $disk" >&2
return 1
fi
$qemu_img convert -f qcow2 -O qcow2 -s $snapshotname $disk $destPath/$destName >& /dev/null
if [ $? -gt 0 ]
then
printf "Failed to backup $snapshotname for disk $disk to $destPath" >&2
return 2
fi
else
printf "***Failed to backup snapshot $snapshotname, undefined type $disk\n" >&2
return 3
fi
return 0
}
@ -192,6 +264,7 @@ do
esac
done
[ -b "$pathval" ] && snapshot=`echo "${snapshot}" | md5sum -t | awk '{ print $1 }'`
if [ "$cflag" == "1" ]
then

View File

@ -37,7 +37,7 @@ mount_raw_disk() {
local vmname=$1
local datadisk=$2
local path=$(mntpath $vmname)
if [ ! -f $datadisk ]
if [ ! -f $datadisk -a ! -b $datadisk ]
then
printf "$datadisk doesn't exist" >&2
return 2
@ -46,9 +46,15 @@ mount_raw_disk() {
retry=10
while [ $retry -gt 0 ]
do
mount $datadisk $path -o loop &>/dev/null
if [ -b $datadisk ]; then
mount $datadisk $path &>/dev/null
ret=$?
else
mount $datadisk $path -o loop &>/dev/null
ret=$?
fi
sleep 10
if [ $? -gt 0 ]
if [ $ret -gt 0 ]
then
sleep 5
else

View File

@ -1156,6 +1156,11 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
if (uriPath == null) {
throw new InvalidParameterValueException("host or path is null, should be sharedmountpoint://localhost/path");
}
} else if (uri.getScheme().equalsIgnoreCase("clvm")) {
String uriPath = uri.getPath();
if (uriPath == null) {
throw new InvalidParameterValueException("host or path is null, should be clvm://localhost/path");
}
}
} catch (URISyntaxException e) {
throw new InvalidParameterValueException(cmd.getUrl() + " is not a valid uri");
@ -1197,6 +1202,8 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
pool = new StoragePoolVO(StoragePoolType.Filesystem, "localhost", 0, hostPath);
} else if (scheme.equalsIgnoreCase("sharedMountPoint")) {
pool = new StoragePoolVO(StoragePoolType.SharedMountPoint, storageHost, 0, hostPath);
} else if (scheme.equalsIgnoreCase("clvm")) {
pool = new StoragePoolVO(StoragePoolType.CLVM, storageHost, 0, hostPath.replaceFirst("/", ""));
} else if (scheme.equalsIgnoreCase("PreSetup")) {
pool = new StoragePoolVO(StoragePoolType.PreSetup, storageHost, 0, hostPath);
} else if (scheme.equalsIgnoreCase("iscsi")) {
@ -1256,7 +1263,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
long poolId = _storagePoolDao.getNextInSequence(Long.class, "id");
String uuid = null;
if (scheme.equalsIgnoreCase("sharedmountpoint")) {
if (scheme.equalsIgnoreCase("sharedmountpoint") || scheme.equalsIgnoreCase("clvm")) {
uuid = UUID.randomUUID().toString();
} else if (scheme.equalsIgnoreCase("PreSetup")) {
uuid = hostPath.replace("/", "");
@ -1480,7 +1487,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
s_logger.debug("creating pool " + pool.getName() + " on host " + hostId);
if (pool.getPoolType() != StoragePoolType.NetworkFilesystem && pool.getPoolType() != StoragePoolType.Filesystem && pool.getPoolType() != StoragePoolType.IscsiLUN
&& pool.getPoolType() != StoragePoolType.Iscsi && pool.getPoolType() != StoragePoolType.VMFS && pool.getPoolType() != StoragePoolType.SharedMountPoint
&& pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.OCFS2) {
&& pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.OCFS2 && pool.getPoolType() != StoragePoolType.CLVM) {
s_logger.warn(" Doesn't support storage pool type " + pool.getPoolType());
return false;
}

View File

@ -95,6 +95,7 @@
'label.SharedMountPoint': '<fmt:message key="label.SharedMountPoint"/>',
'label.PreSetup': '<fmt:message key="label.PreSetup"/>',
'label.iscsi': '<fmt:message key="label.iscsi"/>',
'label.clvm': '<fmt:message key="label.clvm"/>',
'label.VMFS.datastore': '<fmt:message key="label.VMFS.datastore"/>',
'label.theme.default': '<fmt:message key="label.theme.default"/>',
'label.none': '<fmt:message key="label.none"/>',

View File

@ -377,6 +377,13 @@ dictionary = {
<div id="add_pool_lun_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
</li>
<li id="add_pool_clvm_vg_container" style="display: none" input_group="clvm">
<label for="add_pool_clvm_vg">
<fmt:message key="label.volgroup"/>:</label>
<input class="text" type="text" name="add_pool_clvm_vg" id="add_pool_clvm_vg" />
<div id="add_pool_clvm_vg_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
</li>
<li input_group="vmfs">
<label for="add_pool_vmfs_dc">
<fmt:message key="label.vcenter.datacenter"/>:</label>

View File

@ -688,6 +688,13 @@ dictionary = {
<div id="add_pool_lun_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
</li>
<li id="add_pool_clvm_vg_container" style="display: none" input_group="clvm">
<label for="add_pool_clvm_vg">
<fmt:message key="label.volgroup"/>:</label>
<input class="text" type="text" name="add_pool_clvm_vg" id="add_pool_clvm_vg" />
<div id="add_pool_clvm_vg_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
</li>
<li input_group="vmfs">
<label for="add_pool_vmfs_dc">
<fmt:message key="label.vcenter.datacenter"/>:</label>

View File

@ -270,6 +270,13 @@ dictionary = {
<div id="add_pool_lun_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
</li>
<li id="add_pool_clvm_vg_container" style="display: none" input_group="clvm">
<label for="add_pool_clvm_vg">
<fmt:message key="label.volgroup"/>:</label>
<input class="text" type="text" name="add_pool_clvm_vg" id="add_pool_clvm_vg" />
<div id="add_pool_clvm_vg_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
</li>
<li input_group="vmfs">
<label for="add_pool_vmfs_dc">
<fmt:message key="label.vcenter.datacenter"/>:</label>

View File

@ -1096,6 +1096,13 @@
<div id="add_pool_lun_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
</li>
<li id="add_pool_clvm_vg_container" style="display: none" input_group="clvm">
<label for="add_pool_clvm_vg">
<fmt:message key="label.volgroup"/>:</label>
<input class="text" type="text" name="add_pool_clvm_vg" id="add_pool_clvm_vg" />
<div id="add_pool_clvm_vg_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
</li>
<li input_group="vmfs">
<label for="add_pool_vmfs_dc">
<fmt:message key="label.vcenter.datacenter"/>:</label>

View File

@ -675,6 +675,13 @@ dictionary = {
<div id="add_pool_lun_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
</li>
<li id="add_pool_clvm_vg_container" style="display: none" input_group="clvm">
<label for="add_pool_clvm_vg">
<fmt:message key="label.volgroup"/>:</label>
<input class="text" type="text" name="add_pool_clvm_vg" id="add_pool_clvm_vg" />
<div id="add_pool_clvm_vg_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
</li>
<li input_group="vmfs">
<label for="add_pool_vmfs_dc">
<fmt:message key="label.vcenter.datacenter"/>:</label>

View File

@ -814,6 +814,8 @@ function bindAddPrimaryStorageButton($leftmenuItem1) {
isValid &= validateString("Server", $thisDialog.find("#add_pool_nfs_server"), $thisDialog.find("#add_pool_nfs_server_errormsg"));
isValid &= validateString("Target IQN", $thisDialog.find("#add_pool_iqn"), $thisDialog.find("#add_pool_iqn_errormsg"));
isValid &= validateString("LUN #", $thisDialog.find("#add_pool_lun"), $thisDialog.find("#add_pool_lun_errormsg"));
} else if(protocol == "clvm") {
isValid &= validateString("Volume Group", $thisDialog.find("#add_pool_clvm_vg"), $thisDialog.find("#add_pool_clvm_vg_errormsg"));
} else if(protocol == "vmfs") {
isValid &= validateString("vCenter Datacenter", $thisDialog.find("#add_pool_vmfs_dc"), $thisDialog.find("#add_pool_vmfs_dc_errormsg"));
isValid &= validateString("vCenter Datastore", $thisDialog.find("#add_pool_vmfs_ds"), $thisDialog.find("#add_pool_vmfs_ds_errormsg"));
@ -861,6 +863,10 @@ function bindAddPrimaryStorageButton($leftmenuItem1) {
path = "/" + path;
url = SharedMountPointURL(server, path);
}
else if (protocol == "clvm") {
var vg = trim($thisDialog.find("#add_pool_clvm_vg").val());
url = clvmURL(vg);
}
else if (protocol == "vmfs") {
var path = trim($thisDialog.find("#add_pool_vmfs_dc").val());
if(path.substring(0,1)!="/")
@ -1129,6 +1135,15 @@ function SharedMountPointURL(server, path) {
return url;
}
function clvmURL(vgname) {
var url;
if(vgname.indexOf("://")==-1)
url = "clvm://localhost/" + vgname;
else
url = vgname;
return url;
}
function vmfsURL(server, path) {
var url;
if(server.indexOf("://")==-1)

View File

@ -1824,6 +1824,8 @@ function initAddPrimaryStorageShortcut($midmenuAddLink2, currentPageInRightPanel
isValid &= validateString("Server", $thisDialog.find("#add_pool_nfs_server"), $thisDialog.find("#add_pool_nfs_server_errormsg"));
isValid &= validateString("Target IQN", $thisDialog.find("#add_pool_iqn"), $thisDialog.find("#add_pool_iqn_errormsg"));
isValid &= validateString("LUN #", $thisDialog.find("#add_pool_lun"), $thisDialog.find("#add_pool_lun_errormsg"));
} else if(protocol == "clvm") {
isValid &= validateString("Volume Group", $thisDialog.find("#add_pool_clvm_vg"), $thisDialog.find("#add_pool_clvm_vg_errormsg"));
} else if(protocol == "vmfs") {
isValid &= validateString("vCenter Datacenter", $thisDialog.find("#add_pool_vmfs_dc"), $thisDialog.find("#add_pool_vmfs_dc_errormsg"));
isValid &= validateString("vCenter Datastore", $thisDialog.find("#add_pool_vmfs_ds"), $thisDialog.find("#add_pool_vmfs_ds_errormsg"));
@ -1880,6 +1882,10 @@ function initAddPrimaryStorageShortcut($midmenuAddLink2, currentPageInRightPanel
path = "/" + path;
url = SharedMountPointURL(server, path);
}
else if (protocol == "clvm") {
var vg = trim($thisDialog.find("#add_pool_clvm_vg").val());
url = clvmURL(vg);
}
else if(protocol == "vmfs") {
var path = trim($thisDialog.find("#add_pool_vmfs_dc").val());
if(path.substring(0,1)!="/")
@ -1951,6 +1957,7 @@ function bindEventHandlerToDialogAddPool($dialogAddPool) {
$protocolSelector.empty();
$protocolSelector.append('<option value="nfs">' + g_dictionary["label.nfs"] + '</option>');
$protocolSelector.append('<option value="SharedMountPoint">' + g_dictionary["label.SharedMountPoint"] + '</option>');
$protocolSelector.append('<option value="clvm">' + g_dictionary["label.clvm"] + '</option>');
}
else if(clusterObj.hypervisortype == "XenServer") {
$protocolSelector.empty();
@ -1980,6 +1987,7 @@ function bindEventHandlerToDialogAddPool($dialogAddPool) {
$("#add_pool_server_container", $dialogAddPool).show();
$('li[input_group="nfs"]', $dialogAddPool).show();
$('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_path_container").find("label").text(g_dictionary["label.path"]+":");
@ -1999,6 +2007,7 @@ function bindEventHandlerToDialogAddPool($dialogAddPool) {
$("#add_pool_server_container", $dialogAddPool).show();
$('li[input_group="nfs"]', $dialogAddPool).show();
$('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_path_container").find("label").text(g_dictionary["label.SR.name"]+":");
@ -2009,15 +2018,27 @@ function bindEventHandlerToDialogAddPool($dialogAddPool) {
$("#add_pool_server_container", $dialogAddPool).show();
$('li[input_group="nfs"]', $dialogAddPool).hide();
$('li[input_group="iscsi"]', $dialogAddPool).show();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_nfs_server").val("");
$dialogAddPool.find("#add_pool_server_container").show();
}
else if($(this).val() == "clvm") {
$("#add_pool_server_container", $dialogAddPool).hide();
$('li[input_group="nfs"]', $dialogAddPool).hide();
$('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).show();
$('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_nfs_server").val("localhost");
$dialogAddPool.find("#add_pool_server_container").hide()
}
else if($(this).val() == "vmfs") {
$("#add_pool_server_container", $dialogAddPool).hide();
$('li[input_group="nfs"]', $dialogAddPool).hide();
$('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).show();
$dialogAddPool.find("#add_pool_nfs_server").val("");
@ -2027,6 +2048,7 @@ function bindEventHandlerToDialogAddPool($dialogAddPool) {
$("#add_pool_server_container", $dialogAddPool).show();
$('li[input_group="nfs"]', $dialogAddPool).show();
$('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_nfs_server").val("localhost");
@ -2036,6 +2058,7 @@ function bindEventHandlerToDialogAddPool($dialogAddPool) {
//$("#add_pool_server_container", $dialogAddPool).hide();
//$('li[input_group="nfs"]', $dialogAddPool).hide();
$('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_nfs_server").val("");

View File

@ -991,6 +991,8 @@ function bindAddPrimaryStorageButtonOnZonePage($button, zoneId, zoneName) {
isValid &= validateString("Server", $thisDialog.find("#add_pool_nfs_server"), $thisDialog.find("#add_pool_nfs_server_errormsg"));
isValid &= validateString("Target IQN", $thisDialog.find("#add_pool_iqn"), $thisDialog.find("#add_pool_iqn_errormsg"));
isValid &= validateString("LUN #", $thisDialog.find("#add_pool_lun"), $thisDialog.find("#add_pool_lun_errormsg"));
} else if(protocol == "clvm") {
isValid &= validateString("Volume Group", $thisDialog.find("#add_pool_clvm_vg"), $thisDialog.find("#add_pool_clvm_vg_errormsg"));
} else if(protocol == "vmfs") {
isValid &= validateString("vCenter Datacenter", $thisDialog.find("#add_pool_vmfs_dc"), $thisDialog.find("#add_pool_vmfs_dc_errormsg"));
isValid &= validateString("vCenter Datastore", $thisDialog.find("#add_pool_vmfs_ds"), $thisDialog.find("#add_pool_vmfs_ds_errormsg"));
@ -1046,6 +1048,10 @@ function bindAddPrimaryStorageButtonOnZonePage($button, zoneId, zoneName) {
path = "/" + path;
url = SharedMountPointURL(server, path);
}
else if (protocol == "clvm") {
var vg = trim($thisDialog.find("#add_pool_clvm_vg").val());
url = clvmURL(vg);
}
else if (protocol == "vmfs") {
var path = trim($thisDialog.find("#add_pool_vmfs_dc").val());
if(path.substring(0,1)!="/")