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); 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); MockSecStorageVO secStorage = _mockSecStorageDao.findByUrl(secStorageUrl);
if (secStorage == null) { if (secStorage == null) {
return new BackupSnapshotAnswer(cmd, false, "can't find sec storage" + snapshotPath, null, true); 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) { if (sec == null) {
return new CreatePrivateTemplateAnswer(cmd, false, "can't find secondary storage"); 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()); 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) { if (sec == null) {
return new CreatePrivateTemplateAnswer(cmd, false, "can't find secondary storage"); 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 // Attach each data volume to the VM, if there is a deferred attached disk
for (DiskDef disk : vm.getDevices().getDisks()) { for (DiskDef disk : vm.getDevices().getDisks()) {
if (disk.isAttachDeferred()) { 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.computing.LibvirtVMDef.TermPolicy;
import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
import com.cloud.agent.storage.KVMPhysicalDisk; import com.cloud.agent.storage.KVMPhysicalDisk;
import com.cloud.agent.storage.KVMPhysicalDisk.PhysicalDiskFormat;
import com.cloud.agent.storage.KVMStoragePool; import com.cloud.agent.storage.KVMStoragePool;
import com.cloud.agent.storage.KVMStoragePoolManager; import com.cloud.agent.storage.KVMStoragePoolManager;
import com.cloud.agent.storage.LibvirtStorageAdaptor; 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;
import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.VirtualMachineName; 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 _createTmplPath;
private String _heartBeatPath; private String _heartBeatPath;
private String _securityGroupPath; private String _securityGroupPath;
private String _networkUsagePath;
private String _host; private String _host;
private String _dcId; private String _dcId;
private String _pod; private String _pod;
@ -521,6 +524,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
throw new ConfigurationException("Unable to find the security_group.py"); 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"); String value = (String)params.get("developer");
boolean isDeveloper = Boolean.parseBoolean(value); boolean isDeveloper = Boolean.parseBoolean(value);
@ -942,6 +950,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
String volumePath = cmd.getVolumePath(); String volumePath = cmd.getVolumePath();
StorageFilerTO pool = cmd.getPool(); StorageFilerTO pool = cmd.getPool();
String secondaryStorageUrl = cmd.getSecondaryStorageURL(); String secondaryStorageUrl = cmd.getSecondaryStorageURL();
KVMStoragePool secondaryStoragePool = null;
try { try {
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(pool.getUuid()); KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(pool.getUuid());
String volumeName = UUID.randomUUID().toString(); String volumeName = UUID.randomUUID().toString();
@ -949,18 +958,22 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
if (copyToSecondary) { if (copyToSecondary) {
KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(cmd.getVolumePath()); KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(cmd.getVolumePath());
String volumeDestPath = "/volumes/" + cmd.getVolumeId() + File.separator; String volumeDestPath = "/volumes/" + cmd.getVolumeId() + File.separator;
KVMStoragePool secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumeDestPath); secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumeDestPath);
_storagePoolMgr.copyPhysicalDisk(volume, volumeName, secondaryStoragePool); _storagePoolMgr.copyPhysicalDisk(volume, volumeName, secondaryStoragePool);
return new CopyVolumeAnswer(cmd, true, null, null, volumeName); return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
} else { } else {
volumePath = "/volumes/" + cmd.getVolumeId() + File.separator + volumePath; volumePath = "/volumes/" + cmd.getVolumeId() + File.separator + volumePath;
KVMStoragePool secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumePath); secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumePath);
KVMPhysicalDisk volume = secondaryStoragePool.getPhysicalDisk(cmd.getVolumePath()); KVMPhysicalDisk volume = secondaryStoragePool.getPhysicalDisk(cmd.getVolumePath());
_storagePoolMgr.copyPhysicalDisk(volume, volumeName, primaryPool); _storagePoolMgr.copyPhysicalDisk(volume, volumeName, primaryPool);
return new CopyVolumeAnswer(cmd, true, null, null, volumeName); return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
} }
} catch (CloudRuntimeException e) { } catch (CloudRuntimeException e) {
return new CopyVolumeAnswer(cmd, false, e.toString(), null, null); 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 { try {
KVMStoragePool pool = _storagePoolMgr.getStoragePool(vol.getPoolUuid()); KVMStoragePool pool = _storagePoolMgr.getStoragePool(vol.getPoolUuid());
pool.deletePhysicalDisk(vol.getName()); pool.deletePhysicalDisk(vol.getPath());
return new Answer(cmd, true, "Success"); return new Answer(cmd, true, "Success");
} catch (CloudRuntimeException e) { } catch (CloudRuntimeException e) {
@ -1112,6 +1125,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
vlanAllocatedToVM.put(ip.getVlanId(), nicPos++); vlanAllocatedToVM.put(ip.getVlanId(), nicPos++);
} }
nicNum = vlanAllocatedToVM.get(ip.getVlanId()); nicNum = vlanAllocatedToVM.get(ip.getVlanId());
networkUsage(routerIp, "addVif", "eth" + nicNum);
result = _virtRouterResource.assignPublicIpAddress(routerName, routerIp, ip.getPublicIp(), ip.isAdd(), result = _virtRouterResource.assignPublicIpAddress(routerName, routerIp, ip.getPublicIp(), ip.isAdd(),
ip.isFirstIP(), ip.isSourceNat(), ip.isFirstIP(), ip.isSourceNat(),
ip.getVlanId(), ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVlanId(), ip.getVlanGateway(), ip.getVlanNetmask(),
@ -1125,15 +1139,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
} }
return new IpAssocAnswer(cmd, results); return new IpAssocAnswer(cmd, results);
} catch (LibvirtException e) { } catch (LibvirtException e) {
return new ManageSnapshotAnswer(cmd, false, e.toString()); return new IpAssocAnswer(cmd, results);
} catch (InternalErrorException e) { } catch (InternalErrorException e) {
return new ManageSnapshotAnswer(cmd, false, e.toString()); return new IpAssocAnswer(cmd, results);
} }
} }
protected ManageSnapshotAnswer execute(final ManageSnapshotCommand cmd) { protected ManageSnapshotAnswer execute(final ManageSnapshotCommand cmd) {
String snapshotName = cmd.getSnapshotName(); String snapshotName = cmd.getSnapshotName();
String VolPath = cmd.getVolumePath();
String snapshotPath = cmd.getSnapshotPath(); String snapshotPath = cmd.getSnapshotPath();
String vmName = cmd.getVmName(); String vmName = cmd.getVmName();
try { try {
@ -1150,6 +1163,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
} }
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getUuid()); KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getUuid());
KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(cmd.getVolumePath());
if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) { if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) {
String vmUuid = vm.getUUIDString(); String vmUuid = vm.getUUIDString();
Object[] args = new Object[] {snapshotName, vmUuid}; Object[] args = new Object[] {snapshotName, vmUuid};
@ -1169,10 +1183,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
vm.resume(); vm.resume();
} }
} else { } else {
/*VM is not running, create a snapshot by ourself*/ /*VM is not running, create a snapshot by ourself*/
final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) { if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
command.add("-c", VolPath); command.add("-c", disk.getPath());
} else { } else {
command.add("-d", snapshotPath); 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, false, "Failed to manage snapshot: " + result);
} }
} }
return new ManageSnapshotAnswer(cmd, cmd.getSnapshotId(), disk.getPath() + File.separator + snapshotName, true, null);
} catch (LibvirtException e) { } catch (LibvirtException e) {
s_logger.debug("Failed to manage snapshot: " + e.toString()); s_logger.debug("Failed to manage snapshot: " + e.toString());
return new ManageSnapshotAnswer(cmd, false, "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) { protected BackupSnapshotAnswer execute(final BackupSnapshotCommand cmd) {
@ -1201,81 +1217,85 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
String snapshotDestPath = null; String snapshotDestPath = null;
String snapshotRelPath = null; String snapshotRelPath = null;
String vmName = cmd.getVmName(); String vmName = cmd.getVmName();
KVMStoragePool secondaryStoragePool = null;
try { try {
Connect conn = LibvirtConnection.getConnection(); 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;
snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId; String ssPmountPath = secondaryStoragePool.getLocalPath();
Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); snapshotRelPath = File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
command.add("-b", snapshotPath);
command.add("-n", snapshotName); snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
command.add("-p", snapshotDestPath); KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPrimaryStoragePoolNameLabel());
command.add("-t", snapshotName); KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(cmd.getVolumePath());
String result = command.execute(); Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
if (result != null) { command.add("-b", snapshotDisk.getPath());
s_logger.debug("Failed to backup snaptshot: " + result); command.add("-n", snapshotName);
return new BackupSnapshotAnswer(cmd, false, result, null, true); command.add("-p", snapshotDestPath);
} command.add("-t", snapshotName);
/*Delete the snapshot on primary*/ String result = command.execute();
if (result != null) {
DomainInfo.DomainState state = null; s_logger.debug("Failed to backup snaptshot: " + result);
Domain vm = null; return new BackupSnapshotAnswer(cmd, false, result, null, true);
if (vmName != null) { }
try { /*Delete the snapshot on primary*/
vm = getDomain(conn, cmd.getVmName());
state = vm.getInfo().state; DomainInfo.DomainState state = null;
} catch (LibvirtException e) { Domain vm = null;
if (vmName != null) {
} try {
} vm = getDomain(conn, cmd.getVmName());
state = vm.getInfo().state;
KVMStoragePool primaryStorage = _storagePoolMgr.getStoragePool(cmd.getPool().getUuid()); } catch (LibvirtException e) {
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); KVMStoragePool primaryStorage = _storagePoolMgr.getStoragePool(cmd.getPool().getUuid());
DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) {
snap.delete(0); String vmUuid = vm.getUUIDString();
Object[] args = new Object[] {snapshotName, vmUuid};
/*libvirt on RHEL6 doesn't handle resume event emitted from qemu*/ String snapshot = SnapshotXML.format(args);
vm = getDomain(conn, cmd.getVmName()); s_logger.debug(snapshot);
state = vm.getInfo().state; DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) { snap.delete(0);
vm.resume();
} /*libvirt on RHEL6 doesn't handle resume event emitted from qemu*/
} else { vm = getDomain(conn, cmd.getVmName());
command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); state = vm.getInfo().state;
command.add("-d", snapshotPath); if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
command.add("-n", snapshotName); vm.resume();
result = command.execute(); }
if (result != null) { } else {
s_logger.debug("Failed to backup snapshot: " + result); command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
return new BackupSnapshotAnswer(cmd, false, "Failed to backup snapshot: " + result, null, true); command.add("-d", snapshotDisk.getPath());
} command.add("-n", snapshotName);
} result = command.execute();
} catch (LibvirtException e) { if (result != null) {
return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true); s_logger.debug("Failed to backup snapshot: " + result);
} catch (CloudRuntimeException e) { return new BackupSnapshotAnswer(cmd, false, "Failed to backup snapshot: " + result, null, true);
return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true); }
} }
return new BackupSnapshotAnswer(cmd, true, null, snapshotRelPath + File.separator + snapshotName, 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) { protected DeleteSnapshotBackupAnswer execute(final DeleteSnapshotBackupCommand cmd) {
Long dcId = cmd.getDataCenterId(); Long dcId = cmd.getDataCenterId();
Long accountId = cmd.getAccountId(); Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId(); Long volumeId = cmd.getVolumeId();
KVMStoragePool secondaryStoragePool = null;
try { try {
KVMStoragePool secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl()); secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl());
String ssPmountPath = secondaryStoragePool.getLocalPath(); String ssPmountPath = secondaryStoragePool.getLocalPath();
String snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId; 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(); command.execute();
} catch (CloudRuntimeException e) { } catch (CloudRuntimeException e) {
return new DeleteSnapshotBackupAnswer(cmd, false, e.toString()); return new DeleteSnapshotBackupAnswer(cmd, false, e.toString());
} finally {
if (secondaryStoragePool != null) {
secondaryStoragePool.delete();
}
} }
return new DeleteSnapshotBackupAnswer(cmd, true, null); return new DeleteSnapshotBackupAnswer(cmd, true, null);
} }
@ -1295,8 +1319,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
Long dcId = cmd.getDcId(); Long dcId = cmd.getDcId();
Long accountId = cmd.getAccountId(); Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId(); Long volumeId = cmd.getVolumeId();
KVMStoragePool secondaryStoragePool = null;
try { try {
KVMStoragePool secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl()); secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl());
String ssPmountPath = secondaryStoragePool.getLocalPath(); String ssPmountPath = secondaryStoragePool.getLocalPath();
String snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId; 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(); command.execute();
} catch (CloudRuntimeException e) { } catch (CloudRuntimeException e) {
return new Answer(cmd, false, e.toString()); return new Answer(cmd, false, e.toString());
} finally {
if (secondaryStoragePool != null) {
secondaryStoragePool.delete();
}
} }
return new Answer(cmd, true, null); return new Answer(cmd, true, null);
} }
@ -1323,8 +1353,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
String primaryUuid = cmd.getPrimaryStoragePoolNameLabel(); String primaryUuid = cmd.getPrimaryStoragePoolNameLabel();
KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(primaryUuid); KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(primaryUuid);
String volUuid = UUID.randomUUID().toString(); String volUuid = UUID.randomUUID().toString();
KVMPhysicalDisk disk = _storagePoolMgr.createDiskFromSnapshot(snapshot, cmd.getSnapshotName(), volUuid, primaryPool); KVMPhysicalDisk disk = _storagePoolMgr.copyPhysicalDisk(snapshot, volUuid, primaryPool);
return new CreateVolumeFromSnapshotAnswer(cmd, true, "", disk.getPath()); return new CreateVolumeFromSnapshotAnswer(cmd, true, "", disk.getName());
} catch (CloudRuntimeException e) { } catch (CloudRuntimeException e) {
return new CreateVolumeFromSnapshotAnswer(cmd, false, e.toString(), null); return new CreateVolumeFromSnapshotAnswer(cmd, false, e.toString(), null);
} }
@ -1339,24 +1369,28 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromSnapshotCommand cmd) { protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromSnapshotCommand cmd) {
String templateFolder = cmd.getAccountId() + File.separator + cmd.getNewTemplateId(); String templateFolder = cmd.getAccountId() + File.separator + cmd.getNewTemplateId();
String templateInstallFolder = "template/tmpl/" + templateFolder; String templateInstallFolder = "template/tmpl/" + templateFolder;
String snapshotPath = cmd.getSnapshotUuid();
String tmplName = UUID.randomUUID().toString(); String tmplName = UUID.randomUUID().toString();
String tmplFileName = tmplName + ".qcow2"; String tmplFileName = tmplName + ".qcow2";
KVMStoragePool secondaryPool; KVMStoragePool secondaryPool = null;
KVMStoragePool snapshotPool = null;
try { 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()); secondaryPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl());
String templatePath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; String templatePath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder;
_storage.mkdirs(templatePath); _storage.mkdirs(templatePath);
String tmplPath = templateInstallFolder + File.separator + tmplFileName; String tmplPath = templateInstallFolder + File.separator + tmplFileName;
Script command = new Script(_createTmplPath, _timeout, s_logger); Script command = new Script(_createTmplPath, _timeout, s_logger);
command.add("-t", templatePath); command.add("-t", templatePath);
command.add("-n", tmplFileName); command.add("-n", tmplFileName);
command.add("-f", snapshotPath); command.add("-f", snapshot.getPath());
command.execute(); command.execute();
Map<String, Object> params = new HashMap<String, Object>(); 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()); return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
} catch (CloudRuntimeException e) { } catch (CloudRuntimeException e) {
return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); 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); secondaryStorage = _storagePoolMgr.getStoragePoolByURI(secondaryStorageURL);
KVMStoragePool primary = _storagePoolMgr.getStoragePool(cmd.getPrimaryStoragePoolNameLabel());
KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath());
String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateInstallFolder; String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateInstallFolder;
_storage.mkdirs(tmpltPath); _storage.mkdirs(tmpltPath);
Script command = new Script(_createTmplPath, _timeout, s_logger); Script command = new Script(_createTmplPath, _timeout, s_logger);
command.add("-f", cmd.getVolumePath()); command.add("-f", disk.getPath());
command.add("-t", tmpltPath); command.add("-t", tmpltPath);
command.add("-n", cmd.getUniqueName() + ".qcow2"); command.add("-n", cmd.getUniqueName() + ".qcow2");
@ -1451,6 +1493,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); return new CreatePrivateTemplateAnswer(cmd, false, e.toString());
} catch (CloudRuntimeException e) { } catch (CloudRuntimeException e) {
return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); 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; KVMPhysicalDisk tmplVol = null;
KVMStoragePool secondaryPool = null;
try { try {
KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(mountpoint); secondaryPool = _storagePoolMgr.getStoragePoolByURI(mountpoint);
/*Get template vol*/ /*Get template vol*/
if (tmpltname == null) { if (tmpltname == null) {
@ -1484,6 +1530,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
if (tmplVol == null) { if (tmplVol == null) {
return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid()); return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid());
} }
} else {
tmplVol = secondaryPool.getPhysicalDisk(tmpltname);
} }
/*Copy volume to primary storage*/ /*Copy volume to primary storage*/
@ -1494,6 +1542,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new PrimaryStorageDownloadAnswer(primaryVol.getName(), primaryVol.getSize()); return new PrimaryStorageDownloadAnswer(primaryVol.getName(), primaryVol.getSize());
} catch (CloudRuntimeException e) { } catch (CloudRuntimeException e) {
return new PrimaryStorageDownloadAnswer(e.toString()); 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) { private AttachVolumeAnswer execute(AttachVolumeCommand cmd) {
try { try {
Connect conn = LibvirtConnection.getConnection(); 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) { } catch (LibvirtException e) {
return new AttachVolumeAnswer(cmd, e.toString()); return new AttachVolumeAnswer(cmd, e.toString());
} catch (InternalErrorException e) { } catch (InternalErrorException e) {
@ -1885,26 +1939,54 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new GetHostStatsAnswer(cmd, hostStats); return new GetHostStatsAnswer(cmd, hostStats);
} }
private Answer execute(NetworkUsageCommand cmd) { protected String networkUsage(final String privateIpAddress, final String option, final String vif) {
String vmName = cmd.getDomRName(); Script getUsage = new Script(_networkUsagePath, s_logger);
try { if (option.equals("get")) {
Connect conn = LibvirtConnection.getConnection(); getUsage.add("-g");
Domain dm = getDomain(conn, vmName); } else if (option.equals("create")) {
LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); getUsage.add("-c");
String xml = dm.getXMLDesc(0); } else if (option.equals("reset")) {
parser.parseDomainXML(xml); getUsage.add("-r");
List<InterfaceDef> nics = parser.getInterfaces(); } else if (option.equals("addVif")) {
if (nics.size() != 3) { getUsage.add("-a", vif);
return new Answer(cmd, false, vmName + " doesn't have public nic"); } 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) { private Answer execute(RebootCommand cmd) {
Long bytesReceived = null; Long bytesReceived = null;
@ -1939,9 +2021,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
} }
protected Answer execute(RebootRouterCommand cmd) { 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); RebootAnswer answer = (RebootAnswer) execute((RebootCommand) cmd);
answer.setBytesSent(bytesSent);
answer.setBytesReceived(bytesRcvd);
String result = _virtRouterResource.connect(cmd.getPrivateIpAddress()); String result = _virtRouterResource.connect(cmd.getPrivateIpAddress());
if (result == null) { if (result == null) {
networkUsage(cmd.getPrivateIpAddress(), "create", null);
return answer; return answer;
} else { } else {
return new Answer(cmd, false, result); 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 // Attach each data volume to the VM, if there is a deferred attached disk
for (DiskDef disk : vm.getDevices().getDisks()) { for (DiskDef disk : vm.getDevices().getDisks()) {
if (disk.isAttachDeferred()) { 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); String volName = volPath.substring(index + 1);
KVMStoragePool secondaryStorage = _storagePoolMgr.getStoragePoolByURI(volDir); KVMStoragePool secondaryStorage = _storagePoolMgr.getStoragePoolByURI(volDir);
physicalDisk = secondaryStorage.getPhysicalDisk(volName); physicalDisk = secondaryStorage.getPhysicalDisk(volName);
} else { } else if (volume.getType() != Volume.Type.ISO) {
pool = _storagePoolMgr.getStoragePool(volume.getPoolUuid()); pool = _storagePoolMgr.getStoragePool(volume.getPoolUuid());
physicalDisk = pool.getPhysicalDisk(volume.getPath()); 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.diskBus diskBusType = getGuestDiskModel(vmSpec.getOs());
DiskDef disk = new DiskDef(); DiskDef disk = new DiskDef();
@ -2416,10 +2511,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return attachOrDetachDevice(conn, true, vmName, isoXml); 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; List<DiskDef> disks = null;
Domain dm = null; Domain dm = null;
int deviceId = devId; DiskDef diskdef = null;
try { try {
if (!attach) { if (!attach) {
dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName.getBytes())); dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName.getBytes()));
@ -2428,24 +2523,26 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
parser.parseDomainXML(xml); parser.parseDomainXML(xml);
disks = parser.getDisks(); disks = parser.getDisks();
boolean diskAttached = false;
for (DiskDef disk : disks) { for (DiskDef disk : disks) {
String file = disk.getDiskPath(); String file = disk.getDiskPath();
if (file != null && file.equalsIgnoreCase(sourceFile)) { if (file != null && file.equalsIgnoreCase(attachingDisk.getPath())) {
deviceId = disk.getDiskSeq(); diskdef = disk;
diskAttached = true;
break; break;
} }
} }
if (!diskAttached) { if (diskdef == null) {
throw new InternalErrorException("disk: " + sourceFile + " is not attached before"); 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(); String xml = diskdef.toString();
disk.defFileBasedDisk(sourceFile, deviceId, DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2);
String xml = disk.toString();
return attachOrDetachDevice(conn, attach, vmName, xml); return attachOrDetachDevice(conn, attach, vmName, xml);
} finally { } finally {
if (dm != null) { 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; Domain dm = null;
try { try {
dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes((vmName.getBytes()))); dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes((vmName.getBytes())));

View File

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

View File

@ -31,6 +31,18 @@ public class LibvirtStorageVolumeDef {
public String toString() { public String toString() {
return _format; 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 String _volName;
private Long _volSize; private Long _volSize;

View File

@ -32,7 +32,7 @@ public class LibvirtStorageVolumeXMLParser{
Element target = (Element)rootElement.getElementsByTagName("target").item(0); Element target = (Element)rootElement.getElementsByTagName("target").item(0);
String format = getAttrValue("type", "format", target); String format = getAttrValue("type", "format", target);
Long capacity = Long.parseLong(getTagValue("capacity", rootElement)); 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) { } catch (ParserConfigurationException e) {
s_logger.debug(e.toString()); s_logger.debug(e.toString());
} catch (SAXException e) { } catch (SAXException e) {

View File

@ -345,6 +345,14 @@ public class LibvirtVMDef {
_diskLabel = getDevLabel(devId, bus); _diskLabel = getDevLabel(devId, bus);
_bus = 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() { public void setReadonly() {
_readonly = true; _readonly = true;
} }

View File

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

View File

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

View File

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

View File

@ -23,10 +23,7 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.libvirt.Connect; import org.libvirt.Connect;
import org.libvirt.LibvirtException; import org.libvirt.LibvirtException;
@ -35,27 +32,17 @@ import org.libvirt.StoragePoolInfo;
import org.libvirt.StorageVol; import org.libvirt.StorageVol;
import org.libvirt.StoragePoolInfo.StoragePoolState; import org.libvirt.StoragePoolInfo.StoragePoolState;
import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.ManageSnapshotCommand;
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.resource.computing.LibvirtConnection; import com.cloud.agent.resource.computing.LibvirtConnection;
import com.cloud.agent.resource.computing.LibvirtStoragePoolDef; import com.cloud.agent.resource.computing.LibvirtStoragePoolDef;
import com.cloud.agent.resource.computing.LibvirtStoragePoolXMLParser; import com.cloud.agent.resource.computing.LibvirtStoragePoolXMLParser;
import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef; 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.LibvirtStoragePoolDef.poolType;
import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef.volFormat; import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef.volFormat;
import com.cloud.agent.resource.computing.LibvirtStorageVolumeXMLParser; import com.cloud.agent.resource.computing.LibvirtStorageVolumeXMLParser;
import com.cloud.agent.storage.KVMPhysicalDisk.PhysicalDiskFormat; import com.cloud.agent.storage.KVMPhysicalDisk.PhysicalDiskFormat;
import com.cloud.exception.InternalErrorException; import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Storage;
import com.cloud.storage.StorageLayer; import com.cloud.storage.StorageLayer;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.OutputInterpreter; 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 static final Logger s_logger = Logger.getLogger(LibvirtStorageAdaptor.class);
private StorageLayer _storageLayer; private StorageLayer _storageLayer;
private String _mountPoint = "/mnt"; private String _mountPoint = "/mnt";
private String _manageSnapshotPath;
public LibvirtStorageAdaptor(StorageLayer storage public LibvirtStorageAdaptor(StorageLayer storage
) { ) {
_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 { public StorageVol copyVolume(StoragePool destPool, LibvirtStorageVolumeDef destVol, StorageVol srcVol, int timeout) throws LibvirtException {
StorageVol vol = destPool.storageVolCreateXML(destVol.toString(), 0); StorageVol vol = destPool.storageVolCreateXML(destVol.toString(), 0);
String srcPath = srcVol.getKey(); String srcPath = srcVol.getKey();
@ -405,7 +419,9 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool); disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool);
disk.setSize(vol.getInfo().allocation); disk.setSize(vol.getInfo().allocation);
disk.setVirtualSize(vol.getInfo().capacity); 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); disk.setFormat(KVMPhysicalDisk.PhysicalDiskFormat.QCOW2);
} else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.RAW) { } else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.RAW) {
disk.setFormat(KVMPhysicalDisk.PhysicalDiskFormat.RAW); disk.setFormat(KVMPhysicalDisk.PhysicalDiskFormat.RAW);
@ -416,6 +432,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
} }
} }
@Override @Override
public KVMStoragePool createStoragePool(String name, String host, String path, StoragePoolType type) { public KVMStoragePool createStoragePool(String name, String host, String path, StoragePoolType type) {
StoragePool sp = null; StoragePool sp = null;
@ -437,6 +454,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
sp = createNfsStoragePool(conn, name, host, path); sp = createNfsStoragePool(conn, name, host, path);
} else if (type == StoragePoolType.SharedMountPoint || type == StoragePoolType.Filesystem) { } else if (type == StoragePoolType.SharedMountPoint || type == StoragePoolType.Filesystem) {
sp = CreateSharedStoragePool(conn, name, host, path); 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()); KVMPhysicalDisk disk = destPool.createPhysicalDisk(UUID.randomUUID().toString(), format, template.getVirtualSize());
if (format == PhysicalDiskFormat.QCOW2) { if (format == PhysicalDiskFormat.QCOW2) {
Script.runSimpleBashScript("qemu-img create -f qcow2 -b " + template.getPath() + " " + disk.getPath()); Script.runSimpleBashScript("qemu-img create -f " + template.getFormat() + " -b " + template.getPath() + " " + disk.getPath());
} else { } else if (format == PhysicalDiskFormat.RAW) {
Script.runSimpleBashScript("cp " + template.getPath() + " " + disk.getPath()); Script.runSimpleBashScript("qemu-img convert -f " + template.getFormat()+ " -O raw " + template.getPath() + " " + disk.getPath());
} }
return disk; return disk;
} }
@Override @Override
public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk, public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk, String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool) {
String name, PhysicalDiskFormat format, long size,
KVMStoragePool destPool) {
// TODO Auto-generated method stub
return null; return null;
} }
@ -572,7 +588,9 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
KVMPhysicalDisk newDisk = destPool.createPhysicalDisk(name, disk.getVirtualSize()); KVMPhysicalDisk newDisk = destPool.createPhysicalDisk(name, disk.getVirtualSize());
String sourcePath = disk.getPath(); String sourcePath = disk.getPath();
String destPath = newDisk.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; return newDisk;
} }
@ -594,7 +612,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
sourcePath = storageUri.getPath(); sourcePath = storageUri.getPath();
sourcePath = sourcePath.replace("//", "/"); sourcePath = sourcePath.replace("//", "/");
sourceHost = storageUri.getHost(); sourceHost = storageUri.getHost();
uuid = UUID.nameUUIDFromBytes(new String(sourceHost + sourcePath).getBytes()).toString(); uuid = UUID.randomUUID().toString();
protocal = StoragePoolType.NetworkFilesystem; protocal = StoragePoolType.NetworkFilesystem;
} }
@ -610,7 +628,6 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
@Override @Override
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot,
String snapshotName, String name, KVMStoragePool destPool) { String snapshotName, String name, KVMStoragePool destPool) {
// TODO Auto-generated method stub
return null; return null;
} }
@ -625,6 +642,21 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
} }
return true; return true;
} }
@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; return this.uri;
} }
@Override
public PhysicalDiskFormat getDefaultFormat() { public PhysicalDiskFormat getDefaultFormat() {
if (getStoragePoolType() == StoragePoolType.CLVM) { if (getStoragePoolType() == StoragePoolType.CLVM) {
return PhysicalDiskFormat.RAW; return PhysicalDiskFormat.RAW;
@ -128,4 +129,9 @@ public class LibvirtStoragePool implements KVMStoragePool {
public StoragePool getPool() { public StoragePool getPool() {
return this._pool; 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 KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool);
public KVMStoragePool getStoragePoolByUri(String uri); public KVMStoragePool getStoragePoolByUri(String uri);
public KVMPhysicalDisk getPhysicalDiskFromURI(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.PreSetup=PreSetup
label.SR.name = SR Name-Label label.SR.name = SR Name-Label
label.SharedMountPoint=SharedMountPoint label.SharedMountPoint=SharedMountPoint
label.clvm=CLVM
label.volgroup=Volume Group
label.VMFS.datastore=VMFS datastore label.VMFS.datastore=VMFS datastore
label.network.device=Network Device 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.PreSetup=PreSetup
label.SR.name = SR Nombre de etiqueta label.SR.name = SR Nombre de etiqueta
label.SharedMountPoint = SharedMountPoint label.SharedMountPoint = SharedMountPoint
label.clvm=CLVM
label.volgroup=Volume Group
label.VMFS.datastore=VMFS de datos tienda label.VMFS.datastore=VMFS de datos tienda
label.network.device=De dispositivos de red label.network.device=De dispositivos de red
@ -856,4 +858,4 @@ error.login = Su nombre de usuario / contraseña no coincide con nuestros regist
error.menu.select = No se puede realizar la acción debido a que no los artículos que son seleccionados. error.menu.select = No se puede realizar la acción debido a que no los artículos que son seleccionados.
error.mgmt.server.inaccessible = El Servidor de Gestión es inaccesible. Por favor, inténtelo de nuevo más tarde. error.mgmt.server.inaccessible = El Servidor de Gestión es inaccesible. Por favor, inténtelo de nuevo más tarde.
error.session.expired = Su sesión ha caducado. error.session.expired = Su sesión ha caducado.
error.unresolved.internet.name = El nombre de Internet no se puede resolver. error.unresolved.internet.name = El nombre de Internet no se puede resolver.

View File

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

View File

@ -71,6 +71,8 @@ force.stop.instance.warning=警告:强制停止在这个实例应该是你最
label.PreSetup=PreSetup label.PreSetup=PreSetup
label.SR.name=简名称标签 label.SR.name=简名称标签
label.SharedMountPoint = SharedMountPoint label.SharedMountPoint = SharedMountPoint
label.clvm=CLVM
label.volgroup=Volume Group
label.VMFS.datastore=VMFS 数据存储 label.VMFS.datastore=VMFS 数据存储
label.network.device=网络设备 label.network.device=网络设备
@ -855,4 +857,4 @@ error.login=您的用户名/密码与我们的记录不匹配。
error.menu.select=无法执行动作,因为没有选项被选中。 error.menu.select=无法执行动作,因为没有选项被选中。
error.mgmt.server.inaccessible=管理服务器无法访问。请稍后再试。 error.mgmt.server.inaccessible=管理服务器无法访问。请稍后再试。
error.session.expired=您的会话已过期。 error.session.expired=您的会话已过期。
error.unresolved.internet.name=您的网际网路名称无法得到解析。 error.unresolved.internet.name=您的网际网路名称无法得到解析。

View File

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

View File

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

View File

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

View File

@ -37,7 +37,7 @@ mount_raw_disk() {
local vmname=$1 local vmname=$1
local datadisk=$2 local datadisk=$2
local path=$(mntpath $vmname) local path=$(mntpath $vmname)
if [ ! -f $datadisk ] if [ ! -f $datadisk -a ! -b $datadisk ]
then then
printf "$datadisk doesn't exist" >&2 printf "$datadisk doesn't exist" >&2
return 2 return 2
@ -46,9 +46,15 @@ mount_raw_disk() {
retry=10 retry=10
while [ $retry -gt 0 ] while [ $retry -gt 0 ]
do 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 sleep 10
if [ $? -gt 0 ] if [ $ret -gt 0 ]
then then
sleep 5 sleep 5
else else

View File

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

View File

@ -95,6 +95,7 @@
'label.SharedMountPoint': '<fmt:message key="label.SharedMountPoint"/>', 'label.SharedMountPoint': '<fmt:message key="label.SharedMountPoint"/>',
'label.PreSetup': '<fmt:message key="label.PreSetup"/>', 'label.PreSetup': '<fmt:message key="label.PreSetup"/>',
'label.iscsi': '<fmt:message key="label.iscsi"/>', 'label.iscsi': '<fmt:message key="label.iscsi"/>',
'label.clvm': '<fmt:message key="label.clvm"/>',
'label.VMFS.datastore': '<fmt:message key="label.VMFS.datastore"/>', 'label.VMFS.datastore': '<fmt:message key="label.VMFS.datastore"/>',
'label.theme.default': '<fmt:message key="label.theme.default"/>', 'label.theme.default': '<fmt:message key="label.theme.default"/>',
'label.none': '<fmt:message key="label.none"/>', '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 id="add_pool_lun_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div> </div>
</li> </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"> <li input_group="vmfs">
<label for="add_pool_vmfs_dc"> <label for="add_pool_vmfs_dc">
<fmt:message key="label.vcenter.datacenter"/>:</label> <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 id="add_pool_lun_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div> </div>
</li> </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"> <li input_group="vmfs">
<label for="add_pool_vmfs_dc"> <label for="add_pool_vmfs_dc">
<fmt:message key="label.vcenter.datacenter"/>:</label> <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 id="add_pool_lun_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div> </div>
</li> </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"> <li input_group="vmfs">
<label for="add_pool_vmfs_dc"> <label for="add_pool_vmfs_dc">
<fmt:message key="label.vcenter.datacenter"/>:</label> <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 id="add_pool_lun_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div> </div>
</li> </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"> <li input_group="vmfs">
<label for="add_pool_vmfs_dc"> <label for="add_pool_vmfs_dc">
<fmt:message key="label.vcenter.datacenter"/>:</label> <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 id="add_pool_lun_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div> </div>
</li> </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"> <li input_group="vmfs">
<label for="add_pool_vmfs_dc"> <label for="add_pool_vmfs_dc">
<fmt:message key="label.vcenter.datacenter"/>:</label> <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("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("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")); 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") { } else if(protocol == "vmfs") {
isValid &= validateString("vCenter Datacenter", $thisDialog.find("#add_pool_vmfs_dc"), $thisDialog.find("#add_pool_vmfs_dc_errormsg")); 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")); 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; path = "/" + path;
url = SharedMountPointURL(server, 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") { else if (protocol == "vmfs") {
var path = trim($thisDialog.find("#add_pool_vmfs_dc").val()); var path = trim($thisDialog.find("#add_pool_vmfs_dc").val());
if(path.substring(0,1)!="/") if(path.substring(0,1)!="/")
@ -1129,6 +1135,15 @@ function SharedMountPointURL(server, path) {
return url; return url;
} }
function clvmURL(vgname) {
var url;
if(vgname.indexOf("://")==-1)
url = "clvm://localhost/" + vgname;
else
url = vgname;
return url;
}
function vmfsURL(server, path) { function vmfsURL(server, path) {
var url; var url;
if(server.indexOf("://")==-1) 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("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("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")); 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") { } else if(protocol == "vmfs") {
isValid &= validateString("vCenter Datacenter", $thisDialog.find("#add_pool_vmfs_dc"), $thisDialog.find("#add_pool_vmfs_dc_errormsg")); 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")); 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; path = "/" + path;
url = SharedMountPointURL(server, 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") { else if(protocol == "vmfs") {
var path = trim($thisDialog.find("#add_pool_vmfs_dc").val()); var path = trim($thisDialog.find("#add_pool_vmfs_dc").val());
if(path.substring(0,1)!="/") if(path.substring(0,1)!="/")
@ -1951,6 +1957,7 @@ function bindEventHandlerToDialogAddPool($dialogAddPool) {
$protocolSelector.empty(); $protocolSelector.empty();
$protocolSelector.append('<option value="nfs">' + g_dictionary["label.nfs"] + '</option>'); $protocolSelector.append('<option value="nfs">' + g_dictionary["label.nfs"] + '</option>');
$protocolSelector.append('<option value="SharedMountPoint">' + g_dictionary["label.SharedMountPoint"] + '</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") { else if(clusterObj.hypervisortype == "XenServer") {
$protocolSelector.empty(); $protocolSelector.empty();
@ -1980,6 +1987,7 @@ function bindEventHandlerToDialogAddPool($dialogAddPool) {
$("#add_pool_server_container", $dialogAddPool).show(); $("#add_pool_server_container", $dialogAddPool).show();
$('li[input_group="nfs"]', $dialogAddPool).show(); $('li[input_group="nfs"]', $dialogAddPool).show();
$('li[input_group="iscsi"]', $dialogAddPool).hide(); $('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).hide(); $('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_path_container").find("label").text(g_dictionary["label.path"]+":"); $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(); $("#add_pool_server_container", $dialogAddPool).show();
$('li[input_group="nfs"]', $dialogAddPool).show(); $('li[input_group="nfs"]', $dialogAddPool).show();
$('li[input_group="iscsi"]', $dialogAddPool).hide(); $('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).hide(); $('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_path_container").find("label").text(g_dictionary["label.SR.name"]+":"); $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(); $("#add_pool_server_container", $dialogAddPool).show();
$('li[input_group="nfs"]', $dialogAddPool).hide(); $('li[input_group="nfs"]', $dialogAddPool).hide();
$('li[input_group="iscsi"]', $dialogAddPool).show(); $('li[input_group="iscsi"]', $dialogAddPool).show();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).hide(); $('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_nfs_server").val(""); $dialogAddPool.find("#add_pool_nfs_server").val("");
$dialogAddPool.find("#add_pool_server_container").show(); $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") { else if($(this).val() == "vmfs") {
$("#add_pool_server_container", $dialogAddPool).hide(); $("#add_pool_server_container", $dialogAddPool).hide();
$('li[input_group="nfs"]', $dialogAddPool).hide(); $('li[input_group="nfs"]', $dialogAddPool).hide();
$('li[input_group="iscsi"]', $dialogAddPool).hide(); $('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).show(); $('li[input_group="vmfs"]', $dialogAddPool).show();
$dialogAddPool.find("#add_pool_nfs_server").val(""); $dialogAddPool.find("#add_pool_nfs_server").val("");
@ -2027,6 +2048,7 @@ function bindEventHandlerToDialogAddPool($dialogAddPool) {
$("#add_pool_server_container", $dialogAddPool).show(); $("#add_pool_server_container", $dialogAddPool).show();
$('li[input_group="nfs"]', $dialogAddPool).show(); $('li[input_group="nfs"]', $dialogAddPool).show();
$('li[input_group="iscsi"]', $dialogAddPool).hide(); $('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).hide(); $('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_nfs_server").val("localhost"); $dialogAddPool.find("#add_pool_nfs_server").val("localhost");
@ -2036,6 +2058,7 @@ function bindEventHandlerToDialogAddPool($dialogAddPool) {
//$("#add_pool_server_container", $dialogAddPool).hide(); //$("#add_pool_server_container", $dialogAddPool).hide();
//$('li[input_group="nfs"]', $dialogAddPool).hide(); //$('li[input_group="nfs"]', $dialogAddPool).hide();
$('li[input_group="iscsi"]', $dialogAddPool).hide(); $('li[input_group="iscsi"]', $dialogAddPool).hide();
$('li[input_group="clvm"]', $dialogAddPool).hide();
$('li[input_group="vmfs"]', $dialogAddPool).hide(); $('li[input_group="vmfs"]', $dialogAddPool).hide();
$dialogAddPool.find("#add_pool_nfs_server").val(""); $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("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("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")); 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") { } else if(protocol == "vmfs") {
isValid &= validateString("vCenter Datacenter", $thisDialog.find("#add_pool_vmfs_dc"), $thisDialog.find("#add_pool_vmfs_dc_errormsg")); 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")); 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; path = "/" + path;
url = SharedMountPointURL(server, 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") { else if (protocol == "vmfs") {
var path = trim($thisDialog.find("#add_pool_vmfs_dc").val()); var path = trim($thisDialog.find("#add_pool_vmfs_dc").val());
if(path.substring(0,1)!="/") if(path.substring(0,1)!="/")