Skip to content

Commit 3c35faa

Browse files
committed
CLOUDSTACK-4278: Fix resizing RBD volumes
Although libvirt supports resizing RBD volumes (and other formats) the Java bindings (libvirt-java) don't. Right now we use the Java bindings for librbd to handle the resizing for us, but in the future this should be done by libvirt rather then these Java bindings.
1 parent efa861c commit 3c35faa

3 files changed

Lines changed: 65 additions & 29 deletions

File tree

plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,35 +1564,66 @@ public Answer execute(ResizeVolumeCommand cmd) {
15641564
String path = vol.getPath();
15651565
String type = getResizeScriptType(pool, vol);
15661566

1567-
if (type == null) {
1568-
return new ResizeVolumeAnswer(cmd, false, "Unsupported volume format: pool type '"
1569-
+ pool.getType() + "' and volume format '" + vol.getFormat() + "'");
1570-
} else if (type.equals("QCOW2") && shrinkOk) {
1571-
return new ResizeVolumeAnswer(cmd, false, "Unable to shrink volumes of type " + type);
1572-
}
1573-
1574-
s_logger.debug("got to the stage where we execute the volume resize, params:"
1575-
+ path + "," + currentSize + "," + newSize + "," + type + "," + vmInstanceName + "," + shrinkOk);
1576-
final Script resizecmd = new Script(_resizeVolumePath,
1577-
_cmdsTimeout, s_logger);
1578-
resizecmd.add("-s",String.valueOf(newSize));
1579-
resizecmd.add("-c",String.valueOf(currentSize));
1580-
resizecmd.add("-p",path);
1581-
resizecmd.add("-t",type);
1582-
resizecmd.add("-r",String.valueOf(shrinkOk));
1583-
resizecmd.add("-v",vmInstanceName);
1584-
String result = resizecmd.execute();
1567+
/**
1568+
* RBD volumes can't be resized via a Bash script or via libvirt
1569+
*
1570+
* libvirt-java doesn't implemented resizing volumes, so we have to do this manually
1571+
*
1572+
* Future fix would be to hand this over to libvirt
1573+
*/
1574+
if (pool.getType() == StoragePoolType.RBD) {
1575+
try {
1576+
Rados r = new Rados(pool.getAuthUserName());
1577+
r.confSet("mon_host", pool.getSourceHost() + ":" + pool.getSourcePort());
1578+
r.confSet("key", pool.getAuthSecret());
1579+
r.connect();
1580+
s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
15851581

1586-
if (result == null) {
1582+
IoCTX io = r.ioCtxCreate(pool.getSourceDir());
1583+
Rbd rbd = new Rbd(io);
1584+
RbdImage image = rbd.open(vol.getName());
15871585

1588-
/* fetch new size as seen from libvirt, don't want to assume anything */
1589-
pool = _storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid());
1590-
long finalSize = pool.getPhysicalDisk(volid).getVirtualSize();
1591-
s_logger.debug("after resize, size reports as " + finalSize + ", requested " + newSize);
1592-
return new ResizeVolumeAnswer(cmd, true, "success", finalSize);
1586+
s_logger.debug("Resizing RBD volume " + vol.getName() + " to " + newSize + " bytes");
1587+
image.resize(newSize);
1588+
rbd.close(image);
1589+
1590+
r.ioCtxDestroy(io);
1591+
s_logger.debug("Succesfully resized RBD volume " + vol.getName() + " to " + newSize + " bytes");
1592+
} catch (RadosException e) {
1593+
return new ResizeVolumeAnswer(cmd, false, e.toString());
1594+
} catch (RbdException e) {
1595+
return new ResizeVolumeAnswer(cmd, false, e.toString());
1596+
}
1597+
} else {
1598+
if (type == null) {
1599+
return new ResizeVolumeAnswer(cmd, false, "Unsupported volume format: pool type '"
1600+
+ pool.getType() + "' and volume format '" + vol.getFormat() + "'");
1601+
} else if (type.equals("QCOW2") && shrinkOk) {
1602+
return new ResizeVolumeAnswer(cmd, false, "Unable to shrink volumes of type " + type);
1603+
}
1604+
1605+
s_logger.debug("got to the stage where we execute the volume resize, params:"
1606+
+ path + "," + currentSize + "," + newSize + "," + type + "," + vmInstanceName + "," + shrinkOk);
1607+
final Script resizecmd = new Script(_resizeVolumePath,
1608+
_cmdsTimeout, s_logger);
1609+
resizecmd.add("-s",String.valueOf(newSize));
1610+
resizecmd.add("-c",String.valueOf(currentSize));
1611+
resizecmd.add("-p",path);
1612+
resizecmd.add("-t",type);
1613+
resizecmd.add("-r",String.valueOf(shrinkOk));
1614+
resizecmd.add("-v",vmInstanceName);
1615+
String result = resizecmd.execute();
1616+
1617+
if (result != null) {
1618+
return new ResizeVolumeAnswer(cmd, false, result);
1619+
}
15931620
}
15941621

1595-
return new ResizeVolumeAnswer(cmd, false, result);
1622+
/* fetch new size as seen from libvirt, don't want to assume anything */
1623+
pool = _storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid());
1624+
long finalSize = pool.getPhysicalDisk(volid).getVirtualSize();
1625+
s_logger.debug("after resize, size reports as " + finalSize + ", requested " + newSize);
1626+
return new ResizeVolumeAnswer(cmd, true, "success", finalSize);
15961627
} catch (CloudRuntimeException e) {
15971628
String error = "failed to resize volume: " + e;
15981629
s_logger.debug(error);

plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,14 @@ public KVMPhysicalDisk getPhysicalDisk(String volumeUuid,
414414
disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool);
415415
disk.setSize(vol.getInfo().allocation);
416416
disk.setVirtualSize(vol.getInfo().capacity);
417-
if (voldef.getFormat() == null) {
417+
418+
/**
419+
* libvirt returns format = 'unknow', so we have to force
420+
* the format to RAW for RBD storage volumes
421+
*/
422+
if (pool.getType() == StoragePoolType.RBD) {
423+
disk.setFormat(PhysicalDiskFormat.RAW);
424+
} else if (voldef.getFormat() == null) {
418425
File diskDir = new File(disk.getPath());
419426
if (diskDir.exists() && diskDir.isDirectory()) {
420427
disk.setFormat(PhysicalDiskFormat.DIR);
@@ -423,8 +430,6 @@ public KVMPhysicalDisk getPhysicalDisk(String volumeUuid,
423430
} else {
424431
disk.setFormat(pool.getDefaultFormat());
425432
}
426-
} else if (pool.getType() == StoragePoolType.RBD) {
427-
disk.setFormat(PhysicalDiskFormat.RAW);
428433
} else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.QCOW2) {
429434
disk.setFormat(PhysicalDiskFormat.QCOW2);
430435
} else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.RAW) {

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
<cs.java-ipv6.version>0.10</cs.java-ipv6.version>
8383
<cs.replace.properties>build/replace.properties</cs.replace.properties>
8484
<cs.libvirt-java.version>0.4.9</cs.libvirt-java.version>
85-
<cs.rados-java.version>0.1.2</cs.rados-java.version>
85+
<cs.rados-java.version>0.1.3</cs.rados-java.version>
8686
<cs.target.dir>target</cs.target.dir>
8787
<cs.daemon.version>1.0.10</cs.daemon.version>
8888
<cs.jna.version>3.0.9</cs.jna.version>

0 commit comments

Comments
 (0)