mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Adds CLVM as an option for primary storage. It copies most of the RBD bits, in most cases simply adding an 'else if' or similar. In the managesnapshot.sh we add the ability to manipulate snapshots for the CLVM volumes, as well as a few minor fixes like adjusting the usage for the -b option to reflect that it accepts four arguments (note that it already accepted four args, it just wasn't reflected in the usage).
RB: https://reviews.apache.org/r/6470/ Send-by: shadowsor@gmail.com
This commit is contained in:
parent
7895386a81
commit
263216caa5
@ -96,6 +96,7 @@ public class Storage {
|
||||
Iscsi(true), // for e.g., ZFS Comstar
|
||||
ISO(false), // for iso image
|
||||
LVM(false), // XenServer local LVM SR
|
||||
CLVM(true),
|
||||
RBD(true),
|
||||
SharedMountPoint(true),
|
||||
VMFS(true), // VMware VMFS storage
|
||||
|
||||
@ -2640,7 +2640,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements
|
||||
disk.defNetworkBasedDisk(physicalDisk.getPath().replace("rbd:", ""), pool.getSourceHost(), pool.getSourcePort(),
|
||||
pool.getAuthUserName(), pool.getUuid(),
|
||||
devId, diskBusType, diskProtocol.RBD);
|
||||
} else if (volume.getType() == Volume.Type.DATADISK) {
|
||||
} else if (pool.getType() == StoragePoolType.CLVM) {
|
||||
disk.defBlockBasedDisk(physicalDisk.getPath(), devId,
|
||||
diskBusType);
|
||||
} else {
|
||||
if (volume.getType() == Volume.Type.DATADISK) {
|
||||
disk.defFileBasedDisk(physicalDisk.getPath(), devId,
|
||||
DiskDef.diskBus.VIRTIO,
|
||||
DiskDef.diskFmtType.QCOW2);
|
||||
@ -2651,6 +2655,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vm.getDevices().addDevice(disk);
|
||||
}
|
||||
|
||||
|
||||
@ -78,6 +78,10 @@ public class KVMStoragePoolManager {
|
||||
if (destPool.getType() == StoragePoolType.RBD) {
|
||||
return this._storageAdaptor.createDiskFromTemplate(template, name,
|
||||
KVMPhysicalDisk.PhysicalDiskFormat.RAW, template.getSize(), destPool);
|
||||
} else if (destPool.getType() == StoragePoolType.CLVM) {
|
||||
return this._storageAdaptor.createDiskFromTemplate(template, name,
|
||||
KVMPhysicalDisk.PhysicalDiskFormat.RAW, template.getSize(),
|
||||
destPool);
|
||||
} else {
|
||||
return this._storageAdaptor.createDiskFromTemplate(template, name,
|
||||
KVMPhysicalDisk.PhysicalDiskFormat.QCOW2,
|
||||
|
||||
@ -462,6 +462,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
type = StoragePoolType.Filesystem;
|
||||
} else if (spd.getPoolType() == LibvirtStoragePoolDef.poolType.RBD) {
|
||||
type = StoragePoolType.RBD;
|
||||
} else if (spd.getPoolType() == LibvirtStoragePoolDef.poolType.LOGICAL) {
|
||||
type = StoragePoolType.CLVM;
|
||||
}
|
||||
|
||||
LibvirtStoragePool pool = new LibvirtStoragePool(uuid, storage.getName(),
|
||||
@ -551,6 +553,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
sp = CreateSharedStoragePool(conn, name, host, path);
|
||||
} else if (type == StoragePoolType.RBD) {
|
||||
sp = createRBDStoragePool(conn, name, host, port, userInfo, path);
|
||||
} else if (type == StoragePoolType.CLVM) {
|
||||
sp = createCLVMStoragePool(conn, name, host, path);
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,9 +689,15 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
if (destPool.getType() != StoragePoolType.RBD) {
|
||||
disk = destPool.createPhysicalDisk(newUuid, format, template.getVirtualSize());
|
||||
|
||||
if (format == PhysicalDiskFormat.QCOW2) {
|
||||
Script.runSimpleBashScript("qemu-img create -f "
|
||||
+ template.getFormat() + " -b " + template.getPath() + " "
|
||||
+ disk.getPath());
|
||||
} else if (format == PhysicalDiskFormat.RAW) {
|
||||
Script.runSimpleBashScript("qemu-img convert -f "
|
||||
+ template.getFormat() + " -O raw " + template.getPath()
|
||||
+ " " + disk.getPath());
|
||||
}
|
||||
} else {
|
||||
disk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + newUuid, newUuid, destPool);
|
||||
disk.setFormat(format);
|
||||
|
||||
@ -88,8 +88,12 @@ public class LibvirtStoragePool implements KVMStoragePool {
|
||||
|
||||
@Override
|
||||
public PhysicalDiskFormat getDefaultFormat() {
|
||||
if (getStoragePoolType() == StoragePoolType.CLVM) {
|
||||
return PhysicalDiskFormat.RAW;
|
||||
} else {
|
||||
return PhysicalDiskFormat.QCOW2;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public KVMPhysicalDisk createPhysicalDisk(String name,
|
||||
|
||||
@ -19,13 +19,13 @@
|
||||
|
||||
|
||||
# $Id: managesnapshot.sh 11601 2010-08-11 17:26:15Z kris $ $HeadURL: svn://svn.lab.vmops.com/repos/branches/2.1.refactor/java/scripts/storage/qcow2/managesnapshot.sh $
|
||||
# managesnapshot.sh -- manage snapshots for a single disk (create, destroy, rollback)
|
||||
# managesnapshot.sh -- manage snapshots for a single disk (create, destroy, rollback, backup)
|
||||
|
||||
usage() {
|
||||
printf "Usage: %s: -c <path to disk> -n <snapshot name>\n" $(basename $0) >&2
|
||||
printf "Usage: %s: -d <path to disk> -n <snapshot name>\n" $(basename $0) >&2
|
||||
printf "Usage: %s: -r <path to disk> -n <snapshot name>\n" $(basename $0) >&2
|
||||
printf "Usage: %s: -b <path to disk> -n <snapshot name> -p <dest name>\n" $(basename $0) >&2
|
||||
printf "Usage: %s: -b <path to disk> -n <snapshot name> -p <dest dir> -t <dest file>\n" $(basename $0) >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
@ -40,12 +40,60 @@ then
|
||||
fi
|
||||
fi
|
||||
|
||||
is_lv() {
|
||||
# Must be a block device
|
||||
if [ -b "${1}" ]; then
|
||||
# But not a volume group or physical volume
|
||||
lvm vgs "${1}" > /dev/null 2>&1 && return 1
|
||||
# And a logical volume
|
||||
lvm lvs "${1}" > /dev/null 2>&1 && return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
get_vg() {
|
||||
lvm lvs --noheadings --unbuffered --separator=/ "${1}" | cut -d '/' -f 2
|
||||
}
|
||||
|
||||
get_lv() {
|
||||
lvm lvs --noheadings --unbuffered --separator=/ "${1}" | cut -d '/' -f 1
|
||||
}
|
||||
|
||||
double_hyphens() {
|
||||
echo ${1} | sed -e "s/-/--/g"
|
||||
}
|
||||
|
||||
create_snapshot() {
|
||||
local disk=$1
|
||||
local snapshotname="$2"
|
||||
local failed=0
|
||||
|
||||
if [ -f "${disk}" ]; then
|
||||
if [ ${dmsnapshot} = "yes" ] && is_lv ${disk}; then
|
||||
local lv=`get_lv ${disk}`
|
||||
local vg=`get_vg ${disk}`
|
||||
local lv_dm=`double_hyphens ${lv}`
|
||||
local vg_dm=`double_hyphens ${vg}`
|
||||
local lvdevice=/dev/mapper/${vg_dm}-${lv_dm}
|
||||
local lv_bytes=`blockdev --getsize64 ${lvdevice}`
|
||||
local lv_sectors=`blockdev --getsz ${lvdevice}`
|
||||
|
||||
lvm lvcreate --size ${lv_bytes}b --name "${snapshotname}-cow" ${vg} >&2 || return 2
|
||||
dmsetup suspend ${vg_dm}-${lv_dm} >&2
|
||||
if dmsetup info -c --noheadings -o name ${vg_dm}-${lv_dm}-real > /dev/null 2>&1; then
|
||||
echo "0 ${lv_sectors} snapshot ${lvdevice}-real /dev/mapper/${vg_dm}-${snapshotname}--cow p 64" | \
|
||||
dmsetup create "${vg_dm}-${snapshotname}" >&2 || ( destroy_snapshot ${disk} "${snapshotname}"; return 2 )
|
||||
dmsetup resume "${vg_dm}-${snapshotname}" >&2 || ( destroy_snapshot ${disk} "${snapshotname}"; return 2 )
|
||||
else
|
||||
dmsetup table ${vg_dm}-${lv_dm} | dmsetup create ${vg_dm}-${lv_dm}-real >&2 || ( destroy_snapshot ${disk} "${snapshotname}"; return 2 )
|
||||
dmsetup resume ${vg_dm}-${lv_dm}-real >&2 || ( destroy_snapshot ${disk} "${snapshotname}"; return 2 )
|
||||
echo "0 ${lv_sectors} snapshot ${lvdevice}-real /dev/mapper/${vg_dm}-${snapshotname}--cow p 64" | \
|
||||
dmsetup create "${vg_dm}-${snapshotname}" >&2 || ( destroy_snapshot ${disk} "${snapshotname}"; return 2 )
|
||||
echo "0 ${lv_sectors} snapshot-origin ${lvdevice}-real" | \
|
||||
dmsetup load ${vg_dm}-${lv_dm} >&2 || ( destroy_snapshot ${disk} "${snapshotname}"; return 2 )
|
||||
dmsetup resume "${vg_dm}-${snapshotname}" >&2 || ( destroy_snapshot ${disk} "${snapshotname}"; return 2 )
|
||||
fi
|
||||
dmsetup resume "${vg_dm}-${lv_dm}" >&2
|
||||
elif [ -f "${disk}" ]; then
|
||||
$qemu_img snapshot -c "$snapshotname" $disk
|
||||
|
||||
|
||||
@ -70,10 +118,30 @@ create_snapshot() {
|
||||
|
||||
destroy_snapshot() {
|
||||
local disk=$1
|
||||
local snapshotname=$2
|
||||
local snapshotname="$2"
|
||||
local failed=0
|
||||
|
||||
if [ -f $disk ]; then
|
||||
if is_lv ${disk}; then
|
||||
local lv=`get_lv ${disk}`
|
||||
local vg=`get_vg ${disk}`
|
||||
local lv_dm=`double_hyphens ${lv}`
|
||||
local vg_dm=`double_hyphens ${vg}`
|
||||
if [ -e /dev/mapper/${vg_dm}-${lv_dm}-real ]; then
|
||||
local dm_refcount=`dmsetup info -c --noheadings -o open ${vg_dm}-${lv_dm}-real`
|
||||
if [ ${dm_refcount} -le 2 ]; then
|
||||
dmsetup suspend ${vg_dm}-${lv_dm} >&2
|
||||
dmsetup table ${vg_dm}-${lv_dm}-real | dmsetup load ${vg_dm}-${lv_dm} >&2
|
||||
dmsetup resume ${vg_dm}-${lv_dm}
|
||||
dmsetup remove "${vg_dm}-${snapshotname}"
|
||||
dmsetup remove ${vg_dm}-${lv_dm}-real
|
||||
else
|
||||
dmsetup remove "${vg_dm}-${snapshotname}"
|
||||
fi
|
||||
else
|
||||
dmsetup remove "${vg_dm}-${snapshotname}"
|
||||
fi
|
||||
lvm lvremove -f "${vg}/${snapshotname}-cow"
|
||||
elif [ -f $disk ]; then
|
||||
$qemu_img snapshot -d "$snapshotname" $disk
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
@ -102,9 +170,10 @@ rollback_snapshot() {
|
||||
|
||||
return $failed
|
||||
}
|
||||
|
||||
backup_snapshot() {
|
||||
local disk=$1
|
||||
local snapshotname=$2
|
||||
local snapshotname="$2"
|
||||
local destPath=$3
|
||||
local destName=$4
|
||||
|
||||
@ -113,24 +182,37 @@ backup_snapshot() {
|
||||
mkdir -p $destPath >& /dev/null
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
printf "Failed to create $destPath" >&2
|
||||
printf "Failed to create $destPath\n" >&2
|
||||
return 3
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f ${disk} ]; then
|
||||
if [ ${dmsnapshot} = "yes" ] && is_lv ${disk}; then
|
||||
local vg=`get_vg ${disk}`
|
||||
local vg_dm=`double_hyphens ${vg}`
|
||||
local scriptdir=`dirname ${0}`
|
||||
|
||||
if ! dmsetup info -c --noheadings -o name ${vg_dm}-${snapshotname} > /dev/null 2>&1; then
|
||||
printf "Disk ${disk} has no snapshot called ${snapshotname}.\n" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
${qemu_img} convert -f raw -O qcow2 "/dev/mapper/${vg_dm}-${snapshotname}" "${destPath}/${destName}" || \
|
||||
( printf "${qemu_img} failed to create backup of snapshot ${snapshotname} for disk ${disk} to ${destPath}.\n" >&2; return 2 )
|
||||
|
||||
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
|
||||
printf "there is no $snapshotname on disk $disk\n" >&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
|
||||
printf "Failed to backup $snapshotname for disk $disk to $destPath\n" >&2
|
||||
return 2
|
||||
fi
|
||||
else
|
||||
@ -150,6 +232,8 @@ pathval=
|
||||
snapshot=
|
||||
tmplName=
|
||||
deleteDir=
|
||||
dmsnapshot=no
|
||||
dmrollback=no
|
||||
|
||||
while getopts 'c:d:r:n:b:p:t:f' OPTION
|
||||
do
|
||||
@ -180,6 +264,13 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
if modprobe dm-snapshot; then
|
||||
dmsnapshot=yes
|
||||
dmsetup targets | grep -q "^snapshot-merge" && dmrollback=yes
|
||||
fi
|
||||
|
||||
[ -z "${snapshot}" ] && usage
|
||||
|
||||
[ -b "$pathval" ] && snapshot=`echo "${snapshot}" | md5sum -t | awk '{ print $1 }'`
|
||||
|
||||
if [ "$cflag" == "1" ]
|
||||
@ -192,6 +283,7 @@ then
|
||||
exit $?
|
||||
elif [ "$bflag" == "1" ]
|
||||
then
|
||||
[ -z "${destPath}" -o -z "${tmplName}" ] && usage
|
||||
backup_snapshot $pathval $snapshot $destPath $tmplName
|
||||
exit $?
|
||||
elif [ "$rflag" == "1" ]
|
||||
|
||||
@ -1325,6 +1325,8 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
|
||||
pool = new StoragePoolVO(StoragePoolType.Filesystem, "localhost", 0, hostPath);
|
||||
} else if (scheme.equalsIgnoreCase("sharedMountPoint")) {
|
||||
pool = new StoragePoolVO(StoragePoolType.SharedMountPoint, storageHost, 0, hostPath);
|
||||
} else if (scheme.equalsIgnoreCase("clvm")) {
|
||||
pool = new StoragePoolVO(StoragePoolType.CLVM, storageHost, 0, hostPath.replaceFirst("/", ""));
|
||||
} else if (scheme.equalsIgnoreCase("rbd")) {
|
||||
if (port == -1) {
|
||||
port = 6789;
|
||||
@ -1628,7 +1630,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
|
||||
s_logger.debug("creating pool " + pool.getName() + " on host " + hostId);
|
||||
if (pool.getPoolType() != StoragePoolType.NetworkFilesystem && pool.getPoolType() != StoragePoolType.Filesystem && pool.getPoolType() != StoragePoolType.IscsiLUN
|
||||
&& pool.getPoolType() != StoragePoolType.Iscsi && pool.getPoolType() != StoragePoolType.VMFS && pool.getPoolType() != StoragePoolType.SharedMountPoint
|
||||
&& pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.OCFS2 && pool.getPoolType() != StoragePoolType.RBD) {
|
||||
&& pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.OCFS2 && pool.getPoolType() != StoragePoolType.RBD && pool.getPoolType() != StoragePoolType.CLVM) {
|
||||
s_logger.warn(" Doesn't support storage pool type " + pool.getPoolType());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -7510,6 +7510,7 @@
|
||||
items.push({id: "nfs", description: "nfs"});
|
||||
items.push({id: "SharedMountPoint", description: "SharedMountPoint"});
|
||||
items.push({id: "rbd", description: "RBD"});
|
||||
items.push({id: "clvm", description: "CLVM"});
|
||||
args.response.success({data: items});
|
||||
}
|
||||
else if(selectedClusterObj.hypervisortype == "XenServer") {
|
||||
|
||||
@ -966,6 +966,7 @@
|
||||
var items = [];
|
||||
items.push({id: "nfs", description: "nfs"});
|
||||
items.push({id: "SharedMountPoint", description: "SharedMountPoint"});
|
||||
items.push({id: "clvm", description: "CLVM"});
|
||||
args.response.success({data: items});
|
||||
}
|
||||
else if(selectedClusterObj.hypervisortype == "XenServer") {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user