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