Re: [libvirt] PATCH: OpenVZ bridge support
On Fri, Nov 14, 2008 at 07:26:23PM +0300, Evgeniy Sokolov wrote: this condition make container config completely broken. as the patch is already commited, here is fix. Thanks, I've applied your fix. diff -u -r1.49 openvz_conf.c --- openvz_conf.c 12 Nov 2008 16:35:47 - 1.49 +++ openvz_conf.c 14 Nov 2008 16:14:24 - @@ -484,8 +484,7 @@ if (openvz_readline(fd, line, sizeof(line)) = 0) break; -if (!STRPREFIX(line, param) -line[strlen(param)] == '=') { +if (!(STRPREFIX(line, param) line[strlen(param)] == '=')) { if (safewrite(temp_fd, line, strlen(line)) != strlen(line)) goto error; Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] PATCH: Add domain event detail information
On Fri, Nov 14, 2008 at 05:44:29PM +, Daniel P. Berrange wrote: As per our earlier discussion today, this patch expands the callback for domain events so that it also gets a event type specific 'detail' field. This is also kept as an int, and we define enumerations for the possible values associated with each type. [...] Okay, that made the overall callbacks set clearer, ACK If a event type has no detail, 0 is passed. Actually I would define a detail enum for all event type just to make clear what the value will be and expose how it's intended to be extended if needed. I don't make use of 'CRASHED' in QEMU driver yet. It might be useful in Xen though - when a PV guest crashes, Xen stops the domain running, but leaves it there in a shutoff state, but marked as crashed. Now using the C event-test program you can see the effects: myDomainEventCallback1 EVENT: Domain F9x86_64(2) Started Booted myDomainEventCallback2 EVENT: Domain F9x86_64(2) Started Booted myDomainEventCallback1 EVENT: Domain F9x86_64(-1) Stopped Destroyed myDomainEventCallback2 EVENT: Domain F9x86_64(-1) Stopped Destroyed myDomainEventCallback1 EVENT: Domain F9x86_64(3) Started Booted myDomainEventCallback2 EVENT: Domain F9x86_64(3) Started Booted myDomainEventCallback1 EVENT: Domain F9x86_64(3) Suspended myDomainEventCallback2 EVENT: Domain F9x86_64(3) Suspended myDomainEventCallback1 EVENT: Domain F9x86_64(3) Resumed myDomainEventCallback2 EVENT: Domain F9x86_64(3) Resumed myDomainEventCallback1 EVENT: Domain F9x86_64(-1) Stopped Shutdown myDomainEventCallback2 EVENT: Domain F9x86_64(-1) Stopped Shutdown Of the following sequence of actions virsh start F9x86_64 virsh destroy F9x86_64 virsh start F9x86_64 virsh suspend F9x86_64 virsh resume F9x86_64 virsh shutdown F9x86_64 For the last 'shutdown' operation, you'll see the same if you just run a graceful shutdown inside the guest itself. okay NB, I've not tested saved/restored because my install of KVM is not new enough to support that correctly, but I expect it to work without trouble. Likewise for migration. A word about migration... - The destination host first gets a STARTED event, with detail MIGRATED when it starts running - The source host then gets a STOPPED event with detail MIGRATED when it completes What about 'live' migration, i.e. events sent when the migration flows begin but the domain is stil running. I don't know if KVM has this but on Xen I would expect to be able to notice this. On the target host that could be indicated by SUSPENDED + VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED because it will consume the memory resource like a suspended domain but no actual CPU cycle (well except for migration itself). On the source host this is a bit harder to indicate, maybe this isn't needed as the resource usage doesn't really change at that point. - The destination host then gets a RESUMED event, on success, and a STOPPED event with detail FAILED if migration aborts. okay +static const char *eventDetailToString(int event, int detail) { +const char *ret = ; +switch(event) { +case VIR_DOMAIN_EVENT_DEFINED: +if (detail == VIR_DOMAIN_EVENT_DEFINED_ADDED) +ret = Added; +else if (detail == VIR_DOMAIN_EVENT_DEFINED_UPDATED) +ret = Updated; +break; +case VIR_DOMAIN_EVENT_STARTED: +switch (detail) { +case VIR_DOMAIN_EVENT_STARTED_BOOTED: +ret = Booted; +break; +case VIR_DOMAIN_EVENT_STARTED_MIGRATED: +ret = Migrated; +break; +case VIR_DOMAIN_EVENT_STARTED_RESTORED: +ret = Restored; +break; +} +break; +case VIR_DOMAIN_EVENT_STOPPED: +switch (detail) { +case VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN: +ret = Shutdown; +break; +case VIR_DOMAIN_EVENT_STOPPED_DESTROYED: +ret = Destroyed; +break; +case VIR_DOMAIN_EVENT_STOPPED_CRASHED: +ret = Crashed; +break; +case VIR_DOMAIN_EVENT_STOPPED_MIGRATED: +ret = Migrated; +break; +case VIR_DOMAIN_EVENT_STOPPED_SAVED: +ret = Failed; +break; +case VIR_DOMAIN_EVENT_STOPPED_FAILED: +ret = Failed; +break; +} +break; } return ret; One more reason to add enums for all cases would be to catch here with a warning missing addition to the enums. [...] Patch looks fine to me, I would just add enums for all type but I think this is still okay as-is too as this doesn't change the API/ABI in an incompatible way. Daniel -- Daniel
Re: [libvirt] PATCH: Support events for define/undefine in QEMU
On Fri, Nov 14, 2008 at 05:51:22PM +, Daniel P. Berrange wrote: This patch adds support for the DEFINED and UNDEFINED events in the QEMU drive. This was more involved than I expected, because when the daemon gets SIGHUP it re-loads config files and we need to broadcast events for each new config file it finds. So I had to add a callback to the internal virDomainLoadAllConfigs method. okay, The LoadConfig method also had a bogus line of code resetting the domain state to SHUTOFF, which made all your active VMs suddenlly appear inactive, after the daemon got SIGHUP ! whoops :-) Looks fine, +1 Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ [EMAIL PROTECTED] | 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: 7/12: Public API for node devices
On Fri, Nov 14, 2008 at 01:57:26PM -0500, David Lively wrote: On Fri, 2008-11-14 at 13:28 +, Daniel P. Berrange wrote: On Fri, Nov 14, 2008 at 12:46:09PM +, Mark McLoughlin wrote: On Thu, 2008-11-13 at 17:30 +, Daniel P. Berrange wrote: This patch is the public API parts of the node device enumeration code. No changes since David's last submission of this, except for some Makefile tweaks + +int virNodeNumOfDevices (virConnectPtr conn, + unsigned int flags); + +int virNodeListDevices (virConnectPtr conn, + char **const names, + int maxnames, + unsigned int flags); + +int virNodeNumOfDevicesByCap (virConnectPtr conn, + const char *cap, + unsigned int flags); + +int virNodeListDevicesByCap (virConnectPtr conn, + const char *cap, + char **const names, + int maxnames, + unsigned int flags); How about combining these two sets of functions and if the capability type isn't supplied list all devices? Yes, we could just remove the ByCap APIs, and add the 'const char *cap' arg to the first two APIs, allowing NULL. I like this idea as well. Okay, then let's do this ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ [EMAIL PROTECTED] | 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: Add domain event detail information
On Mon, Nov 17, 2008 at 01:03:29PM +0100, Daniel Veillard wrote: On Fri, Nov 14, 2008 at 05:44:29PM +, Daniel P. Berrange wrote: As per our earlier discussion today, this patch expands the callback for domain events so that it also gets a event type specific 'detail' field. This is also kept as an int, and we define enumerations for the possible values associated with each type. [...] Okay, that made the overall callbacks set clearer, ACK If a event type has no detail, 0 is passed. Actually I would define a detail enum for all event type just to make clear what the value will be and expose how it's intended to be extended if needed. I don't make use of 'CRASHED' in QEMU driver yet. It might be useful in Xen though - when a PV guest crashes, Xen stops the domain running, but leaves it there in a shutoff state, but marked as crashed. Now using the C event-test program you can see the effects: myDomainEventCallback1 EVENT: Domain F9x86_64(2) Started Booted myDomainEventCallback2 EVENT: Domain F9x86_64(2) Started Booted myDomainEventCallback1 EVENT: Domain F9x86_64(-1) Stopped Destroyed myDomainEventCallback2 EVENT: Domain F9x86_64(-1) Stopped Destroyed myDomainEventCallback1 EVENT: Domain F9x86_64(3) Started Booted myDomainEventCallback2 EVENT: Domain F9x86_64(3) Started Booted myDomainEventCallback1 EVENT: Domain F9x86_64(3) Suspended myDomainEventCallback2 EVENT: Domain F9x86_64(3) Suspended myDomainEventCallback1 EVENT: Domain F9x86_64(3) Resumed myDomainEventCallback2 EVENT: Domain F9x86_64(3) Resumed myDomainEventCallback1 EVENT: Domain F9x86_64(-1) Stopped Shutdown myDomainEventCallback2 EVENT: Domain F9x86_64(-1) Stopped Shutdown Of the following sequence of actions virsh start F9x86_64 virsh destroy F9x86_64 virsh start F9x86_64 virsh suspend F9x86_64 virsh resume F9x86_64 virsh shutdown F9x86_64 For the last 'shutdown' operation, you'll see the same if you just run a graceful shutdown inside the guest itself. okay NB, I've not tested saved/restored because my install of KVM is not new enough to support that correctly, but I expect it to work without trouble. Likewise for migration. A word about migration... - The destination host first gets a STARTED event, with detail MIGRATED when it starts running - The source host then gets a STOPPED event with detail MIGRATED when it completes What about 'live' migration, i.e. events sent when the migration flows begin but the domain is stil running. I don't know if KVM has this but on Xen I would expect to be able to notice this. On the target host that could be indicated by SUSPENDED + VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED because it will consume the memory resource like a suspended domain but no actual CPU cycle (well except for migration itself). On the source host this is a bit harder to indicate, maybe this isn't needed as the resource usage doesn't really change at that point. The problem with live migration is that, by definition, there is no change in the domain on the source host until migration is complete. It remains in the 'running' state the entire time and does not undergo any lifecycle transitions, so there's no event we could generate for the start of a migrate event on the source. Only the destination host gets an explicit lifecycle change at the start end of migration operation. For non-live migration of course, you would get a transition from the running state, to the paused state on the source host when migration starts, and that actually does mean we need to define another enum for 'detail' on the 'suspended' and 'resumed' events too. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] PATCH: 7/12: Public API for node devices
On Fri, 2008-11-14 at 13:28 +, Daniel P. Berrange wrote: On Fri, Nov 14, 2008 at 12:46:09PM +, Mark McLoughlin wrote: On Thu, 2008-11-13 at 17:30 +, Daniel P. Berrange wrote: + +virNodeDevicePtrvirNodeDeviceLookupByName (virConnectPtr conn, + const char *name); + +const char *virNodeDeviceGetName (virNodeDevicePtr dev); + How stable are these names? e.g. should we say that no-one should rely on the format of the name and that the name of a given device could change across node reboots? Even if HAL guarantees the name to be stable (does it?), if you switch between HAL and DevKit it could change, right? I don't think HAL explicitly guarentees it, it merely happens to have been stable AFAICT. The naming is definitely completely different between HAL and DevKit. This is probably my biggest worry with the impl so far - some app using it will need to have a stable identifier for a device and we won't be providing it. I don't have a good understanding of what this API will be used for, aside from device passthrough. I wouldn't be surprised if we decide that it makes sense to allow using higher level names for passthrough, rather than e.g. PCI IDs - i.e. passthrough device with mac address X rather than vendor:device or bus:dev.func. In that case, you need the names to be stable, but you don't necessarily need them to have a predictable enough structure that people can construct a name themselves. We could invent our own stable naming scheme for devices - the scheme would vary per capability - eg for PCI devices we can use the bus, function, slot identifiers. USB is hard to guarentee though - if a device is plugged in unpluged plugged in again it won't get the same address, and there's no real other identifier we can rely on for this. I think the key thing in the short term is that we make it clear that device names are completely unstable identifiers with no structure or meaning that can be relied upon. I'd almost be tempted to append a few bytes of randomness to the names for now ... Separating the physical from logical devices gives us the opportunity to define more stable names for devices with certain capabilities. eg, for a USB network card, its hard to invent a stable name at the level of the USB device, but for the logical NIC you can easily invent a name based off the MAC address. Another way would be to have multiple names for each device, by aggregating the PCI device and network device capabilities into a single object. The only really advantage to that would be that given a less specialized name for a device, you could easily iterate over the more specialized names. But if we need that we could add virNodeDeviceListChildren() I guess. IOW, the current scheme will probably work out just fine ... Cheers, Mark. -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] PATCH: Add domain event detail information
On Mon, Nov 17, 2008 at 01:27:26PM +, Daniel P. Berrange wrote: On Mon, Nov 17, 2008 at 01:05:30PM +, Daniel P. Berrange wrote: On Mon, Nov 17, 2008 at 01:03:29PM +0100, Daniel Veillard wrote: On Fri, Nov 14, 2008 at 05:44:29PM +, Daniel P. Berrange wrote: As per our earlier discussion today, this patch expands the callback for domain events so that it also gets a event type specific 'detail' field. This is also kept as an int, and we define enumerations for the possible values associated with each type. [...] Okay, that made the overall callbacks set clearer, ACK If a event type has no detail, 0 is passed. Actually I would define a detail enum for all event type just to make clear what the value will be and expose how it's intended to be extended if needed. This new patch does that now. Okay, just one minor suggestion, in eventDetailToString() make a case for all event types and drop default: so the compiler warns us if we forgot to update the function when there is an addition to one of the enums. A word about migration... - The destination host first gets a STARTED event, with detail MIGRATED when it starts running - The source host then gets a STOPPED event with detail MIGRATED when it completes What about 'live' migration, i.e. events sent when the migration flows begin but the domain is stil running. I don't know if KVM has this but on Xen I would expect to be able to notice this. On the target host that could be indicated by SUSPENDED + VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED because it will consume the memory resource like a suspended domain but no actual CPU cycle (well except for migration itself). On the source host this is a bit harder to indicate, maybe this isn't needed as the resource usage doesn't really change at that point. The problem with live migration is that, by definition, there is no change in the domain on the source host until migration is complete. It remains in the 'running' state the entire time and does not undergo any lifecycle transitions, so there's no event we could generate for the start of a migrate event on the source. Only the destination host gets an explicit lifecycle change at the start end of migration operation. For non-live migration of course, you would get a transition from the running state, to the paused state on the source host when migration starts, and that actually does mean we need to define another enum for 'detail' on the 'suspended' and 'resumed' events too. Turns out the QEMU migration implementation was incorrectly ignoring the 'flags' argument and doing all migration operations as 'live'. So this patch fixes that, to pause the VM before migration if non-live was requested. It'll emit VIR_DOMAIN_EVENT_SUSPENDED, with detail field value of VIR_DOMAIN_EVENT_SUSPENED_MIGRATED when starting a non-live migration. I also fixed the patch to use VIR_DOMAIN_EVENT_RESUMED_MIGRATED when the migration operation completes on the destination. Okay, +1 Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ [EMAIL PROTECTED] | 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
[libvirt] PATCH: allow to set nvcpus = 0
OpenVZ uses all CPUs available in system - by default (number of CPUs did not set) - number of CPUs = 0 Currenty, libvirt don't allow to set nvcpus = 0. Attached patch removes limitation in libvirt set nvcpu = 0, but add it to each driver which allow to set number of virtual CPU. For OpenVZ set default number of CPUs = 0. Index: libvirt.c === RCS file: /data/cvs/libvirt/src/libvirt.c,v retrieving revision 1.174 diff -u -p -r1.174 libvirt.c --- libvirt.c 17 Nov 2008 12:18:18 - 1.174 +++ libvirt.c 17 Nov 2008 15:11:12 - @@ -3124,10 +3124,6 @@ virDomainSetVcpus(virDomainPtr domain, u return (-1); } -if (nvcpus 1) { -virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__); -return (-1); -} conn = domain-conn; if (conn-driver-domainSetVcpus) Index: openvz_conf.c === RCS file: /data/cvs/libvirt/src/openvz_conf.c,v retrieving revision 1.50 diff -u -p -r1.50 openvz_conf.c --- openvz_conf.c 17 Nov 2008 09:55:59 - 1.50 +++ openvz_conf.c 17 Nov 2008 15:11:12 - @@ -428,7 +428,7 @@ int openvzLoadDomains(struct openvz_driv } else if (ret 0) { dom-def-vcpus = strtoI(temp); } else { -dom-def-vcpus = 1; +dom-def-vcpus = 0; } /* XXX load rest of VM config data */ Index: openvz_driver.c === RCS file: /data/cvs/libvirt/src/openvz_driver.c,v retrieving revision 1.60 diff -u -p -r1.60 openvz_driver.c --- openvz_driver.c 17 Nov 2008 11:44:51 - 1.60 +++ openvz_driver.c 17 Nov 2008 15:11:12 - @@ -842,12 +842,6 @@ static int openvzDomainSetVcpus(virDomai return -1; } -if (nvcpus = 0) { -openvzError(conn, VIR_ERR_INTERNAL_ERROR, -%s, _(VCPUs should be = 1)); -return -1; -} - snprintf(str_vcpus, 31, %d, nvcpus); str_vcpus[31] = '\0'; Index: qemu_driver.c === RCS file: /data/cvs/libvirt/src/qemu_driver.c,v retrieving revision 1.153 diff -u -p -r1.153 qemu_driver.c --- qemu_driver.c 17 Nov 2008 11:44:51 - 1.153 +++ qemu_driver.c 17 Nov 2008 15:11:12 - @@ -1969,6 +1969,12 @@ static int qemudDomainSetVcpus(virDomain return -1; } +if (nvcpus 1) { +qemudReportError(dom-conn, dom, NULL, VIR_ERR_INVALID_ARG, + _(nvcpus '%u'), nvcpus); +return -1; +} + if (virDomainIsActive(vm)) { qemudReportError(dom-conn, dom, NULL, VIR_ERR_NO_SUPPORT, %s, _(cannot change vcpu count of an active domain)); Index: test.c === RCS file: /data/cvs/libvirt/src/test.c,v retrieving revision 1.96 diff -u -p -r1.96 test.c --- test.c 17 Nov 2008 11:44:51 - 1.96 +++ test.c 17 Nov 2008 15:11:13 - @@ -1180,7 +1180,7 @@ static int testSetVcpus(virDomainPtr dom GET_DOMAIN(domain, -1); /* We allow more cpus in guest than host */ -if (nrCpus 32) { +if (nrCpus 32 || nrCpus 1) { testError(domain-conn, VIR_ERR_INVALID_ARG, __FUNCTION__); return (-1); } Index: virsh.c === RCS file: /data/cvs/libvirt/src/virsh.c,v retrieving revision 1.172 diff -u -p -r1.172 virsh.c --- virsh.c 17 Nov 2008 11:03:25 - 1.172 +++ virsh.c 17 Nov 2008 15:11:13 - @@ -1897,7 +1897,7 @@ cmdSetvcpus(vshControl *ctl, const vshCm return FALSE; count = vshCommandOptInt(cmd, count, count); -if (count = 0) { +if (count 0) { vshError(ctl, FALSE, %s, _(Invalid number of virtual CPUs.)); virDomainFree(dom); return FALSE; Index: xen_unified.c === RCS file: /data/cvs/libvirt/src/xen_unified.c,v retrieving revision 1.61 diff -u -p -r1.61 xen_unified.c --- xen_unified.c 17 Nov 2008 11:44:51 - 1.61 +++ xen_unified.c 17 Nov 2008 15:11:13 - @@ -884,6 +884,11 @@ xenUnifiedDomainSetVcpus (virDomainPtr d GET_PRIVATE(dom-conn); int i; +if (nvcpus 1) { +xenUnifiedError (dom-conn, VIR_ERR_INVALID_ARG, __FUNCTION__); +return -1; +} + /* Try non-hypervisor methods first, then hypervisor direct method * as a last resort. */ -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] PATCH: allow to set nvcpus = 0
On Mon, Nov 17, 2008 at 06:44:07PM +0300, Evgeniy Sokolov wrote: OpenVZ uses all CPUs available in system - by default (number of CPUs did not set) - number of CPUs = 0 Currenty, libvirt don't allow to set nvcpus = 0 Attached patch removes limitation in libvirt set nvcpu = 0, but add it to each driver which allow to set number of virtual CPU. For OpenVZ set default number of CPUs = 0. This is the wrong way to handle this. If OpenVZ allows the container to use all the host CPUs, then the vCPUs number should reflect the number of pCPUs, not 0. So when loading the openvz config, if there is no CPUS= setting in the config file, the driver should fill in the number of host pCPUs. Likewise, when setting the openvz config, if the vCPUs in the XML is = pCPUs, then it should just leave out the CPUS= setting, so OpenVZ uses all CPUs. Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] PATCH: Add domain event detail information
On Mon, Nov 17, 2008 at 03:17:42PM +0100, Daniel Veillard wrote: On Mon, Nov 17, 2008 at 01:27:26PM +, Daniel P. Berrange wrote: On Mon, Nov 17, 2008 at 01:05:30PM +, Daniel P. Berrange wrote: On Mon, Nov 17, 2008 at 01:03:29PM +0100, Daniel Veillard wrote: On Fri, Nov 14, 2008 at 05:44:29PM +, Daniel P. Berrange wrote: As per our earlier discussion today, this patch expands the callback for domain events so that it also gets a event type specific 'detail' field. This is also kept as an int, and we define enumerations for the possible values associated with each type. [...] Okay, that made the overall callbacks set clearer, ACK If a event type has no detail, 0 is passed. Actually I would define a detail enum for all event type just to make clear what the value will be and expose how it's intended to be extended if needed. This new patch does that now. Okay, just one minor suggestion, in eventDetailToString() make a case for all event types and drop default: so the compiler warns us if we forgot to update the function when there is an addition to one of the enums. Ok, made that change comitted it. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] PATCH: Support events for define/undefine in QEMU
On Mon, Nov 17, 2008 at 01:05:42PM +0100, Daniel Veillard wrote: On Fri, Nov 14, 2008 at 05:51:22PM +, Daniel P. Berrange wrote: This patch adds support for the DEFINED and UNDEFINED events in the QEMU drive. This was more involved than I expected, because when the daemon gets SIGHUP it re-loads config files and we need to broadcast events for each new config file it finds. So I had to add a callback to the internal virDomainLoadAllConfigs method. okay, The LoadConfig method also had a bogus line of code resetting the domain state to SHUTOFF, which made all your active VMs suddenlly appear inactive, after the daemon got SIGHUP ! whoops :-) Looks fine, +1 I've comitted this patch too Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] PATCH: 0/12: Modular build node devices integration
On Thu, Nov 13, 2008 at 05:19:07PM +, Daniel P. Berrange wrote: The following series of patches are updated version of patches 7-11 of this series http://www.redhat.com/archives/libvir-list/2008-October/msg00718.html And integrating David Lively's node device patches ontop I've comitted patches 1-5 of this series so far. That's everything upto the dlopen() patch. I'll go through an make the tweaks Mark suggested for node device patches next Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] PATCH: Change signature of virEventAddHandle to allow multiple calls per FD
As discussed previously, this patch changes the semantics of the public API for dealing with file handle watches. Previously we would track the watch based on the file handle number directly. With this change, the virEventAddHandle method returns an integer 'watch' number. This watch number is required when unregistering or updating a watch. The watch is also passed into the callback when an event occurrs. This allows for multiple watches to be registered against the same file descriptor. There was quite alot of fallout from this patch requiring many callers to be updated to comply with the new semantics. examples/domain-events/events-c/event-test.c |7 +- examples/domain-events/events-python/event-test.py | 12 ++-- include/libvirt/libvirt.h | 20 --- include/libvirt/libvirt.h.in | 20 --- python/libvir.c|8 +- qemud/event.c | 27 ++--- qemud/event.h | 10 +-- qemud/mdns.c | 16 +++-- qemud/qemud.c | 59 +++-- qemud/qemud.h |2 src/domain_conf.h |3 + src/event.c|8 +- src/event.h|8 +- src/lxc_driver.c | 25 +--- src/qemu_driver.c | 43 --- src/remote_internal.c | 27 ++--- 16 files changed, 176 insertions(+), 119 deletions(-) Daniel diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -40,8 +40,8 @@ int myDomainEventCallback2 (virConnectPt int event, int detail, void *opaque); int myEventAddHandleFunc (int fd, int event, virEventHandleCallback cb, void *opaque); -void myEventUpdateHandleFunc(int fd, int event); -int myEventRemoveHandleFunc(int fd); +void myEventUpdateHandleFunc(int watch, int event); +int myEventRemoveHandleFunc(int watch); int myEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb, void *opaque); @@ -308,7 +308,8 @@ int main(int argc, char **argv) } if(h_cb) { -h_cb(h_fd, +h_cb(0, + h_fd, myPollEventToEventHandleType(pfd.revents h_event), h_opaque); } diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -75,19 +75,19 @@ def myAddHandle(fd, events, cb, opaque): mypoll.register(fd, myEventHandleTypeToPollEvent(events)) -def myUpdateHandle(fd, event): +def myUpdateHandle(watch, event): global h_fd, h_events #print Updating Handle %s %s % (str(fd), str(events)) h_fd = fd h_events = event -mypoll.unregister(fd) -mypoll.register(fd, myEventHandleTypeToPollEvent(event)) +mypoll.unregister(watch) +mypoll.register(watch, myEventHandleTypeToPollEvent(event)) -def myRemoveHandle(fd): +def myRemoveHandle(watch): global h_fd #print Removing Handle %s % str(fd) h_fd = 0 -mypoll.unregister(fd) +mypoll.unregister(watch) def myAddTimeout(timeout, cb, opaque): global t_active, t_timeout, t_cb, t_opaque @@ -175,7 +175,7 @@ def main(): if h_cb != None: #print Invoking Handle CB -h_cb(h_fd, myPollEventToEventHandleType(revents h_events), +h_cb(0, h_fd, myPollEventToEventHandleType(revents h_events), h_opaque[0], h_opaque[1]) #print DEBUG EXIT diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -1121,13 +1121,15 @@ typedef enum { /** * virEventHandleCallback: * + * @watch: watch on which the event occurred * @fd: file handle on which the event occurred * @events: bitset of events from virEventHandleType constants * @opaque: user data registered with handle * - * callback for receiving file handle events + * Callback for receiving file handle events. The callback will + * be invoked once for each event which is pending. */ -typedef void (*virEventHandleCallback)(int fd, int events, void *opaque); +typedef void (*virEventHandleCallback)(int watch, int fd, int events, void *opaque); /** * virEventAddHandleFunc: @@ -1137,29 +1139,33 @@ typedef void (*virEventHandleCallback)(i * @opaque: user data to pass to the callback * * Part of the
[libvirt] PATCH: Pass a callback for freeing opaque data when registering handle/timer events
When registering for a file descriptor event, or timer events, the event callback has an associated 'void *opaque' data blob. When removing a registered event, the removal may be done asynchronously to allow safe removal from within a callback. This means that it is not safe for the application to assume they can free the 'void *opaque' data immediately after calling virEventRemoveHandle/Timer. So, we extend the AddHandle/Timer method to allow a 2nd callback to be provided. This callback is used to free the 'void *opaque' data at the appropriate (safe) point in time. examples/domain-events/events-c/event-test.c | 24 ++-- include/libvirt/libvirt.h| 52 --- include/libvirt/libvirt.h.in | 52 --- python/libvir.c | 25 +--- python/libvirt_wrap.h|2 + python/types.c | 32 qemud/event.c| 19 - qemud/event.h|9 +++- qemud/mdns.c | 22 +-- qemud/qemud.c|9 src/event.c | 14 +-- src/event.h |9 +++- src/lxc_driver.c |1 src/qemu_driver.c|2 + src/remote_internal.c|2 + 15 files changed, 240 insertions(+), 34 deletions(-) Daniel diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -22,6 +22,7 @@ int h_fd = 0; int h_fd = 0; virEventHandleType h_event = 0; virEventHandleCallback h_cb = NULL; +virEventHandleFreeFunc h_ff = NULL; void *h_opaque = NULL; /* timeout globals */ @@ -29,6 +30,7 @@ int t_active = 0; int t_active = 0; int t_timeout = -1; virEventTimeoutCallback t_cb = NULL; +virEventTimeoutFreeFunc t_ff = NULL; void *t_opaque = NULL; @@ -39,11 +41,15 @@ int myDomainEventCallback2 (virConnectPt int myDomainEventCallback2 (virConnectPtr conn, virDomainPtr dom, int event, int detail, void *opaque); int myEventAddHandleFunc (int fd, int event, - virEventHandleCallback cb, void *opaque); + virEventHandleCallback cb, + virEventHandleFreeFunc ff, + void *opaque); void myEventUpdateHandleFunc(int watch, int event); int myEventRemoveHandleFunc(int watch); -int myEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb, +int myEventAddTimeoutFunc(int timeout, + virEventTimeoutCallback cb, + virEventTimeoutFreeFunc ff, void *opaque); void myEventUpdateTimeoutFunc(int timer, int timout); int myEventRemoveTimeoutFunc(int timer); @@ -199,12 +205,15 @@ virEventHandleType myPollEventToEventHan } int myEventAddHandleFunc(int fd, int event, - virEventHandleCallback cb, void *opaque) + virEventHandleCallback cb, + virEventHandleFreeFunc ff, + void *opaque) { DEBUG(Add handle %d %d %p %p, fd, event, cb, opaque); h_fd = fd; h_event = myEventHandleTypeToPollEvent(event); h_cb = cb; +h_ff = ff; h_opaque = opaque; return 0; } @@ -220,16 +229,21 @@ int myEventRemoveHandleFunc(int fd) { DEBUG(Removed Handle %d, fd); h_fd = 0; +if (h_ff) + (h_ff)(h_opaque); return 0; } -int myEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb, +int myEventAddTimeoutFunc(int timeout, + virEventTimeoutCallback cb, + virEventTimeoutFreeFunc ff, void *opaque) { DEBUG(Adding Timeout %d %p %p, timeout, cb, opaque); t_active = 1; t_timeout = timeout; t_cb = cb; +t_ff = ff; t_opaque = opaque; return 0; } @@ -244,6 +258,8 @@ int myEventRemoveTimeoutFunc(int timer) { DEBUG(Timeout removed %d, timer); t_active = 0; + if (t_ff) + (t_ff)(t_opaque); return 0; } diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -1132,21 +1132,39 @@ typedef void (*virEventHandleCallback)(i typedef void (*virEventHandleCallback)(int watch, int fd, int events, void *opaque); /** + * virEventHandleFreeFunc: + * + * @opaque: user data to be free'd + * + * Callback invoked when memory associated with a file handle + * watch is being freed. Will be passed a pointer to the application's + * opaque data blob. + */ +typedef void (*virEventHandleFreeFunc)(void
Re: [libvirt] PATCH: Change signature of virEventAddHandle to allow multiple calls per FD
well, that was a lot of fallout. All looks necessary though. +1 from me Daniel P. Berrange wrote on 11/17/2008 11:58 AM: As discussed previously, this patch changes the semantics of the public API for dealing with file handle watches. Previously we would track the watch based on the file handle number directly. With this change, the virEventAddHandle method returns an integer 'watch' number. This watch number is required when unregistering or updating a watch. The watch is also passed into the callback when an event occurrs. This allows for multiple watches to be registered against the same file descriptor. There was quite alot of fallout from this patch requiring many callers to be updated to comply with the new semantics. examples/domain-events/events-c/event-test.c |7 +- examples/domain-events/events-python/event-test.py | 12 ++-- include/libvirt/libvirt.h | 20 --- include/libvirt/libvirt.h.in | 20 --- python/libvir.c|8 +- qemud/event.c | 27 ++--- qemud/event.h | 10 +-- qemud/mdns.c | 16 +++-- qemud/qemud.c | 59 +++-- qemud/qemud.h |2 src/domain_conf.h |3 + src/event.c|8 +- src/event.h|8 +- src/lxc_driver.c | 25 +--- src/qemu_driver.c | 43 --- src/remote_internal.c | 27 ++--- 16 files changed, 176 insertions(+), 119 deletions(-) Daniel diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -40,8 +40,8 @@ int myDomainEventCallback2 (virConnectPt int event, int detail, void *opaque); int myEventAddHandleFunc (int fd, int event, virEventHandleCallback cb, void *opaque); -void myEventUpdateHandleFunc(int fd, int event); -int myEventRemoveHandleFunc(int fd); +void myEventUpdateHandleFunc(int watch, int event); +int myEventRemoveHandleFunc(int watch); int myEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb, void *opaque); @@ -308,7 +308,8 @@ int main(int argc, char **argv) } if(h_cb) { -h_cb(h_fd, +h_cb(0, + h_fd, myPollEventToEventHandleType(pfd.revents h_event), h_opaque); } diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -75,19 +75,19 @@ def myAddHandle(fd, events, cb, opaque): mypoll.register(fd, myEventHandleTypeToPollEvent(events)) -def myUpdateHandle(fd, event): +def myUpdateHandle(watch, event): global h_fd, h_events #print Updating Handle %s %s % (str(fd), str(events)) h_fd = fd h_events = event -mypoll.unregister(fd) -mypoll.register(fd, myEventHandleTypeToPollEvent(event)) +mypoll.unregister(watch) +mypoll.register(watch, myEventHandleTypeToPollEvent(event)) -def myRemoveHandle(fd): +def myRemoveHandle(watch): global h_fd #print Removing Handle %s % str(fd) h_fd = 0 -mypoll.unregister(fd) +mypoll.unregister(watch) def myAddTimeout(timeout, cb, opaque): global t_active, t_timeout, t_cb, t_opaque @@ -175,7 +175,7 @@ def main(): if h_cb != None: #print Invoking Handle CB -h_cb(h_fd, myPollEventToEventHandleType(revents h_events), +h_cb(0, h_fd, myPollEventToEventHandleType(revents h_events), h_opaque[0], h_opaque[1]) #print DEBUG EXIT diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -1121,13 +1121,15 @@ typedef enum { /** * virEventHandleCallback: * + * @watch: watch on which the event occurred * @fd: file handle on which the event occurred * @events: bitset of events from virEventHandleType constants * @opaque: user data registered with handle * - * callback for receiving file handle events + * Callback for receiving file handle events. The callback will + * be invoked once for each event which is pending. */ -typedef void (*virEventHandleCallback)(int fd, int events, void *opaque); +typedef void
Re: [libvirt] PATCH: 11/12: virsh support
Daniel P. Berrange [EMAIL PROTECTED] wrote: This patch adds two node virsh commands for the node device enumeration APIs. The only change here is to change the command names to have a shorter prefix, nodedev-list and nodedev-dumpxml Daniel diff -r 0136f215fc06 src/virsh.c ... +vshPrint(ctl, %s\n, virNodeDeviceGetXMLDesc(device, 0)); For non-glibc, you can't print that if it's NULL. Also, shouldn't the returned XML be freed? -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Java bindings for domain events
On Fri, 2008-11-14 at 12:59 -0500, David Lively wrote: On Fri, 2008-11-14 at 17:09 +, Daniel P. Berrange wrote: Or have the virConnectDomainEventRegister method take an extra parameter which is a callbackvoid (*freefunc)(void*). libvirt would just invoke that to free the opaque data chunk. Yeah, I like this better. The dbus(?) API allows an optional destructor (freefunc) to be specified for callback userdata. So let's allow it to be null (in which case we obviously don't call it at remove time). I think we need a similar thing with the event loops APIs for timers and file handle watches, to make it easier to free the opaque data blob they have. Sounds good too. I can make the DomainEvent changes today / this weekend while working on the Java bindings (since I need them to plug the Java leak), and submit them on Monday (or perhaps later today, if I don't get diverted). The attached patch implements this change (adds a freefunc arg to virConnectDomainEventRegister and calls it on Deregister (or Close)). It also modifies the event-test.c example to register a freefunc and deregister callbacks when interrupted or terminated (to verify the freefuncs are properly called). Dave commit 1cacb0944958dbd39f002d99721112ec2b8df7f5 Author: David Lively [EMAIL PROTECTED] Date: Mon Nov 17 15:48:50 2008 -0500 vi-patch: events As discussed on libvir-list, added an extra arg: void (*freefunc)(void *opaque) to virConnectDomainEventRegister. If non-NULL, this function is called by virConnectDomainEventDeregister() and passed the void *opaque argument registered with the callback being removed. diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index 0a741ea..11d62c7 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -1,7 +1,9 @@ #include config.h #include stdio.h +#include stdlib.h #include string.h +#include signal.h #if HAVE_SYS_POLL_H #include sys/types.h @@ -168,6 +170,13 @@ int myDomainEventCallback2 (virConnectPtr conn ATTRIBUTE_UNUSED, return 0; } +static void myFreeFunc(void *opaque) +{ +char *str = opaque; +printf(%s: Freeing [%s]\n, __FUNCTION__, str); +free(str); +} + /* EventImpl Functions */ int myEventHandleTypeToPollEvent(virEventHandleType events) @@ -254,15 +263,27 @@ void usage(const char *pname) printf(%s uri\n, pname); } +int run = 1; + +static void stop(int sig) +{ +printf(Exiting on signal %d\n, sig); +run = 0; +} + + int main(int argc, char **argv) { -int run=1; int sts; +struct sigaction action_stop = { +.sa_handler = stop +}; if(argc 1 STREQ(argv[1],--help)) { usage(argv[0]); return -1; } + virEventRegisterImpl( myEventAddHandleFunc, myEventUpdateHandleFunc, myEventRemoveHandleFunc, @@ -277,11 +298,16 @@ int main(int argc, char **argv) return -1; } +sigaction(SIGTERM, action_stop, NULL); +sigaction(SIGINT, action_stop, NULL); + DEBUG0(Registering domain event cbs); /* Add 2 callbacks to prove this works with more than just one */ -virConnectDomainEventRegister(dconn, myDomainEventCallback1, NULL); -virConnectDomainEventRegister(dconn, myDomainEventCallback2, NULL); +virConnectDomainEventRegister(dconn, myDomainEventCallback1, + strdup(callback 1), myFreeFunc); +virConnectDomainEventRegister(dconn, myDomainEventCallback2, + strdup(callback 2), myFreeFunc); while(run) { struct pollfd pfd = { .fd = h_fd, @@ -315,9 +341,15 @@ int main(int argc, char **argv) } +DEBUG0(Deregistering event handlers); +virConnectDomainEventDeregister(dconn, myDomainEventCallback1); +virConnectDomainEventDeregister(dconn, myDomainEventCallback2); + +DEBUG0(Closing connection); if( dconn virConnectClose(dconn)0 ) { printf(error closing\n); } + printf(done\n); return 0; } diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index d1bb154..c56d272 100644 --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -1095,7 +1095,8 @@ typedef int (*virConnectDomainEventCallback)(virConnectPtr conn, int virConnectDomainEventRegister(virConnectPtr conn, virConnectDomainEventCallback cb, - void *opaque); + void *opaque, + void (*freefunc)(void *)); int virConnectDomainEventDeregister(virConnectPtr conn, virConnectDomainEventCallback cb); diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 0ee657a..6a63ef4 100644 --- a/include/libvirt/libvirt.h.in +++
Re: [libvirt] [PATCH] Java bindings for domain events
On Mon, Nov 17, 2008 at 03:55:13PM -0500, David Lively wrote: On Fri, 2008-11-14 at 12:59 -0500, David Lively wrote: On Fri, 2008-11-14 at 17:09 +, Daniel P. Berrange wrote: Or have the virConnectDomainEventRegister method take an extra parameter which is a callbackvoid (*freefunc)(void*). libvirt would just invoke that to free the opaque data chunk. ???Yeah, I like this better. The dbus(?) API allows an optional destructor (freefunc) to be specified for callback userdata. So let's allow it to be null (in which case we obviously don't call it at remove time). I think we need a similar thing with the event loops APIs for timers and file handle watches, to make it easier to free the opaque data blob they have. Sounds good too. I can make the DomainEvent changes today / this weekend while working on the Java bindings (since I need them to plug the Java leak), and submit them on Monday (or perhaps later today, if I don't get diverted). The attached patch implements this change (adds a freefunc arg to virConnectDomainEventRegister and calls it on Deregister (or Close)). It also modifies the event-test.c example to register a freefunc and deregister callbacks when interrupted or terminated (to verify the freefuncs are properly called). Functionally this all looks fine. From a style point of view, we should keep consistency with the other virEventAddHandle func in terms of typing / param ordering. I prefer to have a typedef for the 'freefunc', even though its trivial, because I hate reading function prototypes :-) Whether we have the freefunc, before or after the 'void opaque' in the register method I don't really mind one way or the other as long as we're consistent. Having the freefunc last is probably best, since its very often just going to be NULL. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC PATCH] set tap mtu
Below is a simple PoC for setting a large MTU size on a tap device. With this we are able to improve net i/o throughput substantially (~40% improvement on TX and ~130% improvement on RX). This is just RFC because it's hardcoded to an MTU of 9000 for any tap device. Thoughts on the best way to add this kind of support? diff -up libvirt-0.4.6/src/bridge.c~tap-mtu libvirt-0.4.6/src/bridge.c --- libvirt-0.4.6/src/bridge.c~tap-mtu 2008-08-29 05:19:52.0 -0700 +++ libvirt-0.4.6/src/bridge.c 2008-11-17 18:37:56.0 -0800 @@ -276,6 +276,38 @@ brDeleteInterface(brControl *ctl ATTRIBU #endif /** + * ifSetMtu: + * @ctl: bridge control pointer + * @ifname: interface name to set MTU for + * @mtu: MTU value + * + * This function sets the @mtu for a given interface @ifname. Typically + * used on a tap device to set up for Jumbo Frames. + * + * Returns 0 in case of success or an errno code in case of failure. + */ +static int +ifSetMtu(brControl *ctl, const char *ifname, int mtu) +{ +struct ifreq ifr; +int len; + +if (!ctl || !ifname) +return EINVAL; + +if ((len = strlen(ifname)) = BR_IFNAME_MAXLEN) +return EINVAL; + +memset(ifr, 0, sizeof(struct ifreq)); + +strncpy(ifr.ifr_name, ifname, len); +ifr.ifr_name[len] = '\0'; +ifr.ifr_mtu = mtu; + +return ioctl(ctl-fd, SIOCSIFMTU, ifr) == 0 ? 0 : errno; +} + +/** * brAddTap: * @ctl: bridge control pointer * @bridge: the bridge name @@ -334,6 +366,8 @@ brAddTap(brControl *ctl, } if (ioctl(fd, TUNSETIFF, try) == 0) { +if ((errno = ifSetMtu(ctl, try.ifr_name, 9000))) +goto error; if ((errno = brAddInterface(ctl, bridge, try.ifr_name))) goto error; if ((errno = brSetInterfaceUp(ctl, try.ifr_name, 1))) -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list