mirror of https://gitee.com/openkylin/libvirt.git
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:
parent
db3ad7cba7
commit
2439573270
101
ChangeLog
101
ChangeLog
|
@ -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
|
||||||
|
|
||||||
|
|
247
qemud/conf.c
247
qemud/conf.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
qemud/conf.h
19
qemud/conf.h
|
@ -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
|
||||||
|
|
||||||
|
|
173
qemud/driver.c
173
qemud/driver.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue