[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH] create() and destroy() support for Power Hypervisor



Hello Matthias,

First of all, I would like to thank you for all the comments you made. I tried to fix all those things up. But I still have some points to say:

Matthias Bolte wrote:
 >> +virCapsPtr
+phypCapsInit(void)
+{
+    struct utsname utsname;
+    virCapsPtr caps;
+    virCapsGuestPtr guest;
+
+    uname(&utsname);
+
+    if ((caps = virCapabilitiesNew(utsname.machine, 0, 0)) == NULL)
+        goto no_memory;
+
+    /* Some machines have problematic NUMA toplogy causing
+     * unexpected failures. We don't want to break the QEMU
+     * driver in this scenario, so log errors & carry on
+     */
+    if (nodeCapsInitNUMA(caps) < 0) {
+        virCapabilitiesFreeNUMAInfo(caps);
+        VIR_WARN0
+            ("Failed to query host NUMA topology, disabling NUMA capabilities");
+    }
+
+    /* XXX shouldn't 'borrow' KVM's prefix */
+    virCapabilitiesSetMacPrefix(caps, (unsigned char[]) {
+                                0x52, 0x54, 0x00});
+
+    if ((guest = virCapabilitiesAddGuest(caps,
+                                         "linux",
+                                         utsname.machine,
+                                         sizeof(int) == 4 ? 32 : 8,
+                                         NULL, NULL, 0, NULL)) == NULL)
+        goto no_memory;
+
+    if (virCapabilitiesAddGuestDomain(guest,
+                                      "phyp", NULL, NULL, 0, NULL) == NULL)
+        goto no_memory;
+
+    return caps;
+
+  no_memory:
+    virCapabilitiesFree(caps);
+    return NULL;
+}

As I understand the mechanics of this driver, the driver is designed
to operator from a client machine. The caps should describe the
capabilities of the hypervisor machine, but this functions initializes
the caps based on the machine where the driver is running.

Yep, you're right. I really need to think a better way to gather remote information about hypervisor. I missunderstood this concept, but I surely will have a fix for next the patch.

+
+int
+phypUUIDTable_ReadFile(virConnectPtr conn)
+{
+    phyp_driverPtr phyp_driver = conn->privateData;
+    uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+    unsigned int i = 0;
+    int fd = -1;
+    char *local_file;
+    int rc = 0;
+    char buffer[1024];
+
+    if (virAsprintf(&local_file, "./uuid_table") < 0) {
+        virReportOOMError(conn);
+        goto err;
+    }

virAsprintf for a fixed string is a bit of overkill, just use const
char *local_file = "./uuid_table".

In addition IMHO using a file in the current working directory for
temporary purpose isn't a good idea. Use a temporary path returned by
mktemp(), or even better try to solve the problem without using a
temporary file.

I agree with you. But this was the fastest way I found to get this part functional. I'll come up with a better solution in the next patch.

+int
+phypUUIDTable_WriteFile(virConnectPtr conn)
+{
+    phyp_driverPtr phyp_driver = conn->privateData;
+    uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+    unsigned int i = 0;
+    int fd = -1;
+    char *local_file;
+
+    if (virAsprintf(&local_file, "./uuid_table") < 0) {
+        virReportOOMError(conn);
+        goto err;
+    }

See comment in phypUUIDTable_ReadFile() about virAsprintf for a static
string etc.

+    if ((fd = creat(local_file, 0755)) == -1)
+        goto err;
+
+    for (i = 0; i < uuid_table->nlpars; i++) {
+        if (write(fd, &uuid_table->lpars[i]->id, sizeof(uuid_table->lpars[i]->id)) == -1)
+            VIR_WARN("%s", "Unable to write information to local file.");
+
+        if (write(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN) == -1)
+            VIR_WARN("%s", "Unable to write information to local file.");

Failed or incomplete writes shouldn't just warnings, they must be
error, because they corrupt the file.

Your binary file format is based on offsets. At offset 0 the first ID
is located, at offset 4 the first UUID, at offset 20 the next ID etc.
If you miss to write the appropriate number of bytes per item you'll
fail to read the data back in correctly.

+    }
+    close(fd);
+    goto exit;
+
+  exit:
+    VIR_FREE(local_file);
+    return 0;
+
+  err:
+    VIR_FREE(local_file);
+    return -1;
+}

It seems you just write the UUID table to a file to read it back in
again in phypUUIDTable_Push(). I would suggest to remove the detour
using the temporary file, but instead calculate the total size of the
data (uuid_table->nlpars * (sizeof (int) + VIR_UUID_BUFLEN)) for
libssh2_scp_send() and write the data directly via
libssh2_channel_write(). Basically merge phypUUIDTable_WriteFile()
into phypUUIDTable_Push() and phypUUIDTable_ReadFile() into
phypUUIDTable_Pull().

This also applies to above comment, I'll come up with a better way to handle this.

Change log:
* Now we have CPU management! Now I assume the user will know how to operate a HMC/IVM IBM system. This saves a lot of (useless) coding time for me :)
 * I solved all the other issues Matthias pointed.

Next steps:
* Find a better way to handle the uuid_table files without the need of use local temp files.
 * Storage management.

Any comments are always welcome. The comments made for this patch will be fixed in time for 0.7.3 version release.

[]'s

--
Eduardo Otubo
Software Engineer
Linux Technology Center
IBM Systems & Technology Group
Mobile: +55 19 8135 0885
eotubo linux vnet ibm com
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index ef465ed..5b5cb3c 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -25,6 +25,7 @@
 #include <config.h>
 
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <limits.h>
 #include <string.h>
 #include <strings.h>
@@ -39,6 +40,9 @@
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <netdb.h>
+#include <fcntl.h>
+#include <sys/utsname.h>
+#include <conf/domain_event.h>
 
 #include "internal.h"
 #include "util.h"
@@ -51,15 +55,12 @@
 #include "virterror_internal.h"
 #include "uuid.h"
 #include "domain_conf.h"
+#include "nodeinfo.h"
 
 #include "phyp_driver.h"
 
 #define VIR_FROM_THIS VIR_FROM_PHYP
 
-#define PHYP_CMD_DEBUG VIR_DEBUG("COMMAND:%s\n",cmd);
-
-static int escape_specialcharacters(char *src, char *dst, size_t dstlen);
-
 /*
  * URI: phyp://user [hmc|ivm]/managed_system
  * */
