Tue Feb 14 15:55:02 IST 2007 Mark McLoughlin <markmc@redhat.com>

* qemud/conf.[ch]: implement parsing and saving network
        configs.

        * qemud/driver.c: flesh out the stubs

        * qemud/internal.h: add networks list etc. to
        struct qemud_server

        * qemud/qemud.c: add qemudStartNetworkDaemon() and
        qemudShutdownNetworkDaemon() stubs.
This commit is contained in:
Mark McLoughlin 2007-02-14 15:58:06 +00:00
parent db3ad7cba7
commit 2439573270
6 changed files with 537 additions and 59 deletions

101
ChangeLog
View File

@ -1,4 +1,91 @@
Tue Feb 14 14:54:25 EST 2007 Mark McLoughlin <markmc@redhat.com Tue Feb 14 15:55:02 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.[ch]: implement parsing and saving network
configs.
* qemud/driver.c: flesh out the stubs
* qemud/internal.h: add networks list etc. to
struct qemud_server
* qemud/qemud.c: add qemudStartNetworkDaemon() and
qemudShutdownNetworkDaemon() stubs.
Tue Feb 14 15:52:34 EST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/protocol.h: add the protocol for virtual networks
* qemud/dispatch.c: implement the protocol
* qemud/driver.[ch]: add stubs for the driver
* qemud/internal.h: add struct qemud_network
* src/qemu_internal.c: add a virtual networks driver
Tue Feb 14 15:43:28 IST 2007 Mark McLoughlin <markmc@redhat.com>
* src/virsh.c: add the net-* commands.
Tue Feb 14 15:37:17 IST 2007 Mark McLoughlin <markmc@redhat.com>
Note: potential ABI break here, but people should
only really be using virError structs returned from
libvirt itself.
* include/libvirt/virterror.h: add virNetwork
to virError
* src/internal.h, src/virterror.c: add network param
to __virRaiseError()
* src/conf.c, src/hash.c, src/libvirt.c, src/proxy_internal.c,
src/qemu_internal.c, src/sexpr.c, src/test.c, src/xen_internal.c,
src/xend_internal.c, src/xm_internal.c, src/xml.c, src/xmlrpc.c,
src/xs_internal.c: update.
Tue Feb 14 15:33:05 IST 2007 Mark McLoughlin <markmc@redhat.com>
* include/libvirt/libvirt.h.in: add the networks APIs
* include/libvirt/virterror.h: add some error codes
* src/driver.h: add network driver vtable
* src/hash.c: add networks hash
* src/internal.h: add virNetwork
* src/libvirt.c: hook up the APIs to the network
driver
* src/libvirt_sym.version: add the new APIs
* src/virterror.c: handle the new error codes
Tue Feb 14 15:07:26 IST 2007 Mark McLoughlin <markmc@redhat.com>
* src/conf.h: fix merge error - remove the argc argument
from qemudBuildCommandLine()
Tue Feb 14 15:03:22 IST 2007 Mark McLoughlin <markmc@redhat.com>
* src/virsh.c: Re-name some of the VSH_DOMBYFOO stuff
to VSH_BYFOO in order to re-use it for the network stuff.
Tue Feb 14 14:58:35 IST 2007 Mark McLoughlin <markmc@redhat.com>
* src/hash.c, src/internal.h: Re-name virConnect->domains_mux
to virConnect->hashes_mux since it will also be used to
protect the networks hash.
Tue Feb 14 14:57:52 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: qemudSaveConfig() will always report a
more specific error, so we should avoid overwriting
this error.
Tue Feb 14 14:54:25 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/qemud.c: Re-factor out qemudExec() so that it can * qemud/qemud.c: Re-factor out qemudExec() so that it can
be used to launch dnsmasq. be used to launch dnsmasq.
@ -6,7 +93,7 @@ Tue Feb 14 14:54:25 EST 2007 Mark McLoughlin <markmc@redhat.com
* qemud/conf.c: don't return argc from qemudBuildCommandLine() * qemud/conf.c: don't return argc from qemudBuildCommandLine()
as exec() doesn't need it. as exec() doesn't need it.
Tue Feb 14 14:52:12 EST 2007 Mark McLoughlin <markmc@redhat.com Tue Feb 14 14:52:12 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: Re-factor bits of conf.c so that: * qemud/conf.c: Re-factor bits of conf.c so that:
@ -16,25 +103,25 @@ Tue Feb 14 14:52:12 EST 2007 Mark McLoughlin <markmc@redhat.com
- split qemudScanConfigDir() out so that qemudScanConfigs() - split qemudScanConfigDir() out so that qemudScanConfigs()
can scan multiple configDirs can scan multiple configDirs
Tue Feb 14 14:50:22 EST 2007 Mark McLoughlin <markmc@redhat.com Tue Feb 14 14:50:22 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: handle an unspecified MAC address, * qemud/conf.c: handle an unspecified MAC address,
fix the argv freeing code in qemudBuildCommandLine() fix the argv freeing code in qemudBuildCommandLine()
and fix copy and paste error in qemudGenerateXML() and fix copy and paste error in qemudGenerateXML()
Tue Feb 14 14:42:38 EST 2007 Mark McLoughlin <markmc@redhat.com Tue Feb 14 14:42:38 IST 2007 Mark McLoughlin <markmc@redhat.com>
* src/internal.h: add virConnect->qemud_fd so that * src/internal.h: add virConnect->qemud_fd so that
xen and qemu don't share the handle member. xen and qemu don't share the handle member.
* src/hash.c, src/qemu_internal.c: update * src/hash.c, src/qemu_internal.c: update
Tue Feb 14 14:40:52 EST 2007 Mark McLoughlin <markmc@redhat.com Tue Feb 14 14:40:52 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c, qemud/dispatch.c, qemud/driver.c, * qemud/conf.c, qemud/dispatch.c, qemud/driver.c,
qemud/qemud.c: include autoconf's config.h qemud/qemud.c: include autoconf's config.h
Tue Feb 14 14:39:18 EST 2007 Mark McLoughlin <markmc@redhat.com Tue Feb 14 14:39:18 IST 2007 Mark McLoughlin <markmc@redhat.com>
* conf.[ch]: rename from config.[ch] so we can use * conf.[ch]: rename from config.[ch] so we can use
autoconf's config.h autoconf's config.h
@ -43,7 +130,7 @@ Tue Feb 14 14:39:18 EST 2007 Mark McLoughlin <markmc@redhat.com
* driver.c, qemud.c: upd. * driver.c, qemud.c: upd.
Tue Feb 14 14:33:22 EST 2007 Mark McLoughlin <markmc@redhat.com Tue Feb 14 14:33:22 IST 2007 Mark McLoughlin <markmc@redhat.com>
* autogen.sh: run autoheader * autogen.sh: run autoheader

