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:
edison 2010-08-19 21:36:51 -07:00
parent ea3bbcb464
commit 3ab4651cf0
6 changed files with 203 additions and 70 deletions

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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();

View File

@ -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;