@@ -72,8 +73,23 @@ phypOpen(virConnectPtr conn,
     ConnectionData *connection_data = NULL;
     char *string;
     size_t len = 0;
-    uuid_dbPtr uuid_db = NULL;
     int internal_socket;
+    uuid_tablePtr uuid_table = NULL;
+    phyp_driverPtr phyp_driver = NULL;
+    char *char_ptr;
+    char *managed_system = conn->uri->path;
+
+    /* need to shift one byte in order to remove the first "/" of URI component */
+    if (managed_system[0] == '/')
+        managed_system++;
+
+    /* here we are handling only the first component of the path,
+     * so skipping the second:
+     * */
+    char_ptr = strchr(managed_system, '/');
+
+    if (char_ptr)
+        *char_ptr = '\0';
 
     if (!conn || !conn->uri)
         return VIR_DRV_OPEN_DECLINED;
@@ -95,7 +111,12 @@ phypOpen(virConnectPtr conn,
         return VIR_DRV_OPEN_ERROR;
     }
 
-    if (VIR_ALLOC(uuid_db) < 0) {
+    if (VIR_ALLOC(phyp_driver) < 0) {
+        virReportOOMError(conn);
+        goto failure;
+    }
+
+    if (VIR_ALLOC(uuid_table) < 0) {
         virReportOOMError(conn);
         goto failure;
     }
@@ -129,17 +150,29 @@ phypOpen(virConnectPtr conn,
     connection_data->session = session;
     connection_data->auth = auth;
 
-    uuid_db->nlpars = 0;
-    uuid_db->lpars = NULL;
+    uuid_table->nlpars = 0;
+    uuid_table->lpars = NULL;
 
-    conn->privateData = uuid_db;
+    phyp_driver->managed_system = managed_system;
+    phyp_driver->uuid_table = uuid_table;
+    if ((phyp_driver->caps = phypCapsInit()) == NULL) {
+        virReportOOMError(conn);
+        goto failure;
+    }
+
+    conn->privateData = phyp_driver;
     conn->networkPrivateData = connection_data;
-    init_uuid_db(conn);
+    if (phypUUIDTable_Init(conn) == -1)
+        goto failure;
+
+    if ((phyp_driver->vios_id = phypGetVIOSPartitionID(conn)) == -1)
+        goto failure;
 
     return VIR_DRV_OPEN_SUCCESS;
 
   failure:
-    VIR_FREE(uuid_db);
+    VIR_FREE(uuid_table);
+    VIR_FREE(uuid_table->lpars);
     VIR_FREE(connection_data);
     VIR_FREE(string);
 
@@ -150,11 +183,14 @@ static int
 phypClose(virConnectPtr conn)
 {
     ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
     LIBSSH2_SESSION *session = connection_data->session;
 
     libssh2_session_disconnect(session, "Disconnecting...");
     libssh2_session_free(session);
 
+    virCapabilitiesFree(phyp_driver->caps);
+    VIR_FREE(phyp_driver);
     VIR_FREE(connection_data);
     return 0;
 }
@@ -174,17 +210,16 @@ openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
     struct addrinfo hints;
     int ret;
 
-    memset (&hints, '\0', sizeof (hints));
+    memset(&hints, '\0', sizeof(hints));
     hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_protocol = 0;
 
-    ret = getaddrinfo (hostname, "22", &hints, &ai);
+    ret = getaddrinfo(hostname, "22", &hints, &ai);
     if (ret != 0) {
         virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
                       VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0,
-                      _("Error while getting %s address info"),
-                      hostname);
+                      _("Error while getting %s address info"), hostname);
         goto err;
     }
 
@@ -192,10 +227,10 @@ openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
     while (cur != NULL) {
         sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
         if (sock >= 0) {
-            if (connect (sock, cur->ai_addr, cur->ai_addrlen) == 0) {
+            if (connect(sock, cur->ai_addr, cur->ai_addrlen) == 0) {
                 goto connected;
             }
-            close (sock);
+            close(sock);
         }
         cur = cur->ai_next;
     }
@@ -203,10 +238,10 @@ openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
     virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
                   VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0,
                   _("Failed to connect to %s"), hostname);
-    freeaddrinfo (ai);
+    freeaddrinfo(ai);
     goto err;
 
-connected:
+  connected:
 
     (*internal_socket) = sock;
 
@@ -407,7 +442,6 @@ phypGetLparID(LIBSSH2_SESSION * session, const char *managed_system,
         virReportOOMError(conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
 
     const char *ret = phypExec(session, cmd, &exit_status, conn);
 
@@ -439,7 +473,6 @@ phypGetLparNAME(LIBSSH2_SESSION * session, const char *managed_system,
         virReportOOMError(conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
 
     char *ret = phypExec(session, cmd, &exit_status, conn);
 
@@ -463,7 +496,7 @@ phypGetLparNAME(LIBSSH2_SESSION * session, const char *managed_system,
 }
 
 
-/* Search into the uuid_db for a lpar_uuid given a lpar_id
+/* Search into the uuid_table for a lpar_uuid given a lpar_id
  * and a managed system name
  *
  * return:  0 - record found
@@ -472,11 +505,12 @@ phypGetLparNAME(LIBSSH2_SESSION * session, const char *managed_system,
 int
 phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn)
 {
-    uuid_dbPtr uuid_db = conn->privateData;
-    lparPtr *lpars = uuid_db->lpars;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+    lparPtr *lpars = uuid_table->lpars;
     unsigned int i = 0;
 
-    for (i = 0; i < uuid_db->nlpars; i++) {
+    for (i = 0; i < uuid_table->nlpars; i++) {
         if (lpars[i]->id == lpar_id) {
             memmove(uuid, lpars[i]->uuid, VIR_UUID_BUFLEN);
             return 0;
@@ -507,20 +541,21 @@ phypGetLparMem(virConnectPtr conn, const char *managed_system, int lpar_id,
 
     if (type) {
         if (virAsprintf(&cmd,
-                        "lshwres -m %s -r mem --level lpar -F curr_mem --filter lpar_ids=%d",
+                        "lshwres -m %s -r mem --level lpar -F curr_mem "
+                        "--filter lpar_ids=%d",
                         managed_system, lpar_id) < 0) {
             virReportOOMError(conn);
             goto err;
         }
     } else {
         if (virAsprintf(&cmd,
-                        "lshwres -m %s -r mem --level lpar -F curr_max_mem --filter lpar_ids=%d",
+                        "lshwres -m %s -r mem --level lpar -F "
+                        "curr_max_mem --filter lpar_ids=%d",
                         managed_system, lpar_id) < 0) {
             virReportOOMError(conn);
             goto err;
         }
     }
-    PHYP_CMD_DEBUG;
 
     char *ret = phypExec(session, cmd, &exit_status, conn);
 
@@ -550,19 +585,45 @@ phypGetLparMem(virConnectPtr conn, const char *managed_system, int lpar_id,
 unsigned long
 phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id)
 {
+    return phypGetLparCPUGeneric(conn, managed_system, lpar_id, 0);
+}
+
+static int
+phypGetLparCPUMAX(virDomainPtr dom)
+{
+    phyp_driverPtr phyp_driver = dom->conn->privateData;
+    char *managed_system = phyp_driver->managed_system;
+
+    return phypGetLparCPUGeneric(dom->conn, managed_system, dom->id, 1);
+}
+
+unsigned long
+phypGetLparCPUGeneric(virConnectPtr conn, const char *managed_system,
+                      int lpar_id, int type)
+{
     ConnectionData *connection_data = conn->networkPrivateData;
     LIBSSH2_SESSION *session = connection_data->session;
     char *cmd;
     int exit_status = 0;
     int vcpus = 0;
 
-    if (virAsprintf(&cmd,
-                    "lshwres -m %s -r proc --level lpar -F curr_procs --filter lpar_ids=%d",
-                    managed_system, lpar_id) < 0) {
-        virReportOOMError(conn);
-        goto err;
+    if (type) {
+        if (virAsprintf(&cmd,
+                        "lshwres -m %s -r proc --level lpar -F "
+                        "curr_max_procs --filter lpar_ids=%d",
+                        managed_system, lpar_id) < 0) {
+            virReportOOMError(conn);
+            goto err;
+        }
+    } else {
+        if (virAsprintf(&cmd,
+                        "lshwres -m %s -r proc --level lpar -F "
+                        "curr_procs --filter lpar_ids=%d",
+                        managed_system, lpar_id) < 0) {
+            virReportOOMError(conn);
+            goto err;
+        }
     }
-    PHYP_CMD_DEBUG;
     char *ret = phypExec(session, cmd, &exit_status, conn);
 
     if (ret == NULL)
@@ -599,12 +660,12 @@ phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
     int exit_status = 0;
 
     if (virAsprintf(&cmd,
-                    "lshwres -m %s -r virtualio --rsubtype scsi -F remote_slot_num --filter lpar_names=%s",
+                    "lshwres -m %s -r virtualio --rsubtype scsi -F "
+                    "remote_slot_num --filter lpar_names=%s",
                     managed_system, lpar_name) < 0) {
         virReportOOMError(conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
     char *ret = phypExec(session, cmd, &exit_status, conn);
 
     if (ret == NULL)
@@ -626,7 +687,7 @@ phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
 
   err:
     VIR_FREE(cmd);
-    return 0;
+    return -1;
 }
 
 char *
@@ -640,16 +701,16 @@ phypGetBackingDevice(virConnectPtr conn, const char *managed_system,
     int exit_status = 0;
 
     if ((remote_slot =
-         phypGetRemoteSlot(conn, managed_system, lpar_name)) == 0)
+         phypGetRemoteSlot(conn, managed_system, lpar_name)) == -1)
         goto err;
 
     if (virAsprintf(&cmd,
-                    "lshwres -m %s -r virtualio --rsubtype scsi -F backing_devices --filter slots=%d",
+                    "lshwres -m %s -r virtualio --rsubtype scsi -F "
+                    "backing_devices --filter slots=%d",
                     managed_system, remote_slot) < 0) {
         virReportOOMError(conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
 
     char *ret = phypExec(session, cmd, &exit_status, conn);
 
@@ -696,24 +757,12 @@ int
 phypGetLparState(virConnectPtr conn, unsigned int lpar_id)
 {
     ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
     LIBSSH2_SESSION *session = connection_data->session;
     char *cmd;
     int exit_status = 0;
     char *char_ptr = NULL;
-    char *managed_system = conn->uri->path;
-
-    /* need to shift one byte in order to remove the first "/" of URI component */
-    if (managed_system[0] == '/')
-        managed_system++;
-
-    /* here we are handling only the first component of the path,
-     * so skipping the second:
-     * */
-
-    char_ptr = strchr(managed_system, '/');
-
-    if (char_ptr)
-        *char_ptr = '\0';
+    char *managed_system = phyp_driver->managed_system;
 
     if (virAsprintf(&cmd,
                     "lssyscfg -r lpar -m %s -F state --filter lpar_ids=%d",
@@ -721,7 +770,6 @@ phypGetLparState(virConnectPtr conn, unsigned int lpar_id)
         virReportOOMError(conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
 
     char *ret = phypExec(session, cmd, &exit_status, conn);
 
@@ -752,27 +800,65 @@ phypGetLparState(virConnectPtr conn, unsigned int lpar_id)
 }
 
 int
+phypGetVIOSPartitionID(virConnectPtr conn)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *cmd;
+    int exit_status = 0;
+    int id = -1;
+    char *char_ptr;
+    char *managed_system = phyp_driver->managed_system;
+
+    if (virAsprintf(&cmd,
+                    "lssyscfg -m %s -r lpar -F lpar_id,lpar_env|grep "
+                    "vioserver|sed -s 's/,.*$//g'", managed_system) < 0) {
+        virReportOOMError(conn);
+        goto err;
+    }
+
+    char *ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    if (virStrToLong_i(ret, &char_ptr, 10, &id) == -1)
+        goto err;
+
+    return id;
+
+  err:
+    VIR_FREE(cmd);
+    return -1;
+}
+
+int
 phypDiskType(virConnectPtr conn, char *backing_device)
 {
+    phyp_driverPtr phyp_driver = conn->privateData;
     ConnectionData *connection_data = conn->networkPrivateData;
     LIBSSH2_SESSION *session = connection_data->session;
     char *cmd;
     int exit_status = 0;
+    char *char_ptr;
+    char *managed_system = phyp_driver->managed_system;
+    int vios_id = phyp_driver->vios_id;
 
     if (virAsprintf(&cmd,
-                    "ioscli lssp -field name type -fmt , -all|grep %s|sed -e 's/^.*,//g'",
-                    backing_device) < 0) {
+                    "viosvrcmd -m %s -p %d -c \"lssp -field name type "
+                    "-fmt , -all|grep %s|sed -e 's/^.*,//g'\"",
+                    managed_system, vios_id, backing_device) < 0) {
         virReportOOMError(conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
 
     char *ret = phypExec(session, cmd, &exit_status, conn);
 
     if (ret == NULL)
         goto err;
 
-    char *char_ptr = strchr(ret, '\n');
+    char_ptr = strchr(ret, '\n');
 
     if (char_ptr)
         *char_ptr = '\0';
@@ -805,12 +891,13 @@ static int
 phypNumDomainsGeneric(virConnectPtr conn, unsigned int type)
 {
     ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
     LIBSSH2_SESSION *session = connection_data->session;
     int exit_status = 0;
     int ndom = 0;
     char *char_ptr;
     char *cmd;
-    char *managed_system = conn->uri->path;
+    char *managed_system = phyp_driver->managed_system;
     const char *state;
 
     if (type == 0)
@@ -820,26 +907,12 @@ phypNumDomainsGeneric(virConnectPtr conn, unsigned int type)
     else
         state = " ";
 
-    /* need to shift one byte in order to remove the first "/" of URI component */
-    if (managed_system[0] == '/')
-        managed_system++;
-
-    /* here we are handling only the first component of the path,
-     * so skipping the second:
-     * */
-
-    char_ptr = strchr(managed_system, '/');
-
-    if (char_ptr)
-        *char_ptr = '\0';
-
     if (virAsprintf(&cmd,
-                    "lssyscfg -r lpar -m %s -F lpar_id,state %s |grep -c ^[0-9]*",
-                    managed_system, state) < 0) {
+                    "lssyscfg -r lpar -m %s -F lpar_id,state %s |grep -c "
+                    "^[0-9]*", managed_system, state) < 0) {
         virReportOOMError(conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
 
     char *ret = phypExec(session, cmd, &exit_status, conn);
 
@@ -874,15 +947,16 @@ phypNumDomains(virConnectPtr conn)
  * in different states: Running, and all:
  *
  * type: 0 - Running
- *       * - all
+ *       1 - all
  * */
 static int
 phypListDomainsGeneric(virConnectPtr conn, int *ids, int nids,
                        unsigned int type)
 {
     ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
     LIBSSH2_SESSION *session = connection_data->session;
-    char *managed_system = conn->uri->path;
+    char *managed_system = phyp_driver->managed_system;
     int exit_status = 0;
     int got = 0;
     char *char_ptr;
@@ -896,18 +970,6 @@ phypListDomainsGeneric(virConnectPtr conn, int *ids, int nids,
     else
         state = " ";
 
-    /* need to shift one byte in order to remove the first "/" of URI component */
-    if (managed_system[0] == '/')
-        managed_system++;
-
-    /* here we are handling only the first component of the path,
-     * so skipping the second:
-     * */
-    char_ptr = strchr(managed_system, '/');
-
-    if (char_ptr)
-        *char_ptr = '\0';
-
     memset(id_c, 0, 10);
 
     if (virAsprintf
@@ -917,7 +979,6 @@ phypListDomainsGeneric(virConnectPtr conn, int *ids, int nids,
         virReportOOMError(conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
     char *ret = phypExec(session, cmd, &exit_status, conn);
 
     /* I need to parse the textual return in order to get the ret */
@@ -957,34 +1018,21 @@ static int
 phypListDefinedDomains(virConnectPtr conn, char **const names, int nnames)
 {
     ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
     LIBSSH2_SESSION *session = connection_data->session;
-    char *managed_system = conn->uri->path;
+    char *managed_system = phyp_driver->managed_system;
     int exit_status = 0;
     int got = 0;
-    char *char_ptr = NULL;
     char *cmd;
     char *domains;
 
-    /* need to shift one byte in order to remove the first "/" of URI component */
-    if (managed_system[0] == '/')
-        managed_system++;
-
-    /* here we are handling only the first component of the path,
-     * so skipping the second:
-     * */
-    char_ptr = strchr(managed_system, '/');
-
-    if (char_ptr)
-        *char_ptr = '\0';
-
     if (virAsprintf
         (&cmd,
-         "lssyscfg -r lpar -m %s -F name,state | grep \"Not Activated\" | sed -e 's/,.*$//g'",
-         managed_system) < 0) {
+         "lssyscfg -r lpar -m %s -F name,state | grep \"Not Activated\" | "
+         "sed -e 's/,.*$//g'", managed_system) < 0) {
         virReportOOMError(conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
 
     char *ret = phypExec(session, cmd, &exit_status, conn);
 
@@ -1030,29 +1078,18 @@ static virDomainPtr
 phypDomainLookupByName(virConnectPtr conn, const char *lpar_name)
 {
     ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
     LIBSSH2_SESSION *session = connection_data->session;
     virDomainPtr dom = NULL;
     int lpar_id = 0;
-    char *managed_system = conn->uri->path;
+    char *managed_system = phyp_driver->managed_system;
     unsigned char *lpar_uuid = NULL;
 
     if (VIR_ALLOC_N(lpar_uuid, VIR_UUID_BUFLEN) < 0)
         virReportOOMError(dom->conn);
 
-    /* need to shift one byte in order to remove the first "/" of uri component */
-    if (managed_system[0] == '/')
-        managed_system++;
-
-    /* here we are handling only the first component of the path,
-     * so skipping the second:
-     * */
-    char *char_ptr = strchr(managed_system, '/');
-
-    if (char_ptr)
-        *char_ptr = '\0';
-
     lpar_id = phypGetLparID(session, managed_system, lpar_name, conn);
-    if (lpar_id < 0)
+    if (lpar_id == -1)
         goto err;
 
     if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1)
@@ -1075,27 +1112,16 @@ static virDomainPtr
 phypDomainLookupByID(virConnectPtr conn, int lpar_id)
 {
     ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
     LIBSSH2_SESSION *session = connection_data->session;
     virDomainPtr dom = NULL;
-    char *managed_system = conn->uri->path;
+    char *managed_system = phyp_driver->managed_system;
     int exit_status = 0;
     unsigned char *lpar_uuid = NULL;
 
     if (VIR_ALLOC_N(lpar_uuid, VIR_UUID_BUFLEN) < 0)
         virReportOOMError(dom->conn);
 
-    /* need to shift one byte in order to remove the first "/" of uri component */
-    if (managed_system[0] == '/')
-        managed_system++;
-
-    /* here we are handling only the first component of the path,
-     * so skipping the second:
-     * */
-    char *char_ptr = strchr(managed_system, '/');
-
-    if (char_ptr)
-        *char_ptr = '\0';
-
     char *lpar_name = phypGetLparNAME(session, managed_system, lpar_id,
                                       conn);
 
@@ -1124,10 +1150,11 @@ static char *
 phypDomainDumpXML(virDomainPtr dom, int flags)
 {
     ConnectionData *connection_data = dom->conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = dom->conn->privateData;
     LIBSSH2_SESSION *session = connection_data->session;
     virDomainDefPtr def = NULL;
     char *ret = NULL;
-    char *managed_system = dom->conn->uri->path;
+    char *managed_system = phyp_driver->managed_system;
     unsigned char *lpar_uuid = NULL;
 
     if (VIR_ALLOC_N(lpar_uuid, VIR_UUID_BUFLEN) < 0)
@@ -1136,18 +1163,6 @@ phypDomainDumpXML(virDomainPtr dom, int flags)
     if (VIR_ALLOC(def) < 0)
         virReportOOMError(dom->conn);
 
-    /* need to shift one byte in order to remove the first "/" of uri component */
-    if (managed_system[0] == '/')
-        managed_system++;
-
-    /* here we are handling only the first component of the path,
-     * so skipping the second:
-     * */
-    char *char_ptr = strchr(managed_system, '/');
-
-    if (char_ptr)
-        *char_ptr = '\0';
-
     def->virtType = VIR_DOMAIN_VIRT_PHYP;
     def->id = dom->id;
 
@@ -1189,33 +1204,24 @@ phypDomainDumpXML(virDomainPtr dom, int flags)
 
     ret = virDomainDefFormat(dom->conn, def, flags);
 
-  err:
-    VIR_FREE(def);
+    virDomainDefFree(def);
     return ret;
+
+  err:
+    virDomainDefFree(def);
+    return NULL;
 }
 
 static int
 phypDomainResume(virDomainPtr dom)
 {
     ConnectionData *connection_data = dom->conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = dom->conn->privateData;
     LIBSSH2_SESSION *session = connection_data->session;
-    char *managed_system = dom->conn->uri->path;
+    char *managed_system = phyp_driver->managed_system;
     int exit_status = 0;
-    char *char_ptr = NULL;
     char *cmd;
 
-    /* need to shift one byte in order to remove the first "/" of URI component */
-    if (managed_system[0] == '/')
-        managed_system++;
-
-    /* here we are handling only the first component of the path,
-     * so skipping the second:
-     * */
-    char_ptr = strchr(managed_system, '/');
-
-    if (char_ptr)
-        *char_ptr = '\0';
-
     if (virAsprintf
         (&cmd,
          "chsysstate -m %s -r lpar -o on --id %d -f %s",
@@ -1223,39 +1229,32 @@ phypDomainResume(virDomainPtr dom)
         virReportOOMError(dom->conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
 
     char *ret = phypExec(session, cmd, &exit_status, dom->conn);
 
-  err:
+    if (exit_status < 0)
+        goto err;
+
     VIR_FREE(cmd);
     VIR_FREE(ret);
     return 0;
 
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
 }
 
 static int
 phypDomainShutdown(virDomainPtr dom)
 {
     ConnectionData *connection_data = dom->conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = dom->conn->privateData;
     LIBSSH2_SESSION *session = connection_data->session;
-    char *managed_system = dom->conn->uri->path;
+    char *managed_system = phyp_driver->managed_system;
     int exit_status = 0;
-    char *char_ptr = NULL;
     char *cmd;
 
-    /* need to shift one byte in order to remove the first "/" of URI component */
-    if (managed_system[0] == '/')
-        managed_system++;
-
-    /* here we are handling only the first component of the path,
-     * so skipping the second:
-     * */
-    char_ptr = strchr(managed_system, '/');
-
-    if (char_ptr)
-        *char_ptr = '\0';
-
     if (virAsprintf
         (&cmd,
          "chsysstate -m %s -r lpar -o shutdown --id %d",
@@ -1263,33 +1262,27 @@ phypDomainShutdown(virDomainPtr dom)
         virReportOOMError(dom->conn);
         goto err;
     }
-    PHYP_CMD_DEBUG;
 
     char *ret = phypExec(session, cmd, &exit_status, dom->conn);
 
-  err:
+    if (exit_status < 0)
+        goto err;
+
     VIR_FREE(cmd);
     VIR_FREE(ret);
     return 0;
 
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
 }
 
 static int
 phypDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
 {
-    char *managed_system = dom->conn->uri->path;
-
-    /* need to shift one byte in order to remove the first "/" of uri component */
-    if (managed_system[0] == '/')
-        managed_system++;
-
-    /* here we are handling only the first component of the path,
-     * so skipping the second:
-     * */
-    char *char_ptr = strchr(managed_system, '/');
-
-    if (char_ptr)
-        *char_ptr = '\0';
+    phyp_driverPtr phyp_driver = dom->conn->privateData;
+    char *managed_system = phyp_driver->managed_system;
 
     info->state = phypGetLparState(dom->conn, dom->id);
 
@@ -1306,6 +1299,215 @@ phypDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
         VIR_WARN("%s", "Unable to determine domain's CPU.");
 
     return 0;
+}
+
+static int
+phypDomainDestroy(virDomainPtr dom)
+{
+    ConnectionData *connection_data = dom->conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = dom->conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int exit_status = 0;
+    char *cmd;
+
+    if (virAsprintf
+        (&cmd,
+         "rmsyscfg -m %s -r lpar --id %d", managed_system, dom->id) < 0) {
+        virReportOOMError(dom->conn);
+        goto err;
+    }
+
+    char *ret = phypExec(session, cmd, &exit_status, dom->conn);
+
+    if (exit_status < 0)
+        goto err;
+
+    if (phypUUIDTable_RemLpar(dom->conn, dom->id) == -1)
+        goto err;
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
+
+}
+
+static virDomainPtr
+phypDomainCreateAndStart(virConnectPtr conn,
+                         const char *xml,
+                         unsigned int flags ATTRIBUTE_UNUSED)
+{
+
+    ConnectionData *connection_data = conn->networkPrivateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    virDomainDefPtr def = NULL;
+    virDomainPtr dom = NULL;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+    lparPtr *lpars = uuid_table->lpars;
+    unsigned int i = 0;
+    char *managed_system = phyp_driver->managed_system;
+
+    if (!(def = virDomainDefParseString(conn, phyp_driver->caps, xml,
+                                        VIR_DOMAIN_XML_INACTIVE)))
+        goto err;
+
+    /* checking if this name already exists on this system */
+    if (phypGetLparID(session, managed_system, def->name, conn) == -1) {
+        VIR_WARN("%s", "LPAR name already exists.");
+        goto err;
+    }
+
+    /* checking if ID or UUID already exists on this system */
+    for (i = 0; i < uuid_table->nlpars; i++) {
+        if (lpars[i]->id == def->id || lpars[i]->uuid == def->uuid) {
+            VIR_WARN("%s", "LPAR ID or UUID already exists.");
+            goto err;
+        }
+    }
+
+    dom->conn = conn;
+    dom->name = def->name;
+    dom->id = def->id;
+    memmove(dom->uuid, def->uuid, VIR_UUID_BUFLEN);
+
+    if ((dom = virGetDomain(conn, def->name, def->uuid)) == NULL)
+        goto err;
+
+    if (phypBuildLpar(conn, def) == -1)
+        goto err;
+
+    if (phypDomainResume(dom) == -1)
+        goto err;
+
+    return dom;
+
+  err:
+    virDomainDefFree(def);
+    VIR_FREE(dom);
+    return NULL;
+}
+
+static char *
+phypConnectGetCapabilities(virConnectPtr conn)
+{
+    phyp_driverPtr phyp_driver = conn->privateData;
+    char *xml;
+
+    if ((xml = virCapabilitiesFormatXML(phyp_driver->caps)) == NULL)
+        virReportOOMError(conn);
+
+    return xml;
+}
+
+virCapsPtr
+phypCapsInit(void)
+{
+    struct utsname utsname;
+    virCapsPtr caps;
+    virCapsGuestPtr guest;
+
+    uname(&utsname);
+
+    if ((caps = virCapabilitiesNew(utsname.machine, 0, 0)) == NULL)
+        goto no_memory;
+
+    /* Some machines have problematic NUMA toplogy causing
+     * unexpected failures. We don't want to break the QEMU
+     * driver in this scenario, so log errors & carry on
+     */
+    if (nodeCapsInitNUMA(caps) < 0) {
+        virCapabilitiesFreeNUMAInfo(caps);
+        VIR_WARN0
+            ("Failed to query host NUMA topology, disabling NUMA capabilities");
+    }
+
+    /* XXX shouldn't 'borrow' KVM's prefix */
+    virCapabilitiesSetMacPrefix(caps, (unsigned char[]) {
+                                0x52, 0x54, 0x00});
+
+    if ((guest = virCapabilitiesAddGuest(caps,
+                                         "linux",
+                                         utsname.machine,
+                                         sizeof(int) == 4 ? 32 : 8,
+                                         NULL, NULL, 0, NULL)) == NULL)
+        goto no_memory;
+
+    if (virCapabilitiesAddGuestDomain(guest,
+                                      "phyp", NULL, NULL, 0, NULL) == NULL)
+        goto no_memory;
+
+    return caps;
+
+  no_memory:
+    virCapabilitiesFree(caps);
+    return NULL;
+}
+
+static int
+phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
+{
+    ConnectionData *connection_data = dom->conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = dom->conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int exit_status = 0;
+    char *cmd;
+    char operation;
+    unsigned long ncpus = 0;
+    unsigned int amount = 0;
+
+    if ((ncpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
+        goto err;
+
+    if (nvcpus > phypGetLparCPUMAX(dom)) {
+        VIR_ERROR("%s",
+                  "You are trying to set a number of CPUs bigger than "
+                  "the max possible..");
+        goto err;
+    }
+
+    if (ncpus > nvcpus) {
+        operation = 'r';
+        amount = nvcpus - ncpus;
+    } else if (ncpus < nvcpus) {
+        operation = 'a';
+        amount = nvcpus - ncpus;
+    } else
+        goto exit;
+
+    if (virAsprintf
+        (&cmd,
+         "chhwres -r proc -m %s --id %d -o %c --procunits %d 2>&1 |sed"
+         "-e 's/^.*\\([0-9]\\+.[0-9]\\+\\).*$/\\1/g'",
+         managed_system, dom->id, operation, amount) < 0) {
+        virReportOOMError(dom->conn);
+        goto err;
+    }
+
+    char *ret = phypExec(session, cmd, &exit_status, dom->conn);
+
+    if (exit_status < 0) {
+        VIR_ERROR("%s",
+                  "Possibly you don't have IBM Tools installed in your LPAR."
+                  "Contact your support to enable this feature.");
+        goto err;
+    }
+
+  exit:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
 
 }
 
@@ -1320,10 +1522,10 @@ virDriver phypDriver = {
     NULL,                       /* getHostname */
     NULL,                       /* getMaxVcpus */
     NULL,                       /* nodeGetInfo */
-    NULL,                       /* getCapabilities */
+    phypConnectGetCapabilities, /* getCapabilities */
     phypListDomains,            /* listDomains */
     phypNumDomains,             /* numOfDomains */
-    NULL,                       /* domainCreateXML */
+    phypDomainCreateAndStart,   /* domainCreateXML */
     phypDomainLookupByID,       /* domainLookupByID */
     NULL,                       /* domainLookupByUUID */
     phypDomainLookupByName,     /* domainLookupByName */
@@ -1331,7 +1533,7 @@ virDriver phypDriver = {
     phypDomainResume,           /* domainResume */
     phypDomainShutdown,         /* domainShutdown */
     NULL,                       /* domainReboot */
-    NULL,                       /* domainDestroy */
+    phypDomainDestroy,          /* domainDestroy */
     NULL,                       /* domainGetOSType */
     NULL,                       /* domainGetMaxMemory */
     NULL,                       /* domainSetMaxMemory */
@@ -1340,10 +1542,10 @@ virDriver phypDriver = {
     NULL,                       /* domainSave */
     NULL,                       /* domainRestore */
     NULL,                       /* domainCoreDump */
-    NULL,                       /* domainSetVcpus */
+    phypDomainSetCPU,           /* domainSetVcpus */
     NULL,                       /* domainPinVcpu */
     NULL,                       /* domainGetVcpus */
-    NULL,                       /* domainGetMaxVcpus */
+    phypGetLparCPUMAX,          /* domainGetMaxVcpus */
     NULL,                       /* domainGetSecurityLabel */
     NULL,                       /* nodeGetSecurityModel */
     phypDomainDumpXML,          /* domainDumpXML */
@@ -1381,52 +1583,424 @@ virDriver phypDriver = {
 };
 
 int
-phypRegister(void)
+phypBuildLpar(virConnectPtr conn, virDomainDefPtr def)
 {
-    virRegisterDriver(&phypDriver);
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    char *cmd;
+    int exit_status = 0;
+
+    if (virAsprintf
+        (&cmd,
+         "mksyscfg -m %s -r lpar --id %d -i name=%s,min_mem=%d,desired_mem=%d,"
+         "max_mem=%d,desired_procs=%d,virtual_scsi_adapters=%s",
+         managed_system, def->id, def->name, (int) def->memory,
+         (int) def->memory, (int) def->maxmem, (int) def->vcpus,
+         def->disks[0]->src) < 0) {
+        virReportOOMError(conn);
+        goto err;
+    }
+
+    char *ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0) {
+        VIR_ERROR("%s\"%s\"", "Unable to create LPAR. Reason: ", ret);
+        goto err;
+    }
+
+    if (phypUUIDTable_AddLpar(conn, def->uuid, def->id) == -1) {
+        VIR_ERROR("%s", "Unable to add LPAR to the table");
+        goto err;
+    }
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return 0;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+int
+phypUUIDTable_RemLpar(virConnectPtr conn, int id)
+{
+    phyp_driverPtr phyp_driver = conn->privateData;
+    uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+    unsigned int i = 0;
+
+    for (i = 0; i <= uuid_table->nlpars; i++) {
+        if (uuid_table->lpars[i]->id == id) {
+            uuid_table->lpars[i]->id = -1;
+            if (!memset(uuid_table->lpars[i]->uuid, '0', VIR_UUID_BUFLEN))
+                goto exit;
+        }
+    }
+
+    if (phypUUIDTable_WriteFile(conn) == -1)
+        goto err;
+
+    if (phypUUIDTable_Push(conn) == -1)
+        goto err;
+
+  exit:
+    return 0;
+
+  err:
+    return -1;
+}
+
+int
+phypUUIDTable_AddLpar(virConnectPtr conn, unsigned char *uuid, int id)
+{
+    phyp_driverPtr phyp_driver = conn->privateData;
+    uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+
+    uuid_table->nlpars++;
+    unsigned int i = uuid_table->nlpars;
+    i--;
+
+    if (VIR_REALLOC_N(uuid_table->lpars, uuid_table->nlpars) < 0) {
+        virReportOOMError(conn);
+        goto err;
+    }
+
+    if (VIR_ALLOC(uuid_table->lpars[i]) < 0) {
+        virReportOOMError(conn);
+        goto err;
+    }
+
+    uuid_table->lpars[i]->id = id;
+    if (memmove(uuid_table->lpars[i]->uuid, uuid, VIR_UUID_BUFLEN) == NULL)
+        goto err;
+
+    if (phypUUIDTable_WriteFile(conn) == -1)
+        goto err;
+
+    if (phypUUIDTable_Push(conn) == -1)
+        goto err;
+
+    return 0;
+
+  err:
+    return -1;
+}
+
+int
+phypUUIDTable_ReadFile(virConnectPtr conn)
+{
+    phyp_driverPtr phyp_driver = conn->privateData;
+    uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+    unsigned int i = 0;
+    int fd = -1;
+    char local_file[] = "./uuid_table";
+    int rc = 0;
+    char buffer[1024];
+
+    if ((fd = open(local_file, O_RDONLY)) == -1) {
+        VIR_WARN("%s", "Unable to write information to local file.");
+        goto err;
+    }
+
+    /* Creating a new data base and writing to local file */
+    if (VIR_ALLOC_N(uuid_table->lpars, uuid_table->nlpars) >= 0) {
+        for (i = 0; i < uuid_table->nlpars; i++) {
+
+            rc = read(fd, buffer, sizeof(int));
+            if (rc == sizeof(int)) {
+                if (VIR_ALLOC(uuid_table->lpars[i]) < 0)
+                    virReportOOMError(conn);
+                uuid_table->lpars[i]->id = (*buffer);
+            } else {
+                VIR_WARN("%s",
+                         "Unable to read from information to local file.");
+                goto err;
+            }
+
+            rc = read(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN);
+            if (rc != VIR_UUID_BUFLEN) {
+                VIR_WARN("%s",
+                         "Unable to read information to local file.");
+                goto err;
+            }
+        }
+    }
+
+    close(fd);
     return 0;
+
+  err:
+    close(fd);
+    return -1;
 }
 
-void
-init_uuid_db(virConnectPtr conn)
+int
+phypUUIDTable_WriteFile(virConnectPtr conn)
 {
-    uuid_dbPtr uuid_db;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+    unsigned int i = 0;
+    int fd = -1;
+    char local_file[] = "./uuid_table";
+
+    if ((fd = creat(local_file, 0755)) == -1)
+        goto err;
+
+    for (i = 0; i < uuid_table->nlpars; i++) {
+        if (write
+            (fd, &uuid_table->lpars[i]->id,
+             sizeof(uuid_table->lpars[i]->id)) == -1)
+            VIR_ERROR("%s", "Unable to write information to local file.");
+
+        if (write(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN) == -1)
+            VIR_ERROR("%s", "Unable to write information to local file.");
+    }
+
+    close(fd);
+    return 0;
+
+  err:
+    close(fd);
+    return -1;
+}
+
+int
+phypUUIDTable_Init(virConnectPtr conn)
+{
+    uuid_tablePtr uuid_table;
+    phyp_driverPtr phyp_driver;
     int nids = 0;
     int *ids = NULL;
     unsigned int i = 0;
 
     if ((nids = phypNumDomainsGeneric(conn, 2)) == 0)
-        goto exit;
-
-    if (VIR_ALLOC_N(ids, nids) < 0)
-        virReportOOMError(conn);
+        goto err;
 
-    if (VIR_ALLOC(uuid_db) < 0)
+    if (VIR_ALLOC_N(ids, nids) < 0) {
         virReportOOMError(conn);
+        goto err;
+    }
 
     if (phypListDomainsGeneric(conn, ids, nids, 1) == 0)
+        goto err;
+
+    phyp_driver = conn->privateData;
+    uuid_table = phyp_driver->uuid_table;
+    uuid_table->nlpars = nids;
+
+    /* try to get the table from server */
+    if (phypUUIDTable_Pull(conn) == -1) {
+        /* file not found in the server, creating a new one */
+        if (VIR_ALLOC_N(uuid_table->lpars, uuid_table->nlpars) >= 0) {
+            for (i = 0; i < uuid_table->nlpars; i++) {
+                if (VIR_ALLOC(uuid_table->lpars[i]) < 0) {
+                    virReportOOMError(conn);
+                    goto err;
+                }
+                uuid_table->lpars[i]->id = ids[i];
+
+                if (virUUIDGenerate(uuid_table->lpars[i]->uuid) < 0)
+                    VIR_WARN("%s %d", "Unable to generate UUID for domain",
+                             ids[i]);
+            }
+        } else
+            goto err;
+
+        if (phypUUIDTable_WriteFile(conn) == -1)
+            goto err;
+
+        if (phypUUIDTable_Push(conn) == -1)
+            goto err;
+    } else {
+        if (phypUUIDTable_ReadFile(conn) == -1)
+            goto err;
         goto exit;
+    }
 
-    uuid_db = conn->privateData;
-    uuid_db->nlpars = nids;
+  exit:
+    VIR_FREE(ids);
+    return 0;
 
-    if (VIR_ALLOC_N(uuid_db->lpars, uuid_db->nlpars) >= 0) {
-        for (i = 0; i < uuid_db->nlpars; i++) {
-            if (VIR_ALLOC(uuid_db->lpars[i]) < 0)
-                virReportOOMError(conn);
-            uuid_db->lpars[i]->id = ids[i];
+  err:
+    VIR_FREE(ids);
+    return -1;
+}
 
-            if (virUUIDGenerate(uuid_db->lpars[i]->uuid) < 0)
-                VIR_WARN("%s %d", "Unable to generate UUID for domain",
-                         ids[i]);
+int
+phypUUIDTable_Push(virConnectPtr conn)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    LIBSSH2_CHANNEL *channel = NULL;
+    struct stat local_fileinfo;
+    char buffer[1024];
+    int rc = 0;
+    FILE *fd;
+    size_t nread, sent;
+    char *ptr;
+    char remote_file[] = "/home/hscroot/libvirt_uuid_table";
+    char local_file[] = "./uuid_table";
+
+    if (stat(local_file, &local_fileinfo) == -1) {
+        VIR_WARN0("Unable to stat local file.");
+        goto err;
+    }
+
+    if (!(fd = fopen(local_file, "rb"))) {
+        VIR_WARN0("Unable to open local file.");
+        goto err;
+    }
+
+    do {
+        channel =
+            libssh2_scp_send(session, remote_file,
+                             0x1FF & local_fileinfo.st_mode,
+                             (unsigned long) local_fileinfo.st_size);
+
+        if ((!channel) && (libssh2_session_last_errno(session) !=
+                           LIBSSH2_ERROR_EAGAIN))
+            goto err;
+    } while (!channel);
+
+    do {
+        nread = fread(buffer, 1, sizeof(buffer), fd);
+        if (nread <= 0) {
+            /* end of file */
+            break;
+        }
+        ptr = buffer;
+        sent = 0;
+
+        do {
+            /* write the same data over and over, until error or completion */
+            rc = libssh2_channel_write(channel, ptr, nread);
+            if (LIBSSH2_ERROR_EAGAIN == rc) {   /* must loop around */
+                continue;
+            } else {
+                /* rc indicates how many bytes were written this time */
+                sent += rc;
+            }
+        } while (rc > 0 && sent < nread);
+        ptr += sent;
+        nread -= sent;
+    } while (1);
+
+    goto exit;
+
+  exit:
+    if (channel) {
+        libssh2_channel_send_eof(channel);
+        libssh2_channel_wait_eof(channel);
+        libssh2_channel_wait_closed(channel);
+        libssh2_channel_free(channel);
+        channel = NULL;
+    }
+    return 0;
+
+  err:
+    if (channel) {
+        libssh2_channel_send_eof(channel);
+        libssh2_channel_wait_eof(channel);
+        libssh2_channel_wait_closed(channel);
+        libssh2_channel_free(channel);
+        channel = NULL;
+    }
+    return -1;
+}
+
+int
+phypUUIDTable_Pull(virConnectPtr conn)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    LIBSSH2_CHANNEL *channel = NULL;
+    struct stat fileinfo;
+    char buffer[1024];
+    int rc = 0;
+    int fd;
+    int got = 0;
+    int amount = 0;
+    int total = 0;
+    int sock = 0;
+    char remote_file[] = "/home/hscroot/libvirt_uuid_table";
+    char local_file[] = "./uuid_table";
+
+    /* Trying to stat the remote file. */
+    do {
+        channel = libssh2_scp_recv(session, remote_file, &fileinfo);
+
+        if (!channel) {
+            if (libssh2_session_last_errno(session) !=
+                LIBSSH2_ERROR_EAGAIN) {
+                goto err;;
+            } else {
+                waitsocket(sock, session);
+            }
         }
+    } while (!channel);
+
+    /* Creating a new data base based on remote file */
+    if ((fd = creat(local_file, 0755)) == -1)
+        goto err;
+
+    /* Request a file via SCP */
+    while (got < fileinfo.st_size) {
+        do {
+            amount = sizeof(buffer);
+
+            if ((fileinfo.st_size - got) < amount) {
+                amount = fileinfo.st_size - got;
+            }
+
+            rc = libssh2_channel_read(channel, buffer, amount);
+            if (rc > 0) {
+                if (write(fd, buffer, rc) == -1)
+                    VIR_WARN("%s",
+                             "Unable to write information to local file.");
+
+                got += rc;
+                total += rc;
+            }
+        } while (rc > 0);
+
+        if ((rc == LIBSSH2_ERROR_EAGAIN)
+            && (got < fileinfo.st_size)) {
+            /* this is due to blocking that would occur otherwise
+             * so we loop on this condition */
+
+            waitsocket(sock, session);  /* now we wait */
+            continue;
+        }
+        break;
     }
+    close(fd);
+    goto exit;
+
   exit:
-    VIR_FREE(ids);
-    return;
+    if (channel) {
+        libssh2_channel_send_eof(channel);
+        libssh2_channel_wait_eof(channel);
+        libssh2_channel_wait_closed(channel);
+        libssh2_channel_free(channel);
+        channel = NULL;
+    }
+    return 0;
+
+  err:
+    if (channel) {
+        libssh2_channel_send_eof(channel);
+        libssh2_channel_wait_eof(channel);
+        libssh2_channel_wait_closed(channel);
+        libssh2_channel_free(channel);
+        channel = NULL;
+    }
+    return -1;
 }
 
-static int
+int
 escape_specialcharacters(char *src, char *dst, size_t dstlen)
 {
     size_t len = strlen(src);
@@ -1437,12 +2011,30 @@ escape_specialcharacters(char *src, char *dst, size_t dstlen)
 
     for (i = 0; i < len; i++) {
         switch (src[i]) {
-            case '&': case ';': case '`': case '@':
-            case '"': case '|': case '*': case '?':
-            case '~': case '<': case '>': case '^':
-            case '(': case ')': case '[': case ']':
-            case '{': case '}': case '$': case '%':
-            case '#': case '\\': case '\n': case '\r':
+            case '&':
+            case ';':
+            case '`':
+            case '@':
+            case '"':
+            case '|':
+            case '*':
+            case '?':
+            case '~':
+            case '<':
+            case '>':
+            case '^':
+            case '(':
+            case ')':
+            case '[':
+            case ']':
+            case '{':
+            case '}':
+            case '$':
+            case '%':
+            case '#':
+            case '\\':
+            case '\n':
+            case '\r':
             case '\t':
                 continue;
             default:
@@ -1488,3 +2080,10 @@ waitsocket(int socket_fd, LIBSSH2_SESSION * session)
 
     return rc;
 }
+
+int
+phypRegister(void)
+{
+    virRegisterDriver(&phypDriver);
+    return 0;
+}
diff --git a/src/phyp/phyp_driver.h b/src/phyp/phyp_driver.h
index b793774..5ec12be 100644
--- a/src/phyp/phyp_driver.h
+++ b/src/phyp/phyp_driver.h
@@ -1,3 +1,29 @@
+
+/*
+ * Copyright IBM Corp. 2009
+ *
+ * phyp_driver.c: ssh layer to access Power Hypervisors
+ *
+ * Authors:
+ *  Eduardo Otubo <otubo at linux.vnet.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "conf/capabilities.h"
+#include "conf/domain_conf.h"
 #include <config.h>
 #include <libssh2.h>
 
@@ -26,22 +52,53 @@ struct _lpar {
 /* Struct that holds how many lpars (domains) we're
  * handling and a pointer to an array of lpar structs
  * */
-typedef struct _uuid_db uuid_db_t;
-typedef uuid_db_t *uuid_dbPtr;
-struct _uuid_db {
+typedef struct _uuid_table uuid_table_t;
+typedef uuid_table_t *uuid_tablePtr;
+struct _uuid_table {
     int nlpars;
     lparPtr *lpars;
 };
 
-int phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn);
+/* This is the main structure of the driver
+ * */
+typedef struct _phyp_driver phyp_driver_t;
+typedef phyp_driver_t *phyp_driverPtr;
+struct _phyp_driver {
+    uuid_tablePtr uuid_table;
+    virCapsPtr caps;
+    int vios_id;
+    char *managed_system;
+};
 
-void init_uuid_db(virConnectPtr conn);
+int phypCheckSPFreeSapce(virConnectPtr conn, int required_size, char *sp);
 
-int phypRegister(void);
+int phypGetVIOSPartitionID(virConnectPtr conn);
+
+virCapsPtr phypCapsInit(void);
+
+int phypBuildLpar(virConnectPtr conn, virDomainDefPtr def);
+
+int phypUUIDTable_WriteFile(virConnectPtr conn);
+
+int phypUUIDTable_ReadFile(virConnectPtr conn);
+
+int phypUUIDTable_AddLpar(virConnectPtr conn, unsigned char *uuid, int id);
+
+int phypUUIDTable_RemLpar(virConnectPtr conn, int id);
 
-void stripPath(char *striped_path, char *path);
+int phypUUIDTable_Pull(virConnectPtr conn);
 
-void stripNewline(char *striped_string, char *string);
+int phypUUIDTable_Push(virConnectPtr conn);
+
+int phypUUIDTable_Init(virConnectPtr conn);
+
+int escape_specialcharacters(char *src, char *dst, size_t dstlen);
+
+int waitsocket(int socket_fd, LIBSSH2_SESSION * session);
+
+int phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn);
+
+int phypRegister(void);
 
 int phypGetLparState(virConnectPtr conn, unsigned int lpar_id);
 
@@ -52,6 +109,10 @@ unsigned long phypGetLparMem(virConnectPtr conn,
 unsigned long phypGetLparCPU(virConnectPtr conn,
                              const char *managed_system, int lpar_id);
 
+unsigned long phypGetLparCPUGeneric(virConnectPtr conn,
+                                    const char *managed_system,
+                                    int lpar_id, int type);
+
 int phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
                       const char *lpar_name);
 
@@ -60,6 +121,5 @@ char *phypGetBackingDevice(virConnectPtr conn, const char *managed_system,
 
 int phypDiskType(virConnectPtr conn, char *backing_device);
 
-LIBSSH2_SESSION *openSSHSession(virConnectPtr conn, virConnectAuthPtr auth, int *internal_socket);
-
-int waitsocket(int socket_fd, LIBSSH2_SESSION * session);
+LIBSSH2_SESSION *openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
+                                int *internal_socket);

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]