Re: [libvirt] [PATCH v2 1/4] doc: Add capability.
Hello, Ping? At least this patch should qualify for 0.9.7. Currently it's only used by qemu, but currently there's no test case for qemu, which uses deviceboot, so it was never noticed that it's missing in the schema. On Tuesday 01 November 2011 10:27:47 Philipp Hahn wrote: > Allow /capabilities/guest/features/deviceboot. > > Signed-off-by: Philipp Hahn > --- > docs/schemas/capability.rng |5 + > 1 files changed, 5 insertions(+), 0 deletions(-) > > diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng > index 99b4a9a..0a63a1c 100644 > --- a/docs/schemas/capability.rng > +++ b/docs/schemas/capability.rng > @@ -302,6 +302,11 @@ > > > > + > + > + > + > + > > -- Philipp Hahn Open Source Software Engineer h...@univention.de Univention GmbHLinux for Your Businessfon: +49 421 22 232- 0 Mary-Somerville-Str.1 D-28359 Bremen fax: +49 421 22 232-99 http://www.univention.de/ signature.asc Description: This is a digitally signed message part. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 2/2] virnetsockettest: Use a temporary directory in /tmp
On Wed, Nov 02, 2011 at 04:28:54PM -0600, Eric Blake wrote: > On 11/02/2011 04:00 PM, Guido Günther wrote: > >>>+template = strdup("/tmp/libvirt_XX"); > >> > >>No need to malloc() the template. Just do: > >> > >>char template[] = "/tmp/libvirt_XX"; > > > >This was actually the first version I had but it didn't seem to match > >libvirt's style (in the non-const form and I didn't find it in HACKING) > > For something short-lived and cleanly scoped, stack allocation of > less than 4k bytes is fine; in fact it is even preferable (more > efficient, fewer failure points). Perhaps most existing uses of > mk[ds]temp in libvirt.git happened to malloc, but that's probably > because they are in situations where the final name must survive the > scope of the function creating the file. I don't know that HACKING > has to specifically speak to this, but I'll review any patch if you > want to tweak it to make that clear. I think it's fine as is, I was just wondering about only finding a single other usage. > > >so I went for the explicit strdup. New version attached. > > ACK to this version. Pushed now. Thanks, -- Guido -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] can't start domain with a corrupted disk attatched
Hi all, I came across below issue when testing: 1.make a volume and attach it to a domain A 2.unplug the vg from the host in order to emulating a volume failure 3.start domain A(failed) In step 3 can't start domainA . because can't find disk listed in xml when create the Domain. I'm not sure if it is reasonable. In common sense, we can still start our system even if we have a corrupt data disk .And also ,if in data center we carelessly attatch a corrupt volumn to all the guest, it will result in all guests fail to boot . I suggest to automatically detach a disk if it can't be found and just give out a warning.Please let me know your opinion about if it is a bug or a feature.Thanks. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v5 06/13] Add support for non-blocking calls in client RPC
When a client wants to send a keepalive message it needs to do so in a non-blocking way to avoid blocking its event loop. This patch adds dontBlock flag which says that the call should be processed without blocking. Such calls do not have a thread waiting for the result associated with them. This means, that sending such call fails if no thread is dispatching and writing to the socket would block. In case there is a thread waiting for its (normal) call to finish, sending non-blocking call just pushes it into the queue and lets the dispatching thread send it. The thread which has the buck tries to send all non-blocking calls in the queue in a best effort way---if sending them would block or there's an error on the socket, non-blocking calls are simply removed from the queue and discarded. In case a non-blocking call is partially sent but sending the rest of it would block, it is moved into client's unfinishedCall and left for future delivery. Every sending attempt first sends the rest of unfinishedCall and than continues with other queued calls. --- Notes: Version 5: - partially sent non-blocking calls now work even for SASL (or other transports that cache data internally) - fixed several other bugs in that area Version 4: - correctly handle partially sent non-blocking calls that would block Version 3: - no changes Version 2: - no changes src/rpc/virnetclient.c | 285 ++-- 1 files changed, 229 insertions(+), 56 deletions(-) diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index 2b5f67c..66d86e0 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -55,6 +55,8 @@ struct _virNetClientCall { virNetMessagePtr msg; bool expectReply; +bool dontBlock; +bool sending; virCond cond; @@ -86,6 +88,9 @@ struct _virNetClient { int wakeupSendFD; int wakeupReadFD; +/* Unfinished call that needs to be finished before any of the calls in + * the queue can be processed */ +virNetClientCallPtr unfinishedCall; /* List of threads currently waiting for dispatch */ virNetClientCallPtr waitDispatch; @@ -94,6 +99,11 @@ struct _virNetClient { }; +static int virNetClientSendInternal(virNetClientPtr client, +virNetMessagePtr msg, +bool expectReply, +bool dontBlock); + static void virNetClientLock(virNetClientPtr client) { virMutexLock(&client->lock); @@ -739,6 +749,7 @@ virNetClientIOWriteMessage(virNetClientPtr client, { ssize_t ret; +thecall->sending = true; ret = virNetSocketWrite(client->sock, thecall->msg->buffer + thecall->msg->bufferOffset, thecall->msg->bufferLength - thecall->msg->bufferOffset); @@ -754,6 +765,7 @@ virNetClientIOWriteMessage(virNetClientPtr client, return -1; } thecall->msg->bufferOffset = thecall->msg->bufferLength = 0; +thecall->sending = false; if (thecall->expectReply) thecall->mode = VIR_NET_CLIENT_MODE_WAIT_RX; else @@ -768,26 +780,45 @@ static ssize_t virNetClientIOHandleOutput(virNetClientPtr client) { virNetClientCallPtr thecall = client->waitDispatch; +ssize_t ret = -1; while (thecall && thecall->mode != VIR_NET_CLIENT_MODE_WAIT_TX) thecall = thecall->next; +/* If there is an unfinished non-blocking call, process it first */ +if (client->unfinishedCall) { +client->unfinishedCall->next = thecall; +thecall = client->unfinishedCall; +} + if (!thecall) -return -1; /* Shouldn't happen, but you never know... */ +goto cleanup; /* Shouldn't happen, but you never know... */ while (thecall) { -ssize_t ret = virNetClientIOWriteMessage(client, thecall); +ret = virNetClientIOWriteMessage(client, thecall); if (ret < 0) -return ret; +goto cleanup; + +if (thecall->mode == VIR_NET_CLIENT_MODE_WAIT_TX) { +/* Blocking write, go back to event loop */ +ret = 0; +goto cleanup; +} -if (thecall->mode == VIR_NET_CLIENT_MODE_WAIT_TX) -return 0; /* Blocking write, to back to event loop */ +if (thecall == client->unfinishedCall) +VIR_DEBUG("Nonblocking call %p finished", thecall); thecall = thecall->next; } -return 0; /* No more calls to send, all done */ +ret = 0; /* No more calls to send, all done */ + +cleanup: +if (client->unfinishedCall) +client->unfinishedCall->next = NULL; + +return ret; } static ssize_t @@ -870,6 +901,89 @@ virNetClientIOHandleInput(virNetClientPtr client) } +static void +virNetClientDiscardNonBlocking(virNetClientPtr client, + v
Re: [libvirt] [PATCH v2 2/4] xen: support bootable flag for Xen-PV.
On Mon, Oct 31, 2011 at 13:39:09 +0100, Philipp Hahn wrote: > Add support for adding the bootable S-Expr to disks. This is needd for > Xen-PV domains using GyPgrub as the boot loader. > > Signed-off-by: Philipp Hahn > --- > src/xen/xend_internal.c |4 ++-- > src/xenxs/xen_sxpr.c| 13 +++-- > src/xenxs/xen_sxpr.h|2 +- > 3 files changed, 14 insertions(+), 5 deletions(-) ACK Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] can't start domain with a corrupted disk attatched
On Thu, Nov 03, 2011 at 05:33:56PM +0800, lvroyce wrote: > Hi all, > >I came across below issue when testing: > >1.make a volume and attach it to a domain A >2.unplug the vg from the host in order to emulating a volume failure >3.start domain A(failed) > > In step 3 can't start domainA . because can't find disk listed > in xml when create the Domain. > > I'm not sure if it is reasonable. In common sense, we can still > start our system even if we have a corrupt data disk .And also ,if > in data center we carelessly attatch a corrupt volumn to all the > guest, it will result in all guests fail to boot . > > I suggest to automatically detach a disk if it can't be found > and just give out a warning.Please let me know your opinion about if > it is a bug or a feature.Thanks. You are not simulating a corrupt data disk in your example, you are simulating a completely missing disk. This is simply administrative error and thus is it perfectly reasonable for the guest to not start when its disk is missing. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/4] doc: Add capability.
On Tue, Nov 01, 2011 at 10:27:47 +0100, Philipp Hahn wrote: > Allow /capabilities/guest/features/deviceboot. > > Signed-off-by: Philipp Hahn > --- > docs/schemas/capability.rng |5 + > 1 files changed, 5 insertions(+), 0 deletions(-) ACK and I agree with this being 0.9.7 material. Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Start of freeze for libvirt-0.9.7 and availability of rc1
Thanks to everybody who provided feedback and patches on rc1, I have made an rc2 available at ftp://libvirt.org/libvirt/libvirt-0.9.7-rc2.tar.gz there is also the rpms rebuilds for Fedora 14. One think I noted while the rpm was building is the following warnings: CCLD libvirt_test.la *** Warning: Linking the shared library libvirt_test.la against the non-libtool *** objects probes.o is not portable! *** Warning: Linking the shared library libvirt.la against the non-libtool *** objects probes.o is not portable! CCLD libvirt-qemu.la I also get *** Warning: Linking the shared library libvirt.la against the non-libtool *** objects probes.o is not portable! when I build from the tree. I assume it's related to src/Makefile.am if WITH_DTRACE libvirt_la_BUILT_LIBADD += probes.o and maybe it expects some .lo instead, but I'm not sure how to tweak this correctly :) Anyway, please check that rc2 too. Eric do you think you will be able to fix the missing 'ptsname_r' in gnulib in time or should we make a small workaround for platforms lacking it for the release ? Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ dan...@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 3/4] xen: fix PyGrub device order using boot/@order
On Mon, Oct 31, 2011 at 13:39:09 +0100, Philipp Hahn wrote: > When PyGrub is used as the bootloader in Xen, it gets passed the first > bootable disk. Xend supports a "bootable"-flag for this, which was > previously unused. > In commit c2969ec7aec5c40519aadf422ab5c47a21938bff the bootable=1 flag > was used to re-order the disks when converting from SEXPR to XML, such > that on re-definition Xend would mark the first disk as bootable. > This got broken with commit c1a98d88255197a8446d08c0b1589861660e9064, > which reorders all disks according to their target-name, making it > impossible to change the boot order without changing the device names. > > When converting from Xen-sexpr to xml, Xens boolean bootable-flag is > converted to libvirts cardinal bootIndex, tracking the order of disks as > returned by Xend. This satisfies the requirement of bootIndex being > unique. > > When converting back to xen-sexpr, disks with an explicit bootIndex are > sorted ascending before all other disks and are marked as bootable. > > Explicitly mark the first disk as bootable for compatibility with Xends > default behaviour. > > Add capability "deviceboot" to Xen-PV-domains. This is not 100% correct, > since for example PyGrub only handles disk devices and not netboot. > > Signed-off-by: Philipp Hahn > --- > v2: explicitly sort disks by bootIndex > v2: Add deviceboot capability. > --- > src/xen/xen_hypervisor.c |7 +++ > src/xenxs/xen_sxpr.c | 39 ++- > 2 files changed, 37 insertions(+), 9 deletions(-) ACK Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Start of freeze for libvirt-0.9.7 and availability of rc1
On Thu, Nov 03, 2011 at 06:19:25PM +0800, Daniel Veillard wrote: > Thanks to everybody who provided feedback and patches on rc1, > I have made an rc2 available at >ftp://libvirt.org/libvirt/libvirt-0.9.7-rc2.tar.gz > there is also the rpms rebuilds for Fedora 14. > One think I noted while the rpm was building is the following warnings: > > CCLD libvirt_test.la > *** Warning: Linking the shared library libvirt_test.la against the > non-libtool > *** objects probes.o is not portable! > > *** Warning: Linking the shared library libvirt.la against the non-libtool > *** objects probes.o is not portable! > CCLD libvirt-qemu.la > > I also get > > *** Warning: Linking the shared library libvirt.la against the non-libtool > *** objects probes.o is not portable! > > when I build from the tree. I assume it's related to src/Makefile.am > > if WITH_DTRACE > libvirt_la_BUILT_LIBADD += probes.o > > and maybe it expects some .lo instead, but I'm not sure how to tweak > this correctly :) This is just libtool getting annoyed that it didn't create the .o file itself - it is created directly by dtrace, so there is no .lo file. There is no actual problem here. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/4] remote driver implementation
* src/remote/remote_driver.c: remote_driver data structure extension. * src/remote/remote_protocol.x: remote protocol extension. Signed-off-by: Hong Xiang --- src/remote/remote_driver.c |4 src/remote/remote_protocol.x | 31 ++- 2 files changed, 34 insertions(+), 1 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index ea7fb24..0272c91 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -4526,6 +4526,10 @@ static virDriver remote_driver = { .domainGetBlockJobInfo = remoteDomainGetBlockJobInfo, /* 0.9.4 */ .domainBlockJobSetSpeed = remoteDomainBlockJobSetSpeed, /* 0.9.4 */ .domainBlockPull = remoteDomainBlockPull, /* 0.9.4 */ +.domainManagedCoreDump = remoteDomainManagedCoreDump, /* 0.9.8 */ +.domainHasManagedCoreDump = remoteDomainHasManagedCoreDump, /* 0.9.8 */ +.domainManagedCoreDumpRemove = remoteDomainManagedCoreDumpRemove, /* 0.9.8 */ +.domainManagedCoreDumpDownload = remoteDomainManagedCoreDumpDownload, /* 0.9.8 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index a174af8..df485e6 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2267,6 +2267,30 @@ struct remote_domain_open_graphics_args { unsigned int flags; }; +struct remote_domain_managed_core_dump_args { +remote_nonnull_domain dom; +unsigned int flags; +}; + +struct remote_domain_has_managed_core_dump_args { +remote_nonnull_domain dom; +unsigned int flags; +}; + +struct remote_domain_has_managed_core_dump_ret { +int result; +}; + +struct remote_domain_managed_core_dump_remove_args { +remote_nonnull_domain dom; +unsigned int flags; +}; + +struct remote_domain_managed_core_dump_download_args { +remote_nonnull_domain dom; +unsigned int flags; +}; + /*- Protocol. -*/ /* Define the program number, protocol version and procedure numbers here. */ @@ -2562,7 +2586,12 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_SNAPSHOT_NUM_CHILDREN = 246, /* autogen autogen priority:high */ REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES = 247, /* autogen autogen priority:high */ REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE = 248, /* skipgen skipgen */ -REMOTE_PROC_DOMAIN_OPEN_GRAPHICS = 249 /* skipgen skipgen */ +REMOTE_PROC_DOMAIN_OPEN_GRAPHICS = 249, /* skipgen skipgen */ +REMOTE_PROC_DOMAIN_MANAGED_CORE_DUMP = 250, /* autogen autogen */ + +REMOTE_PROC_DOMAIN_HAS_MANAGED_CORE_DUMP = 251, /* autogen autogen */ +REMOTE_PROC_DOMAIN_MANAGED_CORE_DUMP_REMOVE = 252, /* autogen autogen */ +REMOTE_PROC_DOMAIN_MANAGED_CORE_DUMP_DOWNLOAD = 253 /* autogen autogen | readstream@1 */ /* * Notice how the entries are grouped in sets of 10 ? -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/4] new APIs/commands for managed core dump
This patch series added new APIs and virsh commands for 'managed core dump' functionality. Existing functionalities are intact. The 'managed core dump' functionality is in line with 'managed save', there can be at most 1 managed core dump per domain. In addition to the generate/check-existence/remove APIs/commands, there's also a download API/command to get the managed core dump of a domain for local use. Currently the new functionality has only been implemented for qemu hypervisor driver. Hong Xiang (4): new public APIs for managed core dump remote driver implementation qemu driver implementation New virsh commands for managed core dump include/libvirt/libvirt.h.in | 13 +++ src/driver.h | 18 src/libvirt.c| 187 +++ src/libvirt_public.syms |8 ++ src/qemu/qemu_conf.h |2 + src/qemu/qemu_driver.c | 176 - src/remote/remote_driver.c |4 + src/remote/remote_protocol.x | 31 ++- tools/virsh.c| 200 ++ 9 files changed, 636 insertions(+), 3 deletions(-) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/4] New virsh commands for managed core dump
New commands: . manageddump . manageddump-remove . manageddump-download * tools/virsh.c: new commands. Signed-off-by: Hong Xiang --- tools/virsh.c | 200 + 1 files changed, 200 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 5544a41..13f9e73 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -14006,6 +14006,201 @@ cleanup: return ret; } +/* + * "manageddump" command + */ +static const vshCmdInfo info_manageddump[] = { +{"help", N_("managed core dump a domain")}, +{"desc", N_("Managed core dump a domain.")}, +{NULL, NULL} +}; + +static const vshCmdOptDef opts_manageddump[] = { +{"live", VSH_OT_BOOL, 0, N_("perform a live core dump if supported")}, +{"crash", VSH_OT_BOOL, 0, N_("crash the domain after core dump")}, +{"bypass-cache", VSH_OT_BOOL, 0, N_("avoid file system cache when saving")}, +{"reset", VSH_OT_BOOL, 0, N_("reset the domain after core dump")}, +{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, +{NULL, 0, 0, NULL} +}; + +static bool +cmdManagedDump(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom; +const char *name; +bool ret = false; +unsigned int flags = 0; + +if (!vshConnectionUsability(ctl, ctl->conn)) +return false; + +if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) +return false; + +if (vshCommandOptBool (cmd, "live")) +flags |= VIR_DUMP_LIVE; +if (vshCommandOptBool (cmd, "crash")) +flags |= VIR_DUMP_CRASH; +if (vshCommandOptBool(cmd, "bypass-cache")) +flags |= VIR_DUMP_BYPASS_CACHE; +if (vshCommandOptBool(cmd, "reset")) +flags |= VIR_DUMP_RESET; + +if (virDomainManagedCoreDump(dom, flags) < 0) { +vshError(ctl, _("Failed to core dump domain %s"), name); +goto cleanup; +} + +vshPrint(ctl, _("Domain %s dumped\n"), name); +ret = true; + +cleanup: +virDomainFree(dom); +return ret; +} + +/* + * "manageddump-remove" command + */ +static const vshCmdInfo info_manageddumpremove[] = { +{"help", N_("Remove managed core dump of a domain")}, +{"desc", N_("Remove an existing managed core dump from a domain")}, +{NULL, NULL} +}; + +static const vshCmdOptDef opts_manageddumpremove[] = { +{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, +{NULL, 0, 0, NULL} +}; + +static bool +cmdManagedDumpRemove(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom; +const char *name; +bool ret = false; +int hascoredump; + +if (!vshConnectionUsability(ctl, ctl->conn)) +return false; + +if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) +return false; + +hascoredump = virDomainHasManagedCoreDump(dom, 0); +if (hascoredump < 0) { +vshError(ctl, "%s", _("Failed to check for domain managed core dump")); +goto cleanup; +} + +if (hascoredump) { +if (virDomainManagedCoreDumpRemove(dom, 0) < 0) { +vshError(ctl, _("Failed to remove managed core dump for domain %s"), + name); +goto cleanup; +} +else +vshPrint(ctl, _("Removed managed core dump for domain %s"), name); +} +else +vshPrint(ctl, _("Domain %s has no managed core dump; removal skipped"), + name); + +ret = true; + +cleanup: +virDomainFree(dom); +return ret; +} + +/* + * "manageddump-download" command + */ +static const vshCmdInfo info_manageddumpdownload[] = { +{"help", N_("Download managed core dump of a domain")}, +{"desc", N_("Download an existing managed core dump of a domain")}, +{NULL, NULL} +}; + +static const vshCmdOptDef opts_manageddumpdownload[] = { +{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, +{"file", VSH_OT_DATA, VSH_OFLAG_NONE, +N_("where to store the downloaded core dump")}, +{NULL, 0, 0, NULL} +}; + +static bool +cmdManagedDumpDownload(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom; +const char *name = NULL; +char *file = NULL; +int fd = -1; +virStreamPtr st = NULL; +int ret = false; +int hascoredump; + +if (!vshConnectionUsability(ctl, ctl->conn)) +return false; + +if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) +return false; + +hascoredump = virDomainHasManagedCoreDump(dom, 0); +if (hascoredump < 0) { +vshError(ctl, "%s", _("Failed to check for domain managed core dump")); +goto cleanup; +} else if(0 == hascoredump) { +vshPrint(ctl, _("Domain %s has no managed core dump"), name); +goto cleanup; +} + +if (vshCommandOptString(cmd, "file", (const char **) &file) < 0) { +vshError(ctl, "%s", _("file must not be empty")); +goto cleanup; +} + +st = virStreamNew(ctl->conn, 0); + +if(virDomainManagedCoreDumpDownload(dom, st, 0)) { +
[libvirt] [PATCH 3/4] qemu driver implementation
* src/qemu/qemu_conf.h: qemud_driver data structure extension. * src/qemu/qemu_driver.c: qemu driver API extension. Signed-off-by: Hong Xiang --- src/qemu/qemu_conf.h |2 + src/qemu/qemu_driver.c | 176 +++- 2 files changed, 176 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index ff5cf23..56e9972 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -138,6 +138,8 @@ struct qemud_driver { * of guests which will be automatically killed * when the virConnectPtr is closed*/ virHashTablePtr autodestroy; + +char *managedCoreDumpDir; }; typedef struct _qemuDomainCmdlineDef qemuDomainCmdlineDef; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5e49ff4..cccfc92 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -472,6 +472,9 @@ qemudStartup(int privileged) { if (virAsprintf(&qemu_driver->autoDumpPath, "%s/lib/libvirt/qemu/dump", LOCALSTATEDIR) == -1) goto out_of_memory; +if (virAsprintf(&qemu_driver->managedCoreDumpDir, +"%s/lib/libvirt/qemu/managed-core-dump", LOCALSTATEDIR) == -1) +goto out_of_memory; } else { uid_t uid = geteuid(); char *userdir = virGetUserDirectory(uid); @@ -502,6 +505,9 @@ qemudStartup(int privileged) { goto out_of_memory; if (virAsprintf(&qemu_driver->autoDumpPath, "%s/qemu/dump", base) == -1) goto out_of_memory; +if (virAsprintf(&qemu_driver->managedCoreDumpDir, +"%s/lib/libvirt/qemu/managed-core-dump", base) == -1) +goto out_of_memory; } if (virFileMakePath(qemu_driver->stateDir) < 0) { @@ -540,6 +546,13 @@ qemudStartup(int privileged) { qemu_driver->autoDumpPath, virStrerror(errno, ebuf, sizeof ebuf)); goto error; } +if (virFileMakePath(qemu_driver->managedCoreDumpDir) < 0) { +char ebuf[1024]; +VIR_ERROR(_("Failed to create managed-core-dump dir '%s': %s"), + qemu_driver->managedCoreDumpDir, + virStrerror(errno, ebuf, sizeof ebuf)); +goto error; +} /* Configuration paths are either ~/.libvirt/qemu/... (session) or * /etc/libvirt/qemu/... (system). @@ -606,6 +619,13 @@ qemudStartup(int privileged) { qemu_driver->snapshotDir, qemu_driver->user, qemu_driver->group); goto error; } +if (chown(qemu_driver->managedCoreDumpDir, qemu_driver->user, qemu_driver->group) < 0) { +virReportSystemError(errno, + _("unable to set ownership of '%s' to %d:%d"), + qemu_driver->managedCoreDumpDir, + qemu_driver->user, qemu_driver->group); +goto error; +} } /* If hugetlbfs is present, then we need to create a sub-directory within @@ -801,6 +821,7 @@ qemudShutdown(void) { VIR_FREE(qemu_driver->hugepage_path); VIR_FREE(qemu_driver->saveImageFormat); VIR_FREE(qemu_driver->dumpImageFormat); +VIR_FREE(qemu_driver->managedCoreDumpDir); virSecurityManagerFree(qemu_driver->securityManager); @@ -2843,6 +2864,19 @@ cleanup: return ret; } +static char * +qemuDomainManagedCoreDumpPath(struct qemud_driver *driver, virDomainObjPtr vm) { +char *ret; + +if (virAsprintf(&ret, "%s/%s.core", driver->managedCoreDumpDir, +vm->def->name) < 0) { +virReportOOMError(); +return(NULL); +} + +return(ret); +} + static int doCoreDump(struct qemud_driver *driver, virDomainObjPtr vm, @@ -2928,7 +2962,7 @@ getCompressionType(struct qemud_driver *driver) return compress; } -static int qemudDomainCoreDump(virDomainPtr dom, +static int qemudDomainCoreDumpInternal(virDomainPtr dom, const char *path, unsigned int flags) { @@ -2938,6 +2972,7 @@ static int qemudDomainCoreDump(virDomainPtr dom, int resume = 0, paused = 0; int ret = -1; virDomainEventPtr event = NULL; +char * real_path = NULL; virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH | VIR_DUMP_BYPASS_CACHE | VIR_DUMP_RESET, -1); @@ -2952,6 +2987,13 @@ static int qemudDomainCoreDump(virDomainPtr dom, _("no domain with matching uuid '%s'"), uuidstr); goto cleanup; } +if (NULL == path) { +real_path = qemuDomainManagedCoreDumpPath(driver, vm); +if(NULL == real_path) +goto cleanup; +} else { +real_path = (char *)path; +} if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm, QEMU_ASYNC_JOB_DUMP) < 0) @@ -2982,7 +3024,7 @@ static int qemudDomainCoreDump(virDomainPtr dom,
[libvirt] [PATCH 1/4] new public APIs for managed core dump
Added new public APIs for managed-core-dump. In line with managed-save functionality, there's at most one managed core-dump per domain. New APIs: . virDomainManagedCoreDump . virDomainHasManagedCoreDump . virDomainManagedCoreDumpRemove . virDomainManagedCoreDumpDownload * include/libvirt/libvirt.h.in: API declarations. * src/driver.h: driver data structure extension. * src/libvirt.c: API implementation. * src/libvirt_public.syms: public symbols. Signed-off-by: Hong Xiang --- include/libvirt/libvirt.h.in | 13 +++ src/driver.h | 18 src/libvirt.c| 187 ++ src/libvirt_public.syms |8 ++ 4 files changed, 226 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7181f62..2abbbf0 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1168,6 +1168,19 @@ int virDomainCoreDump (virDomainPtr domain, unsigned int flags); /* + * Managed domain core dump + */ +intvirDomainManagedCoreDump (virDomainPtr dom, + unsigned int flags); +intvirDomainHasManagedCoreDump(virDomainPtr dom, + unsigned int flags); +intvirDomainManagedCoreDumpRemove(virDomainPtr dom, + unsigned int flags); +intvirDomainManagedCoreDumpDownload(virDomainPtr dom, + virStreamPtr stream, + unsigned int flags); + +/* * Screenshot of current domain console */ char * virDomainScreenshot (virDomainPtr domain, diff --git a/src/driver.h b/src/driver.h index 4c14aaa..25f2edf 100644 --- a/src/driver.h +++ b/src/driver.h @@ -740,6 +740,20 @@ typedef int (*virDrvDomainBlockPull)(virDomainPtr dom, const char *path, unsigned long bandwidth, unsigned int flags); +typedef int +(*virDrvDomainManagedCoreDump)(virDomainPtr domain, unsigned int flags); + +typedef int +(*virDrvDomainHasManagedCoreDump)(virDomainPtr domain, unsigned int flags); + +typedef int +(*virDrvDomainManagedCoreDumpRemove)(virDomainPtr domain, + unsigned int flags); + +typedef int +(*virDrvDomainManagedCoreDumpDownload)(virDomainPtr domain, + virStreamPtr stream, + unsigned int flags); /** * _virDriver: @@ -899,6 +913,10 @@ struct _virDriver { virDrvDomainGetBlockJobInfo domainGetBlockJobInfo; virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed; virDrvDomainBlockPull domainBlockPull; +virDrvDomainManagedCoreDump domainManagedCoreDump; +virDrvDomainHasManagedCoreDump domainHasManagedCoreDump; +virDrvDomainManagedCoreDumpRemove domainManagedCoreDumpRemove; +virDrvDomainManagedCoreDumpDownload domainManagedCoreDumpDownload; }; typedef int diff --git a/src/libvirt.c b/src/libvirt.c index b0d1e01..b7b17f4 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -17083,3 +17083,190 @@ error: virDispatchError(dom->conn); return -1; } + +/** + * virDomainManagedCoreDump: + * @dom: pointer to the domain + * @flags: bitwise-OR of virDomainCoreDumpFlags + * + * This method differs from virDomainCoreDump only in that caller can not + * control where the generated core dump file is stored, it's determined by + * the driver. + * + * Returns 0 in case of success or -1 in case of failure + */ +int virDomainManagedCoreDump(virDomainPtr dom, unsigned int flags) +{ +virConnectPtr conn; + +VIR_DOMAIN_DEBUG(dom, "flags=%x", flags); + +virResetLastError(); + +if (!VIR_IS_CONNECTED_DOMAIN(dom)) { +virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); +virDispatchError(NULL); +return -1; +} + +conn = dom->conn; +if (conn->flags & VIR_CONNECT_RO) { +virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); +goto error; +} + +if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_LIVE)) { +virLibDomainError(VIR_ERR_INVALID_ARG, + _("crash and live flags are mutually exclusive")); +goto error; +} + +if (conn->driver->domainManagedCoreDump) { +int ret; + +ret = conn->driver->domainManagedCoreDump(dom, flags); +if (ret < 0) +goto error; +return ret; +} + +virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: +virDispatchError(conn); +return -1; +} + +/** + * virDomainHasManagedCoreDump: + * @dom: pointer to the domain + * @flags: optional flags currently unused + * + * Check if a domain has a managed core dump as created by + * virD
[libvirt] Re: can't start domain with a corrupted disk attatched
The 03/11/11, lvroyce wrote: > Hi all, > >I came across below issue when testing: > >1.make a volume and attach it to a domain A >2.unplug the vg from the host in order to emulating a volume failure >3.start domain A(failed) > > In step 3 can't start domainA . because can't find disk listed > in xml when create the Domain. > > I'm not sure if it is reasonable. In common sense, we can still > start our system even if we have a corrupt data disk .And also ,if > in data center we carelessly attatch a corrupt volumn to all the > guest, it will result in all guests fail to boot . > > I suggest to automatically detach a disk if it can't be found > and just give out a warning.Please let me know your opinion about if > it is a bug or a feature.Thanks. For most my use cases, I'd rather the guest not to start at all. The reason is that any attached disk is a mount point to somewhere. Not having the disk means that the dedicated space for this mount point is missing. Think about a guest (system with few disk space) doing a local mirror of a distribution (data with a lot of space). Starting the synchronisation script from cron without the disk for data attached means that the synchronisation will restart from scratch and that the system will fail by running out of disk space. Since attached disks are used in many different use cases, I think it would be a real gain to have an option per disk to tell if it's critical or not for the guest to start. -- Nicolas Sebrecht -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 3/4] xen: fix PyGrub device order using boot/@order
On Thu, Nov 03, 2011 at 11:21:24 +0100, Jiri Denemark wrote: > On Mon, Oct 31, 2011 at 13:39:09 +0100, Philipp Hahn wrote: > > When PyGrub is used as the bootloader in Xen, it gets passed the first > > bootable disk. Xend supports a "bootable"-flag for this, which was > > previously unused. > > In commit c2969ec7aec5c40519aadf422ab5c47a21938bff the bootable=1 flag > > was used to re-order the disks when converting from SEXPR to XML, such > > that on re-definition Xend would mark the first disk as bootable. > > This got broken with commit c1a98d88255197a8446d08c0b1589861660e9064, > > which reorders all disks according to their target-name, making it > > impossible to change the boot order without changing the device names. > > > > When converting from Xen-sexpr to xml, Xens boolean bootable-flag is > > converted to libvirts cardinal bootIndex, tracking the order of disks as > > returned by Xend. This satisfies the requirement of bootIndex being > > unique. > > > > When converting back to xen-sexpr, disks with an explicit bootIndex are > > sorted ascending before all other disks and are marked as bootable. > > > > Explicitly mark the first disk as bootable for compatibility with Xends > > default behaviour. > > > > Add capability "deviceboot" to Xen-PV-domains. This is not 100% correct, > > since for example PyGrub only handles disk devices and not netboot. > > > > Signed-off-by: Philipp Hahn > > --- > > v2: explicitly sort disks by bootIndex > > v2: Add deviceboot capability. > > --- > > src/xen/xen_hypervisor.c |7 +++ > > src/xenxs/xen_sxpr.c | 39 ++- > > 2 files changed, 37 insertions(+), 9 deletions(-) > > ACK Actually, I'm changing my mind. After reviewing patch 4/4, seeing you also added deviceboot for hvm guest capabilities and included it in both SEXPRs and XMLs for hvm domains, and realizing why you most likely did that, I think you should fix the code to be consistent with this. You do that because Xen hvm boots from the first disk in SEXPR and you want to preserve that order while doing SEXPR->XML->SEXPR, right? If so, I think you should add deviceboot feature for both hvm and pv guests, but hvm should forbid bootindex > 1 since it is not supported by xen (yet?). This way even users could influence what should be the first disk that Xen will boot from when creating a new domain. BTW, should xen{Parse,Format}XM be changed to do similar thing? That is reorder disk device according to bootindex when creating xm config files? Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Remove translations in socket test case
From: "Daniel P. Berrange" The test case errors should not be translated since they're only targetted at developers, not users. * tests/virnetsockettest.c: Remove error reporting with translations --- tests/virnetsockettest.c | 14 -- 1 files changed, 4 insertions(+), 10 deletions(-) Pushed as a build breaker fix (make syntax-check fails) diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c index a76e5cc..16713e8 100644 --- a/tests/virnetsockettest.c +++ b/tests/virnetsockettest.c @@ -207,14 +207,11 @@ static int testSocketUNIXAccept(const void *data ATTRIBUTE_UNUSED) tmpdir = mkdtemp(template); if (tmpdir == NULL) { -virReportSystemError(errno, "%s", - _("Failed to create temporary directory")); +VIR_WARN("Failed to create temporary directory"); goto cleanup; } -if (virAsprintf(&path, "%s/test.sock", tmpdir) < 0) { -virReportOOMError(); +if (virAsprintf(&path, "%s/test.sock", tmpdir) < 0) goto cleanup; -} if (virNetSocketNewListenUNIX(path, 0700, -1, getgid(), &lsock) < 0) goto cleanup; @@ -260,14 +257,11 @@ static int testSocketUNIXAddrs(const void *data ATTRIBUTE_UNUSED) tmpdir = mkdtemp(template); if (tmpdir == NULL) { -virReportSystemError(errno, "%s", - _("Failed to create temporary directory")); +VIR_WARN("Failed to create temporary directory"); goto cleanup; } -if (virAsprintf(&path, "%s/test.sock", tmpdir) < 0) { -virReportOOMError(); +if (virAsprintf(&path, "%s/test.sock", tmpdir) < 0) goto cleanup; -} if (virNetSocketNewListenUNIX(path, 0700, -1, getgid(), &lsock) < 0) goto cleanup; -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/7] Allow multiple consoles per virtual guest
On Tue, Nov 01, 2011 at 04:03:27PM -0600, Eric Blake wrote: > On 10/20/2011 08:47 AM, Daniel P. Berrange wrote: > >From: "Daniel P. Berrange" > > > >While Xen only has a single paravirt console, UML, and > >QEMU both support multiple paravirt consoles. The LXC > >driver can also be trivially made to support multiple > >consoles. This patch extends the XML to allow multiple > > elements in the XML. It also makes the UML > >and QEMU drivers support this config. > > > > See my earlier question about documenting this in docs/formatdomain.html.in. > > >+++ b/src/qemu/qemu_process.c > >@@ -1112,8 +1112,8 @@ qemuProcessFindCharDevicePTYsMonitor(virDomainObjPtr > >vm, > >paths, chardevfmt)< 0) > > return -1; > > > >-if (vm->def->console&& > >-qemuProcessLookupPTYs(&vm->def->console, 1, paths, chardevfmt)< 0) > >+if (qemuProcessLookupPTYs(vm->def->consoles, vm->def->nconsoles, > >+ paths, chardevfmt)< 0) > > Does qemuProcessLookupPTYs behave if vm->def->nconsoles is 0 (we > previously skipped calling it if there were no consoles, so you may > need to skip calling it here in the same situation). We already call qemuProcessLookupPTYs unconditionally for nserials, nparallels and nchannels & I've double checked its safe :-) > >+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args > >@@ -1,6 +1,7 @@ > > LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S > > -M \ > >-pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \ > >-unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -device \ > >+pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev \ > >+socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon \ > >+chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device \ > > Is this conversion from '-monitor' to '-device -mon' intentional? I > think its okay, but wonder if it should have been split into a > separate patch, since it has nothing to do with consoles. > > >+++ b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio.args > >@@ -1,6 +1,7 @@ > > LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S > > -M \ > >-pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \ > >-unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -device \ > >+pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev \ > >+socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon \ > >+chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device \ > > virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x3 -hda \ > > /dev/HostVG/QEMUGuest1 -chardev pty,id=charconsole0 -device virtconsole,\ > > chardev=charconsole0,id=console0 -usb -device > > virtio-balloon-pci,id=balloon0,\ > >diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c > >index a7ae925..2d158cf 100644 > >--- a/tests/qemuxml2argvtest.c > >+++ b/tests/qemuxml2argvtest.c > >@@ -471,11 +471,13 @@ mymain(void) > > DO_TEST("channel-guestfwd", false, > > QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); > > DO_TEST("channel-virtio", false, > >-QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); > >+QEMU_CAPS_DEVICE, QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG); > > Ah, I see - you altered the flags being passed, which is why the > .args files had to change. It makes sense that you need > QEMU_CAPS_CHARDEV for console-virtio-many to work, and you just made > the other tests consistent; still, my observation above about > splitting just this part of the tests change into a separate commit > might help. Yes, this test case was using a bogus combination of capabilities flags that would never exist in a real QEMU binary, so giving test output that was bogus and caused problems with many console support Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/7] Add support for multiple consoles in LXC
On Wed, Nov 02, 2011 at 02:46:50PM -0600, Eric Blake wrote: > On 10/20/2011 08:47 AM, Daniel P. Berrange wrote: > >From: "Daniel P. Berrange" > > > >Currently the LXC controller only supports setup of a single > >text console. This is wired up to the container init's stdio, > >as well as /dev/console and /dev/tty1. Extending support for > >multiple consoles, means wiring up additional PTYs to /dev/tty2, > >/dev/tty3, etc, etc. The LXC controller is passed multiple open > >file handles, one for each console requested. > > > >* src/lxc/lxc_container.c, src/lxc/lxc_container.h: Wire up > > all the /dev/ttyN links required to symlink to /dev/pts/NN > >* src/lxc/lxc_container.h: Open more container side /dev/pts/NN > > devices, and adapt event loop to handle I/O from all consoles > >* src/lxc/lxc_driver.c: Setup multiple host side PTYs > >--- > > src/lxc/lxc_container.c | 81 +++- > > src/lxc/lxc_container.h |3 +- > > src/lxc/lxc_controller.c | 160 > > +- > > src/lxc/lxc_driver.c | 62 +++--- > > 4 files changed, 191 insertions(+), 115 deletions(-) > > > > >@@ -891,10 +900,9 @@ cleanup: > > virMutexDestroy(&lock); > > signal(SIGCHLD, SIG_DFL); > > cleanup2: > >-VIR_FORCE_CLOSE(console.hostFd); > >-VIR_FORCE_CLOSE(console.contFd); > > VIR_FORCE_CLOSE(monitor.serverFd); > > VIR_FORCE_CLOSE(monitor.clientFd); > >+VIR_FREE(consoles); > > The old code was closing all fds; should the new code be iterating > over consoles and freeing both fd members per consoles[i]? These FDs were actually passed into this method, so I decided it was better practice for the caller to close them instead, since it opened them. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Remove translations in socket test case
On 11/03/2011 06:54 AM, Daniel P. Berrange wrote: From: "Daniel P. Berrange" The test case errors should not be translated since they're only targetted at developers, not users. * tests/virnetsockettest.c: Remove error reporting with translations --- tests/virnetsockettest.c | 14 -- 1 files changed, 4 insertions(+), 10 deletions(-) Pushed as a build breaker fix (make syntax-check fails) diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c index a76e5cc..16713e8 100644 --- a/tests/virnetsockettest.c +++ b/tests/virnetsockettest.c @@ -207,14 +207,11 @@ static int testSocketUNIXAccept(const void *data ATTRIBUTE_UNUSED) tmpdir = mkdtemp(template); if (tmpdir == NULL) { -virReportSystemError(errno, "%s", - _("Failed to create temporary directory")); +VIR_WARN("Failed to create temporary directory"); goto cleanup; } -if (virAsprintf(&path, "%s/test.sock", tmpdir)< 0) { -virReportOOMError(); +if (virAsprintf(&path, "%s/test.sock", tmpdir)< 0) goto cleanup; -} if (virNetSocketNewListenUNIX(path, 0700, -1, getgid(),&lsock)< 0) goto cleanup; @@ -260,14 +257,11 @@ static int testSocketUNIXAddrs(const void *data ATTRIBUTE_UNUSED) tmpdir = mkdtemp(template); if (tmpdir == NULL) { -virReportSystemError(errno, "%s", - _("Failed to create temporary directory")); +VIR_WARN("Failed to create temporary directory"); goto cleanup; } -if (virAsprintf(&path, "%s/test.sock", tmpdir)< 0) { -virReportOOMError(); +if (virAsprintf(&path, "%s/test.sock", tmpdir)< 0) goto cleanup; -} if (virNetSocketNewListenUNIX(path, 0700, -1, getgid(),&lsock)< 0) goto cleanup; ACK -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 01/10] enable cgroup cpuset by default
This prepares for subsequent patches which introduce dependence on cgroup cpuset. Enable cgroup cpuset by default so users don't have to modify configuration file before encountering a cpuset error. --- src/qemu/qemu.conf |5 +++-- src/qemu/qemu_conf.c |3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 4da5d5a..1c14d8f 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -157,18 +157,19 @@ # - 'devices' - use for device whitelisting # - 'memory' - use for memory tunables # - 'blkio' - use for block devices I/O tunables +# - 'cpuset' - use for CPUs and memory nodes # # NB, even if configured here, they won't be used unless # the administrator has mounted cgroups, e.g.: # # mkdir /dev/cgroup -# mount -t cgroup -o devices,cpu,memory,blkio none /dev/cgroup +# mount -t cgroup -o devices,cpu,memory,blkio,cpuset none /dev/cgroup # # They can be mounted anywhere, and different controllers # can be mounted in different locations. libvirt will detect # where they are located. # -# cgroup_controllers = [ "cpu", "devices", "memory", "blkio" ] +# cgroup_controllers = [ "cpu", "devices", "memory", "blkio", "cpuset" ] # This is the basic set of devices allowed / required by # all virtual machines. diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index d1bf075..854e8e7 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -306,7 +306,8 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, (1 << VIR_CGROUP_CONTROLLER_CPU) | (1 << VIR_CGROUP_CONTROLLER_DEVICES) | (1 << VIR_CGROUP_CONTROLLER_MEMORY) | -(1 << VIR_CGROUP_CONTROLLER_BLKIO); +(1 << VIR_CGROUP_CONTROLLER_BLKIO) | +(1 << VIR_CGROUP_CONTROLLER_CPUSET); } for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { if (driver->cgroupControllers & (1 << i)) { -- 1.7.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 03/10] use cpuset to manage numa
This patch deprecates libnuma and uses cpuset to manage numa. We can further add a `numatune' command to adjust numa parameters through cpuset. --- src/qemu/qemu_cgroup.c | 23 +++ 1 files changed, 23 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 2a10bd2..49307b2 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -365,6 +365,29 @@ int qemuSetupCgroup(struct qemud_driver *driver, } } +if (vm->def->numatune.memory.nodemask) { +if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { +char *mask = virDomainCpuSetFormat(vm->def->numatune.memory.nodemask, VIR_DOMAIN_CPUMASK_LEN); +if (!mask) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_("failed to convert memory nodemask")); +goto cleanup; +} + +rc = virCgroupSetCpusetMems(cgroup, mask); +if (rc != 0) { +virReportSystemError(-rc, + _("Unable to set cpuset.mems for domain %s"), + vm->def->name); +goto cleanup; +} +} else { +qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, +_("Unable to set numa for domain %s since cpuset cgroup is " + "not available on this host"), vm->def->name); +goto cleanup; +} +} done: virCgroupFree(&cgroup); return 0; -- 1.7.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 05/10] new numa parameters
This patch adds two parameters: strict and exclusive that we can get/set through cpuset. --- src/conf/domain_conf.c | 15 +++ src/conf/domain_conf.h |2 ++ 2 files changed, 17 insertions(+), 0 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0cf3bb7..02a144b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6802,6 +6802,10 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, VIR_FREE(nodes); /* Extract numatune if exists. */ + +def->numatune.strict = 0; +def->numatune.exclusive = 0; + if ((n = virXPathNodeSet("./numatune", ctxt, NULL)) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot extract numatune nodes")); @@ -6829,6 +6833,13 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, "%s", _("nodeset for NUMA memory tuning must be set")); goto error; } + +if (virXPathNode("./numatune/strict", ctxt)) { +def->numatune.strict = 1; +} +if (virXPathNode("./numatune/exclusive", ctxt)) { +def->numatune.exclusive = 1; +} } n = virXPathNodeSet("./features/*", ctxt, &nodes); @@ -10876,6 +10887,10 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAsprintf(buf, "\n", nodemask); VIR_FREE(nodemask); +if (def->numatune.strict) +virBufferAsprintf(buf, "\n"); +if (def->numatune.exclusive) +virBufferAsprintf(buf, "\n"); virBufferAddLit(buf, " \n"); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ca68437..f3dbece 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1355,6 +1355,8 @@ struct _virDomainNumatuneDef { char *nodemask; } memory; +int strict; +int exclusive; /* Future NUMA tuning related stuff should go here. */ }; -- 1.7.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 06/10] add new API virDomain{G, S}etNumaParameters
Set up the types for the numa functions and insert them into the virDriver structure definition. --- include/libvirt/libvirt.h.in | 23 +++ python/generator.py |2 ++ src/driver.h | 15 +++ src/libvirt_public.syms |6 ++ 4 files changed, 46 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7181f62..7802508 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1281,6 +1281,29 @@ typedef enum { } virDomainMemoryModFlags; +/* Manage numa parameters */ + +/** + * VIR_DOMAIN_NUMA_STRICT: + * + * Whether memory allocations are restricted to the numa nodes + */ +#define VIR_DOMAIN_NUMA_STRICT "numa_strict" + +/** + * VIR_DOMAIN_NUMA_EXCLUSIVE: + * + * Whether others can share the numa nodes + */ +#define VIR_DOMAIN_NUMA_EXCLUSIVE "numa_exclusive" + +int virDomainSetNumaParameters(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, unsigned int flags); +int virDomainGetNumaParameters(virDomainPtr domain, + virTypedParameterPtr params, + int *nparams, unsigned int flags); + /* * Dynamic control of domains */ diff --git a/python/generator.py b/python/generator.py index 71afdb7..5b09123 100755 --- a/python/generator.py +++ b/python/generator.py @@ -382,6 +382,8 @@ skip_impl = ( 'virDomainGetBlkioParameters', 'virDomainSetMemoryParameters', 'virDomainGetMemoryParameters', +'virDomainSetNumaParameters', +'virDomainGetNumaParameters', 'virDomainGetVcpus', 'virDomainPinVcpu', 'virDomainPinVcpuFlags', diff --git a/src/driver.h b/src/driver.h index 4c14aaa..76cf966 100644 --- a/src/driver.h +++ b/src/driver.h @@ -158,6 +158,19 @@ typedef int int *nparams, unsigned int flags); typedef int +(*virDrvDomainSetNumaParameters) +(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, + unsigned int flags); +typedef int +(*virDrvDomainGetNumaParameters) +(virDomainPtr domain, + virTypedParameterPtr params, + int *nparams, + unsigned int flags); + +typedef int (*virDrvDomainSetBlkioParameters) (virDomainPtr domain, virTypedParameterPtr params, @@ -787,6 +800,8 @@ struct _virDriver { virDrvDomainSetMemoryFlags domainSetMemoryFlags; virDrvDomainSetMemoryParameters domainSetMemoryParameters; virDrvDomainGetMemoryParameters domainGetMemoryParameters; +virDrvDomainSetNumaParameters domainSetNumaParameters; +virDrvDomainGetNumaParameters domainGetNumaParameters; virDrvDomainSetBlkioParameters domainSetBlkioParameters; virDrvDomainGetBlkioParameters domainGetBlkioParameters; virDrvDomainGetInfodomainGetInfo; diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index bcefb10..d830974 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -498,4 +498,10 @@ LIBVIRT_0.9.7 { virDomainSnapshotNumChildren; } LIBVIRT_0.9.5; +LIBVIRT_0.9.8 { +global: +virDomainGetNumaParameters; +virDomainSetNumaParameters; +} LIBVIRT_0.9.7; + # define new API here using predicted next version number -- 1.7.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC PATCH 00/10] use cpuset to manage numa
The goal of this series is to use cpuset to manage numa. Currently numa tuning is achieved by libnuma, the disadvantage is numa parameters can not be modified when the domain is running. By using cpuset, we can do this and more: - a new command, numatune, to get/set numa parameters - cpuset can migrate pages to new nodes if a domain's numa nodes is changed when running This is a draft for early reviews. Comments are welcome. TODO: - add --migrate option to numatune - docs for numatune Hu Tao (10): enable cgroup cpuset by default Add functions to set/get cpuset parameters use cpuset to manage numa remove dependence on libnuma new numa parameters add new API virDomain{G,S}etNumaParameters Implement main entries of virDomain{G,S}etNumaParameters Add virDomain{G,S}etNumaParameters support to the remote driver Implement virDomain{G,S}etNumaParameters for the qemu driver add new command numatune to virsh daemon/remote.c | 63 + include/libvirt/libvirt.h.in | 23 +++ python/generator.py |2 + src/conf/domain_conf.c | 35 ++--- src/conf/domain_conf.h |3 +- src/driver.h | 15 ++ src/libvirt.c| 106 +++ src/libvirt_private.syms |6 + src/libvirt_public.syms |6 + src/qemu/qemu.conf |5 +- src/qemu/qemu_cgroup.c | 37 + src/qemu/qemu_conf.c |3 +- src/qemu/qemu_driver.c | 307 ++ src/qemu/qemu_process.c | 111 --- src/remote/remote_driver.c | 50 +++ src/remote/remote_protocol.x | 25 - src/remote_protocol-structs | 16 +++ src/util/cgroup.c| 80 +++ src/util/cgroup.h|7 + tools/virsh.c| 187 + 20 files changed, 950 insertions(+), 137 deletions(-) -- 1.7.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 07/10] Implement main entries of virDomain{G, S}etNumaParameters
--- src/libvirt.c | 106 + 1 files changed, 106 insertions(+), 0 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index b0d1e01..af791bf 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -3712,6 +3712,112 @@ error: } /** + * virDomainSetNumaParameters: + * @domain: pointer to domain object + * @params: pointer to numa parameter objects + * @nparams: number of numa parameter (this value can be the same or + * less than the number of parameters supported) + * @flags: bitwise-OR of virDomainModificationImpact + * + * Change all or a subset of the numa tunables. + * This function may require privileged access to the hypervisor. + * + * Returns -1 in case of error, 0 in case of success. + */ +int virDomainSetNumaParameters(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, unsigned int flags) +{ +virConnectPtr conn; + +VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x", + params, nparams, flags); + +virResetLastError(); + +if (!VIR_IS_CONNECTED_DOMAIN(domain)) { +virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); +virDispatchError(NULL); +return -1; +} +if (domain->conn->flags & VIR_CONNECT_RO) { +virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); +goto error; +} +if ((nparams <= 0) || (params == NULL)) { +virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); +goto error; +} +conn = domain->conn; + +if (conn->driver->domainSetNumaParameters) { +int ret; +ret = conn->driver->domainSetNumaParameters (domain, params, nparams, flags); +if (ret < 0) +goto error; +return ret; +} + +virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: +virDispatchError(domain->conn); +return -1; +} + +/** + * virDomainGetNumaParameters: + * @domain: pointer to domain object + * @params: pointer to numa parameter object + * (return value, allocated by the caller) + * @nparams: pointer to number of numa parameters + * @flags: one of virDomainModificationImpact + * + * This function may require privileged access to the hypervisor. This function + * expects the caller to allocate the @params. + * + * Returns -1 in case of error, 0 in case of success. + */ + +int +virDomainGetNumaParameters(virDomainPtr domain, + virTypedParameterPtr params, + int *nparams, unsigned int flags) +{ +virConnectPtr conn; + +VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x", + params, (nparams) ? *nparams : -1, flags); + +virResetLastError(); + +if (!VIR_IS_CONNECTED_DOMAIN(domain)) { +virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); +virDispatchError(NULL); +return -1; +} +if ((nparams == NULL) || (*nparams < 0) || +(params == NULL && *nparams != 0)) { +virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); +goto error; +} +conn = domain->conn; + +if (conn->driver->domainGetNumaParameters) { +int ret; +ret = conn->driver->domainGetNumaParameters (domain, params, nparams, flags); +if (ret < 0) +goto error; +return ret; +} +virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: +virDispatchError(domain->conn); +return -1; +} + +/** * virDomainSetBlkioParameters: * @domain: pointer to domain object * @params: pointer to blkio parameter objects -- 1.7.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 10/10] add new command numatune to virsh
add new command numatune to virsh to get/set numa parameters --- tools/virsh.c | 187 + 1 files changed, 187 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 5544a41..e2c3cc2 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -4974,6 +4974,192 @@ cmdMemtune(vshControl * ctl, const vshCmd * cmd) } /* + * "numatune" command + */ +static const vshCmdInfo info_numatune[] = { +{"help", N_("Get or set numa parameters")}, +{"desc", N_("Get or set the current numa parameters for a guest" \ +" domain.\n" \ +"To get the numa parameters use following command: \n\n" \ +"virsh # numatune ")}, +{NULL, NULL} + +}; + +static const vshCmdOptDef opts_numatune[] = { +{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, +{"nodeset", VSH_OT_DATA, VSH_OFLAG_NONE, + N_("NUMA node to set")}, +{"strict", VSH_OT_INT, VSH_OFLAG_NONE, + N_("whether memory allocation should be restricted to the memory nodes ")}, +{"exclusive", VSH_OT_INT, VSH_OFLAG_NONE, + N_("XXX")}, +{"config", VSH_OT_BOOL, 0, N_("affect next boot")}, +{"live", VSH_OT_BOOL, 0, N_("affect running domain")}, +{"current", VSH_OT_BOOL, 0, N_("affect current domain")}, +{NULL, 0, 0, NULL} +}; + +static bool +cmdNumatune(vshControl * ctl, const vshCmd * cmd) +{ +virDomainPtr dom; +int rc = -1; +int nparams = 0; +unsigned int i = 0; +virTypedParameterPtr params = NULL, temp = NULL; +const char *nodeset = NULL; +unsigned long strict = 0; +unsigned long exclusive = 0; +bool strictParam = false; +bool exclusiveParam = false; +bool ret = false; +unsigned int flags = 0; +int current = vshCommandOptBool(cmd, "current"); +int config = vshCommandOptBool(cmd, "config"); +int live = vshCommandOptBool(cmd, "live"); + +if (current) { +if (live || config) { +vshError(ctl, "%s", _("--current must be specified exclusively")); +return false; +} +flags = VIR_DOMAIN_AFFECT_CURRENT; +} else { +if (config) +flags |= VIR_DOMAIN_AFFECT_CONFIG; +if (live) +flags |= VIR_DOMAIN_AFFECT_LIVE; +} + +if (!vshConnectionUsability(ctl, ctl->conn)) +return false; + +if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) +return false; + +if (vshCommandOptString(cmd, "nodeset", &nodeset) < 0) { +vshError(ctl, "%s", _("Unable to parse nodeset.")); +virDomainFree(dom); +return false; +} +rc = vshCommandOptUL(cmd, "strict", &strict); +if (rc > 0) { +nparams++; +strictParam = true; +} else if (rc < 0) { +vshError(ctl, "%s", _("Unable to parse parameter --strict.")); +virDomainFree(dom); +return false; +} + +rc = vshCommandOptUL(cmd, "exclusive", &exclusive); +if (rc > 0) { +nparams++; +exclusiveParam = true; +} else if (rc < 0) { +vshError(ctl, "%s", _("Unable to parse parameter --exclusive.")); +virDomainFree(dom); +return false; +} + +if (!nodeset) { +/* get nodeset information */ +} + +if (nparams == 0) { +/* get the number of numa parameters */ +if (virDomainGetNumaParameters(dom, NULL, &nparams, flags) != 0) { +vshError(ctl, "%s", + _("Unable to get number of memory parameters")); +goto cleanup; +} + +if (nparams == 0) { +/* nothing to output */ +ret = true; +goto cleanup; +} + +/* now go get all the numa parameters */ +params = vshCalloc(ctl, nparams, sizeof(*params)); +if (virDomainGetNumaParameters(dom, params, &nparams, flags) != 0) { +vshError(ctl, "%s", _("Unable to get numa parameters")); +goto cleanup; +} + +for (i = 0; i < nparams; i++) { +switch (params[i].type) { +case VIR_TYPED_PARAM_INT: +vshPrint(ctl, "%-15s: %d\n", params[i].field, + params[i].value.i); +break; +case VIR_TYPED_PARAM_UINT: +vshPrint(ctl, "%-15s: %u\n", params[i].field, + params[i].value.ui); +break; +case VIR_TYPED_PARAM_LLONG: +vshPrint(ctl, "%-15s: %lld\n", params[i].field, + params[i].value.l); +break; +case VIR_TYPED_PARAM_ULLONG: +vshPrint(ctl, "%-15s: %llu\n", params[i].field, + params[i].value.ul); +break; +case VIR_TYPED_PARAM_DOUBLE: +vshPrint(ctl, "%-15s: %f\n", params[i].field, +
[libvirt] [PATCH 08/10] Add virDomain{G, S}etNumaParameters support to the remote driver
--- daemon/remote.c | 63 ++ src/remote/remote_driver.c | 50 + src/remote/remote_protocol.x | 25 - src/remote_protocol-structs | 16 ++ 4 files changed, 153 insertions(+), 1 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index bd0c3e3..de6bbc8 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1591,6 +1591,69 @@ cleanup: } static int +remoteDispatchDomainGetNumaParameters(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_get_numa_parameters_args *args, + remote_domain_get_numa_parameters_ret *ret) +{ +virDomainPtr dom = NULL; +virTypedParameterPtr params = NULL; +int nparams = args->nparams; +unsigned int flags; +int rv = -1; +struct daemonClientPrivate *priv = +virNetServerClientGetPrivateData(client); + +if (!priv->conn) { +virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); +goto cleanup; +} + +flags = args->flags; + +if (nparams > REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX) { +virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large")); +goto cleanup; +} +if (VIR_ALLOC_N(params, nparams) < 0) { +virReportOOMError(); +goto cleanup; +} + +if (!(dom = get_nonnull_domain(priv->conn, args->dom))) +goto cleanup; + +if (virDomainGetNumaParameters(dom, params, &nparams, flags) < 0) +goto cleanup; + +/* In this case, we need to send back the number of parameters + * supported + */ +if (args->nparams == 0) { +ret->nparams = nparams; +goto success; +} + +if (remoteSerializeTypedParameters(params, nparams, + &ret->params.params_val, + &ret->params.params_len) < 0) +goto cleanup; + +success: +rv = 0; + +cleanup: +if (rv < 0) +virNetMessageSaveError(rerr); +if (dom) +virDomainFree(dom); +VIR_FREE(params); +return rv; +} + +static int remoteDispatchDomainGetBlkioParameters(virNetServerPtr server ATTRIBUTE_UNUSED, virNetServerClientPtr client ATTRIBUTE_UNUSED, virNetMessagePtr msg ATTRIBUTE_UNUSED, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index ea7fb24..29a1d49 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -1490,6 +1490,54 @@ done: } static int +remoteDomainGetNumaParameters (virDomainPtr domain, + virTypedParameterPtr params, int *nparams, + unsigned int flags) +{ +int rv = -1; +remote_domain_get_numa_parameters_args args; +remote_domain_get_numa_parameters_ret ret; +struct private_data *priv = domain->conn->privateData; + +remoteDriverLock(priv); + +make_nonnull_domain (&args.dom, domain); +args.nparams = *nparams; +args.flags = flags; + +memset (&ret, 0, sizeof ret); +if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_NUMA_PARAMETERS, + (xdrproc_t) xdr_remote_domain_get_numa_parameters_args, (char *) &args, + (xdrproc_t) xdr_remote_domain_get_numa_parameters_ret, (char *) &ret) == -1) +goto done; + +/* Handle the case when the caller does not know the number of parameters + * and is asking for the number of parameters supported + */ +if (*nparams == 0) { +*nparams = ret.nparams; +rv = 0; +goto cleanup; +} + +if (remoteDeserializeTypedParameters(ret.params.params_val, + ret.params.params_len, + REMOTE_DOMAIN_NUMA_PARAMETERS_MAX, + params, + nparams) < 0) +goto cleanup; + +rv = 0; + +cleanup: +xdr_free ((xdrproc_t) xdr_remote_domain_get_numa_parameters_ret, + (char *) &ret); +done: +remoteDriverUnlock(priv); +return rv; +} + +static int remoteDomainGetBlkioParameters (virDomainPtr domain, virTypedParameterPtr params, int *nparams, unsigned int flags) @@ -4526,6 +4574,8 @@ static virDriver remote_driver = { .domainGetBlockJobInfo = remoteDomainGetBlockJobInfo, /* 0.9.4 */ .domainBlockJobSetSpeed = remoteDomainBlockJobSetSpeed, /* 0.9.4 */ .domainBlockPull = remoteDomainBlockPull, /* 0.9.4 */ +.domainSetNumaParameters = remoteDomainSetNumaParameters, /* 0.9.8 */
[libvirt] [PATCH 02/10] Add functions to set/get cpuset parameters
--- src/libvirt_private.syms |6 +++ src/util/cgroup.c| 80 ++ src/util/cgroup.h|7 3 files changed, 93 insertions(+), 0 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6a1562e..64da63d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -78,6 +78,9 @@ virCgroupGetCpuShares; virCgroupGetCpuCfsPeriod; virCgroupGetCpuCfsQuota; virCgroupGetCpuacctUsage; +virCgroupGetCpusetHardwall; +virCgroupGetCpusetMemExclusive; +virCgroupGetCpusetMems; virCgroupGetFreezerState; virCgroupGetMemoryHardLimit; virCgroupGetMemorySoftLimit; @@ -93,6 +96,9 @@ virCgroupSetBlkioWeight; virCgroupSetCpuShares; virCgroupSetCpuCfsPeriod; virCgroupSetCpuCfsQuota; +virCgroupSetCpusetHardwall; +virCgroupSetCpusetMemExclusive; +virCgroupSetCpusetMems; virCgroupSetFreezerState; virCgroupSetMemory; virCgroupSetMemoryHardLimit; diff --git a/src/util/cgroup.c b/src/util/cgroup.c index c8d1f33..7b01a1c 100644 --- a/src/util/cgroup.c +++ b/src/util/cgroup.c @@ -1154,6 +1154,86 @@ int virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) } /** + * virCgroupSetCpusetMems: + * + * @group: The cgroup to set cpuset.mems for + * @mems: the numa nodes to set + * + * Returns: 0 on success + */ +int virCgroupSetCpusetMems(virCgroupPtr group, const char *mems) +{ +return virCgroupSetValueStr(group, +VIR_CGROUP_CONTROLLER_CPUSET, +"cpuset.mems", +mems); +} + +/** + * virCgroupGetCpusetMems: + * + * @group: The cgroup to get cpuset.mems for + * @mems: the numa nodes to get + * + * Returns: 0 on success + */ +int virCgroupGetCpusetMems(virCgroupPtr group, char **mems) +{ +return virCgroupGetValueStr(group, +VIR_CGROUP_CONTROLLER_CPUSET, +"cpuset.mems", +mems); +} + +/** + * virCgroupSetCpusetHardwall: + * + * @group: The cgroup to set cpuset.mems for + * @hardwall: the hardwall to set + * + * Returns: 0 on success + */ +int virCgroupSetCpusetHardwall(virCgroupPtr group, unsigned long long hardwall) +{ +return virCgroupSetValueU64(group, +VIR_CGROUP_CONTROLLER_CPUSET, +"cpuset.mem_hardwall", +hardwall); +} + +/** + * virCgroupGetCpusetHardwall: + * + * @group: The cgroup to get cpuset.mem_hardwall for + * @hardwall: the hardwall to get + * + * Returns: 0 on success + */ +int virCgroupGetCpusetHardwall(virCgroupPtr group, unsigned long long *hardwall) +{ +return virCgroupGetValueU64(group, +VIR_CGROUP_CONTROLLER_CPUSET, +"cpuset.mem_hardwall", +hardwall); +} + +int virCgroupSetCpusetMemExclusive(virCgroupPtr group, unsigned long long memExclusive) +{ +return virCgroupSetValueU64(group, +VIR_CGROUP_CONTROLLER_CPUSET, +"cpuset.mem_exclusive", +memExclusive); +} + +int virCgroupGetCpusetMemExclusive(virCgroupPtr group, unsigned long long *memExclusive) +{ +return virCgroupGetValueU64(group, +VIR_CGROUP_CONTROLLER_CPUSET, +"cpuset.mem_exclusive", +memExclusive); +} + +/** * virCgroupDenyAllDevices: * * @group: The cgroup to deny all permissions, for all devices diff --git a/src/util/cgroup.h b/src/util/cgroup.h index d190bb3..c9d891b 100644 --- a/src/util/cgroup.h +++ b/src/util/cgroup.h @@ -115,6 +115,13 @@ int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage); int virCgroupSetFreezerState(virCgroupPtr group, const char *state); int virCgroupGetFreezerState(virCgroupPtr group, char **state); +int virCgroupSetCpusetMems(virCgroupPtr group, const char *mems); +int virCgroupGetCpusetMems(virCgroupPtr group, char **mems); +int virCgroupSetCpusetMemExclusive(virCgroupPtr group, unsigned long long memExclusive); +int virCgroupGetCpusetMemExclusive(virCgroupPtr group, unsigned long long *memExclusive); +int virCgroupSetCpusetHardwall(virCgroupPtr group, unsigned long long hardwall); +int virCgroupGetCpusetHardwall(virCgroupPtr group, unsigned long long *hardwall); + int virCgroupRemove(virCgroupPtr group); void virCgroupFree(virCgroupPtr *group); -- 1.7.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 04/10] remove dependence on libnuma
Since we use cpuset to manage numa, we can safely remove dependence on libnuma. --- src/conf/domain_conf.c | 24 +-- src/conf/domain_conf.h |1 - src/qemu/qemu_process.c | 111 --- 3 files changed, 1 insertions(+), 135 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 6e2d421..0cf3bb7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -583,11 +583,6 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST, "paravirt", "smpsafe"); -VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST, - "strict", - "preferred", - "interleave"); - VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST, "default", "mandatory", @@ -6834,20 +6829,6 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, "%s", _("nodeset for NUMA memory tuning must be set")); goto error; } - -tmp = virXPathString("string(./numatune/memory/@mode)", ctxt); -if (tmp) { -if ((def->numatune.memory.mode = -virDomainNumatuneMemModeTypeFromString(tmp)) < 0) { -virDomainReportError(VIR_ERR_INTERNAL_ERROR, -_("Unsupported NUMA memory tuning mode '%s'"), -tmp); -goto error; -} -VIR_FREE(tmp); -} else { -def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT; -} } n = virXPathNodeSet("./features/*", ctxt, &nodes); @@ -10882,7 +10863,6 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAddLit(buf, " \n"); if (def->numatune.memory.nodemask) { -const char *mode; char *nodemask = NULL; virBufferAddLit(buf, " \n"); @@ -10894,9 +10874,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, goto cleanup; } -mode = virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode); -virBufferAsprintf(buf, "\n", - mode, nodemask); +virBufferAsprintf(buf, "\n", nodemask); VIR_FREE(nodemask); virBufferAddLit(buf, " \n"); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f74f4bb..ca68437 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1353,7 +1353,6 @@ typedef virDomainNumatuneDef *virDomainNumatuneDefPtr; struct _virDomainNumatuneDef { struct { char *nodemask; -int mode; } memory; /* Future NUMA tuning related stuff should go here. */ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 47164f7..5969b34 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -39,11 +39,6 @@ #include "qemu_bridge_filter.h" #include "qemu_migration.h" -#if HAVE_NUMACTL -# define NUMA_VERSION1_COMPATIBILITY 1 -# include -#endif - #include "datatypes.h" #include "logging.h" #include "virterror_internal.h" @@ -1314,109 +1309,6 @@ qemuProcessDetectVcpuPIDs(struct qemud_driver *driver, return 0; } - -/* - * Set NUMA memory policy for qemu process, to be run between - * fork/exec of QEMU only. - */ -#if HAVE_NUMACTL -static int -qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm) -{ -nodemask_t mask; -int mode = -1; -int node = -1; -int ret = -1; -int i = 0; -int maxnode = 0; -bool warned = false; - -if (!vm->def->numatune.memory.nodemask) -return 0; - -VIR_DEBUG("Setting NUMA memory policy"); - -if (numa_available() < 0) { -qemuReportError(VIR_ERR_INTERNAL_ERROR, -"%s", _("Host kernel is not aware of NUMA.")); -return -1; -} - -maxnode = numa_max_node() + 1; - -/* Convert nodemask to NUMA bitmask. */ -nodemask_zero(&mask); -for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) { -if (vm->def->numatune.memory.nodemask[i]) { -if (i > NUMA_NUM_NODES) { -qemuReportError(VIR_ERR_INTERNAL_ERROR, -_("Host cannot support NUMA node %d"), i); -return -1; -} -if (i > maxnode && !warned) { -VIR_WARN("nodeset is out of range, there is only %d NUMA " - "nodes on host", maxnode); -warned = true; - } -nodemask_set(&mask, i); -} -} - -mode = vm->def->numatune.memory.mode; - -if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) { -numa_set_bind_policy(1); -numa_set_membind(&mask); -numa_set_bind_policy(0); -} else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) { -int nnodes = 0; -for (i = 0; i < NUMA_NUM_NODES; i++) { -if (nodemask_isset(&mask, i)) { -nod
[libvirt] [PATCH 09/10] Implement virDomain{G, S}etNumaParameters for the qemu driver
--- src/qemu/qemu_cgroup.c | 14 ++ src/qemu/qemu_driver.c | 307 2 files changed, 321 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 49307b2..99714ab 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -381,6 +381,20 @@ int qemuSetupCgroup(struct qemud_driver *driver, vm->def->name); goto cleanup; } +rc = virCgroupSetCpusetHardwall(cgroup, vm->def->numatune.strict); +if (rc != 0) { +virReportSystemError(-rc, + _("Unable to set cpuset.mem_hardwall for domain %s"), + vm->def->name); +goto cleanup; +} +rc = virCgroupSetCpusetMemExclusive(cgroup, vm->def->numatune.exclusive); +if (rc != 0) { +virReportSystemError(-rc, + _("Unable to set cpuset.mem_exclusive for domain %s"), + vm->def->name); +goto cleanup; +} } else { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unable to set numa for domain %s since cpuset cgroup is " diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5e49ff4..be9697c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -94,6 +94,8 @@ #define QEMU_NB_MEM_PARAM 3 +#define QEMU_NB_NUMA_PARAM 2 + #if HAVE_LINUX_KVM_H # include #endif @@ -6518,6 +6520,309 @@ cleanup: return ret; } +static int qemuDomainSetNumaParameters(virDomainPtr dom, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ +struct qemud_driver *driver = dom->conn->privateData; +int i; +virDomainDefPtr persistentDef = NULL; +virCgroupPtr group = NULL; +virDomainObjPtr vm = NULL; +int ret = -1; +bool isActive; + +virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + +qemuDriverLock(driver); + +vm = virDomainFindByUUID(&driver->domains, dom->uuid); + +if (vm == NULL) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_("No such domain %s"), dom->uuid); +goto cleanup; +} + +isActive = virDomainObjIsActive(vm); + +if (flags == VIR_DOMAIN_AFFECT_CURRENT) { +if (isActive) +flags = VIR_DOMAIN_AFFECT_LIVE; +else +flags = VIR_DOMAIN_AFFECT_CONFIG; +} + +if (flags & VIR_DOMAIN_AFFECT_LIVE) { +if (!isActive) { +qemuReportError(VIR_ERR_OPERATION_INVALID, +"%s", _("domain is not running")); +goto cleanup; +} + +if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { +qemuReportError(VIR_ERR_OPERATION_INVALID, +"%s", _("cgroup cpuset controller is not mounted")); +goto cleanup; +} + +if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_("cannot find cgroup for domain %s"), vm->def->name); +goto cleanup; +} +} + +if (flags & VIR_DOMAIN_AFFECT_CONFIG) { +if (!vm->persistent) { +qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", +_("cannot change persistent config of a transient domain")); +goto cleanup; +} +if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm))) +goto cleanup; +} + +ret = 0; +for (i = 0; i < nparams; i++) { +virTypedParameterPtr param = ¶ms[i]; + +if (STREQ(param->field, VIR_DOMAIN_NUMA_STRICT)) { +int rc; +if (param->type != VIR_TYPED_PARAM_ULLONG) { +qemuReportError(VIR_ERR_INVALID_ARG, "%s", +_("invalid type for numa strict tunable, expected a 'ullong'")); +ret = -1; +continue; +} + +if (flags & VIR_DOMAIN_AFFECT_LIVE) { +rc = virCgroupSetCpusetHardwall(group, params[i].value.i); +if (rc != 0) { +virReportSystemError(-rc, "%s", + _("unable to set memory hard_limit tunable")); +ret = -1; +} +} + +if (flags & VIR_DOMAIN_AFFECT_CONFIG) { +persistentDef->numatune.strict = params[i].value.i; +} +} else if (STREQ(param->field, VIR_DOMAIN_NUMA_EXCLUSIVE)) { +int rc; +if (param->type != VIR_TYPED_PARAM_ULLONG) { +
Re: [libvirt] [PATCH 04/10] remove dependence on libnuma
On Thu, Nov 03, 2011 at 07:55:19PM +0800, Hu Tao wrote: > Since we use cpuset to manage numa, we can safely remove dependence > on libnuma. > --- > src/conf/domain_conf.c | 24 +-- > src/conf/domain_conf.h |1 - > src/qemu/qemu_process.c | 111 > --- > 3 files changed, 1 insertions(+), 135 deletions(-) > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 6e2d421..0cf3bb7 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -583,11 +583,6 @@ VIR_ENUM_IMPL(virDomainTimerMode, > VIR_DOMAIN_TIMER_MODE_LAST, >"paravirt", >"smpsafe"); > > -VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST, > - "strict", > - "preferred", > - "interleave"); > - > VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST, >"default", >"mandatory", > @@ -6834,20 +6829,6 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr > caps, > "%s", _("nodeset for NUMA memory tuning must > be set")); > goto error; > } > - > -tmp = virXPathString("string(./numatune/memory/@mode)", ctxt); > -if (tmp) { > -if ((def->numatune.memory.mode = > -virDomainNumatuneMemModeTypeFromString(tmp)) < 0) { > -virDomainReportError(VIR_ERR_INTERNAL_ERROR, > -_("Unsupported NUMA memory tuning mode > '%s'"), > -tmp); > -goto error; > -} > -VIR_FREE(tmp); > -} else { > -def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT; > -} > } > > n = virXPathNodeSet("./features/*", ctxt, &nodes); > @@ -10882,7 +10863,6 @@ virDomainDefFormatInternal(virDomainDefPtr def, > virBufferAddLit(buf, " \n"); > > if (def->numatune.memory.nodemask) { > -const char *mode; > char *nodemask = NULL; > > virBufferAddLit(buf, " \n"); > @@ -10894,9 +10874,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, > goto cleanup; > } > > -mode = > virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode); > -virBufferAsprintf(buf, "\n", > - mode, nodemask); > +virBufferAsprintf(buf, "\n", nodemask); > VIR_FREE(nodemask); > virBufferAddLit(buf, " \n"); > } > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index f74f4bb..ca68437 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -1353,7 +1353,6 @@ typedef virDomainNumatuneDef *virDomainNumatuneDefPtr; > struct _virDomainNumatuneDef { > struct { > char *nodemask; > -int mode; > } memory; > > /* Future NUMA tuning related stuff should go here. */ You can't remove this stuff from the XML - this is part of our public stability guarentee. The way it is modelled is not specific to libnuma anyway, so there shouldn't be this tie. > diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c > index 47164f7..5969b34 100644 > --- a/src/qemu/qemu_process.c > +++ b/src/qemu/qemu_process.c > @@ -39,11 +39,6 @@ > #include "qemu_bridge_filter.h" > #include "qemu_migration.h" > > -#if HAVE_NUMACTL > -# define NUMA_VERSION1_COMPATIBILITY 1 > -# include > -#endif > - > #include "datatypes.h" > #include "logging.h" > #include "virterror_internal.h" > @@ -1314,109 +1309,6 @@ qemuProcessDetectVcpuPIDs(struct qemud_driver *driver, > return 0; > } > > - > -/* > - * Set NUMA memory policy for qemu process, to be run between > - * fork/exec of QEMU only. > - */ > -#if HAVE_NUMACTL > -static int > -qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm) > -{ > -nodemask_t mask; > -int mode = -1; > -int node = -1; > -int ret = -1; > -int i = 0; > -int maxnode = 0; > -bool warned = false; > - > -if (!vm->def->numatune.memory.nodemask) > -return 0; > - > -VIR_DEBUG("Setting NUMA memory policy"); > - > -if (numa_available() < 0) { > -qemuReportError(VIR_ERR_INTERNAL_ERROR, > -"%s", _("Host kernel is not aware of NUMA.")); > -return -1; > -} > - > -maxnode = numa_max_node() + 1; > - > -/* Convert nodemask to NUMA bitmask. */ > -nodemask_zero(&mask); > -for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) { > -if (vm->def->numatune.memory.nodemask[i]) { > -if (i > NUMA_NUM_NODES) { > -qemuReportError(VIR_ERR_INTERNAL_ERROR, > -_("Host cannot support NUMA node %d"), i); > -return -1; > -} > -if (i > maxnode && !warned) { > -VIR_WARN("nodeset is out of range, there is only %d NUMA " > -
Re: [libvirt] [PATCH 05/10] new numa parameters
On Thu, Nov 03, 2011 at 07:55:20PM +0800, Hu Tao wrote: > This patch adds two parameters: strict and exclusive that we can > get/set through cpuset. > --- > src/conf/domain_conf.c | 15 +++ > src/conf/domain_conf.h |2 ++ > 2 files changed, 17 insertions(+), 0 deletions(-) > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 0cf3bb7..02a144b 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -6802,6 +6802,10 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr > caps, > VIR_FREE(nodes); > > /* Extract numatune if exists. */ > + > +def->numatune.strict = 0; > +def->numatune.exclusive = 0; > + > if ((n = virXPathNodeSet("./numatune", ctxt, NULL)) < 0) { > virDomainReportError(VIR_ERR_INTERNAL_ERROR, > "%s", _("cannot extract numatune nodes")); > @@ -6829,6 +6833,13 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr > caps, > "%s", _("nodeset for NUMA memory tuning must > be set")); > goto error; > } > + > +if (virXPathNode("./numatune/strict", ctxt)) { > +def->numatune.strict = 1; > +} > +if (virXPathNode("./numatune/exclusive", ctxt)) { > +def->numatune.exclusive = 1; > +} > } > > n = virXPathNodeSet("./features/*", ctxt, &nodes); > @@ -10876,6 +10887,10 @@ virDomainDefFormatInternal(virDomainDefPtr def, > > virBufferAsprintf(buf, "\n", nodemask); > VIR_FREE(nodemask); > +if (def->numatune.strict) > +virBufferAsprintf(buf, "\n"); > +if (def->numatune.exclusive) > +virBufferAsprintf(buf, "\n"); > virBufferAddLit(buf, " \n"); > } > > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index ca68437..f3dbece 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -1355,6 +1355,8 @@ struct _virDomainNumatuneDef { > char *nodemask; > } memory; > > +int strict; > +int exclusive; > /* Future NUMA tuning related stuff should go here. */ > }; NACK to this for the same reason as the previous patch - we can't simply change the XML format at will to suit a new backend implementation. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] sVirt support for LXC?
Hello, We are at the later stage of a project. We are very much interested in sVirt support for LXC. Is there any branch that we can try? We are willing to test one. As I wrote below, we tried Daniel's branch https://gitorious.org/~berrange/libvirt/staging/commits/lxc-svirt. But we didn't have much luck. Any help? Do you have any schedule of adding sVirt support for LXC to upstream libvirt? Thanks, David. -- Dr. Dong-In "David" Kang Computer Scientist USC/ISI - Original Message - From: "Eric Blake" To: "Dong-In David Kang" Cc: libvir-list@redhat.com Sent: Wednesday, November 2, 2011 12:57:16 PM Subject: Re: [libvirt] sVirt support for LXC? On 11/02/2011 10:37 AM, Dong-In David Kang wrote: > > Hello, Replying to a random previous message, even if you change the subject line, doesn't create a new thread. Your message got buried in an existing thread, making it harder to find; in the future, it is better to start a new thread via a fresh email rather than replying to an existing mail. > > Is it planned to support sVirt for LXC? Eventually. It's a work in progress, and tracking this mailing list you will see as it improves. > I know the current libvirt does not support sVirt for LXC. > I found that a branch at > https://gitorious.org/~berrange/libvirt/staging/commits/lxc-svirt seems to > support sVirt for LXC. Yes, that's Daniel's staging area as he works on improving the situation. > I downloaded the tar file and overwrite libvirt-0.9.6 with the branch. Not recommended. Running a staging area patch is rather risky, and it's better to wait for it to hit upstream libvirt.git first, especially if you want support from this list. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list -- Dr. Dong-In "David" Kang Computer Scientist USC/ISI -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] sVirt support for LXC?
On Thu, Nov 03, 2011 at 07:06:46AM -0700, Dong-In David Kang wrote: > > Hello, > > We are at the later stage of a project. > We are very much interested in sVirt support for LXC. > Is there any branch that we can try? > We are willing to test one. > As I wrote below, we tried Daniel's branch > https://gitorious.org/~berrange/libvirt/staging/commits/lxc-svirt. > But we didn't have much luck. > Any help? That branch is just my development snapshot and its not really in a state for people to use, unless you have a very good understanding of libvirt and SELinux and are prepared to debug it yourself. > Do you have any schedule of adding sVirt support for LXC to upstream libvirt? Almost certainly before the end of this year, hopefully for the end of November release of libvirt. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] sVirt support for LXC?
Thanks a lot. It would be wonderful if it can be done by the end of November. David. -- Dr. Dong-In "David" Kang Computer Scientist USC/ISI - Original Message - From: "Daniel P. Berrange" To: "Dong-In David Kang" Cc: libvir-list@redhat.com, "Lorin Hochstein" Sent: Thursday, November 3, 2011 10:10:21 AM Subject: Re: sVirt support for LXC? On Thu, Nov 03, 2011 at 07:06:46AM -0700, Dong-In David Kang wrote: > > Hello, > > We are at the later stage of a project. > We are very much interested in sVirt support for LXC. > Is there any branch that we can try? > We are willing to test one. > As I wrote below, we tried Daniel's branch > https://gitorious.org/~berrange/libvirt/staging/commits/lxc-svirt. > But we didn't have much luck. > Any help? That branch is just my development snapshot and its not really in a state for people to use, unless you have a very good understanding of libvirt and SELinux and are prepared to debug it yourself. > Do you have any schedule of adding sVirt support for LXC to upstream libvirt? Almost certainly before the end of this year, hopefully for the end of November release of libvirt. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] lxc: use common code for process cleanup
Based on a Coverity report - the return value of waitpid() should always be checked, to avoid problems with leaking resources. * src/lxc/lxc_controller.c (lxcControllerRun): Use simpler virPidAbort. --- Daniel previously said to wait until after the lxc multi-console patches were in before visiting this file; but now that those are in, this fix is still applicable: https://www.redhat.com/archives/libvir-list/2011-October/msg01083.html src/lxc/lxc_controller.c | 11 +++ 1 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 649ac87..137ef52 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -59,6 +59,7 @@ #include "util.h" #include "virfile.h" #include "virpidfile.h" +#include "command.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -1266,14 +1267,8 @@ cleanup: VIR_FORCE_CLOSE(loopDevs[i]); VIR_FREE(loopDevs); -if (container > 1) { -int status; -kill(container, SIGTERM); -if (!(waitpid(container, &status, WNOHANG) == 0 && -WIFEXITED(status))) -kill(container, SIGKILL); -waitpid(container, NULL, 0); -} +virPidAbort(container); + return rc; } -- 1.7.4.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] lxc: use common code for process cleanup
On Thu, Nov 03, 2011 at 08:45:45AM -0600, Eric Blake wrote: > Based on a Coverity report - the return value of waitpid() should > always be checked, to avoid problems with leaking resources. > > * src/lxc/lxc_controller.c (lxcControllerRun): Use simpler virPidAbort. > --- > > Daniel previously said to wait until after the lxc multi-console > patches were in before visiting this file; but now that those are > in, this fix is still applicable: > https://www.redhat.com/archives/libvir-list/2011-October/msg01083.html > > src/lxc/lxc_controller.c | 11 +++ > 1 files changed, 3 insertions(+), 8 deletions(-) > > diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c > index 649ac87..137ef52 100644 > --- a/src/lxc/lxc_controller.c > +++ b/src/lxc/lxc_controller.c > @@ -59,6 +59,7 @@ > #include "util.h" > #include "virfile.h" > #include "virpidfile.h" > +#include "command.h" > > #define VIR_FROM_THIS VIR_FROM_LXC > > @@ -1266,14 +1267,8 @@ cleanup: > VIR_FORCE_CLOSE(loopDevs[i]); > VIR_FREE(loopDevs); > > -if (container > 1) { > -int status; > -kill(container, SIGTERM); > -if (!(waitpid(container, &status, WNOHANG) == 0 && > -WIFEXITED(status))) > -kill(container, SIGKILL); > -waitpid(container, NULL, 0); > -} > +virPidAbort(container); > + > return rc; > } ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] client hang in virDomainCreateXML
Hi, We are using Ubuntu 10.04 eucalyptus 1.6.2 and libvirt 0.7.5. We found eucalyptus-nc sometimes hangs in virDomainCreateXML, and never gets response from libvirtd. After 2 days of investigation, I found there is another libvirt client connects to libvirtd 'qemu:///system', which is the same URI as eucalyptus-nc. The bug never shows after I disabled the client. My question is: 1, can I have multiple clients connect to qemu:///system? 2, is this an bug in libvirt and has it been fixed? Thanks a lot -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] lxc: use common code for process cleanup
On 11/03/2011 08:48 AM, Daniel P. Berrange wrote: On Thu, Nov 03, 2011 at 08:45:45AM -0600, Eric Blake wrote: Based on a Coverity report - the return value of waitpid() should always be checked, to avoid problems with leaking resources. * src/lxc/lxc_controller.c (lxcControllerRun): Use simpler virPidAbort. --- ACK Pushed. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] can't start domain with a corrupted disk attatched
On 2011-11-3 18:12, Daniel P. Berrange wrote: On Thu, Nov 03, 2011 at 05:33:56PM +0800, lvroyce wrote: Hi all, I came across below issue when testing: 1.make a volume and attach it to a domain A 2.unplug the vg from the host in order to emulating a volume failure 3.start domain A(failed) In step 3 can't start domainA . because can't find disk listed in xml when create the Domain. I'm not sure if it is reasonable. In common sense, we can still start our system even if we have a corrupt data disk .And also ,if in data center we carelessly attatch a corrupt volumn to all the guest, it will result in all guests fail to boot . I suggest to automatically detach a disk if it can't be found and just give out a warning.Please let me know your opinion about if it is a bug or a feature.Thanks. You are not simulating a corrupt data disk in your example, you are simulating a completely missing disk. This is simply administrative error and thus is it perfectly reasonable for the guest to not start when its disk is missing. I think the she was talking about a non-root disk missing. In physical machine, if a non-root disk was gone, the system can also start up without the disk. Daniel -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-glib] Ask gtkdoc-scan to generate the sections file
On Tue, Nov 01, 2011 at 06:45:44PM +0200, Zeeshan Ali (Khattak) wrote: > From: "Zeeshan Ali (Khattak)" > > This frees us from maintaining the sections file. > --- > docs/libvirt-gconfig/Libvirt-gconfig-sections.txt | 166 -- > docs/libvirt-gconfig/Makefile.am |2 +- > docs/libvirt-glib/Libvirt-glib-sections.txt | 22 -- > docs/libvirt-glib/Makefile.am |2 +- > docs/libvirt-gobject/Libvirt-gobject-sections.txt | 244 > - > docs/libvirt-gobject/Makefile.am |2 +- > 6 files changed, 3 insertions(+), 435 deletions(-) > delete mode 100644 docs/libvirt-gconfig/Libvirt-gconfig-sections.txt > delete mode 100644 docs/libvirt-glib/Libvirt-glib-sections.txt > delete mode 100644 docs/libvirt-gobject/Libvirt-gobject-sections.txt ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 11/33] Rename virVirtualPortProfileParams & APIs
From: "Daniel P. Berrange" Rename the virVirtualPortProfileParams struct to be virNetDevVPortProfile, and rename the APIs to match this prefix. * src/util/network.c, src/util/network.h: Rename port profile APIs * src/conf/domain_conf.c, src/conf/domain_conf.h, src/conf/network_conf.c, src/conf/network_conf.h, src/network/bridge_driver.c, src/qemu/qemu_hotplug.c, src/util/macvtap.c, src/util/macvtap.h: Update for renamed APIs/structs --- src/conf/domain_conf.c | 16 +++--- src/conf/domain_conf.h |8 +++--- src/conf/network_conf.c | 12 +- src/conf/network_conf.h |4 +- src/libvirt_private.syms|6 ++-- src/network/bridge_driver.c |6 ++-- src/qemu/qemu_hotplug.c |4 +- src/util/macvtap.c | 36 src/util/macvtap.h |8 +++--- src/util/network.c | 48 +- src/util/network.h | 33 +++-- 11 files changed, 91 insertions(+), 90 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ab7853d..c1f8950 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3112,8 +3112,8 @@ virDomainActualNetDefParseXML(xmlNodePtr node, virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode && -virVirtualPortProfileParseXML(virtPortNode, - &actual->data.direct.virtPortProfile) < 0) { +virNetDevVPortProfileParse(virtPortNode, + &actual->data.direct.virtPortProfile) < 0) { goto error; } } @@ -3169,7 +3169,7 @@ virDomainNetDefParseXML(virCapsPtr caps, char *mode = NULL; char *linkstate = NULL; virNWFilterHashTablePtr filterparams = NULL; -virVirtualPortProfileParamsPtr virtPort = NULL; +virNetDevVPortProfilePtr virtPort = NULL; virDomainActualNetDefPtr actual = NULL; xmlNodePtr oldnode = ctxt->node; int ret; @@ -3221,7 +3221,7 @@ virDomainNetDefParseXML(virCapsPtr caps, ((def->type == VIR_DOMAIN_NET_TYPE_DIRECT) || (def->type == VIR_DOMAIN_NET_TYPE_NETWORK)) && xmlStrEqual(cur->name, BAD_CAST "virtualport")) { -if (virVirtualPortProfileParseXML(cur, &virtPort) < 0) +if (virNetDevVPortProfileParse(cur, &virtPort) < 0) goto error; } else if ((network == NULL) && ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) || @@ -9721,7 +9721,7 @@ virDomainActualNetDefFormat(virBufferPtr buf, } virBufferAsprintf(buf, " mode='%s'/>\n", mode); virBufferAdjustIndent(buf, 8); -virVirtualPortProfileFormat(buf, def->data.direct.virtPortProfile); +virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf); virBufferAdjustIndent(buf, -8); break; default: @@ -9768,7 +9768,7 @@ virDomainNetDefFormat(virBufferPtr buf, def->data.network.portgroup); virBufferAddLit(buf, "/>\n"); virBufferAdjustIndent(buf, 6); -virVirtualPortProfileFormat(buf, def->data.network.virtPortProfile); +virNetDevVPortProfileFormat(def->data.network.virtPortProfile, buf); virBufferAdjustIndent(buf, -6); if ((flags & VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET) && (virDomainActualNetDefFormat(buf, def->data.network.actual) < 0)) @@ -9818,7 +9818,7 @@ virDomainNetDefFormat(virBufferPtr buf, virMacvtapModeTypeToString(def->data.direct.mode)); virBufferAddLit(buf, "/>\n"); virBufferAdjustIndent(buf, 6); -virVirtualPortProfileFormat(buf, def->data.direct.virtPortProfile); +virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf); virBufferAdjustIndent(buf, -6); break; @@ -13078,7 +13078,7 @@ virDomainNetGetActualDirectMode(virDomainNetDefPtr iface) return iface->data.network.actual->data.direct.mode; } -virVirtualPortProfileParamsPtr +virNetDevVPortProfilePtr virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface) { if (iface->type == VIR_DOMAIN_NET_TYPE_DIRECT) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a3cb834..255d8fd 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -508,7 +508,7 @@ struct _virDomainActualNetDef { struct { char *linkdev; int mode; /* enum virMacvtapMode from util/macvtap.h */ -virVirtualPortProfileParamsPtr virtPortProfile; +virNetDevVPortProfilePtr virtPortProfile; } direct; } data; virNetDevBandwidthPtr bandwidth; @@ -542,7 +542,7 @@ struct _virDomainNetDef { struct { char *name; char *portgroup; -virVirtualPortProfile
[libvirt] [PATCH 03/33] Rename all brXXXX APIs to follow new convention
From: "Daniel P. Berrange" The existing brXXX APIs in src/util/bridge.h are renamed to follow one of three different conventions - virNetDevXXX - operations for any type of interface - virNetDevBridgeXXX - operations for bridge interfaces - virNetDevTapXXX- operations for tap interfaces * src/util/bridge.h, src/util/bridge.c: Rename all APIs * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/uml/uml_conf.c, src/uml/uml_driver.c: Update for API renaming --- src/lxc/lxc_driver.c|2 +- src/network/bridge_driver.c | 32 src/qemu/qemu_command.c |4 +- src/uml/uml_conf.c |4 +- src/uml/uml_driver.c|2 +- src/util/bridge.c | 196 +++--- src/util/bridge.h | 74 7 files changed, 148 insertions(+), 166 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 8ee1306..c75941f 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1269,7 +1269,7 @@ static int lxcSetupInterfaces(virConnectPtr conn, goto error_exit; } -if (brAddInterface(bridge, parentVeth) < 0) +if (virNetDevBridgeAddPort(bridge, parentVeth) < 0) goto error_exit; if (vethInterfaceUpOrDown(parentVeth, 1) < 0) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index d5d2472..bc9d2e1 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -211,7 +211,7 @@ networkFindActiveConfigs(struct network_driver *driver) { /* If bridge exists, then mark it active */ if (obj->def->bridge && -brHasBridge(obj->def->bridge) == 0) { +virNetDevExists(obj->def->bridge) == 0) { obj->active = 1; /* Try and read dnsmasq/radvd pids if any */ @@ -1677,8 +1677,8 @@ networkAddAddrToBridge(virNetworkObjPtr network, return -1; } -if (brAddInetAddress(network->def->bridge, - &ipdef->address, prefix) < 0) +if (virNetDevSetIPv4Addres(network->def->bridge, + &ipdef->address, prefix) < 0) return -1; return 0; @@ -1699,7 +1699,7 @@ networkStartNetworkVirtual(struct network_driver *driver, return -1; /* Create and configure the bridge device */ -if (brAddBridge(network->def->bridge) < 0) +if (virNetDevBridgeCreate(network->def->bridge) < 0) return -1; if (network->def->mac_specified) { @@ -1714,20 +1714,20 @@ networkStartNetworkVirtual(struct network_driver *driver, virReportOOMError(); goto err0; } -if (brAddTap(network->def->bridge, - &macTapIfName, network->def->mac, 0, false, NULL) < 0) { +if (virNetDevTapCreateInBridgePort(network->def->bridge, + &macTapIfName, network->def->mac, 0, false, NULL) < 0) { VIR_FREE(macTapIfName); goto err0; } } /* Set bridge options */ -if (brSetForwardDelay(network->def->bridge, +if (virNetDevBridgeSetSTPDelay(network->def->bridge, network->def->delay) < 0) goto err1; -if (brSetEnableSTP(network->def->bridge, - network->def->stp ? 1 : 0) < 0) +if (virNetDevBridgeSetSTP(network->def->bridge, + network->def->stp ? 1 : 0) < 0) goto err1; /* Disable IPv6 on the bridge if there are no IPv6 addresses @@ -1755,7 +1755,7 @@ networkStartNetworkVirtual(struct network_driver *driver, } /* Bring up the bridge interface */ -if (brSetInterfaceUp(network->def->bridge, 1) < 0) +if (virNetDevSetOnline(network->def->bridge, 1) < 0) goto err2; /* If forwardType != NONE, turn on global IP forwarding */ @@ -1804,7 +1804,7 @@ networkStartNetworkVirtual(struct network_driver *driver, err3: if (!save_err) save_err = virSaveLastError(); -ignore_value(brSetInterfaceUp(network->def->bridge, 0)); +ignore_value(virNetDevSetOnline(network->def->bridge, 0)); err2: if (!save_err) @@ -1815,13 +1815,13 @@ networkStartNetworkVirtual(struct network_driver *driver, if (!save_err) save_err = virSaveLastError(); -ignore_value(brDeleteTap(macTapIfName)); +ignore_value(virNetDevTapDelete(macTapIfName)); VIR_FREE(macTapIfName); err0: if (!save_err) save_err = virSaveLastError(); -ignore_value(brDeleteBridge(network->def->bridge)); +ignore_value(virNetDevBridgeDelete(network->def->bridge)); if (save_err) { virSetError(save_err); @@ -1859,16 +1859,16 @@ static int networkShutdownNetworkVirtual(struct network_driver *driver, if (!macTapIfName) { virReportOOMError(); } else { -ignore_value(brDeleteTap(macTapIfName)); +
[libvirt] [PATCH 00/33] Refactor all network device handling code
This series is a major re-arrangement and de-duplication of internal code for dealing with physical network interfaces. Currently code for physical network interfaces is split across the following files - bridge.c: bridge management, TAP device management and interface IPv4 address management - network.c: socket address management, network bandwidth and virtual port profile data management - interface.c: some generic interface management and macvtap/macvlan management - macvtap.c: more macvtap/macvlan management and virtual port profile interface setup code - lxc/veth.c: veth device management and generic interface management Furthermore across these files - Argument ordering is inconsistent - sometimes ifname is the first parameter, sometimes it isn't - Error handing is terribly inconsistent 1. Return errno values 2. Raise errors 3. Raise errors and return errno values 4. Raise errors, except when a parameter tells it not to - API naming is inconsistent. Some APIs have a vir prefix, others have different prefixes, other don't even follow a standard prefix, eg virSocketFormatAddr vs virSocketAddrMaks vs virSocketGetPort - The bridge.c APIs have an annoying 'brControl *' struct that must be passed around just to avoid opening & closing an unbound socket. - Some APIs are implemented natively, while others call out to external commands - Duplication of functionality across APIs - XML parsing & formatting code is in src/util instead of src/conf - Some of the API declarations are hidden behind #ifdefs forcing yet more #ifdefs in the callers of the APIs After applying this series, we get to a stage where the source file split is: - src/util/virnetdev.c: APIs relating to any type of interface - src/util/virnetdevbridge.c: APIs relating to bridge interfaces - src/util/virnetdevmacvlan.c: APIs relating to macvlan/macvtap interfaces - src/util/virnetdevveth.c: APIs relating to veth interfaces - src/util/virnetdevbandwidth.c: APIs for network bandwidth controls - src/util/virnetdevvportprofile.c: APIs for 802.11Qb{g,h} port profiles - src/util/virsocketaddr.c: the socket address management APIs - src/conf/netdev_bandwidth_conf.c: Parsing/formatting bandwidth XML - src/conf/netdev_vport_profile_conf.c: parsing/formatting 801.11Qb{g,h} profile XML The following style is followed - All APIs return -1 on error and raise a libvirt error. No exceptions or flags to turn off errors - Callers which don't want the raised error call virResetLastError - All APIs are annotated with ATTRIBUTE_NONNULL and ATTRIBUTE_RETURN_CHECK where appropriate - The first parameter of all APIs operating on a network interface is the interface name - All APIs have a fixed name prefix which matches the source file. No exceptions. - All XML handling code is under src/conf/ - All APIs are unconditionally declared in header files, and stubbed out with virReportSystemError(ENOSYS...) where unsupported. - No functionality is duplicated across files - External commands are avoided except in case of setting IPv4 addresses and network bandwidth controls The diffstat is a little bit misleading, showing a slight growth in the number of lines. This is primarily due to the extra GPL copyright header lines in the new files, being much larger than those removed from old files. Overall we have a decrease in actual real code, through removal of duplicated APIs b/configure.ac |5 b/daemon/libvirtd.h |1 b/daemon/remote.c |1 b/libvirt.spec.in |2 b/po/POTFILES.in| 12 b/src/Makefile.am | 26 b/src/conf/domain_conf.c| 59 - b/src/conf/domain_conf.h| 20 b/src/conf/netdev_bandwidth_conf.c | 230 b/src/conf/netdev_bandwidth_conf.h | 37 b/src/conf/netdev_vport_profile_conf.c | 236 b/src/conf/netdev_vport_profile_conf.h | 39 b/src/conf/network_conf.c | 101 +- b/src/conf/network_conf.h | 12 b/src/conf/nwfilter_conf.c | 16 b/src/conf/nwfilter_conf.h |2 b/src/esx/esx_util.h|2 b/src/libvirt_private.syms | 71 - b/src/lxc/lxc_container.c |9 b/src/lxc/lxc_controller.c |7 b/src/lxc/lxc_driver.c | 42 b/src/network/bridge_driver.c | 192 +-- b/src/nwfilter/nwfilter_ebiptables_driver.c |4 b/src/nwfilter/nwfilter_gentech_driver.c| 25 b/src/nwfilter/nwfilter_learnipaddr.c | 32 b/src/openvz/openvz_driver.c|1 b/src/qemu/qemu_command.
[libvirt] [PATCH 05/33] Expose MTU management APIs
From: "Daniel P. Berrange" The MTU management APIs are useful to other code inside libvirt, so should be exposed as non-static APIs. * src/util/bridge.c, src/util/bridge.h: Expose virNetDevSetMTU, virNetDevSetMTUFromDevice & virNetDevGetMTU --- src/util/bridge.c | 18 +- src/util/bridge.h |8 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/util/bridge.c b/src/util/bridge.c index 1584052..247ce93 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -365,7 +365,7 @@ cleanup: * * Returns the MTU value in case of success, or -1 on failure. */ -static int virNetDevGetMTU(const char *ifname) +int virNetDevGetMTU(const char *ifname) { int fd = -1; int ret = -1; @@ -398,7 +398,7 @@ cleanup: * * Returns 0 in case of success, or -1 on failure */ -static int virNetDevSetMTU(const char *ifname, int mtu) +int virNetDevSetMTU(const char *ifname, int mtu) { int fd = -1; int ret = -1; @@ -424,18 +424,18 @@ cleanup: } /** - * brSetInterfaceMtu - * @brname: name of the bridge interface + * virNetDevSetMTUFromDevice: * @ifname: name of the interface whose MTU we want to set + * @otherifname: name of the interface whose MTU we want to copy * - * Sets the interface mtu to the same MTU of the bridge + * Sets the interface mtu to the same MTU as another interface * * Returns 0 in case of success, or -1 on failure */ -static int virNetDevSetMTUFromDevice(const char *brname, - const char *ifname) +int virNetDevSetMTUFromDevice(const char *ifname, + const char *otherifname) { -int mtu = virNetDevGetMTU(brname); +int mtu = virNetDevGetMTU(otherifname); if (mtu < 0) return -1; @@ -543,7 +543,7 @@ int virNetDevTapCreateInBridgePort(const char *brname, * to the bridge, because the bridge will have its * MTU adjusted automatically when we add the new interface. */ -if (virNetDevSetMTUFromDevice(brname, *ifname) < 0) +if (virNetDevSetMTUFromDevice(*ifname, brname) < 0) goto error; if (virNetDevBridgeAddPort(brname, *ifname) < 0) diff --git a/src/util/bridge.h b/src/util/bridge.h index 2de7259..0cc89c0 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -112,6 +112,14 @@ int virNetDevTapCreate(char **ifname, int virNetDevSetMAC(const char *ifname, const unsigned char *macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetMTU(const char *ifname, +int mtu) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetMTUFromDevice(const char *ifname, + const char *otherifname) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMTU(const char *ifname) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; # endif /* WITH_BRIDGE */ -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 04/33] Turn two int parameters into bools in bridge APIs
From: "Daniel P. Berrange" * src/util/bridge.c, src/util/bridge.h: s/int/bool/ in virNetDevSetOnline and virNetDevBridgeSetSTP --- src/util/bridge.c | 18 +- src/util/bridge.h |8 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/util/bridge.c b/src/util/bridge.c index a853c2a..1584052 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -605,14 +605,14 @@ cleanup: /** * virNetDevSetOnline: * @ifname: the interface name - * @up: 1 for up, 0 for down + * @online: true for up, false for down * - * Function to control if an interface is activated (up, 1) or not (down, 0) + * Function to control if an interface is activated (up, true) or not (down, false) * * Returns 0 in case of success or -1 on error. */ int virNetDevSetOnline(const char *ifname, - int up) + bool online) { int fd = -1; int ret = -1; @@ -629,7 +629,7 @@ int virNetDevSetOnline(const char *ifname, goto cleanup; } -if (up) +if (online) ifflags = ifr.ifr_flags | IFF_UP; else ifflags = ifr.ifr_flags & ~IFF_UP; @@ -654,14 +654,14 @@ cleanup: /** * virNetDevIsOnline: * @ifname: the interface name - * @up: where to store the status + * @online: where to store the status * - * Function to query if an interface is activated (1) or not (0) + * Function to query if an interface is activated (true) or not (false) * * Returns 0 in case of success or an errno code in case of failure. */ int virNetDevIsOnline(const char *ifname, - int *up) + bool *online) { int fd = -1; int ret = -1; @@ -677,7 +677,7 @@ int virNetDevIsOnline(const char *ifname, goto cleanup; } -*up = (ifr.ifr_flags & IFF_UP) ? 1 : 0; +*online = (ifr.ifr_flags & IFF_UP) ? true : false; ret = 0; cleanup: @@ -809,7 +809,7 @@ cleanup: * Returns 0 in case of success or -1 on failure */ int virNetDevBridgeSetSTP(const char *brname, - int enable) + bool enable) { virCommandPtr cmd; int ret = -1; diff --git a/src/util/bridge.h b/src/util/bridge.h index 44b6631..2de7259 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -76,10 +76,10 @@ int virNetDevTapDelete(const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevSetOnline(const char *ifname, - int up) + bool online) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevIsOnline(const char *ifname, - int *up) + bool *online) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevSetIPv4Addres(const char *ifname, @@ -98,10 +98,10 @@ int virNetDevBridgeGetSTPDelay(const char *brname, int *delay) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevBridgeSetSTP(const char *brname, - int enable) + bool enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevBridgeGetSTP(const char *brname, - int *enable) + bool *enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevTapCreate(char **ifname, -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 07/33] Remove usage of brctl command line tool
From: "Daniel P. Berrange" Convert the virNetDevBridgeSetSTP and virNetDevBridgeSetSTPDelay to use ioctls instead of spawning brctl. Implement the virNetDevBridgeGetSTP and virNetDevBridgeGetSTPDelay methods which were declared in the header but never existed * src/util/bridge.c: Convert to use bridge ioctls instead of brctl --- configure.ac |2 - libvirt.spec.in |2 - src/util/bridge.c | 199 + 3 files changed, 184 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index 5753c08..0ce020d 100644 --- a/configure.ac +++ b/configure.ac @@ -197,8 +197,6 @@ AC_DEFINE_UNQUOTED([DNSMASQ],["$DNSMASQ"], [Location or name of the dnsmasq program]) AC_DEFINE_UNQUOTED([RADVD],["$RADVD"], [Location or name of the radvd program]) -AC_DEFINE_UNQUOTED([BRCTL],["$BRCTL"], -[Location or name of the brctl program (see bridge-utils)]) AC_DEFINE_UNQUOTED([TC],["$TC"], [Location or name of the tc profram (see iproute2)]) if test -n "$UDEVADM"; then diff --git a/libvirt.spec.in b/libvirt.spec.in index 261f34c..eda0bcc 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -251,7 +251,6 @@ Requires: %{name}-client = %{version}-%{release} # Used by many of the drivers, so turn it on whenever the # daemon is present %if %{with_libvirtd} -Requires: bridge-utils # for modprobe of pci devices Requires: module-init-tools # for /sbin/ip & /sbin/tc @@ -380,7 +379,6 @@ BuildRequires: radvd %if %{with_nwfilter} BuildRequires: ebtables %endif -BuildRequires: bridge-utils BuildRequires: module-init-tools %if %{with_sasl} BuildRequires: cyrus-sasl-devel diff --git a/src/util/bridge.c b/src/util/bridge.c index 3a7012c..0265e81 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -52,6 +52,7 @@ # include "logging.h" # include "network.h" # include "virterror_internal.h" +# include "intprops.h" # define JIFFIES_TO_MS(j) (((j)*1000)/HZ) # define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) @@ -99,6 +100,112 @@ static int virNetDevSetupControl(const char *ifname, return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); } +# define SYSFS_NET_DIR "/sys/class/net" +/* + * Bridge parameters can be set via sysfs on newish kernels, + * or by ioctl on older kernels. Perhaps we could just use + * ioctl for every kernel, but its not clear what the long + * term lifespan of the ioctl interface is... + */ +static int virNetDevBridgeSet(const char *brname, + const char *paramname, /* sysfs param name */ + unsigned long value,/* new value */ + int fd, /* control socket */ + struct ifreq *ifr) /* pre-filled bridge name */ +{ +char *path = NULL; +int ret = -1; + +if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname) < 0) { +virReportOOMError(); +return -1; +} + +if (virFileExists(path)) { +char valuestr[INT_BUFSIZE_BOUND(value)]; +snprintf(valuestr, sizeof(valuestr), "%lu", value); +if (virFileWriteStr(path, valuestr, 0) < 0) { +virReportSystemError(errno, + _("Unable to set bridge %s %s"), brname, paramname); +goto cleanup; +} +} else { +unsigned long paramid; +if (STREQ(paramname, "stp_state")) { +paramid = BRCTL_SET_BRIDGE_STP_STATE; +} else if (STREQ(paramname, "forward_delay")) { +paramid = BRCTL_SET_BRIDGE_FORWARD_DELAY; +} else { +virReportSystemError(EINVAL, + _("Unable to set bridge %s %s"), brname, paramname); +goto cleanup; +} +unsigned long args[] = { paramid, value, 0, 0 }; +ifr->ifr_data = (char*)&args; +if (ioctl(fd, SIOCDEVPRIVATE, ifr) < 0) { +virReportSystemError(errno, + _("Unable to set bridge %s %s"), brname, paramname); +goto cleanup; +} +} + +ret = 0; +cleanup: +VIR_FREE(path); +return ret; +} + + +static int virNetDevBridgeGet(const char *brname, + const char *paramname, /* sysfs param name */ + unsigned long *value, /* current value */ + int fd, /* control socket */ + struct ifreq *ifr) /* pre-filled bridge name */ +{ +char *path = NULL; +int ret = -1; + +if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname) < 0) { +virReportOOMError(); +return -1; +} + +if (virFileExists(path)) { +char *valuestr; +if (virFileReadAll(path, INT_BUFSIZE_BOUND(unsigned long), &valuestr) < 0) +goto cleanup; + +if (virStrToLong_ul(valuestr, NULL, 10, v
[libvirt] [PATCH 22/33] Move the low level macvlan creation APIs
From: "Daniel P. Berrange" Move the low level macvlan creation APIs into the virnetdevmacvlan.c file where they more naturally belong * util/interface.c, util/interface.h: Remove virNetDevMacVLanCreate and virNetDevMacVLanDelete * util/virnetdevmacvlan.c, util/virnetdevmacvlan.h: Add virNetDevMacVLanCreate and virNetDevMacVLanDelete --- src/util/interface.c| 270 --- src/util/interface.h| 12 -- src/util/virnetdevmacvlan.c | 254 - src/util/virnetdevmacvlan.h | 12 ++ 4 files changed, 263 insertions(+), 285 deletions(-) diff --git a/src/util/interface.c b/src/util/interface.c index a1c56f5..e757c6f 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -312,276 +312,6 @@ ifaceGetIPAddress(const char *ifname ATTRIBUTE_UNUSED, #endif /* __linux__ */ -/** - * virNetDevMacVLanCreate: - * - * @ifname: The name the interface is supposed to have; optional parameter - * @type: The type of device, i.e., "macvtap" - * @macaddress: The MAC address of the device - * @srcdev: The name of the 'link' device - * @macvlan_mode: The macvlan mode to use - * @retry: Pointer to integer that will be '1' upon return if an interface - * with the same name already exists and it is worth to try - * again with a different name - * - * Create a macvtap device with the given properties. - * - * Returns 0 on success, -1 on fatal error. - */ -#if defined(__linux__) && WITH_MACVTAP -int -virNetDevMacVLanCreate(const char *ifname, - const char *type, - const unsigned char *macaddress, - const char *srcdev, - uint32_t macvlan_mode, - int *retry) -{ -int rc = 0; -struct nlmsghdr *resp; -struct nlmsgerr *err; -struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC }; -int ifindex; -unsigned char *recvbuf = NULL; -unsigned int recvbuflen; -struct nl_msg *nl_msg; -struct nlattr *linkinfo, *info_data; - -if (ifaceGetIndex(true, srcdev, &ifindex) < 0) -return -1; - -*retry = 0; - -nl_msg = nlmsg_alloc_simple(RTM_NEWLINK, -NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); -if (!nl_msg) { -virReportOOMError(); -return -1; -} - -if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) -goto buffer_too_small; - -if (nla_put_u32(nl_msg, IFLA_LINK, ifindex) < 0) -goto buffer_too_small; - -if (nla_put(nl_msg, IFLA_ADDRESS, VIR_MAC_BUFLEN, macaddress) < 0) -goto buffer_too_small; - -if (ifname && -nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) -goto buffer_too_small; - -if (!(linkinfo = nla_nest_start(nl_msg, IFLA_LINKINFO))) -goto buffer_too_small; - -if (nla_put(nl_msg, IFLA_INFO_KIND, strlen(type), type) < 0) -goto buffer_too_small; - -if (macvlan_mode > 0) { -if (!(info_data = nla_nest_start(nl_msg, IFLA_INFO_DATA))) -goto buffer_too_small; - -if (nla_put(nl_msg, IFLA_MACVLAN_MODE, sizeof(macvlan_mode), -&macvlan_mode) < 0) -goto buffer_too_small; - -nla_nest_end(nl_msg, info_data); -} - -nla_nest_end(nl_msg, linkinfo); - -if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) { -rc = -1; -goto cleanup; -} - -if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL) -goto malformed_resp; - -resp = (struct nlmsghdr *)recvbuf; - -switch (resp->nlmsg_type) { -case NLMSG_ERROR: -err = (struct nlmsgerr *)NLMSG_DATA(resp); -if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) -goto malformed_resp; - -switch (err->error) { - -case 0: -break; - -case -EEXIST: -*retry = 1; -rc = -1; -break; - -default: -virReportSystemError(-err->error, - _("error creating %s type of interface"), - type); -rc = -1; -} -break; - -case NLMSG_DONE: -break; - -default: -goto malformed_resp; -} - -cleanup: -nlmsg_free(nl_msg); - -VIR_FREE(recvbuf); - -return rc; - -malformed_resp: -nlmsg_free(nl_msg); - -ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("malformed netlink response message")); -VIR_FREE(recvbuf); -return -1; - -buffer_too_small: -nlmsg_free(nl_msg); - -ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("allocated netlink buffer is too small")); -return -1; -} - -#else - -int virNetDevMacVLanCreate(const char *ifname ATTRIBUTE_UNUSED, - const char *type ATTRIBUTE_UNUSED, - const unsigned char *macaddress ATTRIBUTE_UNUSED, - const ch
[libvirt] [PATCH 16/33] Remove ifaceUp, ifaceDown, ifaceCtrl & ifaceIsUp APIs
From: "Daniel P. Berrange" The ifaceUp, ifaceDown, ifaceCtrl & ifaceIsUp APIs can be replaced with calls to virNetDevSetOnline and virNetDevIsOnline * src/util/interface.c, src/util/interface.h: Delete ifaceUp, ifaceDown, ifaceCtrl & ifaceIsUp * src/nwfilter/nwfilter_gentech_driver.c, src/util/macvtap.c: Update to use virNetDevSetOnline and virNetDevIsOnline --- src/libvirt_private.syms |3 - src/nwfilter/nwfilter_gentech_driver.c |4 +- src/util/interface.c | 150 src/util/interface.h | 12 --- src/util/macvtap.c | 18 ++-- 5 files changed, 10 insertions(+), 177 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4bc9217..a88b806 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -576,8 +576,6 @@ virHookPresent; # interface.h ifaceCheck; -ifaceCtrl; -ifaceGetFlags; ifaceGetIndex; ifaceGetMacAddress; ifaceGetIPAddress; @@ -585,7 +583,6 @@ ifaceGetNthParent; ifaceGetPhysicalFunction; ifaceGetVirtualFunctionIndex; ifaceGetVlanID; -ifaceIsUp; ifaceIsVirtualFunction; ifaceLinkDel; ifaceMacvtapLinkAdd; diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 7891983..899bd32 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -34,7 +34,7 @@ #include "nwfilter_gentech_driver.h" #include "nwfilter_ebiptables_driver.h" #include "nwfilter_learnipaddr.h" - +#include "virnetdev.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER @@ -963,7 +963,7 @@ virNWFilterInstantiateFilterLate(virConnectPtr conn, if (rc) { /* something went wrong... 'DOWN' the interface */ if ((ifaceCheck(false, ifname, NULL, ifindex) < 0) || -(ifaceDown(ifname) < 0)) { +(virNetDevSetOnline(ifname, false) < 0)) { /* assuming interface disappeared... */ _virNWFilterTeardownFilter(ifname); } diff --git a/src/util/interface.c b/src/util/interface.c index 12bf7bc..913beb5 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -54,156 +54,6 @@ virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) -#if __linux__ -static int -getFlags(int fd, const char *ifname, struct ifreq *ifr) { - -memset(ifr, 0, sizeof(*ifr)); - -if (virStrncpy(ifr->ifr_name, - ifname, strlen(ifname), sizeof(ifr->ifr_name)) == NULL) -return -ENODEV; - -if (ioctl(fd, SIOCGIFFLAGS, ifr) < 0) -return -errno; - -return 0; -} - - -/** - * ifaceGetFlags - * - * @ifname : name of the interface - * @flags : pointer to short holding the flags on success - * - * Get the flags of the interface. Returns 0 on success, -errno on failure. - */ -int -ifaceGetFlags(const char *ifname, short *flags) { -struct ifreq ifr; -int rc; -int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - -if (fd < 0) -return -errno; - -rc = getFlags(fd, ifname, &ifr); - -*flags = ifr.ifr_flags; - -VIR_FORCE_CLOSE(fd); - -return rc; -} - - -int -ifaceIsUp(const char *ifname, bool *up) { -short flags = 0; -int rc = ifaceGetFlags(ifname, &flags); - -if (rc < 0) -return rc; - -*up = ((flags & IFF_UP) == IFF_UP); - -return 0; -} -#else - -/* Note: Showstopper on cygwin is only missing PF_PACKET */ - -int - -ifaceGetFlags(const char *ifname ATTRIBUTE_UNUSED, - short *flags ATTRIBUTE_UNUSED) { -ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ifaceGetFlags is not supported on non-linux platforms")); -return -ENOSYS; -} - -int -ifaceIsUp(const char *ifname ATTRIBUTE_UNUSED, - bool *up ATTRIBUTE_UNUSED) { - -ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ifaceIsUp is not supported on non-linux platforms")); -return -ENOSYS; -} - -#endif /* __linux__ */ - -/* - * chgIfaceFlags: Change flags on an interface - * - * @ifname : name of the interface - * @flagclear : the flags to clear - * @flagset : the flags to set - * - * The new flags of the interface will be calculated as - * flagmask = (~0 ^ flagclear) - * newflags = (curflags & flagmask) | flagset; - * - * Returns 0 on success, -errno on failure. - */ -#ifdef __linux__ -static int chgIfaceFlags(const char *ifname, short flagclear, short flagset) { -struct ifreq ifr; -int rc = 0; -short flags; -short flagmask = (~0 ^ flagclear); -int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - -if (fd < 0) -return -errno; - -rc = getFlags(fd, ifname, &ifr); -if (rc < 0) -goto cleanup; - -flags = (ifr.ifr_flags & flagmask) | flagset; - -if (ifr.ifr_flags != flags) { -ifr.ifr_flags = flags; - -if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) -rc = -errno; -} - -cleanup: -VIR_FORCE_CLOSE(fd); -return rc; -} -
[libvirt] [PATCH 28/33] Move virNetDevGetIPv4Address to virnetdev.c
From: "Daniel P. Berrange" Move the virNetDevGetIPv4Address function to virnetdev.c * util/interface.c, util/interface.h: Remove virNetDevGetIPv4Address * util/virnetdev.c, util/virnetdev.h: Add virNetDevGetIPv4Address --- src/util/interface.c | 63 -- src/util/interface.h |3 -- src/util/virnetdev.c | 53 ++ src/util/virnetdev.h |2 + 4 files changed, 55 insertions(+), 66 deletions(-) diff --git a/src/util/interface.c b/src/util/interface.c index 4e1ee25..e86d183 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -141,69 +141,6 @@ ifaceCheck(bool reportError ATTRIBUTE_UNUSED, #endif /* __linux__ */ -/** - * virNetDevGetIPv4Address: - * @ifname: name of the interface whose IP address we want - * @addr: filled with the IPv4 address - * - * This function gets the IPv4 address for the interface @ifname - * and stores it in @addr - * - * Returns 0 on success, -errno on failure. - */ -#ifdef __linux__ -int virNetDevGetIPv4Address(const char *ifname, -virSocketAddrPtr addr) -{ -struct ifreq ifr; -int fd; -int rc = 0; - -memset (addr, 0, sizeof(*addr)); -addr->data.stor.ss_family = AF_UNSPEC; - -fd = socket(AF_INET, SOCK_STREAM, 0); -if (fd < 0) { -virReportSystemError(errno, "%s", - _("Unable to open control socket")); -return -1; -} - -memset(&ifr, 0, sizeof(struct ifreq)); -if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { -virReportSystemError(ERANGE, - _("invalid interface name %s"), - ifname); -goto cleanup; -} - -if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { -virReportSystemError(errno, - _("Unable to get IPv4 address for interface %s"), ifname); -goto cleanup; -} - -addr->data.stor.ss_family = AF_INET; -addr->len = sizeof(addr->data.inet4); -memcpy(&addr->data.inet4, &ifr.ifr_addr, addr->len); - -cleanup: -VIR_FORCE_CLOSE(fd); -return rc; -} - -#else - -int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED, -virSocketAddrPtr addr ATTRIBUTE_UNUSED) -{ -virReportSystemError(ENOSYS, "%s", - _("Unable to get IPv4 address on this platform")); -return -1; -} - -#endif /* __linux__ */ - #if defined(__linux__) && defined(IFLA_PORT_MAX) diff --git a/src/util/interface.h b/src/util/interface.h index 0a11ecd..afe417d 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -33,9 +33,6 @@ struct nlattr; int ifaceCheck(bool reportError, const char *ifname, const unsigned char *macaddr, int ifindex); -int virNetDevGetIPv4Address(const char *ifname, virSocketAddrPtr addr) -ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, struct nlattr **tb, unsigned char **recvbuf, uint32_t (*getPidFunc)(void)); diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index b25235a..b272d31 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -803,3 +803,56 @@ cleanup: virCommandFree(cmd); return ret; } + + +/** + * virNetDevGetIPv4Address: + * @ifname: name of the interface whose IP address we want + * @addr: filled with the IPv4 address + * + * This function gets the IPv4 address for the interface @ifname + * and stores it in @addr + * + * Returns 0 on success, -errno on failure. + */ +#ifdef __linux__ +int virNetDevGetIPv4Address(const char *ifname, +virSocketAddrPtr addr) +{ +int fd = -1; +int ret = -1; +struct ifreq ifr; + +memset(addr, 0, sizeof(*addr)); +addr->data.stor.ss_family = AF_UNSPEC; + +if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) +return -1; + +if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { +virReportSystemError(errno, + _("Unable to get IPv4 address for interface %s"), ifname); +goto cleanup; +} + +addr->data.stor.ss_family = AF_INET; +addr->len = sizeof(addr->data.inet4); +memcpy(&addr->data.inet4, &ifr.ifr_addr, addr->len); +ret = 0; + +cleanup: +VIR_FORCE_CLOSE(fd); +return ret; +} + +#else + +int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED, +virSocketAddrPtr addr ATTRIBUTE_UNUSED) +{ +virReportSystemError(ENOSYS, "%s", + _("Unable to get IPv4 address on this platform")); +return -1; +} + +#endif /* __linux__ */ diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index c89516c..70ac1a3 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -43,6 +43,8 @@ int virNetDevClearIPv4Address(const char *ifname,
[libvirt] [PATCH 06/33] Add an API for retrieving the MAC address of an interface
From: "Daniel P. Berrange" * src/util/bridge.c, src/util/bridge.h: Add virNetDevGetMAC --- src/util/bridge.c | 35 +++ src/util/bridge.h |3 +++ 2 files changed, 38 insertions(+), 0 deletions(-) diff --git a/src/util/bridge.c b/src/util/bridge.c index 247ce93..3a7012c 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -358,6 +358,41 @@ cleanup: } /** + * virNetDevGetMAC: + * @ifname: interface name to set MTU for + * @macaddr: MAC address (VIR_MAC_BUFLEN in size) + * + * This function gets the @macaddr for a given interface @ifname. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevGetMAC(const char *ifname, +unsigned char *macaddr) +{ +int fd = -1; +int ret = -1; +struct ifreq ifr; + +if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) +return -1; + +if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { +virReportSystemError(errno, + _("Cannot get interface MAC on '%s'"), + ifname); +goto cleanup; +} + +memcpy(macaddr, ifr.ifr_hwaddr.sa_data, VIR_MAC_BUFLEN); + +ret = 0; + +cleanup: +VIR_FORCE_CLOSE(fd); +return ret; +} + +/** * virNetDevGetMTU: * @ifname: interface name get MTU for * diff --git a/src/util/bridge.h b/src/util/bridge.h index 0cc89c0..7504925 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -112,6 +112,9 @@ int virNetDevTapCreate(char **ifname, int virNetDevSetMAC(const char *ifname, const unsigned char *macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMAC(const char *ifname, +unsigned char *macaddr) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevSetMTU(const char *ifname, int mtu) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 15/33] Move LXC veth.c code into shared utility APIs
From: "Daniel P. Berrange" Move the virNetDevSetName and virNetDevSetNamespace APIs out of LXC's veth.c and into virnetdev.c. Move the remaining content of the file to src/util/virnetdevveth.c * src/lxc/veth.c: Rename to src/util/virnetdevveth.c * src/lxc/veth.h: Rename to src/util/virnetdevveth.h * src/util/virnetdev.c, src/util/virnetdev.h: Add virNetDevSetName and virNetDevSetNamespace * src/lxc/lxc_container.c, src/lxc/lxc_controller.c, src/lxc/lxc_driver.c: Update include paths --- src/Makefile.am |7 +- src/lxc/lxc_container.c |2 +- src/lxc/lxc_controller.c |3 +- src/lxc/lxc_driver.c |2 +- src/lxc/veth.h | 29 - src/util/virnetdev.c | 81 + src/util/virnetdev.h |4 + src/{lxc/veth.c => util/virnetdevveth.c} | 95 + src/util/virnetdevveth.h | 35 +++ 9 files changed, 144 insertions(+), 114 deletions(-) delete mode 100644 src/lxc/veth.h rename src/{lxc/veth.c => util/virnetdevveth.c} (74%) create mode 100644 src/util/virnetdevveth.h diff --git a/src/Makefile.am b/src/Makefile.am index 2faf659..6ffa8c6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -94,6 +94,7 @@ UTIL_SOURCES = \ util/virnetdevbandwidth.h util/virnetdevbandwidth.c \ util/virnetdevbridge.h util/virnetdevbridge.c \ util/virnetdevtap.h util/virnetdevtap.c \ + util/virnetdevveth.h util/virnetdevveth.c \ util/virnetdevvportprofile.h util/virnetdevvportprofile.c \ util/virsocketaddr.h util/virsocketaddr.c @@ -318,14 +319,12 @@ endif LXC_DRIVER_SOURCES = \ lxc/lxc_conf.c lxc/lxc_conf.h \ lxc/lxc_container.c lxc/lxc_container.h \ - lxc/lxc_driver.c lxc/lxc_driver.h \ - lxc/veth.c lxc/veth.h + lxc/lxc_driver.c lxc/lxc_driver.h LXC_CONTROLLER_SOURCES = \ lxc/lxc_conf.c lxc/lxc_conf.h \ lxc/lxc_container.c lxc/lxc_container.h \ - lxc/lxc_controller.c\ - lxc/veth.c lxc/veth.h + lxc/lxc_controller.c SECURITY_DRIVER_APPARMOR_HELPER_SOURCES = \ security/virt-aa-helper.c diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 1617117..7163ad8 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -56,7 +56,7 @@ #include "lxc_container.h" #include "util.h" #include "memory.h" -#include "veth.h" +#include "virnetdevveth.h" #include "uuid.h" #include "virfile.h" #include "command.h" diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index d18055a..d863f38 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -54,7 +54,8 @@ #include "lxc_conf.h" #include "lxc_container.h" -#include "veth.h" +#include "virnetdev.h" +#include "virnetdevveth.h" #include "memory.h" #include "util.h" #include "virfile.h" diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 77ac605..ccb0bbf 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -44,7 +44,7 @@ #include "memory.h" #include "util.h" #include "virnetdevbridge.h" -#include "veth.h" +#include "virnetdevveth.h" #include "nodeinfo.h" #include "uuid.h" #include "stats_linux.h" diff --git a/src/lxc/veth.h b/src/lxc/veth.h deleted file mode 100644 index 4a66098..000 --- a/src/lxc/veth.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * veth.h: Interface to tools for managing veth pairs - * - * Copyright (C) 2010 Red Hat, Inc. - * Copyright IBM Corp. 2008 - * - * See COPYING.LIB for the License of this software - * - * Authors: - * David L. Leskovec - */ - -#ifndef VETH_H -# define VETH_H - -# include -# include "internal.h" - -/* Function declarations */ -int virNetDevVethCreate(char **veth1, char **veth2) -ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevVethDelete(const char *veth) -ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevSetNamespace(const char *ifname, int pidInNs) -ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevSetName(const char *ifname, const char *newifname) -ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -#endif /* VETH_H */ diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index c9fb6a1..5311ae7 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -332,6 +332,87 @@ int virNetDevSetMTUFromDevice(const char *ifname, } +/** + * virNetDevSetNamespace: + * @ifname: name of device + * @pidInNs: PID of process in tar
[libvirt] [PATCH 09/33] Santize naming of socket address APIs
From: "Daniel P. Berrange" The socket address APIs in src/util/network.h either take the form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr. Sanitize this so everything is virSocketAddr, and ensure that the virSocketAddr parameter is always the first one. * src/util/network.c, src/util/network.h: Santize socket address API naming * src/conf/domain_conf.c, src/conf/network_conf.c, src/conf/nwfilter_conf.c, src/network/bridge_driver.c, src/nwfilter/nwfilter_ebiptables_driver.c, src/nwfilter/nwfilter_learnipaddr.c, src/qemu/qemu_command.c, src/rpc/virnetsocket.c, src/util/dnsmasq.c, src/util/iptables.c, src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for API renaming --- src/conf/domain_conf.c| 12 ++-- src/conf/network_conf.c | 66 ++-- src/conf/nwfilter_conf.c | 16 ++--- src/libvirt_private.syms | 18 +++--- src/network/bridge_driver.c | 42 +++--- src/nwfilter/nwfilter_ebiptables_driver.c |4 +- src/nwfilter/nwfilter_learnipaddr.c |2 +- src/qemu/qemu_command.c |4 +- src/rpc/virnetsocket.c|6 +- src/util/dnsmasq.c|4 +- src/util/iptables.c | 20 +++--- src/util/network.c| 93 ++--- src/util/network.h| 46 +++--- src/util/virnetdev.c |8 +- src/vbox/vbox_tmpl.c | 10 ++-- tests/sockettest.c| 20 +++--- tests/virnetsockettest.c |1 + tests/virnettlscontexttest.c |6 +- 18 files changed, 188 insertions(+), 190 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 238edfd..2b235c8 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3685,7 +3685,7 @@ virDomainChrDefParseTargetXML(virCapsPtr caps, goto error; } -if (virSocketParseAddr(addrStr, def->target.addr, AF_UNSPEC) < 0) +if (virSocketAddrParse(def->target.addr, addrStr, AF_UNSPEC) < 0) goto error; if (def->target.addr->data.stor.ss_family != AF_INET) { @@ -3709,7 +3709,7 @@ virDomainChrDefParseTargetXML(virCapsPtr caps, goto error; } -virSocketSetPort(def->target.addr, port); +virSocketAddrSetPort(def->target.addr, port); break; case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO: @@ -8378,8 +8378,8 @@ static bool virDomainChannelDefCheckABIStability(virDomainChrDefPtr src, case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: if (memcmp(src->target.addr, dst->target.addr, sizeof(*src->target.addr)) != 0) { -char *saddr = virSocketFormatAddrFull(src->target.addr, true, ":"); -char *daddr = virSocketFormatAddrFull(dst->target.addr, true, ":"); +char *saddr = virSocketAddrFormatFull(src->target.addr, true, ":"); +char *daddr = virSocketAddrFormatFull(dst->target.addr, true, ":"); virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target channel addr %s does not match source %s"), NULLSTR(daddr), NULLSTR(saddr)); @@ -10034,14 +10034,14 @@ virDomainChrDefFormat(virBufferPtr buf, switch (def->targetType) { case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: { -int port = virSocketGetPort(def->target.addr); +int port = virSocketAddrGetPort(def->target.addr); if (port < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to format guestfwd port")); return -1; } -const char *addr = virSocketFormatAddr(def->target.addr); +const char *addr = virSocketAddrFormat(def->target.addr); if (addr == NULL) return -1; diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index f7369e8..8dca618 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -286,7 +286,7 @@ virNetworkDefGetIpByIndex(const virNetworkDefPtr def, /* find the nth ip of type "family" */ for (ii = 0; ii < def->nips; ii++) { -if (VIR_SOCKET_IS_FAMILY(&def->ips[ii].address, family) +if (VIR_SOCKET_ADDR_IS_FAMILY(&def->ips[ii].address, family) && (n-- <= 0)) { return &def->ips[ii]; } @@ -302,9 +302,9 @@ int virNetworkIpDefPrefix(const virNetworkIpDefPtr def) { if (def->prefix > 0) { return def->prefix; -} else if (VIR_SOCKET_HAS_ADDR(&def->netmask)) { -return virSocketGetNumNetmaskBits(&def->netmask); -} else if (VIR_SOCKET_IS_FAMILY(&def->address, AF_INET)) { +} el
[libvirt] [PATCH 02/33] Make all brXXX APIs raise errors, instead of returning errnos
From: "Daniel P. Berrange" Currently every caller of the brXXX APIs has to store the returned errno value and then raise an error message. This results in inconsistent error messages across drivers, additional burden on the callers and makes the error reporting inaccurate since it is hard to distinguish different scenarios from 1 errno value. * src/util/bridge.c: Raise errors instead of returning errnos * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/uml/uml_conf.c, src/uml/uml_driver.c: Remove error reporting code --- po/POTFILES.in |1 + src/lxc/lxc_driver.c|7 +- src/network/bridge_driver.c | 78 +++--- src/qemu/qemu_command.c | 23 + src/uml/uml_conf.c | 28 +- src/uml/uml_driver.c| 14 +-- src/util/bridge.c | 262 +-- 7 files changed, 196 insertions(+), 217 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 5ce35ae..bd1d7bd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -102,6 +102,7 @@ src/test/test_driver.c src/uml/uml_conf.c src/uml/uml_driver.c src/util/authhelper.c +src/util/bridge.c src/util/cgroup.c src/util/command.c src/util/conf.c diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 2505efc..8ee1306 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1194,7 +1194,6 @@ static int lxcSetupInterfaces(virConnectPtr conn, { int rc = -1, i; char *bridge = NULL; -int ret; for (i = 0 ; i < def->nnets ; i++) { char *parentVeth; @@ -1270,12 +1269,8 @@ static int lxcSetupInterfaces(virConnectPtr conn, goto error_exit; } -if ((ret = brAddInterface(bridge, parentVeth)) != 0) { -virReportSystemError(ret, - _("Failed to add %s device to %s"), - parentVeth, bridge); +if (brAddInterface(bridge, parentVeth) < 0) goto error_exit; -} if (vethInterfaceUpOrDown(parentVeth, 1) < 0) goto error_exit; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 053acfd..d5d2472 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -1678,12 +1678,8 @@ networkAddAddrToBridge(virNetworkObjPtr network, } if (brAddInetAddress(network->def->bridge, - &ipdef->address, prefix) < 0) { -networkReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot set IP address on bridge '%s'"), - network->def->bridge); + &ipdef->address, prefix) < 0) return -1; -} return 0; } @@ -1692,7 +1688,7 @@ static int networkStartNetworkVirtual(struct network_driver *driver, virNetworkObjPtr network) { -int ii, err; +int ii; bool v4present = false, v6present = false; virErrorPtr save_err = NULL; virNetworkIpDefPtr ipdef; @@ -1703,12 +1699,8 @@ networkStartNetworkVirtual(struct network_driver *driver, return -1; /* Create and configure the bridge device */ -if ((err = brAddBridge(network->def->bridge))) { -virReportSystemError(err, - _("cannot create bridge '%s'"), - network->def->bridge); +if (brAddBridge(network->def->bridge) < 0) return -1; -} if (network->def->mac_specified) { /* To set a mac for the bridge, we need to define a dummy tap @@ -1722,12 +1714,8 @@ networkStartNetworkVirtual(struct network_driver *driver, virReportOOMError(); goto err0; } -if ((err = brAddTap(network->def->bridge, -&macTapIfName, network->def->mac, 0, false, NULL))) { -virReportSystemError(err, - _("cannot create dummy tap device '%s' to set mac" - " address on bridge '%s'"), - macTapIfName, network->def->bridge); +if (brAddTap(network->def->bridge, + &macTapIfName, network->def->mac, 0, false, NULL) < 0) { VIR_FREE(macTapIfName); goto err0; } @@ -1735,20 +1723,12 @@ networkStartNetworkVirtual(struct network_driver *driver, /* Set bridge options */ if (brSetForwardDelay(network->def->bridge, - network->def->delay)) { -networkReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot set forward delay on bridge '%s'"), - network->def->bridge); + network->def->delay) < 0) goto err1; -} if (brSetEnableSTP(network->def->bridge, - network->def->stp ? 1 : 0)) { -networkReportError(VIR_ERR_INTERNAL_ERROR, - _("c
[libvirt] [PATCH 01/33] Remove 'brControl' object
From: "Daniel P. Berrange" The bridge management APIs in src/util/bridge.c require a brControl object to be passed around. This holds the file descriptor for the control socket. This extra object complicates use of the API for only a minor efficiency gain, which is in turn entirely offset by the need to fork/exec the brctl command for STP configuration. This patch removes the 'brControl' object entirely, instead opening the control socket & closing it again within the scope of each method. The parameter names for the APIs are also made to consistently use 'brname' for bridge device name, and 'ifname' for an interface device name. Finally annotations are added for non-NULL parameters and return check validation * src/util/bridge.c, src/util/bridge.h: Remove brControl object and update API parameter names & annotations. * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/uml/uml_conf.h, src/uml/uml_conf.c, src/uml/uml_driver.c, src/qemu/qemu_command.c, src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Remove reference to 'brControl' object --- src/lxc/lxc_driver.c| 10 +- src/network/bridge_driver.c | 41 ++--- src/qemu/qemu_command.c |8 +- src/qemu/qemu_conf.h|1 - src/qemu/qemu_driver.c |3 - src/uml/uml_conf.c | 13 +-- src/uml/uml_conf.h |1 - src/uml/uml_driver.c|9 +- src/util/bridge.c | 454 +-- src/util/bridge.h | 104 +- 10 files changed, 295 insertions(+), 349 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index d6e5e20..2505efc 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1194,15 +1194,8 @@ static int lxcSetupInterfaces(virConnectPtr conn, { int rc = -1, i; char *bridge = NULL; -brControl *brctl = NULL; int ret; -if ((ret = brInit(&brctl)) != 0) { -virReportSystemError(ret, "%s", - _("Unable to initialize bridging")); -return -1; -} - for (i = 0 ; i < def->nnets ; i++) { char *parentVeth; char *containerVeth = NULL; @@ -1277,7 +1270,7 @@ static int lxcSetupInterfaces(virConnectPtr conn, goto error_exit; } -if ((ret = brAddInterface(brctl, bridge, parentVeth)) != 0) { +if ((ret = brAddInterface(bridge, parentVeth)) != 0) { virReportSystemError(ret, _("Failed to add %s device to %s"), parentVeth, bridge); @@ -1303,7 +1296,6 @@ static int lxcSetupInterfaces(virConnectPtr conn, rc = 0; error_exit: -brShutdown(brctl); if (rc != 0) { for (i = 0 ; i < def->nnets ; i++) networkReleaseActualDevice(def->nets[i]); diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 445c3cb..053acfd 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -82,7 +82,6 @@ struct network_driver { virNetworkObjList networks; iptablesContext *iptables; -brControl *brctl; char *networkConfigDir; char *networkAutostartDir; char *logDir; @@ -212,7 +211,7 @@ networkFindActiveConfigs(struct network_driver *driver) { /* If bridge exists, then mark it active */ if (obj->def->bridge && -brHasBridge(driver->brctl, obj->def->bridge) == 0) { +brHasBridge(obj->def->bridge) == 0) { obj->active = 1; /* Try and read dnsmasq/radvd pids if any */ @@ -263,7 +262,6 @@ static int networkStartup(int privileged) { uid_t uid = geteuid(); char *base = NULL; -int err; if (VIR_ALLOC(driverState) < 0) goto error; @@ -312,12 +310,6 @@ networkStartup(int privileged) { VIR_FREE(base); -if ((err = brInit(&driverState->brctl))) { -virReportSystemError(err, "%s", - _("cannot initialize bridge support")); -goto error; -} - if (!(driverState->iptables = iptablesContextNew())) { goto out_of_memory; } @@ -416,8 +408,6 @@ networkShutdown(void) { VIR_FREE(driverState->networkConfigDir); VIR_FREE(driverState->networkAutostartDir); -if (driverState->brctl) -brShutdown(driverState->brctl); if (driverState->iptables) iptablesContextFree(driverState->iptables); @@ -1675,8 +1665,7 @@ out: } static int -networkAddAddrToBridge(struct network_driver *driver, - virNetworkObjPtr network, +networkAddAddrToBridge(virNetworkObjPtr network, virNetworkIpDefPtr ipdef) { int prefix = virNetworkIpDefPrefix(ipdef); @@ -1688,7 +1677,7 @@ networkAddAddrToBridge(struct network_driver *driver, return -1; } -if (brAddInetAddress(driver->brctl, network->def->bridge, +if (brAddInetAddress(network->def->bridge, &ipdef->address, prefix) < 0
[libvirt] [PATCH 10/33] Adjust naming of network device bandwidth management APIs
From: "Daniel P. Berrange" Rename virBandwidth to virNetDevBandwidth, and virRate to virNetDevBandwidthRate. * src/util/network.c, src/util/network.h: Rename bandwidth structs and APIs * src/conf/domain_conf.c, src/conf/domain_conf.h, src/conf/network_conf.c, src/conf/network_conf.h, src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/util/macvtap.c, src/util/macvtap.h, tools/virsh.c: Update for API changes. --- src/conf/domain_conf.c | 14 +++--- src/conf/domain_conf.h |6 +- src/conf/network_conf.c | 12 ++-- src/conf/network_conf.h |4 +- src/libvirt_private.syms| 14 +++--- src/lxc/lxc_driver.c|4 +- src/network/bridge_driver.c | 17 ++- src/qemu/qemu_command.c |4 +- src/util/macvtap.c |4 +- src/util/macvtap.h |2 +- src/util/network.c | 115 +- src/util/network.h | 43 +--- tools/virsh.c |4 +- 13 files changed, 110 insertions(+), 133 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2b235c8..ab7853d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -862,7 +862,7 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def) break; } -virBandwidthDefFree(def->bandwidth); +virNetDevBandwidthFree(def->bandwidth); VIR_FREE(def); } @@ -921,7 +921,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def) VIR_FREE(def->filter); virNWFilterHashTableFree(def->filterparams); -virBandwidthDefFree(def->bandwidth); +virNetDevBandwidthFree(def->bandwidth); VIR_FREE(def); } @@ -3120,7 +3120,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node, bandwidth_node = virXPathNode("./bandwidth", ctxt); if (bandwidth_node && -!(actual->bandwidth = virBandwidthDefParseNode(bandwidth_node))) +!(actual->bandwidth = virNetDevBandwidthParse(bandwidth_node))) goto error; *def = actual; @@ -3278,7 +3278,7 @@ virDomainNetDefParseXML(virCapsPtr caps, if (virDomainActualNetDefParseXML(cur, ctxt, &actual) < 0) goto error; } else if (xmlStrEqual(cur->name, BAD_CAST "bandwidth")) { -if (!(def->bandwidth = virBandwidthDefParseNode(cur))) +if (!(def->bandwidth = virNetDevBandwidthParse(cur))) goto error; } } @@ -9729,7 +9729,7 @@ virDomainActualNetDefFormat(virBufferPtr buf, } virBufferAdjustIndent(buf, 8); -if (virBandwidthDefFormat(buf, def->bandwidth) < 0) +if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0) goto error; virBufferAdjustIndent(buf, -8); @@ -9882,7 +9882,7 @@ virDomainNetDefFormat(virBufferPtr buf, virDomainNetInterfaceLinkStateTypeToString(def->linkstate)); virBufferAdjustIndent(buf, 6); -if (virBandwidthDefFormat(buf, def->bandwidth) < 0) +if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0) return -1; virBufferAdjustIndent(buf, -6); @@ -13090,7 +13090,7 @@ virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface) return iface->data.network.actual->data.direct.virtPortProfile; } -virBandwidthPtr +virNetDevBandwidthPtr virDomainNetGetActualBandwidth(virDomainNetDefPtr iface) { if ((iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) && diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 5ebb441..a3cb834 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -511,7 +511,7 @@ struct _virDomainActualNetDef { virVirtualPortProfileParamsPtr virtPortProfile; } direct; } data; -virBandwidthPtr bandwidth; +virNetDevBandwidthPtr bandwidth; }; /* Stores the virtual network interface configuration */ @@ -576,7 +576,7 @@ struct _virDomainNetDef { virDomainDeviceInfo info; char *filter; virNWFilterHashTablePtr filterparams; -virBandwidthPtr bandwidth; +virNetDevBandwidthPtr bandwidth; int linkstate; }; @@ -1797,7 +1797,7 @@ char *virDomainNetGetActualDirectDev(virDomainNetDefPtr iface); int virDomainNetGetActualDirectMode(virDomainNetDefPtr iface); virVirtualPortProfileParamsPtr virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface); -virBandwidthPtr +virNetDevBandwidthPtr virDomainNetGetActualBandwidth(virDomainNetDefPtr iface); int virDomainControllerInsert(virDomainDefPtr def, diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 8dca618..a70b5a2 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -92,7 +92,7 @@ virPortGroupDefClear(virPortGroupDefPtr def) { VIR_FREE(def->name); VIR_FREE(def->virtPortProfile); -virBandwidthDefFree(def->bandwidth); +virNetDevBandwidthFree(def->bandwidth); def->bandwidth = NULL; } @@ -171,7 +171,7 @@ void virNetworkDefFree(
[libvirt] [PATCH 14/33] Rename the LXC veth management APIs and delete duplicated APIs
From: "Daniel P. Berrange" The src/lxc/veth.c file contains APIs for managing veth devices, but some of the APIs duplicate stuff from src/util/virnetdev.h. Delete thed duplicate APIs and rename the remaining ones to follow virNetDevVeth * src/lxc/veth.c, src/lxc/veth.h: Rename APIs & delete duplicates * src/lxc/lxc_container.c, src/lxc/lxc_controller.c, src/lxc/lxc_driver.c: Update for API renaming --- po/POTFILES.in |1 - src/lxc/lxc_container.c |7 ++- src/lxc/lxc_controller.c |4 +- src/lxc/lxc_driver.c | 19 +++- src/lxc/veth.c | 109 - src/lxc/veth.h | 20 +++- 6 files changed, 42 insertions(+), 118 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 1665d2d..810cf68 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -42,7 +42,6 @@ src/lxc/lxc_container.c src/lxc/lxc_conf.c src/lxc/lxc_controller.c src/lxc/lxc_driver.c -src/lxc/veth.c src/libxl/libxl_driver.c src/libxl/libxl_conf.c src/network/bridge_driver.c diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index c4e5f28..1617117 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -60,6 +60,7 @@ #include "uuid.h" #include "virfile.h" #include "command.h" +#include "virnetdev.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -269,12 +270,12 @@ static int lxcContainerRenameAndEnableInterfaces(unsigned int nveths, } VIR_DEBUG("Renaming %s to %s", veths[i], newname); -rc = setInterfaceName(veths[i], newname); +rc = virNetDevSetName(veths[i], newname); if (rc < 0) goto error_out; VIR_DEBUG("Enabling %s", newname); -rc = vethInterfaceUpOrDown(newname, 1); +rc = virNetDevSetOnline(newname, true); if (rc < 0) goto error_out; @@ -283,7 +284,7 @@ static int lxcContainerRenameAndEnableInterfaces(unsigned int nveths, /* enable lo device only if there were other net devices */ if (veths) -rc = vethInterfaceUpOrDown("lo", 1); +rc = virNetDevSetOnline("lo", true); error_out: VIR_FREE(newname); diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 649ac87..d18055a 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -932,7 +932,7 @@ static int lxcControllerMoveInterfaces(unsigned int nveths, { unsigned int i; for (i = 0 ; i < nveths ; i++) -if (moveInterfaceToNetNs(veths[i], container) < 0) +if (virNetDevSetNamespace(veths[i], container) < 0) return -1; return 0; @@ -953,7 +953,7 @@ static int lxcControllerCleanupInterfaces(unsigned int nveths, { unsigned int i; for (i = 0 ; i < nveths ; i++) -vethDelete(veths[i]); +ignore_value(virNetDevVethDelete(veths[i])); return 0; } diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 2c1154f..77ac605 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -55,6 +55,7 @@ #include "domain_audit.h" #include "domain_nwfilter.h" #include "network/bridge_driver.h" +#include "virnetdev.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -1152,8 +1153,8 @@ static void lxcVmCleanup(lxc_driver_t *driver, priv->monitorWatch = -1; for (i = 0 ; i < vm->def->nnets ; i++) { -vethInterfaceUpOrDown(vm->def->nets[i]->ifname, 0); -vethDelete(vm->def->nets[i]->ifname); +ignore_value(virNetDevSetOnline(vm->def->nets[i]->ifname, false)); +ignore_value(virNetDevVethDelete(vm->def->nets[i]->ifname)); networkReleaseActualDevice(vm->def->nets[i]); } @@ -1246,7 +1247,7 @@ static int lxcSetupInterfaces(virConnectPtr conn, VIR_DEBUG("calling vethCreate()"); parentVeth = def->nets[i]->ifname; -if (vethCreate(&parentVeth, &containerVeth) < 0) +if (virNetDevVethCreate(&parentVeth, &containerVeth) < 0) goto error_exit; VIR_DEBUG("parentVeth: %s, containerVeth: %s", parentVeth, containerVeth); @@ -1262,17 +1263,13 @@ static int lxcSetupInterfaces(virConnectPtr conn, (*veths)[(*nveths)] = containerVeth; (*nveths)++; -{ -char macaddr[VIR_MAC_STRING_BUFLEN]; -virFormatMacAddr(def->nets[i]->mac, macaddr); -if (setMacAddr(containerVeth, macaddr) < 0) -goto error_exit; -} +if (virNetDevSetMAC(containerVeth, def->nets[i]->mac) < 0) +goto error_exit; if (virNetDevBridgeAddPort(bridge, parentVeth) < 0) goto error_exit; -if (vethInterfaceUpOrDown(parentVeth, 1) < 0) +if (virNetDevSetOnline(parentVeth, true) < 0) goto error_exit; if (virNetDevBandwidthSet(def->nets[i]->ifname, @@ -1829,7 +1826,7 @@ cleanup: } for (i = 0 ; i < nveths ; i++) { if (rc != 0) -vethDelete(veths[i]); +ignore_value(virNetDevVe
[libvirt] [PATCH 20/33] Rename high level macvlan creation APIs
From: "Daniel P. Berrange" Rename virNetDevMacVLanCreate to virNetDevMacVLanCreateWithVPortProfile and virNetDevMacVLanDelete to virNetDevMacVLanDeleteWithVPortProfile To make way for renaming the other macvlan creation APIs in interface.c * util/virnetdevmacvlan.c, util/virnetdevmacvlan.h, qemu/qemu_command.c, qemu/qemu_hotplug.c, qemu/qemu_process.c: Rename APIs --- src/qemu/qemu_command.c | 28 + src/qemu/qemu_hotplug.c | 11 +++--- src/qemu/qemu_process.c | 11 +++--- src/util/virnetdevmacvlan.c | 72 +- src/util/virnetdevmacvlan.h | 34 ++-- 5 files changed, 80 insertions(+), 76 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 687d284..6df1f83 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -150,14 +150,15 @@ qemuPhysIfaceConnect(virDomainDefPtr def, net->model && STREQ(net->model, "virtio")) vnet_hdr = 1; -rc = virNetDevMacVLanCreate(net->ifname, net->mac, -virDomainNetGetActualDirectDev(net), -virDomainNetGetActualDirectMode(net), -vnet_hdr, def->uuid, - virDomainNetGetActualDirectVirtPortProfile(net), -&res_ifname, -vmop, driver->stateDir, -virDomainNetGetActualBandwidth(net)); +rc = virNetDevMacVLanCreateWithVPortProfile( +net->ifname, net->mac, +virDomainNetGetActualDirectDev(net), +virDomainNetGetActualDirectMode(net), +vnet_hdr, def->uuid, +virDomainNetGetActualDirectVirtPortProfile(net), +&res_ifname, +vmop, driver->stateDir, +virDomainNetGetActualBandwidth(net)); if (rc >= 0) { virDomainAuditNetDevice(def, net, res_ifname, true); VIR_FREE(net->ifname); @@ -177,11 +178,12 @@ qemuPhysIfaceConnect(virDomainDefPtr def, err = virDomainConfNWFilterInstantiate(conn, net); if (err) { VIR_FORCE_CLOSE(rc); -ignore_value(virNetDevMacVLanDelete(net->ifname, net->mac, - virDomainNetGetActualDirectDev(net), - virDomainNetGetActualDirectMode(net), - virDomainNetGetActualDirectVirtPortProfile(net), -driver->stateDir)); +ignore_value(virNetDevMacVLanDeleteWithVPortProfile( + net->ifname, net->mac, + virDomainNetGetActualDirectDev(net), + virDomainNetGetActualDirectMode(net), + virDomainNetGetActualDirectVirtPortProfile(net), + driver->stateDir)); VIR_FREE(net->ifname); } } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index f9365fe..5c64482 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1910,11 +1910,12 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, virDomainConfNWFilterTeardown(detach); if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_DIRECT) { -ignore_value(virNetDevMacVLanDelete(detach->ifname, detach->mac, - virDomainNetGetActualDirectDev(detach), - virDomainNetGetActualDirectMode(detach), - virDomainNetGetActualDirectVirtPortProfile(detach), -driver->stateDir)); +ignore_value(virNetDevMacVLanDeleteWithVPortProfile( + detach->ifname, detach->mac, + virDomainNetGetActualDirectDev(detach), + virDomainNetGetActualDirectMode(detach), + virDomainNetGetActualDirectVirtPortProfile(detach), + driver->stateDir)); VIR_FREE(detach->ifname); } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index f4096f8..04fcdef 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3411,11 +3411,12 @@ void qemuProcessStop(struct qemud_driver *driver, for (i = 0; i < def->nnets; i++) { virDomainNetDefPtr net = def->nets[i]; if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) { -ignore_value(virNetDevMacVLanDelete(net->ifname, net->mac, - virDomainNetGetActualDirectDev(net), - virDomainNetGetActualDirectMode(net), - virDomainNetGetActualDirectVirtPort
[libvirt] [PATCH 26/33] Move virNetDevGetIndex & virNetDevGetVLanID to virnetdev.c
From: "Daniel P. Berrange" Move virNetDevGetIndex & virNetDevGetVLanID to virnetdev.c to suit their functional purpose * util/interface.c, util/interface.h: Remove virNetDevGetIndex & virNetDevGetVLanID * util/virnetdev.c, util/virnetdev.h: Add virNetDevGetIndex & virNetDevGetVLanID --- src/nwfilter/nwfilter_learnipaddr.c |1 + src/util/interface.c| 111 --- src/util/interface.h|6 -- src/util/virnetdev.c| 109 ++ src/util/virnetdev.h|7 ++ 5 files changed, 117 insertions(+), 117 deletions(-) diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 9a51fc2..319f317 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -46,6 +46,7 @@ #include "logging.h" #include "datatypes.h" #include "interface.h" +#include "virnetdev.h" #include "virterror_internal.h" #include "threads.h" #include "conf/nwfilter_params.h" diff --git a/src/util/interface.c b/src/util/interface.c index af1def2..9762145 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -142,117 +142,6 @@ ifaceCheck(bool reportError ATTRIBUTE_UNUSED, /** - * virNetDevGetIndex - * @ifname : Name of the interface whose index is to be found - * @ifindex: Pointer to int where the index will be written into - * - * Get the index of an interface given its name. - * - * Returns 0 on success, -1 on failure - */ -#ifdef __linux__ -int -virNetDevGetIndex(const char *ifname, int *ifindex) -{ -int ret = -1; -struct ifreq ifreq; -int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - -if (fd < 0) { -virReportSystemError(errno, "%s", - _("Unable to open control socket")); -return -1; -} - -memset(&ifreq, 0, sizeof(ifreq)); - -if (virStrncpy(ifreq.ifr_name, ifname, strlen(ifname), - sizeof(ifreq.ifr_name)) == NULL) { -virReportSystemError(ERANGE, - _("invalid interface name %s"), - ifname); -goto cleanup; -} - -if (ioctl(fd, SIOCGIFINDEX, &ifreq) < 0) { -virReportSystemError(errno, - _("Unable to get index for interface %s"), ifname); -goto cleanup; -} - -*ifindex = ifreq.ifr_ifindex; -ret = 0; - -cleanup: -VIR_FORCE_CLOSE(fd); -return ret; -} - -#else - -int -virNetDevGetIndex(const char *ifname ATTRIBUTE_UNUSED, - int *ifindex ATTRIBUTE_UNUSED) -{ -virReportSystemError(ENOSYS, "%s", - _("Unable to get interface index on this platform")); -return -1; -} - -#endif /* __linux__ */ - -#ifdef __linux__ -int -virNetDevGetVLanID(const char *ifname, int *vlanid) -{ -struct vlan_ioctl_args vlanargs = { - .cmd = GET_VLAN_VID_CMD, -}; -int ret = -1; -int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - -if (fd < 0) { -virReportSystemError(errno, "%s", - _("Unable to open control socket")); -return -1; -} - -if (virStrcpyStatic(vlanargs.device1, ifname) == NULL) { -virReportSystemError(ERANGE, - _("invalid interface name %s"), - ifname); -goto cleanup; -} - -if (ioctl(fd, SIOCGIFVLAN, &vlanargs) != 0) { -virReportSystemError(errno, - _("Unable to get VLAN for interface %s"), ifname); -goto cleanup; -} - -*vlanid = vlanargs.u.VID; -ret = 0; - - cleanup: -VIR_FORCE_CLOSE(fd); - -return ret; -} - -#else - -int -virNetDevGetVLanID(const char *ifname ATTRIBUTE_UNUSED, - int *vlanid ATTRIBUTE_UNUSED) -{ -virReportSystemError(ENOSYS, "%s", - _("Unable to get VLAN on this platform")); -return -1; -} -#endif /* __linux__ */ - - -/** * ifaceGetIPAddress: * @ifname: name of the interface whose IP address we want * @macaddr: MAC address (VIR_MAC_BUFLEN in size) diff --git a/src/util/interface.h b/src/util/interface.h index 51d5c28..aa70192 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -33,12 +33,6 @@ struct nlattr; int ifaceCheck(bool reportError, const char *ifname, const unsigned char *macaddr, int ifindex); -int virNetDevGetIndex(const char *ifname, int *ifindex) -ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virNetDevGetVLanID(const char *ifname, int *vlanid) -ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - int ifaceGetIPAddress(const char *ifname, virSocketAddrPtr addr); int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 9674391..b25235a 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -34,6 +34,11 @@ #endif
[libvirt] [PATCH 29/33] Rename ifaceCheck to virNetDevValidateConfig
From: "Daniel P. Berrange" Rename the ifaceCheck method to virNetDevValidateConfig and change so that it always raises an error and returns -1 on error. * src/util/interface.c, src/util/interface.h: Rename ifaceCheck to virNetDevValidateConfig * src/nwfilter/nwfilter_gentech_driver.c, src/nwfilter/nwfilter_learnipaddr.c: Update for API rename --- src/libvirt_private.syms |2 +- src/nwfilter/nwfilter_gentech_driver.c |6 ++- src/nwfilter/nwfilter_learnipaddr.c|6 ++- src/util/interface.c | 83 --- src/util/interface.h |5 +- 5 files changed, 55 insertions(+), 47 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 183e4f5..6b7e231 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -575,7 +575,7 @@ virHookPresent; # interface.h -ifaceCheck; +virNetDevValidateConfig; virNetDevGetIndex; virNetDevGetIPv4Address; ifaceGetNthParent; diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 9f44aef..9dffdc5 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -715,7 +715,8 @@ virNWFilterInstantiate(virConnectPtr conn, if (teardownOld && rc == 0) techdriver->tearOldRules(conn, ifname); -if (rc == 0 && (ifaceCheck(false, ifname, NULL, ifindex) < 0)) { +if (rc == 0 && (virNetDevValidateConfig(ifname, NULL, ifindex) <= 0)) { +virResetLastError(); /* interface changed/disppeared */ techdriver->allTeardown(ifname); rc = 1; @@ -963,8 +964,9 @@ virNWFilterInstantiateFilterLate(virConnectPtr conn, &foundNewFilter); if (rc) { /* something went wrong... 'DOWN' the interface */ -if ((ifaceCheck(false, ifname, NULL, ifindex) < 0) || +if ((virNetDevValidateConfig(ifname, NULL, ifindex) <= 0) || (virNetDevSetOnline(ifname, false) < 0)) { +virResetLastError(); /* assuming interface disappeared... */ _virNWFilterTeardownFilter(ifname); } diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 319f317..03716ea 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -434,7 +434,8 @@ learnIPAddressThread(void *arg) req->status = 0; /* anything change to the VM's interface -- check at least once */ -if (ifaceCheck(false, req->ifname, NULL, req->ifindex) < 0) { +if (virNetDevValidateConfig(req->ifname, NULL, req->ifindex) <= 0) { +virResetLastError(); req->status = ENODEV; goto done; } @@ -504,7 +505,8 @@ learnIPAddressThread(void *arg) } /* check whether VM's dev is still there */ -if (ifaceCheck(false, req->ifname, NULL, req->ifindex) < 0) { +if (virNetDevValidateConfig(req->ifname, NULL, req->ifindex) <= 0) { +virResetLastError(); req->status = ENODEV; showError = false; break; diff --git a/src/util/interface.c b/src/util/interface.c index e86d183..16ad155 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -56,9 +56,7 @@ __FUNCTION__, __LINE__, __VA_ARGS__) /** - * ifaceCheck - * - * @reportError: whether to report errors or keep silent + * virNetDevValidateConfig: * @ifname: Name of the interface * @macaddr: expected MAC address of the interface; not checked if NULL * @ifindex: expected index of the interface; not checked if '-1' @@ -67,78 +65,83 @@ * it must have the given MAC address and if an interface index is * passed, it must also match the interface index. * - * Returns 0 on success, -errno on failure. - * -ENODEV : if interface with given name does not exist or its interface - * index is different than the one passed - * -EINVAL : if interface name is invalid (too long) + * Returns 1 if the config matches, 0 if the config does not match, or interface does not exist, -1 on error */ #ifdef __linux__ -int -ifaceCheck(bool reportError, const char *ifname, - const unsigned char *macaddr, int ifindex) +int virNetDevValidateConfig(const char *ifname, +const unsigned char *macaddr, int ifindex) { -struct ifreq ifr; int fd = -1; -int rc = 0; +int ret = -1; +struct ifreq ifr; int idx; +int rc; + +if ((rc = virNetDevExists(ifname)) < 0) +return -1; +if (rc == 0) { +ret = 0; +goto cleanup; +} if (macaddr != NULL) { fd = socket(PF_PACKET, SOCK_DGRAM, 0); -if (fd < 0) -return -errno; +if (fd < 0) { +virReportSystemError(errno, "%s", + _("Unable to open contro
[libvirt] [PATCH 17/33] Remove ifaceSetMac and ifaceGetMac APIs
From: "Daniel P. Berrange" The ifaceSetMac and ifaceGetMac APIs duplicate the functionality of the virNetDevSetMAC and virNetDevGetMAC APIs, but returning errno's instead of raising errors. * src/util/interface.c, src/util/interface.h: Remove ifaceSetMac and ifaceGetMac APIs, adjusting callers for new error behaviour --- src/libvirt_private.syms |2 - src/util/interface.c | 190 +++--- src/util/interface.h |4 - 3 files changed, 27 insertions(+), 169 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a88b806..52d2076 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -577,7 +577,6 @@ virHookPresent; # interface.h ifaceCheck; ifaceGetIndex; -ifaceGetMacAddress; ifaceGetIPAddress; ifaceGetNthParent; ifaceGetPhysicalFunction; @@ -589,7 +588,6 @@ ifaceMacvtapLinkAdd; ifaceMacvtapLinkDump; ifaceReplaceMacAddress; ifaceRestoreMacAddress; -ifaceSetMacAddress; # interface_conf.h diff --git a/src/util/interface.c b/src/util/interface.c index 913beb5..63e6bf7 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -47,6 +47,7 @@ #include "netlink.h" #include "pci.h" #include "logging.h" +#include "virnetdev.h" #define VIR_FROM_THIS VIR_FROM_NET @@ -251,118 +252,6 @@ ifaceGetVlanID(const char *vlanifname ATTRIBUTE_UNUSED, } #endif /* __linux__ */ -/** - * ifaceGetMacAddress: - * @ifname: interface name to set MTU for - * @macaddr: MAC address (VIR_MAC_BUFLEN in size) - * - * This function gets the @macaddr for a given interface @ifname. - * - * Returns 0 on success, -errno on failure. - */ -#ifdef __linux__ -int -ifaceGetMacAddress(const char *ifname, - unsigned char *macaddr) -{ -struct ifreq ifr; -int fd; -int rc = 0; - -if (!ifname) -return -EINVAL; - -fd = socket(AF_INET, SOCK_STREAM, 0); -if (fd < 0) -return -errno; - -memset(&ifr, 0, sizeof(struct ifreq)); -if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { -rc = -EINVAL; -goto cleanup; -} - -if (ioctl(fd, SIOCGIFHWADDR, (char *)&ifr) != 0) { -rc = -errno; -goto cleanup; -} - -memcpy(macaddr, ifr.ifr_ifru.ifru_hwaddr.sa_data, VIR_MAC_BUFLEN); - -cleanup: -VIR_FORCE_CLOSE(fd); -return rc; -} - -#else - -int -ifaceGetMacAddress(const char *ifname ATTRIBUTE_UNUSED, - unsigned char *macaddr ATTRIBUTE_UNUSED) -{ -return -ENOSYS; -} - -#endif /* __linux__ */ - -/** - * ifaceSetMacAddress: - * @ifname: interface name to set MTU for - * @macaddr: MAC address (VIR_MAC_BUFLEN in size) - * - * This function sets the @macaddr for a given interface @ifname. This - * gets rid of the kernel's automatically assigned random MAC. - * - * Returns 0 on success, -errno on failure. - */ -#ifdef __linux__ -int -ifaceSetMacAddress(const char *ifname, - const unsigned char *macaddr) -{ -struct ifreq ifr; -int fd; -int rc = 0; - -if (!ifname) -return -EINVAL; - -fd = socket(AF_INET, SOCK_STREAM, 0); -if (fd < 0) -return -errno; - -memset(&ifr, 0, sizeof(struct ifreq)); -if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { -rc = -EINVAL; -goto cleanup; -} - -/* To fill ifr.ifr_hdaddr.sa_family field */ -if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0) { -rc = -errno; -goto cleanup; -} - -memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN); - -rc = ioctl(fd, SIOCSIFHWADDR, &ifr) == 0 ? 0 : -errno; - -cleanup: -VIR_FORCE_CLOSE(fd); -return rc; -} - -#else - -int -ifaceSetMacAddress(const char *ifname ATTRIBUTE_UNUSED, - const unsigned char *macaddr ATTRIBUTE_UNUSED) -{ -return -ENOSYS; -} - -#endif /* __linux__ */ - /** * ifaceGetIPAddress: @@ -945,7 +834,7 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, * @linkdev: name of interface * @stateDir: directory to store old MAC address * - * Returns 0 on success, -errno on failure. + * Returns 0 on success, -1 on failure * */ int @@ -954,46 +843,30 @@ ifaceReplaceMacAddress(const unsigned char *macaddress, const char *stateDir) { unsigned char oldmac[6]; -int rc; +char *path = NULL; +char macstr[VIR_MAC_STRING_BUFLEN]; -rc = ifaceGetMacAddress(linkdev, oldmac); - -if (rc < 0) { -virReportSystemError(rc, - _("Getting MAC address from '%s' " - "to '%02x:%02x:%02x:%02x:%02x:%02x' failed."), - linkdev, - oldmac[0], oldmac[1], oldmac[2], - oldmac[3], oldmac[4], oldmac[5]); -} else { -char *path = NULL; -char macstr[VIR_MAC_STRING_BUFLEN]; - -if (virAsprintf(&path, "%s/%s", -stateDir, -linkdev) < 0) { -virRe
[libvirt] [PATCH 24/33] Move MAC address replacement functions to virnetdev.c
From: "Daniel P. Berrange" Move virNetDevReplaceMacAddress and virNetDevRestoreMacAddress to the virnetdev.c file where they naturally belong * util/interface.c, util/interface.h: Remove virNetDevReplaceMacAddress and virNetDevRestoreMacAddress * util/virnetdev.c, util/virnetdev.h: Add virNetDevReplaceMacAddress and virNetDevRestoreMacAddress --- src/util/interface.c | 84 -- src/util/interface.h | 10 - src/util/virnetdev.c | 91 ++ src/util/virnetdev.h | 12 ++ 4 files changed, 103 insertions(+), 94 deletions(-) diff --git a/src/util/interface.c b/src/util/interface.c index df2aa88..ebe537e 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -553,90 +553,6 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, #endif -/** - * virNetDevReplaceMacAddress: - * @macaddress: new MAC address for interface - * @linkdev: name of interface - * @stateDir: directory to store old MAC address - * - * Returns 0 on success, -1 on failure - * - */ -int -virNetDevReplaceMacAddress(const char *linkdev, - const unsigned char *macaddress, - const char *stateDir) -{ -unsigned char oldmac[6]; -char *path = NULL; -char macstr[VIR_MAC_STRING_BUFLEN]; - -if (virNetDevGetMAC(linkdev, oldmac) < 0) -return -1; - - -if (virAsprintf(&path, "%s/%s", -stateDir, -linkdev) < 0) { -virReportOOMError(); -return -1; -} -virFormatMacAddr(oldmac, macstr); -if (virFileWriteStr(path, macstr, O_CREAT|O_TRUNC|O_WRONLY) < 0) { -virReportSystemError(errno, _("Unable to preserve mac for %s"), - linkdev); -return -1; -} - -if (virNetDevSetMAC(linkdev, macaddress) < 0) -return -1; - -return 0; -} - -/** - * virNetDevRestoreMacAddress: - * @linkdev: name of interface - * @stateDir: directory containing old MAC address - * - * Returns 0 on success, -errno on failure. - * - */ -int -virNetDevRestoreMacAddress(const char *linkdev, - const char *stateDir) -{ -int rc; -char *oldmacname = NULL; -char *macstr = NULL; -char *path = NULL; -unsigned char oldmac[6]; - -if (virAsprintf(&path, "%s/%s", -stateDir, -linkdev) < 0) { -virReportOOMError(); -return -1; -} - -if (virFileReadAll(path, VIR_MAC_STRING_BUFLEN, &macstr) < 0) -return -1; - -if (virParseMacAddr(macstr, &oldmac[0]) != 0) { -ifaceError(VIR_ERR_INTERNAL_ERROR, - _("Cannot parse MAC address from '%s'"), - oldmacname); -VIR_FREE(macstr); -return -1; -} - -/*reset mac and remove file-ignore results*/ -rc = virNetDevSetMAC(linkdev, oldmac); -ignore_value(unlink(path)); -VIR_FREE(macstr); - -return rc; -} #ifdef __linux__ static int diff --git a/src/util/interface.h b/src/util/interface.h index 6a4631c..e322a21 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -49,16 +49,6 @@ int ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6); -int virNetDevReplaceMacAddress(const char *linkdev, - const unsigned char *macaddress, - const char *stateDir) -ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) -ATTRIBUTE_RETURN_CHECK; - -int virNetDevRestoreMacAddress(const char *linkdev, - const char *stateDir) -ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - int ifaceIsVirtualFunction(const char *ifname); int ifaceGetVirtualFunctionIndex(const char *pfname, const char *vfname, diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 5311ae7..9674391 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -32,8 +32,12 @@ #ifdef HAVE_NET_IF_H # include #endif +#include #define VIR_FROM_THIS VIR_FROM_NONE +#define virNetDevError(code, ...) \ +virReportErrorHelper(VIR_FROM_THIS, code, __FILE__,\ + __FUNCTION__, __LINE__, __VA_ARGS__) #ifdef HAVE_NET_IF_H static int virNetDevSetupControlFull(const char *ifname, @@ -223,6 +227,93 @@ int virNetDevGetMAC(const char *ifname, #endif + +/** + * virNetDevReplaceMacAddress: + * @macaddress: new MAC address for interface + * @linkdev: name of interface + * @stateDir: directory to store old MAC address + * + * Returns 0 on success, -1 on failure + * + */ +int +virNetDevReplaceMacAddress(const char *linkdev, + const unsigned char *macaddress, + const char *stateDir) +{ +unsigned char oldmac[6]; +char *pa
[libvirt] [PATCH 21/33] Rename low level macvlan creation APIs
From: "Daniel P. Berrange" Rename ifaceMacvtapLinkAdd to virNetDevMacVLanCreate and ifaceLinkDel to virNetDevMacVLanDelete. Strictly speaking the latter isn't restricted to macvlan devices, but that's the only use libvirt has for it. * util/interface.c, util/interface.h, util/virnetdevmacvlan.c: Rename APIs --- src/libvirt_private.syms|4 ++-- src/util/interface.c| 41 ++--- src/util/interface.h| 19 +++ src/util/virnetdevmacvlan.c | 12 ++-- 4 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 85f4064..27a9fdf 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -583,8 +583,8 @@ ifaceGetPhysicalFunction; ifaceGetVirtualFunctionIndex; ifaceGetVlanID; ifaceIsVirtualFunction; -ifaceLinkDel; -ifaceMacvtapLinkAdd; +virNetDevMacVLanCreate; +virNetDevMacVLanDelete; ifaceMacvtapLinkDump; ifaceReplaceMacAddress; ifaceRestoreMacAddress; diff --git a/src/util/interface.c b/src/util/interface.c index 63e6bf7..a1c56f5 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -313,12 +313,11 @@ ifaceGetIPAddress(const char *ifname ATTRIBUTE_UNUSED, #endif /* __linux__ */ /** - * ifaceLinkAdd + * virNetDevMacVLanCreate: * + * @ifname: The name the interface is supposed to have; optional parameter * @type: The type of device, i.e., "macvtap" * @macaddress: The MAC address of the device - * @macaddrsize: The size of the MAC address, typically '6' - * @ifname: The name the interface is supposed to have; optional parameter * @srcdev: The name of the 'link' device * @macvlan_mode: The macvlan mode to use * @retry: Pointer to integer that will be '1' upon return if an interface @@ -331,12 +330,12 @@ ifaceGetIPAddress(const char *ifname ATTRIBUTE_UNUSED, */ #if defined(__linux__) && WITH_MACVTAP int -ifaceMacvtapLinkAdd(const char *type, -const unsigned char *macaddress, int macaddrsize, -const char *ifname, -const char *srcdev, -uint32_t macvlan_mode, -int *retry) +virNetDevMacVLanCreate(const char *ifname, + const char *type, + const unsigned char *macaddress, + const char *srcdev, + uint32_t macvlan_mode, + int *retry) { int rc = 0; struct nlmsghdr *resp; @@ -366,7 +365,7 @@ ifaceMacvtapLinkAdd(const char *type, if (nla_put_u32(nl_msg, IFLA_LINK, ifindex) < 0) goto buffer_too_small; -if (nla_put(nl_msg, IFLA_ADDRESS, macaddrsize, macaddress) < 0) +if (nla_put(nl_msg, IFLA_ADDRESS, VIR_MAC_BUFLEN, macaddress) < 0) goto buffer_too_small; if (ifname && @@ -458,14 +457,12 @@ buffer_too_small: #else -int -ifaceMacvtapLinkAdd(const char *type ATTRIBUTE_UNUSED, -const unsigned char *macaddress ATTRIBUTE_UNUSED, -int macaddrsize ATTRIBUTE_UNUSED, -const char *ifname ATTRIBUTE_UNUSED, -const char *srcdev ATTRIBUTE_UNUSED, -uint32_t macvlan_mode ATTRIBUTE_UNUSED, -int *retry ATTRIBUTE_UNUSED) +int virNetDevMacVLanCreate(const char *ifname ATTRIBUTE_UNUSED, + const char *type ATTRIBUTE_UNUSED, + const unsigned char *macaddress ATTRIBUTE_UNUSED, + const char *srcdev ATTRIBUTE_UNUSED, + uint32_t macvlan_mode ATTRIBUTE_UNUSED, + int *retry ATTRIBUTE_UNUSED) { ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", # if defined(__linux__) && !WITH_MACVTAP @@ -483,7 +480,7 @@ ifaceMacvtapLinkAdd(const char *type ATTRIBUTE_UNUSED, /** - * ifaceLinkDel + * virNetDevMacVLanDelete: * * @ifname: Name of the interface * @@ -492,8 +489,7 @@ ifaceMacvtapLinkAdd(const char *type ATTRIBUTE_UNUSED, * Returns 0 on success, -1 on fatal error. */ #if defined( __linux__) && WITH_MACVTAP -int -ifaceLinkDel(const char *ifname) +int virNetDevMacVLanDelete(const char *ifname) { int rc = 0; struct nlmsghdr *resp; @@ -572,8 +568,7 @@ buffer_too_small: #else -int -ifaceLinkDel(const char *ifname ATTRIBUTE_UNUSED) +int virNetDevMacVLanDelete(const char *ifname ATTRIBUTE_UNUSED) { ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", # if defined(__linux__) && !WITH_MACVTAP diff --git a/src/util/interface.h b/src/util/interface.h index 4adc601..a62f26a 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -39,14 +39,17 @@ int ifaceGetVlanID(const char *vlanifname, int *vlanid); int ifaceGetIPAddress(const char *ifname, virSocketAddrPtr addr); -int ifaceMacvtapLinkAdd(const char *type, -const unsigned char *macaddress, int macaddrsize, -const char *ifname, -
[libvirt] [PATCH 27/33] Rename ifaceGetIPAddress to virNetDevGetIPv4Address
From: "Daniel P. Berrange" To match up with the existing virNetDevSetIPv4Address, rename ifaceGetIPAddress to virNetDevGetIPv4Address * util/interface.h, util/interface.c: Rename API * network/bridge_driver.c: Update for API rename --- src/libvirt_private.syms|2 +- src/network/bridge_driver.c | 11 +++-- src/util/interface.c| 46 +++--- src/util/interface.h|3 +- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8206b23..183e4f5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -577,7 +577,7 @@ virHookPresent; # interface.h ifaceCheck; virNetDevGetIndex; -ifaceGetIPAddress; +virNetDevGetIPv4Address; ifaceGetNthParent; ifaceGetPhysicalFunction; ifaceGetVirtualFunctionIndex; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index bad5337..3f8c8c4 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -3147,13 +3147,10 @@ networkGetNetworkAddress(const char *netname, char **netaddr) } if (dev_name) { -if (ifaceGetIPAddress(dev_name, &addr)) { -virReportSystemError(errno, - _("Failed to get IP address for '%s' (network '%s')"), - dev_name, netdef->name); -} else { -addrptr = &addr; -} +if (virNetDevGetIPv4Address(dev_name, &addr) < 0) +goto cleanup; + +addrptr = &addr; } if (addrptr && diff --git a/src/util/interface.c b/src/util/interface.c index 9762145..4e1ee25 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -142,60 +142,64 @@ ifaceCheck(bool reportError ATTRIBUTE_UNUSED, /** - * ifaceGetIPAddress: + * virNetDevGetIPv4Address: * @ifname: name of the interface whose IP address we want - * @macaddr: MAC address (VIR_MAC_BUFLEN in size) + * @addr: filled with the IPv4 address * - * This function gets the @macaddr for a given interface @ifname. + * This function gets the IPv4 address for the interface @ifname + * and stores it in @addr * * Returns 0 on success, -errno on failure. */ #ifdef __linux__ -int -ifaceGetIPAddress(const char *ifname, - virSocketAddrPtr addr) +int virNetDevGetIPv4Address(const char *ifname, +virSocketAddrPtr addr) { struct ifreq ifr; int fd; int rc = 0; -if (!ifname || !addr) -return -EINVAL; - memset (addr, 0, sizeof(*addr)); addr->data.stor.ss_family = AF_UNSPEC; fd = socket(AF_INET, SOCK_STREAM, 0); -if (fd < 0) -return -errno; +if (fd < 0) { +virReportSystemError(errno, "%s", + _("Unable to open control socket")); +return -1; +} memset(&ifr, 0, sizeof(struct ifreq)); if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { -rc = -EINVAL; -goto err_exit; +virReportSystemError(ERANGE, + _("invalid interface name %s"), + ifname); +goto cleanup; } -if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) != 0) { -rc = -errno; -goto err_exit; +if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { +virReportSystemError(errno, + _("Unable to get IPv4 address for interface %s"), ifname); +goto cleanup; } addr->data.stor.ss_family = AF_INET; addr->len = sizeof(addr->data.inet4); memcpy(&addr->data.inet4, &ifr.ifr_addr, addr->len); -err_exit: +cleanup: VIR_FORCE_CLOSE(fd); return rc; } #else -int -ifaceGetIPAddress(const char *ifname ATTRIBUTE_UNUSED, - virSocketAddrPtr addr ATTRIBUTE_UNUSED) +int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED, +virSocketAddrPtr addr ATTRIBUTE_UNUSED) { -return -ENOSYS; +virReportSystemError(ENOSYS, "%s", + _("Unable to get IPv4 address on this platform")); +return -1; } #endif /* __linux__ */ diff --git a/src/util/interface.h b/src/util/interface.h index aa70192..0a11ecd 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -33,7 +33,8 @@ struct nlattr; int ifaceCheck(bool reportError, const char *ifname, const unsigned char *macaddr, int ifindex); -int ifaceGetIPAddress(const char *ifname, virSocketAddrPtr addr); +int virNetDevGetIPv4Address(const char *ifname, virSocketAddrPtr addr) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, struct nlattr **tb, unsigned char **recvbuf, -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 31/33] Rename APIs for dealing with virtual/physical functions
From: "Daniel P. Berrange" Rename ifaceIsVirtualFunction to virNetDevIsVirtualFunction, ifaceGetVirtualFunctionIndex to virNetDevGetVirtualFunctionIndex and ifaceGetPhysicalFunction to virNetDevGetPhysicalFunction * src/util/interface.c, src/util/interface.h: Rename APIs * src/util/virnetdevvportprofile.c: Update for API rename --- src/libvirt_private.syms |6 ++-- src/util/interface.c | 54 + src/util/interface.h | 12 +--- src/util/virnetdevvportprofile.c |6 ++-- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6b7e231..8f58105 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -579,10 +579,10 @@ virNetDevValidateConfig; virNetDevGetIndex; virNetDevGetIPv4Address; ifaceGetNthParent; -ifaceGetPhysicalFunction; -ifaceGetVirtualFunctionIndex; +virNetDevGetPhysicalFunction; +virNetDevGetVirtualFunctionIndex; virNetDevGetVLanID; -ifaceIsVirtualFunction; +virNetDevIsVirtualFunction; virNetDevMacVLanCreate; virNetDevMacVLanDelete; ifaceMacvtapLinkDump; diff --git a/src/util/interface.c b/src/util/interface.c index 8264e7c..2882511 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -299,7 +299,7 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, #ifdef __linux__ static int -ifaceSysfsFile(char **pf_sysfs_device_link, const char *ifname, +virNetDevSysfsFile(char **pf_sysfs_device_link, const char *ifname, const char *file) { @@ -313,7 +313,7 @@ ifaceSysfsFile(char **pf_sysfs_device_link, const char *ifname, } static int -ifaceSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, +virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, const char *file) { @@ -327,8 +327,7 @@ ifaceSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, } /** - * ifaceIsVirtualFunction - * + * virNetDevIsVirtualFunction: * @ifname : name of the interface * * Checks if an interface is a SRIOV virtual function. @@ -337,12 +336,12 @@ ifaceSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, * */ int -ifaceIsVirtualFunction(const char *ifname) +virNetDevIsVirtualFunction(const char *ifname) { char *if_sysfs_device_link = NULL; int ret = -1; -if (ifaceSysfsFile(&if_sysfs_device_link, ifname, "device") < 0) +if (virNetDevSysfsFile(&if_sysfs_device_link, ifname, "device") < 0) return ret; ret = pciDeviceIsVirtualFunction(if_sysfs_device_link); @@ -353,7 +352,7 @@ ifaceIsVirtualFunction(const char *ifname) } /** - * ifaceGetVirtualFunctionIndex + * virNetDevGetVirtualFunctionIndex * * @pfname : name of the physical function interface name * @vfname : name of the virtual function interface name @@ -364,16 +363,16 @@ ifaceIsVirtualFunction(const char *ifname) * */ int -ifaceGetVirtualFunctionIndex(const char *pfname, const char *vfname, - int *vf_index) +virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname, + int *vf_index) { char *pf_sysfs_device_link = NULL, *vf_sysfs_device_link = NULL; int ret = -1; -if (ifaceSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0) +if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0) return ret; -if (ifaceSysfsFile(&vf_sysfs_device_link, vfname, "device") < 0) { +if (virNetDevSysfsFile(&vf_sysfs_device_link, vfname, "device") < 0) { VIR_FREE(pf_sysfs_device_link); return ret; } @@ -389,7 +388,7 @@ ifaceGetVirtualFunctionIndex(const char *pfname, const char *vfname, } /** - * ifaceGetPhysicalFunction + * virNetDevGetPhysicalFunction * * @ifname : name of the physical function interface name * @pfname : Contains sriov physical function for interface ifname @@ -399,12 +398,12 @@ ifaceGetVirtualFunctionIndex(const char *pfname, const char *vfname, * */ int -ifaceGetPhysicalFunction(const char *ifname, char **pfname) +virNetDevGetPhysicalFunction(const char *ifname, char **pfname) { char *physfn_sysfs_path = NULL; int ret = -1; -if (ifaceSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0) +if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0) return ret; ret = pciDeviceNetName(physfn_sysfs_path, pfname); @@ -413,34 +412,31 @@ ifaceGetPhysicalFunction(const char *ifname, char **pfname) return ret; } -#else +#else /* !__linux__ */ int -ifaceIsVirtualFunction(const char *ifname ATTRIBUTE_UNUSED) +virNetDevIsVirtualFunction(const char *ifname ATTRIBUTE_UNUSED) { -ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ifaceIsVirtualFunction is not supported on non-linux " - "platforms")); +virReportSystemError(ENOSYS, "%s", + _("Unable to check virtual
[libvirt] [PATCH 23/33] Rename interface MAC address replacement APIs
From: "Daniel P. Berrange" Rename ifaceReplaceMacAddress to virNetDevReplaceMacAddress and ifaceRestoreMacAddress to virNetDevRestoreMacAddress. * util/interface.c, util/interface.h, util/virnetdevmacvlan.c: Rename APIs --- src/libvirt_private.syms|4 ++-- src/util/interface.c| 14 +++--- src/util/interface.h| 15 +-- src/util/virnetdevmacvlan.c |5 ++--- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 27a9fdf..9706efc 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -586,8 +586,8 @@ ifaceIsVirtualFunction; virNetDevMacVLanCreate; virNetDevMacVLanDelete; ifaceMacvtapLinkDump; -ifaceReplaceMacAddress; -ifaceRestoreMacAddress; +virNetDevReplaceMacAddress; +virNetDevRestoreMacAddress; # interface_conf.h diff --git a/src/util/interface.c b/src/util/interface.c index e757c6f..df2aa88 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -554,7 +554,7 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, #endif /** - * ifaceReplaceMacAddress: + * virNetDevReplaceMacAddress: * @macaddress: new MAC address for interface * @linkdev: name of interface * @stateDir: directory to store old MAC address @@ -563,9 +563,9 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, * */ int -ifaceReplaceMacAddress(const unsigned char *macaddress, - const char *linkdev, - const char *stateDir) +virNetDevReplaceMacAddress(const char *linkdev, + const unsigned char *macaddress, + const char *stateDir) { unsigned char oldmac[6]; char *path = NULL; @@ -595,7 +595,7 @@ ifaceReplaceMacAddress(const unsigned char *macaddress, } /** - * ifaceRestoreMacAddress: + * virNetDevRestoreMacAddress: * @linkdev: name of interface * @stateDir: directory containing old MAC address * @@ -603,8 +603,8 @@ ifaceReplaceMacAddress(const unsigned char *macaddress, * */ int -ifaceRestoreMacAddress(const char *linkdev, - const char *stateDir) +virNetDevRestoreMacAddress(const char *linkdev, + const char *stateDir) { int rc; char *oldmacname = NULL; diff --git a/src/util/interface.h b/src/util/interface.h index 1dd8f35..6a4631c 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -49,12 +49,15 @@ int ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6); -int ifaceReplaceMacAddress(const unsigned char *macaddress, - const char *linkdev, - const char *stateDir); - -int ifaceRestoreMacAddress(const char *linkdev, - const char *stateDir); +int virNetDevReplaceMacAddress(const char *linkdev, + const unsigned char *macaddress, + const char *stateDir) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) +ATTRIBUTE_RETURN_CHECK; + +int virNetDevRestoreMacAddress(const char *linkdev, + const char *stateDir) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int ifaceIsVirtualFunction(const char *ifname); diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index a4bad18..6e09440 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -497,9 +497,8 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname, * emulate their switch in firmware. */ if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { -if (ifaceReplaceMacAddress(macaddress, linkdev, stateDir) < 0) { +if (virNetDevReplaceMacAddress(linkdev, macaddress, stateDir) < 0) return -1; -} } if (tgifname) { @@ -604,7 +603,7 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname, { int ret = 0; if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { -ifaceRestoreMacAddress(linkdev, stateDir); +ignore_value(virNetDevRestoreMacAddress(linkdev, stateDir)); } if (ifname) { -- 1.7.6.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 18/33] Rename Macvtap management APIs
From: "Daniel P. Berrange" In preparation for code re-organization, rename the Macvtap management APIs to have the following patterns virNetDevMacVLanX - macvlan/macvtap interface management virNetDevVPortProfile - virtual port profile management * src/util/macvtap.c, src/util/macvtap.h: Rename APIs * src/conf/domain_conf.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/qemu/qemu_command.h, src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c, src/qemu/qemu_process.c, src/qemu/qemu_process.h: Update for renamed APIs --- src/conf/domain_conf.c | 10 +- src/libvirt_private.syms|4 +- src/network/bridge_driver.c |8 +- src/qemu/qemu_command.c | 30 ++-- src/qemu/qemu_command.h |4 +- src/qemu/qemu_driver.c | 12 +- src/qemu/qemu_hotplug.c | 12 +- src/qemu/qemu_migration.c | 24 ++-- src/qemu/qemu_process.c | 12 +- src/qemu/qemu_process.h |2 +- src/util/macvtap.c | 386 ++- src/util/macvtap.h | 100 ++- tests/qemuxml2argvtest.c|2 +- tests/qemuxmlnstest.c |2 +- 14 files changed, 312 insertions(+), 296 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b3c3339..f6d2892 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3102,7 +3102,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node, mode = virXPathString("string(./source[1]/@mode)", ctxt); if (mode) { int m; -if ((m = virMacvtapModeTypeFromString(mode)) < 0) { +if ((m = virNetDevMacVLanModeTypeFromString(mode)) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("Unkown mode '%s' in interface element"), mode); @@ -3416,14 +3416,14 @@ virDomainNetDefParseXML(virCapsPtr caps, if (mode != NULL) { int m; -if ((m = virMacvtapModeTypeFromString(mode)) < 0) { +if ((m = virNetDevMacVLanModeTypeFromString(mode)) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unkown mode has been specified")); goto error; } def->data.direct.mode = m; } else -def->data.direct.mode = VIR_MACVTAP_MODE_VEPA; +def->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA; def->data.direct.virtPortProfile = virtPort; virtPort = NULL; @@ -9712,7 +9712,7 @@ virDomainActualNetDefFormat(virBufferPtr buf, virBufferEscapeString(buf, " dev='%s'", def->data.direct.linkdev); -mode = virMacvtapModeTypeToString(def->data.direct.mode); +mode = virNetDevMacVLanModeTypeToString(def->data.direct.mode); if (!mode) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected source mode %d"), @@ -9817,7 +9817,7 @@ virDomainNetDefFormat(virBufferPtr buf, virBufferEscapeString(buf, " data.direct.linkdev); virBufferAsprintf(buf, " mode='%s'", - virMacvtapModeTypeToString(def->data.direct.mode)); + virNetDevMacVLanModeTypeToString(def->data.direct.mode)); virBufferAddLit(buf, "/>\n"); virBufferAdjustIndent(buf, 6); if (virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf) < 0) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 52d2076..85f4064 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -739,8 +739,8 @@ virLogUnlock; # macvtap.h -virVMOperationTypeFromString; -virVMOperationTypeToString; +virNetDevVPortProfileOpTypeFromString; +virNetDevVPortProfileOpTypeToString; # memory.h diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index e68712f..bad5337 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -2780,16 +2780,16 @@ networkAllocateActualDevice(virDomainNetDefPtr iface) iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_DIRECT; switch (netdef->forwardType) { case VIR_NETWORK_FORWARD_BRIDGE: -iface->data.network.actual->data.direct.mode = VIR_MACVTAP_MODE_BRIDGE; +iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_BRIDGE; break; case VIR_NETWORK_FORWARD_PRIVATE: -iface->data.network.actual->data.direct.mode = VIR_MACVTAP_MODE_PRIVATE; +iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_PRIVATE; break; case VIR_NETWORK_FORWARD_VEPA: -iface->data.network.actual->data.direct.mode = VIR_MACVTAP_MODE_VEPA; +iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA;
[libvirt] [PATCH 25/33] Rename ifaceGetIndex and ifaceGetVLAN
From: "Daniel P. Berrange" Rename the ifaceGetIndex method to virNetDevGetIndex and ifaceGetVlanID to virNetDevGetVLanID. Also change the error reporting behaviour to always raise errors and return -1 on failure * util/interface.c, util/interface.h: Rename ifaceGetIndex and ifaceGetVLAN * nwfilter/nwfilter_gentech_driver.c, nwfilter/nwfilter_learnipaddr.c, nwfilter/nwfilter_learnipaddr.c, util/virnetdevvportprofile.c: Update for API renames and error handling changes --- src/libvirt_private.syms |4 +- src/nwfilter/nwfilter_gentech_driver.c | 13 +++-- src/nwfilter/nwfilter_learnipaddr.c| 22 --- src/util/interface.c | 103 src/util/interface.h |6 +- src/util/virnetdevmacvlan.c| 17 -- src/util/virnetdevvportprofile.c |6 +- 7 files changed, 92 insertions(+), 79 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9706efc..8206b23 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -576,12 +576,12 @@ virHookPresent; # interface.h ifaceCheck; -ifaceGetIndex; +virNetDevGetIndex; ifaceGetIPAddress; ifaceGetNthParent; ifaceGetPhysicalFunction; ifaceGetVirtualFunctionIndex; -ifaceGetVlanID; +virNetDevGetVLanID; ifaceIsVirtualFunction; virNetDevMacVLanCreate; virNetDevMacVLanDelete; diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 899bd32..9f44aef 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -903,9 +903,10 @@ _virNWFilterInstantiateFilter(virConnectPtr conn, /* after grabbing the filter update lock check for the interface; if it's not there anymore its filters will be or are being removed (while holding the lock) and we don't want to build new ones */ -if (ifaceGetIndex(false, net->ifname, &ifindex) < 0) { +if (virNetDevGetIndex(net->ifname, &ifindex) < 0) { /* interfaces / VMs can disappear during filter instantiation; don't mark it as an error */ +virResetLastError(); rc = 0; goto cleanup; } @@ -1021,8 +1022,9 @@ int virNWFilterRollbackUpdateFilter(virConnectPtr conn, } /* don't tear anything while the address is being learned */ -if (ifaceGetIndex(true, net->ifname, &ifindex) == 0 && -virNWFilterLookupLearnReq(ifindex) != NULL) +if (virNetDevGetIndex(net->ifname, &ifindex) < 0) +virResetLastError(); +else if (virNWFilterLookupLearnReq(ifindex) != NULL) return 0; return techdriver->tearNewRules(conn, net->ifname); @@ -1047,8 +1049,9 @@ virNWFilterTearOldFilter(virConnectPtr conn, } /* don't tear anything while the address is being learned */ -if (ifaceGetIndex(true, net->ifname, &ifindex) == 0 && -virNWFilterLookupLearnReq(ifindex) != NULL) +if (virNetDevGetIndex(net->ifname, &ifindex) < 0) +virResetLastError(); +else if (virNWFilterLookupLearnReq(ifindex) != NULL) return 0; return techdriver->tearOldRules(conn, net->ifname); diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 68bdcfc..9a51fc2 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -252,21 +252,23 @@ virNWFilterTerminateLearnReq(const char *ifname) { int ifindex; virNWFilterIPAddrLearnReqPtr req; -if (ifaceGetIndex(false, ifname, &ifindex) == 0) { - -IFINDEX2STR(ifindex_str, ifindex); +if (virNetDevGetIndex(ifname, &ifindex) < 0) { +virResetLastError(); +return rc; +} -virMutexLock(&pendingLearnReqLock); +IFINDEX2STR(ifindex_str, ifindex); -req = virHashLookup(pendingLearnReq, ifindex_str); -if (req) { -rc = 0; -req->terminate = true; -} +virMutexLock(&pendingLearnReqLock); -virMutexUnlock(&pendingLearnReqLock); +req = virHashLookup(pendingLearnReq, ifindex_str); +if (req) { +rc = 0; +req->terminate = true; } +virMutexUnlock(&pendingLearnReqLock); + return rc; } diff --git a/src/util/interface.c b/src/util/interface.c index ebe537e..af1def2 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -115,8 +115,9 @@ ifaceCheck(bool reportError, const char *ifname, } if (ifindex != -1) { -rc = ifaceGetIndex(reportError, ifname, &idx); -if (rc == 0 && idx != ifindex) +if (virNetDevGetIndex(ifname, &idx) < 0) +virResetLastError(); +else if (idx != ifindex) rc = -ENODEV; } @@ -141,114 +142,112 @@ ifaceCheck(bool reportError ATTRIBUTE_UNUSED, /** - * ifaceGetIndex - * - * @reportError: whether to report errors or keep silent + * virNetDevGetIndex * @ifname : Name of the interface whose index is to be found * @ifindex: Poi
[libvirt] [PATCH 32/33] Move functions for dealing with physical/virtual devices
From: "Daniel P. Berrange" Move virNetDevIsVirtualFunction, virNetDevGetVirtualFunctionIndex and virNetDevGetPhysicalFunction to virnetdev.c * src/util/interface.c, src/util/interface.h, src/util/virnetdev.c, src/util/virnetdev.h: Move APIs --- src/util/interface.c | 146 - src/util/interface.h | 13 - src/util/virnetdev.c | 148 ++ src/util/virnetdev.h | 10 4 files changed, 158 insertions(+), 159 deletions(-) diff --git a/src/util/interface.c b/src/util/interface.c index 2882511..00a873e 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -45,7 +45,6 @@ #include "virfile.h" #include "memory.h" #include "netlink.h" -#include "pci.h" #include "logging.h" #include "virnetdev.h" @@ -295,148 +294,3 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, } #endif - - -#ifdef __linux__ -static int -virNetDevSysfsFile(char **pf_sysfs_device_link, const char *ifname, - const char *file) -{ - -if (virAsprintf(pf_sysfs_device_link, NET_SYSFS "%s/%s", -ifname, file) < 0) { -virReportOOMError(); -return -1; -} - -return 0; -} - -static int -virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, - const char *file) -{ - -if (virAsprintf(pf_sysfs_device_link, NET_SYSFS "%s/device/%s", -ifname, file) < 0) { -virReportOOMError(); -return -1; -} - -return 0; -} - -/** - * virNetDevIsVirtualFunction: - * @ifname : name of the interface - * - * Checks if an interface is a SRIOV virtual function. - * - * Returns 1 if interface is SRIOV virtual function, 0 if not and -1 if error - * - */ -int -virNetDevIsVirtualFunction(const char *ifname) -{ -char *if_sysfs_device_link = NULL; -int ret = -1; - -if (virNetDevSysfsFile(&if_sysfs_device_link, ifname, "device") < 0) -return ret; - -ret = pciDeviceIsVirtualFunction(if_sysfs_device_link); - -VIR_FREE(if_sysfs_device_link); - -return ret; -} - -/** - * virNetDevGetVirtualFunctionIndex - * - * @pfname : name of the physical function interface name - * @vfname : name of the virtual function interface name - * @vf_index : Pointer to int. Contains vf index of interface upon successful - * return - * - * Returns 0 on success, -1 on failure - * - */ -int -virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname, - int *vf_index) -{ -char *pf_sysfs_device_link = NULL, *vf_sysfs_device_link = NULL; -int ret = -1; - -if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0) -return ret; - -if (virNetDevSysfsFile(&vf_sysfs_device_link, vfname, "device") < 0) { -VIR_FREE(pf_sysfs_device_link); -return ret; -} - -ret = pciGetVirtualFunctionIndex(pf_sysfs_device_link, - vf_sysfs_device_link, - vf_index); - -VIR_FREE(pf_sysfs_device_link); -VIR_FREE(vf_sysfs_device_link); - -return ret; -} - -/** - * virNetDevGetPhysicalFunction - * - * @ifname : name of the physical function interface name - * @pfname : Contains sriov physical function for interface ifname - * upon successful return - * - * Returns 0 on success, -1 on failure - * - */ -int -virNetDevGetPhysicalFunction(const char *ifname, char **pfname) -{ -char *physfn_sysfs_path = NULL; -int ret = -1; - -if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0) -return ret; - -ret = pciDeviceNetName(physfn_sysfs_path, pfname); - -VIR_FREE(physfn_sysfs_path); - -return ret; -} -#else /* !__linux__ */ -int -virNetDevIsVirtualFunction(const char *ifname ATTRIBUTE_UNUSED) -{ -virReportSystemError(ENOSYS, "%s", - _("Unable to check virtual function status on this platfornm")); -return -1; -} - -int -virNetDevGetVirtualFunctionIndex(const char *pfname ATTRIBUTE_UNUSED, - const char *vfname ATTRIBUTE_UNUSED, - int *vf_index ATTRIBUTE_UNUSED) -{ -virReportSystemError(ENOSYS, "%s", - _("Unable to get virtual function index on this platfornm")); -return -1; -} - -int -virNetDevGetPhysicalFunction(const char *ifname ATTRIBUTE_UNUSED, - char **pfname ATTRIBUTE_UNUSED) -{ -virReportSystemError(ENOSYS, "%s", - _("Unable to get physical function status on this platfornm")); -return -1; -} -#endif /* !__linux__ */ diff --git a/src/util/interface.h b/src/util/interface.h index 86f9aac..141d19c 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -27,8 +27,6 @@ struct nlattr; # include "datatypes.h" # include "virsocketaddr.h" -# define NET_SYSFS "/sys/class/net/" - int ifaceMacvtapLinkDump(bool nltarget_kernel, const char
[libvirt] [PATCH 12/33] Fix error reporting in port profile parsing/formatting APIs
From: "Daniel P. Berrange" The virtual port profile parsing/formatting APIs do not correctly handle unknown profile type strings/numbers. They behave as a no-op, instead of raising an error * src/util/network.c, src/util/network.h: Fix error handling of port profile APIs * src/conf/domain_conf.c, src/conf/network_conf.c: Update for API changes --- src/conf/domain_conf.c | 16 +++- src/conf/network_conf.c | 20 +++--- src/util/network.c | 61 --- src/util/network.h |8 +++--- 4 files changed, 54 insertions(+), 51 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c1f8950..b1e47a3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3112,10 +3112,9 @@ virDomainActualNetDefParseXML(xmlNodePtr node, virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode && -virNetDevVPortProfileParse(virtPortNode, - &actual->data.direct.virtPortProfile) < 0) { +(!(actual->data.direct.virtPortProfile = + virNetDevVPortProfileParse(virtPortNode goto error; -} } bandwidth_node = virXPathNode("./bandwidth", ctxt); @@ -3221,7 +3220,7 @@ virDomainNetDefParseXML(virCapsPtr caps, ((def->type == VIR_DOMAIN_NET_TYPE_DIRECT) || (def->type == VIR_DOMAIN_NET_TYPE_NETWORK)) && xmlStrEqual(cur->name, BAD_CAST "virtualport")) { -if (virNetDevVPortProfileParse(cur, &virtPort) < 0) +if (!(virtPort = virNetDevVPortProfileParse(cur))) goto error; } else if ((network == NULL) && ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) || @@ -9721,7 +9720,8 @@ virDomainActualNetDefFormat(virBufferPtr buf, } virBufferAsprintf(buf, " mode='%s'/>\n", mode); virBufferAdjustIndent(buf, 8); -virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf); +if (virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf) < 0) +goto error; virBufferAdjustIndent(buf, -8); break; default: @@ -9768,7 +9768,8 @@ virDomainNetDefFormat(virBufferPtr buf, def->data.network.portgroup); virBufferAddLit(buf, "/>\n"); virBufferAdjustIndent(buf, 6); -virNetDevVPortProfileFormat(def->data.network.virtPortProfile, buf); +if (virNetDevVPortProfileFormat(def->data.network.virtPortProfile, buf) < 0) +return -1; virBufferAdjustIndent(buf, -6); if ((flags & VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET) && (virDomainActualNetDefFormat(buf, def->data.network.actual) < 0)) @@ -9818,7 +9819,8 @@ virDomainNetDefFormat(virBufferPtr buf, virMacvtapModeTypeToString(def->data.direct.mode)); virBufferAddLit(buf, "/>\n"); virBufferAdjustIndent(buf, 6); -virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf); +if (virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf) < 0) +return -1; virBufferAdjustIndent(buf, -6); break; diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 023eb9f..5e38bee 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -790,10 +790,8 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def, virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode && -(virNetDevVPortProfileParse(virtPortNode, -&def->virtPortProfile) < 0)) { +(!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode goto error; -} bandwidth_node = virXPathNode("./bandwidth", ctxt); if (bandwidth_node && @@ -894,10 +892,8 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode && -(virNetDevVPortProfileParse(virtPortNode, -&def->virtPortProfile) < 0)) { +(!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode goto error; -} nPortGroups = virXPathNodeSet("./portgroup", ctxt, &portGroupNodes); if (nPortGroups < 0) @@ -1258,7 +1254,7 @@ error: return result; } -static void +static int virPortGroupDefFormat(virBufferPtr buf, const virPortGroupDefPtr def) { @@ -1268,10 +1264,12 @@ virPortGroupDefFormat(virBufferPtr buf, } virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 4); -virNetDevVPortProfileFormat(def->virtPortProfile, buf); +if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0) +return -1; virNetDevBandwidthFormat(def->bandwidth, buf); virBufferAdjustIndent(buf, -4); virBufferAd
[libvirt] [PATCH 33/33] Move ifaceMacvtapLinkDump and ifaceGetNthParent functions
From: "Daniel P. Berrange" Move the ifaceMacvtapLinkDump and ifaceGetNthParent functions into virnetdevvportprofile.c since they are specific to that code. This avoids polluting the headers with the Linux specific netlink data types * src/util/interface.c, src/util/interface.h: Move ifaceMacvtapLinkDump and ifaceGetNthParent functions and delete remaining file * src/util/virnetdevvportprofile.c: Add ifaceMacvtapLinkDump and ifaceGetNthParent functions * src/network/bridge_driver.c, src/nwfilter/nwfilter_gentech_driver.c, src/nwfilter/nwfilter_learnipaddr.c, src/util/virnetdevmacvlan.c: Remove include of interface.h --- po/POTFILES.in |1 - src/Makefile.am|1 - src/libvirt_private.syms |2 - src/network/bridge_driver.c|1 - src/nwfilter/nwfilter_gentech_driver.c |2 +- src/nwfilter/nwfilter_learnipaddr.c|1 - src/util/interface.c | 296 src/util/interface.h | 41 - src/util/virnetdevmacvlan.c|3 +- src/util/virnetdevvportprofile.c | 199 +- 10 files changed, 196 insertions(+), 351 deletions(-) delete mode 100644 src/util/interface.c delete mode 100644 src/util/interface.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 6797298..403d94b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -112,7 +112,6 @@ src/util/hash.c src/util/hooks.c src/util/hostusb.c src/util/iohelper.c -src/util/interface.c src/util/iptables.c src/util/json.c src/util/netlink.c diff --git a/src/Makefile.am b/src/Makefile.am index 6703bc1..bb45ab6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,7 +70,6 @@ UTIL_SOURCES = \ util/pci.c util/pci.h \ util/processinfo.c util/processinfo.h \ util/hostusb.c util/hostusb.h \ - util/interface.c util/interface.h \ util/qparams.c util/qparams.h \ util/sexpr.c util/sexpr.h \ util/stats_linux.c util/stats_linux.h \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8f58105..7baaf77 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -578,14 +578,12 @@ virHookPresent; virNetDevValidateConfig; virNetDevGetIndex; virNetDevGetIPv4Address; -ifaceGetNthParent; virNetDevGetPhysicalFunction; virNetDevGetVirtualFunctionIndex; virNetDevGetVLanID; virNetDevIsVirtualFunction; virNetDevMacVLanCreate; virNetDevMacVLanDelete; -ifaceMacvtapLinkDump; virNetDevReplaceMacAddress; virNetDevRestoreMacAddress; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 3f8c8c4..b8a96b9 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -56,7 +56,6 @@ #include "memory.h" #include "uuid.h" #include "iptables.h" -#include "interface.h" #include "logging.h" #include "dnsmasq.h" #include "configmake.h" diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 9dffdc5..c9c1415 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -28,13 +28,13 @@ #include "memory.h" #include "logging.h" -#include "interface.h" #include "domain_conf.h" #include "virterror_internal.h" #include "nwfilter_gentech_driver.h" #include "nwfilter_ebiptables_driver.h" #include "nwfilter_learnipaddr.h" #include "virnetdev.h" +#include "datatypes.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 03716ea..1843c98 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -45,7 +45,6 @@ #include "memory.h" #include "logging.h" #include "datatypes.h" -#include "interface.h" #include "virnetdev.h" #include "virterror_internal.h" #include "threads.h" diff --git a/src/util/interface.c b/src/util/interface.c deleted file mode 100644 index 00a873e..000 --- a/src/util/interface.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * interface.c: interface support functions - * - * Copyright (C) 2011 Red Hat, Inc. - * Copyright (C) 2010 IBM Corp. - * Copyright (C) 2010 Stefan Berger - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You sho
[libvirt] [PATCH 30/33] Move virNetDevValidateConfig to virnetdev.c
From: "Daniel P. Berrange" * src/util/interface.c, src/util/interface.h: Remove virNetDevValidateConfig * src/util/virnetdev.c, src/util/virnetdev.h: Add virNetDevValidateConfig --- src/util/interface.c | 89 -- src/util/interface.h |4 -- src/util/virnetdev.c | 77 +++ src/util/virnetdev.h |4 ++ 4 files changed, 81 insertions(+), 93 deletions(-) diff --git a/src/util/interface.c b/src/util/interface.c index 16ad155..8264e7c 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -55,95 +55,6 @@ virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) -/** - * virNetDevValidateConfig: - * @ifname: Name of the interface - * @macaddr: expected MAC address of the interface; not checked if NULL - * @ifindex: expected index of the interface; not checked if '-1' - * - * Determine whether a given interface is still available. If so, - * it must have the given MAC address and if an interface index is - * passed, it must also match the interface index. - * - * Returns 1 if the config matches, 0 if the config does not match, or interface does not exist, -1 on error - */ -#ifdef __linux__ -int virNetDevValidateConfig(const char *ifname, -const unsigned char *macaddr, int ifindex) -{ -int fd = -1; -int ret = -1; -struct ifreq ifr; -int idx; -int rc; - -if ((rc = virNetDevExists(ifname)) < 0) -return -1; -if (rc == 0) { -ret = 0; -goto cleanup; -} - -if (macaddr != NULL) { -fd = socket(PF_PACKET, SOCK_DGRAM, 0); -if (fd < 0) { -virReportSystemError(errno, "%s", - _("Unable to open control socket")); -return -1; -} - -memset(&ifr, 0, sizeof(ifr)); - -if (virStrncpy(ifr.ifr_name, - ifname, strlen(ifname), sizeof(ifr.ifr_name)) == NULL) { -virReportSystemError(ERANGE, - _("invalid interface name %s"), - ifname); -goto cleanup; -} - -if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { -if (errno == ENODEV) { -ret = 0; -goto cleanup; -} -virReportSystemError(errno, - _("coud not get MAC address of interface %s"), - ifname); -goto cleanup; -} - -if (memcmp(&ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN) != 0) { -ret = 0; -goto cleanup; -} -} - -if (ifindex != -1) { -if (virNetDevGetIndex(ifname, &idx) < 0) -goto cleanup; -else if (idx != ifindex) { -ret = 0; -goto cleanup; -} -} - -ret = 1; - - cleanup: -VIR_FORCE_CLOSE(fd); -return ret; -} -#else /* ! __linux__ */ -int virNetDevValidateConfig(const char *ifname ATTRIBUTE_UNUSED, -const unsigned char *macaddr ATTRIBUTE_UNUSED, -int ifindex ATTRIBUTE_UNUSED) -{ -return -ENOSYS; -} -#endif /* ! __linux__ */ - - #if defined(__linux__) && defined(IFLA_PORT_MAX) diff --git a/src/util/interface.h b/src/util/interface.h index c230264..4256f29 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -30,10 +30,6 @@ struct nlattr; # define NET_SYSFS "/sys/class/net/" -int virNetDevValidateConfig(const char *ifname, -const unsigned char *macaddr, int ifindex) -ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, struct nlattr **tb, unsigned char **recvbuf, uint32_t (*getPidFunc)(void)); diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index b272d31..453c343 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -856,3 +856,80 @@ int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED, } #endif /* __linux__ */ + + +/** + * virNetDevValidateConfig: + * @ifname: Name of the interface + * @macaddr: expected MAC address of the interface; not checked if NULL + * @ifindex: expected index of the interface; not checked if '-1' + * + * Determine whether a given interface is still available. If so, + * it must have the given MAC address and if an interface index is + * passed, it must also match the interface index. + * + * Returns 1 if the config matches, 0 if the config does not match, or interface does not exist, -1 on error + */ +#ifdef __linux__ +int virNetDevValidateConfig(const char *ifname, +const unsigned char *macaddr, int ifindex) +{ +int fd = -1; +int ret = -1; +struct ifreq ifr; +int idx; +int rc; + +if ((rc = virNetDe
[libvirt] [PATCHv6 3/5] API: add trivial qemu support for VIR_TYPED_PARAM_STRING
Qemu will be the first driver to make use of a typed string in the next round of additions. Separate out the trivial addition. * src/qemu/qemu_driver.c (qemudSupportsFeature): Advertise feature. (qemuDomainGetBlkioParameters, qemuDomainGetMemoryParameters) (qemuGetSchedulerParametersFlags, qemudDomainBlockStatsFlags): Allow typed strings flag where trivially supported. --- v6: no real change src/qemu/qemu_driver.c | 24 1 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 118197a..c8a858e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -920,6 +920,7 @@ qemudSupportsFeature (virConnectPtr conn ATTRIBUTE_UNUSED, int feature) case VIR_DRV_FEATURE_MIGRATION_P2P: case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION: case VIR_DRV_FEATURE_FD_PASSING: +case VIR_DRV_FEATURE_TYPED_PARAM_STRING: return 1; default: return 0; @@ -6041,9 +6042,13 @@ static int qemuDomainGetBlkioParameters(virDomainPtr dom, bool isActive; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | - VIR_DOMAIN_AFFECT_CONFIG, -1); + VIR_DOMAIN_AFFECT_CONFIG | + VIR_TYPED_PARAM_STRING_OKAY, -1); qemuDriverLock(driver); +/* We don't return strings, and thus trivially support this flag. */ +flags &= ~VIR_TYPED_PARAM_STRING_OKAY; + vm = virDomainFindByUUID(&driver->domains, dom->uuid); if (vm == NULL) { @@ -6336,10 +6341,14 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom, bool isActive; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | - VIR_DOMAIN_AFFECT_CONFIG, -1); + VIR_DOMAIN_AFFECT_CONFIG | + VIR_TYPED_PARAM_STRING_OKAY, -1); qemuDriverLock(driver); +/* We don't return strings, and thus trivially support this flag. */ +flags &= ~VIR_TYPED_PARAM_STRING_OKAY; + vm = virDomainFindByUUID(&driver->domains, dom->uuid); if (vm == NULL) { @@ -6883,10 +6892,14 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom, int saved_nparams = 0; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | - VIR_DOMAIN_AFFECT_CONFIG, -1); + VIR_DOMAIN_AFFECT_CONFIG | + VIR_TYPED_PARAM_STRING_OKAY, -1); qemuDriverLock(driver); +/* We don't return strings, and thus trivially support this flag. */ +flags &= ~VIR_TYPED_PARAM_STRING_OKAY; + if ((flags & (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG)) == (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG)) { qemuReportError(VIR_ERR_INVALID_ARG, "%s", @@ -7142,7 +7155,10 @@ qemuDomainBlockStatsFlags(virDomainPtr dom, long long wr_total_times, flush_req, flush_total_times, errs; virTypedParameterPtr param; -virCheckFlags(0, -1); +virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1); + +/* We don't return strings, and thus trivially support this flag. */ +flags &= ~VIR_TYPED_PARAM_STRING_OKAY; qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); -- 1.7.4.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCHv6 1/5] API: add VIR_TYPED_PARAM_STRING
This allows strings to be transported between client and server in the context of name-type-value virTypedParameter functions. For compatibility, o new clients will not send strings to old servers, based on a feature check o new servers will not send strings to old clients without the flag VIR_TYPED_PARAM_STRING_OKAY; this will be enforced at the RPC layer in the next patch, so that drivers need not worry about it in general. The one exception is that virDomainGetSchedulerParameters lacks a flags argument, so it must not return a string; drivers that forward that function on to virDomainGetSchedulerParametersFlags will have to pay attention to the flag. o the flag VIR_TYPED_PARAM_STRING_OKAY is set automatically, based on a feature check (so far, no driver implements it), so clients do not have to worry about it Future patches can then enable the feature on a per-driver basis. This patch also ensures that drivers can blindly strdup() field names (previously, a malicious client could stuff 80 non-NUL bytes into field and cause a read overrun). * src/libvirt_internal.h (VIR_DRV_FEATURE_TYPED_PARAM_STRING): New driver feature. * src/libvirt.c (virTypedParameterValidateSet) (virTypedParameterSanitizeGet): New helper functions. (virDomainSetMemoryParameters, virDomainSetBlkioParameters) (virDomainSetSchedulerParameters) (virDomainSetSchedulerParametersFlags) (virDomainGetMemoryParameters, virDomainGetBlkioParameters) (virDomainGetSchedulerParameters) (virDomainGetSchedulerParametersFlags, virDomainBlockStatsFlags): Use them. * src/util/util.h (virTypedParameterArrayClear): New helper function. * src/util/util.c (virTypedParameterArrayClear): Implement it. * src/libvirt_private.syms (util.h): Export it. Based on an initial patch by Hu Tao, with feedback from Daniel P. Berrange. Signed-off-by: Eric Blake --- v6: address review comments from Stefan, defer filtering of string params on Get functions to the rpc side include/libvirt/libvirt.h.in | 32 ++- src/libvirt.c| 92 -- src/libvirt_internal.h |9 +++- src/libvirt_private.syms |1 + src/util/util.c | 14 ++ src/util/util.h |2 + 6 files changed, 134 insertions(+), 16 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7181f62..e10a72b 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -200,11 +200,14 @@ typedef virDomainControlInfo *virDomainControlInfoPtr; * current domain state. VIR_DOMAIN_AFFECT_LIVE requires a running * domain, and VIR_DOMAIN_AFFECT_CONFIG requires a persistent domain * (whether or not it is running). + * + * These enums should not conflict with those of virTypedParameterFlags. */ typedef enum { VIR_DOMAIN_AFFECT_CURRENT = 0, /* Affect current domain state. */ VIR_DOMAIN_AFFECT_LIVE= 1 << 0, /* Affect running domain state. */ VIR_DOMAIN_AFFECT_CONFIG = 1 << 1, /* Affect persistent domain state. */ +/* 1 << 2 is reserved for virTypedParameterFlags */ } virDomainModificationImpact; /** @@ -489,10 +492,36 @@ typedef enum { VIR_TYPED_PARAM_LLONG = 3, /* long long case */ VIR_TYPED_PARAM_ULLONG = 4, /* unsigned long long case */ VIR_TYPED_PARAM_DOUBLE = 5, /* double case */ -VIR_TYPED_PARAM_BOOLEAN = 6 /* boolean(character) case */ +VIR_TYPED_PARAM_BOOLEAN = 6, /* boolean(character) case */ +VIR_TYPED_PARAM_STRING = 7, /* string case */ } virTypedParameterType; /** + * virTypedParameterFlags: + * + * Flags related to libvirt APIs that use virTypedParameter. + * + * These enums should not conflict with those of virDomainModificationImpact. + */ +typedef enum { +/* 1 << 0 is reserved for virDomainModificationImpact */ +/* 1 << 1 is reserved for virDomainModificationImpact */ + +/* Older servers lacked the ability to handle string typed + * parameters. Attempts to set a string parameter with an older + * server will fail at the client, but attempts to retrieve + * parameters must not return strings from a new server to an + * older client, so this flag exists to identify newer clients to + * newer servers. This flag is automatically set when needed, so + * the user does not have to worry about it; however, manually + * setting the flag can be used to reject servers that cannot + * return typed strings, even if no strings would be returned. + */ +VIR_TYPED_PARAM_STRING_OKAY = 1 << 2, + +} virTypedParameterFlags; + +/** * VIR_TYPED_PARAM_FIELD_LENGTH: * * Macro providing the field length of virTypedParameter name @@ -520,6 +549,7 @@ struct _virTypedParameter { unsigned long long int ul; /* type is ULLONG */ double d; /* type is DOUBLE */ char b; /* type is BOOLEAN */ +
[libvirt] [PATCHv6 5/5] blkiotune: add qemu support for blkiotune.device_weight
From: Hu Tao Implement setting/getting per-device blkio weights in qemu, using the cgroups blkio.weight_device tunable. --- v5: did not include this patch v6: split v4 2/2 into two parts; this part covers just the qemu. Rebase to accomodate 'device_weight' naming and VIR_TYPED_PARAM_STRING handling. This patch is broken, with several flaws: 1. 'virsh blkiotune dom --device-weight /dev/sda,500 --live' does not alter the 'virsh dumpxml dom' live XML. The cgroups change is active, but unless we also reflect the change in the eventual xml dump, then we aren't accurately telling the user the current state of the domain. This means that qemuDomainSetBlkioParameters needs a fix. 2. 'virsh blkiotune dom --live' now shows output that looks like: weight : 500 device_weight : 8,0 500 whereas 'virsh blkiotune dom --config' shows: weight : 500 device_weight : /dev/sda,500 The --config version is correct - it accurately reflects the XML. The --live version is wrong - we MUST NOT expose major,minor back to the user, since we intentionally decided that the XML should track only the device name, not the major/minor implementation detail of cgroups. I think the correct fix would be to just delete virCgroupGetBlkioDeviceWeight and treat cgroups blkio.weight_device as write-only, and instead have qemuDomainGetBlkioParameters always produce output from the domain definition (--live vs. --config merely choosing between vm->def vs. persistentDef), which stems back to my solution of point 1 in having in vm->def accurately reflect whatever is written into cgroups. src/qemu/qemu_cgroup.c | 22 ++ src/qemu/qemu_driver.c | 191 ++- src/util/cgroup.c | 33 src/util/cgroup.h |4 + 4 files changed, 245 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 2a10bd2..d397578 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -312,6 +312,28 @@ int qemuSetupCgroup(struct qemud_driver *driver, } } +if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { +char *tmp; +if (virBlkioDeviceWeightToStr(vm->def->blkio.devices, + vm->def->blkio.ndevices, + &tmp) < 0) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_("Unable to set io device weight for domain %s"), +vm->def->name); +goto cleanup; +} +if (tmp) { +rc = virCgroupSetBlkioDeviceWeight(cgroup, tmp); +VIR_FREE(tmp); +if (rc != 0) { +virReportSystemError(-rc, + _("Unable to set io device weight for domain %s"), + vm->def->name); +goto cleanup; +} +} +} + if (vm->def->mem.hard_limit != 0 || vm->def->mem.soft_limit != 0 || vm->def->mem.swap_hard_limit != 0) { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index c8a858e..6b0acf0 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -112,7 +112,7 @@ # define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ #endif -#define QEMU_NB_BLKIO_PARAM 1 +#define QEMU_NB_BLKIO_PARAM 2 static void processWatchdogEvent(void *data, void *opaque); @@ -5888,6 +5888,82 @@ cleanup: return ret; } +/* deviceWeightStr in the form of /device/path,weight;/device/path,weight + * for example, /dev/disk/by-path/pci-:00:1f.2-scsi-0:0:0:0,800 + */ +static int +parseBlkioWeightDeviceStr(char *deviceWeightStr, + virBlkioDeviceWeightPtr *dw, int *size) +{ +char *temp; +int ndevices = 0; +int i; +virBlkioDeviceWeightPtr result = NULL; + +temp = deviceWeightStr; +while (temp) { +temp = strchr(temp, ';'); +if (temp) { +temp++; +if (*temp == '\0') +break; +ndevices++; +} +} +ndevices++; + +if (VIR_ALLOC_N(result, ndevices) < 0) { +virReportOOMError(); +return -1; +} + +i = 0; +temp = deviceWeightStr; +while (temp && i < ndevices) { +char *p = temp; + +/* device path */ + +p = strchr(p, ','); +if (!p) +goto error; + +result[i].path = strndup(temp, p - temp); +if (!result[i].path) { +virReportOOMError(); +goto cleanup; +} + +/* weight */ +temp = p + 1; + +if (virStrToLong_i(temp, &p, 10, &result[i].weight) < 0) +goto error; + +i++; +if (*p == '\0') +break; +else if (*p != ';') +goto error; +temp = p + 1; +} +if (i != ndevices) +goto error; + +*dw = result; +*size = i; + +return 0; + +error: +
[libvirt] [PATCHv6 0/5] expose per-device blkio weight tuning, via string param
This is v6 of Hu's original proposal: v1: https://www.redhat.com/archives/libvir-list/2011-September/msg00334.html v4: https://www.redhat.com/archives/libvir-list/2011-October/msg00444.html v5: https://www.redhat.com/archives/libvir-list/2011-November/msg00060.html Patches 1-3 are solid in my testing. When I first started working on these patches, I was thinking it would be worth having VIR_TYPED_PARAM_STRING in 0.9.7; however, now that I've spent longer on it, I'm reluctant to push this new virTypedParameter API without at least one other API that takes advantage of a typed string. I tested 1-3 by using patches 4 and 5, using all 4 combinations of pre- and post-patch clients and servers. If either (or both) sides were old, then behavior is unchanged from 0.9.6 (no strings are present, a new client won't confuse an old server, a new server won't confuse an old client, and all non-string parameters are still passed in all cases); if both sides are new, then the string passing works as designed. Patch 4 is close to feature-complete, and would be the first API to take advantage of patches 1-3, but it is pointless to apply it without at least one driver implementation. Also, it has a user interface issue, in that '/path/to/dev1,weight;/path/to/dev2,weight' is awkward to type in a virsh command line; it might be nicer if if we used the string '/path/to/dev1,weight,/path/to/dev2,weight' instead, but that would mean some further parsing alterations. Note that in patch 4, I renamed the virsh option to 'virsh blkiotune --device-weight', in part because having both '--weight-device' and '--weight' would interfere with my (future) plans to make virsh do unambiguous option prefix parsing, and in part because the XML is laid out with device as the primary name, with weight as a sub-feature of each device (just because cgroups named things backwards doesn't mean that we have to repeat that mistake). Patch 5 is broken. I've already spent too long on this series, so I'm hoping Hu can resume ownership of this series and post a working v7 that resolves my complaints. More details in that particular patch message; but the short summary is that 'virsh blkiotune --live' and 'virsh blkiotune --config' must give identically formatted output. Eric Blake (4): API: add VIR_TYPED_PARAM_STRING API: remote support for VIR_TYPED_PARAM_STRING API: add trivial qemu support for VIR_TYPED_PARAM_STRING blkiotune: add interface for blkiotune.device_weight Hu Tao (1): blkiotune: add qemu support for blkiotune.device_weight daemon/remote.c | 88 - docs/formatdomain.html.in | 29 +- docs/schemas/domaincommon.rng | 12 +++ include/libvirt/libvirt.h.in | 42 - src/conf/domain_conf.c| 130 - src/conf/domain_conf.h| 17 src/libvirt.c | 92 +++--- src/libvirt_internal.h|9 ++- src/libvirt_private.syms |3 + src/qemu/qemu_cgroup.c| 22 src/qemu/qemu_driver.c| 213 +++-- src/remote/remote_driver.c| 28 +- src/remote/remote_protocol.x |2 + src/remote_protocol-structs |2 + src/rpc/gendispatch.pl|3 +- src/util/cgroup.c | 33 +++ src/util/cgroup.h |4 + src/util/util.c | 14 +++ src/util/util.h |2 + tools/virsh.c | 32 ++- tools/virsh.pod |6 +- 21 files changed, 720 insertions(+), 63 deletions(-) -- 1.7.4.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCHv6 4/5] blkiotune: add interface for blkiotune.device_weight
This adds per-device weights to . Note that the cgroups implementation only supports weights per block device, and not per-file within the device; hence this option must be global to the domain definition rather than tied to individual / entries: /path/to/block 1000 ... This patch also adds a parameter --device-weight to virsh command blkiotune for setting/getting blkiotune.weight_device for any hypervisor that supports it. All entries under are concatenated into a single string attribute under virDomain{Get,Set}BlkioParameters, named "device_weight". --- v5: did not include this patch v6: split v4 2/2 into two parts; this part covers just the libvirt.h and virsh changes. Rename public-facing terminology to be "device_weight", not "weight_device", since we are talking about per-device weights and may later add other per-device attributes (no need to propagate cgroups' stupid naming to the user). Rebase to fit in with VIR_TYPED_PARAM_STRING tweaks earlier in series. Should we use just commas for field separation, rather than commas between device and weight but semicolon between device-weight pairs? It would make it much easier to do: virsh blkiotune dom --device-weight /dev/sda,500,/dev/sdb,500 instead of requiring shell quoting: virsh blkiotune dom --device-weight '/dev/sda,500;/dev/sdb,500' docs/formatdomain.html.in | 29 - docs/schemas/domaincommon.rng | 12 include/libvirt/libvirt.h.in | 10 +++ src/conf/domain_conf.c| 130 - src/conf/domain_conf.h| 17 + src/libvirt_private.syms |2 + tools/virsh.c | 32 +- tools/virsh.pod |6 ++- 8 files changed, 228 insertions(+), 10 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index cbad196..e848b7d 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -505,6 +505,14 @@ ...... @@ -514,10 +522,25 @@ blkiotune The optional blkiotune element provides the ability to tune Blkio cgroup tunable parameters for the domain. If this is -omitted, it defaults to the OS provided defaults. +omitted, it defaults to the OS provided +defaults. Since 0.8.8 weight - The optional weight element is the I/O weight of the -guest. The value should be in range [100, 1000]. + The optional weight element is the overall I/O +weight of the guest. The value should be in the range [100, +1000]. + device + The domain may have multiple device elements +that further tune the weights for each host block device in +use by the domain. Note that +multiple guest disks can share a +single host block device, if they are backed by files within +the same host file system, which is why this tuning parameter +is at the global domain level rather than associated with each +guest disk device. Each device element has two +mandatory sub-elements, path describing the +absolute path of the device, and weight giving +the relative weight of that device, in the range [100, +1000]. Since 0.9.7 diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index b6f858e..6f96fe2 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -328,6 +328,18 @@ + + + + + + + + + + + + diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index e10a72b..5ae7d10 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1236,6 +1236,16 @@ char * virDomainGetSchedulerType(virDomainPtr domain, #define VIR_DOMAIN_BLKIO_WEIGHT "weight" +/** + * VIR_DOMAIN_BLKIO_DEVICE_WEIGHT: + * + * Macro for the blkio tunable weight_device: it represents the + * per-device weight, as a string. The string is parsed as a + * series of /path/to/device,weight elements, separated by ';'. + */ + +#define VIR_DOMAIN_BLKIO_DEVICE_WEIGHT "device_weight" + /* Set Blkio tunables for the domain*/ int virDomainSetBlkioParameters(virDomainPtr domain, virTypedParameterPtr params, diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 238edfd..e5b5f69 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -603,6 +603,99 @@ VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST, #define 800 ++ +/dev/sda +1000 ++ /dev/sdb +500 +
[libvirt] [PATCHv6 2/5] API: remote support for VIR_TYPED_PARAM_STRING
Send and receive string typed parameters across RPC. This also completes the back-compat mentioned in the previous patch - the only time we have an older client talking to a newer server is if RPC is in use, so filtering out strings during RPC prevents returning an unknown type to the older client. * src/remote/remote_protocol.x (remote_typed_param_value): Add another union value. * daemon/remote.c (remoteDeserializeTypedParameters): Handle strings on rpc. (remoteSerializeTypedParameters): Likewise; plus filter out strings when replying to older clients. Adjust callers. * src/remote/remote_driver.c (remoteFreeTypedParameters) (remoteSerializeTypedParameters) (remoteDeserializeTypedParameters): Handle strings on rpc. * src/rpc/gendispatch.pl: Properly clean up typed arrays. * src/remote_protocol-structs: Update. Based on an initial patch by Hu Tao, with feedback from Daniel P. Berrange. Signed-off-by: Eric Blake --- v6: address review comments from Stefan, add filtering of string params on Get functions daemon/remote.c | 88 + src/remote/remote_driver.c | 28 - src/remote/remote_protocol.x |2 + src/remote_protocol-structs |2 + src/rpc/gendispatch.pl |3 +- 5 files changed, 94 insertions(+), 29 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index bd0c3e3..aa3f768 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -92,11 +92,6 @@ static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr static void make_nonnull_nwfilter(remote_nonnull_nwfilter *net_dst, virNWFilterPtr nwfilter_src); static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src); -static int -remoteSerializeTypedParameters(virTypedParameterPtr params, - int nparams, - remote_typed_param **ret_params_val, - u_int *ret_params_len); static virTypedParameterPtr remoteDeserializeTypedParameters(remote_typed_param *args_params_val, u_int args_params_len, @@ -682,14 +677,17 @@ cleanup: return rv; } -/* Helper to serialize typed parameters. */ +/* Helper to serialize typed parameters. This also filters out any string + * parameters that must not be returned to older clients. */ static int remoteSerializeTypedParameters(virTypedParameterPtr params, int nparams, remote_typed_param **ret_params_val, - u_int *ret_params_len) + u_int *ret_params_len, + unsigned int flags) { int i; +int j; int rv = -1; remote_typed_param *val; @@ -699,38 +697,53 @@ remoteSerializeTypedParameters(virTypedParameterPtr params, goto cleanup; } -for (i = 0; i < nparams; ++i) { +for (i = 0, j = 0; i < nparams; ++i) { +if (!(flags & VIR_TYPED_PARAM_STRING_OKAY) && +params[i].type == VIR_TYPED_PARAM_STRING) { +--*ret_params_len; +continue; +} + /* remoteDispatchClientRequest will free this: */ -val[i].field = strdup (params[i].field); -if (val[i].field == NULL) { +val[j].field = strdup(params[i].field); +if (val[j].field == NULL) { virReportOOMError(); goto cleanup; } -val[i].value.type = params[i].type; -switch (params[i].type) { +val[j].value.type = params[i].type; +switch (params[j].type) { case VIR_TYPED_PARAM_INT: -val[i].value.remote_typed_param_value_u.i = params[i].value.i; +val[j].value.remote_typed_param_value_u.i = params[i].value.i; break; case VIR_TYPED_PARAM_UINT: -val[i].value.remote_typed_param_value_u.ui = params[i].value.ui; +val[j].value.remote_typed_param_value_u.ui = params[i].value.ui; break; case VIR_TYPED_PARAM_LLONG: -val[i].value.remote_typed_param_value_u.l = params[i].value.l; +val[j].value.remote_typed_param_value_u.l = params[i].value.l; break; case VIR_TYPED_PARAM_ULLONG: -val[i].value.remote_typed_param_value_u.ul = params[i].value.ul; +val[j].value.remote_typed_param_value_u.ul = params[i].value.ul; break; case VIR_TYPED_PARAM_DOUBLE: -val[i].value.remote_typed_param_value_u.d = params[i].value.d; +val[j].value.remote_typed_param_value_u.d = params[i].value.d; break; case VIR_TYPED_PARAM_BOOLEAN: -val[i].value.remote_typed_param_value_u.b = params[i].value.b; +val[j].value.remote_typed_param_value_u.b = params[i].value.b; +break; +case VIR_TYPED_PARAM_STRING: +val[j].value.r
Re: [libvirt] [PATCH v2 1/4] doc: Add capability.
On 11/03/2011 04:10 AM, Jiri Denemark wrote: On Tue, Nov 01, 2011 at 10:27:47 +0100, Philipp Hahn wrote: Allow /capabilities/guest/features/deviceboot. Signed-off-by: Philipp Hahn --- docs/schemas/capability.rng |5 + 1 files changed, 5 insertions(+), 0 deletions(-) ACK and I agree with this being 0.9.7 material. Pushed. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] build: fix deep VPATH builds
I ran into the following build failure: $ mkdir -p build1 build2/a/very/deep/hierarcy $ cd build2/a/very/deep/hierarcy $ ../../../../../configure && make $ cd ../../../../build1 $ ../configure && make ... ../../src/remote/remote_protocol.c:7:55: fatal error: ../../../../../src/remote/remote_protocol.h: No such file or directory Turns out that we were sometimes generating the remote_protocol.c file with information from the VPATH build, which is bad, since any file shipped in the tarball should be idempotent no matter how deep the VPATH build tree that created it. * src/rpc/genprotocol.pl: Don't embed VPATH into generated file. --- Pushing under the build-breaker rule. And yes, I really did create a directory by that name, while testing the earlier patches for the testsuite failure to create a UNIX socket in a deep location. :) src/rpc/genprotocol.pl |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/rpc/genprotocol.pl b/src/rpc/genprotocol.pl index 7124e5c..166508b 100755 --- a/src/rpc/genprotocol.pl +++ b/src/rpc/genprotocol.pl @@ -59,7 +59,7 @@ while () { s/xdr_u_quad_t/xdr_uint64_t/g; s/xdr_quad_t/xdr_int64_t/g; s/(?https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] build: fix build on platforms without ptsname_r
MacOS lacks ptsname_r, and gnulib doesn't (yet) provide it. But we can avoid it altogether, by using gnulib openpty() instead. Note that we do _not_ want the pt_chown module; all systems that we currently port to can either properly do openpty() and/or grantpt(), or lack ptys altogether; we are not porting to any system that requires us to deal with the hassle of installing a setuid pt_chown helper just to satisfy gnulib's ability to provide openpty() on even more platforms. * .gnulib: Update to latest, for openpty fixes * bootstrap.conf (gnulib_modules): Add openpty, ttyname_r. (gnulib_tool_option_extras): Exclude pt_chown module. * src/util/util.c (virFileOpenTty): Rewrite in terms of openpty and ttyname_r. * src/util/util.h (virFileOpenTtyAt): Delete dead prototype. Reported by Justin Clift. --- I compile-tested this on Linux, but haven't yet tested this on MacOS, which is the driving force behind this patch. Meanwhile, it would be nice to run some LXC tests to ensure this all still works. I'm posting it now, to get the review started while I figure out how to run further tests. Gnulib changes are: * .gnulib 2394a60...84c3f9c (78): > New module 'unlinkat', split off from module 'openat'. > New module 'fchmodat', split off from module 'openat'. > putenv: indent #definition of "environ" to placate cppi > gitlog-to-changelog: provide a ChangeLog-repair mechanism > gitlog-to-changelog: avoid an infloop > * MODULES.html.sh: Fix sed-script shell quoting and locale issues. > fchownat: Improve description. > * tests/test-stdalign.c (TEST_ALIGNMENT): Shrink back to 8. > Fix my old ChangeLog entry to properly cite Bruno's email. > alignof: Avoid collision with stdalign module. > New module 'fchownat', split off from module 'openat'. > stdalign: port better to MSVC and to Sun C 5.11 > doc about some IRIX 5.3 problems. > gitlog-to-changelog: fix git-log invocation > gitlog-to-changelog: new option --append-dot > ffsl, ffsll: Avoid compilation error due to 'restrict'. > GNUmakefile: reenable "make syntax-check" for most projects > gitlog-to-changelog: treat a message with only blank lines as empty > test-parse-datetime.c: avoid new DST-related false positive test failure > autoupdate > fstat: Tweak documentation. > Update documentation regarding 'largefile' module. > maint.mk: don't maintain a second build-aux variable. > Adjust to Bruno's comments. > sys_socket: use stdalign, not alignof > crypto libraries: use stdalign > argp: use stdalign > stdalign-tests: new module > stdalign: new module > raise test: Avoid a test failure on Linux/MIPS. > nonblocking tests: Fix test failure on Linux/MIPS. > utimensat: Work around problem on Linux/hppa. > maint.mk: fix a bug in sc_prohibit_stddef_without_use > maint.mk: exempt ENODATA from a syntax-check rule > fts: close parent dir FD before returning from post-traversal fts_read > autoupdate > readme-release: improve safety of release prep instructions. > errno, strerror-override: Support for MSVC 10. > perror: Recognize when test program crashes. > perror: Fix indentation. > isfinite, isinf, isnan, signbit: Don't define as a macro in C++. > relocatable-prog-wrapper: Don't leave object files behind. > openpty, posix_openpt: Remove code duplication. > unlockpt: Detect invalid argument. > openpty: Avoid compilation error on AIX 6.1. > autoupdate > posix_openpt: Support for OpenBSD. > posix_openpt test: Coding style. > grantpt: Support --avoid=pt_chown. > posix_openpt: Fix autoconf macro. > openpty: Update comments. > openpty: relax license > pt_chown: use configmake to simplify build > ptsname and others: relax license > update from texinfo > posix_openpt: remove spurious #endif > maint.mk: Respect $(build_aux) in web-manual rule. > posix_openpt: Fix compilation error. > Support for old NeXTstep 3.3 frexp(). > Support for old NeXTstep 3.3 sed. > Support for old NeXTstep 3.3 gcc. > posix_openpt: new module > xstrtoll: Fix compilation failure. > vasnprintf: Optimize bit search operation. > vasnprintf: Fix comments. > Tests for module 'integer_length_ll'. > New module 'integer_length_ll'. > Tests for module 'integer_length_l'. > New module 'integer_length_l'. > Tests for module 'integer_length'. > New module 'integer_length'. > popen: Fix dependency conditions. > perror: Fix autoconf test. > ffsl: Optimize on 64-bit platforms. > autoupdate > ffsl: Optimize on 32-bit platforms. > ffsl, ffsll: Optimize for GCC. > ffs, bcopy, memset: Support symbol renaming via config.h. .gnulib |2 +- bootstrap.conf |3 ++ src/util/util.c | 62 -- src/util/util.h |5 4 files changed, 45 insertions(+), 27 deletions(-) diff --git a/.gnulib b/.gnulib index 2394a60..84c3f9c 16 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 2394a603e7586e671226478e
Re: [libvirt] [Libvirt-announce] Start of freeze for libvirt-0.9.7 and availability of rc1
On 11/03/2011 04:19 AM, Daniel Veillard wrote: Thanks to everybody who provided feedback and patches on rc1, I have made an rc2 available at ftp://libvirt.org/libvirt/libvirt-0.9.7-rc2.tar.gz *** Warning: Linking the shared library libvirt.la against the non-libtool *** objects probes.o is not portable! when I build from the tree. and maybe it expects some .lo instead, but I'm not sure how to tweak this correctly :) Nothing to fix, unless you're willing to hack libtool to tell it that we specifically know that this is non-portable, but we are only doing it on Linux, where we know it works. Anyway, please check that rc2 too. Eric do you think you will be able to fix the missing 'ptsname_r' in gnulib in time or should we make a small workaround for platforms lacking it for the release ? I just posted a proposed patch for that: https://www.redhat.com/archives/libvir-list/2011-November/msg00210.html -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [Libvirt-announce] Start of freeze for libvirt-0.9.7 and availability of rc1
On Tue, Nov 01, 2011 at 08:20:16AM -0600, Eric Blake thus spake: On 11/01/2011 04:44 AM, Justin Clift wrote: Fails on OSX 10.6.8, with this: make all-am Undefined symbols: "_ptsname_r", referenced from: _virFileOpenTty in libvirt_util.a(libvirt_util_la-util.o) ld: symbol(s) not found collect2: ld returned 1 exit status make[3]: *** [libvirt_iohelper] Error 1 make[3]: *** Waiting for unfinished jobs make[2]: *** [all] Error 2 make[1]: *** [all-recursive] Error 1 make: *** [all] Error 2 Anyone feel like investigating? :) Yeah, ptsname_r is not standardized, but is very useful; it sounds like something gnulib should be able to fix. I'll take a crack at it this week. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org I received a similar build error for FreeBSD: storage/storage_driver.c:507: warning: null format string [-Wformat] CC libvirt_driver_storage_la-storage_backend.lo CC libvirt_driver_storage_la-storage_backend_fs.lo CC libvirt_driver_storage_la-storage_backend_scsi.lo CCLD libvirt_driver_storage.la CCLD libvirt_test.la CC libvirt_iohelper-iohelper.o CCLD libvirt_iohelper ./.libs/libvirt_util.a(libvirt_util_la-util.o)(.text+0x2249): In function `virFileOpenTty': : undefined reference to `ptsname_r' gmake[3]: *** [libvirt_iohelper] Error 1 gmake[3]: Leaving directory `/home/jhelfman/ports/devel/libvirt/work/libvirt-0.9.7/src' gmake[2]: *** [all] Error 2 gmake[2]: Leaving directory `/home/jhelfman/ports/devel/libvirt/work/libvirt-0.9.7/src' gmake[1]: *** [all-recursive] Error 1 gmake[1]: Leaving directory `/home/jhelfman/ports/devel/libvirt/work/libvirt-0.9.7' gmake: *** [all] Error 2 *** Error code 1 -jgh -- Jason Helfman System Administrator experts-exchange.com http://www.experts-exchange.com/M_4830110.html E4AD 7CF1 1396 27F6 79DD 4342 5E92 AD66 8C8C FBA5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Start of freeze for libvirt-0.9.7 and availability of rc1
On Thu, Nov 03, 2011 at 06:19:25PM +0800, Daniel Veillard wrote: > Thanks to everybody who provided feedback and patches on rc1, > I have made an rc2 available at >ftp://libvirt.org/libvirt/libvirt-0.9.7-rc2.tar.gz > there is also the rpms rebuilds for Fedora 14. Builds fine now on Debian: https://buildd.debian.org/status/package.php?p=libvirt&suite=experimental packages will be available with the next mirror pulse. Cheers, -- Guido -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv6 1/5] API: add VIR_TYPED_PARAM_STRING
On 11/03/2011 02:05 PM, Eric Blake wrote: This allows strings to be transported between client and server in the context of name-type-value virTypedParameter functions. For compatibility, o new clients will not send strings to old servers, based on a feature check o new servers will not send strings to old clients without the flag VIR_TYPED_PARAM_STRING_OKAY; this will be enforced at the RPC layer in the next patch, so that drivers need not worry about it in general. The one exception is that virDomainGetSchedulerParameters lacks a flags argument, so it must not return a string; drivers that forward that function on to virDomainGetSchedulerParametersFlags will have to pay attention to the flag. o the flag VIR_TYPED_PARAM_STRING_OKAY is set automatically, based on a feature check (so far, no driver implements it), so clients do not have to worry about it Future patches can then enable the feature on a per-driver basis. This patch also ensures that drivers can blindly strdup() field names (previously, a malicious client could stuff 80 non-NUL bytes into field and cause a read overrun). * src/libvirt_internal.h (VIR_DRV_FEATURE_TYPED_PARAM_STRING): New driver feature. * src/libvirt.c (virTypedParameterValidateSet) (virTypedParameterSanitizeGet): New helper functions. (virDomainSetMemoryParameters, virDomainSetBlkioParameters) (virDomainSetSchedulerParameters) (virDomainSetSchedulerParametersFlags) (virDomainGetMemoryParameters, virDomainGetBlkioParameters) (virDomainGetSchedulerParameters) (virDomainGetSchedulerParametersFlags, virDomainBlockStatsFlags): Use them. * src/util/util.h (virTypedParameterArrayClear): New helper function. * src/util/util.c (virTypedParameterArrayClear): Implement it. * src/libvirt_private.syms (util.h): Export it. Based on an initial patch by Hu Tao, with feedback from Daniel P. Berrange. Signed-off-by: Eric Blake --- v6: address review comments from Stefan, defer filtering of string params on Get functions to the rpc side include/libvirt/libvirt.h.in | 32 ++- src/libvirt.c| 92 -- src/libvirt_internal.h |9 +++- src/libvirt_private.syms |1 + src/util/util.c | 14 ++ src/util/util.h |2 + 6 files changed, 134 insertions(+), 16 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7181f62..e10a72b 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -200,11 +200,14 @@ typedef virDomainControlInfo *virDomainControlInfoPtr; * current domain state. VIR_DOMAIN_AFFECT_LIVE requires a running * domain, and VIR_DOMAIN_AFFECT_CONFIG requires a persistent domain * (whether or not it is running). + * + * These enums should not conflict with those of virTypedParameterFlags. */ typedef enum { VIR_DOMAIN_AFFECT_CURRENT = 0, /* Affect current domain state. */ VIR_DOMAIN_AFFECT_LIVE= 1<< 0, /* Affect running domain state. */ VIR_DOMAIN_AFFECT_CONFIG = 1<< 1, /* Affect persistent domain state. */ +/* 1<< 2 is reserved for virTypedParameterFlags */ } virDomainModificationImpact; /** @@ -489,10 +492,36 @@ typedef enum { VIR_TYPED_PARAM_LLONG = 3, /* long long case */ VIR_TYPED_PARAM_ULLONG = 4, /* unsigned long long case */ VIR_TYPED_PARAM_DOUBLE = 5, /* double case */ -VIR_TYPED_PARAM_BOOLEAN = 6 /* boolean(character) case */ +VIR_TYPED_PARAM_BOOLEAN = 6, /* boolean(character) case */ +VIR_TYPED_PARAM_STRING = 7, /* string case */ } virTypedParameterType; /** + * virTypedParameterFlags: + * + * Flags related to libvirt APIs that use virTypedParameter. + * + * These enums should not conflict with those of virDomainModificationImpact. + */ +typedef enum { +/* 1<< 0 is reserved for virDomainModificationImpact */ +/* 1<< 1 is reserved for virDomainModificationImpact */ + +/* Older servers lacked the ability to handle string typed + * parameters. Attempts to set a string parameter with an older + * server will fail at the client, but attempts to retrieve + * parameters must not return strings from a new server to an + * older client, so this flag exists to identify newer clients to + * newer servers. This flag is automatically set when needed, so + * the user does not have to worry about it; however, manually + * setting the flag can be used to reject servers that cannot + * return typed strings, even if no strings would be returned. + */ +VIR_TYPED_PARAM_STRING_OKAY = 1<< 2, + +} virTypedParameterFlags; + +/** * VIR_TYPED_PARAM_FIELD_LENGTH: * * Macro providing the field length of virTypedParameter name @@ -520,6 +549,7 @@ struct _virTypedParameter { unsigned long long int ul; /* type is ULLONG */ double d; /* ty
Re: [libvirt] [PATCHv6 3/5] API: add trivial qemu support for VIR_TYPED_PARAM_STRING
On 11/03/2011 02:05 PM, Eric Blake wrote: Qemu will be the first driver to make use of a typed string in the next round of additions. Separate out the trivial addition. * src/qemu/qemu_driver.c (qemudSupportsFeature): Advertise feature. (qemuDomainGetBlkioParameters, qemuDomainGetMemoryParameters) (qemuGetSchedulerParametersFlags, qemudDomainBlockStatsFlags): Allow typed strings flag where trivially supported. --- v6: no real change src/qemu/qemu_driver.c | 24 1 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 118197a..c8a858e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -920,6 +920,7 @@ qemudSupportsFeature (virConnectPtr conn ATTRIBUTE_UNUSED, int feature) case VIR_DRV_FEATURE_MIGRATION_P2P: case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION: case VIR_DRV_FEATURE_FD_PASSING: +case VIR_DRV_FEATURE_TYPED_PARAM_STRING: return 1; default: return 0; @@ -6041,9 +6042,13 @@ static int qemuDomainGetBlkioParameters(virDomainPtr dom, bool isActive; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | - VIR_DOMAIN_AFFECT_CONFIG, -1); + VIR_DOMAIN_AFFECT_CONFIG | + VIR_TYPED_PARAM_STRING_OKAY, -1); qemuDriverLock(driver); +/* We don't return strings, and thus trivially support this flag. */ +flags&= ~VIR_TYPED_PARAM_STRING_OKAY; + vm = virDomainFindByUUID(&driver->domains, dom->uuid); if (vm == NULL) { @@ -6336,10 +6341,14 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom, bool isActive; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | - VIR_DOMAIN_AFFECT_CONFIG, -1); + VIR_DOMAIN_AFFECT_CONFIG | + VIR_TYPED_PARAM_STRING_OKAY, -1); qemuDriverLock(driver); +/* We don't return strings, and thus trivially support this flag. */ +flags&= ~VIR_TYPED_PARAM_STRING_OKAY; + vm = virDomainFindByUUID(&driver->domains, dom->uuid); if (vm == NULL) { @@ -6883,10 +6892,14 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom, int saved_nparams = 0; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | - VIR_DOMAIN_AFFECT_CONFIG, -1); + VIR_DOMAIN_AFFECT_CONFIG | + VIR_TYPED_PARAM_STRING_OKAY, -1); qemuDriverLock(driver); +/* We don't return strings, and thus trivially support this flag. */ +flags&= ~VIR_TYPED_PARAM_STRING_OKAY; + if ((flags& (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG)) == (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG)) { qemuReportError(VIR_ERR_INVALID_ARG, "%s", @@ -7142,7 +7155,10 @@ qemuDomainBlockStatsFlags(virDomainPtr dom, long long wr_total_times, flush_req, flush_total_times, errs; virTypedParameterPtr param; -virCheckFlags(0, -1); +virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1); + +/* We don't return strings, and thus trivially support this flag. */ +flags&= ~VIR_TYPED_PARAM_STRING_OKAY; qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); ACK -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv6 2/5] API: remote support for VIR_TYPED_PARAM_STRING
On 11/03/2011 02:05 PM, Eric Blake wrote: Send and receive string typed parameters across RPC. This also completes the back-compat mentioned in the previous patch - the only time we have an older client talking to a newer server is if RPC is in use, so filtering out strings during RPC prevents returning an unknown type to the older client. * src/remote/remote_protocol.x (remote_typed_param_value): Add another union value. * daemon/remote.c (remoteDeserializeTypedParameters): Handle strings on rpc. (remoteSerializeTypedParameters): Likewise; plus filter out strings when replying to older clients. Adjust callers. * src/remote/remote_driver.c (remoteFreeTypedParameters) (remoteSerializeTypedParameters) (remoteDeserializeTypedParameters): Handle strings on rpc. * src/rpc/gendispatch.pl: Properly clean up typed arrays. * src/remote_protocol-structs: Update. Based on an initial patch by Hu Tao, with feedback from Daniel P. Berrange. Signed-off-by: Eric Blake --- v6: address review comments from Stefan, add filtering of string params on Get functions daemon/remote.c | 88 + src/remote/remote_driver.c | 28 - src/remote/remote_protocol.x |2 + src/remote_protocol-structs |2 + src/rpc/gendispatch.pl |3 +- 5 files changed, 94 insertions(+), 29 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index bd0c3e3..aa3f768 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -92,11 +92,6 @@ static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr static void make_nonnull_nwfilter(remote_nonnull_nwfilter *net_dst, virNWFilterPtr nwfilter_src); static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src); -static int -remoteSerializeTypedParameters(virTypedParameterPtr params, - int nparams, - remote_typed_param **ret_params_val, - u_int *ret_params_len); static virTypedParameterPtr remoteDeserializeTypedParameters(remote_typed_param *args_params_val, u_int args_params_len, @@ -682,14 +677,17 @@ cleanup: return rv; } -/* Helper to serialize typed parameters. */ +/* Helper to serialize typed parameters. This also filters out any string + * parameters that must not be returned to older clients. */ static int remoteSerializeTypedParameters(virTypedParameterPtr params, int nparams, remote_typed_param **ret_params_val, - u_int *ret_params_len) + u_int *ret_params_len, + unsigned int flags) { int i; +int j; int rv = -1; remote_typed_param *val; @@ -699,38 +697,53 @@ remoteSerializeTypedParameters(virTypedParameterPtr params, goto cleanup; } -for (i = 0; i< nparams; ++i) { +for (i = 0, j = 0; i< nparams; ++i) { +if (!(flags& VIR_TYPED_PARAM_STRING_OKAY)&& +params[i].type == VIR_TYPED_PARAM_STRING) { +--*ret_params_len; +continue; +} + /* remoteDispatchClientRequest will free this: */ -val[i].field = strdup (params[i].field); -if (val[i].field == NULL) { +val[j].field = strdup(params[i].field); +if (val[j].field == NULL) { virReportOOMError(); goto cleanup; } -val[i].value.type = params[i].type; -switch (params[i].type) { +val[j].value.type = params[i].type; +switch (params[j].type) { case VIR_TYPED_PARAM_INT: -val[i].value.remote_typed_param_value_u.i = params[i].value.i; +val[j].value.remote_typed_param_value_u.i = params[i].value.i; break; case VIR_TYPED_PARAM_UINT: -val[i].value.remote_typed_param_value_u.ui = params[i].value.ui; +val[j].value.remote_typed_param_value_u.ui = params[i].value.ui; break; case VIR_TYPED_PARAM_LLONG: -val[i].value.remote_typed_param_value_u.l = params[i].value.l; +val[j].value.remote_typed_param_value_u.l = params[i].value.l; break; case VIR_TYPED_PARAM_ULLONG: -val[i].value.remote_typed_param_value_u.ul = params[i].value.ul; +val[j].value.remote_typed_param_value_u.ul = params[i].value.ul; break; case VIR_TYPED_PARAM_DOUBLE: -val[i].value.remote_typed_param_value_u.d = params[i].value.d; +val[j].value.remote_typed_param_value_u.d = params[i].value.d; break; case VIR_TYPED_PARAM_BOOLEAN: -val[i].value.remote_typed_param_value_u.b = params[i].value.b; +val[j].value.remote_typed_param_value_u.b = params[i].value.b; +
[libvirt] [PATCH] lxc: avoid use-after-free
I got this weird failure: error: Failed to start domain simple error: internal error cannot mix caller fds with blocking execution and tracked it down to a use-after-free - virCommandSetOutputFD was storing the address of a stack-local variable, which then went out of scope before the virCommandRun that dereferenced it. Bug introduced in commit 451cfd05 (0.9.2). * src/lxc/lxc_driver.c (lxcBuildControllerCmd): Move log fd registration... (lxcVmStart): ...to caller. --- I have no idea how danpb got so lucky in being able to test recent lxc addtions, given the fact that booting an LXC domain has basically been broken for several months now, depending on whether the compiler happened to smash the stack variable in question. src/lxc/lxc_driver.c |7 +++ 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index d6e5e20..37092bc 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1449,7 +1449,6 @@ lxcBuildControllerCmd(lxc_driver_t *driver, char **veths, int *ttyFDs, size_t nttyFDs, - int logfile, int handshakefd) { size_t i; @@ -1524,8 +1523,6 @@ lxcBuildControllerCmd(lxc_driver_t *driver, } virCommandPreserveFD(cmd, handshakefd); -virCommandSetOutputFD(cmd, &logfile); -virCommandSetErrorFD(cmd, &logfile); return cmd; cleanup: @@ -1747,8 +1744,10 @@ static int lxcVmStart(virConnectPtr conn, vm, nveths, veths, ttyFDs, nttyFDs, - logfd, handshakefds[1]))) + handshakefds[1]))) goto cleanup; +virCommandSetOutputFD(cmd, &logfd); +virCommandSetErrorFD(cmd, &logfd); /* Log timestamp */ if ((timestamp = virTimestamp()) == NULL) { -- 1.7.4.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv6 4/5] blkiotune: add interface for blkiotune.device_weight
On 11/03/2011 02:06 PM, Eric Blake wrote: This adds per-device weights to. Note that the cgroups implementation only supports weights per block device, and not per-file within the device; hence this option must be global to the domain definition rather than tied to individual / entries: /path/to/block 1000 ... This patch also adds a parameter --device-weight to virsh command blkiotune for setting/getting blkiotune.weight_device for any hypervisor that supports it. All entries under are concatenated into a single string attribute under virDomain{Get,Set}BlkioParameters, named "device_weight". --- v5: did not include this patch v6: split v4 2/2 into two parts; this part covers just the libvirt.h and virsh changes. Rename public-facing terminology to be "device_weight", not "weight_device", since we are talking about per-device weights and may later add other per-device attributes (no need to propagate cgroups' stupid naming to the user). Rebase to fit in with VIR_TYPED_PARAM_STRING tweaks earlier in series. Should we use just commas for field separation, rather than commas between device and weight but semicolon between device-weight pairs? It would make it much easier to do: virsh blkiotune dom --device-weight /dev/sda,500,/dev/sdb,500 instead of requiring shell quoting: virsh blkiotune dom --device-weight '/dev/sda,500;/dev/sdb,500' Either looks fine to me, but the first is likely better for non-shell savvy users... docs/formatdomain.html.in | 29 - docs/schemas/domaincommon.rng | 12 include/libvirt/libvirt.h.in | 10 +++ src/conf/domain_conf.c| 130 - src/conf/domain_conf.h| 17 + src/libvirt_private.syms |2 + tools/virsh.c | 32 +- tools/virsh.pod |6 ++- 8 files changed, 228 insertions(+), 10 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index cbad196..e848b7d 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -505,6 +505,14 @@ ...... @@ -514,10 +522,25 @@ blkiotune The optionalblkiotune element provides the ability to tune Blkio cgroup tunable parameters for the domain. If this is -omitted, it defaults to the OS provided defaults. +omitted, it defaults to the OS provided +defaults.Since 0.8.8 weight - The optionalweight element is the I/O weight of the -guest. The value should be in range [100, 1000]. + The optionalweight element is the overall I/O +weight of the guest. The value should be in the range [100, +1000]. +device +The domain may have multipledevice elements +that further tune the weights for each host block device in +use by the domain. Note that +multipleguest disks can share a +single host block device, if they are backed by files within +the same host file system, which is why this tuning parameter +is at the global domain level rather than associated with each +guest disk device. Eachdevice element has two +mandatory sub-elements,path describing the +absolute path of the device, andweight giving +the relative weight of that device, in the range [100, +1000].Since 0.9.7 diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index b6f858e..6f96fe2 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -328,6 +328,18 @@ + + + + + + + + 'int' or 'unsigned int' ? If there's a definite valid range beyond 'should be [100,1000]', have a data type like 100 1000 + + + + diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index e10a72b..5ae7d10 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1236,6 +1236,16 @@ char * virDomainGetSchedulerType(virDomainPtr domain, #define VIR_DOMAIN_BLKIO_WEIGHT "weight" +/** + * VIR_DOMAIN_BLKIO_DEVICE_WEIGHT: + * + * Macro for the blkio tunable weight_device: it represents the + * per-device weight, as a string. The string is parsed as a + * series of /path/to/device,weight elements, separated by ';'. + */ + +#define VIR_DOMAIN_BLKIO_DEVICE_WEIGHT "device_weight" + /* Set Blkio tunables for the domain*/ int virDomainSetBlkioParameters(virDomainPtr domain, virTypedParameterPtr params, diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 238edfd..e5b5f69 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -603,6 +603,99 @@ VIR_ENUM_IMPL(virDo 800 ++ +/dev/sda +1000 ++ /dev/sdb +500 +
Re: [libvirt] [PATCH 04/10] remove dependence on libnuma
On Thu, Nov 03, 2011 at 12:13:27PM +, Daniel P. Berrange wrote: > On Thu, Nov 03, 2011 at 07:55:19PM +0800, Hu Tao wrote: > > Since we use cpuset to manage numa, we can safely remove dependence > > on libnuma. > > --- > > src/conf/domain_conf.c | 24 +-- > > src/conf/domain_conf.h |1 - > > src/qemu/qemu_process.c | 111 > > --- > > 3 files changed, 1 insertions(+), 135 deletions(-) > > > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > > index 6e2d421..0cf3bb7 100644 > > --- a/src/conf/domain_conf.c > > +++ b/src/conf/domain_conf.c > > @@ -583,11 +583,6 @@ VIR_ENUM_IMPL(virDomainTimerMode, > > VIR_DOMAIN_TIMER_MODE_LAST, > >"paravirt", > >"smpsafe"); > > > > -VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST, > > - "strict", > > - "preferred", > > - "interleave"); > > - > > VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST, > >"default", > >"mandatory", > > @@ -6834,20 +6829,6 @@ static virDomainDefPtr > > virDomainDefParseXML(virCapsPtr caps, > > "%s", _("nodeset for NUMA memory tuning > > must be set")); > > goto error; > > } > > - > > -tmp = virXPathString("string(./numatune/memory/@mode)", ctxt); > > -if (tmp) { > > -if ((def->numatune.memory.mode = > > -virDomainNumatuneMemModeTypeFromString(tmp)) < 0) { > > -virDomainReportError(VIR_ERR_INTERNAL_ERROR, > > -_("Unsupported NUMA memory tuning mode > > '%s'"), > > -tmp); > > -goto error; > > -} > > -VIR_FREE(tmp); > > -} else { > > -def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT; > > -} > > } > > > > n = virXPathNodeSet("./features/*", ctxt, &nodes); > > @@ -10882,7 +10863,6 @@ virDomainDefFormatInternal(virDomainDefPtr def, > > virBufferAddLit(buf, " \n"); > > > > if (def->numatune.memory.nodemask) { > > -const char *mode; > > char *nodemask = NULL; > > > > virBufferAddLit(buf, " \n"); > > @@ -10894,9 +10874,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, > > goto cleanup; > > } > > > > -mode = > > virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode); > > -virBufferAsprintf(buf, "\n", > > - mode, nodemask); > > +virBufferAsprintf(buf, "\n", nodemask); > > VIR_FREE(nodemask); > > virBufferAddLit(buf, " \n"); > > } > > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > > index f74f4bb..ca68437 100644 > > --- a/src/conf/domain_conf.h > > +++ b/src/conf/domain_conf.h > > @@ -1353,7 +1353,6 @@ typedef virDomainNumatuneDef *virDomainNumatuneDefPtr; > > struct _virDomainNumatuneDef { > > struct { > > char *nodemask; > > -int mode; > > } memory; > > > > /* Future NUMA tuning related stuff should go here. */ > > You can't remove this stuff from the XML - this is part of our public > stability guarentee. The way it is modelled is not specific to libnuma > anyway, so there shouldn't be this tie. > > > > diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c > > index 47164f7..5969b34 100644 > > --- a/src/qemu/qemu_process.c > > +++ b/src/qemu/qemu_process.c > > @@ -39,11 +39,6 @@ > > #include "qemu_bridge_filter.h" > > #include "qemu_migration.h" > > > > -#if HAVE_NUMACTL > > -# define NUMA_VERSION1_COMPATIBILITY 1 > > -# include > > -#endif > > - > > #include "datatypes.h" > > #include "logging.h" > > #include "virterror_internal.h" > > @@ -1314,109 +1309,6 @@ qemuProcessDetectVcpuPIDs(struct qemud_driver > > *driver, > > return 0; > > } > > > > - > > -/* > > - * Set NUMA memory policy for qemu process, to be run between > > - * fork/exec of QEMU only. > > - */ > > -#if HAVE_NUMACTL > > -static int > > -qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm) > > -{ > > -nodemask_t mask; > > -int mode = -1; > > -int node = -1; > > -int ret = -1; > > -int i = 0; > > -int maxnode = 0; > > -bool warned = false; > > - > > -if (!vm->def->numatune.memory.nodemask) > > -return 0; > > - > > -VIR_DEBUG("Setting NUMA memory policy"); > > - > > -if (numa_available() < 0) { > > -qemuReportError(VIR_ERR_INTERNAL_ERROR, > > -"%s", _("Host kernel is not aware of NUMA.")); > > -return -1; > > -} > > - > > -maxnode = numa_max_node() + 1; > > - > > -/* Convert nodemask to NUMA bitmask. */ > > -nodemask_zero(&mask); > > -for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) { > > -if (vm->def->numatune.memory.nodemask[i]) { > > -