Search in sources :

Example 1 with PhysicalDiskFormat

use of org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat in project cloudstack by apache.

the class LibvirtComputingResource method getResizeScriptType.

public String getResizeScriptType(final KVMStoragePool pool, final KVMPhysicalDisk vol) {
    final StoragePoolType poolType = pool.getType();
    final PhysicalDiskFormat volFormat = vol.getFormat();
    if (pool.getType() == StoragePoolType.CLVM && volFormat == PhysicalDiskFormat.RAW) {
        return "CLVM";
    } else if ((poolType == StoragePoolType.NetworkFilesystem || poolType == StoragePoolType.SharedMountPoint || poolType == StoragePoolType.Filesystem || poolType == StoragePoolType.Gluster) && volFormat == PhysicalDiskFormat.QCOW2) {
        return "QCOW2";
    } else if (poolType == StoragePoolType.Linstor) {
        return RESIZE_NOTIFY_ONLY;
    }
    throw new CloudRuntimeException("Cannot determine resize type from pool type " + pool.getType());
}
Also used : StoragePoolType(com.cloud.storage.Storage.StoragePoolType) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) PhysicalDiskFormat(org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat)

Example 2 with PhysicalDiskFormat

use of org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat in project cloudstack by apache.

the class QemuImgFileTest method testFileNameAndSizeAndFormatAtContructor.

@Test
public void testFileNameAndSizeAndFormatAtContructor() {
    PhysicalDiskFormat format = PhysicalDiskFormat.RAW;
    long size = 1024;
    String filename = "/tmp/test-image.qcow2";
    QemuImgFile file = new QemuImgFile(filename, size, format);
    assertEquals(file.getFileName(), filename);
    assertEquals(file.getSize(), size);
    assertEquals(file.getFormat(), format);
}
Also used : PhysicalDiskFormat(org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat) Test(org.junit.Test)

Example 3 with PhysicalDiskFormat

use of org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat in project cloudstack by apache.

the class QemuImgTest method testConvertAdvanced.

@Test
public void testConvertAdvanced() throws QemuImgException, LibvirtException {
    long srcSize = 4019200;
    String srcFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
    String destFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
    PhysicalDiskFormat srcFormat = PhysicalDiskFormat.RAW;
    PhysicalDiskFormat destFormat = PhysicalDiskFormat.QCOW2;
    QemuImgFile srcFile = new QemuImgFile(srcFileName, srcSize, srcFormat);
    QemuImgFile destFile = new QemuImgFile(destFileName, destFormat);
    QemuImg qemu = new QemuImg(0);
    qemu.create(srcFile);
    qemu.convert(srcFile, destFile);
    Map<String, String> info = qemu.info(destFile);
    PhysicalDiskFormat infoFormat = PhysicalDiskFormat.valueOf(info.get(QemuImg.FILE_FORMAT).toUpperCase());
    assertEquals(destFormat, infoFormat);
    Long infoSize = Long.parseLong(info.get(QemuImg.VIRTUAL_SIZE));
    assertEquals(Long.valueOf(srcSize), Long.valueOf(infoSize));
    File sf = new File(srcFileName);
    sf.delete();
    File df = new File(destFileName);
    df.delete();
}
Also used : File(java.io.File) PhysicalDiskFormat(org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat) Test(org.junit.Test)

Example 4 with PhysicalDiskFormat

use of org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat in project cloudstack by apache.

the class LibvirtStorageAdaptor method createDiskFromSnapshot.

@Override
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool, int timeout) {
    s_logger.info("Creating volume " + name + " from snapshot " + snapshotName + " in pool " + destPool.getUuid() + " (" + destPool.getType().toString() + ")");
    PhysicalDiskFormat format = snapshot.getFormat();
    long size = snapshot.getSize();
    String destPath = destPool.getLocalPath().endsWith("/") ? destPool.getLocalPath() + name : destPool.getLocalPath() + "/" + name;
    if (destPool.getType() == StoragePoolType.NetworkFilesystem) {
        try {
            if (format == PhysicalDiskFormat.QCOW2) {
                QemuImg qemu = new QemuImg(timeout);
                QemuImgFile destFile = new QemuImgFile(destPath, format);
                if (size > snapshot.getVirtualSize()) {
                    destFile.setSize(size);
                } else {
                    destFile.setSize(snapshot.getVirtualSize());
                }
                QemuImgFile srcFile = new QemuImgFile(snapshot.getPath(), snapshot.getFormat());
                qemu.convert(srcFile, destFile, snapshotName);
            }
        } catch (QemuImgException | LibvirtException e) {
            s_logger.error("Failed to create " + destPath + " due to a failed executing of qemu-img: " + e.getMessage());
        }
    }
    return destPool.getPhysicalDisk(name);
}
Also used : LibvirtException(org.libvirt.LibvirtException) QemuImgFile(org.apache.cloudstack.utils.qemu.QemuImgFile) QemuImgException(org.apache.cloudstack.utils.qemu.QemuImgException) PhysicalDiskFormat(org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat) QemuImg(org.apache.cloudstack.utils.qemu.QemuImg)

