mirror of https://github.com/apache/cloudstack.git
Issue #: 5978 5977 5971 5972
Status 5978: resolved fixed Status 5977: resolved fixed Status 5971: resolved fixed Status 5972: resolved fixed
This commit is contained in:
parent
ea3bbcb464
commit
3ab4651cf0
|
|
@ -1228,21 +1228,46 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
protected ManageSnapshotAnswer execute(final ManageSnapshotCommand cmd) {
|
||||
String snapshotName = cmd.getSnapshotName();
|
||||
String VolPath = cmd.getVolumePath();
|
||||
String snapshotPath = cmd.getSnapshotPath();
|
||||
String vmName = cmd.getVmName();
|
||||
try {
|
||||
StorageVol vol = getVolume(VolPath);
|
||||
if (vol == null) {
|
||||
return new ManageSnapshotAnswer(cmd, false, null);
|
||||
DomainInfo.DomainState state = null;
|
||||
Domain vm = null;
|
||||
if (vmName != null) {
|
||||
try {
|
||||
vm = getDomain(cmd.getVmName());
|
||||
state = vm.getInfo().state;
|
||||
} catch (LibvirtException e) {
|
||||
|
||||
}
|
||||
}
|
||||
Domain vm = getDomain(cmd.getVmName());
|
||||
String vmUuid = vm.getUUIDString();
|
||||
Object[] args = new Object[] {snapshotName, vmUuid};
|
||||
String snapshot = SnapshotXML.format(args);
|
||||
s_logger.debug(snapshot);
|
||||
if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
|
||||
vm.snapshotCreateXML(snapshot);
|
||||
|
||||
if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING) {
|
||||
String vmUuid = vm.getUUIDString();
|
||||
Object[] args = new Object[] {snapshotName, vmUuid};
|
||||
String snapshot = SnapshotXML.format(args);
|
||||
s_logger.debug(snapshot);
|
||||
if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
|
||||
vm.snapshotCreateXML(snapshot);
|
||||
} else {
|
||||
DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
|
||||
snap.delete(0);
|
||||
}
|
||||
} else {
|
||||
DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
|
||||
snap.delete(0);
|
||||
/*VM is not running, create a snapshot by ourself*/
|
||||
final Script command = new Script(_manageSnapshotPath, _timeout, s_logger);
|
||||
if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
|
||||
command.add("-c", VolPath);
|
||||
} else {
|
||||
command.add("-d", snapshotPath);
|
||||
}
|
||||
|
||||
command.add("-n", snapshotName);
|
||||
String result = command.execute();
|
||||
if (result != null) {
|
||||
s_logger.debug("Failed to manage snapshot: " + result);
|
||||
return new ManageSnapshotAnswer(cmd, false, "Failed to manage snapshot: " + result);
|
||||
}
|
||||
}
|
||||
} catch (LibvirtException e) {
|
||||
s_logger.debug("Failed to manage snapshot: " + e.toString());
|
||||
|
|
@ -1259,28 +1284,52 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
String snapshotName = cmd.getSnapshotName();
|
||||
String snapshotPath = cmd.getSnapshotUuid();
|
||||
String snapshotDestPath = null;
|
||||
String vmName = cmd.getVmName();
|
||||
|
||||
try {
|
||||
StoragePool secondaryStoragePool = getNfsSPbyURI(_conn, new URI(secondaryStoragePoolURL));
|
||||
String ssPmountPath = _mountPoint + File.separator + secondaryStoragePool.getUUIDString();
|
||||
snapshotDestPath = ssPmountPath + File.separator + dcId + File.separator + "snapshots" + File.separator + accountId + File.separator + volumeId;
|
||||
final Script command = new Script(_manageSnapshotPath, _timeout, s_logger);
|
||||
Script command = new Script(_manageSnapshotPath, _timeout, 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);
|
||||
}
|
||||
/*Delete the snapshot on primary*/
|
||||
Domain vm = getDomain(cmd.getVmName());
|
||||
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);
|
||||
|
||||
DomainInfo.DomainState state = null;
|
||||
Domain vm = null;
|
||||
if (vmName != null) {
|
||||
try {
|
||||
vm = getDomain(cmd.getVmName());
|
||||
state = vm.getInfo().state;
|
||||
} catch (LibvirtException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING) {
|
||||
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);
|
||||
} else {
|
||||
command = new Script(_manageSnapshotPath, _timeout, 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);
|
||||
}
|
||||
}
|
||||
} catch (LibvirtException e) {
|
||||
return new BackupSnapshotAnswer(cmd, false, e.toString(), null);
|
||||
} catch (URISyntaxException e) {
|
||||
|
|
@ -1356,7 +1405,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
try {
|
||||
secondaryPool = getNfsSPbyURI(_conn, new URI(cmd.getSecondaryStoragePoolURL()));
|
||||
/*TODO: assuming all the storage pools mounted under _mountPoint, the mount point should be got from pool.dumpxml*/
|
||||
String templatePath = _mountPoint + File.separator + secondaryPool.getUUIDString() + File.separator + templateInstallFolder;
|
||||
String templatePath = _mountPoint + File.separator + secondaryPool.getUUIDString() + File.separator + templateInstallFolder;
|
||||
File f = new File(templatePath);
|
||||
if (!f.exists()) {
|
||||
f.mkdir();
|
||||
}
|
||||
String tmplPath = templateInstallFolder + File.separator + tmplFileName;
|
||||
Script command = new Script(_createTmplPath, _timeout, s_logger);
|
||||
command.add("-t", templatePath);
|
||||
|
|
@ -1403,38 +1456,58 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
}
|
||||
protected CreatePrivateTemplateAnswer execute(CreatePrivateTemplateCommand cmd) {
|
||||
String secondaryStorageURL = cmd.getSecondaryStorageURL();
|
||||
String snapshotUUID = cmd.getSnapshotPath();
|
||||
|
||||
StoragePool secondaryStorage = null;
|
||||
StoragePool privateTemplStorage = null;
|
||||
StorageVol privateTemplateVol = null;
|
||||
StorageVol snapshotVol = null;
|
||||
try {
|
||||
String templateFolder = cmd.getAccountId() + File.separator + cmd.getTemplateId() + File.separator;
|
||||
String templateInstallFolder = "/template/tmpl/" + templateFolder;
|
||||
|
||||
|
||||
secondaryStorage = getNfsSPbyURI(_conn, new URI(secondaryStorageURL));
|
||||
/*TODO: assuming all the storage pools mounted under _mountPoint, the mount point should be got from pool.dumpxml*/
|
||||
String mountPath = _mountPoint + File.separator + secondaryStorage.getUUIDString() + templateInstallFolder;
|
||||
File mpfile = new File(mountPath);
|
||||
String tmpltPath = _mountPoint + File.separator + secondaryStorage.getUUIDString() + templateInstallFolder;
|
||||
File mpfile = new File(tmpltPath);
|
||||
if (!mpfile.exists()) {
|
||||
mpfile.mkdir();
|
||||
}
|
||||
|
||||
Script command = new Script(_createTmplPath, _timeout, s_logger);
|
||||
command.add("-f", cmd.getSnapshotPath());
|
||||
command.add("-c", cmd.getSnapshotName());
|
||||
command.add("-t", tmpltPath);
|
||||
command.add("-n", cmd.getUniqueName() + ".qcow2");
|
||||
command.add("-s");
|
||||
String result = command.execute();
|
||||
|
||||
// Create a SR for the secondary storage installation folder
|
||||
privateTemplStorage = getNfsSPbyURI(_conn, new URI(secondaryStorageURL + templateInstallFolder));
|
||||
snapshotVol = getVolume(snapshotUUID);
|
||||
|
||||
LibvirtStorageVolumeDef vol = new LibvirtStorageVolumeDef(UUID.randomUUID().toString(), snapshotVol.getInfo().capacity, volFormat.QCOW2, null, null);
|
||||
s_logger.debug(vol.toString());
|
||||
privateTemplateVol = copyVolume(privateTemplStorage, vol, snapshotVol);
|
||||
if (result != null) {
|
||||
s_logger.debug("failed to create template: " + result);
|
||||
return new CreatePrivateTemplateAnswer(cmd,
|
||||
false,
|
||||
result,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put(StorageLayer.InstanceConfigKey, _storage);
|
||||
Processor qcow2Processor = new QCOW2Processor();
|
||||
|
||||
qcow2Processor.configure("QCOW2 Processor", params);
|
||||
|
||||
FormatInfo info = qcow2Processor.process(tmpltPath, null, cmd.getUniqueName());
|
||||
|
||||
TemplateLocation loc = new TemplateLocation(_storage, tmpltPath);
|
||||
loc.create(1, true, cmd.getUniqueName());
|
||||
loc.addFormat(info);
|
||||
loc.save();
|
||||
|
||||
return new CreatePrivateTemplateAnswer(cmd,
|
||||
true,
|
||||
null,
|
||||
templateInstallFolder + privateTemplateVol.getName(),
|
||||
privateTemplateVol.getInfo().capacity/1024*1024, /*in Mega unit*/
|
||||
privateTemplateVol.getName(),
|
||||
templateInstallFolder + cmd.getUniqueName() + ".qcow2",
|
||||
info.virtualSize,
|
||||
cmd.getUniqueName(),
|
||||
ImageFormat.QCOW2);
|
||||
} catch (URISyntaxException e) {
|
||||
return new CreatePrivateTemplateAnswer(cmd,
|
||||
|
|
@ -1453,7 +1526,31 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
0,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
} catch (InternalErrorException e) {
|
||||
return new CreatePrivateTemplateAnswer(cmd,
|
||||
false,
|
||||
e.toString(),
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
null);
|
||||
} catch (IOException e) {
|
||||
return new CreatePrivateTemplateAnswer(cmd,
|
||||
false,
|
||||
e.toString(),
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
null);
|
||||
} catch (ConfigurationException e) {
|
||||
return new CreatePrivateTemplateAnswer(cmd,
|
||||
false,
|
||||
e.toString(),
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
private StoragePool getNfsSPbyURI(Connect conn, URI uri) throws LibvirtException {
|
||||
|
|
@ -3165,7 +3262,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
String datadiskPath = tmplVol.getKey();
|
||||
|
||||
diskDef hda = new diskDef();
|
||||
hda.defFileBasedDisk(rootkPath, "vda", diskDef.diskBus.IDE, diskDef.diskFmtType.QCOW2);
|
||||
hda.defFileBasedDisk(rootkPath, "hda", diskDef.diskBus.IDE, diskDef.diskFmtType.QCOW2);
|
||||
disks.add(hda);
|
||||
|
||||
diskDef hdb = new diskDef();
|
||||
|
|
|
|||
|
|
@ -80,6 +80,20 @@ create_from_file() {
|
|||
fi
|
||||
}
|
||||
|
||||
create_from_snapshot() {
|
||||
local tmpltImg=$1
|
||||
local snapshotName=$2
|
||||
local tmpltfs=$3
|
||||
local tmpltname=$4
|
||||
|
||||
cloud-qemu-img convert -f qcow2 -O qcow2 -s $snapshotName $tmpltImg /$tmpltfs/$tmpltname >& /dev/null
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
printf "Failed to create template /$tmplfs/$tmpltname from snapshot $snapshotName on disk $tmpltImg "
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
tflag=
|
||||
nflag=
|
||||
fflag=
|
||||
|
|
@ -89,8 +103,9 @@ hvm=false
|
|||
cleanup=false
|
||||
dflag=
|
||||
cflag=
|
||||
snapshotName=
|
||||
|
||||
while getopts 'uht:n:f:s:c:d:' OPTION
|
||||
while getopts 'uht:n:f:sc:d:' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
t) tflag=1
|
||||
|
|
@ -103,10 +118,10 @@ do
|
|||
tmpltimg="$OPTARG"
|
||||
;;
|
||||
s) sflag=1
|
||||
volsize="$OPTARG"
|
||||
sflag=1
|
||||
;;
|
||||
c) cflag=1
|
||||
cksum="$OPTARG"
|
||||
snapshotName="$OPTARG"
|
||||
;;
|
||||
d) dflag=1
|
||||
descr="$OPTARG"
|
||||
|
|
@ -119,12 +134,6 @@ do
|
|||
esac
|
||||
done
|
||||
|
||||
if [ "$tflag$nflag$fflag" != "111" ]
|
||||
then
|
||||
usage
|
||||
exit 2
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -d /$tmpltfs ]
|
||||
then
|
||||
|
|
@ -148,7 +157,12 @@ then
|
|||
printf "failed to uncompress $tmpltimg\n"
|
||||
fi
|
||||
|
||||
create_from_file $tmpltfs $tmpltimg $tmpltname
|
||||
if [ "$sflag" == "1" ]
|
||||
then
|
||||
create_from_snapshot $tmpltimg $snapshotName $tmpltfs $tmpltname
|
||||
else
|
||||
create_from_file $tmpltfs $tmpltimg $tmpltname
|
||||
fi
|
||||
|
||||
touch /$tmpltfs/template.properties
|
||||
echo -n "" > /$tmpltfs/template.properties
|
||||
|
|
|
|||
|
|
@ -16,13 +16,20 @@ create_snapshot() {
|
|||
local snapshotname=$2
|
||||
local failed=0
|
||||
|
||||
qemu-img snapshot -c $snapshotname $disk
|
||||
if [ ! -f $disk ]
|
||||
then
|
||||
failed=1
|
||||
printf "No disk $disk exist\n" >&2
|
||||
return $failed
|
||||
fi
|
||||
|
||||
cloud-qemu-img snapshot -c $snapshotname $disk
|
||||
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
failed=1
|
||||
failed=2
|
||||
printf "***Failed to create snapshot $snapshotname for path $disk\n" >&2
|
||||
qemu-img snapshot -d $snapshotname $disk
|
||||
cloud-qemu-img snapshot -d $snapshotname $disk
|
||||
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
|
|
@ -34,21 +41,24 @@ create_snapshot() {
|
|||
}
|
||||
|
||||
destroy_snapshot() {
|
||||
local backupSnapDir=$1
|
||||
local disk=$1
|
||||
local snapshotname=$2
|
||||
local failed=0
|
||||
|
||||
if [ -f $backupSnapDir/$snapshotname ]
|
||||
if [ ! -f $disk ]
|
||||
then
|
||||
rm -f $backupSnapDir/$snapshotname
|
||||
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
printf "***Failed to delete snapshot $snapshotname for path $backupSnapDir\n" >&2
|
||||
failed=1
|
||||
fi
|
||||
failed=1
|
||||
printf "No disk $disk exist\n" >&2
|
||||
return $failed
|
||||
fi
|
||||
|
||||
cloud-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
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +81,7 @@ backup_snapshot() {
|
|||
local disk=$1
|
||||
local snapshotname=$2
|
||||
local destPath=$3
|
||||
local destName=$4
|
||||
|
||||
if [ ! -d $destPath ]
|
||||
then
|
||||
|
|
@ -90,7 +101,7 @@ backup_snapshot() {
|
|||
return 1
|
||||
fi
|
||||
|
||||
cloud-qemu-img convert -f qcow2 -O qcow2 -s $snapshotname $disk $destPath/$snapshotname >& /dev/null
|
||||
cloud-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
|
||||
|
|
@ -107,8 +118,9 @@ bflag=
|
|||
nflag=
|
||||
pathval=
|
||||
snapshot=
|
||||
tmplName=
|
||||
|
||||
while getopts 'c:d:r:n:b:p:' OPTION
|
||||
while getopts 'c:d:r:n:b:p:t:' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
c) cflag=1
|
||||
|
|
@ -128,6 +140,8 @@ do
|
|||
;;
|
||||
p) destPath="$OPTARG"
|
||||
;;
|
||||
t) tmplName="$OPTARG"
|
||||
;;
|
||||
?) usage
|
||||
;;
|
||||
esac
|
||||
|
|
@ -144,7 +158,7 @@ then
|
|||
exit $?
|
||||
elif [ "$bflag" == "1" ]
|
||||
then
|
||||
backup_snapshot $pathval $snapshot $destPath
|
||||
backup_snapshot $pathval $snapshot $destPath $tmplName
|
||||
exit $?
|
||||
elif [ "$rflag" == "1" ]
|
||||
then
|
||||
|
|
|
|||
|
|
@ -939,10 +939,12 @@ public class StorageManagerImpl implements StorageManager {
|
|||
if (vmId != null) {
|
||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
|
||||
if (vmInstance != null) {
|
||||
return vmInstance.getHostId();
|
||||
Long hostId = vmInstance.getHostId();
|
||||
if (hostId != null && !avoidHosts.contains(vmInstance.getHostId()))
|
||||
return hostId;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
/*Can't find the vm where host resides on(vm is destroyed? or volume is detached from vm), randomly choose a host to send the cmd */
|
||||
}
|
||||
List<StoragePoolHostVO> poolHosts = _poolHostDao.listByHostStatus(poolVO.getId(), Status.Up);
|
||||
Collections.shuffle(poolHosts);
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ public class SnapshotManagerImpl implements SnapshotManager {
|
|||
}
|
||||
txn.commit();
|
||||
|
||||
VolumeVO volume = _volsDao.findById(volumeId);
|
||||
VolumeVO volume = _volsDao.lock(volumeId, true);
|
||||
|
||||
if (!shouldRunSnapshot(userId, volume, policyIds)) {
|
||||
// A null snapshot is interpreted as snapshot creation failed which is what we want to indicate
|
||||
|
|
@ -477,7 +477,7 @@ public class SnapshotManagerImpl implements SnapshotManager {
|
|||
_snapshotDao.update(snapshot.getId(), snapshot);
|
||||
|
||||
long volumeId = snapshot.getVolumeId();
|
||||
VolumeVO volume = _volsDao.findById(volumeId);
|
||||
VolumeVO volume = _volsDao.lock(volumeId, true);
|
||||
|
||||
String primaryStoragePoolNameLabel = _storageMgr.getPrimaryStorageNameLabel(volume);
|
||||
Long dcId = volume.getDataCenterId();
|
||||
|
|
|
|||
|
|
@ -686,6 +686,7 @@ public class UserVmManagerImpl implements UserVmManager {
|
|||
}
|
||||
|
||||
boolean started = false;
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
|
||||
|
|
@ -736,6 +737,11 @@ public class UserVmManagerImpl implements UserVmManager {
|
|||
VolumeVO vol = rootVols.get(0);
|
||||
|
||||
List<VolumeVO> vols = _volsDao.findCreatedByInstance(vm.getId());
|
||||
List<VolumeVO> vos = new ArrayList<VolumeVO>();
|
||||
/*compete with take snapshot*/
|
||||
for (VolumeVO userVmVol : vols) {
|
||||
vos.add(_volsDao.lock(userVmVol.getId(), true));
|
||||
}
|
||||
|
||||
Answer answer = null;
|
||||
int retry = _retry;
|
||||
|
|
@ -2215,7 +2221,7 @@ public class UserVmManagerImpl implements UserVmManager {
|
|||
@Override @DB
|
||||
public SnapshotVO createTemplateSnapshot(long userId, long volumeId) {
|
||||
SnapshotVO createdSnapshot = null;
|
||||
VolumeVO volume = _volsDao.findById(volumeId);
|
||||
VolumeVO volume = _volsDao.lock(volumeId, true);
|
||||
|
||||
Long id = null;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue