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