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

[libvirt] [PATCH] read network config in OpenVZ driver



This patch add possibility to load network configuration for container in OpenVZ driver. It support routing network and bridge devices. This types is currently supported in create/define command.
Also, patch contain fix to small bug in openvzReadConfigParam method.
Index: openvz_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/openvz_conf.c,v
retrieving revision 1.38
diff -u -p -r1.38 openvz_conf.c
--- openvz_conf.c	5 Sep 2008 15:00:14 -0000	1.38
+++ openvz_conf.c	8 Sep 2008 11:38:48 -0000
@@ -151,6 +151,148 @@ char *openvzMacToString(const unsigned c
     return strdup(str);
 }
 
+/*parse MAC from view: 00:18:51:8F:D9:F3
+  return -1 - error
+          0 - OK
+*/
+int openvzParseMac(const char *macaddr, unsigned char *mac)
+{
+    int ret;
+    ret = sscanf((const char *)macaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
+               (unsigned int*)&mac[0],
+               (unsigned int*)&mac[1],
+               (unsigned int*)&mac[2],
+               (unsigned int*)&mac[3],
+               (unsigned int*)&mac[4],
+               (unsigned int*)&mac[5]) ;
+    if (ret == 6)
+        return 0;
+
+    return -1;
+}
+
+virDomainNetDefPtr
+openvzReadNetworkConf(virConnectPtr conn, int veid) {
+    int ret;
+    virDomainNetDefPtr net = NULL;
+    virDomainNetDefPtr new_net;
+    char temp[4096];
+    char *token, *saveptr = NULL;
+
+    /*parse routing network configuration*
+     * Sample from config:
+     *   IP_ADDRESS="1.1.1.1 1.1.1.2"
+     *   splited IPs by space
+     */
+    ret = openvzReadConfigParam(veid, "IP_ADDRESS", temp, sizeof(temp));
+    if (ret < 0) {
+        openvzError(conn, VIR_ERR_INTERNAL_ERROR,
+                 _("Cound not read 'IP_ADDRESS' from config for container %d"),
+                  veid);
+        goto error;
+    } else if (ret > 0) {
+        token = strtok_r(temp, " ", &saveptr);
+        while (token != NULL) {
+            new_net = NULL;
+            if (VIR_ALLOC(new_net) < 0) {
+                openvzError(conn, VIR_ERR_NO_MEMORY, _("virDomainNetDefPtr"));
+                goto error;
+            }
+            new_net->next = net;
+            net = new_net;
+
+            net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
+            net->data.ethernet.ipaddr = strdup(token);
+
+            token = strtok_r(NULL, " ", &saveptr);
+        }
+    }
+
+    /*parse bridge devices*/
+    /*Sample from config:
+     *NETIF="ifname=eth10,mac=00:18:51:C1:05:EE,host_ifname=veth105.10,host_mac=00:18:51:8F:D9:F3"
+     *devices splited by ';'
+     */
+    ret = openvzReadConfigParam(veid, "NETIF", temp, sizeof(temp));
+    if (ret < 0) {
+        openvzError(conn, VIR_ERR_INTERNAL_ERROR,
+                     _("Cound not read 'NETIF' from config for container %d"),
+                     veid);
+        goto error;
+    } else if (ret > 0) {
+        token = strtok_r(temp, ";", &saveptr);
+        while (token != NULL) {
+            /*add new device to list*/
+            new_net = NULL;
+            if (VIR_ALLOC(new_net) < 0) {
+                openvzError(conn, VIR_ERR_NO_MEMORY, _("virDomainNetDefPtr"));
+                goto error;
+            }
+            new_net->next = net;
+            net = new_net;
+
+            net->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
+
+            char *p = token, *next = token;
+            char cpy_temp[32];
+            int len;
+
+            /*parse string*/
+            do {
+                while (*next != '\0' && *next != ',') next++;
+                if (STREQLEN("ifname=", p, 7)) {
+                    p += 7;
+                    len = next - p;
+                    if (len > 16) {
+                        openvzError(conn, VIR_ERR_INTERNAL_ERROR,
+                                _("Too long network device name"));
+                        goto error;
+                    }
+                    strncpy(cpy_temp, p, len);
+                    cpy_temp[len] = '\0';
+                    net->data.bridge.brname = strdup(cpy_temp);
+
+                    if (net->data.bridge.brname == NULL) {
+                        openvzError(conn, VIR_ERR_NO_MEMORY, _("Can't strdup"));
+                        goto error;
+                    }
+
+                } else if (STREQLEN("host_ifname=", p, 12)) {
+                    p += 12;
+                    //skip in libvirt
+                } else if (STREQLEN("mac=", p, 4)) {
+                    p += 4;
+                    len = next - p;
+                    if (len != 17) { //should be 17
+                        openvzError(conn, VIR_ERR_INTERNAL_ERROR,
+                              _("Wrong length MAC address"));
+                        goto error;
+                    }
+                    strncpy(cpy_temp, p, len);
+                    cpy_temp[len] = '\0';
+                    if (openvzParseMac(cpy_temp, net->mac)<0) {
+                        openvzError(conn, VIR_ERR_INTERNAL_ERROR,
+                              _("Wrong MAC address"));
+                        goto error;
+                    }
+                } else if (STREQLEN("host_mac=", p, 9)) {
+                    p += 9;
+                    //skip in libvirt
+                }
+                p = ++next;
+            } while (p < token + strlen(token));
+
+            token = strtok_r(NULL, ";", &saveptr);
+        }
+    }
+
+    return net;
+error:
+    virDomainNetDefFree(net);
+    return NULL;
+}
+
+
 /* Free all memory associated with a openvz_driver structure */
 void
 openvzFreeDriver(struct openvz_driver *driver)