Example 5 with PhysicalDiskFormat

use of org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat in project cloudstack by apache.

the class LibvirtStorageAdaptor method copyPhysicalDisk.

/**
 * This copies a volume from Primary Storage to Secondary Storage
 *
 * In theory it could also do it the other way around, but the current implementation
 * in ManagementServerImpl shows that the destPool is always a Secondary Storage Pool
 */
@Override
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMStoragePool destPool, int timeout) {
    /**
     *            With RBD you can't run qemu-img convert with an existing RBD image as destination
     *            qemu-img will exit with the error that the destination already exists.
     *            So for RBD we don't create the image, but let qemu-img do that for us.
     *
     *            We then create a KVMPhysicalDisk object that we can return
     *
     *            It is however very unlikely that the destPool will be RBD, since it isn't supported
     *            for Secondary Storage
     */
    KVMStoragePool srcPool = disk.getPool();
    PhysicalDiskFormat sourceFormat = disk.getFormat();
    String sourcePath = disk.getPath();
    KVMPhysicalDisk newDisk;
    s_logger.debug("copyPhysicalDisk: disk size:" + toHumanReadableSize(disk.getSize()) + ", virtualsize:" + toHumanReadableSize(disk.getVirtualSize()) + " format:" + disk.getFormat());
    if (destPool.getType() != StoragePoolType.RBD) {
        if (disk.getFormat() == PhysicalDiskFormat.TAR) {
            newDisk = destPool.createPhysicalDisk(name, PhysicalDiskFormat.DIR, Storage.ProvisioningType.THIN, disk.getVirtualSize());
        } else {
            newDisk = destPool.createPhysicalDisk(name, Storage.ProvisioningType.THIN, disk.getVirtualSize());
        }
    } else {
        newDisk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + name, name, destPool);
        newDisk.setFormat(PhysicalDiskFormat.RAW);
        newDisk.setSize(disk.getVirtualSize());
        newDisk.setVirtualSize(disk.getSize());
    }
    String destPath = newDisk.getPath();
    PhysicalDiskFormat destFormat = newDisk.getFormat();
    QemuImg qemu = new QemuImg(timeout);
    QemuImgFile srcFile = null;
    QemuImgFile destFile = null;
    if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() != StoragePoolType.RBD)) {
        if (sourceFormat == PhysicalDiskFormat.TAR && destFormat == PhysicalDiskFormat.DIR) {
            // LXC template
            Script.runSimpleBashScript("cp " + sourcePath + " " + destPath);
        } else if (sourceFormat == PhysicalDiskFormat.TAR) {
            Script.runSimpleBashScript("tar -x -f " + sourcePath + " -C " + destPath, timeout);
        } else if (sourceFormat == PhysicalDiskFormat.DIR) {
            Script.runSimpleBashScript("mkdir -p " + destPath);
            Script.runSimpleBashScript("chmod 755 " + destPath);
            Script.runSimpleBashScript("cp -p -r " + sourcePath + "/* " + destPath, timeout);
        } else {
            srcFile = new QemuImgFile(sourcePath, sourceFormat);
            try {
                Map<String, String> info = qemu.info(srcFile);
                String backingFile = info.get(QemuImg.BACKING_FILE);
                // qcow2 templates can just be copied into place
                if (sourceFormat.equals(destFormat) && backingFile == null && sourcePath.endsWith(".qcow2")) {
                    String result = Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath, timeout);
                    if (result != null) {
                        throw new CloudRuntimeException("Failed to create disk: " + result);
                    }
                } else {
                    destFile = new QemuImgFile(destPath, destFormat);
                    try {
                        qemu.convert(srcFile, destFile);
                        Map<String, String> destInfo = qemu.info(destFile);
                        Long virtualSize = Long.parseLong(destInfo.get(QemuImg.VIRTUAL_SIZE));
                        newDisk.setVirtualSize(virtualSize);
                        newDisk.setSize(virtualSize);
                    } catch (QemuImgException | LibvirtException e) {
                        s_logger.error("Failed to convert " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
                        newDisk = null;
                    }
                }
            } catch (QemuImgException | LibvirtException e) {
                s_logger.error("Failed to fetch the information of file " + srcFile.getFileName() + " the error was: " + e.getMessage());
                newDisk = null;
            }
        }
    } else if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() == StoragePoolType.RBD)) {
        /**
         * Using qemu-img we copy the QCOW2 disk to RAW (on RBD) directly.
         * To do so it's mandatory that librbd on the system is at least 0.67.7 (Ceph Dumpling)
         */
        s_logger.debug("The source image is not RBD, but the destination is. We will convert into RBD format 2");
        try {
            srcFile = new QemuImgFile(sourcePath, sourceFormat);
            String rbdDestPath = destPool.getSourceDir() + "/" + name;
            String rbdDestFile = KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), destPool.getSourcePort(), destPool.getAuthUserName(), destPool.getAuthSecret(), rbdDestPath);
            destFile = new QemuImgFile(rbdDestFile, destFormat);
            s_logger.debug("Starting copy from source image " + srcFile.getFileName() + " to RBD image " + rbdDestPath);
            qemu.convert(srcFile, destFile);
            s_logger.debug("Succesfully converted source image " + srcFile.getFileName() + " to RBD image " + rbdDestPath);
            /* We have to stat the RBD image to see how big it became afterwards */
            Rados r = new Rados(destPool.getAuthUserName());
            r.confSet("mon_host", destPool.getSourceHost() + ":" + destPool.getSourcePort());
            r.confSet("key", destPool.getAuthSecret());
            r.confSet("client_mount_timeout", "30");
            r.connect();
            s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
            IoCTX io = r.ioCtxCreate(destPool.getSourceDir());
            Rbd rbd = new Rbd(io);
            RbdImage image = rbd.open(name);
            RbdImageInfo rbdInfo = image.stat();
            newDisk.setSize(rbdInfo.size);
            newDisk.setVirtualSize(rbdInfo.size);
            s_logger.debug("After copy the resulting RBD image " + rbdDestPath + " is " + toHumanReadableSize(rbdInfo.size) + " bytes long");
            rbd.close(image);
            r.ioCtxDestroy(io);
        } catch (QemuImgException | LibvirtException e) {
            s_logger.error("Failed to convert from " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
            newDisk = null;
        } catch (RadosException e) {
            s_logger.error("A Ceph RADOS operation failed (" + e.getReturnValue() + "). The error was: " + e.getMessage());
            newDisk = null;
        } catch (RbdException e) {
            s_logger.error("A Ceph RBD operation failed (" + e.getReturnValue() + "). The error was: " + e.getMessage());
            newDisk = null;
        }
    } else {
        /**
         *                We let Qemu-Img do the work here. Although we could work with librbd and have that do the cloning
         *                it doesn't benefit us. It's better to keep the current code in place which works
         */
        srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(), sourcePath));
        srcFile.setFormat(sourceFormat);
        destFile = new QemuImgFile(destPath);
        destFile.setFormat(destFormat);
        try {
            qemu.convert(srcFile, destFile);
        } catch (QemuImgException | LibvirtException e) {
            s_logger.error("Failed to convert " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
            newDisk = null;
        }
    }
    if (newDisk == null) {
        throw new CloudRuntimeException("Failed to copy " + disk.getPath() + " to " + name);
    }
    return newDisk;
}
Also used : LibvirtException(org.libvirt.LibvirtException) Rados(com.ceph.rados.Rados) RadosException(com.ceph.rados.exceptions.RadosException) RbdImageInfo(com.ceph.rbd.jna.RbdImageInfo) PhysicalDiskFormat(org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat) QemuImg(org.apache.cloudstack.utils.qemu.QemuImg) QemuImgFile(org.apache.cloudstack.utils.qemu.QemuImgFile) Rbd(com.ceph.rbd.Rbd) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) QemuImgException(org.apache.cloudstack.utils.qemu.QemuImgException) RbdImage(com.ceph.rbd.RbdImage) IoCTX(com.ceph.rados.IoCTX) RbdException(com.ceph.rbd.RbdException)

Aggregations

PhysicalDiskFormat (org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat)8 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)4 QemuImgException (org.apache.cloudstack.utils.qemu.QemuImgException)4 LibvirtException (org.libvirt.LibvirtException)4 RadosException (com.ceph.rados.exceptions.RadosException)3 RbdException (com.ceph.rbd.RbdException)3 StoragePoolType (com.cloud.storage.Storage.StoragePoolType)3 IoCTX (com.ceph.rados.IoCTX)2 Rados (com.ceph.rados.Rados)2 Rbd (com.ceph.rbd.Rbd)2 RbdImage (com.ceph.rbd.RbdImage)2 RbdImageInfo (com.ceph.rbd.jna.RbdImageInfo)2 InternalErrorException (com.cloud.exception.InternalErrorException)2 File (java.io.File)2 QemuImg (org.apache.cloudstack.utils.qemu.QemuImg)2 QemuImgFile (org.apache.cloudstack.utils.qemu.QemuImgFile)2 Test (org.junit.Test)2 ErrorCode (com.ceph.rados.exceptions.ErrorCode)1 RbdSnapInfo (com.ceph.rbd.jna.RbdSnapInfo)1 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)1