On Mon, 2007-01-15 at 20:06 +0000, Mark McLoughlin wrote: > * Since virConnect is supposed to be a connection to a specific > hypervisor, does it make sense to create networks (which should > be hypervisor agnostic) through virConnect? Okay, here's a suggestion - a virConnectPtr is a connection to a specific hypervisor *and* the virtual network supervisor on that same physical machine or user session. What I like about this is that if a domain's description mentions a virtual network, that name is scoped within the network supervisor associated with the hypervisor on which the guest is being created. Attached is a kind of a hacky patch to do something like that - if e.g. you connect to xend, you also get a "network-only" connection to qemud for managing networks. Cheers, Mark.
Virtual networks are not specific to QEMU, they just happen to be managed by qemud. When you are managing Xen guests, you should be able to use the virtual networks API using that same connection handle. This patch adds another "network-only" qemud driver which will be used with non-qemu drivers to provide access to the networks managed by qemud. It's a bit of a hack, and there are a few problems: 1) If the "real" driver connection fails (e.g. to xend), then the qemud network driver may still succeed giving the impression that the real driver connection did in fact succeed. We should only attempt to make the qemud network connection if the real connection succeeded. 2) For non-root, by default, virsh will create a read-only connection. This applies to the qemud network driver too, even though non-privileged users may be allowed to create networks. Perhaps this makes sense, though. With a Xen connection, non-root shouldn't be allowed to great guests *or* networks. They may only do that with a QEMU connection. 3) No account is taken here for remote connections. If you are managing remote Xen guests, you also want to connect to the remote qemud in order to manage the remote networks. Index: libvirt/src/driver.h =================================================================== --- libvirt.orig/src/driver.h +++ libvirt/src/driver.h @@ -23,7 +23,8 @@ typedef enum { VIR_DRV_TEST = 4, VIR_DRV_XEN_PROXY = 5, VIR_DRV_XEN_XM = 6, - VIR_DRV_QEMUD = 7 + VIR_DRV_QEMUD = 7, + VIR_DRV_NETWORK } virDrvNo; Index: libvirt/src/qemud_internal.c =================================================================== --- libvirt.orig/src/qemud_internal.c +++ libvirt/src/qemud_internal.c @@ -60,6 +60,9 @@ static int tlsinitialized = 0; int qemudOpen(virConnectPtr conn, const char *name, int flags); +int qemudNetworkOpen(virConnectPtr conn, + const char *name, + int flags); int qemudClose (virConnectPtr conn); int qemudGetVersion(virConnectPtr conn, unsigned long *hvVer); @@ -174,6 +177,61 @@ static virDriver qemudDriver = { qemudNetworkDumpXML, /* networkDumpXML */ }; +static virDriver qemudNetworkDriver = { + VIR_DRV_QEMUD, + "Network", + LIBVIR_VERSION_NUMBER, + NULL, /* init */ + qemudNetworkOpen, /* open */ + qemudClose, /* close */ + NULL, /* type */ + qemudGetVersion, /* version */ + NULL, /* nodeGetInfo */ + NULL, /* listDomains */ + NULL, /* numOfDomains */ + NULL, /* domainCreateLinux */ + NULL, /* domainLookupByID */ + NULL, /* domainLookupByUUID */ + NULL, /* domainLookupByName */ + NULL, /* domainSuspend */ + NULL, /* domainResume */ + NULL, /* domainShutdown */ + NULL, /* domainReboot */ + NULL, /* domainDestroy */ + NULL, /* domainGetOSType */ + NULL, /* domainGetMaxMemory */ + NULL, /* domainSetMaxMemory */ + NULL, /* domainSetMemory */ + NULL, /* domainGetInfo */ + NULL, /* domainSave */ + NULL, /* domainRestore */ + NULL, /* domainCoreDump */ + NULL, /* domainSetVcpus */ + NULL, /* domainPinVcpu */ + NULL, /* domainGetVcpus */ + NULL, /* domainDumpXML */ + NULL, /* listDomains */ + NULL, /* numOfDomains */ + NULL, /* domainCreate */ + NULL, /* domainDefineXML */ + NULL, /* domainUndefine */ + NULL, /* domainAttachDevice */ + NULL, /* domainDetachDevice */ + qemudNumOfNetworks, /* numOfNetworks */ + qemudListNetworks, /* listNetworks */ + qemudNumOfDefinedNetworks, /* numOfDefinedNetworks */ + qemudListDefinedNetworks, /* listDefinedNetworks */ + qemudNetworkLookupByID, /* networkLookupByID */ + qemudNetworkLookupByUUID, /* networkLookupByUUID */ + qemudNetworkLookupByName, /* networkLookupByName */ + qemudNetworkCreateXML , /* networkCreateXML */ + qemudNetworkDefineXML , /* networkDefineXML */ + qemudNetworkUndefine, /* networkUndefine */ + qemudNetworkCreate, /* networkCreate */ + qemudNetworkDestroy, /* networkDestroy */ + qemudNetworkDumpXML, /* networkDumpXML */ +}; + static void qemudError(virConnectPtr con, @@ -215,6 +273,7 @@ static void qemudPacketError(virConnectP void qemudRegister(void) { virRegisterDriver(&qemudDriver); + virRegisterDriver(&qemudNetworkDriver); } @@ -781,6 +840,36 @@ int qemudOpen(virConnectPtr conn, } +/* + * Open a connection to the QEMU manager in order + * to allow network management via a connection + * to other hypervisors. + */ +int qemudNetworkOpen(virConnectPtr conn, + const char *name, + int flags){ + xmlURIPtr uri = NULL; + int ret = -1; + + if (name) + uri = xmlParseURI(name); + + if (!name || !uri || !uri->scheme || strcmp(uri->scheme, "qemud") != 0) { + if (geteuid() == 0) { + ret = qemudOpen(conn, "qemud:///system", flags); + } else { + ret = qemudOpen(conn, "qemud:///session", flags); + } + } + + if (uri) + xmlFreeURI(uri); + + out: + return ret; +} + + int qemudClose (virConnectPtr conn) { if (conn->handle != -1) { if (conn->secure) {