Thu Feb 15 15:56:32 IST 2007 Mark McLoughlin <markmc@redhat.com>

* qemud/conf.[ch], qemud/dispatch.c, qemud/internal.h,
	  qemud/qemud.c, qemud/driver.c: allow re-defining network
	configs; basically copying dan's patch for domains.
This commit is contained in:
Mark McLoughlin 2007-02-15 16:00:16 +00:00
parent f83f9ad351
commit f9f7aeb4b7
6 changed files with 133 additions and 117 deletions

View File

@ -1256,24 +1256,13 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
} }
void qemudFreeNetwork(struct qemud_network *network) {
struct qemud_dhcp_range_def *range = network->def.ranges;
while (range) {
struct qemud_dhcp_range_def *next = range->next;
free(range);
range = next;
}
free(network);
}
static int qemudSaveNetworkConfig(struct qemud_server *server, static int qemudSaveNetworkConfig(struct qemud_server *server,
struct qemud_network *network) { struct qemud_network *network) {
char *xml; char *xml;
int fd, ret = -1; int fd, ret = -1;
int towrite; int towrite;
if (!(xml = qemudGenerateNetworkXML(server, network))) { if (!(xml = qemudGenerateNetworkXML(server, network, 0))) {
return -1; return -1;
} }
@ -1308,16 +1297,32 @@ static int qemudSaveNetworkConfig(struct qemud_server *server,
return ret; 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;
free(range);
range = next;
}
free(def);
}
void qemudFreeNetwork(struct qemud_network *network) {
qemudFreeNetworkDef(network->def);
if (network->newDef)
qemudFreeNetworkDef(network->newDef);
free(network);
}
static int qemudParseBridgeXML(struct qemud_server *server ATTRIBUTE_UNUSED, static int qemudParseBridgeXML(struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_network *network, struct qemud_network_def *def,
xmlNodePtr node) { xmlNodePtr node) {
xmlChar *name, *stp, *delay; xmlChar *name, *stp, *delay;
name = xmlGetProp(node, BAD_CAST "name"); name = xmlGetProp(node, BAD_CAST "name");
if (name != NULL) { if (name != NULL) {
strncpy(network->def.bridge, (const char *)name, IF_NAMESIZE-1); strncpy(def->bridge, (const char *)name, IF_NAMESIZE-1);
network->def.bridge[IF_NAMESIZE-1] = '\0'; def->bridge[IF_NAMESIZE-1] = '\0';
xmlFree(name); xmlFree(name);
name = NULL; name = NULL;
} }
@ -1325,7 +1330,7 @@ static int qemudParseBridgeXML(struct qemud_server *server ATTRIBUTE_UNUSED,
stp = xmlGetProp(node, BAD_CAST "stp"); stp = xmlGetProp(node, BAD_CAST "stp");
if (stp != NULL) { if (stp != NULL) {
if (xmlStrEqual(stp, BAD_CAST "off")) { if (xmlStrEqual(stp, BAD_CAST "off")) {
network->def.disableSTP = 1; def->disableSTP = 1;
} }
xmlFree(stp); xmlFree(stp);
stp = NULL; stp = NULL;
@ -1333,7 +1338,7 @@ static int qemudParseBridgeXML(struct qemud_server *server ATTRIBUTE_UNUSED,
delay = xmlGetProp(node, BAD_CAST "delay"); delay = xmlGetProp(node, BAD_CAST "delay");
if (delay != NULL) { if (delay != NULL) {
network->def.forwardDelay = strtol((const char *)delay, NULL, 10); def->forwardDelay = strtol((const char *)delay, NULL, 10);
xmlFree(delay); xmlFree(delay);
delay = NULL; delay = NULL;
} }
@ -1342,7 +1347,7 @@ static int qemudParseBridgeXML(struct qemud_server *server ATTRIBUTE_UNUSED,
} }
static int qemudParseDhcpRangesXML(struct qemud_server *server, static int qemudParseDhcpRangesXML(struct qemud_server *server,
struct qemud_network *network, struct qemud_network_def *def,
xmlNodePtr node) { xmlNodePtr node) {
xmlNodePtr cur; xmlNodePtr cur;
@ -1373,9 +1378,9 @@ static int qemudParseDhcpRangesXML(struct qemud_server *server,
strncpy(range->end, (const char *)end, BR_INET_ADDR_MAXLEN-1); strncpy(range->end, (const char *)end, BR_INET_ADDR_MAXLEN-1);
range->end[BR_INET_ADDR_MAXLEN-1] = '\0'; range->end[BR_INET_ADDR_MAXLEN-1] = '\0';
range->next = network->def.ranges; range->next = def->ranges;
network->def.ranges = range; def->ranges = range;
network->def.nranges++; def->nranges++;
} else { } else {
free(range); free(range);
} }
@ -1392,23 +1397,23 @@ static int qemudParseDhcpRangesXML(struct qemud_server *server,
} }
static int qemudParseInetXML(struct qemud_server *server ATTRIBUTE_UNUSED, static int qemudParseInetXML(struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_network *network, struct qemud_network_def *def,
xmlNodePtr node) { xmlNodePtr node) {
xmlChar *address, *netmask; xmlChar *address, *netmask;
xmlNodePtr cur; xmlNodePtr cur;
address = xmlGetProp(node, BAD_CAST "address"); address = xmlGetProp(node, BAD_CAST "address");
if (address != NULL) { if (address != NULL) {
strncpy(network->def.ipAddress, (const char *)address, BR_INET_ADDR_MAXLEN-1); strncpy(def->ipAddress, (const char *)address, BR_INET_ADDR_MAXLEN-1);
network->def.ipAddress[BR_INET_ADDR_MAXLEN-1] = '\0'; def->ipAddress[BR_INET_ADDR_MAXLEN-1] = '\0';
xmlFree(address); xmlFree(address);
address = NULL; address = NULL;
} }
netmask = xmlGetProp(node, BAD_CAST "netmask"); netmask = xmlGetProp(node, BAD_CAST "netmask");
if (netmask != NULL) { if (netmask != NULL) {
strncpy(network->def.netmask, (const char *)netmask, BR_INET_ADDR_MAXLEN-1); strncpy(def->netmask, (const char *)netmask, BR_INET_ADDR_MAXLEN-1);
network->def.netmask[BR_INET_ADDR_MAXLEN-1] = '\0'; def->netmask[BR_INET_ADDR_MAXLEN-1] = '\0';
xmlFree(netmask); xmlFree(netmask);
netmask = NULL; netmask = NULL;
} }
@ -1417,7 +1422,7 @@ static int qemudParseInetXML(struct qemud_server *server ATTRIBUTE_UNUSED,
while (cur != NULL) { while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE && if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "dhcp") && xmlStrEqual(cur->name, BAD_CAST "dhcp") &&
!qemudParseDhcpRangesXML(server, network, cur)) !qemudParseDhcpRangesXML(server, def, cur))
return 0; return 0;
cur = cur->next; cur = cur->next;
} }
@ -1426,12 +1431,17 @@ static int qemudParseInetXML(struct qemud_server *server ATTRIBUTE_UNUSED,
} }
static int qemudParseNetworkXML(struct qemud_server *server, static struct qemud_network_def *qemudParseNetworkXML(struct qemud_server *server,
xmlDocPtr xml, xmlDocPtr xml) {
struct qemud_network *network) {
xmlNodePtr root = NULL; xmlNodePtr root = NULL;
xmlXPathContextPtr ctxt = NULL; xmlXPathContextPtr ctxt = NULL;
xmlXPathObjectPtr obj = NULL; xmlXPathObjectPtr obj = NULL;
struct qemud_network_def *def;
if (!(def = calloc(1, sizeof(struct qemud_network_def)))) {
qemudReportError(server, VIR_ERR_NO_MEMORY, "network_def");
return NULL;
}
/* Prepare parser / xpath context */ /* Prepare parser / xpath context */
root = xmlDocGetRootElement(xml); root = xmlDocGetRootElement(xml);
@ -1458,7 +1468,7 @@ static int qemudParseNetworkXML(struct qemud_server *server,
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "network name length too long"); qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "network name length too long");
goto error; goto error;
} }
strcpy(network->def.name, (const char *)obj->stringval); strcpy(def->name, (const char *)obj->stringval);
xmlXPathFreeObject(obj); xmlXPathFreeObject(obj);
@ -1470,7 +1480,7 @@ static int qemudParseNetworkXML(struct qemud_server *server,
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "missing uuid element"); qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "missing uuid element");
goto error; goto error;
} }
if (qemudParseUUID((const char *)obj->stringval, network->def.uuid) < 0) { if (qemudParseUUID((const char *)obj->stringval, def->uuid) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "malformed uuid element"); qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "malformed uuid element");
goto error; goto error;
} }
@ -1480,7 +1490,7 @@ static int qemudParseNetworkXML(struct qemud_server *server,
obj = xmlXPathEval(BAD_CAST "/network/bridge[1]", ctxt); obj = xmlXPathEval(BAD_CAST "/network/bridge[1]", ctxt);
if ((obj != NULL) && (obj->type == XPATH_NODESET) && if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) { (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) {
if (!qemudParseBridgeXML(server, network, obj->nodesetval->nodeTab[0])) { if (!qemudParseBridgeXML(server, def, obj->nodesetval->nodeTab[0])) {
goto error; goto error;
} }
} }
@ -1490,7 +1500,7 @@ static int qemudParseNetworkXML(struct qemud_server *server,
obj = xmlXPathEval(BAD_CAST "/network/ip[1]", ctxt); obj = xmlXPathEval(BAD_CAST "/network/ip[1]", ctxt);
if ((obj != NULL) && (obj->type == XPATH_NODESET) && if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) { (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) {
if (!qemudParseInetXML(server, network, obj->nodesetval->nodeTab[0])) { if (!qemudParseInetXML(server, def, obj->nodesetval->nodeTab[0])) {
goto error; goto error;
} }
} }
@ -1498,7 +1508,7 @@ static int qemudParseNetworkXML(struct qemud_server *server,
xmlXPathFreeContext(ctxt); xmlXPathFreeContext(ctxt);
return 0; return def;
error: error:
/* XXX free all the stuff in the qemud_network struct, or leave it upto /* XXX free all the stuff in the qemud_network struct, or leave it upto
@ -1507,15 +1517,18 @@ static int qemudParseNetworkXML(struct qemud_server *server,
xmlXPathFreeObject(obj); xmlXPathFreeObject(obj);
if (ctxt) if (ctxt)
xmlXPathFreeContext(ctxt); xmlXPathFreeContext(ctxt);
return -1; qemudFreeNetworkDef(def);
return NULL;
} }
struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server, struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
const char *file, const char *file,
const char *doc, const char *doc,
int save) { int save) {
struct qemud_network_def *def = NULL;
struct qemud_network *network = NULL; struct qemud_network *network = NULL;
xmlDocPtr xml; xmlDocPtr xml;
int newNetwork = 0;
if (!(xml = xmlReadDoc(BAD_CAST doc, file ? file : "network.xml", NULL, if (!(xml = xmlReadDoc(BAD_CAST doc, file ? file : "network.xml", NULL,
XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOENT | XML_PARSE_NONET |
@ -1524,23 +1537,28 @@ struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
return NULL; return NULL;
} }
if (!(def = qemudParseNetworkXML(server, xml))) {
xmlFreeDoc(xml);
return NULL;
}
xmlFreeDoc(xml);
if ((network = qemudFindNetworkByName(server, def->name))) {
if (!network->active) {
qemudFreeNetworkDef(network->def);
network->def = def;
} else {
if (network->newDef)
qemudFreeNetworkDef(network->newDef);
network->newDef = def;
}
} else {
if (!(network = calloc(1, sizeof(struct qemud_network)))) { if (!(network = calloc(1, sizeof(struct qemud_network)))) {
qemudReportError(server, VIR_ERR_NO_MEMORY, "network"); qemudReportError(server, VIR_ERR_NO_MEMORY, "network");
return NULL; return NULL;
} }
if (qemudParseNetworkXML(server, xml, network) < 0) { newNetwork = 1;
xmlFreeDoc(xml);
qemudFreeNetwork(network);
return NULL;
}
xmlFreeDoc(xml);
if (qemudFindNetworkByUUID(server, network->def.uuid) ||
qemudFindNetworkByName(server, network->def.name)) {
qemudReportError(server, VIR_ERR_NETWORK_EXIST, network->def.name);
qemudFreeNetwork(network);
return NULL;
} }
if (file) { if (file) {
@ -1548,7 +1566,7 @@ struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
network->configFile[PATH_MAX-1] = '\0'; network->configFile[PATH_MAX-1] = '\0';
} else { } else {
if (save) { if (save) {
if (qemudMakeConfigPath(server->networkConfigDir, network->def.name, ".xml", network->configFile, PATH_MAX) < 0) { if (qemudMakeConfigPath(server->networkConfigDir, network->def->name, ".xml", network->configFile, PATH_MAX) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot construct config file path"); qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot construct config file path");
qemudFreeNetwork(network); qemudFreeNetwork(network);
return NULL; return NULL;
@ -1563,6 +1581,12 @@ struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
} }
} }
if (newNetwork) {
network->next = server->inactivenetworks;
server->inactivenetworks = network;
server->ninactivenetworks++;
}
return network; return network;
} }
@ -1600,12 +1624,7 @@ static void qemudLoadConfig(struct qemud_server *server,
if (isGuest) { if (isGuest) {
qemudLoadConfigXML(server, file, xml, 1); qemudLoadConfigXML(server, file, xml, 1);
} else { } else {
struct qemud_network *network; qemudLoadNetworkConfigXML(server, file, xml, 1);
if ((network = qemudLoadNetworkConfigXML(server, file, xml, 1))) {
network->next = server->inactivenetworks;
server->inactivenetworks = network;
server->ninactivenetworks++;
}
} }
cleanup: cleanup:
fclose(fh); fclose(fh);
@ -1914,7 +1933,9 @@ char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm, int liv
char *qemudGenerateNetworkXML(struct qemud_server *server, char *qemudGenerateNetworkXML(struct qemud_server *server,
struct qemud_network *network) { struct qemud_network *network,
int live) {
struct qemud_network_def *def = live ? network->def : (network->newDef ? network->newDef : network->def);
struct qemudBuffer buf; struct qemudBuffer buf;
unsigned char *uuid; unsigned char *uuid;
@ -1925,10 +1946,10 @@ char *qemudGenerateNetworkXML(struct qemud_server *server,
if (qemudBufferPrintf(&buf, "<network>\n") < 0) if (qemudBufferPrintf(&buf, "<network>\n") < 0)
goto no_memory; goto no_memory;
if (qemudBufferPrintf(&buf, " <name>%s</name>\n", network->def.name) < 0) if (qemudBufferPrintf(&buf, " <name>%s</name>\n", def->name) < 0)
goto no_memory; goto no_memory;
uuid = network->def.uuid; uuid = def->uuid;
if (qemudBufferPrintf(&buf, " <uuid>%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x</uuid>\n", if (qemudBufferPrintf(&buf, " <uuid>%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x</uuid>\n",
uuid[0], uuid[1], uuid[2], uuid[3], uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7], uuid[4], uuid[5], uuid[6], uuid[7],
@ -1937,28 +1958,28 @@ char *qemudGenerateNetworkXML(struct qemud_server *server,
goto no_memory; goto no_memory;
if (qemudBufferPrintf(&buf, " <bridge name='%s' stp='%s' delay='%d' />\n", if (qemudBufferPrintf(&buf, " <bridge name='%s' stp='%s' delay='%d' />\n",
network->def.bridge, def->bridge,
network->def.disableSTP ? "off" : "on", def->disableSTP ? "off" : "on",
network->def.forwardDelay) < 0) def->forwardDelay) < 0)
goto no_memory; goto no_memory;
if (network->def.ipAddress[0] || network->def.netmask[0]) { if (def->ipAddress[0] || def->netmask[0]) {
if (qemudBufferAdd(&buf, " <ip") < 0) if (qemudBufferAdd(&buf, " <ip") < 0)
goto no_memory; goto no_memory;
if (network->def.ipAddress[0] && if (def->ipAddress[0] &&
qemudBufferPrintf(&buf, " address='%s'", network->def.ipAddress) < 0) qemudBufferPrintf(&buf, " address='%s'", def->ipAddress) < 0)
goto no_memory; goto no_memory;
if (network->def.netmask[0] && if (def->netmask[0] &&
qemudBufferPrintf(&buf, " netmask='%s'", network->def.netmask) < 0) qemudBufferPrintf(&buf, " netmask='%s'", def->netmask) < 0)
goto no_memory; goto no_memory;
if (qemudBufferAdd(&buf, ">\n") < 0) if (qemudBufferAdd(&buf, ">\n") < 0)
goto no_memory; goto no_memory;
if (network->def.ranges) { if (def->ranges) {
struct qemud_dhcp_range_def *range = network->def.ranges; struct qemud_dhcp_range_def *range = def->ranges;
if (qemudBufferAdd(&buf, " <dhcp>\n") < 0) if (qemudBufferAdd(&buf, " <dhcp>\n") < 0)
goto no_memory; goto no_memory;
while (range) { while (range) {

View File

@ -44,13 +44,15 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
char *qemudGenerateXML(struct qemud_server *server, char *qemudGenerateXML(struct qemud_server *server,
struct qemud_vm *vm, int live); struct qemud_vm *vm, int live);
void qemudFreeNetworkDef(struct qemud_network_def *def);
void qemudFreeNetwork(struct qemud_network *network); void qemudFreeNetwork(struct qemud_network *network);
struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server, struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
const char *file, const char *file,
const char *doc, const char *doc,
int persist); int persist);
char *qemudGenerateNetworkXML(struct qemud_server *server, char *qemudGenerateNetworkXML(struct qemud_server *server,
struct qemud_network *network); struct qemud_network *network,
int live);
#endif #endif

View File

@ -568,7 +568,7 @@ static int qemudDispatchNetworkLookupByName(struct qemud_server *server, struct
} else { } else {
out->header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_NAME; out->header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_NAME;
out->header.dataSize = sizeof(out->data.networkLookupByNameReply); out->header.dataSize = sizeof(out->data.networkLookupByNameReply);
memcpy(out->data.networkLookupByNameReply.uuid, network->def.uuid, QEMUD_UUID_RAW_LEN); memcpy(out->data.networkLookupByNameReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN);
} }
return 0; return 0;
} }
@ -585,7 +585,7 @@ static int qemudDispatchNetworkLookupByUUID(struct qemud_server *server, struct
} else { } else {
out->header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_UUID; out->header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_UUID;
out->header.dataSize = sizeof(out->data.networkLookupByUUIDReply); out->header.dataSize = sizeof(out->data.networkLookupByUUIDReply);
strncpy(out->data.networkLookupByUUIDReply.name, network->def.name, QEMUD_MAX_NAME_LEN-1); strncpy(out->data.networkLookupByUUIDReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1);
out->data.networkLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; out->data.networkLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
} }
return 0; return 0;
@ -605,8 +605,8 @@ static int qemudDispatchNetworkCreate(struct qemud_server *server, struct qemud_
} else { } else {
out->header.type = QEMUD_PKT_NETWORK_CREATE; out->header.type = QEMUD_PKT_NETWORK_CREATE;
out->header.dataSize = sizeof(out->data.networkCreateReply); out->header.dataSize = sizeof(out->data.networkCreateReply);
memcpy(out->data.networkCreateReply.uuid, network->def.uuid, QEMUD_UUID_RAW_LEN); memcpy(out->data.networkCreateReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN);
strncpy(out->data.networkCreateReply.name, network->def.name, QEMUD_MAX_NAME_LEN-1); strncpy(out->data.networkCreateReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1);
out->data.networkCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; out->data.networkCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
} }
return 0; return 0;
@ -626,8 +626,8 @@ static int qemudDispatchNetworkDefine(struct qemud_server *server, struct qemud_
} else { } else {
out->header.type = QEMUD_PKT_NETWORK_DEFINE; out->header.type = QEMUD_PKT_NETWORK_DEFINE;
out->header.dataSize = sizeof(out->data.networkDefineReply); out->header.dataSize = sizeof(out->data.networkDefineReply);
memcpy(out->data.networkDefineReply.uuid, network->def.uuid, QEMUD_UUID_RAW_LEN); memcpy(out->data.networkDefineReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN);
strncpy(out->data.networkDefineReply.name, network->def.name, QEMUD_MAX_NAME_LEN-1); strncpy(out->data.networkDefineReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1);
out->data.networkDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0'; out->data.networkDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
} }
return 0; return 0;

View File

@ -537,14 +537,14 @@ struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
struct qemud_network *network = server->activenetworks; struct qemud_network *network = server->activenetworks;
while (network) { while (network) {
if (!memcmp(network->def.uuid, uuid, QEMUD_UUID_RAW_LEN)) if (!memcmp(network->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
return network; return network;
network = network->next; network = network->next;
} }
network = server->inactivenetworks; network = server->inactivenetworks;
while (network) { while (network) {
if (!memcmp(network->def.uuid, uuid, QEMUD_UUID_RAW_LEN)) if (!memcmp(network->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
return network; return network;
network = network->next; network = network->next;
} }
@ -557,14 +557,14 @@ struct qemud_network *qemudFindNetworkByName(const struct qemud_server *server,
struct qemud_network *network = server->activenetworks; struct qemud_network *network = server->activenetworks;
while (network) { while (network) {
if (!strcmp(network->def.name, name)) if (!strcmp(network->def->name, name))
return network; return network;
network = network->next; network = network->next;
} }
network = server->inactivenetworks; network = server->inactivenetworks;
while (network) { while (network) {
if (!strcmp(network->def.name, name)) if (!strcmp(network->def->name, name))
return network; return network;
network = network->next; network = network->next;
} }
@ -580,7 +580,7 @@ int qemudListNetworks(struct qemud_server *server, char *const*names, int nnames
struct qemud_network *network = server->activenetworks; struct qemud_network *network = server->activenetworks;
int got = 0; int got = 0;
while (network && got < nnames) { while (network && got < nnames) {
strncpy(names[got], network->def.name, QEMUD_MAX_NAME_LEN-1); strncpy(names[got], network->def->name, QEMUD_MAX_NAME_LEN-1);
names[got][QEMUD_MAX_NAME_LEN-1] = '\0'; names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
network = network->next; network = network->next;
got++; got++;
@ -596,7 +596,7 @@ int qemudListDefinedNetworks(struct qemud_server *server, char *const*names, int
struct qemud_network *network = server->inactivenetworks; struct qemud_network *network = server->inactivenetworks;
int got = 0; int got = 0;
while (network && got < nnames) { while (network && got < nnames) {
strncpy(names[got], network->def.name, QEMUD_MAX_NAME_LEN-1); strncpy(names[got], network->def->name, QEMUD_MAX_NAME_LEN-1);
names[got][QEMUD_MAX_NAME_LEN-1] = '\0'; names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
network = network->next; network = network->next;
got++; got++;
@ -611,30 +611,16 @@ struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char
return NULL; return NULL;
} }
if (qemudStartNetworkDaemon(server, network) < 0) { if (qemudNetworkStart(server, network) < 0) {
qemudFreeNetwork(network); qemudFreeNetwork(network);
return NULL; return NULL;
} }
network->next = server->activenetworks;
server->activenetworks = network;
server->nactivenetworks++;
return network; return network;
} }
struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) { struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) {
struct qemud_network *network; return qemudLoadNetworkConfigXML(server, NULL, xml, 1);
if (!(network = qemudLoadNetworkConfigXML(server, NULL, xml, 1))) {
return NULL;
}
network->next = server->inactivenetworks;
server->inactivenetworks = network;
server->ninactivenetworks++;
return network;
} }
int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) { int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) {
@ -646,7 +632,7 @@ int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid)
return -1; return -1;
} }
if (qemudDeleteConfig(server, network->configFile, network->def.name) < 0) if (qemudDeleteConfig(server, network->configFile, network->def->name) < 0)
return -1; return -1;
network->configFile[0] = '\0'; network->configFile[0] = '\0';
@ -718,7 +704,7 @@ int qemudNetworkDumpXML(struct qemud_server *server, const unsigned char *uuid,
return -1; return -1;
} }
networkxml = qemudGenerateNetworkXML(server, network); networkxml = qemudGenerateNetworkXML(server, network, 1);
if (!networkxml) if (!networkxml)
return -1; return -1;

View File

@ -238,7 +238,8 @@ struct qemud_network_def {
struct qemud_network { struct qemud_network {
char configFile[PATH_MAX]; char configFile[PATH_MAX];
struct qemud_network_def def; struct qemud_network_def *def; /* The current definition */
struct qemud_network_def *newDef; /* New definition to activate at shutdown */
char bridge[BR_IFNAME_MAXLEN]; char bridge[BR_IFNAME_MAXLEN];
int dnsmasqPid; int dnsmasqPid;

View File

@ -788,7 +788,7 @@ qemudBuildDnsmasqArgv(struct qemud_server *server,
2 + /* --conf-file "" */ 2 + /* --conf-file "" */
2 + /* --except-interface lo */ 2 + /* --except-interface lo */
2 + /* --listen-address 10.0.0.1 */ 2 + /* --listen-address 10.0.0.1 */
(2 * network->def.nranges) + /* --dhcp-range 10.0.0.2,10.0.0.254 */ (2 * network->def->nranges) + /* --dhcp-range 10.0.0.2,10.0.0.254 */
1; /* NULL */ 1; /* NULL */
if (!(*argv = malloc(len * sizeof(char *)))) if (!(*argv = malloc(len * sizeof(char *))))
@ -818,9 +818,9 @@ qemudBuildDnsmasqArgv(struct qemud_server *server,
APPEND_ARG(*argv, i++, "lo"); APPEND_ARG(*argv, i++, "lo");
APPEND_ARG(*argv, i++, "--listen-address"); APPEND_ARG(*argv, i++, "--listen-address");
APPEND_ARG(*argv, i++, network->def.ipAddress); APPEND_ARG(*argv, i++, network->def->ipAddress);
range = network->def.ranges; range = network->def->ranges;
while (range) { while (range) {
snprintf(buf, sizeof(buf), "%s,%s", snprintf(buf, sizeof(buf), "%s,%s",
range->start, range->end); range->start, range->end);
@ -853,7 +853,7 @@ dhcpStartDhcpDaemon(struct qemud_server *server,
char **argv; char **argv;
int ret, i; int ret, i;
if (network->def.ipAddress[0] == '\0') { if (network->def->ipAddress[0] == '\0') {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot start dhcp daemon without IP address for server"); "cannot start dhcp daemon without IP address for server");
return -1; return -1;
@ -1012,11 +1012,11 @@ int qemudStartNetworkDaemon(struct qemud_server *server,
return -1; return -1;
} }
if (network->def.bridge[0] == '\0' || if (network->def->bridge[0] == '\0' ||
strchr(network->def.bridge, '%')) { strchr(network->def->bridge, '%')) {
name = "vnet%d"; name = "vnet%d";
} else { } else {
name = network->def.bridge; name = network->def->bridge;
} }
if ((err = brAddBridge(server->brctl, name, network->bridge, sizeof(network->bridge)))) { if ((err = brAddBridge(server->brctl, name, network->bridge, sizeof(network->bridge)))) {
@ -1025,23 +1025,23 @@ int qemudStartNetworkDaemon(struct qemud_server *server,
return -1; return -1;
} }
if (network->def.ipAddress[0] && if (network->def->ipAddress[0] &&
(err = brSetInetAddress(server->brctl, network->bridge, network->def.ipAddress))) { (err = brSetInetAddress(server->brctl, network->bridge, network->def->ipAddress))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot set IP address on bridge '%s' to '%s' : %s\n", "cannot set IP address on bridge '%s' to '%s' : %s\n",
network->bridge, network->def.ipAddress, strerror(err)); network->bridge, network->def->ipAddress, strerror(err));
goto err_delbr; goto err_delbr;
} }
if (network->def.netmask[0] && if (network->def->netmask[0] &&
(err = brSetInetNetmask(server->brctl, network->bridge, network->def.netmask))) { (err = brSetInetNetmask(server->brctl, network->bridge, network->def->netmask))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot set netmask on bridge '%s' to '%s' : %s\n", "cannot set netmask on bridge '%s' to '%s' : %s\n",
network->bridge, network->def.netmask, strerror(err)); network->bridge, network->def->netmask, strerror(err));
goto err_delbr; goto err_delbr;
} }
if (network->def.ipAddress[0] && if (network->def->ipAddress[0] &&
(err = brSetInterfaceUp(server->brctl, network->bridge, 1))) { (err = brSetInterfaceUp(server->brctl, network->bridge, 1))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to bring the bridge '%s' up : %s\n", "failed to bring the bridge '%s' up : %s\n",
@ -1058,7 +1058,7 @@ int qemudStartNetworkDaemon(struct qemud_server *server,
goto err_delbr2; goto err_delbr2;
} }
if (network->def.ranges && if (network->def->ranges &&
dhcpStartDhcpDaemon(server, network) < 0) dhcpStartDhcpDaemon(server, network) < 0)
goto err_delbr2; goto err_delbr2;
@ -1070,7 +1070,7 @@ int qemudStartNetworkDaemon(struct qemud_server *server,
qemudRemoveIptablesRules(server, network); qemudRemoveIptablesRules(server, network);
err_delbr1: err_delbr1:
if (network->def.ipAddress[0] && if (network->def->ipAddress[0] &&
(err = brSetInterfaceUp(server->brctl, network->bridge, 0))) { (err = brSetInterfaceUp(server->brctl, network->bridge, 0))) {
printf("Damn! Failed to bring down bridge '%s' : %s\n", printf("Damn! Failed to bring down bridge '%s' : %s\n",
network->bridge, strerror(err)); network->bridge, strerror(err));
@ -1099,7 +1099,7 @@ int qemudShutdownNetworkDaemon(struct qemud_server *server,
qemudRemoveIptablesRules(server, network); qemudRemoveIptablesRules(server, network);
if (network->def.ipAddress[0] && if (network->def->ipAddress[0] &&
(err = brSetInterfaceUp(server->brctl, network->bridge, 0))) { (err = brSetInterfaceUp(server->brctl, network->bridge, 0))) {
printf("Damn! Failed to bring down bridge '%s' : %s\n", printf("Damn! Failed to bring down bridge '%s' : %s\n",
network->bridge, strerror(err)); network->bridge, strerror(err));
@ -1142,6 +1142,12 @@ int qemudShutdownNetworkDaemon(struct qemud_server *server,
network->dnsmasqPid = -1; network->dnsmasqPid = -1;
network->active = 0; network->active = 0;
if (network->newDef) {
qemudFreeNetworkDef(network->def);
network->def = network->newDef;
network->newDef = NULL;
}
return 0; return 0;
} }