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 */
--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to