@@ -243,6 +385,8 @@ int openvzLoadDomains(struct openvz_driv
 
         /* XXX load rest of VM config data .... */
 
+        dom->def->nets = openvzReadNetworkConf(NULL, veid);
+
         if (prev) {
             prev->next = dom;
         } else {
@@ -298,10 +442,13 @@ openvzReadConfigParam(int vpsid ,const c
         if (STREQLEN(line, param, strlen(param))) {
             sf = line;
             sf += strlen(param);
-            if (sf[0] == '=' && (token = strtok_r(sf,"\"\t=\n", &saveptr)) != NULL) {
-                strncpy(value, token, maxlen) ;
-                value[maxlen-1] = '\0';
-                found = 1;
+            if (sf[0] == '=' && sf[1] != '\0' ) {
+                sf ++;
+                if ((token = strtok_r(sf,"\"\t\n", &saveptr)) != NULL) {
+                    strncpy(value, token, maxlen) ;
+                    value[maxlen-1] = '\0';
+                    found = 1;
+                }
             }
        }
     }
Index: openvz_conf.h
===================================================================
RCS file: /data/cvs/libvirt/src/openvz_conf.h,v
retrieving revision 1.12
diff -u -p -r1.12 openvz_conf.h
--- openvz_conf.h	5 Sep 2008 14:10:58 -0000	1.12
+++ openvz_conf.h	8 Sep 2008 11:38:48 -0000
@@ -60,6 +60,9 @@ void openvzFreeDriver(struct openvz_driv
 int strtoI(const char *str);
 int openvzCheckEmptyMac(const unsigned char *mac);
 char *openvzMacToString(const unsigned char *mac);
+int openvzParseMac(const char *macaddr, unsigned char *mac);
 int openvzSetDefinedUUID(int vpsid, unsigned char *uuid);
+virDomainNetDefPtr openvzReadNetworkConf(virConnectPtr conn, int veid);
+
 
 #endif /* OPENVZ_CONF_H */

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