[libvirt] [PATCH 2/3] PHYP: Adding basic network functions

Eduardo Otubo otubo at linux.vnet.ibm.com
Fri Nov 19 14:55:05 UTC 2010


Now adding some basic operation network functions and its UUID
"helpers".
---
 src/phyp/phyp_driver.c |  202 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/phyp/phyp_uuid.c   |  177 ++++++++++++++++++++++++++++++++++++++++++
 src/phyp/phyp_uuid.h   |    8 ++
 3 files changed, 382 insertions(+), 5 deletions(-)

diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index 6f3f49d..c44fc69 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -667,6 +667,7 @@ phypOpen(virConnectPtr conn,
     size_t len = 0;
     int internal_socket;
     uuid_tablePtr uuid_table = NULL;
+    uuid_nettablePtr uuid_nettable = NULL;
     phyp_driverPtr phyp_driver = NULL;
     char *char_ptr;
     char *managed_system = NULL;
@@ -693,6 +694,11 @@ phypOpen(virConnectPtr conn,
         goto failure;
     }
 
+    if (VIR_ALLOC(uuid_nettable) < 0) {
+        virReportOOMError();
+        goto failure;
+    }
+
     if (VIR_ALLOC(connection_data) < 0) {
         virReportOOMError();
         goto failure;
@@ -744,10 +750,15 @@ phypOpen(virConnectPtr conn,
     uuid_table->nlpars = 0;
     uuid_table->lpars = NULL;
 
+    uuid_nettable->nnets = 0;
+    uuid_nettable->nets = NULL;
+
     if (conn->uri->path)
         phyp_driver->managed_system = managed_system;
 
     phyp_driver->uuid_table = uuid_table;
+    phyp_driver->uuid_nettable = uuid_nettable;
+
     if ((phyp_driver->caps = phypCapsInit()) == NULL) {
         virReportOOMError();
         goto failure;
@@ -759,14 +770,17 @@ phypOpen(virConnectPtr conn,
     if ((phyp_driver->system_type = phypGetSystemType(conn)) == -1)
         goto failure;
 
-    if (phypUUIDTable_Init(conn) == -1)
-        goto failure;
-
     if (phyp_driver->system_type == HMC) {
         if ((phyp_driver->vios_id = phypGetVIOSPartitionID(conn)) == -1)
             goto failure;
     }
 
+    if (phypUUIDTable_Init(conn) == -1)
+        goto failure;
+
+    if (phypUUIDNetworkTable_Init(conn) == -1)
+        goto failure;
+
     return VIR_DRV_OPEN_SUCCESS;
 
   failure:
@@ -777,6 +791,7 @@ phypOpen(virConnectPtr conn,
     }
 
     phypUUIDTable_Free(uuid_table);
+    phypUUIDNetworkTable_Free(uuid_nettable);
 
     if (session != NULL) {
         libssh2_session_disconnect(session, "Disconnecting...");
@@ -801,6 +816,7 @@ phypClose(virConnectPtr conn)
 
     virCapabilitiesFree(phyp_driver->caps);
     phypUUIDTable_Free(phyp_driver->uuid_table);
+    phypUUIDNetworkTable_Free(phyp_driver->uuid_nettable);
     VIR_FREE(phyp_driver->managed_system);
     VIR_FREE(phyp_driver);
     VIR_FREE(connection_data);
@@ -2813,6 +2829,182 @@ phypGetStoragePoolXMLDesc(virStoragePoolPtr pool, unsigned int flags)
     return NULL;
 }
 
+int
+phypListNetworkMAC(virConnectPtr conn, long long *macs, int nnets)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    int system_type = phyp_driver->system_type;
+    char *managed_system = phyp_driver->managed_system;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    int got = -1;
+    char *cmd = NULL;
+    char *ret = NULL;
+    char *line, *next_line;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    virBufferAddLit(&buf, "lshwres");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s", managed_system);
+
+    virBufferVSprintf(&buf, " -r virtualio --rsubtype eth --level lpar"
+                      "|grep -v lpar_id=%d| sed -e 's/^.*mac_addr=//g'",
+                      vios_id);
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    /* I need to parse the textual return in order to get the macs */
+    line = ret;
+    got = 0;
+    while (*line && got < nnets) {
+        if (virStrToLong_ll(line, &next_line, 10, &macs[got]) == -1) {
+            VIR_ERROR(_("Cannot parse number from '%s'"), line);
+            got = -1;
+            goto err;
+        }
+        got++;
+        line = next_line;
+        while (*line == '\n')
+            line++;             /* skip \n */
+    }
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return got;
+}
+
+int
+phypListNetworks(virConnectPtr conn, char **const names, int nnames)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    int system_type = phyp_driver->system_type;
+    char *managed_system = phyp_driver->managed_system;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    int got = 0;
+    int i;
+    char *cmd = NULL;
+    char *ret = NULL;
+    char *networks = NULL;
+    char *char_ptr2 = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    virBufferAddLit(&buf, "lshwres");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, " -m %s", managed_system);
+    virBufferVSprintf(&buf, " -r virtualio --rsubtype slot  --level slot"
+                      "|grep eth|grep -v lpar_id=%d|"
+                      "sed -e 's/^.*drc_name=//g'", vios_id);
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    /* I need to parse the textual return in order to get the network interfaces */
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+    else {
+        networks = ret;
+
+        while (got < nnames) {
+            char_ptr2 = strchr(networks, '\n');
+
+            if (char_ptr2) {
+                *char_ptr2 = '\0';
+                if ((names[got++] = strdup(networks)) == NULL) {
+                    virReportOOMError();
+                    goto err;
+                }
+                char_ptr2++;
+                networks = char_ptr2;
+            } else
+                break;
+        }
+    }
+
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return got;
+
+  err:
+    for (i = 0; i < got; i++)
+        VIR_FREE(names[i]);
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+}
+
+int
+phypNumOfNetworks(virConnectPtr conn)
+{
+    ConnectionData *connection_data = conn->networkPrivateData;
+    phyp_driverPtr phyp_driver = conn->privateData;
+    LIBSSH2_SESSION *session = connection_data->session;
+    char *managed_system = phyp_driver->managed_system;
+    int system_type = phyp_driver->system_type;
+    int vios_id = phyp_driver->vios_id;
+    int exit_status = 0;
+    int nnets = 0;
+    char *char_ptr;
+    char *cmd = NULL;
+    char *ret = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    virBufferAddLit(&buf, "lshwres ");
+    if (system_type == HMC)
+        virBufferVSprintf(&buf, "-m %s ", managed_system);
+
+    virBufferVSprintf(&buf,
+                      "-r virtualio --rsubtype eth --level lpar|"
+                      "grep -v lpar_id=%d|grep -c lpar_name", vios_id);
+
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError();
+        return -1;
+    }
+    cmd = virBufferContentAndReset(&buf);
+
+    ret = phypExec(session, cmd, &exit_status, conn);
+
+    if (exit_status < 0 || ret == NULL)
+        goto err;
+
+    if (virStrToLong_i(ret, &char_ptr, 10, &nnets) == -1)
+        goto err;
+
+    if (char_ptr)
+        *char_ptr = '\0';
+
+    VIR_FREE(cmd);
+    return nnets;
+
+  err:
+    VIR_FREE(cmd);
+    VIR_FREE(ret);
+    return -1;
+
+}
+
 static int
 phypGetLparState(virConnectPtr conn, unsigned int lpar_id)
 {
@@ -3637,8 +3829,8 @@ static virNetworkDriver phypNetworkDriver = {
     .name = "PHYP",
     .open = phypVIOSDriverOpen,
     .close = phypVIOSDriverClose,
-    .numOfNetworks = NULL,
-    .listNetworks = NULL,
+    .numOfNetworks = phypNumOfNetworks,
+    .listNetworks = phypListNetworks,
     .numOfDefinedNetworks = NULL,
     .listDefinedNetworks = NULL,
     .networkLookupByUUID = NULL,
diff --git a/src/phyp/phyp_uuid.c b/src/phyp/phyp_uuid.c
index a97dd44..c4a0cc2 100644
--- a/src/phyp/phyp_uuid.c
+++ b/src/phyp/phyp_uuid.c
@@ -655,3 +655,180 @@ phypUUIDTable_Free(uuid_tablePtr uuid_table)
     VIR_FREE(uuid_table->lpars);
     VIR_FREE(uuid_table);
 }
+
+int
+phypUUIDTable_RemNetwork(virConnectPtr conn, long long mac)
+{
+    phyp_driverPtr phyp_driver = conn->privateData;
+    uuid_nettablePtr uuid_nettable = phyp_driver->uuid_nettable;
+    unsigned int i = 0;
+
+    for (i = 0; i < uuid_nettable->nnets; i++) {
+        if (uuid_nettable->nets[i]->mac == mac) {
+            uuid_nettable->nets[i]->mac = -1;
+            memset(uuid_nettable->nets[i]->uuid, 0, VIR_UUID_BUFLEN);
+            break;
+        }
+    }
+
+    if (phypUUIDTable_WriteFile(conn, NET) == -1)
+        goto err;
+
+    if (phypUUIDTable_Push(conn, NET) == -1)
+        goto err;
+
+    return 0;
+
+  err:
+    return -1;
+}
+
+int
+phypUUIDTable_AddNetwork(virConnectPtr conn, unsigned char *uuid,
+                         long long mac, char *name)
+{
+    phyp_driverPtr phyp_driver = conn->privateData;
+    uuid_nettablePtr uuid_nettable = phyp_driver->uuid_nettable;
+
+    unsigned int i = uuid_nettable->nnets;
+    uuid_nettable->nnets++;
+
+    if (VIR_REALLOC_N(uuid_nettable->nets, uuid_nettable->nnets) < 0) {
+        virReportOOMError();
+        goto err;
+    }
+
+    if (VIR_ALLOC(uuid_nettable->nets[i]) < 0) {
+        virReportOOMError();
+        goto err;
+    }
+
+    uuid_nettable->nets[i]->mac = mac;
+    memmove(uuid_nettable->nets[i]->uuid, uuid, VIR_UUID_BUFLEN);
+    memmove(uuid_nettable->nets[i]->name, name, NETNAME_SIZE);
+
+    if (phypUUIDTable_WriteFile(conn, NET) == -1)
+        goto err;
+
+    if (phypUUIDTable_Push(conn, NET) == -1)
+        goto err;
+
+    return 0;
+
+  err:
+    return -1;
+}
+
+int
+phypUUIDNetworkTable_Init(virConnectPtr conn)
+{
+    uuid_nettablePtr uuid_nettable;
+    phyp_driverPtr phyp_driver;
+    int nnets_numnetworks = 0;
+    int nnets_listnetworks = 0;
+    long long *macs = NULL;
+    char **names = NULL;
+    unsigned int i = 0;
+
+    if ((nnets_numnetworks = phypNumOfNetworks(conn)) < 0)
+        goto err;
+
+    if (VIR_ALLOC_N(macs, nnets_numnetworks) < 0) {
+        virReportOOMError();
+        goto err;
+    }
+
+    if ((nnets_listnetworks =
+         phypListNetworkMAC(conn, macs, nnets_numnetworks)) < 0)
+        goto err;
+
+    /* exit early if there are no domains */
+    if (nnets_numnetworks == 0 && nnets_listnetworks == 0)
+        goto exit;
+    else if (nnets_numnetworks != nnets_listnetworks) {
+        VIR_ERROR0(_
+                   ("Unable to determine number of networks interfaces."));
+        goto err;
+    }
+
+    if (VIR_ALLOC_N(names, nnets_numnetworks) < 0) {
+        virReportOOMError();
+        goto err;
+    }
+
+    for (i = 0; i < nnets_numnetworks; i++) {
+        if (VIR_ALLOC_N(names[i], NETNAME_SIZE) < 0) {
+            virReportOOMError();
+            goto err;
+        }
+    }
+
+    if (phypListNetworks(conn, names, nnets_numnetworks) < 0)
+        goto err;
+
+    phyp_driver = conn->privateData;
+    uuid_nettable = phyp_driver->uuid_nettable;
+    uuid_nettable->nnets = nnets_listnetworks;
+
+    /* try to get the table from server */
+    if (phypUUIDTable_Pull(conn, NET) == -1) {
+        /* file not found in the server, creating a new one */
+        if (VIR_ALLOC_N(uuid_nettable->nets, uuid_nettable->nnets) >= 0) {
+            for (i = 0; i < uuid_nettable->nnets; i++) {
+                if (VIR_ALLOC(uuid_nettable->nets[i]) < 0) {
+                    virReportOOMError();
+                    goto err;
+                }
+                uuid_nettable->nets[i]->mac = macs[i];
+
+                if (memcpy
+                    (uuid_nettable->nets[i]->name, names[i],
+                     NETNAME_SIZE) == NULL)
+                    goto err;
+
+                if (virUUIDGenerate(uuid_nettable->nets[i]->uuid) < 0)
+                    VIR_WARN
+                        ("Unable to generate UUID for Network with MAC %lld",
+                         macs[i]);
+            }
+        } else {
+            virReportOOMError();
+            goto err;
+        }
+
+        if (phypUUIDTable_WriteFile(conn, NET) == -1)
+            goto err;
+
+        if (phypUUIDTable_Push(conn, NET) == -1)
+            goto err;
+    } else {
+        if (phypUUIDTable_ReadFile(conn, NET) == -1)
+            goto err;
+        goto exit;
+    }
+
+  exit:
+    VIR_FREE(macs);
+    VIR_FREE(names);
+    return 0;
+
+  err:
+    VIR_FREE(macs);
+    VIR_FREE(names);
+    return -1;
+}
+
+void
+phypUUIDNetworkTable_Free(uuid_nettablePtr uuid_nettable)
+{
+    int i;
+
+    if (uuid_nettable == NULL)
+        return;
+
+    for (i = 0; i < uuid_nettable->nnets; i++)
+        VIR_FREE(uuid_nettable->nets[i]);
+
+    VIR_FREE(uuid_nettable->nets);
+    VIR_FREE(uuid_nettable);
+}
diff --git a/src/phyp/phyp_uuid.h b/src/phyp/phyp_uuid.h
index ddf28f4..90a0178 100644
--- a/src/phyp/phyp_uuid.h
+++ b/src/phyp/phyp_uuid.h
@@ -34,3 +34,11 @@ void phypUUIDTable_Free(uuid_tablePtr uuid_table);
 int phypUUIDTable_RemLpar(virConnectPtr conn, int id);
 
 int phypUUIDTable_AddLpar(virConnectPtr conn, unsigned char *uuid, int id);
+
+int phypUUIDNetworkTable_Init(virConnectPtr conn);
+
+void phypUUIDNetworkTable_Free(uuid_nettablePtr uuid_table);
+
+int phypUUIDTable_AddNetwork(virConnectPtr conn, unsigned char *uuid, long long mac, char *name);
+
+int phypUUIDTable_RemNetwork(virConnectPtr conn, long long mac);
-- 
1.7.1




More information about the libvir-list mailing list