View File

@ -1086,8 +1086,6 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
} }
if (qemudSaveConfig(server, vm) < 0) { if (qemudSaveConfig(server, vm) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot save config file for guest");
qemudFreeVM(vm); qemudFreeVM(vm);
return NULL; return NULL;
} }
@ -1100,17 +1098,186 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
} }
void qemudFreeNetwork(struct qemud_network *network) {
free(network);
}
static int qemudSaveNetworkConfig(struct qemud_server *server,
struct qemud_network *network) {
char *xml;
int fd, ret = -1;
int towrite;
if (!(xml = qemudGenerateNetworkXML(server, network))) {
return -1;
}
if (qemudEnsureConfigDir(server, server->networkConfigDir) < 0) {
goto cleanup;
}
if ((fd = open(network->configFile,
O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR )) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot create config file %s", network->configFile);
goto cleanup;
}
towrite = strlen(xml);
if (write(fd, xml, towrite) != towrite) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot write config file %s", network->configFile);
goto cleanup;
}
if (close(fd) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot save config file %s", network->configFile);
goto cleanup;
}
ret = 0;
cleanup:
free(xml);
return ret;
}
static int qemudParseNetworkXML(struct qemud_server *server,
xmlDocPtr xml,
struct qemud_network *network) {
xmlNodePtr root = NULL;
xmlXPathContextPtr ctxt = NULL;
xmlXPathObjectPtr obj = NULL;
/* Prepare parser / xpath context */
root = xmlDocGetRootElement(xml);
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "network"))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "incorrect root element");
goto error;
}
ctxt = xmlXPathNewContext(xml);
if (ctxt == NULL) {
qemudReportError(server, VIR_ERR_NO_MEMORY, "xmlXPathContext");
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(server, VIR_ERR_NO_NAME, NULL);
goto error;
}
if (strlen((const char *)obj->stringval) >= (QEMUD_MAX_NAME_LEN-1)) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "network name length too long");
goto error;
}
strcpy(network->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)) {
/* XXX auto-generate a UUID */
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "missing uuid element");
goto error;
}
if (qemudParseUUID((const char *)obj->stringval, network->def.uuid) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "malformed uuid element");
goto error;
}
xmlXPathFreeObject(obj);
xmlXPathFreeContext(ctxt);
return 0;
error:
/* XXX free all the stuff in the qemud_network struct, or leave it upto
the caller ? */
if (obj)
xmlXPathFreeObject(obj);
if (ctxt)
xmlXPathFreeContext(ctxt);
return -1;
}
struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
const char *file,
const char *doc,
int save) {
struct qemud_network *network = NULL;
xmlDocPtr xml;
if (!(xml = xmlReadDoc(BAD_CAST doc, file ? file : "network.xml", NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
qemudReportError(server, VIR_ERR_XML_ERROR, NULL);
return NULL;
}
if (!(network = calloc(1, sizeof(struct qemud_network)))) {
qemudReportError(server, VIR_ERR_NO_MEMORY, "network");
return NULL;
}
if (qemudParseNetworkXML(server, xml, network) < 0) {
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) {
strncpy(network->configFile, file, PATH_MAX);
network->configFile[PATH_MAX-1] = '\0';
} else {
if (save) {
if (qemudMakeConfigPath(server->networkConfigDir, network->def.name, ".xml", network->configFile, PATH_MAX) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot construct config file path");
qemudFreeNetwork(network);
return NULL;
}
if (qemudSaveNetworkConfig(server, network) < 0) {
qemudFreeNetwork(network);
return NULL;
}
} else {
network->configFile[0] = '\0';
}
}
return network;
}
/* Load a guest from its persistent config file */ /* Load a guest from its persistent config file */
static void qemudLoadConfig(struct qemud_server *server, static void qemudLoadConfig(struct qemud_server *server,
const char *file) { const char *file,
int isGuest) {
FILE *fh; FILE *fh;
struct stat st; struct stat st;
struct qemud_vm *vm;
char xml[QEMUD_MAX_XML_LEN]; char xml[QEMUD_MAX_XML_LEN];
int ret; int ret;
if (!(fh = fopen(file, "r"))) { if (!(fh = fopen(file, "r"))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot open guest config file %s", file); qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot open config file %s", file);
return; return;
} }
@ -1120,7 +1287,7 @@ static void qemudLoadConfig(struct qemud_server *server,
} }
if (st.st_size >= QEMUD_MAX_XML_LEN) { if (st.st_size >= QEMUD_MAX_XML_LEN) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "guest config too large in file %s", file); qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "config too large in file %s", file);
goto cleanup; goto cleanup;
} }
@ -1130,11 +1297,21 @@ static void qemudLoadConfig(struct qemud_server *server,
} }
xml[st.st_size] = '\0'; xml[st.st_size] = '\0';
if (isGuest) {
struct qemud_vm *vm;
if ((vm = qemudLoadConfigXML(server, file, xml, 1))) { if ((vm = qemudLoadConfigXML(server, file, xml, 1))) {
vm->next = server->inactivevms; vm->next = server->inactivevms;
server->inactivevms = vm; server->inactivevms = vm;
server->ninactivevms++; server->ninactivevms++;
} }
} else {
struct qemud_network *network;
if ((network = qemudLoadNetworkConfigXML(server, file, xml, 1))) {
network->next = server->inactivenetworks;
server->inactivenetworks = network;
server->ninactivenetworks++;
}
}
cleanup: cleanup:
fclose(fh); fclose(fh);
@ -1143,7 +1320,8 @@ static void qemudLoadConfig(struct qemud_server *server,
static static
int qemudScanConfigDir(struct qemud_server *server, int qemudScanConfigDir(struct qemud_server *server,
const char *configDir) { const char *configDir,
int isGuest) {
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;
@ -1161,7 +1339,7 @@ int qemudScanConfigDir(struct qemud_server *server,
if (qemudMakeConfigPath(configDir, entry->d_name, NULL, file, PATH_MAX) < 0) if (qemudMakeConfigPath(configDir, entry->d_name, NULL, file, PATH_MAX) < 0)
continue; continue;
qemudLoadConfig(server, file); qemudLoadConfig(server, file, isGuest);
} }
closedir(dir); closedir(dir);
@ -1171,7 +1349,9 @@ int qemudScanConfigDir(struct qemud_server *server,
/* Scan for all guest and network config files */ /* Scan for all guest and network config files */
int qemudScanConfigs(struct qemud_server *server) { int qemudScanConfigs(struct qemud_server *server) {
return qemudScanConfigDir(server, server->configDir); if (qemudScanConfigDir(server, server->configDir, 0) < 0)
return -1;
return qemudScanConfigDir(server, server->networkConfigDir, 1);
} }
/* Simple grow-on-demand string buffer */ /* Simple grow-on-demand string buffer */
@ -1426,19 +1606,54 @@ char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm) {
} }
int qemudDeleteConfigXML(struct qemud_server *server, struct qemud_vm *vm) { char *qemudGenerateNetworkXML(struct qemud_server *server,
if (!vm->configFile[0]) { struct qemud_network *network) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "no config file for guest %s", vm->def.name); struct qemudBuffer buf;
unsigned char *uuid;
buf.len = QEMUD_MAX_XML_LEN;
buf.used = 0;
buf.data = malloc(buf.len);
if (qemudBufferPrintf(&buf, "<network>\n") < 0)
goto no_memory;
if (qemudBufferPrintf(&buf, " <name>%s</name>\n", network->def.name) < 0)
goto no_memory;
uuid = network->def.uuid;
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[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11],
uuid[12], uuid[13], uuid[14], uuid[15]) < 0)
goto no_memory;
if (qemudBufferAdd(&buf, "</network>\n") < 0)
goto no_memory;
return buf.data;
no_memory:
qemudReportError(server, VIR_ERR_NO_MEMORY, "xml");
free(buf.data);
return NULL;
}
int qemudDeleteConfig(struct qemud_server *server,
const char *configFile,
const char *name) {
if (!configFile[0]) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "no config file for %s", name);
return -1; return -1;
} }
if (unlink(vm->configFile) < 0) { if (unlink(configFile) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot remove config for guest %s", vm->def.name); qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot remove config for %s", name);
return -1; return -1;
} }
vm->configFile[0] = '\0';
return 0; return 0;
} }

