This patch ports the networking part of the QEMU driver to the new network APIs. Obviously we delete alot of the struct defintions and all the code used for parsing and formatting XML. Then there follows alot of fixup to deal with API name changes. The other notable point is that the char * arrays are no longer pre-declared as PATH_MAX in size, instead being allocated on the heap. So we change alot of conditionals from looking like foo[0] == '\0' over to foo == NULL Really this networking code doesn't belong in the QEMU driver at all. We really ought to move it out into a network_driver.c file as its nothing todo with QEMU at all. Its just here from historical days when it had to run inside the libvirt_qemud daemon. Since the last version of the patch lots of bugs fixed, and also al the code for saving/loading the persistent config files has been moved into the generic network_conf.c module too. bridge.c | 63 ++--- bridge.h | 4 qemu_conf.c | 626 ---------------------------------------------------------- qemu_conf.h | 95 -------- qemu_driver.c | 377 ++++++++++++++++++---------------- 5 files changed, 230 insertions(+), 935 deletions(-) Daniel diff -r 86abc19320a1 src/bridge.c --- a/src/bridge.c Tue Jul 08 15:06:51 2008 +0100 +++ b/src/bridge.c Tue Jul 08 15:26:10 2008 +0100 @@ -116,60 +116,41 @@ /** * brAddBridge: * @ctl: bridge control pointer - * @nameOrFmt: the bridge name (or name template) - * @name: pointer to @maxlen bytes to store the bridge name - * @maxlen: size of @name array + * @name: the bridge name * - * This function register a new bridge, @nameOrFmt can be either - * a fixed name or a name template with '%d' for dynamic name allocation. - * in either case the final name for the bridge will be stored in @name. + * This function register a new bridge * * Returns 0 in case of success or an errno code in case of failure. */ #ifdef SIOCBRADDBR int brAddBridge(brControl *ctl, - const char *nameOrFmt, - char *name, - int maxlen) + char **name) { - int id, subst; - - if (!ctl || !ctl->fd || !nameOrFmt || !name) + if (!ctl || !ctl->fd || !name) return EINVAL; - if (maxlen >= BR_IFNAME_MAXLEN) - maxlen = BR_IFNAME_MAXLEN; + if (*name) { + if (ioctl(ctl->fd, SIOCBRADDBR, *name) == 0) + return 0; + } else { + int id = 0; + do { + char try[50]; - subst = id = 0; + snprintf(try, sizeof(try), "virbr%d", id); - if (strstr(nameOrFmt, "%d")) - subst = 1; + if (ioctl(ctl->fd, SIOCBRADDBR, try) == 0) { + if (!(*name = strdup(try))) { + ioctl(ctl->fd, SIOCBRDELBR, name); + return ENOMEM; + } + return 0; + } - do { - char try[BR_IFNAME_MAXLEN]; - int len; - - if (subst) { - len = snprintf(try, maxlen, nameOrFmt, id); - if (len >= maxlen) - return EADDRINUSE; - } else { - len = strlen(nameOrFmt); - if (len >= maxlen - 1) - return EINVAL; - - strncpy(try, nameOrFmt, len); - try[len] = '\0'; - } - - if (ioctl(ctl->fd, SIOCBRADDBR, try) == 0) { - strncpy(name, try, maxlen); - return 0; - } - - id++; - } while (subst && id <= MAX_BRIDGE_ID); + id++; + } while (id < MAX_BRIDGE_ID); + } return errno; } diff -r 86abc19320a1 src/bridge.h --- a/src/bridge.h Tue Jul 08 15:06:51 2008 +0100 +++ b/src/bridge.h Tue Jul 08 15:26:10 2008 +0100 @@ -47,9 +47,7 @@ void brShutdown (brControl *ctl); int brAddBridge (brControl *ctl, - const char *nameOrFmt, - char *name, - int maxlen); + char **name); int brDeleteBridge (brControl *ctl, const char *name); diff -r 86abc19320a1 src/qemu_conf.c --- a/src/qemu_conf.c Tue Jul 08 15:06:51 2008 +0100 +++ b/src/qemu_conf.c Tue Jul 08 15:26:10 2008 +0100 @@ -175,32 +175,6 @@ if (STREQ(vm->def->name, name)) return vm; vm = vm->next; - } - - return NULL; -} - -struct qemud_network *qemudFindNetworkByUUID(const struct qemud_driver *driver, - const unsigned char *uuid) { - struct qemud_network *network = driver->networks; - - while (network) { - if (!memcmp(network->def->uuid, uuid, VIR_UUID_BUFLEN)) - return network; - network = network->next; - } - - return NULL; -} - -struct qemud_network *qemudFindNetworkByName(const struct qemud_driver *driver, - const char *name) { - struct qemud_network *network = driver->networks; - - while (network) { - if (STREQ(network->def->name, name)) - return network; - network = network->next; } return NULL; @@ -2254,7 +2228,7 @@ struct qemud_vm_net_def *net, int vlan) { - struct qemud_network *network = NULL; + virNetworkObjPtr network = NULL; char *brname; char *ifname; char tapfdstr[4+3+32+7]; @@ -2263,18 +2237,18 @@ int tapfd = -1; if (net->type == QEMUD_NET_NETWORK) { - if (!(network = qemudFindNetworkByName(driver, net->dst.network.name))) { + if (!(network = virNetworkFindByName(driver->networks, net->dst.network.name))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("Network '%s' not found"), net->dst.network.name); goto error; - } else if (network->bridge[0] == '\0') { + } else if (network->def->bridge == NULL) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("Network '%s' not active"), net->dst.network.name); goto error; } - brname = network->bridge; + brname = network->def->bridge; if (net->dst.network.ifname[0] == '\0' || STRPREFIX(net->dst.network.ifname, "vnet") || strchr(net->dst.network.ifname, '%')) { @@ -3113,465 +3087,6 @@ return qemudSaveConfig(conn, driver, vm, def); } -static int qemudSaveNetworkConfig(virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network *network, - struct qemud_network_def *def) { - char *xml; - int fd, ret = -1; - int towrite; - int err; - - if (!(xml = qemudGenerateNetworkXML(conn, driver, network, def))) { - return -1; - } - - if ((err = virFileMakePath(driver->networkConfigDir))) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot create config directory %s: %s"), - driver->networkConfigDir, strerror(err)); - goto cleanup; - } - - if ((fd = open(network->configFile, - O_WRONLY | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR )) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot create config file %s: %s"), - network->configFile, strerror(errno)); - goto cleanup; - } - - towrite = strlen(xml); - if (safewrite(fd, xml, towrite) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot write config file %s: %s"), - network->configFile, strerror(errno)); - goto cleanup; - } - - if (close(fd) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot save config file %s: %s"), - network->configFile, strerror(errno)); - goto cleanup; - } - - ret = 0; - - cleanup: - - VIR_FREE(xml); - - return ret; -} - -void qemudFreeNetworkDef(struct qemud_network_def *def) { - struct qemud_dhcp_range_def *range = def->ranges; - while (range) { - struct qemud_dhcp_range_def *next = range->next; - VIR_FREE(range); - range = next; - } - VIR_FREE(def); -} - -void qemudFreeNetwork(struct qemud_network *network) { - qemudFreeNetworkDef(network->def); - if (network->newDef) - qemudFreeNetworkDef(network->newDef); - VIR_FREE(network); -} - -static int qemudParseBridgeXML(struct qemud_driver *driver ATTRIBUTE_UNUSED, - struct qemud_network_def *def, - xmlNodePtr node) { - xmlChar *name, *stp, *delay; - - name = xmlGetProp(node, BAD_CAST "name"); - if (name != NULL) { - strncpy(def->bridge, (const char *)name, IF_NAMESIZE-1); - def->bridge[IF_NAMESIZE-1] = '\0'; - xmlFree(name); - name = NULL; - } - - stp = xmlGetProp(node, BAD_CAST "stp"); - if (stp != NULL) { - if (xmlStrEqual(stp, BAD_CAST "off")) { - def->disableSTP = 1; - } - xmlFree(stp); - stp = NULL; - } - - delay = xmlGetProp(node, BAD_CAST "delay"); - if (delay != NULL) { - def->forwardDelay = strtol((const char *)delay, NULL, 10); - xmlFree(delay); - delay = NULL; - } - - return 1; -} - -static int qemudParseDhcpRangesXML(virConnectPtr conn, - struct qemud_driver *driver ATTRIBUTE_UNUSED, - struct qemud_network_def *def, - xmlNodePtr node) { - - xmlNodePtr cur; - - cur = node->children; - while (cur != NULL) { - struct qemud_dhcp_range_def *range; - xmlChar *start, *end; - - if (cur->type != XML_ELEMENT_NODE || - !xmlStrEqual(cur->name, BAD_CAST "range")) { - cur = cur->next; - continue; - } - - if (VIR_ALLOC(range) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, - "%s", _("failed to allocate space for range string")); - return 0; - } - - start = xmlGetProp(cur, BAD_CAST "start"); - end = xmlGetProp(cur, BAD_CAST "end"); - - if (start && start[0] && end && end[0]) { - strncpy(range->start, (const char *)start, BR_INET_ADDR_MAXLEN-1); - range->start[BR_INET_ADDR_MAXLEN-1] = '\0'; - - strncpy(range->end, (const char *)end, BR_INET_ADDR_MAXLEN-1); - range->end[BR_INET_ADDR_MAXLEN-1] = '\0'; - - range->next = def->ranges; - def->ranges = range; - def->nranges++; - } else { - VIR_FREE(range); - } - - xmlFree(start); - xmlFree(end); - - cur = cur->next; - } - - return 1; -} - -static int qemudParseInetXML(virConnectPtr conn, - struct qemud_driver *driver ATTRIBUTE_UNUSED, - struct qemud_network_def *def, - xmlNodePtr node) { - xmlChar *address, *netmask; - xmlNodePtr cur; - - address = xmlGetProp(node, BAD_CAST "address"); - if (address != NULL) { - strncpy(def->ipAddress, (const char *)address, BR_INET_ADDR_MAXLEN-1); - def->ipAddress[BR_INET_ADDR_MAXLEN-1] = '\0'; - xmlFree(address); - address = NULL; - } - - netmask = xmlGetProp(node, BAD_CAST "netmask"); - if (netmask != NULL) { - strncpy(def->netmask, (const char *)netmask, BR_INET_ADDR_MAXLEN-1); - def->netmask[BR_INET_ADDR_MAXLEN-1] = '\0'; - xmlFree(netmask); - netmask = NULL; - } - - if (def->ipAddress[0] && def->netmask[0]) { - struct in_addr inaddress, innetmask; - char *netaddr; - - inet_aton((const char*)def->ipAddress, &inaddress); - inet_aton((const char*)def->netmask, &innetmask); - - inaddress.s_addr &= innetmask.s_addr; - - netaddr = inet_ntoa(inaddress); - - snprintf(def->network,sizeof(def->network)-1, - "%s/%s", netaddr, (const char *)def->netmask); - } - - cur = node->children; - while (cur != NULL) { - if (cur->type == XML_ELEMENT_NODE && - xmlStrEqual(cur->name, BAD_CAST "dhcp") && - !qemudParseDhcpRangesXML(conn, driver, def, cur)) - return 0; - cur = cur->next; - } - - return 1; -} - - -static struct qemud_network_def *qemudParseNetworkXML(virConnectPtr conn, - struct qemud_driver *driver, - xmlDocPtr xml) { - xmlNodePtr root = NULL; - xmlXPathContextPtr ctxt = NULL; - xmlXPathObjectPtr obj = NULL, tmp = NULL; - struct qemud_network_def *def; - - if (VIR_ALLOC(def) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, - "%s", _("failed to allocate space for network_def string")); - return NULL; - } - - /* Prepare parser / xpath context */ - root = xmlDocGetRootElement(xml); - if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "network"))) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("incorrect root element")); - goto error; - } - - ctxt = xmlXPathNewContext(xml); - if (ctxt == NULL) { - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, - "%s", _("failed to allocate space for xmlXPathContext string")); - goto error; - } - - - /* Extract network name */ - obj = xmlXPathEval(BAD_CAST "string(/network/name[1])", ctxt); - if ((obj == NULL) || (obj->type != XPATH_STRING) || - (obj->stringval == NULL) || (obj->stringval[0] == 0)) { - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_NAME, NULL); - goto error; - } - if (strlen((const char *)obj->stringval) >= (QEMUD_MAX_NAME_LEN-1)) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("network name length too long")); - goto error; - } - strcpy(def->name, (const char *)obj->stringval); - xmlXPathFreeObject(obj); - - - /* Extract network uuid */ - obj = xmlXPathEval(BAD_CAST "string(/network/uuid[1])", ctxt); - if ((obj == NULL) || (obj->type != XPATH_STRING) || - (obj->stringval == NULL) || (obj->stringval[0] == 0)) { - int err; - if ((err = virUUIDGenerate(def->uuid))) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("Failed to generate UUID: %s"), strerror(err)); - goto error; - } - } else if (virUUIDParse((const char *)obj->stringval, def->uuid) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("malformed uuid element")); - goto error; - } - xmlXPathFreeObject(obj); - - /* Parse bridge information */ - obj = xmlXPathEval(BAD_CAST "/network/bridge[1]", ctxt); - if ((obj != NULL) && (obj->type == XPATH_NODESET) && - (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) { - if (!qemudParseBridgeXML(driver, def, obj->nodesetval->nodeTab[0])) { - goto error; - } - } - xmlXPathFreeObject(obj); - - /* Parse IP information */ - obj = xmlXPathEval(BAD_CAST "/network/ip[1]", ctxt); - if ((obj != NULL) && (obj->type == XPATH_NODESET) && - (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) { - if (!qemudParseInetXML(conn, driver, def, obj->nodesetval->nodeTab[0])) { - goto error; - } - } - xmlXPathFreeObject(obj); - - /* IPv4 forwarding setup */ - obj = xmlXPathEval(BAD_CAST "count(/network/forward) > 0", ctxt); - if ((obj != NULL) && (obj->type == XPATH_BOOLEAN) && - obj->boolval) { - if (!def->ipAddress[0] || - !def->netmask[0]) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("Forwarding requested, but no IPv4 address/netmask provided")); - goto error; - } - - def->forward = 1; - - tmp = xmlXPathEval(BAD_CAST "string(/network/forward[1]/@mode)", ctxt); - if ((tmp != NULL) && (tmp->type == XPATH_STRING) && - (tmp->stringval != NULL) && (xmlStrEqual(tmp->stringval, BAD_CAST "route"))) { - def->forwardMode = QEMUD_NET_FORWARD_ROUTE; - } else { - def->forwardMode = QEMUD_NET_FORWARD_NAT; - } - xmlXPathFreeObject(tmp); - tmp = NULL; - - tmp = xmlXPathEval(BAD_CAST "string(/network/forward[1]/@dev)", ctxt); - if ((tmp != NULL) && (tmp->type == XPATH_STRING) && - (tmp->stringval != NULL) && (tmp->stringval[0] != 0)) { - int len; - if ((len = xmlStrlen(tmp->stringval)) >= (BR_IFNAME_MAXLEN-1)) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("forward device name '%s' is too long"), - (char*)tmp->stringval); - goto error; - } - strcpy(def->forwardDev, (char*)tmp->stringval); - } else { - def->forwardDev[0] = '\0'; - } - xmlXPathFreeObject(tmp); - tmp = NULL; - } else { - def->forward = 0; - } - xmlXPathFreeObject(obj); - - xmlXPathFreeContext(ctxt); - - return def; - - error: - /* XXX free all the stuff in the qemud_network struct, or leave it upto - the caller ? */ - xmlXPathFreeObject(obj); - xmlXPathFreeObject(tmp); - xmlXPathFreeContext(ctxt); - qemudFreeNetworkDef(def); - return NULL; -} - -struct qemud_network_def * -qemudParseNetworkDef(virConnectPtr conn, - struct qemud_driver *driver, - const char *xmlStr, - const char *displayName) { - xmlDocPtr xml; - struct qemud_network_def *def; - - if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "network.xml", NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | - XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR, NULL); - return NULL; - } - - def = qemudParseNetworkXML(conn, driver, xml); - - xmlFreeDoc(xml); - - return def; -} - -struct qemud_network * -qemudAssignNetworkDef(virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network_def *def) { - struct qemud_network *network; - - if ((network = qemudFindNetworkByName(driver, def->name))) { - if (!qemudIsActiveNetwork(network)) { - qemudFreeNetworkDef(network->def); - network->def = def; - } else { - if (network->newDef) - qemudFreeNetworkDef(network->newDef); - network->newDef = def; - } - - return network; - } - - if (VIR_ALLOC(network) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, - "%s", _("failed to allocate space for network string")); - return NULL; - } - - network->def = def; - network->next = driver->networks; - - driver->networks = network; - driver->ninactivenetworks++; - - return network; -} - -void -qemudRemoveInactiveNetwork(struct qemud_driver *driver, - struct qemud_network *network) -{ - struct qemud_network *prev = NULL, *curr; - - curr = driver->networks; - while (curr != network) { - prev = curr; - curr = curr->next; - } - - if (curr) { - if (prev) - prev->next = curr->next; - else - driver->networks = curr->next; - - driver->ninactivenetworks--; - } - - qemudFreeNetwork(network); -} - -int -qemudSaveNetworkDef(virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network *network, - struct qemud_network_def *def) { - - if (network->configFile[0] == '\0') { - int err; - - if ((err = virFileMakePath(driver->networkConfigDir))) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot create config directory %s: %s"), - driver->networkConfigDir, strerror(err)); - return -1; - } - - if (virFileBuildPath(driver->networkConfigDir, def->name, ".xml", - network->configFile, PATH_MAX) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot construct config file path")); - return -1; - } - - if (virFileBuildPath(driver->networkAutostartDir, def->name, ".xml", - network->autostartLink, PATH_MAX) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot construct autostart link path")); - network->configFile[0] = '\0'; - return -1; - } - } - - return qemudSaveNetworkConfig(conn, driver, network, def); -} - static struct qemud_vm * qemudLoadConfig(struct qemud_driver *driver, @@ -3618,54 +3133,10 @@ return vm; } -static struct qemud_network * -qemudLoadNetworkConfig(struct qemud_driver *driver, - const char *file, - const char *path, - const char *xml, - const char *autostartLink) { - struct qemud_network_def *def; - struct qemud_network *network; - - if (!(def = qemudParseNetworkDef(NULL, driver, xml, file))) { - virErrorPtr err = virGetLastError(); - qemudLog(QEMUD_WARN, _("Error parsing network config '%s' : %s"), - path, err->message); - return NULL; - } - - if (!virFileMatchesNameSuffix(file, def->name, ".xml")) { - qemudLog(QEMUD_WARN, - _("Network config filename '%s'" - " does not match network name '%s'"), - path, def->name); - qemudFreeNetworkDef(def); - return NULL; - } - - if (!(network = qemudAssignNetworkDef(NULL, driver, def))) { - qemudLog(QEMUD_WARN, - _("Failed to load network config '%s': out of memory"), path); - qemudFreeNetworkDef(def); - return NULL; - } - - strncpy(network->configFile, path, PATH_MAX); - network->configFile[PATH_MAX-1] = '\0'; - - strncpy(network->autostartLink, autostartLink, PATH_MAX); - network->autostartLink[PATH_MAX-1] = '\0'; - - network->autostart = virFileLinkPointsTo(network->autostartLink, network->configFile); - - return network; -} - static int qemudScanConfigDir(struct qemud_driver *driver, const char *configDir, - const char *autostartDir, - int isGuest) { + const char *autostartDir) { DIR *dir; struct dirent *entry; @@ -3704,10 +3175,7 @@ if (virFileReadAll(path, QEMUD_MAX_XML_LEN, &xml) < 0) continue; - if (isGuest) - qemudLoadConfig(driver, entry->d_name, path, xml, autostartLink); - else - qemudLoadNetworkConfig(driver, entry->d_name, path, xml, autostartLink); + qemudLoadConfig(driver, entry->d_name, path, xml, autostartLink); VIR_FREE(xml); } @@ -3719,10 +3187,7 @@ /* Scan for all guest and network config files */ int qemudScanConfigs(struct qemud_driver *driver) { - if (qemudScanConfigDir(driver, driver->configDir, driver->autostartDir, 1) < 0) - return -1; - - if (qemudScanConfigDir(driver, driver->networkConfigDir, driver->networkAutostartDir, 0) < 0) + if (qemudScanConfigDir(driver, driver->configDir, driver->autostartDir) < 0) return -1; return 0; @@ -4128,83 +3593,6 @@ } -char *qemudGenerateNetworkXML(virConnectPtr conn, - struct qemud_driver *driver ATTRIBUTE_UNUSED, - struct qemud_network *network, - struct qemud_network_def *def) { - virBuffer buf = VIR_BUFFER_INITIALIZER; - unsigned char *uuid; - char *tmp; - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - virBufferAddLit(&buf, "<network>\n"); - - virBufferVSprintf(&buf, " <name>%s</name>\n", def->name); - - uuid = def->uuid; - virUUIDFormat(uuid, uuidstr); - virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr); - - if (def->forward) { - if (def->forwardDev[0]) { - virBufferVSprintf(&buf, " <forward dev='%s' mode='%s'/>\n", - def->forwardDev, (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat")); - } else { - virBufferVSprintf(&buf, " <forward mode='%s'/>\n", (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat")); - } - } - - virBufferAddLit(&buf, " <bridge"); - if (qemudIsActiveNetwork(network)) { - virBufferVSprintf(&buf, " name='%s'", network->bridge); - } else if (def->bridge[0]) { - virBufferVSprintf(&buf, " name='%s'", def->bridge); - } - virBufferVSprintf(&buf, " stp='%s' forwardDelay='%d' />\n", - def->disableSTP ? "off" : "on", - def->forwardDelay); - - if (def->ipAddress[0] || def->netmask[0]) { - virBufferAddLit(&buf, " <ip"); - - if (def->ipAddress[0]) - virBufferVSprintf(&buf, " address='%s'", def->ipAddress); - - if (def->netmask[0]) - virBufferVSprintf(&buf, " netmask='%s'", def->netmask); - - virBufferAddLit(&buf, ">\n"); - - if (def->ranges) { - struct qemud_dhcp_range_def *range = def->ranges; - virBufferAddLit(&buf, " <dhcp>\n"); - while (range) { - virBufferVSprintf(&buf, " <range start='%s' end='%s' />\n", - range->start, range->end); - range = range->next; - } - virBufferAddLit(&buf, " </dhcp>\n"); - } - - virBufferAddLit(&buf, " </ip>\n"); - } - - virBufferAddLit(&buf, "</network>\n"); - - if (virBufferError(&buf)) - goto no_memory; - - return virBufferContentAndReset(&buf); - - no_memory: - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, - "%s", _("failed to generate XML: out of memory")); - tmp = virBufferContentAndReset(&buf); - VIR_FREE(tmp); - return NULL; -} - - int qemudDeleteConfig(virConnectPtr conn, struct qemud_driver *driver ATTRIBUTE_UNUSED, const char *configFile, diff -r 86abc19320a1 src/qemu_conf.h --- a/src/qemu_conf.h Tue Jul 08 15:06:51 2008 +0100 +++ b/src/qemu_conf.h Tue Jul 08 15:26:10 2008 +0100 @@ -32,6 +32,7 @@ #include "bridge.h" #include "iptables.h" #include "capabilities.h" +#include "network_conf.h" #include <netinet/in.h> #include <sched.h> @@ -94,12 +95,6 @@ QEMUD_NET_MCAST, QEMUD_NET_NETWORK, QEMUD_NET_BRIDGE, -}; - -/* 2 possible types of forwarding */ -enum qemud_vm_net_forward_type { - QEMUD_NET_FORWARD_NAT, - QEMUD_NET_FORWARD_ROUTE, }; #define QEMUD_MAX_NAME_LEN 50 @@ -349,53 +344,6 @@ struct qemud_vm *next; }; -/* Store start and end addresses of a dhcp range */ -struct qemud_dhcp_range_def { - char start[BR_INET_ADDR_MAXLEN]; - char end[BR_INET_ADDR_MAXLEN]; - - struct qemud_dhcp_range_def *next; -}; - -/* Virtual Network main configuration */ -struct qemud_network_def { - unsigned char uuid[VIR_UUID_BUFLEN]; - char name[QEMUD_MAX_NAME_LEN]; - - char bridge[BR_IFNAME_MAXLEN]; - int disableSTP; - int forwardDelay; - - int forward; - int forwardMode; /* From qemud_vm_net_forward_type */ - char forwardDev[BR_IFNAME_MAXLEN]; - - char ipAddress[BR_INET_ADDR_MAXLEN]; - char netmask[BR_INET_ADDR_MAXLEN]; - char network[BR_INET_ADDR_MAXLEN+BR_INET_ADDR_MAXLEN+1]; - - int nranges; - struct qemud_dhcp_range_def *ranges; -}; - -/* Virtual Network runtime state */ -struct qemud_network { - char configFile[PATH_MAX]; - char autostartLink[PATH_MAX]; - - struct qemud_network_def *def; /* The current definition */ - struct qemud_network_def *newDef; /* New definition to activate at shutdown */ - - char bridge[BR_IFNAME_MAXLEN]; - int dnsmasqPid; - - unsigned int active : 1; - unsigned int autostart : 1; - - struct qemud_network *next; -}; - - /* Main driver state */ struct qemud_driver { int qemuVersion; @@ -403,9 +351,9 @@ int ninactivevms; struct qemud_vm *vms; int nextvmid; - int nactivenetworks; - int ninactivenetworks; - struct qemud_network *networks; + + virNetworkObjPtr networks; + brControl *brctl; iptablesContext *iptables; char *configDir; @@ -428,12 +376,6 @@ return vm->id != -1; } -static inline int -qemudIsActiveNetwork(const struct qemud_network *network) -{ - return network->active; -} - void qemudReportError(virConnectPtr conn, virDomainPtr dom, virNetworkPtr net, @@ -450,11 +392,6 @@ const unsigned char *uuid); struct qemud_vm *qemudFindVMByName(const struct qemud_driver *driver, const char *name); - -struct qemud_network *qemudFindNetworkByUUID(const struct qemud_driver *driver, - const unsigned char *uuid); -struct qemud_network *qemudFindNetworkByName(const struct qemud_driver *driver, - const char *name); virCapsPtr qemudCapsInit (void); @@ -501,30 +438,6 @@ struct qemud_vm_def *def, int live); -void qemudFreeNetworkDef (struct qemud_network_def *def); -void qemudFreeNetwork (struct qemud_network *network); - -struct qemud_network * - qemudAssignNetworkDef (virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network_def *def); -void qemudRemoveInactiveNetwork (struct qemud_driver *driver, - struct qemud_network *network); - -struct qemud_network_def * - qemudParseNetworkDef (virConnectPtr conn, - struct qemud_driver *driver, - const char *xmlStr, - const char *displayName); -int qemudSaveNetworkDef (virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network *network, - struct qemud_network_def *def); -char * qemudGenerateNetworkXML (virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network *network, - struct qemud_network_def *def); - const char *qemudVirtTypeToString (int type); #endif /* WITH_QEMU */ diff -r 86abc19320a1 src/qemu_driver.c --- a/src/qemu_driver.c Tue Jul 08 15:06:51 2008 +0100 +++ b/src/qemu_driver.c Tue Jul 08 15:26:10 2008 +0100 @@ -120,11 +120,11 @@ static int qemudStartNetworkDaemon(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network); + virNetworkObjPtr network); static int qemudShutdownNetworkDaemon(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network); + virNetworkObjPtr network); static int qemudDomainGetMaxVcpus(virDomainPtr dom); static int qemudMonitorCommand (const struct qemud_driver *driver, @@ -137,15 +137,15 @@ static void qemudAutostartConfigs(struct qemud_driver *driver) { - struct qemud_network *network; + virNetworkObjPtr network; struct qemud_vm *vm; network = driver->networks; while (network != NULL) { - struct qemud_network *next = network->next; + virNetworkObjPtr next = network->next; if (network->autostart && - !qemudIsActiveNetwork(network) && + !virNetworkIsActive(network) && qemudStartNetworkDaemon(NULL, driver, network) < 0) { virErrorPtr err = virGetLastError(); qemudLog(QEMUD_ERR, _("Failed to autostart network '%s': %s"), @@ -247,6 +247,13 @@ qemudShutdown(); return -1; } + if (virNetworkLoadAllConfigs(NULL, + &qemu_driver->networks, + qemu_driver->networkConfigDir, + qemu_driver->networkAutostartDir) < 0) { + qemudShutdown(); + return -1; + } qemudAutostartConfigs(qemu_driver); return 0; @@ -273,6 +280,10 @@ static int qemudReload(void) { qemudScanConfigs(qemu_driver); + virNetworkLoadAllConfigs(NULL, + &qemu_driver->networks, + qemu_driver->networkConfigDir, + qemu_driver->networkAutostartDir); if (qemu_driver->iptables) { qemudLog(QEMUD_INFO, @@ -295,11 +306,14 @@ */ static int qemudActive(void) { - /* If we've any active networks or guests, then we - * mark this driver as active - */ - if (qemu_driver->nactivenetworks && - qemu_driver->nactivevms) + virNetworkObjPtr net = qemu_driver->networks; + while (net) { + if (net->active) + return 1; + net = net->next; + } + + if (qemu_driver->nactivevms) return 1; /* Otherwise we're happy to deal with a shutdown */ @@ -314,7 +328,7 @@ static int qemudShutdown(void) { struct qemud_vm *vm; - struct qemud_network *network; + virNetworkObjPtr network; if (!qemu_driver) return -1; @@ -346,8 +360,8 @@ /* shutdown active networks */ network = qemu_driver->networks; while (network) { - struct qemud_network *next = network->next; - if (qemudIsActiveNetwork(network)) + virNetworkObjPtr next = network->next; + if (virNetworkIsActive(network)) qemudShutdownNetworkDaemon(NULL, qemu_driver, network); network = next; } @@ -355,13 +369,11 @@ /* free inactive networks */ network = qemu_driver->networks; while (network) { - struct qemud_network *next = network->next; - qemudFreeNetwork(network); + virNetworkObjPtr next = network->next; + virNetworkObjFree(network); network = next; } qemu_driver->networks = NULL; - qemu_driver->nactivenetworks = 0; - qemu_driver->ninactivenetworks = 0; VIR_FREE(qemu_driver->configDir); VIR_FREE(qemu_driver->autostartDir); @@ -1039,11 +1051,10 @@ static int qemudBuildDnsmasqArgv(virConnectPtr conn, - struct qemud_network *network, + virNetworkObjPtr network, char ***argv) { - int i, len; + int i, len, r; char buf[PATH_MAX]; - struct qemud_dhcp_range_def *range; len = 1 + /* dnsmasq */ @@ -1109,15 +1120,13 @@ LOCAL_STATE_DIR, network->def->name); APPEND_ARG(*argv, i++, buf); - range = network->def->ranges; - while (range) { + for (r = 0 ; r < network->def->nranges ; r++) { snprintf(buf, sizeof(buf), "%s,%s", - range->start, range->end); + network->def->ranges[r].start, + network->def->ranges[r].end); APPEND_ARG(*argv, i++, "--dhcp-range"); APPEND_ARG(*argv, i++, buf); - - range = range->next; } #undef APPEND_ARG @@ -1138,12 +1147,12 @@ static int dhcpStartDhcpDaemon(virConnectPtr conn, - struct qemud_network *network) + virNetworkObjPtr network) { char **argv; int ret, i; - if (network->def->ipAddress[0] == '\0') { + if (network->def->ipAddress == NULL) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("cannot start dhcp daemon without IP address for server")); return -1; @@ -1165,27 +1174,27 @@ static int qemudAddMasqueradingIptablesRules(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network) { + virNetworkObjPtr network) { int err; /* allow forwarding packets from the bridge interface */ if ((err = iptablesAddForwardAllowOut(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow forwarding from '%s' : %s\n"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto masqerr1; } /* allow forwarding packets to the bridge interface if they are part of an existing connection */ if ((err = iptablesAddForwardAllowRelatedIn(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow forwarding to '%s' : %s\n"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto masqerr2; } @@ -1204,12 +1213,12 @@ masqerr3: iptablesRemoveForwardAllowRelatedIn(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); masqerr2: iptablesRemoveForwardAllowOut(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); masqerr1: return 0; @@ -1218,27 +1227,27 @@ static int qemudAddRoutingIptablesRules(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network) { + virNetworkObjPtr network) { int err; /* allow routing packets from the bridge interface */ if ((err = iptablesAddForwardAllowOut(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow routing from '%s' : %s\n"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto routeerr1; } /* allow routing packets to the bridge interface */ if ((err = iptablesAddForwardAllowIn(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow routing to '%s' : %s\n"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto routeerr2; } @@ -1248,7 +1257,7 @@ routeerr2: iptablesRemoveForwardAllowOut(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); routeerr1: return 0; @@ -1257,7 +1266,7 @@ static int qemudAddIptablesRules(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network) { + virNetworkObjPtr network) { int err; if (!driver->iptables && !(driver->iptables = iptablesContextNew())) { @@ -1268,71 +1277,69 @@ /* allow DHCP requests through to dnsmasq */ - if ((err = iptablesAddTcpInput(driver->iptables, network->bridge, 67))) { + if ((err = iptablesAddTcpInput(driver->iptables, network->def->bridge, 67))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow DHCP requests from '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err1; } - if ((err = iptablesAddUdpInput(driver->iptables, network->bridge, 67))) { + if ((err = iptablesAddUdpInput(driver->iptables, network->def->bridge, 67))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow DHCP requests from '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err2; } /* allow DNS requests through to dnsmasq */ - if ((err = iptablesAddTcpInput(driver->iptables, network->bridge, 53))) { + if ((err = iptablesAddTcpInput(driver->iptables, network->def->bridge, 53))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow DNS requests from '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err3; } - if ((err = iptablesAddUdpInput(driver->iptables, network->bridge, 53))) { + if ((err = iptablesAddUdpInput(driver->iptables, network->def->bridge, 53))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow DNS requests from '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err4; } /* Catch all rules to block forwarding to/from bridges */ - if ((err = iptablesAddForwardRejectOut(driver->iptables, network->bridge))) { + if ((err = iptablesAddForwardRejectOut(driver->iptables, network->def->bridge))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to block outbound traffic from '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err5; } - if ((err = iptablesAddForwardRejectIn(driver->iptables, network->bridge))) { + if ((err = iptablesAddForwardRejectIn(driver->iptables, network->def->bridge))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to block inbound traffic to '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err6; } /* Allow traffic between guests on the same bridge */ - if ((err = iptablesAddForwardAllowCross(driver->iptables, network->bridge))) { + if ((err = iptablesAddForwardAllowCross(driver->iptables, network->def->bridge))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow cross bridge traffic on '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err7; } - if (network->def->forward) { - /* If masquerading is enabled, set up the rules*/ - if (network->def->forwardMode == QEMUD_NET_FORWARD_NAT && - !qemudAddMasqueradingIptablesRules(conn, driver, network)) - goto err8; - /* else if routing is enabled, set up the rules*/ - else if (network->def->forwardMode == QEMUD_NET_FORWARD_ROUTE && - !qemudAddRoutingIptablesRules(conn, driver, network)) - goto err8; - } + /* If masquerading is enabled, set up the rules*/ + if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT && + !qemudAddMasqueradingIptablesRules(conn, driver, network)) + goto err8; + /* else if routing is enabled, set up the rules*/ + else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE && + !qemudAddRoutingIptablesRules(conn, driver, network)) + goto err8; iptablesSaveRules(driver->iptables); @@ -1340,56 +1347,56 @@ err8: iptablesRemoveForwardAllowCross(driver->iptables, - network->bridge); + network->def->bridge); err7: iptablesRemoveForwardRejectIn(driver->iptables, - network->bridge); + network->def->bridge); err6: iptablesRemoveForwardRejectOut(driver->iptables, - network->bridge); + network->def->bridge); err5: - iptablesRemoveUdpInput(driver->iptables, network->bridge, 53); + iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53); err4: - iptablesRemoveTcpInput(driver->iptables, network->bridge, 53); + iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53); err3: - iptablesRemoveUdpInput(driver->iptables, network->bridge, 67); + iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67); err2: - iptablesRemoveTcpInput(driver->iptables, network->bridge, 67); + iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67); err1: return 0; } static void qemudRemoveIptablesRules(struct qemud_driver *driver, - struct qemud_network *network) { - if (network->def->forward) { + virNetworkObjPtr network) { + if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) { iptablesRemoveForwardMasquerade(driver->iptables, network->def->network, network->def->forwardDev); - if (network->def->forwardMode == QEMUD_NET_FORWARD_NAT) + if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) iptablesRemoveForwardAllowRelatedIn(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); - else if (network->def->forwardMode == QEMUD_NET_FORWARD_ROUTE) + else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE) iptablesRemoveForwardAllowIn(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); iptablesRemoveForwardAllowOut(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); } - iptablesRemoveForwardAllowCross(driver->iptables, network->bridge); - iptablesRemoveForwardRejectIn(driver->iptables, network->bridge); - iptablesRemoveForwardRejectOut(driver->iptables, network->bridge); - iptablesRemoveUdpInput(driver->iptables, network->bridge, 53); - iptablesRemoveTcpInput(driver->iptables, network->bridge, 53); - iptablesRemoveUdpInput(driver->iptables, network->bridge, 67); - iptablesRemoveTcpInput(driver->iptables, network->bridge, 67); + iptablesRemoveForwardAllowCross(driver->iptables, network->def->bridge); + iptablesRemoveForwardRejectIn(driver->iptables, network->def->bridge); + iptablesRemoveForwardRejectOut(driver->iptables, network->def->bridge); + iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53); + iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53); + iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67); + iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67); iptablesSaveRules(driver->iptables); } @@ -1415,11 +1422,10 @@ static int qemudStartNetworkDaemon(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network) { - const char *name; + virNetworkObjPtr network) { int err; - if (qemudIsActiveNetwork(network)) { + if (virNetworkIsActive(network)) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("network is already active")); return -1; @@ -1431,77 +1437,68 @@ return -1; } - if (network->def->bridge[0] == '\0' || - strchr(network->def->bridge, '%')) { - name = "vnet%d"; - } else { - name = network->def->bridge; - } - - if ((err = brAddBridge(driver->brctl, name, network->bridge, sizeof(network->bridge)))) { + if ((err = brAddBridge(driver->brctl, &network->def->bridge))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot create bridge '%s' : %s"), name, strerror(err)); + _("cannot create bridge '%s' : %s"), + network->def->bridge, strerror(err)); return -1; } - if (network->def->forwardDelay && - (err = brSetForwardDelay(driver->brctl, network->bridge, network->def->forwardDelay))) { + if (network->def->delay && + (err = brSetForwardDelay(driver->brctl, network->def->bridge, network->def->delay))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("failed to set bridge forward delay to %d"), - network->def->forwardDelay); + _("failed to set bridge forward delay to %ld"), + network->def->delay); goto err_delbr; } - if ((err = brSetEnableSTP(driver->brctl, network->bridge, network->def->disableSTP ? 0 : 1))) { + if ((err = brSetEnableSTP(driver->brctl, network->def->bridge, network->def->stp ? 1 : 0))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to set bridge STP to %s"), - network->def->disableSTP ? "off" : "on"); + network->def->stp ? "on" : "off"); goto err_delbr; } - if (network->def->ipAddress[0] && - (err = brSetInetAddress(driver->brctl, network->bridge, network->def->ipAddress))) { + if (network->def->ipAddress && + (err = brSetInetAddress(driver->brctl, network->def->bridge, network->def->ipAddress))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("cannot set IP address on bridge '%s' to '%s' : %s"), - network->bridge, network->def->ipAddress, strerror(err)); + network->def->bridge, network->def->ipAddress, strerror(err)); goto err_delbr; } - if (network->def->netmask[0] && - (err = brSetInetNetmask(driver->brctl, network->bridge, network->def->netmask))) { + if (network->def->netmask && + (err = brSetInetNetmask(driver->brctl, network->def->bridge, network->def->netmask))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("cannot set netmask on bridge '%s' to '%s' : %s"), - network->bridge, network->def->netmask, strerror(err)); + network->def->bridge, network->def->netmask, strerror(err)); goto err_delbr; } - if (network->def->ipAddress[0] && - (err = brSetInterfaceUp(driver->brctl, network->bridge, 1))) { + if (network->def->ipAddress && + (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to bring the bridge '%s' up : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err_delbr; } if (!qemudAddIptablesRules(conn, driver, network)) goto err_delbr1; - if (network->def->forward && + if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE && !qemudEnableIpForwarding()) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to enable IP forwarding : %s"), strerror(err)); goto err_delbr2; } - if (network->def->ranges && + if (network->def->nranges && dhcpStartDhcpDaemon(conn, network) < 0) goto err_delbr2; network->active = 1; - - driver->ninactivenetworks--; - driver->nactivenetworks++; return 0; @@ -1509,16 +1506,16 @@ qemudRemoveIptablesRules(driver, network); err_delbr1: - if (network->def->ipAddress[0] && - (err = brSetInterfaceUp(driver->brctl, network->bridge, 0))) { + if (network->def->ipAddress && + (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) { qemudLog(QEMUD_WARN, _("Failed to bring down bridge '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); } err_delbr: - if ((err = brDeleteBridge(driver->brctl, network->bridge))) { + if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) { qemudLog(QEMUD_WARN, _("Failed to delete bridge '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); } return -1; @@ -1527,12 +1524,12 @@ static int qemudShutdownNetworkDaemon(virConnectPtr conn ATTRIBUTE_UNUSED, struct qemud_driver *driver, - struct qemud_network *network) { + virNetworkObjPtr network) { int err; qemudLog(QEMUD_INFO, _("Shutting down network '%s'"), network->def->name); - if (!qemudIsActiveNetwork(network)) + if (!virNetworkIsActive(network)) return 0; if (network->dnsmasqPid > 0) @@ -1540,15 +1537,15 @@ qemudRemoveIptablesRules(driver, network); - if (network->def->ipAddress[0] && - (err = brSetInterfaceUp(driver->brctl, network->bridge, 0))) { + if (network->def->ipAddress && + (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) { qemudLog(QEMUD_WARN, _("Failed to bring down bridge '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); } - if ((err = brDeleteBridge(driver->brctl, network->bridge))) { + if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) { qemudLog(QEMUD_WARN, _("Failed to delete bridge '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); } if (network->dnsmasqPid > 0 && @@ -1559,21 +1556,18 @@ "%s", _("Got unexpected pid for dnsmasq")); } - network->bridge[0] = '\0'; network->dnsmasqPid = -1; network->active = 0; if (network->newDef) { - qemudFreeNetworkDef(network->def); + virNetworkDefFree(network->def); network->def = network->newDef; network->newDef = NULL; } - driver->nactivenetworks--; - driver->ninactivenetworks++; - - if (!network->configFile[0]) - qemudRemoveInactiveNetwork(driver, network); + if (!network->configFile) + virNetworkRemoveInactive(&driver->networks, + network); return 0; } @@ -3290,9 +3284,9 @@ } static virNetworkPtr qemudNetworkLookupByUUID(virConnectPtr conn ATTRIBUTE_UNUSED, - const unsigned char *uuid) { + const unsigned char *uuid) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, uuid); virNetworkPtr net; if (!network) { @@ -3305,9 +3299,9 @@ return net; } static virNetworkPtr qemudNetworkLookupByName(virConnectPtr conn ATTRIBUTE_UNUSED, - const char *name) { + const char *name) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByName(driver, name); + virNetworkObjPtr network = virNetworkFindByName(driver->networks, name); virNetworkPtr net; if (!network) { @@ -3337,16 +3331,23 @@ } static int qemudNumNetworks(virConnectPtr conn) { + int nactive = 0; struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - return driver->nactivenetworks; + virNetworkObjPtr net = driver->networks; + while (net) { + if (virNetworkIsActive(net)) + nactive++; + net = net->next; + } + return nactive; } static int qemudListNetworks(virConnectPtr conn, char **const names, int nnames) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network *network = driver->networks; + virNetworkObjPtr network = driver->networks; int got = 0, i; while (network && got < nnames) { - if (qemudIsActiveNetwork(network)) { + if (virNetworkIsActive(network)) { if (!(names[got] = strdup(network->def->name))) { qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "%s", _("failed to allocate space for VM name string")); @@ -3365,16 +3366,23 @@ } static int qemudNumDefinedNetworks(virConnectPtr conn) { + int ninactive = 0; struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - return driver->ninactivenetworks; + virNetworkObjPtr net = driver->networks; + while (net) { + if (!virNetworkIsActive(net)) + ninactive++; + net = net->next; + } + return ninactive; } static int qemudListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network *network = driver->networks; + virNetworkObjPtr network = driver->networks; int got = 0, i; while (network && got < nnames) { - if (!qemudIsActiveNetwork(network)) { + if (!virNetworkIsActive(network)) { if (!(names[got] = strdup(network->def->name))) { qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "%s", _("failed to allocate space for VM name string")); @@ -3394,20 +3402,23 @@ static virNetworkPtr qemudNetworkCreate(virConnectPtr conn, const char *xml) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network_def *def; - struct qemud_network *network; + virNetworkDefPtr def; + virNetworkObjPtr network; virNetworkPtr net; - if (!(def = qemudParseNetworkDef(conn, driver, xml, NULL))) + if (!(def = virNetworkDefParseString(conn, xml))) return NULL; - if (!(network = qemudAssignNetworkDef(conn, driver, def))) { - qemudFreeNetworkDef(def); + if (!(network = virNetworkAssignDef(conn, + &driver->networks, + def))) { + virNetworkDefFree(def); return NULL; } if (qemudStartNetworkDaemon(conn, driver, network) < 0) { - qemudRemoveInactiveNetwork(driver, network); + virNetworkRemoveInactive(&driver->networks, + network); return NULL; } @@ -3417,30 +3428,34 @@ static virNetworkPtr qemudNetworkDefine(virConnectPtr conn, const char *xml) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network_def *def; - struct qemud_network *network; - virNetworkPtr net; + virNetworkDefPtr def; + virNetworkObjPtr network; - if (!(def = qemudParseNetworkDef(conn, driver, xml, NULL))) + if (!(def = virNetworkDefParseString(conn, xml))) return NULL; - if (!(network = qemudAssignNetworkDef(conn, driver, def))) { - qemudFreeNetworkDef(def); + if (!(network = virNetworkAssignDef(conn, + &driver->networks, + def))) { + virNetworkDefFree(def); return NULL; } - if (qemudSaveNetworkDef(conn, driver, network, def) < 0) { - qemudRemoveInactiveNetwork(driver, network); + if (virNetworkSaveConfig(conn, + driver->networkConfigDir, + driver->networkAutostartDir, + network) < 0) { + virNetworkRemoveInactive(&driver->networks, + network); return NULL; } - net = virGetNetwork(conn, network->def->name, network->def->uuid); - return net; + return virGetNetwork(conn, network->def->name, network->def->uuid); } static int qemudNetworkUndefine(virNetworkPtr net) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_DOMAIN, @@ -3448,24 +3463,24 @@ return -1; } - if (qemudDeleteConfig(net->conn, driver, network->configFile, network->def->name) < 0) + if (virNetworkIsActive(network)) { + qemudReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR, + "%s", _("network is still active")); + return -1; + } + + if (virNetworkDeleteConfig(net->conn, network) < 0) return -1; - if (unlink(network->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) - qemudLog(QEMUD_WARN, _("Failed to delete autostart link '%s': %s"), - network->autostartLink, strerror(errno)); - - network->configFile[0] = '\0'; - network->autostartLink[0] = '\0'; - - qemudRemoveInactiveNetwork(driver, network); + virNetworkRemoveInactive(&driver->networks, + network); return 0; } static int qemudNetworkStart(virNetworkPtr net) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK, @@ -3478,7 +3493,7 @@ static int qemudNetworkDestroy(virNetworkPtr net) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); int ret; if (!network) { @@ -3494,7 +3509,7 @@ static char *qemudNetworkDumpXML(virNetworkPtr net, int flags ATTRIBUTE_UNUSED) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK, @@ -3502,12 +3517,12 @@ return NULL; } - return qemudGenerateNetworkXML(net->conn, driver, network, network->def); + return virNetworkDefFormat(net->conn, network->def); } static char *qemudNetworkGetBridgeName(virNetworkPtr net) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); char *bridge; if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK, @@ -3515,7 +3530,7 @@ return NULL; } - bridge = strdup(network->bridge); + bridge = strdup(network->def->bridge); if (!bridge) { qemudReportError(net->conn, NULL, net, VIR_ERR_NO_MEMORY, "%s", _("failed to allocate space for network bridge string")); @@ -3527,7 +3542,7 @@ static int qemudNetworkGetAutostart(virNetworkPtr net, int *autostart) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK, @@ -3543,7 +3558,7 @@ static int qemudNetworkSetAutostart(virNetworkPtr net, int autostart) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK, -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list