[libvirt] [PATCHv2] PHYP: Adding network interface management

Eduardo Otubo otubo at linux.vnet.ibm.com
Wed Dec 8 12:45:45 UTC 2010


Sorry for the tops posting, but I was wondering if someone could take a 
look at my patch v2, thanks.

Regards,

On 11/22/2010 11:03 PM, Eduardo Otubo wrote:
> This is the implementation of the previous patch now using virInterface*
> API. Ended up this patch got much more simpler, smaller and easier to
> review. Here is some details:
>
>   * MAC size and interface name are fixed due to specifications on HMC,
>     both are created automatically and CAN'T be specified from user. They
>     have the following format:
>
>      * MAC: 122980003002
>      * Interface name: U9124.720.067BE8B-V3-C0
>
>   * I did replaced all the |grep|sed following the comments Eric Blake
>     did on the last patch.
>
>   * According to my last email, It's not possible to create a network
>     interface without assigning it to a specific lpar. Then, I am using
>     this very minimalistic XML file for testing:
>
>      <interface type='ethernet' name='LPAR01'>
>      </interface>
>
>     In this file I am using "name" as the lpar name which I am going to
>     assign the new network interface. I couldn't find a better way to
>     refer to it. Comments are welcome.
>
>   * Regarding the fact I am sleeping one second waiting for the HMC to
>     complete creation of the interface, I don't have means to check
>     if the whole process is done. All I do is execute a command, wait
>     until is complete (which is not enough in this case) check
>     the return and the exit status. The process of actually creating
>     a networking interface seems to take a little longer than just the
>     return of the ssh control.
> ---
>   src/phyp/phyp_driver.c |  572 ++++++++++++++++++++++++++++++++++++++++++++++--
>   1 files changed, 553 insertions(+), 19 deletions(-)
>
> diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
> index 4c723a2..407f644 100644
> --- a/src/phyp/phyp_driver.c
> +++ b/src/phyp/phyp_driver.c
> @@ -59,6 +59,7 @@
>   #include "storage_conf.h"
>   #include "nodeinfo.h"
>   #include "files.h"
> +#include "interface_conf.h"
>
>   #include "phyp_driver.h"
>
> @@ -74,6 +75,8 @@
>
>   static unsigned const int HMC = 0;
>   static unsigned const int IVM = 127;
> +static unsigned const int PHYP_IFACENAME_SIZE = 24;
> +static unsigned const int PHYP_MAC_SIZE= 12;
>
>   static int
>   waitsocket(int socket_fd, LIBSSH2_SESSION * session)
> @@ -3268,6 +3271,542 @@ phypGetStoragePoolXMLDesc(virStoragePoolPtr pool, unsigned int flags)
>   }
>
>   static int
> +phypInterfaceDestroy(virInterfacePtr iface,
> +                     unsigned int flags ATTRIBUTE_UNUSED)
> +{
> +    ConnectionData *connection_data = iface->conn->networkPrivateData;
> +    phyp_driverPtr phyp_driver = iface->conn->privateData;
> +    LIBSSH2_SESSION *session = connection_data->session;
> +    virBuffer buf = VIR_BUFFER_INITIALIZER;
> +    char *managed_system = phyp_driver->managed_system;
> +    int system_type = phyp_driver->system_type;
> +    int exit_status = 0;
> +    int slot_num = 0;
> +    int lpar_id = 0;
> +    char *char_ptr;
> +    char *cmd = NULL;
> +    char *ret = NULL;
> +
> +    /* Getting the remote slot number */
> +
> +    char_ptr = NULL;
> +    char_ptr = strchr(iface->mac, '\n');
> +
> +    if (char_ptr)
> +        *char_ptr = '\0';
> +
> +    virBufferAddLit(&buf, "lshwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      " -r virtualio --rsubtype eth --level lpar "
> +                      " -F mac_addr,slot_num|"
> +                      " sed -n '/%s/ s/^.*,//p'", iface->mac);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        return -1;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, iface->conn);
> +
> +    if (exit_status<  0 || ret == NULL)
> +        goto err;
> +
> +    if (virStrToLong_i(ret,&char_ptr, 10,&slot_num) == -1)
> +        goto err;
> +
> +    /* Getting the remote slot number */
> +
> +    virBufferAddLit(&buf, "lshwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      " -r virtualio --rsubtype eth --level lpar "
> +                      " -F mac_addr,lpar_id|"
> +                      " sed -n '/%s/ s/^.*,//p'", iface->mac);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        return -1;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, iface->conn);
> +
> +    if (exit_status<  0 || ret == NULL)
> +        goto err;
> +
> +    if (virStrToLong_i(ret,&char_ptr, 10,&lpar_id) == -1)
> +        goto err;
> +
> +    /* excluding interface */
> +
> +    virBufferAddLit(&buf, "chhwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      " -r virtualio --rsubtype eth"
> +                      " --id %d -o r -s %d", lpar_id, slot_num);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        return -1;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, iface->conn);
> +
> +    if (exit_status<  0 || ret != NULL)
> +        goto err;
> +
> +    VIR_FREE(cmd);
> +    VIR_FREE(ret);
> +    return 0;
> +
> +  err:
> +    VIR_FREE(cmd);
> +    VIR_FREE(ret);
> +    return -1;
> +}
> +
> +static virInterfacePtr
> +phypInterfaceDefineXML(virConnectPtr conn, const char *xml,
> +                       unsigned int flags ATTRIBUTE_UNUSED)
> +{
> +    ConnectionData *connection_data = conn->networkPrivateData;
> +    phyp_driverPtr phyp_driver = conn->privateData;
> +    LIBSSH2_SESSION *session = connection_data->session;
> +    virBuffer buf = VIR_BUFFER_INITIALIZER;
> +    char *managed_system = phyp_driver->managed_system;
> +    int system_type = phyp_driver->system_type;
> +    int exit_status = 0;
> +    char *char_ptr;
> +    char *cmd = NULL;
> +    int slot = 0;
> +    char *ret = NULL;
> +    char *name = NULL;
> +    char *mac = NULL;
> +    virInterfaceDefPtr def;
> +
> +    if (VIR_ALLOC_N(name, PHYP_IFACENAME_SIZE)<  0) {
> +        virReportOOMError();
> +        goto err;
> +    }
> +
> +    if (VIR_ALLOC_N(mac, PHYP_MAC_SIZE)<  0) {
> +        virReportOOMError();
> +        goto err;
> +    }
> +
> +    if (!(def = virInterfaceDefParseString(xml)))
> +        goto err;
> +
> +    /* Now need to get the next free slot number */
> +    virBufferAddLit(&buf, "lshwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      " -r virtualio --rsubtype slot --level slot"
> +                      " -Fslot_num --filter lpar_names=%s"
> +                      " |sort|tail -n 1", def->name);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        goto err;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, conn);
> +
> +    if (exit_status<  0 || ret == NULL)
> +        goto err;
> +
> +    if (virStrToLong_i(ret,&char_ptr, 10,&slot) == -1)
> +        goto err;
> +
> +    /* The next free slot itself: */
> +    slot++;
> +
> +    /* Now addig the new network interface */
> +    virBufferAddLit(&buf, "chhwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      " -r virtualio --rsubtype eth"
> +                      " -p %s -o a -s %d -a port_vlan_id=1,"
> +                      "ieee_virtual_eth=0", def->name, slot);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        goto err;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, conn);
> +
> +    if (exit_status<  0 || ret != NULL)
> +        goto err;
> +
> +    /* Need to sleep a little while to wait for the HMC to
> +     * complete the execution of the command.
> +     * */
> +    sleep(1);
> +
> +    /* Getting the new interface name */
> +    virBufferAddLit(&buf, "lshwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      " -r virtualio --rsubtype slot --level slot"
> +                      " |sed '/lpar_name=%s/!d; /slot_num=%d/!d; "
> +                      "s/^.*drc_name=//'", def->name, slot);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        goto err;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, conn);
> +
> +    if (exit_status<  0 || ret == NULL)
> +        goto err;
> +
> +    char_ptr = NULL;
> +    char_ptr = strchr(ret, '\n');
> +
> +    if (char_ptr)
> +        *char_ptr = '\0';
> +
> +    if (memcpy(name, ret, PHYP_IFACENAME_SIZE) == NULL)
> +        goto err;
> +
> +    /* Getting the new interface mac addr */
> +    virBufferAddLit(&buf, "lshwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      "-r virtualio --rsubtype eth --level lpar "
> +                      " |sed '/lpar_name=%s/!d; /slot_num=%d/!d; "
> +                      "s/^.*mac_addr=//'", def->name, slot);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        goto err;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, conn);
> +
> +    if (exit_status<  0 || ret == NULL)
> +        goto err;
> +
> +    if (memcpy(mac, ret, PHYP_IFACENAME_SIZE) == NULL)
> +        goto err;
> +
> +    VIR_FREE(cmd);
> +    VIR_FREE(ret);
> +    return virGetInterface(conn, name, mac);
> +
> +  err:
> +    VIR_FREE(name);
> +    VIR_FREE(cmd);
> +    VIR_FREE(ret);
> +    return NULL;
> +}
> +
> +static virInterfacePtr
> +phypInterfaceLookupByName(virConnectPtr conn, const char *name)
> +{
> +    ConnectionData *connection_data = conn->networkPrivateData;
> +    phyp_driverPtr phyp_driver = conn->privateData;
> +    LIBSSH2_SESSION *session = connection_data->session;
> +    virBuffer buf = VIR_BUFFER_INITIALIZER;
> +    char *managed_system = phyp_driver->managed_system;
> +    int system_type = phyp_driver->system_type;
> +    int exit_status = 0;
> +    char *char_ptr;
> +    char *cmd = NULL;
> +    char *ret = NULL;
> +    int slot = 0;
> +    int lpar_id = 0;
> +
> +    /*Getting the slot number for the interface */
> +    virBufferAddLit(&buf, "lshwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      " -r virtualio --rsubtype slot --level slot "
> +                      " -F drc_name,slot_num |"
> +                      " sed -n '/%s/ s/^.*,//p'", name);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        return NULL;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, conn);
> +
> +    if (exit_status<  0 || ret == NULL)
> +        goto err;
> +
> +    if (virStrToLong_i(ret,&char_ptr, 10,&slot) == -1)
> +        goto err;
> +
> +    if (char_ptr)
> +        *char_ptr = '\0';
> +
> +    /*Getting the lpar_id for the interface */
> +    virBufferAddLit(&buf, "lshwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      " -r virtualio --rsubtype slot --level slot "
> +                      " -F drc_name,lpar_id |"
> +                      " sed -n '/%s/ s/^.*,//p'", name);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        return NULL;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, conn);
> +
> +    if (exit_status<  0 || ret == NULL)
> +        goto err;
> +
> +    if (virStrToLong_i(ret,&char_ptr, 10,&lpar_id) == -1)
> +        goto err;
> +
> +    if (char_ptr)
> +        *char_ptr = '\0';
> +
> +    /*Getting the interface mac */
> +    virBufferAddLit(&buf, "lshwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      " -r virtualio --rsubtype eth --level lpar "
> +                      " -F lpar_id,slot_num,mac_addr|"
> +                      " sed -n '/%d,%d/ s/^.*,//p'", lpar_id, slot);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        return NULL;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, conn);
> +
> +    if (exit_status<  0 || ret == NULL)
> +        goto err;
> +
> +    VIR_FREE(cmd);
> +    return virGetInterface(conn, name, ret);
> +
> +  err:
> +    VIR_FREE(cmd);
> +    VIR_FREE(ret);
> +    return NULL;
> +
> +}
> +
> +static int
> +phypInterfaceIsActive(virInterfacePtr iface)
> +{
> +    ConnectionData *connection_data = iface->conn->networkPrivateData;
> +    phyp_driverPtr phyp_driver = iface->conn->privateData;
> +    LIBSSH2_SESSION *session = connection_data->session;
> +    virBuffer buf = VIR_BUFFER_INITIALIZER;
> +    char *managed_system = phyp_driver->managed_system;
> +    int system_type = phyp_driver->system_type;
> +    int exit_status = 0;
> +    int state = 0;
> +    char *char_ptr;
> +    char *cmd = NULL;
> +    char *ret = NULL;
> +
> +    virBufferAddLit(&buf, "lshwres ");
> +    if (system_type == HMC)
> +        virBufferVSprintf(&buf, "-m %s ", managed_system);
> +
> +    virBufferVSprintf(&buf,
> +                      " -r virtualio --rsubtype eth --level lpar "
> +                      " -F mac_addr,state |"
> +                      " sed -n '/%s/ s/^.*,//p'", iface->mac);
> +
> +    if (virBufferError(&buf)) {
> +        virBufferFreeAndReset(&buf);
> +        virReportOOMError();
> +        return -1;
> +    }
> +    cmd = virBufferContentAndReset(&buf);
> +
> +    ret = phypExec(session, cmd,&exit_status, iface->conn);
> +
> +    if (exit_status<  0 || ret == NULL)
> +        goto err;
> +
> +    if (virStrToLong_i(ret,&char_ptr, 10,&state) == -1)
> +        goto err;
> +
> +    if (char_ptr)
> +        *char_ptr = '\0';
> +
> +    VIR_FREE(cmd);
> +    return state;
> +
> +  err:
> +    VIR_FREE(cmd);
> +    VIR_FREE(ret);
> +    return -1;
> +
> +}
> +
> +static int
> +phypListInterfaces(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|"
> +                      " sed '/eth/!d; /lpar_id=%d/d; 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;
> +}
> +
> +static int
> +phypNumOfInterfaces(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)
>   {
>       ConnectionData *connection_data = conn->networkPrivateData;
> @@ -4087,27 +4626,22 @@ static virStorageDriver phypStorageDriver = {
>       .poolIsPersistent = NULL
>   };
>
> -static virNetworkDriver phypNetworkDriver = {
> +static virInterfaceDriver phypInterfaceDriver = {
>       .name = "PHYP",
>       .open = phypVIOSDriverOpen,
>       .close = phypVIOSDriverClose,
> -    .numOfNetworks = NULL,
> -    .listNetworks = NULL,
> -    .numOfDefinedNetworks = NULL,
> -    .listDefinedNetworks = NULL,
> -    .networkLookupByUUID = NULL,
> -    .networkLookupByName = NULL,
> -    .networkCreateXML = NULL,
> -    .networkDefineXML = NULL,
> -    .networkUndefine = NULL,
> -    .networkCreate = NULL,
> -    .networkDestroy = NULL,
> -    .networkDumpXML = NULL,
> -    .networkGetBridgeName = NULL,
> -    .networkGetAutostart = NULL,
> -    .networkSetAutostart = NULL,
> -    .networkIsActive = NULL,
> -    .networkIsPersistent = NULL
> +    .numOfInterfaces = phypNumOfInterfaces,
> +    .listInterfaces = phypListInterfaces,
> +    .numOfDefinedInterfaces = NULL,
> +    .listDefinedInterfaces = NULL,
> +    .interfaceLookupByName = phypInterfaceLookupByName,
> +    .interfaceLookupByMACString = NULL,
> +    .interfaceGetXMLDesc = NULL,
> +    .interfaceDefineXML = phypInterfaceDefineXML,
> +    .interfaceUndefine = NULL,
> +    .interfaceCreate = NULL,
> +    .interfaceDestroy = phypInterfaceDestroy,
> +    .interfaceIsActive = phypInterfaceIsActive
>   };
>
>   int
> @@ -4117,7 +4651,7 @@ phypRegister(void)
>           return -1;
>       if (virRegisterStorageDriver(&phypStorageDriver)<  0)
>           return -1;
> -    if (virRegisterNetworkDriver(&phypNetworkDriver)<  0)
> +    if (virRegisterInterfaceDriver(&phypInterfaceDriver)<  0)
>           return -1;
>
>       return 0;


-- 
Eduardo Otubo
Software Engineer
Linux Technology Center
IBM Systems & Technology Group
Mobile: +55 19 8135 0885
eotubo at linux.vnet.ibm.com




More information about the libvir-list mailing list