mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-26 18:41:17 +00:00
Tue Feb 14 16:08:55 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: add support for connecting a qemu guest to a bridge using a tap device in order to connect it to a virtual network. * qemud/internal.h: add <interface type="network"> config and track tapfds so as to not close them on exec. * qemud/qemud.c: don't close tapfds on exec and disconnect the iface when the guest shuts down.
This commit is contained in:
parent
3fbd82faa0
commit
0c15bd8b87
124
ChangeLog
124
ChangeLog
@ -1,26 +1,128 @@
|
|||||||
Tue Feb 14 15:07:26 EST 2007 Mark McLoughlin <markmc@redhat.com>
|
Tue Feb 14 16:08:55 IST 2007 Mark McLoughlin <markmc@redhat.com>
|
||||||
|
|
||||||
|
* qemud/conf.c: add support for connecting a qemu
|
||||||
|
guest to a bridge using a tap device in order to
|
||||||
|
connect it to a virtual network.
|
||||||
|
|
||||||
|
* qemud/internal.h: add <interface type="network">
|
||||||
|
config and track tapfds so as to not close them
|
||||||
|
on exec.
|
||||||
|
|
||||||
|
* qemud/qemud.c: don't close tapfds on exec and
|
||||||
|
disconnect the iface when the guest shuts down.
|
||||||
|
|
||||||
|
Tue Feb 14 16:04:48 IST 2007 Mark McLoughlin <markmc@redhat.com>
|
||||||
|
|
||||||
|
* qemud/conf.c, qemud/internal.h: add dhcp config
|
||||||
|
|
||||||
|
* qemud/qemud.c: start dnsmasq to provide dns/dhcp
|
||||||
|
for virtual networks.
|
||||||
|
|
||||||
|
Tue Feb 14 16:02:23 IST 2007 Mark McLoughlin <markmc@redhat.com>
|
||||||
|
|
||||||
|
* configure.in: add --disable-bridge-params, check
|
||||||
|
for libsysfs and various kernel headers
|
||||||
|
|
||||||
|
* bridge.[ch]: add code for managing bridges
|
||||||
|
|
||||||
|
* qemud/Makefile.am: add bridge.[ch] and link against
|
||||||
|
libsysfs if enabled.
|
||||||
|
|
||||||
|
* qemud/conf.c: add support for bridge config.
|
||||||
|
|
||||||
|
* qemud/internal.h: add various bridging bits
|
||||||
|
|
||||||
|
* qemud/qemud.c: implement qemudStartNetworkDaemon()
|
||||||
|
and qemudShutdownNetworkDaemon().
|
||||||
|
|
||||||
|
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
|
* src/conf.h: fix merge error - remove the argc argument
|
||||||
from qemudBuildCommandLine()
|
from qemudBuildCommandLine()
|
||||||
|
|
||||||
Tue Feb 14 15:03:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
|
Tue Feb 14 15:03:22 IST 2007 Mark McLoughlin <markmc@redhat.com>
|
||||||
|
|
||||||
* src/virsh.c: Re-name some of the VSH_DOMBYFOO stuff
|
* src/virsh.c: Re-name some of the VSH_DOMBYFOO stuff
|
||||||
to VSH_BYFOO in order to re-use it for the network stuff.
|
to VSH_BYFOO in order to re-use it for the network stuff.
|
||||||
|
|
||||||
Tue Feb 14 14:58:35 EST 2007 Mark McLoughlin <markmc@redhat.com>
|
Tue Feb 14 14:58:35 IST 2007 Mark McLoughlin <markmc@redhat.com>
|
||||||
|
|
||||||
* src/hash.c, src/internal.h: Re-name virConnect->domains_mux
|
* src/hash.c, src/internal.h: Re-name virConnect->domains_mux
|
||||||
to virConnect->hashes_mux since it will also be used to
|
to virConnect->hashes_mux since it will also be used to
|
||||||
protect the networks hash.
|
protect the networks hash.
|
||||||
|
|
||||||
Tue Feb 14 14:57:52 EST 2007 Mark McLoughlin <markmc@redhat.com>
|
Tue Feb 14 14:57:52 IST 2007 Mark McLoughlin <markmc@redhat.com>
|
||||||
|
|
||||||
* qemud/conf.c: qemudSaveConfig() will always report a
|
* qemud/conf.c: qemudSaveConfig() will always report a
|
||||||
more specific error, so we should avoid overwriting
|
more specific error, so we should avoid overwriting
|
||||||
this error.
|
this error.
|
||||||
|
|
||||||
Tue Feb 14 14:54:25 EST 2007 Mark McLoughlin <markmc@redhat.com>
|
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.
|
||||||
@ -28,7 +130,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:
|
||||||
|
|
||||||
@ -38,25 +140,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
|
||||||
@ -65,7 +167,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
|
||||||
|
|
||||||
|
148
qemud/conf.c
148
qemud/conf.c
@ -366,6 +366,8 @@ static struct qemud_vm_net_def *qemudParseInterfaceXML(struct qemud_server *serv
|
|||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
xmlChar *macaddr = NULL;
|
xmlChar *macaddr = NULL;
|
||||||
xmlChar *type = NULL;
|
xmlChar *type = NULL;
|
||||||
|
xmlChar *network = NULL;
|
||||||
|
xmlChar *tapifname = NULL;
|
||||||
|
|
||||||
if (!net) {
|
if (!net) {
|
||||||
qemudReportError(server, VIR_ERR_NO_MEMORY, "net");
|
qemudReportError(server, VIR_ERR_NO_MEMORY, "net");
|
||||||
@ -386,6 +388,8 @@ static struct qemud_vm_net_def *qemudParseInterfaceXML(struct qemud_server *serv
|
|||||||
net->type = QEMUD_NET_CLIENT;
|
net->type = QEMUD_NET_CLIENT;
|
||||||
else if (xmlStrEqual(type, BAD_CAST "mcast"))
|
else if (xmlStrEqual(type, BAD_CAST "mcast"))
|
||||||
net->type = QEMUD_NET_MCAST;
|
net->type = QEMUD_NET_MCAST;
|
||||||
|
else if (xmlStrEqual(type, BAD_CAST "network"))
|
||||||
|
net->type = QEMUD_NET_NETWORK;
|
||||||
/*
|
/*
|
||||||
else if (xmlStrEqual(type, BAD_CAST "vde"))
|
else if (xmlStrEqual(type, BAD_CAST "vde"))
|
||||||
typ = QEMUD_NET_VDE;
|
typ = QEMUD_NET_VDE;
|
||||||
@ -402,6 +406,14 @@ static struct qemud_vm_net_def *qemudParseInterfaceXML(struct qemud_server *serv
|
|||||||
if ((macaddr == NULL) &&
|
if ((macaddr == NULL) &&
|
||||||
(xmlStrEqual(cur->name, BAD_CAST "mac"))) {
|
(xmlStrEqual(cur->name, BAD_CAST "mac"))) {
|
||||||
macaddr = xmlGetProp(cur, BAD_CAST "address");
|
macaddr = xmlGetProp(cur, BAD_CAST "address");
|
||||||
|
} else if ((network == NULL) &&
|
||||||
|
(net->type == QEMUD_NET_NETWORK) &&
|
||||||
|
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
||||||
|
network = xmlGetProp(cur, BAD_CAST "network");
|
||||||
|
} else if ((tapifname == NULL) &&
|
||||||
|
(net->type == QEMUD_NET_NETWORK) &&
|
||||||
|
xmlStrEqual(cur->name, BAD_CAST "tap")) {
|
||||||
|
tapifname = xmlGetProp(cur, BAD_CAST "ifname");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
@ -421,7 +433,47 @@ static struct qemud_vm_net_def *qemudParseInterfaceXML(struct qemud_server *serv
|
|||||||
xmlFree(macaddr);
|
xmlFree(macaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (net->type == QEMUD_NET_NETWORK) {
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (network == NULL) {
|
||||||
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"No <source> 'network' attribute specified with <interface type='network'/>");
|
||||||
|
goto error;
|
||||||
|
} else if ((len = xmlStrlen(network)) >= QEMUD_MAX_NAME_LEN) {
|
||||||
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Network name '%s' too long", network);
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
strncpy(net->dst.network.name, (char *)network, len);
|
||||||
|
net->dst.network.name[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (network)
|
||||||
|
xmlFree(network);
|
||||||
|
|
||||||
|
if (tapifname != NULL) {
|
||||||
|
if ((len == xmlStrlen(tapifname)) >= BR_IFNAME_MAXLEN) {
|
||||||
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"TAP interface name '%s' is too long", tapifname);
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
strncpy(net->dst.network.tapifname, (char *)tapifname, len);
|
||||||
|
net->dst.network.tapifname[len] = '\0';
|
||||||
|
}
|
||||||
|
xmlFree(tapifname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return net;
|
return net;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (network)
|
||||||
|
xmlFree(network);
|
||||||
|
if (tapifname)
|
||||||
|
xmlFree(tapifname);
|
||||||
|
free(net);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -770,6 +822,68 @@ static int qemudParseXML(struct qemud_server *server,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
qemudNetworkIfaceConnect(struct qemud_server *server,
|
||||||
|
struct qemud_vm *vm,
|
||||||
|
struct qemud_vm_net_def *net)
|
||||||
|
{
|
||||||
|
struct qemud_network *network;
|
||||||
|
const char *tapifname;
|
||||||
|
char tapfdstr[4+3+32+7];
|
||||||
|
char *retval = NULL;
|
||||||
|
int err;
|
||||||
|
int tapfd = -1;
|
||||||
|
int *tapfds;
|
||||||
|
|
||||||
|
if (!(network = qemudFindNetworkByName(server, net->dst.network.name))) {
|
||||||
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Network '%s' not found", net->dst.network.name);
|
||||||
|
goto error;
|
||||||
|
} else if (network->bridge[0] == '\0') {
|
||||||
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Network '%s' not active", net->dst.network.name);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (net->dst.network.tapifname[0] == '\0' ||
|
||||||
|
strchr(net->dst.network.tapifname, '%')) {
|
||||||
|
tapifname = "vnet%d";
|
||||||
|
} else {
|
||||||
|
tapifname = net->dst.network.tapifname;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((err = brAddTap(server->brctl, network->bridge, tapifname,
|
||||||
|
&net->dst.network.tapifname[0], BR_IFNAME_MAXLEN, &tapfd))) {
|
||||||
|
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Failed to add tap interface '%s' to bridge '%s' : %s",
|
||||||
|
tapifname, network->bridge, strerror(err));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(tapfdstr, sizeof(tapfdstr), "tap,fd=%d,script=", tapfd);
|
||||||
|
|
||||||
|
if (!(retval = strdup(tapfdstr)))
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (!(tapfds = realloc(vm->tapfds, sizeof(int) * (vm->ntapfds+2))))
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
vm->tapfds = tapfds;
|
||||||
|
vm->tapfds[vm->ntapfds++] = tapfd;
|
||||||
|
vm->tapfds[vm->ntapfds] = -1;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
no_memory:
|
||||||
|
qemudReportError(server, VIR_ERR_NO_MEMORY, "tapfds");
|
||||||
|
error:
|
||||||
|
if (retval)
|
||||||
|
free(retval);
|
||||||
|
if (tapfd != -1)
|
||||||
|
close(tapfd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructs a argv suitable for launching qemu with config defined
|
* Constructs a argv suitable for launching qemu with config defined
|
||||||
* for a given virtual machine.
|
* for a given virtual machine.
|
||||||
@ -921,9 +1035,15 @@ int qemudBuildCommandLine(struct qemud_server *server,
|
|||||||
goto no_memory;
|
goto no_memory;
|
||||||
if (!((*argv)[++n] = strdup("-net")))
|
if (!((*argv)[++n] = strdup("-net")))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
/* XXX don't hardcode user */
|
|
||||||
if (!((*argv)[++n] = strdup("user")))
|
if (net->type != QEMUD_NET_NETWORK) {
|
||||||
goto no_memory;
|
/* XXX don't hardcode user */
|
||||||
|
if (!((*argv)[++n] = strdup("user")))
|
||||||
|
goto no_memory;
|
||||||
|
} else {
|
||||||
|
if (!((*argv)[++n] = qemudNetworkIfaceConnect(server, vm, net)))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
net = net->next;
|
net = net->next;
|
||||||
}
|
}
|
||||||
@ -948,12 +1068,20 @@ int qemudBuildCommandLine(struct qemud_server *server,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
no_memory:
|
no_memory:
|
||||||
|
qemudReportError(server, VIR_ERR_NO_MEMORY, "argv");
|
||||||
|
error:
|
||||||
|
if (vm->tapfds) {
|
||||||
|
for (i = 0; vm->tapfds[i] != -1; i++)
|
||||||
|
close(vm->tapfds[i]);
|
||||||
|
free(vm->tapfds);
|
||||||
|
vm->tapfds = NULL;
|
||||||
|
vm->ntapfds = 0;
|
||||||
|
}
|
||||||
if (argv) {
|
if (argv) {
|
||||||
for (i = 0 ; i < n ; i++)
|
for (i = 0 ; i < n ; i++)
|
||||||
free((*argv)[i]);
|
free((*argv)[i]);
|
||||||
free(*argv);
|
free(*argv);
|
||||||
}
|
}
|
||||||
qemudReportError(server, VIR_ERR_NO_MEMORY, "argv");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1716,6 +1844,18 @@ char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm) {
|
|||||||
net->mac[3], net->mac[4], net->mac[5]) < 0)
|
net->mac[3], net->mac[4], net->mac[5]) < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
|
if (net->type == QEMUD_NET_NETWORK) {
|
||||||
|
if (qemudBufferPrintf(&buf, " <network name='%s", net->dst.network.name) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (net->dst.network.tapifname[0] != '\0' &&
|
||||||
|
qemudBufferPrintf(&buf, " tapifname='%s'", net->dst.network.tapifname) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (qemudBufferPrintf(&buf, "/>\n") < 0)
|
||||||
|
goto no_memory;
|
||||||
|
}
|
||||||
|
|
||||||
if (qemudBufferPrintf(&buf, " </interface>\n") < 0)
|
if (qemudBufferPrintf(&buf, " </interface>\n") < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ enum qemud_vm_net_type {
|
|||||||
QEMUD_NET_SERVER,
|
QEMUD_NET_SERVER,
|
||||||
QEMUD_NET_CLIENT,
|
QEMUD_NET_CLIENT,
|
||||||
QEMUD_NET_MCAST,
|
QEMUD_NET_MCAST,
|
||||||
|
QEMUD_NET_NETWORK,
|
||||||
/* QEMUD_NET_VDE*/
|
/* QEMUD_NET_VDE*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -123,6 +124,10 @@ struct qemud_vm_net_def {
|
|||||||
struct {
|
struct {
|
||||||
char vlan[PATH_MAX];
|
char vlan[PATH_MAX];
|
||||||
} vde;
|
} vde;
|
||||||
|
struct {
|
||||||
|
char name[QEMUD_MAX_NAME_LEN];
|
||||||
|
char tapifname[BR_IFNAME_MAXLEN];
|
||||||
|
} network;
|
||||||
} dst;
|
} dst;
|
||||||
|
|
||||||
struct qemud_vm_net_def *next;
|
struct qemud_vm_net_def *next;
|
||||||
@ -193,6 +198,9 @@ struct qemud_vm {
|
|||||||
int monitor;
|
int monitor;
|
||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
|
int *tapfds;
|
||||||
|
int ntapfds;
|
||||||
|
|
||||||
char configFile[PATH_MAX];
|
char configFile[PATH_MAX];
|
||||||
|
|
||||||
struct qemud_vm_def def;
|
struct qemud_vm_def def;
|
||||||
|
@ -332,9 +332,24 @@ static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemudLeaveFdOpen(int *openfds, int fd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!openfds)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; openfds[i] != -1; i++)
|
||||||
|
if (fd == openfds[i])
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qemudExec(struct qemud_server *server, char **argv,
|
qemudExec(struct qemud_server *server, char **argv,
|
||||||
int *retpid, int *outfd, int *errfd) {
|
int *retpid, int *outfd, int *errfd, int *openfds) {
|
||||||
int pid, null;
|
int pid, null;
|
||||||
int pipeout[2] = {-1,-1};
|
int pipeout[2] = {-1,-1};
|
||||||
int pipeerr[2] = {-1,-1};
|
int pipeerr[2] = {-1,-1};
|
||||||
@ -392,7 +407,8 @@ qemudExec(struct qemud_server *server, char **argv,
|
|||||||
for (i = 0; i < open_max; i++)
|
for (i = 0; i < open_max; i++)
|
||||||
if (i != STDOUT_FILENO &&
|
if (i != STDOUT_FILENO &&
|
||||||
i != STDERR_FILENO &&
|
i != STDERR_FILENO &&
|
||||||
i != STDIN_FILENO)
|
i != STDIN_FILENO &&
|
||||||
|
!qemudLeaveFdOpen(openfds, i))
|
||||||
close(i);
|
close(i);
|
||||||
|
|
||||||
execvp(argv[0], argv);
|
execvp(argv[0], argv);
|
||||||
@ -429,10 +445,20 @@ int qemudStartVMDaemon(struct qemud_server *server,
|
|||||||
if (qemudBuildCommandLine(server, vm, &argv) < 0)
|
if (qemudBuildCommandLine(server, vm, &argv) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (qemudExec(server, argv, &vm->pid, &vm->stdout, &vm->stderr) == 0) {
|
if (qemudExec(server, argv, &vm->pid, &vm->stdout, &vm->stderr, vm->tapfds) == 0) {
|
||||||
vm->def.id = server->nextvmid++;
|
vm->def.id = server->nextvmid++;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vm->tapfds) {
|
||||||
|
for (i = 0; vm->tapfds[i] != -1; i++) {
|
||||||
|
close(vm->tapfds[i]);
|
||||||
|
vm->tapfds[i] = -1;
|
||||||
|
}
|
||||||
|
free(vm->tapfds);
|
||||||
|
vm->tapfds = NULL;
|
||||||
|
vm->ntapfds = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0 ; argv[i] ; i++)
|
for (i = 0 ; argv[i] ; i++)
|
||||||
free(argv[i]);
|
free(argv[i]);
|
||||||
@ -632,8 +658,17 @@ static int qemudVMData(struct qemud_server *server ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
qemudNetworkIfaceDisconnect(struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||||
|
struct qemud_vm *vm ATTRIBUTE_UNUSED,
|
||||||
|
struct qemud_vm_net_def *net) {
|
||||||
|
/* FIXME: will be needed to remove iptables rules */
|
||||||
|
net = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
|
int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
|
||||||
struct qemud_vm *prev = NULL, *curr = server->activevms;
|
struct qemud_vm *prev = NULL, *curr = server->activevms;
|
||||||
|
struct qemud_vm_net_def *net;
|
||||||
|
|
||||||
/* Already cleaned-up */
|
/* Already cleaned-up */
|
||||||
if (vm->pid < 0)
|
if (vm->pid < 0)
|
||||||
@ -676,6 +711,13 @@ int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
|
|||||||
curr->monitor = -1;
|
curr->monitor = -1;
|
||||||
server->nvmfds -= 2;
|
server->nvmfds -= 2;
|
||||||
|
|
||||||
|
net = vm->def.nets;
|
||||||
|
while (net) {
|
||||||
|
if (net->type == QEMUD_NET_NETWORK)
|
||||||
|
qemudNetworkIfaceDisconnect(server, vm, net);
|
||||||
|
net = net->next;
|
||||||
|
}
|
||||||
|
|
||||||
if (waitpid(vm->pid, NULL, WNOHANG) != vm->pid) {
|
if (waitpid(vm->pid, NULL, WNOHANG) != vm->pid) {
|
||||||
kill(vm->pid, SIGKILL);
|
kill(vm->pid, SIGKILL);
|
||||||
if (waitpid(vm->pid, NULL, 0) != vm->pid) {
|
if (waitpid(vm->pid, NULL, 0) != vm->pid) {
|
||||||
@ -794,7 +836,7 @@ dhcpStartDhcpDaemon(struct qemud_server *server,
|
|||||||
if (qemudBuildDnsmasqArgv(server, network, &argv) < 0)
|
if (qemudBuildDnsmasqArgv(server, network, &argv) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = qemudExec(server, argv, &network->dnsmasqPid, NULL, NULL);
|
ret = qemudExec(server, argv, &network->dnsmasqPid, NULL, NULL, NULL);
|
||||||
|
|
||||||
for (i = 0; argv[i]; i++)
|
for (i = 0; argv[i]; i++)
|
||||||
free(argv[i]);
|
free(argv[i]);
|
||||||
|
Loading…
Reference in New Issue
Block a user