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

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



New patch, more fixes.

Matthias Bolte wrote:
+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;
+        }
+    }

def->id is always -1 here because you're parsing the domain XML with
the VIR_DOMAIN_XML_INACTIVE flag set.

+    dom->conn = conn;
+    dom->name = def->name;
+    dom->id = def->id;
+    memmove(dom->uuid, def->uuid, VIR_UUID_BUFLEN);

You're accessing a NULL pointer here. Just remove this 4 lines of
code, because you're setting dom a line below anyway.

+    if ((dom = virGetDomain(conn, def->name, def->uuid)) == NULL)
+        goto err;

def->id is -1 here. As I understand phypBuildLpar() it calls mksyscfg
to actually define a new LPAR with a given ID. You use def->id for
this. You're either defining all new LPARs with ID -1 or I
misunderstand how this method is working.

I was thinking I could just avoid handling the ID at all here, HMC does it by itself. So, skiping ID and just dealing with the LPAR name.


+    if (phypBuildLpar(conn, def) == -1)
+        goto err;
+
+    if (phypDomainResume(dom) == -1)
+        goto err;
+
+    return dom;
+
+  err:
+    virDomainDefFree(def);
+    VIR_FREE(dom);
+    return NULL;
+}
+

[...]
-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.");
+    }

You should goto err if a write fails, because a single failed write
will corrupt the while table.

You should instead check for

write(...) != sizeof(uuid_table->lpars[i]->id) and
write(...) != VIR_UUID_BUFLEN

because write() may write less bytes than requested.

+    close(fd);
+    return 0;
+
+  err:
+    close(fd);
+    return -1;
+}
+

You fixed most issues in this version of the patch, but some memory
leaks are still there.


All the other things are fixed.
Thanks for all the comments.
[]'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..4563619 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 <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,11 @@ 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;
 
     if (!conn || !conn->uri)
         return VIR_DRV_OPEN_DECLINED;
@@ -91,11 +95,23 @@ phypOpen(virConnectPtr conn,
     if (conn->uri->path == NULL) {
         virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
                       VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
+                      _("Missing managed system name in phyp:// URI"));
+        return VIR_DRV_OPEN_ERROR;
+    }
+
+    if (conn->uri->path == NULL) {
+        virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
+                      VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
                       _("Missing path name in phyp:// URI"));
         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;
     }
@@ -112,6 +128,27 @@ phypOpen(virConnectPtr conn,
         goto failure;
     }
 
+    if (VIR_ALLOC_N(managed_system, len) < 0) {
+        virReportOOMError(conn);
+        goto failure;
+    }
+
+    managed_system = strdup(conn->uri->path);
+    if (!managed_system)
+        goto failure;
+
+    /* 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 (escape_specialcharacters(conn->uri->path, string, len) == -1) {
         virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
                       VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
@@ -129,17 +166,32 @@ 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;
+
+    phyp_driver->managed_system = managed_system;
+    phyp_driver->uuid_table = uuid_table;
+    if ((phyp_driver->caps = phypCapsInit()) == NULL) {
+        virReportOOMError(conn);
+        goto failure;
+    }
 
-    conn->privateData = uuid_db;
+    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);
+    virCapabilitiesFree(phyp_driver->caps);
+    VIR_FREE(phyp_driver->managed_system);
+    VIR_FREE(phyp_driver);
+    VIR_FREE(uuid_table);
+    VIR_FREE(uuid_table->lpars);
     VIR_FREE(connection_data);
     VIR_FREE(string);
 
@@ -150,11 +202,17 @@ 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->uuid_table);
+    VIR_FREE(phyp_driver->uuid_table->lpars);
+    VIR_FREE(phyp_driver->managed_system);
+    VIR_FREE(phyp_driver);
     VIR_FREE(connection_data);
     return 0;
 }
@@ -174,17 +232,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 +249,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 +260,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 +464,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 +495,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 +518,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 +527,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 +563,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 +607,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 +682,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 +709,7 @@ phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
 
   err:
     VIR_FREE(cmd);
-    return 0;
+    return -1;
 }
 
 char *
@@ -640,16 +723,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 +779,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 +792,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 +822,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 +913,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 +929,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 +969,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 +992,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 +1001,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 +1040,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 +1100,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 +1134,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 +1172,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 +1185,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 +1226,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 +1251,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 +1284,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 +1321,210 @@ 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 -1;
+
+}
+
+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_SECURE)))
+        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;
+        }
+    }
+
+    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 +1539,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 +1550,7 @@ virDriver phypDriver = {
     phypDomainResume,           /* domainResume */
     phypDomainShutdown,         /* domainShutdown */
     NULL,                       /* domainReboot */
-    NULL,                       /* domainDestroy */
+    phypDomainDestroy,          /* domainDestroy */
     NULL,                       /* domainGetOSType */
     NULL,                       /* domainGetMaxMemory */
     NULL,                       /* domainSetMaxMemory */
@@ -1340,10 +1559,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 +1600,430 @@ 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 -p %s -i min_mem=%d,desired_mem=%d,"
+         "max_mem=%d,desired_procs=%d,virtual_scsi_adapters=%s",
+         managed_system, 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;
+}
+
+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[] = "./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)) ==
+            sizeof(uuid_table->lpars[i]->id)) {
+            VIR_ERROR("%s", "Unable to write information to local file.");
+            goto err;
+        }
+
+        if (write(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN) ==
+            VIR_UUID_BUFLEN) {
+            VIR_ERROR("%s", "Unable to write information to local file.");
+            goto err;
+        }
+    }
+
+    close(fd);
     return 0;
+
+  err:
+    close(fd);
+    return -1;
 }
 
-void
-init_uuid_db(virConnectPtr conn)
+int
+phypUUIDTable_Init(virConnectPtr conn)
 {
-    uuid_dbPtr uuid_db;
+    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 +2034,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 +2103,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]