View File

@ -28,21 +28,28 @@
int qemudBuildCommandLine(struct qemud_server *server, int qemudBuildCommandLine(struct qemud_server *server,
struct qemud_vm *vm, struct qemud_vm *vm,
char ***argv, char ***argv);
int *argc);
int qemudScanConfigs(struct qemud_server *server);
int qemudDeleteConfig(struct qemud_server *server,
const char *configFile,
const char *name);
void qemudFreeVM(struct qemud_vm *vm); void qemudFreeVM(struct qemud_vm *vm);
struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server, struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
const char *file, const char *file,
const char *doc, const char *doc,
int persist); int persist);
int qemudScanConfigs(struct qemud_server *server);
char *qemudGenerateXML(struct qemud_server *server, char *qemudGenerateXML(struct qemud_server *server,
struct qemud_vm *vm); struct qemud_vm *vm);
int qemudDeleteConfigXML(struct qemud_server *server, void qemudFreeNetwork(struct qemud_network *network);
struct qemud_vm *vm); struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
const char *file,
const char *doc,
int persist);
char *qemudGenerateNetworkXML(struct qemud_server *server,
struct qemud_network *network);
#endif #endif

View File

@ -522,9 +522,11 @@ int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid)
return -1; return -1;
} }
if (qemudDeleteConfigXML(server, vm) < 0) if (qemudDeleteConfig(server, vm->configFile, vm->def.name) < 0)
return -1; return -1;
vm->configFile[0] = '\0';
while (curr) { while (curr) {
if (curr == vm) { if (curr == vm) {
if (prev) { if (prev) {
@ -547,67 +549,198 @@ int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid)
struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server, struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
const unsigned char *uuid) { const unsigned char *uuid) {
server = NULL; uuid = NULL; struct qemud_network *network = server->activenetworks;
while (network) {
if (!memcmp(network->def.uuid, uuid, QEMUD_UUID_RAW_LEN))
return network;
network = network->next;
}
network = server->inactivenetworks;
while (network) {
if (!memcmp(network->def.uuid, uuid, QEMUD_UUID_RAW_LEN))
return network;
network = network->next;
}
return NULL; return NULL;
} }
struct qemud_network *qemudFindNetworkByName(const struct qemud_server *server, struct qemud_network *qemudFindNetworkByName(const struct qemud_server *server,
const char *name) { const char *name) {
server = NULL; name = NULL; struct qemud_network *network = server->activenetworks;
while (network) {
if (!strcmp(network->def.name, name))
return network;
network = network->next;
}
network = server->inactivenetworks;
while (network) {
if (!strcmp(network->def.name, name))
return network;
network = network->next;
}
return NULL; return NULL;
} }
int qemudNumNetworks(struct qemud_server *server) { int qemudNumNetworks(struct qemud_server *server) {
server = NULL; return server->nactivenetworks;
return 0;
} }
int qemudListNetworks(struct qemud_server *server, char *const*names, int nnames) { int qemudListNetworks(struct qemud_server *server, char *const*names, int nnames) {
server = NULL; names = NULL; nnames = 0; struct qemud_network *network = server->activenetworks;
return 0; int got = 0;
while (network && got < nnames) {
strncpy(names[got], network->def.name, QEMUD_MAX_NAME_LEN-1);
names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
network = network->next;
got++;
}
return got;
} }
int qemudNumDefinedNetworks(struct qemud_server *server) { int qemudNumDefinedNetworks(struct qemud_server *server) {
server = NULL; return server->ninactivenetworks;
return 0;
} }
int qemudListDefinedNetworks(struct qemud_server *server, char *const*names, int nnames) { int qemudListDefinedNetworks(struct qemud_server *server, char *const*names, int nnames) {
server = NULL; names = NULL; nnames = 0; struct qemud_network *network = server->inactivenetworks;
return 0; int got = 0;
while (network && got < nnames) {
strncpy(names[got], network->def.name, QEMUD_MAX_NAME_LEN-1);
names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
network = network->next;
got++;
}
return got;
} }
struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char *xml) { struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char *xml) {
server = NULL; xml = NULL; struct qemud_network *network;
if (!(network = qemudLoadNetworkConfigXML(server, NULL, xml, 0))) {
return NULL; return NULL;
} }
if (qemudStartNetworkDaemon(server, network) < 0) {
qemudFreeNetwork(network);
return NULL;
}
network->next = server->activenetworks;
server->activenetworks = network;
server->nactivenetworks++;
return network;
}
struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) { struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) {
server = NULL; xml = NULL; struct qemud_network *network;
if (!(network = qemudLoadNetworkConfigXML(server, NULL, xml, 1))) {
return NULL; 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) {
qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid"); struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
uuid = NULL; struct qemud_network *prev = NULL, *curr = server->inactivenetworks;
if (!network) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no network with matching uuid");
return -1; return -1;
} }
if (qemudDeleteConfig(server, network->configFile, network->def.name) < 0)
return -1;
network->configFile[0] = '\0';
while (curr) {
if (curr == network) {
if (prev) {
prev->next = curr->next;
} else {
server->inactivenetworks = curr->next;
}
server->ninactivenetworks--;
break;
}
prev = curr;
curr = curr->next;
}
qemudFreeNetwork(network);
return 0;
}
int qemudNetworkStart(struct qemud_server *server, struct qemud_network *network) { int qemudNetworkStart(struct qemud_server *server, struct qemud_network *network) {
server = NULL; network = NULL; struct qemud_network *prev = NULL, *curr = server->inactivenetworks;
if (qemudStartNetworkDaemon(server, network) < 0) {
return 1; return 1;
} }
while (curr) {
if (curr == network) {
if (prev)
prev->next = curr->next;
else
server->inactivenetworks = curr->next;
server->ninactivenetworks--;
break;
}
prev = curr;
curr = curr->next;
}
network->next = server->activenetworks;
server->activenetworks = network;
server->nactivenetworks++;
return 0;
}
int qemudNetworkDestroy(struct qemud_server *server, const unsigned char *uuid) { int qemudNetworkDestroy(struct qemud_server *server, const unsigned char *uuid) {
uuid = NULL; struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
if (!network) {
qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid"); qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
return -1; return -1;
} }
int qemudNetworkDumpXML(struct qemud_server *server, const unsigned char *uuid, char *xml, int xmllen) { if (qemudShutdownNetworkDaemon(server, network) < 0)
qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
uuid = NULL; xml = NULL; xmllen = 0;
return -1; return -1;
return 0;
}
int qemudNetworkDumpXML(struct qemud_server *server, const unsigned char *uuid, char *xml, int xmllen) {
struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
char *networkxml;
if (!network) {
qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
return -1;
}
networkxml = qemudGenerateNetworkXML(server, network);
if (!networkxml)
return -1;
strncpy(xml, networkxml, xmllen);
xml[xmllen-1] = '\0';
return 0;
} }
/* /*

View File

@ -207,6 +207,8 @@ struct qemud_network_def {
/* Virtual Network runtime state */ /* Virtual Network runtime state */
struct qemud_network { struct qemud_network {
char configFile[PATH_MAX];
struct qemud_network_def def; struct qemud_network_def def;
struct qemud_network *next; struct qemud_network *next;
}; };
@ -243,7 +245,12 @@ struct qemud_server {
int ninactivevms; int ninactivevms;
struct qemud_vm *inactivevms; struct qemud_vm *inactivevms;
int nextvmid; int nextvmid;
int nactivenetworks;
struct qemud_network *activenetworks;
int ninactivenetworks;
struct qemud_network *inactivenetworks;
char configDir[PATH_MAX]; char configDir[PATH_MAX];
char networkConfigDir[PATH_MAX];
char errorMessage[QEMUD_MAX_ERROR_LEN]; char errorMessage[QEMUD_MAX_ERROR_LEN];
int errorCode; int errorCode;
}; };
@ -254,6 +261,13 @@ int qemudStartVMDaemon(struct qemud_server *server,
int qemudShutdownVMDaemon(struct qemud_server *server, int qemudShutdownVMDaemon(struct qemud_server *server,
struct qemud_vm *vm); struct qemud_vm *vm);
int qemudStartNetworkDaemon(struct qemud_server *server,
struct qemud_network *network);
int qemudShutdownNetworkDaemon(struct qemud_server *server,
struct qemud_network *network);
#endif #endif
/* /*

View File

@ -251,6 +251,9 @@ static struct qemud_server *qemudInitialize(int sys) {
if (snprintf(server->configDir, sizeof(server->configDir), "%s/qemud", SYSCONF_DIR) >= (int)sizeof(server->configDir)) { if (snprintf(server->configDir, sizeof(server->configDir), "%s/qemud", SYSCONF_DIR) >= (int)sizeof(server->configDir)) {
goto cleanup; goto cleanup;
} }
if (snprintf(server->networkConfigDir, sizeof(server->networkConfigDir), "%s/qemud/networks", SYSCONF_DIR) >= (int)sizeof(server->networkConfigDir)) {
goto cleanup;
}
} else { } else {
struct passwd *pw; struct passwd *pw;
int uid; int uid;
@ -264,7 +267,12 @@ static struct qemud_server *qemudInitialize(int sys) {
if (snprintf(server->configDir, sizeof(server->configDir), "%s/.qemud", pw->pw_dir) >= (int)sizeof(server->configDir)) { if (snprintf(server->configDir, sizeof(server->configDir), "%s/.qemud", pw->pw_dir) >= (int)sizeof(server->configDir)) {
goto cleanup; goto cleanup;
} }
if (snprintf(server->networkConfigDir, sizeof(server->networkConfigDir), "%s/.qemud.d/networks", pw->pw_dir) >= (int)sizeof(server->networkConfigDir)) {
goto cleanup;
} }
}
if (qemudListen(server, sys) < 0) { if (qemudListen(server, sys) < 0) {
goto cleanup; goto cleanup;
@ -696,6 +704,20 @@ static int qemudDispatchVMFailure(struct qemud_server *server, struct qemud_vm *
} }
int qemudStartNetworkDaemon(struct qemud_server *server,
struct qemud_network *network) {
server = NULL; network = NULL;
return 0;
}
int qemudShutdownNetworkDaemon(struct qemud_server *server,
struct qemud_network *network) {
server = NULL; network = NULL;
return 0;
}
static int qemudDispatchPoll(struct qemud_server *server, struct pollfd *fds) { static int qemudDispatchPoll(struct qemud_server *server, struct pollfd *fds) {
struct qemud_socket *sock = server->sockets; struct qemud_socket *sock = server->sockets;
struct qemud_client *client = server->clients; struct qemud_client *client = server->clients;