[libvirt] [PATCH] phyp: Adding storage management driver

Eduardo Otubo otubo at linux.vnet.ibm.com
Fri Jun 18 21:11:11 UTC 2010


Hello Folks, 

This is the result of a couple of months of hard work. I added the storage 
management driver to the Power Hypervisor driver. This is a big but simple
patch, it's just a new set of functions, nothing more. I could split it 
into multiple commits, but the feature freeze starts in some hours and I 
really reed this feature to be included in the next release.

This patch includes:
 * Storage driver: The set of pool-* and vol-* functions.
 * attach-disk function.
 * Support for IVM on the new functions.

I've been looking at this code for a long time, so I apologize now for the 
silly mistakes that might be present. Looking forward to see the comments.

Thanks!

---
 src/phyp/phyp_driver.c | 1638 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/phyp/phyp_driver.h |   52 ++
 2 files changed, 1688 insertions(+), 2 deletions(-)

diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index cefb8be..77a74ef 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -56,6 +56,7 @@
 #include "virterror_internal.h"
 #include "uuid.h"
 #include "domain_conf.h"
+#include "storage_conf.h"
 #include "nodeinfo.h"
 
 #include "phyp_driver.h"
@@ -1680,6 +1681,466 @@ phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
 
 }
 
+static char *
+phypGetLparProfile(virConnectPtr conn, int lpar_id)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int exit_status = 0;
+    char *cmd = NULL;
+    char *ret = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    virBufferAddLit(&buf, "lssyscfg");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s ", managed_system);
+    virBufferVSprintf(&buf,
+                      " -r prof --filter lpar_ids=%d -F name|head -n 1",
+                      lpar_id);
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return NULL;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    char *char_ptr = strchr(ret, '\n');
+
+    if (char_ptr)
+        *char_ptr = '\0';
+
+    VIR_FREE(cmd);
+    return ret;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return NULL;
+}
+
+static int
+phypGetVIOSNextSlotNumber(virConnectPtr conn)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    char *char_ptr;
+    char *cmd = NULL;
+    char *ret = NULL;
+    char *profile = NULL;
+    int slot = 0;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (!(profile = phypGetLparProfile(conn, vios_id))) {
+        VIR_ERROR("%s", "Unable to get VIOS profile name.");
+        goto err;
+    }
+
+    virBufferAddLit(&buf, "echo $((`lssyscfg");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s ", managed_system);
+    virBufferVSprintf(&buf, "-r prof --filter "
+                      "profile_names=%s -F virtual_eth_adapters,"
+                      "virtual_opti_pool_id,virtual_scsi_adapters,"
+                      "virtual_serial_adapters|sed -e 's/\"//g' -e "
+                      "'s/,/\\n/g'|sed -e 's/\\(^[0-9][0-9]\\*\\).*$/\\1/'"
+                      "|sort|tail -n 1` +1 ))", profile);
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    if (virStrToLong_i(ret, &char_ptr, 10, &slot) == -1)
+        goto err;
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return slot;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+static int
+phypCreateServerSCSIAdapter(virConnectPtr conn)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    char *cmd = NULL;
+    char *ret = NULL;
+    char *profile = NULL;
+    int slot = 0;
+    char *vios_name = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (!
+        (vios_name =
+         phypGetLparNAME(session, managed_system, vios_id, conn))) {
+        VIR_ERROR("%s", "Unable to get VIOS name");
+        goto err;
+    }
+
+    if (!(profile = phypGetLparProfile(conn, vios_id))) {
+        VIR_ERROR("%s", "Unable to get VIOS profile name.");
+        goto err;
+    }
+
+    if ((slot = phypGetVIOSNextSlotNumber(conn)) == -1) {
+        VIR_ERROR("%s", "Unable to get free slot number");
+        goto err;
+    }
+
+    /* Listing all the virtual_scsi_adapter interfaces, the new adapter must
+     * be appended to this list
+     * */
+    virBufferAddLit(&buf, "lssyscfg");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s ", managed_system);
+    virBufferVSprintf(&buf, "-r prof --filter lpar_ids=%d,profile_names=%s"
+                      " -F virtual_scsi_adapters|sed -e s/\"//g",
+                      vios_id, profile);
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    /* Here I change the VIOS configuration to append the new adapter
+     * with the free slot I got with phypGetVIOSNextSlotNumber.
+     * */
+    virBufferAddLit(&buf, "chsyscfg");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s ", managed_system);
+    virBufferVSprintf(&buf, "-r prof -i 'name=%s,lpar_id=%d,"
+                      "\"virtual_scsi_adapters=%s,%d/server/any/any/1\"'",
+                      vios_name, vios_id, ret, slot);
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    /* Finally I add the new scsi adapter to VIOS using the same slot
+     * I used in the VIOS configuration.
+     * */
+    virBufferAddLit(&buf, "chhwres -r virtualio --rsubtype scsi ");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s ", managed_system);
+    virBufferVSprintf(&buf,
+                      "-p %s -o a -s %d -d 0 -a \"adapter_type=server\"",
+                      vios_name, slot);
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    VIR_FREE(profile);
+    VIR_FREE(vios_name);
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
+
+  err:
+    VIR_FREE(profile);
+    VIR_FREE(vios_name);
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+static char *
+phypGetVIOSFreeSCSIAdapter(virConnectPtr conn)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    char *cmd = NULL;
+    char *ret = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lsmap -all -field svsa backing -fmt ,'");
+    } else {
+        virBufferVSprintf(&buf, "lsmap -all -field svsa backing -fmt ,");
+    }
+    virBufferVSprintf(&buf, "|grep -v ',[^.*]'|head -n 1|sed -e 's/,//g'");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return NULL;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    char *char_ptr = strchr(ret, '\n');
+
+    if (char_ptr)
+        *char_ptr = '\0';
+
+    VIR_FREE(cmd);
+    return ret;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return NULL;
+}
+
+
+int
+phypAttachDevice(virDomainPtr domain, const char *xml)
+{
+
+    virConnectPtr conn = domain->conn;
+    ConnectionData *connection_data = domain->conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = domain->conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    char *char_ptr = NULL;
+    char *cmd = NULL;
+    char *ret = NULL;
+    char *scsi_adapter = NULL;
+    int slot = 0;
+    char *vios_name = NULL;
+    char *profile = NULL;
+    virDomainDeviceDefPtr dev = NULL;
+    virDomainDefPtr def = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    def->os.type = strdup("aix");
+
+    if (def->os.type == NULL) {
+        virReportOOMError();
+        goto err;
+    }
+
+    dev = virDomainDeviceDefParse(phyp_driver->caps, def, xml,
+                                  VIR_DOMAIN_XML_INACTIVE);
+    if (!dev) {
+        virReportOOMError();
+        goto err;
+    }
+
+    if (!
+        (vios_name =
+         phypGetLparNAME(session, managed_system, vios_id, conn))) {
+        VIR_ERROR("%s", "Unable to get VIOS name");
+        goto err;
+    }
+
+    /* First, let's look for a free SCSI Adapter
+     * */
+    if (!(scsi_adapter = phypGetVIOSFreeSCSIAdapter(conn))) {
+        /* If not found, let's create one.
+         * */
+        if (phypCreateServerSCSIAdapter(conn) == -1) {
+            VIR_ERROR("%s", "Unable to create new virtual adapter");
+            goto err;
+        } else {
+            if (!(scsi_adapter = phypGetVIOSFreeSCSIAdapter(conn))) {
+                VIR_ERROR("%s", "Unable to create new virtual adapter");
+                goto err;
+            }
+        }
+    }
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'mkvdev -vdev %s -vadapter %s'",
+                          dev->data.disk->src, scsi_adapter);
+    } else {
+        virBufferVSprintf(&buf, "mkvdev -vdev %s -vadapter %s",
+                          dev->data.disk->src, scsi_adapter);
+    }
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    if (!(profile = phypGetLparProfile(conn, domain->id))) {
+        VIR_ERROR("%s", "Unable to get VIOS profile name.");
+        goto err;
+    }
+
+    /* Let's get the slot number for the adapter we just created
+     * */
+    virBufferAddLit(&buf, "lshwres -r virtualio --rsubtype scsi ");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s", managed_system);
+    virBufferVSprintf(&buf,
+                      "slot_num,backing_device|grep %s|cut -d, -f1",
+                      dev->data.disk->src);
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    if (virStrToLong_i(ret, &char_ptr, 10, &slot) == -1)
+        goto err;
+
+    /* Listing all the virtual_scsi_adapter interfaces, the new adapter must
+     * be appended to this list
+     * */
+    virBufferAddLit(&buf, "lssyscfg");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s ", managed_system);
+    virBufferVSprintf(&buf,
+                      "-r prof --filter lpar_ids=%d,profile_names=%s"
+                      " -F virtual_scsi_adapters|sed -e s/\"//g",
+                      vios_id, profile);
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    /* Here I change the LPAR configuration to append the new adapter
+     * with the new slot we just created
+     * */
+    virBufferAddLit(&buf, "chsyscfg");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s ", managed_system);
+    virBufferVSprintf(&buf,
+                      "-r prof -i 'name=%s,lpar_id=%d,"
+                      "\"virtual_scsi_adapters=%s,%d/client/%d/%s/0\"'",
+                      domain->name, domain->id, ret, slot,
+                      vios_id, vios_name);
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (virStrToLong_i(ret, &char_ptr, 10, &slot) == -1)
+        goto err;
+
+    /* Finally I add the new scsi adapter to VIOS using the same slot
+     * I used in the VIOS configuration.
+     * */
+    virBufferAddLit(&buf, "chhwres -r virtualio --rsubtype scsi ");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s ", managed_system);
+    virBufferVSprintf(&buf,
+                      " -p %s -o a -s %d -d 0 -a \"adapter_type=server\"",
+                      domain->name, slot);
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL) {
+        VIR_ERROR0(_
+                   ("Possibly you don't have IBM Tools installed in your LPAR."
+                    "Contact your support to enable this feature."));
+        goto err;
+    }
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    VIR_FREE(def);
+    VIR_FREE(dev);
+    VIR_FREE(vios_name);
+    VIR_FREE(scsi_adapter);
+    return 0;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    VIR_FREE(def);
+    VIR_FREE(dev);
+    VIR_FREE(vios_name);
+    VIR_FREE(scsi_adapter);
+    return -1;
+}
+
 virDriver phypDriver = {
     VIR_DRV_PHYP, "PHYP", phypOpen,     /* open */
     phypClose,                  /* close */
@@ -1725,7 +2186,7 @@ virDriver phypDriver = {
     NULL,                       /* domainCreateWithFlags */
     NULL,                       /* domainDefineXML */
     NULL,                       /* domainUndefine */
-    NULL,                       /* domainAttachDevice */
+    phypAttachDevice,           /* domainAttachDevice */
     NULL,                       /* domainAttachDeviceFlags */
     NULL,                       /* domainDetachDevice */
     NULL,                       /* domainDetachDeviceFlags */
@@ -1779,6 +2240,1175 @@ virDriver phypDriver = {
     NULL,                       /* domainSnapshotDelete */
 };
 
+virStorageDriver phypStorageDriver = {
+    .name = "PHYP",
+    .open = phypStorageOpen,
+    .close = phypStorageClose,
+
+    .numOfPools = phypNumOfStoragePools,
+    .listPools = phypListStoragePools,
+    .numOfDefinedPools = NULL,
+    .listDefinedPools = NULL,
+    .findPoolSources = NULL,
+    .poolLookupByName = phypStoragePoolLookupByName,
+    .poolLookupByUUID = phypGetStoragePoolLookUpByUUID,
+    .poolLookupByVolume = NULL,
+    .poolCreateXML = phypStoragePoolCreateXML,
+    .poolDefineXML = NULL,
+    .poolBuild = NULL,
+    .poolUndefine = NULL,
+    .poolCreate = NULL,
+    .poolDestroy = phypDestroyStoragePool,
+    .poolDelete = NULL,
+    .poolRefresh = NULL,
+    .poolGetInfo = NULL,
+    .poolGetXMLDesc = phypGetStoragePoolXMLDesc,
+    .poolGetAutostart = NULL,
+    .poolSetAutostart = NULL,
+    .poolNumOfVolumes = phypStoragePoolNumOfVolumes,
+    .poolListVolumes = phypStoragePoolListVolumes,
+
+    .volLookupByName = phypVolumeLookupByName,
+    .volLookupByKey = NULL,
+    .volLookupByPath = phypVolumeLookupByPath,
+    .volCreateXML = NULL,
+    .volCreateXMLFrom = NULL,
+    .volDelete = NULL,
+    .volGetInfo = NULL,
+    .volGetXMLDesc = phypVolumeGetXMLDesc,
+    .volGetPath = phypVolumeGetPath,
+    .poolIsActive = NULL,
+    .poolIsPersistent = NULL
+};
+
+static int
+phypVolumeGetKey(virConnectPtr conn, char *key, const char *name)
+{
+
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    char *cmd = NULL;
+    char *ret = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lslv %s -field lvid'", name);
+    } else {
+        virBufferVSprintf(&buf, "lslv %s -field lvid", name);
+    }
+    virBufferVSprintf(&buf, "|sed -e 's/^LV IDENTIFIER://' -e 's/\\ //g'");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    char *char_ptr = strchr(ret, '\n');
+
+    if (char_ptr)
+        *char_ptr = '\0';
+
+    if (memmove(key, ret, PATH_MAX) == NULL)
+        goto err;
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+static char *
+phypGetStoragePoolDevice(virConnectPtr conn, char *name)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    char *cmd = NULL;
+    char *ret = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lssp -detail -sp %s -field name'", name);
+    } else {
+        virBufferVSprintf(&buf, "lssp -detail -sp %s -field name", name);
+    }
+    virBufferVSprintf(&buf, "|sed '1d'|sed -e 's/\\ //g'");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return NULL;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    char *char_ptr = strchr(ret, '\n');
+
+    if (char_ptr)
+        *char_ptr = '\0';
+
+    VIR_FREE(cmd);
+    return ret;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return NULL;
+}
+
+static unsigned long int
+phypGetStoragePoolSize(virConnectPtr conn, char *name)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int exit_status = 0;
+    int vios_id = phyp_driver->vios_id;
+    char *cmd = NULL;
+    char *ret = NULL;
+    int sp_size = 0;
+    char *char_ptr;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lssp -detail -sp %s -field size'", name);
+    } else {
+        virBufferVSprintf(&buf, "lssp -detail -sp %s -field size", name);
+    }
+    virBufferVSprintf(&buf, "|sed '1d'|sed -e 's/\\ //g'");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    if (virStrToLong_i(ret, &char_ptr, 10, &sp_size) == -1)
+        goto err;
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return sp_size;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+static int
+phypBuildVolume(virConnectPtr conn, const char *lvname, const char *spname,
+                unsigned int capacity, char *key)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    int vios_id = phyp_driver->vios_id;
+    int system_type = phyp_driver->system_type;
+    char *managed_system = phyp_driver->managed_system;
+    char *cmd = NULL;
+    char *ret = NULL;
+    int exit_status = 0;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'mklv -lv %s %s %d'", lvname, spname,
+                          capacity);
+    } else {
+        virBufferVSprintf(&buf, "mklv -lv %s %s %d", lvname, spname,
+                          capacity);
+    }
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0) {
+        VIR_ERROR("%s\"%s\"", "Unable to create Volume. Reason: ", ret);
+        goto err;
+    }
+
+    if (phypVolumeGetKey(conn, key, lvname) == -1)
+        goto err;;
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+virStorageVolPtr
+phypStorageVolCreateXML(virStoragePoolPtr pool, const char *xml,
+                        unsigned int flags ATTRIBUTE_UNUSED)
+{
+
+    virStorageVolDefPtr voldef = NULL;
+    virStoragePoolDefPtr spdef = NULL;
+    virStorageVolPtr vol = NULL;
+    char *key = NULL;
+
+    if (VIR_ALLOC(spdef) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    if (VIR_ALLOC_N(key, PATH_MAX) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    /* Filling spdef manually
+     * */
+    if (pool->name != NULL) {
+        spdef->name = pool->name;
+    } else {
+        VIR_ERROR("%s", "Unable to determine storage pool's name.");
+        goto err;
+    }
+
+    if (memmove(spdef->uuid, pool->uuid, VIR_UUID_BUFLEN) == NULL) {
+        VIR_ERROR("%s", "Unable to determine storage pool's uuid.");
+        goto err;
+    }
+
+    if ((spdef->capacity =
+         phypGetStoragePoolSize(pool->conn, pool->name)) == -1) {
+        VIR_ERROR("%s", "Unable to determine storage pools's size.");
+        goto err;
+    }
+
+    /* Information not avaliable */
+    spdef->allocation = 0;
+    spdef->available = 0;
+
+    spdef->source.ndevice = 1;
+
+    /*XXX source adapter not working properly, should show hdiskX */
+    if ((spdef->source.adapter =
+         phypGetStoragePoolDevice(pool->conn, pool->name)) == NULL) {
+        VIR_ERROR("%s",
+                  "Unable to determine storage pools's source adapter.");
+        goto err;
+    }
+
+    if ((voldef = virStorageVolDefParseString(spdef, xml)) == NULL) {
+        VIR_ERROR("%s", "Error parsing volume XML.");
+        goto err;
+    }
+
+    /* checking if this name already exists on this system */
+    if (phypVolumeLookupByName(pool, voldef->name) != NULL) {
+        VIR_ERROR("%s", "StoragePool name already exists.");
+        goto err;
+    }
+
+    /* The key must be NULL, the Power Hypervisor creates a key
+     * in the moment you create the volume.
+     * */
+    if (voldef->key) {
+        VIR_ERROR("%s",
+                  "Key must be empty, Power Hypervisor will create one for you.");
+        goto err;
+    }
+
+    if (voldef->capacity) {
+        VIR_ERROR("%s", "Capacity cannot be empty.");
+        goto err;
+    }
+
+    if (phypBuildVolume
+        (pool->conn, voldef->name, spdef->name, voldef->capacity,
+         key) == -1)
+        goto err;
+
+    if ((vol =
+         virGetStorageVol(pool->conn, pool->name, voldef->name,
+                          key)) == NULL)
+        goto err;
+
+    return vol;
+
+  err:
+    virStorageVolDefFree(voldef);
+    virStoragePoolDefFree(spdef);
+    if (vol)
+        virUnrefStorageVol(vol);
+    return NULL;
+}
+
+static char *
+phypVolumeGetPhysicalVolumeByStoragePool(virStorageVolPtr vol, char *sp)
+{
+    virConnectPtr conn = vol->conn;
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    char *cmd = NULL;
+    char *ret = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lssp -detail -sp %s -field pvname'", sp);
+    } else {
+        virBufferVSprintf(&buf, "lssp -detail -sp %s -field pvname", sp);
+    }
+    virBufferVSprintf(&buf, "|sed 1d");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return NULL;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    char *char_ptr = strchr(ret, '\n');
+
+    if (char_ptr)
+        *char_ptr = '\0';
+
+    VIR_FREE(cmd);
+    return ret;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return NULL;
+
+}
+
+virStorageVolPtr
+phypVolumeLookupByPath(virConnectPtr conn, const char *volname)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    char *cmd = NULL;
+    char *spname = NULL;
+    char *key = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lslv %s -field vgname'", volname);
+    } else {
+        virBufferVSprintf(&buf, "lslv %s -field vgname", volname);
+    }
+    virBufferVSprintf(&buf,
+                      "|sed -e 's/^VOLUME\\ GROUP://g' -e 's/\\ //g'");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return NULL;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    spname = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || spname == NULL)
+        return NULL;
+
+    char *char_ptr = strchr(spname, '\n');
+
+    if (char_ptr)
+        *char_ptr = '\0';
+
+    if (VIR_ALLOC_N(key, PATH_MAX) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    if (phypVolumeGetKey(conn, key, volname) == -1)
+        return NULL;
+
+    return virGetStorageVol(conn, spname, volname, key);
+}
+
+char *
+phypVolumeGetXMLDesc(virStorageVolPtr vol,
+                     unsigned int flags ATTRIBUTE_UNUSED)
+{
+    virStorageVolDef voldef;
+    memset(&voldef, 0, sizeof(virStorageVolDef));
+
+    virStoragePoolPtr sp =
+        phypStoragePoolLookupByName(vol->conn, vol->pool);
+
+    if (!sp)
+        goto err;
+
+    virStoragePoolDef pool;
+    memset(&pool, 0, sizeof(virStoragePoolDef));
+
+    if (VIR_ALLOC_N(voldef.key, PATH_MAX) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    if (sp->name != NULL) {
+        pool.name = sp->name;
+    } else {
+        VIR_ERROR("%s", "Unable to determine storage sp's name.");
+        goto err;
+    }
+
+    if (memmove(pool.uuid, sp->uuid, VIR_UUID_BUFLEN) == NULL) {
+        VIR_ERROR("%s", "Unable to determine storage sp's uuid.");
+        goto err;
+    }
+
+    if ((pool.capacity = phypGetStoragePoolSize(sp->conn, sp->name)) == -1) {
+        VIR_ERROR("%s", "Unable to determine storage sps's size.");
+        goto err;
+    }
+
+    /* Information not avaliable */
+    pool.allocation = 0;
+    pool.available = 0;
+
+    pool.source.ndevice = 1;
+
+    if ((pool.source.adapter =
+         phypGetStoragePoolDevice(sp->conn, sp->name)) == NULL) {
+        VIR_ERROR("%s",
+                  "Unable to determine storage sps's source adapter.");
+        goto err;
+    }
+
+    if (vol->name != NULL)
+        voldef.name = vol->name;
+    else {
+        VIR_ERROR("%s", "Unable to determine storage pool's name.");
+        goto err;
+    }
+
+    if (memmove(voldef.key, vol->key, PATH_MAX) == NULL) {
+        VIR_ERROR("%s", "Unable to determine volume's key.");
+        goto err;
+    }
+
+    voldef.type = VIR_STORAGE_POOL_LOGICAL;
+
+    return virStorageVolDefFormat(&pool, &voldef);
+
+  err:
+    return NULL;
+}
+
+/* The Volume Group path here will be treated as suggested in the
+ * email on the libvirt mailling list. As soon as I can't get the
+ * path for every volume, the path will be a representation in
+ * the form:
+ *
+ * /physical_volume/storage_pool/logical_volume
+ *
+ * */
+char *
+phypVolumeGetPath(virStorageVolPtr vol)
+{
+    virConnectPtr conn = vol->conn;
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    char *cmd = NULL;
+    char *sp = NULL;
+    char *path = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lslv %s -field vgname'", vol->name);
+    } else {
+        virBufferVSprintf(&buf, "lslv %s -field vgname", vol->name);
+    }
+    virBufferVSprintf(&buf,
+                      "|sed -e 's/^VOLUME\\ GROUP://g' -e 's/\\ //g'");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return NULL;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    sp = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || sp == NULL)
+        goto err;
+
+    char *char_ptr = strchr(sp, '\n');
+
+    if (char_ptr)
+        *char_ptr = '\0';
+
+    char *pv = phypVolumeGetPhysicalVolumeByStoragePool(vol, sp);
+
+    if (pv) {
+        if (virAsprintf(&path, "/%s/%s/%s", pv, sp, vol->name) < 0) {
+            virReportOOMError();
+            goto err;
+        }
+    } else {
+        goto err;
+    }
+
+    VIR_FREE(cmd);
+    return path;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(sp);
+    VIR_FREE(path);
+    return NULL;
+
+}
+
+virStorageVolPtr
+phypVolumeLookupByName(virStoragePoolPtr pool, const char *volname)
+{
+
+    char key[PATH_MAX];
+
+    if (phypVolumeGetKey(pool->conn, key, volname) == -1)
+        return NULL;
+
+    return virGetStorageVol(pool->conn, pool->name, volname, key);
+}
+
+int
+phypStoragePoolListVolumes(virStoragePoolPtr pool, char **const volumes,
+                           int nvolumes)
+{
+    virConnectPtr conn = pool->conn;
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    int got = 0;
+    int i;
+    char *cmd = NULL;
+    char *ret = NULL;
+    char *volumes_list = NULL;
+    char *char_ptr2 = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lsvg -lv %s -field lvname'", pool->name);
+    } else {
+        virBufferVSprintf(&buf, "lsvg -lv %s -field lvname", pool->name);
+    }
+    virBufferVSprintf(&buf, "|sed '1d'|sed '1d'");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    /* I need to parse the textual return in order to get the volumes */
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+    else {
+        volumes_list = ret;
+
+        while (got < nvolumes) {
+            char_ptr2 = strchr(volumes_list, '\n');
+
+            if (char_ptr2) {
+                *char_ptr2 = '\0';
+                if ((volumes[got++] = strdup(volumes_list)) == NULL) {
+                    virReportOOMError();
+                    goto err;
+                }
+                char_ptr2++;
+                volumes_list = char_ptr2;
+            } else
+                break;
+        }
+    }
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return got;
+
+  err:
+    for (i = 0; i < got; i++)
+        VIR_FREE(volumes[i]);
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+int
+phypStoragePoolNumOfVolumes(virStoragePoolPtr pool)
+{
+    virConnectPtr conn = pool->conn;
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    int system_type = phyp_driver->system_type;
+    int exit_status = 0;
+    int nvolumes = 0;
+    char *cmd = NULL;
+    char *ret = NULL;
+    char *managed_system = phyp_driver->managed_system;
+    int vios_id = phyp_driver->vios_id;
+    char *char_ptr;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lsvg -lv %s -field lvname'", pool->name);
+    } else {
+        virBufferVSprintf(&buf, "lsvg -lv %s -field lvname", pool->name);
+    }
+    virBufferVSprintf(&buf, "|sed '1d'|sed '1d'|grep -c '^.*$'");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    if (virStrToLong_i(ret, &char_ptr, 10, &nvolumes) == -1)
+        goto err;
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return nvolumes;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+int
+phypDestroyStoragePool(virStoragePoolPtr pool)
+{
+    virConnectPtr conn = pool->conn;
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    int vios_id = phyp_driver->vios_id;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    char *cmd = NULL;
+    char *ret = NULL;
+    int exit_status = 0;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'rmsp %s'", pool->name);
+    } else {
+        virBufferVSprintf(&buf, "'rmsp %s'", pool->name);
+    }
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    if (virAsprintf(&cmd,
+                    "viosvrcmd -m %s --id %d -c "
+                    "'rmsp %s'", managed_system, vios_id,
+                    pool->name) < 0) {
+        virReportOOMError();
+        goto err;
+    }
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0) {
+        VIR_ERROR("%s\"%s\"", "Unable to create Storage Pool. Reason: ",
+                  ret);
+        goto err;
+    }
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+static int
+phypBuildStoragePool(virConnectPtr conn, virStoragePoolDefPtr def)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    virStoragePoolSource source = def->source;
+    int vios_id = phyp_driver->vios_id;
+    int system_type = phyp_driver->system_type;
+    char *managed_system = phyp_driver->managed_system;
+    char *cmd = NULL;
+    char *ret = NULL;
+    int exit_status = 0;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'mksp -f %schild %s'", def->name,
+                          source.adapter);
+    } else {
+        virBufferVSprintf(&buf, "mksp -f %schild %s", def->name,
+                          source.adapter);
+    }
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0) {
+        VIR_ERROR("%s\"%s\"", "Unable to create Storage Pool. Reason: ",
+                  ret);
+        goto err;
+    }
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+
+}
+
+virStoragePoolPtr
+phypStoragePoolCreateXML(virConnectPtr conn,
+                         const char *xml,
+                         unsigned int flags ATTRIBUTE_UNUSED)
+{
+
+    virStoragePoolDefPtr def = NULL;
+    virStoragePoolPtr sp = NULL;
+
+    if (!(def = virStoragePoolDefParseString(xml)))
+        goto err;
+
+    /* checking if this name already exists on this system */
+    if (phypStoragePoolLookupByName(conn, def->name) != NULL) {
+        VIR_WARN0("StoragePool name already exists.");
+        goto err;
+    }
+
+    /* checking if ID or UUID already exists on this system */
+    if (phypGetStoragePoolLookUpByUUID(conn, def->uuid) != NULL) {
+        VIR_WARN0("StoragePool uuid already exists.");
+        goto err;
+    }
+
+    if ((sp = virGetStoragePool(conn, def->name, def->uuid)) == NULL)
+        goto err;
+
+    if (phypBuildStoragePool(conn, def) == -1)
+        goto err;
+
+    return sp;
+
+  err:
+    virStoragePoolDefFree(def);
+    if (sp)
+        virUnrefStoragePool(sp);
+    return NULL;
+}
+
+char *
+phypGetStoragePoolXMLDesc(virStoragePoolPtr pool,
+                          unsigned int flags ATTRIBUTE_UNUSED)
+{
+    virStoragePoolDef def;
+    memset(&def, 0, sizeof(virStoragePoolDef));
+
+    if (pool->name != NULL)
+        def.name = pool->name;
+    else {
+        VIR_ERROR("%s", "Unable to determine storage pool's name.");
+        goto err;
+    }
+
+    if (memmove(def.uuid, pool->uuid, VIR_UUID_BUFLEN) == NULL) {
+        VIR_ERROR("%s", "Unable to determine storage pool's uuid.");
+        goto err;
+    }
+
+    if ((def.capacity =
+         phypGetStoragePoolSize(pool->conn, pool->name)) == -1) {
+        VIR_ERROR("%s", "Unable to determine storage pools's size.");
+        goto err;
+    }
+
+    /* Information not avaliable */
+    def.allocation = 0;
+    def.available = 0;
+
+    def.source.ndevice = 1;
+
+    /*XXX source adapter not working properly, should show hdiskX */
+    if ((def.source.adapter =
+         phypGetStoragePoolDevice(pool->conn, pool->name)) == NULL) {
+        VIR_ERROR("%s",
+                  "Unable to determine storage pools's source adapter.");
+        goto err;
+    }
+
+    return virStoragePoolDefFormat(&def);
+
+  err:
+    return NULL;
+}
+
+static int
+phypGetStoragePoolUUID(virConnectPtr conn, unsigned char *uuid,
+                       const char *name)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    char *cmd = NULL;
+    char *ret = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lsdev -dev %s -attr vgserial_id'", name);
+    } else {
+        virBufferVSprintf(&buf, "lsdev -dev %s -attr vgserial_id", name);
+    }
+    virBufferVSprintf(&buf, "|sed '1d'|sed '1d'");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    if (memmove(uuid, ret, VIR_UUID_BUFLEN) == NULL)
+        goto err;
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+virStoragePoolPtr
+phypGetStoragePoolLookUpByUUID(virConnectPtr conn,
+                               const unsigned char *uuid)
+{
+    virStoragePoolPtr sp = NULL;
+    int npools = 0;
+    int gotpools = 0;
+    char **pools = NULL;
+    unsigned int i = 0;
+    unsigned char *local_uuid = NULL;
+
+    if (VIR_ALLOC_N(local_uuid, VIR_UUID_BUFLEN) < 0) {
+        virReportOOMError();
+        goto err;
+    }
+
+    if ((npools = phypNumOfStoragePools(conn)) == -1) {
+        virReportOOMError();
+        goto err;
+    }
+
+    if (VIR_ALLOC_N(pools, npools) < 0) {
+        virReportOOMError();
+        goto err;
+    }
+
+    if ((gotpools = phypListStoragePools(conn, pools, npools)) == -1) {
+        virReportOOMError();
+        goto err;
+    }
+
+    if (gotpools != npools) {
+        virReportOOMError();
+        goto err;
+    }
+
+    for (i = 0; i < gotpools; i++) {
+        if (phypGetStoragePoolUUID(conn, local_uuid, pools[i]) == -1)
+            continue;
+
+        if (STREQLEN((char *) local_uuid, (char *) uuid, VIR_UUID_BUFLEN)) {
+            sp = virGetStoragePool(conn, pools[i], uuid);
+            VIR_FREE(local_uuid);
+            VIR_FREE(pools);
+
+            if (sp)
+                return sp;
+            else
+                goto err;
+        }
+    }
+
+  err:
+    VIR_FREE(local_uuid);
+    VIR_FREE(pools);
+    return NULL;
+}
+
+virStoragePoolPtr
+phypStoragePoolLookupByName(virConnectPtr conn, const char *name)
+{
+    unsigned char uuid[VIR_UUID_BUFLEN];
+
+    if (phypGetStoragePoolUUID(conn, uuid, name) == -1)
+        return NULL;
+
+    return virGetStoragePool(conn, name, uuid);
+}
+
+int
+phypNumOfStoragePools(virConnectPtr conn)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    int system_type = phyp_driver->system_type;
+    int exit_status = 0;
+    int nsp = 0;
+    char *cmd = NULL;
+    char *ret = NULL;
+    char *managed_system = phyp_driver->managed_system;
+    int vios_id = phyp_driver->vios_id;
+    char *char_ptr;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lsvg'");
+    } else {
+        virBufferVSprintf(&buf, "lsvg");
+    }
+    virBufferVSprintf(&buf, "grep -c '^.*$'");
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    if (virStrToLong_i(ret, &char_ptr, 10, &nsp) == -1)
+        goto err;
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return nsp;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+int
+phypListStoragePools(virConnectPtr conn, char **const pools, int npools)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    int got = 0;
+    int i;
+    char *cmd = NULL;
+    char *ret = NULL;
+    char *storage_pools = NULL;
+    char *char_ptr2 = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (system_type == HMC) {
+        virBufferVSprintf(&buf, "viosvrcmd -m %s --id %d -c ",
+                          managed_system, vios_id);
+        virBufferVSprintf(&buf, "'lsvg'");
+    } else {
+        virBufferVSprintf(&buf, "lsvg");
+    }
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    /* I need to parse the textual return in order to get the storage pools */
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+    else {
+        storage_pools = ret;
+
+        while (got < npools) {
+            char_ptr2 = strchr(storage_pools, '\n');
+
+            if (char_ptr2) {
+                *char_ptr2 = '\0';
+                if ((pools[got++] = strdup(storage_pools)) == NULL) {
+                    virReportOOMError();
+                    goto err;
+                }
+                char_ptr2++;
+                storage_pools = char_ptr2;
+            } else
+                break;
+        }
+    }
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return got;
+
+  err:
+    for (i = 0; i < got; i++)
+        VIR_FREE(pools[i]);
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+virDrvOpenStatus
+phypStorageOpen(virConnectPtr conn ATTRIBUTE_UNUSED,
+                virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                int flags ATTRIBUTE_UNUSED)
+{
+    return VIR_DRV_OPEN_SUCCESS;
+}
+
+int
+phypStorageClose(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    return 0;
+}
+
 int
 phypBuildLpar(virConnectPtr conn, virDomainDefPtr def)
 {
@@ -2360,6 +3990,10 @@ waitsocket(int socket_fd, LIBSSH2_SESSION * session)
 int
 phypRegister(void)
 {
-    virRegisterDriver(&phypDriver);
+    if (virRegisterDriver(&phypDriver) < 0)
+        return -1;
+    if (virRegisterStorageDriver(&phypStorageDriver) < 0)
+        return -1;
+
     return 0;
 }
diff --git a/src/phyp/phyp_driver.h b/src/phyp/phyp_driver.h
index 80ff0c3..2606fe4 100644
--- a/src/phyp/phyp_driver.h
+++ b/src/phyp/phyp_driver.h
@@ -75,6 +75,58 @@ struct _phyp_driver {
     char *managed_system;
 };
 
+
+/*
+ * Storage functions
+ * */
+virStorageVolPtr
+phypStorageVolCreateXML(virStoragePoolPtr pool, const char *xmldesc,
+                        unsigned int flags ATTRIBUTE_UNUSED);
+
+virStorageVolPtr phypVolumeLookupByPath (virConnectPtr pool, const char *path);
+
+char *phypVolumeGetXMLDesc(virStorageVolPtr vol,
+                           unsigned int flags ATTRIBUTE_UNUSED);
+
+char *phypVolumeGetPath(virStorageVolPtr vol);
+
+virStorageVolPtr phypVolumeLookupByName(virStoragePoolPtr pool,
+                                        const char *name);
+
+int phypStoragePoolListVolumes(virStoragePoolPtr pool,
+                               char **const volumes, int maxvolumes);
+
+int phypStoragePoolNumOfVolumes(virStoragePoolPtr pool);
+
+int phypDestroyStoragePool(virStoragePoolPtr pool);
+
+virStoragePoolPtr phypStoragePoolCreateXML(virConnectPtr conn,
+                                           const char *xml,
+                                           unsigned int flags
+                                           ATTRIBUTE_UNUSED);
+
+int phypNumOfStoragePools(virConnectPtr conn);
+
+int phypListStoragePools(virConnectPtr conn, char **const pools,
+                         int npools);
+
+virStoragePoolPtr phypStoragePoolLookupByName(virConnectPtr conn, const char *name);
+
+virStoragePoolPtr phypGetStoragePoolLookUpByUUID(virConnectPtr conn, const unsigned char *uuid);
+
+char * phypGetStoragePoolXMLDesc(virStoragePoolPtr pool, unsigned int flags);
+
+virDrvOpenStatus phypStorageOpen(virConnectPtr conn ATTRIBUTE_UNUSED,
+                                 virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                                 int flags ATTRIBUTE_UNUSED);
+
+int phypStorageClose(virConnectPtr conn);
+
+/*
+ * Driver functions
+ * */
+int phypAttachDevice(virDomainPtr domain, const char *xml);
+
 int phypCheckSPFreeSapce(virConnectPtr conn, int required_size, char *sp);
 
 int phypGetSystemType(virConnectPtr conn);
-- 
1.7.0.4




More information about the libvir-list mailing list