Re: [libvirt] [PATCH] qemu: event: Fix retrieval of the service field from graphics events
On Mon, Jun 29, 2015 at 03:17:50PM +0200, Peter Krempa wrote: On Mon, Jun 29, 2015 at 13:47:50 +0100, Daniel Berrange wrote: On Mon, Jun 29, 2015 at 02:42:50PM +0200, Peter Krempa wrote: qemu's event has following format: { timestamp: { seconds: 1435580974, microseconds: 82226 }, event: SPICE_INITIALIZED, data: { server: { auth: none, port: 5900, family: ipv4, host: 127.0.0.1 }, client: { port: 53224, family: ipv4, channel-type: 3, connection-id: 1113096064, host: 127.0.0.1, channel-id: 0, tls: false } } } Our code tried to extract the service field but qemu reports it as port. Hmm, that's somewhat odd - did you check back historical versions of QEMU where this event was first introduced to see if it has always had this name ? It smells like the kind of thing that could have been a regression at some point Actually the regression would be on the VNC side, since VNC uses service and the function that I've modified handles both. I failed to notice that fact at first. I'll post a V2 with dual handling. Hmm, are you saying QEMU uses a different field name when it has VNC vs SPICE ? If so that's a bug in QEMU that needs adressing (though of course we'd have to workaround it in libvirt too now). 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] qemu: event: Fix retrieval of the service field from graphics events
On Mon, Jun 29, 2015 at 14:22:47 +0100, Daniel Berrange wrote: On Mon, Jun 29, 2015 at 03:17:50PM +0200, Peter Krempa wrote: On Mon, Jun 29, 2015 at 13:47:50 +0100, Daniel Berrange wrote: On Mon, Jun 29, 2015 at 02:42:50PM +0200, Peter Krempa wrote: qemu's event has following format: { timestamp: { seconds: 1435580974, microseconds: 82226 }, event: SPICE_INITIALIZED, data: { server: { auth: none, port: 5900, family: ipv4, host: 127.0.0.1 }, client: { port: 53224, family: ipv4, channel-type: 3, connection-id: 1113096064, host: 127.0.0.1, channel-id: 0, tls: false } } } Our code tried to extract the service field but qemu reports it as port. Hmm, that's somewhat odd - did you check back historical versions of QEMU where this event was first introduced to see if it has always had this name ? It smells like the kind of thing that could have been a regression at some point Actually the regression would be on the VNC side, since VNC uses service and the function that I've modified handles both. I failed to notice that fact at first. I'll post a V2 with dual handling. Hmm, are you saying QEMU uses a different field name when it has VNC vs SPICE ? If so that's a bug in QEMU that needs adressing (though of course we'd have to workaround it in libvirt too now). Well, qemu uses different fields but they also use them in different events (VNC_CONNECTED vs SPICE_CONNECTED) with different return structures since spice provides a lot more data. The issue is that libvirt tries to use the same handler for parsing the data. I'm now conflicted whether to duplicate it or do a dual handler for both. If we will ever want to parse more data from that we will need a new function for that. Peter signature.asc Description: Digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-glib PATCHv2 2/5] gobject: Add API to query connection interfaces
Add API to query network interfaces from a connection. --- libvirt-gobject/libvirt-gobject-connection.c | 226 +++ libvirt-gobject/libvirt-gobject-connection.h | 6 +- libvirt-gobject/libvirt-gobject.sym | 5 + 3 files changed, 235 insertions(+), 2 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c index cf073a5..20c43fc 100644 --- a/libvirt-gobject/libvirt-gobject-connection.c +++ b/libvirt-gobject/libvirt-gobject-connection.c @@ -44,6 +44,7 @@ struct _GVirConnectionPrivate GHashTable *domains; GHashTable *pools; +GHashTable *interfaces; }; G_DEFINE_TYPE(GVirConnection, gvir_connection, G_TYPE_OBJECT); @@ -252,6 +253,10 @@ static void gvir_connection_init(GVirConnection *conn) g_str_equal, NULL, g_object_unref); +priv-interfaces = g_hash_table_new_full(g_str_hash, + g_str_equal, + NULL, + g_object_unref); } @@ -668,6 +673,11 @@ void gvir_connection_close(GVirConnection *conn) priv-pools = NULL; } +if (priv-interfaces) { +g_hash_table_unref(priv-interfaces); +priv-interfaces = NULL; +} + if (priv-conn) { virConnectDomainEventDeregister(priv-conn, domain_event_cb); virConnectClose(priv-conn); @@ -1588,6 +1598,222 @@ GVirDomain *gvir_connection_start_domain(GVirConnection *conn, } /** + * gvir_connection_fetch_interfaces: + * @conn: a #GVirConnection + * @cancellable: (allow-none)(transfer none): cancellation object + */ +gboolean gvir_connection_fetch_interfaces(GVirConnection *conn, + GCancellable *cancellable, + GError **err) +{ +GVirConnectionPrivate *priv; +GHashTable *interfaces; +gchar **inactive = NULL; +gint ninactive = 0; +gchar **active = NULL; +gint nactive = 0; +gboolean ret = FALSE; +gint i; +virConnectPtr vconn = NULL; +GError *lerr = NULL; + +g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE); +g_return_val_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable), + FALSE); +g_return_val_if_fail((err == NULL) || (*err == NULL), FALSE); + +priv = conn-priv; +g_mutex_lock(priv-lock); +if (!priv-conn) { +g_set_error_literal(err, GVIR_CONNECTION_ERROR, +0, +_(Connection is not open)); +g_mutex_unlock(priv-lock); +goto cleanup; +} +vconn = priv-conn; +/* Stop another thread closing the connection just at the minute */ +virConnectRef(vconn); +g_mutex_unlock(priv-lock); + +if (g_cancellable_set_error_if_cancelled(cancellable, err)) +goto cleanup; + +active = fetch_list(vconn, +Interfaces, +virConnectNumOfInterfaces, +virConnectListInterfaces, +cancellable, +nactive, +lerr); +if (lerr) { +g_propagate_error(err, lerr); +lerr = NULL; +goto cleanup; +} + +if (g_cancellable_set_error_if_cancelled(cancellable, err)) +goto cleanup; + +inactive = fetch_list(vconn, + Interfaces, + virConnectNumOfDefinedInterfaces, + virConnectListDefinedInterfaces, + cancellable, + ninactive, + lerr); +if (lerr) { +g_propagate_error(err, lerr); +lerr = NULL; +goto cleanup; +} + +interfaces = g_hash_table_new_full(g_str_hash, + g_str_equal, + NULL, + g_object_unref); + +for (i = 0 ; i nactive ; i++) { +if (g_cancellable_set_error_if_cancelled(cancellable, err)) +goto cleanup; + +virInterfacePtr viface; +GVirInterface *iface; + +viface = virInterfaceLookupByName(vconn, active[i]); +if (!viface) +continue; + +iface = GVIR_INTERFACE(g_object_new(GVIR_TYPE_INTERFACE, + handle, viface, + NULL)); +virInterfaceFree(viface); + +g_hash_table_insert(interfaces, +active[i], +iface); +} + +for (i = 0 ; i ninactive ; i++) { +if (g_cancellable_set_error_if_cancelled(cancellable, err)) +goto cleanup; + +virInterfacePtr viface; +
[libvirt] [libvirt-glib] More coverage for networking API v2
Fixed the compiler warnings introduced by one of the patches. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-glib PATCHv2 5/5] gobject: Add wrapper for virNetworkGetDHCPLeases
--- libvirt-gobject/libvirt-gobject-network.c | 53 +++ libvirt-gobject/libvirt-gobject-network.h | 4 +++ libvirt-gobject/libvirt-gobject.sym | 3 ++ 3 files changed, 60 insertions(+) diff --git a/libvirt-gobject/libvirt-gobject-network.c b/libvirt-gobject/libvirt-gobject-network.c index b1b38a0..650a164 100644 --- a/libvirt-gobject/libvirt-gobject-network.c +++ b/libvirt-gobject/libvirt-gobject-network.c @@ -29,6 +29,7 @@ #include libvirt-glib/libvirt-glib.h #include libvirt-gobject/libvirt-gobject.h #include libvirt-gobject-compat.h +#include libvirt-gobject/libvirt-gobject-network-dhcp-lease-private.h #define GVIR_NETWORK_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_NETWORK, GVirNetworkPrivate)) @@ -224,3 +225,55 @@ GVirConfigNetwork *gvir_network_get_config(GVirNetwork *network, free(xml); return conf; } + +/** + * gvir_network_get_dhcp_leases: + * @network: the network + * @mac: (allow-none): The optional ASCII formatted MAC address of an interface + * @flags: the flags + * @err: Place-holder for possible errors + * + * This function fetches leases info of guests in the specified network. If the + * optional parameter @mac is specified, the returned list will contain only + * lease info about a specific guest interface with @mac. There can be multiple + * leases for a single @mac because this API supports DHCPv6 too. + * + * Returns: (element-type LibvirtGObject.NetworkDHCPLease) (transfer full): the + * list of network leases. Each object in the returned list should be unreffed + * with g_object_unref() and the list itself using g_list_free, when no longer + * needed. + */ +GList *gvir_network_get_dhcp_leases(GVirNetwork *network, +const char* mac, +guint flags, +GError **err) +{ +virNetworkDHCPLeasePtr *leases; +GList *ret = NULL; +int num_leases, i; + +g_return_val_if_fail(GVIR_IS_NETWORK(network), NULL); +g_return_val_if_fail(err == NULL || *err == NULL, NULL); + +num_leases = virNetworkGetDHCPLeases(network-priv-handle, mac, leases, flags); +if (num_leases 0) { +gvir_set_error_literal(err, GVIR_NETWORK_ERROR, + 0, + Unable to get network DHCP leases); +return NULL; +} + +if (num_leases == 0) +return NULL; + +for (i = 0; i num_leases; i++) { +GVirNetworkDHCPLease *lease; + +lease = gvir_network_dhcp_lease_new(leases[i]); +ret = g_list_prepend(ret, lease); +} +ret = g_list_reverse(ret); +free(leases); + +return ret; +} diff --git a/libvirt-gobject/libvirt-gobject-network.h b/libvirt-gobject/libvirt-gobject-network.h index 9f746c0..5617ed6 100644 --- a/libvirt-gobject/libvirt-gobject-network.h +++ b/libvirt-gobject/libvirt-gobject-network.h @@ -71,6 +71,10 @@ const gchar *gvir_network_get_uuid(GVirNetwork *network); GVirConfigNetwork *gvir_network_get_config(GVirNetwork *network, guint flags, GError **err); +GList *gvir_network_get_dhcp_leases(GVirNetwork *network, +const char* mac, +guint flags, +GError **err); G_END_DECLS diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index e35130b..7518422 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym @@ -285,6 +285,9 @@ LIBVIRT_GOBJECT_0.2.2 { gvir_interface_get_mac; gvir_ip_addr_type_get_type; + + gvir_network_get_dhcp_leases; + gvir_network_dhcp_lease_get_type; gvir_network_dhcp_lease_get_clientid; -- 2.4.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] RFC: add Intel CMT feature support
-Original Message- From: Peter Krempa [mailto:pkre...@redhat.com] Sent: Monday, June 29, 2015 5:44 PM To: Ren, Qiaowei Cc: libvir-list@redhat.com Subject: Re: [libvirt] RFC: add Intel CMT feature support On Sat, Jun 27, 2015 at 03:45:21 +, Ren, Qiaowei wrote: Hi All, Some Intel processor families (e.g. the Intel Xeon processor E5 v3 family) introduced some PQos (Platform Qos) features to monitor or control shared resource. - CMT (Cache Monitoring Technology): measure the usage of cache by applications running on the platform. - CAT (Cache Allocation Technology): enable an OS or Hypervisor/VMM to specify the amount of cache space into which an application can fill. - MBM (Memory Bandwidth Monitoring): build on the CMT infrastructure to allow monitoring of bandwidth from one level of the cache hierarchy to the next - in this case focusing on the L3 cache, which is typically backed directly by system memory. As a result of this implementation, memory bandwidth can be monitored. For more information, see Intel 64 and IA-32 Architectures Software Developer's Manual. Among these PQos features, currently CMT patches has been merged into Linux kernel mainline. So this patch series proposed in this mail will focus on CMT feature support in libvirt. At the library API layer, I plan on adding cache related field into virDomainInfo and virNodeInfo: Add cache member into virNodeInfo to get total size of cache in one node. struct virNodeInfo { ... unsigned int cores; /* number of cores per socket, total number of processors in case of unusual NUMA topology*/ unsigned int threads; /* number of threads per core, 1 in case of unusual numa topology */ + unsigned int cache; /* cache size in bytes */ We don't allow changing/adding members to public structures. You probably will be better of by adding this info to the capabilities XML. Ok. So I have to modify capabilities XML and struct virCaps to add total cache size related field. }; Add cacheOcc member into virDomainInfo to get cache occupancy for one VM. struct virDomainInfo { ... unsigned short nrVirtCpu; /* the number of virtual CPUs for the domain */ unsigned long long cpuTime; /* the CPU time used in nanoseconds */ + unsigned long long cacheOcc; /* the cache occupancy in Bytes */ Neither this structure can be modified. }; With this change, those applications like OpenStack based on libvirt can collect cache usage for metering and monitoring (e.g. any VM using more than X% of cache). You can use the bulk stats API (virDomainListGetStats) to add this field since that uses the typed parameter approach which can be extended. Got it. I will try to extend virDomainListGetStats API. Because CMT implementation in Linux kernel is based on perf mechanism and there is no nice and public API library for perf, I have to wrapper system call for perf in libvirt to use CMT feature, and enable/disable perf event for CMT when VM is created/destroyed. Any thoughts on this plan before I start submitting code patches? Do you think whether I need add several new APIs and XML element for CMT feature (or more PQos features)? Thanks, Qiaowei -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: event: Fix retrieval of the service field from graphics events
On Mon, Jun 29, 2015 at 02:42:50PM +0200, Peter Krempa wrote: qemu's event has following format: { timestamp: { seconds: 1435580974, microseconds: 82226 }, event: SPICE_INITIALIZED, data: { server: { auth: none, port: 5900, family: ipv4, host: 127.0.0.1 }, client: { port: 53224, family: ipv4, channel-type: 3, connection-id: 1113096064, host: 127.0.0.1, channel-id: 0, tls: false } } } Our code tried to extract the service field but qemu reports it as port. Hmm, that's somewhat odd - did you check back historical versions of QEMU where this event was first introduced to see if it has always had this name ? It smells like the kind of thing that could have been a regression at some point 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] qemu: event: Fix retrieval of the service field from graphics events
On Mon, Jun 29, 2015 at 03:35:05PM +0200, Jiri Denemark wrote: On Mon, Jun 29, 2015 at 15:17:50 +0200, Peter Krempa wrote: On Mon, Jun 29, 2015 at 13:47:50 +0100, Daniel Berrange wrote: On Mon, Jun 29, 2015 at 02:42:50PM +0200, Peter Krempa wrote: qemu's event has following format: { timestamp: { seconds: 1435580974, microseconds: 82226 }, event: SPICE_INITIALIZED, data: { server: { auth: none, port: 5900, family: ipv4, host: 127.0.0.1 }, client: { port: 53224, family: ipv4, channel-type: 3, connection-id: 1113096064, host: 127.0.0.1, channel-id: 0, tls: false } } } Our code tried to extract the service field but qemu reports it as port. Hmm, that's somewhat odd - did you check back historical versions of QEMU where this event was first introduced to see if it has always had this name ? It smells like the kind of thing that could have been a regression at some point Actually the regression would be on the VNC side, since VNC uses service and the function that I've modified handles both. I failed to notice that fact at first. Heh, I was thinking service was an old downstream-only spelling of port and checked it wasn't the case. But I failed to notice the same handler is used for VNC too... I've confirmed all the way back to 0.14.0 QEMU VNC and SPICE have used different names service vs port respectively. 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] qemu: event: Fix retrieval of the service field from graphics events
qemu's event has following format: { timestamp: { seconds: 1435580974, microseconds: 82226 }, event: SPICE_INITIALIZED, data: { server: { auth: none, port: 5900, family: ipv4, host: 127.0.0.1 }, client: { port: 53224, family: ipv4, channel-type: 3, connection-id: 1113096064, host: 127.0.0.1, channel-id: 0, tls: false } } } Our code tried to extract the service field but qemu reports it as port. --- src/qemu/qemu_monitor_json.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index d3e98d4..bd73b05 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -652,7 +652,7 @@ static void qemuMonitorJSONHandleGraphics(qemuMonitorPtr mon, virJSONValuePtr da VIR_WARN(missing local hostname in graphics event); return; } -localService = virJSONValueObjectGetString(server, service); +localService = virJSONValueObjectGetString(server, port); if (!localService) localService = ; /* Spice has multiple ports, so this isn't provided */ @@ -666,7 +666,7 @@ static void qemuMonitorJSONHandleGraphics(qemuMonitorPtr mon, virJSONValuePtr da VIR_WARN(missing remote hostname in graphics event); return; } -remoteService = virJSONValueObjectGetString(client, service); +remoteService = virJSONValueObjectGetString(client, port); if (!remoteService) remoteService = ; /* Spice has multiple ports, so this isn't provided */ -- 2.4.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: event: Fix retrieval of the service field from graphics events
On Mon, Jun 29, 2015 at 14:42:50 +0200, Peter Krempa wrote: qemu's event has following format: { timestamp: { seconds: 1435580974, microseconds: 82226 }, event: SPICE_INITIALIZED, data: { server: { auth: none, port: 5900, family: ipv4, host: 127.0.0.1 }, client: { port: 53224, family: ipv4, channel-type: 3, connection-id: 1113096064, host: 127.0.0.1, channel-id: 0, tls: false } } } Our code tried to extract the service field but qemu reports it as port. --- src/qemu/qemu_monitor_json.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) ACK Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-glib PATCHv2 4/5] gobject: Add wrapper for virNetworkDHCPLease
--- libvirt-gobject/Makefile.am| 5 +- .../libvirt-gobject-network-dhcp-lease-private.h | 34 +++ .../libvirt-gobject-network-dhcp-lease.c | 252 + .../libvirt-gobject-network-dhcp-lease.h | 85 +++ libvirt-gobject/libvirt-gobject.h | 1 + libvirt-gobject/libvirt-gobject.sym| 13 ++ 6 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 libvirt-gobject/libvirt-gobject-network-dhcp-lease-private.h create mode 100644 libvirt-gobject/libvirt-gobject-network-dhcp-lease.c create mode 100644 libvirt-gobject/libvirt-gobject-network-dhcp-lease.h diff --git a/libvirt-gobject/Makefile.am b/libvirt-gobject/Makefile.am index 7163c7d..8464f04 100644 --- a/libvirt-gobject/Makefile.am +++ b/libvirt-gobject/Makefile.am @@ -13,6 +13,7 @@ GOBJECT_HEADER_FILES = \ libvirt-gobject-domain.h \ libvirt-gobject-interface.h \ libvirt-gobject-network.h \ + libvirt-gobject-network-dhcp-lease.h \ libvirt-gobject-network-filter.h \ libvirt-gobject-node-device.h \ libvirt-gobject-secret.h \ @@ -22,7 +23,8 @@ GOBJECT_HEADER_FILES = \ libvirt-gobject-connection.h \ libvirt-gobject-manager.h noinst_HEADERS = \ - libvirt-gobject-storage-pool-private.h + libvirt-gobject-storage-pool-private.h \ + libvirt-gobject-network-dhcp-lease-private.h GOBJECT_SOURCE_FILES = \ libvirt-gobject-main.c \ libvirt-gobject-domain-snapshot.c \ @@ -32,6 +34,7 @@ GOBJECT_SOURCE_FILES = \ libvirt-gobject-domain.c \ libvirt-gobject-interface.c \ libvirt-gobject-network.c \ + libvirt-gobject-network-dhcp-lease.c \ libvirt-gobject-network-filter.c \ libvirt-gobject-node-device.c \ libvirt-gobject-secret.c \ diff --git a/libvirt-gobject/libvirt-gobject-network-dhcp-lease-private.h b/libvirt-gobject/libvirt-gobject-network-dhcp-lease-private.h new file mode 100644 index 000..eaf6c2f --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-network-dhcp-lease-private.h @@ -0,0 +1,34 @@ +/* + * libvirt-gobject-network-dhcp-lease-private.h: libvirt gobject integration + * + * Copyright (C) 2010-2011 Red Hat, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * http://www.gnu.org/licenses/. + * + * Authors: Zeeshan Ali (Khattak) zeesha...@gnome.org + * Daniel P. Berrange berra...@redhat.com + */ + +#ifndef __LIBVIRT_GOBJECT_NETWORK_DHCP_LEASE_PRIVATE_H__ +#define __LIBVIRT_GOBJECT_NETWORK_DHCP_LEASE_PRIVATE_H__ + +G_BEGIN_DECLS + +GVirNetworkDHCPLease *gvir_network_dhcp_lease_new(virNetworkDHCPLeasePtr handle); + +G_END_DECLS + +#endif /* __LIBVIRT_GOBJECT_NETWORK_DHCP_LEASE_PRIVATE_H__ */ diff --git a/libvirt-gobject/libvirt-gobject-network-dhcp-lease.c b/libvirt-gobject/libvirt-gobject-network-dhcp-lease.c new file mode 100644 index 000..57ccf0d --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-network-dhcp-lease.c @@ -0,0 +1,252 @@ +/* + * libvirt-gobject-network-dhcp-lease.h: libvirt glib integration + * + * Copyright (C) 2008 Daniel P. Berrange + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * http://www.gnu.org/licenses/. + * + * Authors: Zeeshan Ali (Khattak) zeesha...@gnome.org + * Daniel P. Berrange berra...@redhat.com + */ + +#include config.h + +#include
[libvirt] [libvirt-glib PATCHv2 3/5] gobject: Add API to query connection networks
Add API to query networks from a connection. --- libvirt-gobject/libvirt-gobject-connection.c | 226 +++ libvirt-gobject/libvirt-gobject-connection.h | 6 +- libvirt-gobject/libvirt-gobject.sym | 4 + 3 files changed, 234 insertions(+), 2 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c index 20c43fc..eea2eed 100644 --- a/libvirt-gobject/libvirt-gobject-connection.c +++ b/libvirt-gobject/libvirt-gobject-connection.c @@ -45,6 +45,7 @@ struct _GVirConnectionPrivate GHashTable *domains; GHashTable *pools; GHashTable *interfaces; +GHashTable *networks; }; G_DEFINE_TYPE(GVirConnection, gvir_connection, G_TYPE_OBJECT); @@ -257,6 +258,10 @@ static void gvir_connection_init(GVirConnection *conn) g_str_equal, NULL, g_object_unref); +priv-networks = g_hash_table_new_full(g_str_hash, + g_str_equal, + NULL, + g_object_unref); } @@ -678,6 +683,11 @@ void gvir_connection_close(GVirConnection *conn) priv-interfaces = NULL; } +if (priv-networks) { +g_hash_table_unref(priv-networks); +priv-networks = NULL; +} + if (priv-conn) { virConnectDomainEventDeregister(priv-conn, domain_event_cb); virConnectClose(priv-conn); @@ -1814,6 +1824,222 @@ GVirInterface *gvir_connection_find_interface_by_mac(GVirConnection *conn, } /** + * gvir_connection_fetch_networks: + * @conn: a #GVirConnection + * @cancellable: (allow-none)(transfer none): cancellation object + */ +gboolean gvir_connection_fetch_networks(GVirConnection *conn, + GCancellable *cancellable, + GError **err) +{ +GVirConnectionPrivate *priv; +GHashTable *networks; +gchar **inactive = NULL; +gint ninactive = 0; +gchar **active = NULL; +gint nactive = 0; +gboolean ret = FALSE; +gint i; +virConnectPtr vconn = NULL; +GError *lerr = NULL; + +g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE); +g_return_val_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable), + FALSE); +g_return_val_if_fail((err == NULL) || (*err == NULL), FALSE); + +priv = conn-priv; +g_mutex_lock(priv-lock); +if (!priv-conn) { +g_set_error_literal(err, GVIR_CONNECTION_ERROR, +0, +_(Connection is not open)); +g_mutex_unlock(priv-lock); +goto cleanup; +} +vconn = priv-conn; +/* Stop another thread closing the connection just at the minute */ +virConnectRef(vconn); +g_mutex_unlock(priv-lock); + +if (g_cancellable_set_error_if_cancelled(cancellable, err)) +goto cleanup; + +active = fetch_list(vconn, +Networks, +virConnectNumOfNetworks, +virConnectListNetworks, +cancellable, +nactive, +lerr); +if (lerr) { +g_propagate_error(err, lerr); +lerr = NULL; +goto cleanup; +} + +if (g_cancellable_set_error_if_cancelled(cancellable, err)) +goto cleanup; + +inactive = fetch_list(vconn, + Networks, + virConnectNumOfDefinedNetworks, + virConnectListDefinedNetworks, + cancellable, + ninactive, + lerr); +if (lerr) { +g_propagate_error(err, lerr); +lerr = NULL; +goto cleanup; +} + +networks = g_hash_table_new_full(g_str_hash, + g_str_equal, + NULL, + g_object_unref); + +for (i = 0 ; i nactive ; i++) { +if (g_cancellable_set_error_if_cancelled(cancellable, err)) +goto cleanup; + +virNetworkPtr vnetwork; +GVirNetwork *network; + +vnetwork = virNetworkLookupByName(vconn, active[i]); +if (!vnetwork) +continue; + +network = GVIR_NETWORK(g_object_new(GVIR_TYPE_NETWORK, +handle, vnetwork, +NULL)); +virNetworkFree(vnetwork); + +g_hash_table_insert(networks, +(gpointer)gvir_network_get_uuid(network), +network); +} + +for (i = 0 ; i ninactive ; i++) { +if (g_cancellable_set_error_if_cancelled(cancellable, err)) +goto cleanup; + +
Re: [libvirt] [PATCH] qemu: event: Fix retrieval of the service field from graphics events
On Mon, Jun 29, 2015 at 13:47:50 +0100, Daniel Berrange wrote: On Mon, Jun 29, 2015 at 02:42:50PM +0200, Peter Krempa wrote: qemu's event has following format: { timestamp: { seconds: 1435580974, microseconds: 82226 }, event: SPICE_INITIALIZED, data: { server: { auth: none, port: 5900, family: ipv4, host: 127.0.0.1 }, client: { port: 53224, family: ipv4, channel-type: 3, connection-id: 1113096064, host: 127.0.0.1, channel-id: 0, tls: false } } } Our code tried to extract the service field but qemu reports it as port. Hmm, that's somewhat odd - did you check back historical versions of QEMU where this event was first introduced to see if it has always had this name ? It smells like the kind of thing that could have been a regression at some point Actually the regression would be on the VNC side, since VNC uses service and the function that I've modified handles both. I failed to notice that fact at first. I'll post a V2 with dual handling. Peter signature.asc Description: Digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: event: Fix retrieval of the service field from graphics events
On Mon, Jun 29, 2015 at 15:17:50 +0200, Peter Krempa wrote: On Mon, Jun 29, 2015 at 13:47:50 +0100, Daniel Berrange wrote: On Mon, Jun 29, 2015 at 02:42:50PM +0200, Peter Krempa wrote: qemu's event has following format: { timestamp: { seconds: 1435580974, microseconds: 82226 }, event: SPICE_INITIALIZED, data: { server: { auth: none, port: 5900, family: ipv4, host: 127.0.0.1 }, client: { port: 53224, family: ipv4, channel-type: 3, connection-id: 1113096064, host: 127.0.0.1, channel-id: 0, tls: false } } } Our code tried to extract the service field but qemu reports it as port. Hmm, that's somewhat odd - did you check back historical versions of QEMU where this event was first introduced to see if it has always had this name ? It smells like the kind of thing that could have been a regression at some point Actually the regression would be on the VNC side, since VNC uses service and the function that I've modified handles both. I failed to notice that fact at first. Heh, I was thinking service was an old downstream-only spelling of port and checked it wasn't the case. But I failed to notice the same handler is used for VNC too... Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-glib PATCHv2 1/5] gobject: Add gvir_interface_get_mac()
Add a wrapper for virInterfaceGetMACString(). --- libvirt-gobject/libvirt-gobject-interface.c | 13 + libvirt-gobject/libvirt-gobject-interface.h | 1 + libvirt-gobject/libvirt-gobject.sym | 5 + 3 files changed, 19 insertions(+) diff --git a/libvirt-gobject/libvirt-gobject-interface.c b/libvirt-gobject/libvirt-gobject-interface.c index 1fc6656..6b2df59 100644 --- a/libvirt-gobject/libvirt-gobject-interface.c +++ b/libvirt-gobject/libvirt-gobject-interface.c @@ -171,6 +171,19 @@ const gchar *gvir_interface_get_name(GVirInterface *iface) return name; } +const gchar *gvir_interface_get_mac(GVirInterface *iface) +{ +const char *mac; + +g_return_val_if_fail(GVIR_IS_INTERFACE(iface), NULL); + +if (!(mac = virInterfaceGetMACString(iface-priv-handle))) { +gvir_warning(Failed to get interface mac on %p, iface-priv-handle); +return NULL; +} + +return mac; +} /** * gvir_interface_get_config: diff --git a/libvirt-gobject/libvirt-gobject-interface.h b/libvirt-gobject/libvirt-gobject-interface.h index f437bc7..a8776e5 100644 --- a/libvirt-gobject/libvirt-gobject-interface.h +++ b/libvirt-gobject/libvirt-gobject-interface.h @@ -63,6 +63,7 @@ GType gvir_interface_get_type(void); GType gvir_interface_handle_get_type(void); const gchar *gvir_interface_get_name(GVirInterface *iface); +const gchar *gvir_interface_get_mac(GVirInterface *iface); GVirConfigInterface *gvir_interface_get_config(GVirInterface *iface, guint flags, diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index dcda675..29c4349 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym @@ -271,4 +271,9 @@ LIBVIRT_GOBJECT_0.2.1 { gvir_storage_pool_set_autostart; } LIBVIRT_GOBJECT_0.2.0; +LIBVIRT_GOBJECT_0.2.2 { + global: + gvir_interface_get_mac; +} LIBVIRT_GOBJECT_0.2.1; + # define new API here using predicted next version number -- 2.4.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemuxml2argv: Remove CPU models from unrelated tests
Proper Haswell CPU model handling is tested in several qemuxml2argv-cpu-* which are run in a special environment. Let's remove the CPU model from other tests to make them less fragile. Signed-off-by: Jiri Denemark jdene...@redhat.com --- .../qemuxml2argv-hugepages-numa.args | 1 - .../qemuxml2argv-hugepages-numa.xml| 3 +-- .../qemuxml2argv-interface-server.xml | 25 +- 3 files changed, 2 insertions(+), 27 deletions(-) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args index b697942..37511b1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args @@ -2,7 +2,6 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice \ /usr/bin/qemu-system-x86_64 \ -S \ -M pc-i440fx-2.3 \ --cpu Haswell \ -m size=1048576k,slots=16,maxmem=1099511627776k \ -smp 2 \ -object memory-backend-file,id=ram-node0,prealloc=yes,\ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.xml b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.xml index 8c1f19c..8cda5c6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.xml @@ -17,8 +17,7 @@ apic/ pae/ /features - cpu mode='custom' match='exact' -model fallback='allow'Haswell/model + cpu numa cell id='0' cpus='0-1' memory='1048576' unit='KiB'/ /numa diff --git a/tests/qemuxml2argvdata/qemuxml2argv-interface-server.xml b/tests/qemuxml2argvdata/qemuxml2argv-interface-server.xml index 9edf773..a92aff4 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-interface-server.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-interface-server.xml @@ -19,30 +19,7 @@ apic/ pae/ /features - cpu mode='custom' match='exact' -model fallback='allow'Haswell/model -vendorIntel/vendor -feature policy='require' name='tm2'/ -feature policy='require' name='est'/ -feature policy='require' name='vmx'/ -feature policy='require' name='osxsave'/ -feature policy='require' name='smx'/ -feature policy='require' name='ss'/ -feature policy='require' name='ds'/ -feature policy='require' name='vme'/ -feature policy='require' name='dtes64'/ -feature policy='require' name='abm'/ -feature policy='require' name='ht'/ -feature policy='require' name='acpi'/ -feature policy='require' name='pbe'/ -feature policy='require' name='tm'/ -feature policy='require' name='pdcm'/ -feature policy='require' name='pdpe1gb'/ -feature policy='require' name='ds_cpl'/ -feature policy='require' name='rdrand'/ -feature policy='require' name='f16c'/ -feature policy='require' name='xtpr'/ -feature policy='require' name='monitor'/ + cpu numa cell id='0' cpus='0' memory='1048576' unit='KiB'/ cell id='1' cpus='1' memory='1048576' unit='KiB'/ -- 2.4.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Fix nodeinfo output on PPC64 KVM hosts
On Thu, 2016-06-25 at 12:03 +0530, Shivaprasad G Bhat wrote: Hi Shivaprasad, here are a few comments about your patch. [...] +# if HAVE_LINUX_KVM_H +# include linux/kvm.h This line should be moved to the top of the file, with all the other #include directives. +kvmfd = open(/dev/kvm, O_RDONLY); +if (kvmfd = 0) { +# ifdef KVM_CAP_PPC_SMT +valid_ppc64_kvmhost_mode = true; +/* For Phyp and KVM based guests the ioctl for KVM_CAP_PPC_SMT + * returns zero and both primary and secondary threads will be + * online. Dont try to alter or interpret anything here. + */ +threads_per_subcore = ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_PPC_SMT); +if (threads_per_subcore == 0) +valid_ppc64_kvmhost_mode = false; +# endif +} +VIR_FORCE_CLOSE(kvmfd); +# endif +rewinddir(cpudir); +lastonline = -1; +while (valid_ppc64_kvmhost_mode + ((direrr = virDirRead(cpudir, cpudirent, node)) 0)) { +if (sscanf(cpudirent-d_name, cpu%u, cpu) != 1) +continue; +if ((online = virNodeGetCpuValue(node, cpu, online, 1)) 0) +goto cleanup; + +if (online) { +if (lastonline != -1 +(cpu - lastonline) threads_per_subcore) { +valid_ppc64_kvmhost_mode = false; /* if any of secondaries + * online */ If a comment is long enough to span two lines, it should probably not start at the end of a statement but rather be above it. +break; +} +lastonline = cpu; +} +} +} + Enclosing this whole block within the #if and #ifdef directives would make the code cleaner; on the other hand, since the skeleton of the loop is identical to the one a few lines above, maybe you could move the part reading from /dev/kvm closer to the top and merge the two loops together? /* allocate cpu maps for each socket */ if (VIR_ALLOC_N(core_maps, sock_max) 0) goto cleanup; @@ -473,6 +539,7 @@ virNodeParseNode(const char *node, /* iterate over all CPU's in the node */ rewinddir(cpudir); +lastonline = -1; while ((direrr = virDirRead(cpudir, cpudirent, node)) 0) { if (sscanf(cpudirent-d_name, cpu%u, cpu) != 1) continue; @@ -480,6 +547,17 @@ virNodeParseNode(const char *node, if ((online = virNodeGetCpuValue(node, cpu, online, 1)) 0) goto cleanup; +if (ARCH_IS_PPC64(arch) valid_ppc64_kvmhost_mode) { valid_ppc64_kvmhost_mode can be true iff ARCH_IS_PPC64(arch), so this condition is kinda redundant. +if (online) { +lastonline = cpu; +} else if (lastonline != -1 + (cpu-lastonline) threads_per_subcore) { +processors++; /* Count only those secondaries whose primary + subcore is online */ Same as above. +continue; +} +} + if (!online) { (*offline)++; continue; @@ -528,6 +606,13 @@ virNodeParseNode(const char *node, *cores = core; } +if (ARCH_IS_PPC64(arch) valid_ppc64_kvmhost_mode) { Same as above. +/* The actual host threads per core is + * multiple of the subcores_per_core(i.e variable *threads in this case) + * and threads_per_subcore. + */ +*threads = *threads * threads_per_subcore; +} ret = processors; cleanup: Overall, the code makes sense and seems to work from my limited testing. However, this change completely breaks the topology information reported by `virsh capabilities`. Here's the output on a host with subcores_per_core=1, without the patch: topology cells num='4' cell id='0' memory unit='KiB'67108864/memory pages unit='KiB' size='64'1048576/pages pages unit='KiB' size='16384'0/pages pages unit='KiB' size='16777216'0/pages distances sibling id='0' value='10'/ sibling id='1' value='20'/ sibling id='16' value='40'/ sibling id='17' value='40'/ /distances cpus num='5' cpu id='0' socket_id='0' core_id='32' siblings='0'/ cpu id='8' socket_id='0' core_id='40' siblings='8'/ cpu id='16' socket_id='0' core_id='48' siblings='16'/ cpu id='24' socket_id='0' core_id='96' siblings='24'/ cpu id='32' socket_id='0' core_id='104' siblings='32'/ /cpus /cell cell id='1' memory unit='KiB'67108864/memory pages unit='KiB' size='64'1048576/pages pages unit='KiB' size='16384'0/pages
[libvirt] [PATCH] bootstrap: Don't require python-config
We've split the python bindings a long time ago. However, we are still requiring python-config (as an obfuscation to python-devel). This does not make any sense. The only thing we need is python, not python-devel. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- bootstrap.conf | 13 + 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index c06ee4c..783b3a3 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -196,10 +196,7 @@ local_gl_dir=gnulib/local # Build prerequisites # Note that some of these programs are only required for 'make dist' to # succeed from a fresh git checkout; not all of these programs are -# required to run 'make dist' on a tarball. As a special case, we want -# to require the equivalent of the Fedora python-devel package, but -# RHEL 5 lacks the witness python-config package; we hack around that -# old environment below. +# required to run 'make dist' on a tarball. buildreq=\ autoconf 2.59 automake 1.9.6 @@ -212,19 +209,11 @@ patch - perl 5.5 perl::XML::XPath - pkg-config - -python-config - rpcgen - tar- xmllint - xsltproc - -# Use rpm as a fallback to bypass the bootstrap probe for python-config, -# for the sake of RHEL 5; without requiring it on newer systems that -# have python-config to begin with. -if `(${PYTHON_CONFIG-python-config} --version; - test $? -lt 126 || rpm -q python-devel) /dev/null 21`; then - PYTHON_CONFIG=true -fi # Automake requires that ChangeLog and AUTHORS exist. touch AUTHORS ChangeLog || exit 1 -- 2.3.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH libvirt-python] virPyDictToTypedParams: packing lists of values
On 16.06.2015 03:39, Pavel Boldin wrote: Pack a list or a tuple of values passed to a Python method to the multi-value parameter. --- libvirt-override.c | 228 ++--- 1 file changed, 129 insertions(+), 99 deletions(-) ACKed. Even though we are in freeze, this patch was sent early enough and I've promised to review it. Then, it makes the selective block migration possible in python bindings. Therefore I've pushed it too. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] RFC: add Intel CMT feature support
On Sat, Jun 27, 2015 at 03:45:21 +, Ren, Qiaowei wrote: Hi All, Some Intel processor families (e.g. the Intel Xeon processor E5 v3 family) introduced some PQos (Platform Qos) features to monitor or control shared resource. - CMT (Cache Monitoring Technology): measure the usage of cache by applications running on the platform. - CAT (Cache Allocation Technology): enable an OS or Hypervisor/VMM to specify the amount of cache space into which an application can fill. - MBM (Memory Bandwidth Monitoring): build on the CMT infrastructure to allow monitoring of bandwidth from one level of the cache hierarchy to the next - in this case focusing on the L3 cache, which is typically backed directly by system memory. As a result of this implementation, memory bandwidth can be monitored. For more information, see Intel 64 and IA-32 Architectures Software Developer's Manual. Among these PQos features, currently CMT patches has been merged into Linux kernel mainline. So this patch series proposed in this mail will focus on CMT feature support in libvirt. At the library API layer, I plan on adding cache related field into virDomainInfo and virNodeInfo: Add cache member into virNodeInfo to get total size of cache in one node. struct virNodeInfo { ... unsigned int cores; /* number of cores per socket, total number of processors in case of unusual NUMA topology*/ unsigned int threads; /* number of threads per core, 1 in case of unusual numa topology */ + unsigned int cache; /* cache size in bytes */ We don't allow changing/adding members to public structures. You probably will be better of by adding this info to the capabilities XML. }; Add cacheOcc member into virDomainInfo to get cache occupancy for one VM. struct virDomainInfo { ... unsigned short nrVirtCpu; /* the number of virtual CPUs for the domain */ unsigned long long cpuTime; /* the CPU time used in nanoseconds */ + unsigned long long cacheOcc; /* the cache occupancy in Bytes */ Neither this structure can be modified. }; With this change, those applications like OpenStack based on libvirt can collect cache usage for metering and monitoring (e.g. any VM using more than X% of cache). You can use the bulk stats API (virDomainListGetStats) to add this field since that uses the typed parameter approach which can be extended. Because CMT implementation in Linux kernel is based on perf mechanism and there is no nice and public API library for perf, I have to wrapper system call for perf in libvirt to use CMT feature, and enable/disable perf event for CMT when VM is created/destroyed. Any thoughts on this plan before I start submitting code patches? Do you think whether I need add several new APIs and XML element for CMT feature (or more PQos features)? Thanks, Qiaowei Peter signature.asc Description: Digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-php][PATCH v1] snapshot flags
* add more snapshot flag constants * add flags support to snapshot functions Signed-off-by: Vasiliy Tolstov v.tols...@selfip.ru --- src/libvirt-php.c | 61 --- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/src/libvirt-php.c b/src/libvirt-php.c index d13e5b4..a2949f1 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -1240,6 +1240,31 @@ PHP_MINIT_FUNCTION(libvirt) /* Domain snapshot constants */ REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_DELETE_CHILDREN, VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_DELETE_METADATA_ONLY, VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_DELETE_CHILDREN_ONLY, VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_CREATE_REDEFINE, VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_CREATE_CURRENT, VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_CREATE_NO_METADATA, VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_CREATE_HALT, VIR_DOMAIN_SNAPSHOT_CREATE_HALT,CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_CREATE_DISK_ONLY, VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_CREATE_REUSE_EXT, VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_CREATE_QUIESCE, VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_CREATE_ATOMIC, VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_CREATE_LIVE, VIR_DOMAIN_SNAPSHOT_CREATE_LIVE,CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_DESCENDANTS, VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_ROOTS, VIR_DOMAIN_SNAPSHOT_LIST_ROOTS, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_METADATA, VIR_DOMAIN_SNAPSHOT_LIST_METADATA, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_LEAVES, VIR_DOMAIN_SNAPSHOT_LIST_LEAVES,CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_NO_LEAVES, VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_NO_METADATA, VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_INACTIVE, VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_ACTIVE, VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE,CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_DISK_ONLY, VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_INTERNAL, VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_LIST_EXTERNAL, VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_REVERT_RUNNING, VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_REVERT_PAUSED, VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT(VIR_SNAPSHOT_REVERT_FORCE, VIR_DOMAIN_SNAPSHOT_REVERT_FORCE, CONST_CS | CONST_PERSISTENT); /* Memory constants */ REGISTER_LONG_CONSTANT(VIR_MEMORY_VIRTUAL,1, CONST_CS | CONST_PERSISTENT); @@ -6568,6 +6593,7 @@ PHP_FUNCTION(libvirt_domain_get_job_info) * Since version: 0.4.1(-2) * Description: Function is used to get the information whether domain has the current snapshot * Arguments: @res [resource]: libvirt domain resource + * @flags [int]: libvirt snapshot flags * Returns: TRUE is domain has the current snapshot, otherwise FALSE (you may need to check for error using libvirt_get_last_error()) */ PHP_FUNCTION(libvirt_domain_has_current_snapshot) @@ -6575,10 +6601,11 @@ PHP_FUNCTION(libvirt_domain_has_current_snapshot) php_libvirt_domain *domain=NULL; zval *zdomain; int retval; +long flags = 0; -GET_DOMAIN_FROM_ARGS(r,zdomain); +GET_DOMAIN_FROM_ARGS(r|l,zdomain, flags); -retval=virDomainHasCurrentSnapshot(domain-domain, 0); +retval=virDomainHasCurrentSnapshot(domain-domain, flags); if (retval = 0) RETURN_FALSE; RETURN_TRUE; } @@ -6589,6 +6616,7 @@
[libvirt] [PATCH 6/9] Implement the public APIs for multi-thread compress parameters.
Define helper function virdomainMigrateSetParameters and virdomainMigrateGetParameters, which allow to or get multi-thread compress parameters. include/libvirt/libvirt-domain.h * Define virdomainMigrateSetParameters, virdomainMigrateGetParameters src/driver-hypervisor.h: * Define domainMigrateSetParameters, domainMigrateGetParameters src/libvirt-domain.c: * Implement virdomainMigrateSetParameters * Implement virdomainMigrateGetParameters src/libvirt_public.syms: * Export the new symbols Signed-off-by: Eli Qiao liyong.q...@intel.com Signed-off-by: ShaoHe Feng shaohe.f...@intel.com --- include/libvirt/libvirt-domain.h | 10 +++- src/driver-hypervisor.h | 14 + src/libvirt-domain.c | 110 +++ src/libvirt_public.syms | 5 ++ 4 files changed, 137 insertions(+), 2 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 29b2b22..092d4f1 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -799,6 +799,14 @@ int virDomainMigrateGetMaxSpeed(virDomainPtr domain, unsigned long *bandwidth, unsigned int flags); +int virDomainMigrateSetParameters(virDomainPtr dom, + virTypedParameterPtr params, + int nparams, unsigned int flags); + +int virDomainMigrateGetParameters(virDomainPtr dom, + virTypedParameterPtr params, + int *nparams, unsigned int flags); + char * virConnectGetDomainCapabilities(virConnectPtr conn, const char *emulatorbin, const char *arch, @@ -2789,8 +2797,6 @@ int virDomainAbortJob(virDomainPtr dom); */ # define VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW compression_overflow - - /** * VIR_DOMAIN_MIRGRATE_COMPRESSION_LEVEL: * diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 3275343..7e5f619 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -712,6 +712,18 @@ typedef int unsigned int flags); typedef int +(*virDrvDomainMigrateSetParameters)(virDomainPtr dom, +virTypedParameterPtr params, +int nparams, +unsigned int flags); + +typedef int +(*virDrvDomainMigrateGetParameters)(virDomainPtr dom, +virTypedParameterPtr params, +int *nparams, +unsigned int flags); + +typedef int (*virDrvConnectDomainEventRegisterAny)(virConnectPtr conn, virDomainPtr dom, int eventID, @@ -1359,6 +1371,8 @@ struct _virHypervisorDriver { virDrvDomainMigrateSetCompressionCache domainMigrateSetCompressionCache; virDrvDomainMigrateGetMaxSpeed domainMigrateGetMaxSpeed; virDrvDomainMigrateSetMaxSpeed domainMigrateSetMaxSpeed; +virDrvDomainMigrateSetParameters domainMigrateSetParameters; +virDrvDomainMigrateGetParameters domainMigrateGetParameters; virDrvConnectDomainEventRegisterAny connectDomainEventRegisterAny; virDrvConnectDomainEventDeregisterAny connectDomainEventDeregisterAny; virDrvDomainManagedSave domainManagedSave; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 2edba1a..c704af7 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -9165,6 +9165,116 @@ virDomainMigrateGetMaxSpeed(virDomainPtr domain, /** + * virDomainMigrateSetParameters: + * @dom: a domain object + * @params: pointer to memory parameter objects + * @nparams: number of live mirgration compress parameter (this value can be + * the same or less than the number of parameters supported) + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * The parameters which will be used when doing live migration if we enable + * multi-thread compression. Currently it supports compress-level, + * compress-threads, decompress-threads. Not all hypervisors + * will support multi-thread compression. + * + * Returns 0 in case of success, -1 otherwise. + */ +int +virDomainMigrateSetParameters(virDomainPtr dom, + virTypedParameterPtr params, + int nparams, unsigned int flags) +{ +virConnectPtr conn; + +VIR_DOMAIN_DEBUG(dom, miagrateion set parameters + params=%p, nparams=%d, flags=%x, params, nparams, flags); +VIR_TYPED_PARAMS_DEBUG(params, nparams); + +virResetLastError(); + +virCheckDomainReturn(dom, -1); +conn = dom-conn; + +virCheckReadOnlyGoto(conn-flags, error); +virCheckPositiveArgGoto(nparams, error); +virCheckNonNullArgGoto(params, error); + +if
[libvirt] [PATCH 2/9] qemu: Add monitor API for get/set migration parameters
Add monitor API to tune and query the parameters used in live migration. * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h, src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Add monitor API for get/set migration parameters Signed-off-by: Eli Qiao liyong.q...@intel.com Signed-off-by: ShaoHe Feng shaohe.f...@intel.com --- src/qemu/qemu_monitor.c | 38 ++ src/qemu/qemu_monitor.h | 10 + src/qemu/qemu_monitor_json.c | 93 +++ src/qemu/qemu_monitor_json.h | 9 + src/qemu/qemu_monitor_text.c | 95 src/qemu/qemu_monitor_text.h | 10 + 6 files changed, 255 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 18abfee..1ab8dc4 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2176,6 +2176,44 @@ qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon, int +qemuMonitorGetMigrationParameters(qemuMonitorPtr mon, + unsigned int *level, + unsigned int *threads, + unsigned int *dthreads) +{ +VIR_DEBUG(level=%p threads=%p dthreads=%p, level, threads, dthreads); + +QEMU_CHECK_MONITOR_JSON(mon); + +if (mon-json) +return qemuMonitorJSONGetMigrationParameters(mon, level, + threads, dthreads); +else +return qemuMonitorTextGetMigrationParameters(mon, level, + threads, dthreads); +} + + +int +qemuMonitorSetMigrationParameters(qemuMonitorPtr mon, + int level, + int threads, + int dthreads) +{ +VIR_DEBUG(level=%d threads=%d dthreads=%d, level, threads, dthreads); + +QEMU_CHECK_MONITOR_JSON(mon); + +if (mon-json) +return qemuMonitorJSONSetMigrationParameters(mon, level, + threads, dthreads); +else +return qemuMonitorTextSetMigrationParameters(mon, level, + threads, dthreads); +} + + +int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon, qemuMonitorMigrationStatusPtr status) { diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 52d0be7..37157ac 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -438,6 +438,16 @@ int qemuMonitorGetMigrationCacheSize(qemuMonitorPtr mon, int qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon, unsigned long long cacheSize); +int qemuMonitorGetMigrationParameters(qemuMonitorPtr mon, + unsigned int *level, + unsigned int *threads, + unsigned int *dthreads); + +int qemuMonitorSetMigrationParameters(qemuMonitorPtr mon, + int level, + int threads, + int dthreads); + enum { QEMU_MONITOR_MIGRATION_STATUS_INACTIVE, QEMU_MONITOR_MIGRATION_STATUS_ACTIVE, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index e281140..5eaf553 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2469,6 +2469,99 @@ qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon, } +int +qemuMonitorJSONGetMigrationParameters(qemuMonitorPtr mon, + unsigned int *level, + unsigned int *threads, + unsigned int *dthreads) +{ +int ret = -1; +virJSONValuePtr result; +virJSONValuePtr cmd; +virJSONValuePtr reply = NULL; + +*level = 0; +*threads = 0; +*dthreads = 0; + +cmd = qemuMonitorJSONMakeCommand(query-migrate-parameters, NULL); +if (!cmd) +return -1; + +ret = qemuMonitorJSONCommand(mon, cmd, reply); + +if (ret == 0) +ret = qemuMonitorJSONCheckError(cmd, reply); + +if (ret 0) +goto cleanup; + +if (!(result = virJSONValueObjectGet(reply, return))) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, + _(query-migrate-parameters reply was missing + 'return' data)); +goto cleanup; +} + +virJSONValueObjectGetNumberUint(result, compress-level, level); +virJSONValueObjectGetNumberUint(result, compress-threads, threads); +virJSONValueObjectGetNumberUint(result, decompress-threads, dthreads); + +ret = 0; + cleanup: +virJSONValueFree(cmd); +virJSONValueFree(reply); +return ret; +} + + +int qemuMonitorJSONSetMigrationParameters(qemuMonitorPtr mon, +
[libvirt] [PATCH 7/9] remote: Add support for set and get multil thread migration parameters
From: Eli Qiao liyong.q...@intel.com Add remote support for the set/get migration parameters API's Signed-off-by: Eli Qiao liyong.q...@intel.com Signed-off-by: ShaoHe Feng shaohe.f...@intel.com --- daemon/remote.c | 62 src/remote/remote_driver.c | 54 ++ src/remote/remote_protocol.x | 30 - src/remote_protocol-structs | 26 +++ 4 files changed, 171 insertions(+), 1 deletion(-) diff --git a/daemon/remote.c b/daemon/remote.c index e259a76..7e4838f 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -5642,6 +5642,68 @@ remoteDispatchDomainMigrateFinish3Params(virNetServerPtr server ATTRIBUTE_UNUSED static int +remoteDispatchDomainMigrateGetParameters(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr hdr ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_migrate_get_parameters_args *args, + remote_domain_migrate_get_parameters_ret *ret) +{ +virDomainPtr dom = NULL; +int rv = -1; +virTypedParameterPtr params = NULL; +int nparams = 0; +struct daemonClientPrivate *priv = +virNetServerClientGetPrivateData(client); + +if (!priv-conn) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, _(connection not open)); +goto cleanup; +} + +if (args-nparams REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, _(nparams too large)); +goto cleanup; +} + +if (args-nparams VIR_ALLOC_N(params, args-nparams) 0) +goto cleanup; +nparams = args-nparams; + +if (!(dom = get_nonnull_domain(priv-conn, args-dom))) +goto cleanup; + +if (virDomainMigrateGetParameters(dom, params, nparams, args-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; +} + +/* Serialise the migration parameters. */ +if (remoteSerializeTypedParameters(params, nparams, + ret-params.params_val, + ret-params.params_len, + args-flags) 0) +goto cleanup; + + success: +rv = 0; + + cleanup: +if (rv 0) +virNetMessageSaveError(rerr); +virTypedParamsFree(params, nparams); +virObjectUnref(dom); +return rv; +} + + +static int remoteDispatchDomainMigrateConfirm3Params(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 dd8dab6..4ed87dc 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -7442,6 +7442,58 @@ remoteDomainMigrateConfirm3Params(virDomainPtr domain, } +static int remoteDomainMigrateGetParameters(virDomainPtr domain, +virTypedParameterPtr params, +int *nparams, +unsigned int flags) +{ +int rv = -1; +remote_domain_migrate_get_parameters_args args; +remote_domain_migrate_get_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_MIGRATE_GET_PARAMETERS, + (xdrproc_t) xdr_remote_domain_migrate_get_parameters_args, + (char *) args, + (xdrproc_t) xdr_remote_domain_migrate_get_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_MIGRATE_PARAM_LIST_MAX, + params, + nparams) 0) +goto cleanup; + +rv = 0; + + cleanup: +xdr_free((xdrproc_t) xdr_remote_domain_migrate_get_parameters_ret, + (char *) ret); + done: +remoteDriverUnlock(priv); +return rv;
[libvirt] [PATCH 9/9] virsh: Add set and get multi-thread migration parameters commands
From: Eli Qiao liyong.q...@intel.com Add command to allow set and get multi-thread migration parameters for a domain. Signed-off-by: ShaoHe Feng shaohe.f...@intel.com Signed-off-by: Eli Qiao liyong.q...@intel.com --- tools/virsh-domain.c | 171 ++- tools/virsh.pod | 14 + 2 files changed, 184 insertions(+), 1 deletion(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index b5713cc..11ac27d 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -10301,7 +10301,7 @@ static const vshCmdInfo info_migrate_setspeed[] = { }, {.name = desc, .data = N_(Set the maximum migration bandwidth (in MiB/s) for a domain -which is being migrated to another host.) +before migrating another host.) }, {.name = NULL} }; @@ -10392,6 +10392,163 @@ cmdMigrateGetMaxSpeed(vshControl *ctl, const vshCmd *cmd) } /* + * migrate-setparameters command + */ +static const vshCmdInfo info_migrate_setparameters[] = { +{.name = help, + .data = N_(Set the multi-thread migration parameters) +}, +{.name = desc, + .data = N_(Set the multi-thread migration parameters for a domain +which is being migrated to another host.) +}, +{.name = NULL} +}; + +static const vshCmdOptDef opts_migrate_setparameters[] = { +{.name = domain, + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_(domain name, id or uuid) +}, +{.name = level, + .type = VSH_OT_INT, + .help = N_(compression level, from 1-9, 0 means use default level) +}, +{.name = threads, + .type = VSH_OT_INT, + .help = N_(compression thread count for multi-thread migration) +}, +{.name = dthreads, + .type = VSH_OT_INT, + .help = N_(decompression thread count for multi-thread migration) +}, +{.name = NULL} +}; + +static bool +cmdMigrateSetParameters(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom = NULL; +virTypedParameterPtr params = NULL; +int flags = 0; +unsigned int level = 0; +unsigned int threads = 0; +unsigned int dthreads = 0; +int nparams = 0; +int maxparams = 0; +bool ret = false; +int rv = 0; + +if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) +return false; + +if ((rv = vshCommandOptUIntWrap(cmd, level, level)) 0) { +vshError(ctl, + _(Numeric value for %s option is malformed or out of range), + level); +goto done; +} else if (rv 0) { +if (virTypedParamsAddUInt(params, nparams, maxparams, + VIR_DOMAIN_MIRGRATE_COMPRESSION_LEVEL, + level) 0) +goto done; +} + +if ((rv = vshCommandOptUIntWrap(cmd, threads, threads)) 0) { +vshError(ctl, + _(Numeric value for %s option is malformed or out of range), + threads); +goto done; +} else if (rv 0) { +if (virTypedParamsAddUInt(params, nparams, maxparams, + VIR_DOMAIN_MIRGRATE_COMPRESSION_THREADS, + threads) 0) +goto done; +} + +if ((rv = vshCommandOptUIntWrap(cmd, dthreads, dthreads)) 0) { +vshError(ctl, + _(Numeric value for %s option is malformed or out of range), + dthreads); +goto done; +} else if (rv 0) { +if (virTypedParamsAddUInt(params, nparams, maxparams, + VIR_DOMAIN_MIRGRATE_DECOMPRESSION_THREADS, + dthreads) 0) +goto done; +} + +if (virDomainMigrateSetParameters(dom, params, nparams, flags) 0) +goto done; + +ret = true; + + done: +virDomainFree(dom); +virTypedParamsFree(params, nparams); +return ret; +} + +/* + * migrate-getparameters command + */ +static const vshCmdInfo info_migrate_getparameters[] = { +{.name = help, + .data = N_(Get the mutit-thread migration parameters) +}, +{.name = desc, + .data = N_(Get the mutit-thread migration parameters for a domain.) +}, +{.name = NULL} +}; + +static const vshCmdOptDef opts_migrate_getparameters[] = { +{.name = domain, + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_(domain name, id or uuid) +}, +{.name = NULL} +}; + +static bool +cmdMigrateGetParameters(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom = NULL; +int flags = 0; +int i = 0; +int nparams = 0; +virTypedParameterPtr params = NULL; +bool ret = false; + +if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) +return false; + +/* probe the compress param number of migrate. Now it supports 3 params. */ +if (virDomainMigrateGetParameters(dom, NULL, nparams, 0) 0) +goto done; + +params = vshCalloc(ctl, nparams,
[libvirt] [PATCH 8/9] qemu_driver: Add support to set/get migration parameters.
From: Eli Qiao liyong.q...@intel.com Add qemuDomainMigrateGetParameters and qemuDomainMigrateSetParameters in order to set or get multi-thread compress parameters. Signed-off-by: ShaoHe Feng shaohe.f...@intel.com Signed-off-by: Eli Qiao liyong.q...@intel.com --- src/qemu/qemu_driver.c | 158 + 1 file changed, 158 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 498bcac..16a8b44 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -110,6 +110,8 @@ VIR_LOG_INIT(qemu.qemu_driver); #define QEMU_NB_BLOCK_IO_TUNE_PARAM 6 #define QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX 13 +#define QEMU_NB_MIGRATE_COMPRESS_PARAM 3 + #define QEMU_NB_NUMA_PARAM 2 #define QEMU_SCHED_MIN_PERIOD 1000LL @@ -13745,6 +13747,160 @@ qemuDomainMigrateGetMaxSpeed(virDomainPtr dom, return ret; } +static int +qemuDomainMigrateSetParameters(virDomainPtr dom, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ +size_t i; +virQEMUDriverPtr driver = dom-conn-privateData; +virDomainObjPtr vm; +qemuDomainObjPrivatePtr priv; +int ret = -1; +int level = -1; +int threads = -1; +int dthreads = -1; + +virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1); + +if (!(vm = qemuDomObjFromDomain(dom))) +goto cleanup; + +if (virTypedParamsValidate(params, nparams, + VIR_DOMAIN_MIRGRATE_COMPRESSION_LEVEL, + VIR_TYPED_PARAM_INT, + VIR_DOMAIN_MIRGRATE_COMPRESSION_THREADS, + VIR_TYPED_PARAM_INT, + VIR_DOMAIN_MIRGRATE_DECOMPRESSION_THREADS, + VIR_TYPED_PARAM_INT, + NULL) 0) +goto cleanup; + +if (virDomainMigrateSetParametersEnsureACL(dom-conn, vm-def) 0) +goto cleanup; + +priv = vm-privateData; + +for (i = 0; i nparams; i++) { +virTypedParameterPtr param = params[i]; + +if (STREQ(param-field, VIR_DOMAIN_MIRGRATE_COMPRESSION_LEVEL)) { +level = params[i].value.i; +} else if (STREQ(param-field, VIR_DOMAIN_MIRGRATE_COMPRESSION_THREADS)) { +threads = params[i].value.i; +} else if (STREQ(param-field, VIR_DOMAIN_MIRGRATE_DECOMPRESSION_THREADS)) { +dthreads = params[i].value.i; +} +} + +if (level QEMU_DOMAIN_MIG_PARAMETERS_LEVEL_MAX) { +virReportError(VIR_ERR_OVERFLOW, + _(level must be less than %d), + QEMU_DOMAIN_MIG_PARAMETERS_LEVEL_MAX + 1); +goto cleanup; +} else if (priv-job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN) { +virReportError(VIR_ERR_OPERATION_INVALID, %s, +_(compress level is invalid for destination + hypervisor during live migration)); +goto cleanup; +} + +if ((threads QEMU_DOMAIN_MIG_PARAMETERS_THREADS_MAX) || +(dthreads QEMU_DOMAIN_MIG_PARAMETERS_THREADS_MAX)) { +virReportError(VIR_ERR_OVERFLOW, _(both compress and decompress + threads number must be less than %d), + QEMU_DOMAIN_MIG_PARAMETERS_THREADS_MAX + 1); +goto cleanup; +} else if ((priv-job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN) || + (priv-job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT)) { +virReportError(VIR_ERR_OPERATION_INVALID, %s, + _(neither compress nor decompress threads number + setting is valid during live migration)); +goto cleanup; +} + +VIR_DEBUG(Setting migration multi-thread compress parameters: + level is %d, compress threads is %d, + decompress threads is %d, level, threads, dthreads); + +qemuDomainObjEnterMonitor(driver, vm); +ret = qemuMonitorSetMigrationParameters(priv-mon, level, threads, dthreads); + +if (qemuDomainObjExitMonitor(driver, vm) 0) +ret = -1; +ret = 0; + + cleanup: +virDomainObjEndAPI(vm); +return ret; +} + + +static int +qemuDomainMigrateGetParameters(virDomainPtr dom, + virTypedParameterPtr params, + int *nparams, + unsigned int flags) +{ +virDomainObjPtr vm; +virQEMUDriverPtr driver = dom-conn-privateData; +qemuDomainObjPrivatePtr priv; +int ret = -1; +unsigned int level = 0; +unsigned int threads = 0; +unsigned int dthreads = 0; + + +virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1); + +if (!(vm = qemuDomObjFromDomain(dom))) +goto cleanup; + +priv = vm-privateData; + +if (virDomainMigrateGetParametersEnsureACL(dom-conn, vm-def) 0) +goto cleanup; + +if ((*nparams) ==
[libvirt] [PATCH 4/9] set multi-thread compress params for Migrate3 during live migration
just support setting these params for Migrate3Full protocal. Signed-off-by: Eli Qiao liyong.q...@intel.com Signed-off-by: ShaoHe Feng shaohe.f...@intel.com --- include/libvirt/libvirt-domain.h | 24 src/qemu/qemu_domain.h | 3 +++ src/qemu/qemu_driver.c | 28 +++ src/qemu/qemu_migration.c| 49 src/qemu/qemu_migration.h| 9 5 files changed, 113 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index d851225..1c6ab16 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -2791,6 +2791,30 @@ int virDomainAbortJob(virDomainPtr dom); /** + * VIR_DOMAIN_MIRGRATE_COMPRESSION_LEVEL: + * + * .domainMigrateGetParameters field: level of compression when live migration, + * as VIR_TYPED_PARAM_UINT. + */ +# define VIR_DOMAIN_MIRGRATE_COMPRESSION_LEVEL migrate.compress-level + +/** + * VIR_DOMAIN_MIRGRATE_COMPRESSION_THREADS: + * + * .domainMigrateGetParameters field: numbers of compression threads when live + * migration, as VIR_TYPED_PARAM_UINT. + */ +# define VIR_DOMAIN_MIRGRATE_COMPRESSION_THREADS migrate.compress-threads + +/** + * VIR_DOMAIN_MIRGRATE_DECOMPRESSION_THREADS: + * + * .domainMigrateGetParameters field: numbers of decompression threads when + * live migration, as VIR_TYPED_PARAM_UINT. + */ +# define VIR_DOMAIN_MIRGRATE_DECOMPRESSION_THREADS migrate.decompress-threads + +/** * virConnectDomainEventGenericCallback: * @conn: the connection pointer * @dom: the domain pointer diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index a6df199..53af176 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -48,6 +48,9 @@ # define QEMU_DOMAIN_MIG_BANDWIDTH_MAX (INT64_MAX / (1024 * 1024)) # endif +# define QEMU_DOMAIN_MIG_PARAMETERS_LEVEL_MAX 9 +# define QEMU_DOMAIN_MIG_PARAMETERS_THREADS_MAX 255 + # define JOB_MASK(job) (1 (job - 1)) # define QEMU_JOB_DEFAULT_MASK \ (JOB_MASK(QEMU_JOB_QUERY) | \ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d1b00a2..498bcac 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12599,6 +12599,7 @@ qemuDomainMigrateBegin3Params(virDomainPtr domain, { const char *xmlin = NULL; const char *dname = NULL; +virQEMUDriverPtr driver = domain-conn-privateData; virDomainObjPtr vm; virCheckFlags(QEMU_MIGRATION_FLAGS, NULL); @@ -12620,6 +12621,10 @@ qemuDomainMigrateBegin3Params(virDomainPtr domain, virDomainObjEndAPI(vm); return NULL; } +if (qemuMigrationPrepareExtraParams(driver, vm, params, nparams) 0) { +virDomainObjEndAPI(vm); +return NULL; +} return qemuMigrationBegin(domain-conn, vm, xmlin, dname, cookieout, cookieoutlen, flags); @@ -12688,11 +12693,14 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, virQEMUDriverPtr driver = dconn-privateData; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virDomainDefPtr def = NULL; +virDomainObjPtr vm = NULL; const char *dom_xml = NULL; const char *dname = NULL; const char *uri_in = NULL; const char *listenAddress = cfg-migrationAddress; char *origname = NULL; +unsigned char uuid[VIR_UUID_BUFLEN]; +char *uuidstr = NULL; int ret = -1; virCheckFlagsGoto(QEMU_MIGRATION_FLAGS, cleanup); @@ -12726,6 +12734,8 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, if (!(def = qemuMigrationPrepareDef(driver, dom_xml, dname, origname))) goto cleanup; +memcpy(uuid, def-uuid, VIR_UUID_BUFLEN); + if (virDomainMigratePrepare3ParamsEnsureACL(dconn, def) 0) goto cleanup; @@ -12734,6 +12744,24 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, cookieout, cookieoutlen, uri_in, uri_out, def, origname, listenAddress, flags); +if (ret 0) + goto cleanup; + +if (!(vm = virDomainObjListFindByUUID(driver-domains, uuid))) { +virUUIDFormat(uuid, uuidstr); +virReportError(VIR_ERR_NO_DOMAIN, + _(no domain with matching uuid '%s'), uuidstr); +goto cleanup; +} +/* only domain start, we can set these prarams for it. */ +ret = qemuMigrationPrepareExtraParams(driver, vm, params, nparams); +if (ret 0){ +/* we need to stop the vm and realse the resource. */ +virDomainAuditStart(vm, migrated, false); +qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, 0); +qemuMigrationJobFinish(driver, vm); +} +virObjectUnlock(vm); cleanup: VIR_FREE(origname); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 3322f72..4ca4db2 100644 --- a/src/qemu/qemu_migration.c +++
[libvirt] [PATCH 5/9] virsh: add multi-thread migration option for live migrate command
Signed-off-by: Eli Qiao liyong.q...@intel.com Signed-off-by: ShaoHe Feng shaohe.f...@intel.com --- include/libvirt/libvirt-domain.h | 1 + tools/virsh-domain.c | 54 tools/virsh.pod | 22 +++- 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 1c6ab16..29b2b22 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -659,6 +659,7 @@ typedef enum { VIR_MIGRATE_ABORT_ON_ERROR= (1 12), /* abort migration on I/O errors happened during migration */ VIR_MIGRATE_AUTO_CONVERGE = (1 13), /* force convergence */ VIR_MIGRATE_RDMA_PIN_ALL = (1 14), /* RDMA memory pinning */ +VIR_MIGRATE_MT_COMPRESSED = (1 15), /* multiple threads compression during migration */ } virDomainMigrateFlags; diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 91a1ca2..b5713cc 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -9853,6 +9853,10 @@ static const vshCmdOptDef opts_migrate[] = { .type = VSH_OT_BOOL, .help = N_(compress repeated pages during live migration) }, +{.name = multi-thread-compress, + .type = VSH_OT_BOOL, + .help = N_(enable multi-thread compression during live migration) +}, {.name = auto-converge, .type = VSH_OT_BOOL, .help = N_(force convergence during live migration) @@ -9889,6 +9893,21 @@ static const vshCmdOptDef opts_migrate[] = { .type = VSH_OT_STRING, .help = N_(filename containing updated XML for the target) }, +{.name = compress-level, + .type = VSH_OT_INT, + .help = N_(compres level, from 0-9, 0 means use default level. +'--multi-thread-compress' option will set as true with this option.) +}, +{.name = compress-threads, + .type = VSH_OT_INT, + .help = N_(compres thread count for multi-thread migration, from 0-255. +'--multi-thread-compress' option will set as true with this option.) +}, +{.name = decompress-threads, + .type = VSH_OT_INT, + .help = N_(decompres thread count for multi-thread migration, from 0-255. +'--multi-thread-compress' option will set as true with this option.) +}, {.name = NULL} }; @@ -9907,6 +9926,8 @@ doMigrate(void *opaque) virTypedParameterPtr params = NULL; int nparams = 0; int maxparams = 0; +int value = 0; +int rv; virConnectPtr dconn = data-dconn; sigemptyset(sigmask); @@ -9948,6 +9969,36 @@ doMigrate(void *opaque) VIR_MIGRATE_PARAM_DEST_NAME, opt) 0) goto save_error; +if ((rv = vshCommandOptInt(cmd, compress-level, value)) 0) { +goto save_error; +} else if (rv 0) { +if (virTypedParamsAddInt(params, nparams, maxparams, + VIR_DOMAIN_MIRGRATE_COMPRESSION_LEVEL, + value) 0) +goto save_error; +flags |= VIR_MIGRATE_MT_COMPRESSED; +} + +if ((rv = vshCommandOptInt(cmd, compress-threads, value)) 0) { +goto save_error; +} else if (rv 0) { +if (virTypedParamsAddInt(params, nparams, maxparams, + VIR_DOMAIN_MIRGRATE_COMPRESSION_THREADS, + value) 0) +goto save_error; +flags |= VIR_MIGRATE_MT_COMPRESSED; +} + +if ((rv = vshCommandOptInt(cmd, decompress-threads, value)) 0) { +goto save_error; +} else if (rv 0) { +if (virTypedParamsAddInt(params, nparams, maxparams, + VIR_DOMAIN_MIRGRATE_DECOMPRESSION_THREADS, + value) 0) +goto save_error; +flags |= VIR_MIGRATE_MT_COMPRESSED; +} + if (vshCommandOptStringReq(ctl, cmd, xml, opt) 0) goto out; if (opt) { @@ -9996,6 +10047,9 @@ doMigrate(void *opaque) if (vshCommandOptBool(cmd, compressed)) flags |= VIR_MIGRATE_COMPRESSED; +if (vshCommandOptBool(cmd, multi-thread-compress)) +flags |= VIR_MIGRATE_MT_COMPRESSED; + if (vshCommandOptBool(cmd, auto-converge)) flags |= VIR_MIGRATE_AUTO_CONVERGE; diff --git a/tools/virsh.pod b/tools/virsh.pod index d588e5a..b81fd01 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1518,9 +1518,11 @@ to the Iuri namespace is displayed instead of being modified. =item Bmigrate [I--live] [I--offline] [I--direct] [I--p2p [I--tunnelled]] [I--persistent] [I--undefinesource] [I--suspend] [I--copy-storage-all] [I--copy-storage-inc] [I--change-protection] [I--unsafe] [I--verbose] -[I--compressed] [I--abort-on-error] [I--auto-converge] -Idomain Idesturi [Imigrateuri] [Igraphicsuri] [Ilisten-address] -[Idname] [I--timeout Bseconds] [I--xml Bfile] +[I--compressed] [I--multi-thread-compress]
[libvirt] [PATCH 3/9] Add test cases for qemuMonitorJSONGetMigrationParameter
From: Eli Qiao liyong.q...@intel.com This patch add test case for qemuMonitorJSONGetMigrationParameter. It will verify if qemu monitor json value can be parsed correctly. Signed-off-by: ShaoHe Feng shaohe.f...@intel.com Signed-off-by: Eli Qiao liyong.q...@intel.com --- tests/qemumonitorjsontest.c | 53 + 1 file changed, 53 insertions(+) diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 0f82fd8..70c28c5 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1620,6 +1620,59 @@ testQemuMonitorJSONqemuMonitorJSONGetBlockStatsInfo(const void *data) return ret; } +tatic int +testQemuMonitorJSONqemuMonitorJSONGetMigrationParameters(const void *data) +{ +virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; +qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); +int ret = -1; +unsigned int level; +unsigned int threads; +unsigned int dthreads; + +if (!test) +return -1; + +if (qemuMonitorTestAddItem(test, query-migrate-parameters, + { + \return\: { + \decompress-threads\: 2, + \compress-threads\: 8, + \compress-level\: 1 + } + }) 0) { +goto cleanup; +} + +if (qemuMonitorJSONGetMigrationParameters(qemuMonitorTestGetMonitor(test), + level, threads, dthreads) 0) +goto cleanup; +if (dthreads != 2) { +virReportError(VIR_ERR_INTERNAL_ERROR, + Invalid decompress-threads: %d, expected 2, + dthreads); +goto cleanup; +} +if (threads != 8) { +virReportError(VIR_ERR_INTERNAL_ERROR, + Invalid decompress-threads: %d, expected 8, + threads); +goto cleanup; +} +if (level != 1) { +virReportError(VIR_ERR_INTERNAL_ERROR, + Invalid decompress-threads: %d, expected 1, + level); +goto cleanup; +} +ret = 0; + + cleanup: +qemuMonitorTestFree(test); +return ret; +} + + static int testQemuMonitorJSONqemuMonitorJSONGetMigrationCacheSize(const void *data) { -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/9] qemu_migration: Add support for mutil-thread compressed migration enable
We need to set the mutil-thread compress capability as true to enable it. Signed-off-by: Eli Qiao liyong.q...@intel.com Signed-off-by: ShaoHe Feng shaohe.f...@intel.com --- src/qemu/qemu_migration.c | 56 +++ src/qemu/qemu_migration.h | 9 +++- src/qemu/qemu_monitor.c | 2 +- src/qemu/qemu_monitor.h | 1 + 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index f7432e8..3322f72 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2234,6 +2234,52 @@ qemuMigrationSetCompression(virQEMUDriverPtr driver, return ret; } +int +qemuMigrationSetMultiThreadCompression(virQEMUDriverPtr driver, + virDomainObjPtr vm, + bool state, + qemuDomainAsyncJob job) +{ +qemuDomainObjPrivatePtr priv = vm-privateData; +int ret = -1; + +if (qemuDomainObjEnterMonitorAsync(driver, vm, job) 0) +return -1; + +ret = qemuMonitorGetMigrationCapability( +priv-mon, +QEMU_MONITOR_MIGRATION_CAPS_MT_COMPRESS); + +if (ret 0) { +goto cleanup; +} else if (ret == 0 !state) { +/* Unsupported but we want it off anyway */ +goto cleanup; +} else if (ret == 0) { +if (job == QEMU_ASYNC_JOB_MIGRATION_IN) { +virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, + _(Multi-thread compressed migration is not supported by + target QEMU binary)); +} else { +virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, + _(Multi-thread compressed migration is not supported by + source QEMU binary)); +} +ret = -1; +goto cleanup; +} + +ret = qemuMonitorSetMigrationCapability( +priv-mon, +QEMU_MONITOR_MIGRATION_CAPS_MT_COMPRESS, +state); + + cleanup: +if (qemuDomainObjExitMonitor(driver, vm) 0) +ret = -1; +return ret; +} + static int qemuMigrationSetAutoConverge(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -3143,6 +3189,11 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, QEMU_ASYNC_JOB_MIGRATION_IN) 0) goto stop; +if (qemuMigrationSetMultiThreadCompression(driver, vm, + flags VIR_MIGRATE_MT_COMPRESSED, + QEMU_ASYNC_JOB_MIGRATION_IN) 0) +goto stop; + if (STREQ_NULLABLE(protocol, rdma) virProcessSetMaxMemLock(vm-pid, vm-def-mem.hard_limit 10) 0) { goto stop; @@ -3980,6 +4031,11 @@ qemuMigrationRun(virQEMUDriverPtr driver, QEMU_ASYNC_JOB_MIGRATION_OUT) 0) goto cleanup; +if (qemuMigrationSetMultiThreadCompression(driver, vm, + flags VIR_MIGRATE_MT_COMPRESSED, + QEMU_ASYNC_JOB_MIGRATION_OUT) 0) +goto cleanup; + if (qemuMigrationSetAutoConverge(driver, vm, flags VIR_MIGRATE_AUTO_CONVERGE, QEMU_ASYNC_JOB_MIGRATION_OUT) 0) diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 1726455..065623b 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -41,7 +41,8 @@ VIR_MIGRATE_COMPRESSED | \ VIR_MIGRATE_ABORT_ON_ERROR | \ VIR_MIGRATE_AUTO_CONVERGE |\ - VIR_MIGRATE_RDMA_PIN_ALL) + VIR_MIGRATE_RDMA_PIN_ALL | \ + VIR_MIGRATE_MT_COMPRESSED) /* All supported migration parameters and their types. */ # define QEMU_MIGRATION_PARAMETERS \ @@ -177,4 +178,10 @@ int qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK; +int +qemuMigrationSetMultiThreadCompression(virQEMUDriverPtr driver, + virDomainObjPtr vm, + bool state, + qemuDomainAsyncJob job); + #endif /* __QEMU_MIGRATION_H__ */ diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index f959b74..18abfee 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -163,7 +163,7 @@ VIR_ENUM_IMPL(qemuMonitorMigrationStatus, VIR_ENUM_IMPL(qemuMonitorMigrationCaps, QEMU_MONITOR_MIGRATION_CAPS_LAST, - xbzrle, auto-converge, rdma-pin-all) + xbzrle, auto-converge, rdma-pin-all, compress) VIR_ENUM_IMPL(qemuMonitorVMStatus,
[libvirt] [PATCH v2 4/4] qemu_hotplug: try harder to eject media
Some guests lock the tray and QEMU eject command will simply fail to eject the media. But the guest OS can handle this attempt to eject the media and can unlock the tray and open it. In this case, we should try again to actually eject the media. If the first attempt fails to detect a tray_open we will fail with error, from monitor. If we receive that event, we know, that the guest properly reacted to the eject request, unlocked the tray and opened it. In this case, we need to run the command again to actually eject the media from the device. The reason to call it again is, that QEMU don't wait for the guest to react and report an error, that the tray is locked. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1147471 Signed-off-by: Pavel Hrdina phrd...@redhat.com --- src/qemu/qemu_hotplug.c | 73 +++-- src/qemu/qemu_process.c | 2 ++ 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 0628964..17595b7 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -59,7 +59,7 @@ VIR_LOG_INIT(qemu.qemu_hotplug); -#define CHANGE_MEDIA_RETRIES 10 +#define CHANGE_MEDIA_TIMEOUT 5000 /* Wait up to 5 seconds for device removal to finish. */ unsigned long long qemuDomainRemoveDeviceWaitTime = 1000ull * 5; @@ -166,12 +166,13 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, virStorageSourcePtr newsrc, bool force) { -int ret = -1; +int ret = -1, rc; char *driveAlias = NULL; qemuDomainObjPrivatePtr priv = vm-privateData; -int retries = CHANGE_MEDIA_RETRIES; const char *format = NULL; char *sourcestr = NULL; +bool ejectRetry = false; +unsigned long long now; if (!disk-info.alias) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -193,36 +194,31 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, if (!(driveAlias = qemuDeviceDriveHostAlias(disk, priv-qemuCaps))) goto error; -qemuDomainObjEnterMonitor(driver, vm); -ret = qemuMonitorEjectMedia(priv-mon, driveAlias, force); -if (qemuDomainObjExitMonitor(driver, vm) 0) { -ret = -1; -goto cleanup; -} - -if (ret 0) -goto error; +do { +qemuDomainObjEnterMonitor(driver, vm); +rc = qemuMonitorEjectMedia(priv-mon, driveAlias, force); +if (qemuDomainObjExitMonitor(driver, vm) 0) +goto cleanup; -virObjectRef(vm); -/* we don't want to report errors from media tray_open polling */ -while (retries) { -if (disk-tray_status == VIR_DOMAIN_DISK_TRAY_OPEN) -break; +if (rc == -2) { +/* we've already tried, error out */ +if (ejectRetry) +goto error; +VIR_DEBUG(tray is locked, wait for the guest to unlock + the tray and try to eject it again); +ejectRetry = true; +} else if (rc 0) { +goto error; +} -retries--; -virObjectUnlock(vm); -VIR_DEBUG(Waiting 500ms for tray to open. Retries left %d, retries); -usleep(500 * 1000); /* sleep 500ms */ -virObjectLock(vm); -} -virObjectUnref(vm); +if (virTimeMillisNow(now) 0) +goto error; -if (retries = 0) { -virReportError(VIR_ERR_OPERATION_FAILED, %s, - _(Unable to eject media)); -ret = -1; -goto error; -} +while (disk-tray_status != VIR_DOMAIN_DISK_TRAY_OPEN) { +if (virDomainObjWaitUntil(vm, now + CHANGE_MEDIA_TIMEOUT) != 0) +goto error; +} +} while (ejectRetry rc != 0); if (!virStorageSourceIsEmpty(newsrc)) { if (qemuGetDriveSourceString(newsrc, conn, sourcestr) 0) @@ -237,19 +233,17 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, } } qemuDomainObjEnterMonitor(driver, vm); -ret = qemuMonitorChangeMedia(priv-mon, - driveAlias, - sourcestr, - format); -if (qemuDomainObjExitMonitor(driver, vm) 0) { -ret = -1; +rc = qemuMonitorChangeMedia(priv-mon, +driveAlias, +sourcestr, +format); +if (qemuDomainObjExitMonitor(driver, vm) 0) goto cleanup; -} } -virDomainAuditDisk(vm, disk-src, newsrc, update, ret = 0); +virDomainAuditDisk(vm, disk-src, newsrc, update, rc = 0); -if (ret 0) +if (rc 0) goto error; /* remove the old source from shared device list */ @@ -259,6 +253,7 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, virStorageSourceFree(disk-src); disk-src = newsrc;
[libvirt] [PATCH 08/13] vsh: Introduce client hooks
--- tools/virsh.c | 1 + tools/vsh.c | 1 + tools/vsh.h | 6 ++ 3 files changed, 8 insertions(+) diff --git a/tools/virsh.c b/tools/virsh.c index 404deb8..017a669 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -82,6 +82,7 @@ static char *progname; static const vshCmdGrp cmdGroups[]; +static const vshClientHooks hooks; double virshPrettyCapacity(unsigned long long val, const char **unit) diff --git a/tools/vsh.c b/tools/vsh.c index 71c8344..5f8461c 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -67,6 +67,7 @@ # define SA_SIGINFO 0 #endif +static const vshClientHooks *hooks; static const vshCmdGrp *cmdGroups; /* Bypass header poison */ diff --git a/tools/vsh.h b/tools/vsh.h index aaeb086..eae38d5 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -114,6 +114,7 @@ enum { }; /* forward declarations */ +typedef struct _vshClientHooks vshClientHooks; typedef struct _vshCmd vshCmd; typedef struct _vshCmdDef vshCmdDef; typedef struct _vshCmdGrp vshCmdGrp; @@ -223,6 +224,11 @@ struct _vshControl { void *privData; /* client specific data */ }; +typedef void * +(*vshConnectionHook)(vshControl *ctl); + +struct _vshClientHooks { +vshConnectionHook connHandler; }; struct _vshCmdGrp { -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 12/13] virsh: Introduce connection handler
Before any virsh command can be executed, client connection to daemon needs to be checked, i.e. first we try to reconnect if needed and then check the connection usability which is connection type specific. This handler is registered as client hook. --- tools/virsh.c | 8 1 file changed, 8 insertions(+) diff --git a/tools/virsh.c b/tools/virsh.c index 017a669..fcbd553 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -915,9 +915,17 @@ virshConnectionUsability(vshControl *ctl, virConnectPtr conn) return true; } +static void * +virshConnectionHandler(vshControl *ctl) { +virshControlPtr priv = ctl-privData; +if (!priv-conn || disconnected) +virshReconnect(ctl); +if (virshConnectionUsability(ctl, priv-conn)) +return priv-conn; +return NULL; } /* --- -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 10/13] vsh: Introduce new global initializer
Right now, there's very little to do in global initializer besides registering client hooks, but there's a potential to have some more features that will need to be properly initialized beforehand (exporting vshControl pointer only would definitely make use of this). --- tools/vsh.c | 24 tools/vsh.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/tools/vsh.c b/tools/vsh.c index 4eb5de2..ed1fdb9 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -1942,6 +1942,30 @@ vshInitDebug(vshControl *ctl) } +/* + * Initialize global data + */ +int +vshInit(vshControl *ctl, +const vshClientHooks *clhooks, +const vshCmdGrp *clgrps) +{ +if (!clhooks || !clhooks-connHandler) { +vshError(ctl, %s, _(client hooks must not be NULL)); +return -1; +} + +if (!clgrps) { +vshError(ctl, %s, _(command groups must not be NULL)); +return -1; +} + +hooks = clhooks; +cmdGroups = clgrps; +vshInitDebug(ctl); +return 0; +} + #define LOGFILE_FLAGS (O_WRONLY | O_APPEND | O_CREAT | O_SYNC) /** diff --git a/tools/vsh.h b/tools/vsh.h index eae38d5..6bf742d 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -300,6 +300,9 @@ typedef enum { void vshPrintExtra(vshControl *ctl, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); +int vshInit(vshControl *ctl, const vshClientHooks *clhooks, +const vshCmdGrp *clgrps) +ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); void vshDebug(vshControl *ctl, int level, const char *format, ...) ATTRIBUTE_FMT_PRINTF(3, 4); -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 11/13] vsh: Make separated generic methods public
Earlier, we have moved virsh generic methods into vsh module, but to make them really usable by other clients, they cannot be defined as static. --- tools/vsh.c | 22 +++--- tools/vsh.h | 16 ++-- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index ed1fdb9..9b810c9 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -1128,7 +1128,7 @@ vshCommandOptArgv(vshControl *ctl ATTRIBUTE_UNUSED, const vshCmd *cmd, /* * Executes command(s) and returns return code from last command */ -static bool +bool vshCommandRun(vshControl *ctl, const vshCmd *cmd) { bool ret = true; @@ -1415,7 +1415,7 @@ vshCommandArgvGetArg(vshControl *ctl, vshCommandParser *parser, char **res) return VSH_TK_ARG; } -static bool +bool vshCommandArgvParse(vshControl *ctl, int nargs, char **argv) { vshCommandParser parser; @@ -1494,7 +1494,7 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res) return VSH_TK_ARG; } -static bool +bool vshCommandStringParse(vshControl *ctl, char *cmdstr) { vshCommandParser parser; @@ -1745,7 +1745,7 @@ vshError(vshControl *ctl, const char *format, ...) } -static void +void vshEventLoop(void *opaque) { vshControl *ctl = opaque; @@ -1788,7 +1788,7 @@ vshEventInt(int sig ATTRIBUTE_UNUSED, /* Event loop handler used to limit length of waiting for any other event. */ -static void +void vshEventTimeout(int timer ATTRIBUTE_UNUSED, void *opaque) { @@ -1911,7 +1911,7 @@ vshEventCleanup(vshControl *ctl) /* * Initialize debug settings. */ -static void +void vshInitDebug(vshControl *ctl) { const char *debugEnv; @@ -2213,7 +2213,7 @@ vshReadlineCompletion(const char *text, int start, # define VIRSH_HISTSIZE_MAX 50 -static int +int vshReadlineInit(vshControl *ctl) { char *userdir = NULL; @@ -2271,7 +2271,7 @@ vshReadlineInit(vshControl *ctl) return 0; } -static void +void vshReadlineDeinit(vshControl *ctl) { if (ctl-historyfile != NULL) { @@ -2289,7 +2289,7 @@ vshReadlineDeinit(vshControl *ctl) VIR_FREE(ctl-historyfile); } -static char * +char * vshReadline(vshControl *ctl ATTRIBUTE_UNUSED, const char *prompt) { return readline(prompt); @@ -2297,14 +2297,14 @@ vshReadline(vshControl *ctl ATTRIBUTE_UNUSED, const char *prompt) #else /* !WITH_READLINE */ -static int +int vshReadlineInit(vshControl *ctl ATTRIBUTE_UNUSED) { /* empty */ return 0; } -static void +void vshReadlineDeinit(vshControl *ctl ATTRIBUTE_UNUSED) { /* empty */ diff --git a/tools/vsh.h b/tools/vsh.h index 6bf742d..1ad0287 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -287,8 +287,12 @@ int vshCommandOptScaledInt(vshControl *ctl, const vshCmd *cmd, int scale, unsigned long long max) ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK; bool vshCommandOptBool(const vshCmd *cmd, const char *name); +bool vshCommandRun(vshControl *ctl, const vshCmd *cmd); +bool vshCommandStringParse(vshControl *ctl, char *cmdstr); + const vshCmdOpt *vshCommandOptArgv(vshControl *ctl, const vshCmd *cmd, const vshCmdOpt *opt); +bool vshCommandArgvParse(vshControl *ctl, int nargs, char **argv); /* Filter flags for various vshCommandOpt*By() functions */ typedef enum { @@ -303,6 +307,7 @@ void vshPrintExtra(vshControl *ctl, const char *format, ...) int vshInit(vshControl *ctl, const vshClientHooks *clhooks, const vshCmdGrp *clgrps) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +void vshInitDebug(vshControl *ctl); void vshDebug(vshControl *ctl, int level, const char *format, ...) ATTRIBUTE_FMT_PRINTF(3, 4); @@ -341,10 +346,17 @@ enum { VSH_EVENT_TIMEOUT, VSH_EVENT_DONE, }; -int vshEventStart(vshControl *ctl, int timeout_ms); +void vshEventCleanup(vshControl *ctl); void vshEventDone(vshControl *ctl); +void vshEventLoop(void *opaque); +int vshEventStart(vshControl *ctl, int timeout_ms); +void vshEventTimeout(int timer, void *opaque); int vshEventWait(vshControl *ctl); -void vshEventCleanup(vshControl *ctl); + +/* readline */ +char * vshReadline(vshControl *ctl, const char *prompt); +int vshReadlineInit(vshControl *ctl); +void vshReadlineDeinit(vshControl *ctl); /* allocation wrappers */ void *_vshMalloc(vshControl *ctl, size_t sz, const char *filename, int line); -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 07/13] vsh: Make use of introduced private data
--- tools/virsh-console.c| 3 +- tools/virsh-domain-monitor.c | 23 + tools/virsh-domain.c | 110 +++ tools/virsh-host.c | 78 ++ tools/virsh-interface.c | 46 +++--- tools/virsh-network.c| 36 -- tools/virsh-nodedev.c| 31 +++- tools/virsh-nwfilter.c | 21 + tools/virsh-pool.c | 44 ++--- tools/virsh-secret.c | 15 +++--- tools/virsh-snapshot.c | 25 +- tools/virsh-volume.c | 17 --- tools/virsh.c| 57 +- 13 files changed, 311 insertions(+), 195 deletions(-) diff --git a/tools/virsh-console.c b/tools/virsh-console.c index 86ba456..c1927c2 100644 --- a/tools/virsh-console.c +++ b/tools/virsh-console.c @@ -311,6 +311,7 @@ virshRunConsole(vshControl *ctl, unsigned int flags) { virConsolePtr con = NULL; +virshControlPtr priv = ctl-privData; int ret = -1; struct sigaction old_sigquit; @@ -341,7 +342,7 @@ virshRunConsole(vshControl *ctl, if (VIR_ALLOC(con) 0) goto cleanup; -con-escapeChar = virshGetEscapeChar(ctl-escapeChar); +con-escapeChar = virshGetEscapeChar(priv-escapeChar); con-st = virStreamNew(virDomainGetConnect(dom), VIR_STREAM_NONBLOCK); if (!con-st) diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index 1f53428..0762d6e 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -1210,6 +1210,7 @@ cmdDominfo(vshControl *ctl, const vshCmd *cmd) unsigned int id; char *str, uuid[VIR_UUID_STRING_BUFLEN]; int has_managed_save = 0; +virshControlPtr priv = ctl-privData; if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) return false; @@ -1281,7 +1282,7 @@ cmdDominfo(vshControl *ctl, const vshCmd *cmd) /* Security model and label information */ memset(secmodel, 0, sizeof(secmodel)); -if (virNodeGetSecurityModel(ctl-conn, secmodel) == -1) { +if (virNodeGetSecurityModel(priv-conn, secmodel) == -1) { if (last_error-code != VIR_ERR_NO_SUPPORT) { virDomainFree(dom); return false; @@ -1568,9 +1569,10 @@ virshDomainListCollect(vshControl *ctl, unsigned int flags) int state; int nsnap; int mansave; +virshControlPtr priv = ctl-privData; /* try the list with flags support (0.9.13 and later) */ -if ((ret = virConnectListAllDomains(ctl-conn, list-domains, +if ((ret = virConnectListAllDomains(priv-conn, list-domains, flags)) = 0) { list-ndomains = ret; goto finished; @@ -1588,7 +1590,7 @@ virshDomainListCollect(vshControl *ctl, unsigned int flags) VIR_CONNECT_LIST_DOMAINS_INACTIVE); vshResetLibvirtError(); -if ((ret = virConnectListAllDomains(ctl-conn, list-domains, +if ((ret = virConnectListAllDomains(priv-conn, list-domains, newflags)) = 0) { list-ndomains = ret; goto filter; @@ -1607,7 +1609,7 @@ virshDomainListCollect(vshControl *ctl, unsigned int flags) /* list active domains, if necessary */ if (!VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) || VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE)) { -if ((nids = virConnectNumOfDomains(ctl-conn)) 0) { +if ((nids = virConnectNumOfDomains(priv-conn)) 0) { vshError(ctl, %s, _(Failed to list active domains)); goto cleanup; } @@ -1615,7 +1617,7 @@ virshDomainListCollect(vshControl *ctl, unsigned int flags) if (nids) { ids = vshMalloc(ctl, sizeof(int) * nids); -if ((nids = virConnectListDomains(ctl-conn, ids, nids)) 0) { +if ((nids = virConnectListDomains(priv-conn, ids, nids)) 0) { vshError(ctl, %s, _(Failed to list active domains)); goto cleanup; } @@ -1624,7 +1626,7 @@ virshDomainListCollect(vshControl *ctl, unsigned int flags) if (!VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) || VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE)) { -if ((nnames = virConnectNumOfDefinedDomains(ctl-conn)) 0) { +if ((nnames = virConnectNumOfDefinedDomains(priv-conn)) 0) { vshError(ctl, %s, _(Failed to list inactive domains)); goto cleanup; } @@ -1632,7 +1634,7 @@ virshDomainListCollect(vshControl *ctl, unsigned int flags) if (nnames) { names = vshMalloc(ctl, sizeof(char *) * nnames); -if ((nnames = virConnectListDefinedDomains(ctl-conn, names, +if ((nnames = virConnectListDefinedDomains(priv-conn, names, nnames)) 0) {
[libvirt] [PATCH 13/13] tools: Update makefile to include 'vsh' sources as well
--- tools/Makefile.am | 4 1 file changed, 4 insertions(+) diff --git a/tools/Makefile.am b/tools/Makefile.am index 93d642d..03e9339 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -179,7 +179,11 @@ virt_login_shell_CFLAGS = \ $(PIE_CFLAGS) \ $(COVERAGE_CFLAGS) +virt_shell_SOURCES = \ + vsh.c vsh.h + virsh_SOURCES =\ + $(virt_shell_SOURCES) \ virsh.c virsh.h \ virsh-console.c virsh-console.h \ virsh-domain.c virsh-domain.h \ -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/2] qemu: event: Clean up VNC monitor handling
Get rid of spice specific stuff from the handler func and save a few lines by reflowing the conditions. --- src/qemu/qemu_monitor_json.c | 29 + 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index ba1e4f9..e9af1e1 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -638,40 +638,37 @@ qemuMonitorJSONHandleGraphicsVNC(qemuMonitorPtr mon, return; } -authScheme = virJSONValueObjectGetString(server, auth); -if (!authScheme) { +if (!(authScheme = virJSONValueObjectGetString(server, auth))) { /* not all events are required to contain auth scheme */ VIR_DEBUG(missing auth scheme in graphics event); authScheme = ; } -localFamily = virJSONValueObjectGetString(server, family); -if (!localFamily) { +if (!(localFamily = virJSONValueObjectGetString(server, family))) { VIR_WARN(missing local address family in graphics event); return; } -localNode = virJSONValueObjectGetString(server, host); -if (!localNode) { +if (!(localNode = virJSONValueObjectGetString(server, host))) { VIR_WARN(missing local hostname in graphics event); return; } -localService = virJSONValueObjectGetString(server, service); -if (!localService) -localService = ; /* Spice has multiple ports, so this isn't provided */ +if (!(localService = virJSONValueObjectGetString(server, service))) { +VIR_WARN(missing local service in graphics event); +return; +} -remoteFamily = virJSONValueObjectGetString(client, family); -if (!remoteFamily) { +if (!(remoteFamily = virJSONValueObjectGetString(client, family))) { VIR_WARN(missing remote address family in graphics event); return; } -remoteNode = virJSONValueObjectGetString(client, host); -if (!remoteNode) { +if (!(remoteNode = virJSONValueObjectGetString(client, host))) { VIR_WARN(missing remote hostname in graphics event); return; } -remoteService = virJSONValueObjectGetString(client, service); -if (!remoteService) -remoteService = ; /* Spice has multiple ports, so this isn't provided */ +if (!(remoteService = virJSONValueObjectGetString(client, service))) { +VIR_WARN(missing remote service in graphics event); +return; +} saslUsername = virJSONValueObjectGetString(client, sasl_username); x509dname = virJSONValueObjectGetString(client, x509_dname); -- 2.4.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/2] qemu: event: Properly handle spice events
Spice events have mostly similar information present in the event JSON but they differ in the name of the element containing the port. The JSON event also provides connection ID which might be useful in the future. This patch splits up the event parser code into two functions and the SPICE reimplements the event parsing with correct names and drops the VNC only stuff. --- src/qemu/qemu_monitor_json.c | 81 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index d3e98d4..ba1e4f9 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -617,7 +617,10 @@ VIR_ENUM_IMPL(qemuMonitorGraphicsAddressFamily, VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_LAST, ipv4, ipv6, unix); -static void qemuMonitorJSONHandleGraphics(qemuMonitorPtr mon, virJSONValuePtr data, int phase) +static void +qemuMonitorJSONHandleGraphicsVNC(qemuMonitorPtr mon, + virJSONValuePtr data, + int phase) { const char *localNode, *localService, *localFamily; const char *remoteNode, *remoteService, *remoteFamily; @@ -690,37 +693,101 @@ static void qemuMonitorJSONHandleGraphics(qemuMonitorPtr mon, virJSONValuePtr da static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data) { -qemuMonitorJSONHandleGraphics(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT); +qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT); } static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data) { -qemuMonitorJSONHandleGraphics(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE); +qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE); } static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data) { -qemuMonitorJSONHandleGraphics(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT); +qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT); +} + + +static void +qemuMonitorJSONHandleGraphicsSPICE(qemuMonitorPtr mon, + virJSONValuePtr data, + int phase) +{ +const char *lhost, *lport, *lfamily; +const char *rhost, *rport, *rfamily; +const char *auth = ; +int lfamilyID, rfamilyID; +virJSONValuePtr client; +virJSONValuePtr server; + +if (!(client = virJSONValueObjectGetObject(data, client)) || +!(server = virJSONValueObjectGetObject(data, server))) { +VIR_WARN(missing server or client info in SPICE event); +return; +} + +if (phase == VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE +!(auth = virJSONValueObjectGetString(server, auth))) { +VIR_DEBUG(missing auth scheme in graphics event); +auth = ; +} + +if (!(lfamily = virJSONValueObjectGetString(server, family))) { +VIR_WARN(missing local address family in graphics event); +return; +} +if (!(lhost = virJSONValueObjectGetString(server, host))) { +VIR_WARN(missing local hostname in graphics event); +return; +} +if (!(lport = virJSONValueObjectGetString(server, port))) { +VIR_WARN(missing local port in graphics event); +return; +} + +if (!(rfamily = virJSONValueObjectGetString(client, family))) { +VIR_WARN(missing remote address family in graphics event); +return; +} +if (!(rhost = virJSONValueObjectGetString(client, host))) { +VIR_WARN(missing remote hostname in graphics event); +return; +} +if (!(rport = virJSONValueObjectGetString(client, port))) { +VIR_WARN(missing remote service in graphics event); +return; +} + +if ((lfamilyID = qemuMonitorGraphicsAddressFamilyTypeFromString(lfamily)) 0) { +VIR_WARN(unknown address family '%s', lfamily); +lfamilyID = VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4; +} +if ((rfamilyID = qemuMonitorGraphicsAddressFamilyTypeFromString(rfamily)) 0) { +VIR_WARN(unknown address family '%s', rfamily); +rfamilyID = VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4; +} + +qemuMonitorEmitGraphics(mon, phase, lfamilyID, lhost, lport, rfamilyID, +rhost, rport, auth, NULL, NULL); } static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONValuePtr data) { -qemuMonitorJSONHandleGraphics(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT); +qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT); } static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJSONValuePtr data) { -qemuMonitorJSONHandleGraphics(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE); +qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE); } static
[libvirt] [PATCH 0/2] qemu: Properly report port numbers in spice events
Peter Krempa (2): qemu: event: Properly handle spice events qemu: event: Clean up VNC monitor handling src/qemu/qemu_monitor_json.c | 110 ++- 1 file changed, 87 insertions(+), 23 deletions(-) -- 2.4.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 02/13] vsh: Remove client specific data, only generic data are kept
Virt shell (vsh) started as a copy of virsh, but it needs to be split from virsh, so remove all virsh specific data that cannot/need not be used with other potential clients like virt-admin --- tools/vsh.c | 1505 +-- tools/vsh.h | 66 +-- 2 files changed, 9 insertions(+), 1562 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index 609c8f3..8ef04b9 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -32,7 +32,6 @@ #include stdarg.h #include unistd.h #include errno.h -#include getopt.h #include sys/time.h #include c-ctype.h #include fcntl.h @@ -63,27 +62,12 @@ #include virtypedparam.h #include virstring.h -#include virsh-console.h -#include virsh-domain.h -#include virsh-domain-monitor.h -#include virsh-host.h -#include virsh-interface.h -#include virsh-network.h -#include virsh-nodedev.h -#include virsh-nwfilter.h -#include virsh-pool.h -#include virsh-secret.h -#include virsh-snapshot.h -#include virsh-volume.h - /* Gnulib doesn't guarantee SA_SIGINFO support. */ #ifndef SA_SIGINFO # define SA_SIGINFO 0 #endif -static char *progname; - -static const vshCmdGrp cmdGroups[]; +static const vshCmdGrp *cmdGroups; /* Bypass header poison */ #undef strdup @@ -138,44 +122,6 @@ vshNameSorter(const void *a, const void *b) return vshStrcasecmp(*sa, *sb); } -double -vshPrettyCapacity(unsigned long long val, const char **unit) -{ -double limit = 1024; - -if (val limit) { -*unit = B; -return val; -} -limit *= 1024; -if (val limit) { -*unit = KiB; -return val / (limit / 1024); -} -limit *= 1024; -if (val limit) { -*unit = MiB; -return val / (limit / 1024); -} -limit *= 1024; -if (val limit) { -*unit = GiB; -return val / (limit / 1024); -} -limit *= 1024; -if (val limit) { -*unit = TiB; -return val / (limit / 1024); -} -limit *= 1024; -if (val limit) { -*unit = PiB; -return val / (limit / 1024); -} -limit *= 1024; -*unit = EiB; -return val / (limit / 1024); -} /* * Convert the strings separated by ',' into array. The returned @@ -299,743 +245,14 @@ vshReportError(vshControl *ctl) vshError(ctl, %s, last_error-message); - out: -vshResetLibvirtError(); -} - -/* - * Detection of disconnections and automatic reconnection support - */ -static int disconnected; /* we may have been disconnected */ - -/* - * vshCatchDisconnect: - * - * We get here when the connection was closed. We can't do much in the - * handler, just save the fact it was raised. - */ -static void -vshCatchDisconnect(virConnectPtr conn ATTRIBUTE_UNUSED, - int reason, - void *opaque ATTRIBUTE_UNUSED) -{ -if (reason != VIR_CONNECT_CLOSE_REASON_CLIENT) -disconnected++; -} - -/* Main Function which should be used for connecting. - * This function properly handles keepalive settings. */ -virConnectPtr -vshConnect(vshControl *ctl, const char *uri, bool readonly) -{ -virConnectPtr c = NULL; -int interval = 5; /* Default */ -int count = 6;/* Default */ -bool keepalive_forced = false; - -if (ctl-keepalive_interval = 0) { -interval = ctl-keepalive_interval; -keepalive_forced = true; -} -if (ctl-keepalive_count = 0) { -count = ctl-keepalive_count; -keepalive_forced = true; -} - -c = virConnectOpenAuth(uri, virConnectAuthPtrDefault, - readonly ? VIR_CONNECT_RO : 0); -if (!c) -return NULL; - -if (interval 0 -virConnectSetKeepAlive(c, interval, count) != 0) { -if (keepalive_forced) { -vshError(ctl, %s, - _(Cannot setup keepalive on connection - as requested, disconnecting)); -virConnectClose(c); -return NULL; -} -vshDebug(ctl, VSH_ERR_INFO, %s, - _(Failed to setup keepalive on connection\n)); -} - -return c; -} - -/* - * vshReconnect: - * - * Reconnect after a disconnect from libvirtd - * - */ -static void -vshReconnect(vshControl *ctl) -{ -bool connected = false; - -if (ctl-conn) { -int ret; - -connected = true; - -virConnectUnregisterCloseCallback(ctl-conn, vshCatchDisconnect); -ret = virConnectClose(ctl-conn); -if (ret 0) -vshError(ctl, %s, _(Failed to disconnect from the hypervisor)); -else if (ret 0) -vshError(ctl, %s, _(One or more references were leaked after - disconnect from the hypervisor)); -} - -ctl-conn = vshConnect(ctl, ctl-name, ctl-readonly); - -if (!ctl-conn) { -if (disconnected) -vshError(ctl, %s, _(Failed to reconnect to the hypervisor)); -else -vshError(ctl, %s, _(failed to connect to the hypervisor)); -}
[libvirt] [PATCH 09/13] vsh: Make use of newly introduced client side hooks
--- tools/vsh.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index 5f8461c..4eb5de2 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -1137,15 +1137,11 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd) struct timeval before, after; bool enable_timing = ctl-timing; -if ((ctl-conn == NULL || disconnected) -!(cmd-def-flags VSH_CMD_FLAG_NOCONNECT)) -vshReconnect(ctl); - if (enable_timing) GETTIMEOFDAY(before); if ((cmd-def-flags VSH_CMD_FLAG_NOCONNECT) || -vshConnectionUsability(ctl, ctl-conn)) { +(hooks hooks-connHandler hooks-connHandler(ctl))) { ret = cmd-def-handler(ctl, cmd); } else { /* connection is not usable, return error */ -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 06/13] vsh: vshControl now includes client private data and client specific progname
For our new generic methods, it's highly sufficient to use generic vshControl structure only, however this doesn't apply for clients themselves. They need their own control structure and we need a valid reference to them, so why not store them as generic private data that only the client can process. --- tools/vsh.h | 4 1 file changed, 4 insertions(+) diff --git a/tools/vsh.h b/tools/vsh.h index 76704a1..aaeb086 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -194,6 +194,7 @@ struct _vshCmd { */ struct _vshControl { char *name; /* connection name */ +char *progname; /* program name */ vshCmd *cmd;/* the current command */ char *cmdstr; /* string with command */ bool imode; /* interactive mode? */ @@ -219,6 +220,9 @@ struct _vshControl { struct termios termattr;/* settings of the tty terminal */ # endif bool istty; /* is the terminal a tty */ +void *privData; /* client specific data */ +}; + }; struct _vshCmdGrp { -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 05/13] virsh: Rename client specific methods in virsh.h
--- tools/virsh.h | 19 +++ 1 file changed, 19 insertions(+) diff --git a/tools/virsh.h b/tools/virsh.h index 15a938e..d10ed66 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -36,6 +36,7 @@ # include internal.h # include virerror.h # include virthread.h +# include vsh.h # define VIRSH_MAX_XML_FILE (10*1024*1024) @@ -60,7 +61,10 @@ # define VIRSH_CMD_GRP_HOST_AND_HV Host and Hypervisor # define VIRSH_CMD_GRP_VIRSHVirsh itself +typedef struct _virshControl virshControl; +typedef virshControl *virshControlPtr; +typedef struct _virshCtrlData virshCtrlData; /* * vshControl @@ -91,9 +95,24 @@ struct _virshCtrlData { virConnectPtr dconn; }; +virConnectPtr virshConnect(vshControl *ctl, const char *uri, bool readonly); +int virshCommandOptTimeoutToMs(vshControl *ctl, const vshCmd *cmd, int *timeout); +/* Given an index, return either the name of that device (non-NULL) or + * of its parent (NULL if a root). */ +typedef const char * (*vshTreeLookup)(int devid, bool parent, void *opaque); +int virshTreePrint(vshControl *ctl, vshTreeLookup lookup, void *opaque, + int num_devices, int devid); +int virshDomainState(vshControl *ctl, virDomainPtr dom, int *reason); +char *virshEditWriteToTempFile(vshControl *ctl, const char *doc); +int virshEditFile(vshControl *ctl, const char *filename); +char *virshEditReadBackFile(vshControl *ctl, const char *filename); +int virshAskReedit(vshControl *ctl, const char *msg, bool relax_avail); +int virshStreamSink(virStreamPtr st, const char *bytes, size_t nbytes, + void *opaque); +double virshPrettyCapacity(unsigned long long val, const char **unit); #endif /* VIRSH_H */ -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-python][PATCH] examples: Introduce nodestats example
So, this is an exercise to show libvirt capabilities. Firstly, for each host NUMA nodes some statistics are printed out, i.e. total memory and free memory. Then, for each running domain, that has memory strictly bound to certain host nodes, a small statistics of how much memory it takes is printed out too. For instance: # ./nodestats.py NUMA stats NUMA nodes: 0 1 2 3 MemTotal: 3950396739373943 MemFree:434 674 149 216 Dom 'gentoo': 1048576 1048576 1048576 1048576 We can see 4 host NUMA nodes, all of them having roughly 4GB of RAM. Yeah, some of them has nearly all the memory consumed. Then, there's only one running domain, called 'gentoo', and it has 1GB per each NUMA node configured. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- examples/nodestats.py | 106 ++ 1 file changed, 106 insertions(+) create mode 100755 examples/nodestats.py diff --git a/examples/nodestats.py b/examples/nodestats.py new file mode 100755 index 000..dbf5593 --- /dev/null +++ b/examples/nodestats.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# Print some host NUMA node statistics +# +# Authors: +# Michal Privoznik mpriv...@redhat.com + +import libvirt +import sys +from xml.dom import minidom +import libxml2 + +class virBitmap: +def __init__(self): +self.bitmap = 0 + +def setBit(self, offset): +mask = 1 offset +self.bitmap = self.bitmap | mask + +def clearBit(self, offset): +mask = ~(1 offset) +self.bitmap = self.bitmap mask + +def isSet(self, offset): +mask = 1 offset +return(self.bitmap mask) + +def setRange(self, start, end): +while (start = end): +self.setBit(start) +start = start + 1 + +def parse(self, string): +for s in string.split(','): +list = s.split('-', 2) +start = int(list[0]) +if len(list) == 2: +end = int(list[1]) +else: +end = start +self.setRange(start, end) + +def xpath_eval(ctxt, path): +res = ctxt.xpathEval(path) +if res is None or len(res) == 0: +value = None +else: +value = res[0].content +return value + +try: +conn = libvirt.openReadOnly(None) +except libvirt.libvirtError: +print('Failed to connect to the hypervisor') +sys.exit(1) + +try: +capsXML = conn.getCapabilities() +except libvirt.libvirtError: +print('Failed to request capabilities') +sys.exit(1) + +caps = minidom.parseString(capsXML) +cells = caps.getElementsByTagName('cells')[0] + +nodesIDs = [ int(proc.getAttribute('id')) + for proc in cells.getElementsByTagName('cell') ] + +nodesMem = [ conn.getMemoryStats(int(proc)) + for proc in nodesIDs] + +doms = conn.listAllDomains(libvirt.VIR_CONNECT_LIST_DOMAINS_ACTIVE) +domsStrict = [ proc + for proc in doms + if proc.numaParameters()['numa_mode'] == libvirt.VIR_DOMAIN_NUMATUNE_MEM_STRICT ] + +domsStrictCfg = {} + +for dom in domsStrict: +xmlStr = dom.XMLDesc() +doc = libxml2.parseDoc(xmlStr) +ctxt = doc.xpathNewContext() + +domsStrictCfg[dom] = [ 0 for node in nodesIDs ] + +for memnode in ctxt.xpathEval(/domain/numatune/memnode): +ctxt.setContextNode(memnode) +cellid = xpath_eval(ctxt, @cellid) +mode = xpath_eval(ctxt, @mode) +nodeset = xpath_eval(ctxt, @nodeset) + +bitmap = virBitmap() +bitmap.parse(nodeset) +for node in nodesIDs: +if bitmap.isSet(int(node)): +mem = xpath_eval(ctxt, /domain/cpu/numa/cell[@id='%s']/@memory % cellid) +domsStrictCfg[dom][int(node)] += int(mem) + +print(NUMA stats) +print(NUMA nodes:\t\t + \t.join(str(node) for node in nodesIDs)) +print(MemTotal:\t\t + \t.join(str(i.get('total') / 1024) for i in nodesMem)) +print(MemFree:\t\t + \t.join(str(i.get('free') / 1024) for i in nodesMem)) + +for dom in domsStrictCfg: +sys.stdout.write(Dom '%s':\t\t % dom.name()) +print(\t.join(map(str, domsStrictCfg[dom][:]))) -- 2.3.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 3/4] monitor: detect that eject fails because the tray is locked
Modify the eject monitor functions to parse the return code and detect, whether the error contains is locked to report this type of failure to upper layers. Signed-off-by: Pavel Hrdina phrd...@redhat.com --- src/qemu/qemu_monitor_json.c | 14 ++ src/qemu/qemu_monitor_text.c | 10 ++ 2 files changed, 24 insertions(+) diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index d3e98d4..9aac342 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -44,6 +44,7 @@ #include virprobe.h #include virstring.h #include cpu/cpu_x86.h +#include c-strcasestr.h #ifdef WITH_DTRACE_PROBES # include libvirt_qemu_probes.h @@ -2116,6 +2117,14 @@ int qemuMonitorJSONSetCPU(qemuMonitorPtr mon, } +/** + * Run QMP command to eject a media from ejectable device. + * + * Returns: + * -2 on error, when the tray is locked + * -1 on all other errors + * 0 on success + */ int qemuMonitorJSONEjectMedia(qemuMonitorPtr mon, const char *dev_name, bool force) @@ -2134,6 +2143,11 @@ int qemuMonitorJSONEjectMedia(qemuMonitorPtr mon, if (ret == 0) ret = qemuMonitorJSONCheckError(cmd, reply); +VIR_DEBUG(%s, virJSONValueToString(reply, false)); + +if (ret 0 c_strcasestr(virJSONValueToString(reply, false), is locked)) +ret = -2; + virJSONValueFree(cmd); virJSONValueFree(reply); return ret; diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 2e77534..2aa0460 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1169,6 +1169,14 @@ int qemuMonitorTextSetCPU(qemuMonitorPtr mon, int cpu, bool online) } +/** + * Run HMP command to eject a media from ejectable device. + * + * Returns: + * -2 on error, when the tray is locked + * -1 on all other errors + * 0 on success + */ int qemuMonitorTextEjectMedia(qemuMonitorPtr mon, const char *dev_name, bool force) @@ -1187,6 +1195,8 @@ int qemuMonitorTextEjectMedia(qemuMonitorPtr mon, * device not found, device is locked ... * No message is printed on success it seems */ if (c_strcasestr(reply, device )) { +if (c_strcasestr(reply, is locked)) +ret = -2; virReportError(VIR_ERR_OPERATION_FAILED, _(could not eject media on %s: %s), dev_name, reply); goto cleanup; -- 2.4.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 0/4] fix ejecting removable media and some cleanup
Pavel Hrdina (4): virCondWaitUntil: add another return value virDomainObjSignal: drop this function monitor: detect that eject fails because the tray is locked qemu_hotplug: try harder to eject media src/conf/domain_conf.c | 27 src/conf/domain_conf.h | 1 - src/libvirt_private.syms | 1 - src/qemu/qemu_hotplug.c | 73 +--- src/qemu/qemu_monitor_json.c | 14 + src/qemu/qemu_monitor_text.c | 10 ++ src/qemu/qemu_process.c | 6 ++-- 7 files changed, 77 insertions(+), 55 deletions(-) -- 2.4.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 2/4] virDomainObjSignal: drop this function
There are multiple consumers for the domain condition and we should always wake them all. Signed-off-by: Pavel Hrdina phrd...@redhat.com --- src/conf/domain_conf.c | 7 --- src/conf/domain_conf.h | 1 - src/libvirt_private.syms | 1 - src/qemu/qemu_process.c | 4 ++-- 4 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 988818c..9efe175 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2661,13 +2661,6 @@ virDomainObjEndAPI(virDomainObjPtr *vm) void -virDomainObjSignal(virDomainObjPtr vm) -{ -virCondSignal(vm-cond); -} - - -void virDomainObjBroadcast(virDomainObjPtr vm) { virCondBroadcast(vm-cond); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index aeba5a5..59655c1 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2442,7 +2442,6 @@ void virDomainObjEndAPI(virDomainObjPtr *vm); bool virDomainObjTaint(virDomainObjPtr obj, virDomainTaintFlags taint); -void virDomainObjSignal(virDomainObjPtr vm); void virDomainObjBroadcast(virDomainObjPtr vm); int virDomainObjWait(virDomainObjPtr vm); int virDomainObjWaitUntil(virDomainObjPtr vm, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1566d11..720afdf 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -412,7 +412,6 @@ virDomainObjParseNode; virDomainObjSetDefTransient; virDomainObjSetMetadata; virDomainObjSetState; -virDomainObjSignal; virDomainObjTaint; virDomainObjUpdateModificationImpact; virDomainObjWait; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index ba84182..a688feb 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1004,7 +1004,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED, /* We have a SYNC API waiting for this event, dispatch it back */ diskPriv-blockJobType = type; diskPriv-blockJobStatus = status; -virDomainObjSignal(vm); +virDomainObjBroadcast(vm); } else { /* there is no waiting SYNC API, dispatch the update to a thread */ if (VIR_ALLOC(processEvent) 0) @@ -1500,7 +1500,7 @@ qemuProcessHandleSpiceMigrated(qemuMonitorPtr mon ATTRIBUTE_UNUSED, } priv-job.spiceMigrated = true; -virDomainObjSignal(vm); +virDomainObjBroadcast(vm); cleanup: virObjectUnlock(vm); -- 2.4.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 1/4] virCondWaitUntil: add another return value
We should distinguish between success and timeout, to let the user handle those two events differently. Signed-off-by: Pavel Hrdina phrd...@redhat.com --- src/conf/domain_conf.c | 20 +++- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2c3b96b..988818c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2686,15 +2686,25 @@ virDomainObjWait(virDomainObjPtr vm) } +/** + * Waits for domain condition to be triggered for a specific period of time. + * + * Returns: + * -1 in case of error + * 0 on success + * 1 on timeout + */ int virDomainObjWaitUntil(virDomainObjPtr vm, unsigned long long whenms) { -if (virCondWaitUntil(vm-cond, vm-parent.lock, whenms) 0 -errno != ETIMEDOUT) { -virReportSystemError(errno, %s, - _(failed to wait for domain condition)); -return -1; +if (virCondWaitUntil(vm-cond, vm-parent.lock, whenms) 0) { +if (errno != ETIMEDOUT) { +virReportSystemError(errno, %s, + _(failed to wait for domain condition)); +return -1; +} +return 1; } return 0; } -- 2.4.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 04/13] virsh: remove generic data, only client specific are kept
The very opposite action to removing client specific data from vsh. As all the generic methods/structures/variables have been moved to vsh, there's no need for them in virsh. --- tools/virsh.c | 2393 - tools/virsh.h | 428 --- tools/vsh.c |2 +- 3 files changed, 140 insertions(+), 2683 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index f293d0f..9280b40 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -25,7 +25,6 @@ #include config.h #include virsh.h -#include assert.h #include stdio.h #include stdlib.h #include string.h @@ -41,7 +40,6 @@ #include limits.h #include sys/stat.h #include inttypes.h -#include strings.h #include signal.h #if WITH_READLINE @@ -85,59 +83,6 @@ static char *progname; static const vshCmdGrp cmdGroups[]; -/* Bypass header poison */ -#undef strdup - -void * -_vshMalloc(vshControl *ctl, size_t size, const char *filename, int line) -{ -char *x; - -if (VIR_ALLOC_N(x, size) == 0) -return x; -vshError(ctl, _(%s: %d: failed to allocate %d bytes), - filename, line, (int) size); -exit(EXIT_FAILURE); -} - -void * -_vshCalloc(vshControl *ctl, size_t nmemb, size_t size, const char *filename, - int line) -{ -char *x; - -if (!xalloc_oversized(nmemb, size) -VIR_ALLOC_N(x, nmemb * size) == 0) -return x; -vshError(ctl, _(%s: %d: failed to allocate %d bytes), - filename, line, (int) (size*nmemb)); -exit(EXIT_FAILURE); -} - -char * -_vshStrdup(vshControl *ctl, const char *s, const char *filename, int line) -{ -char *x; - -if (VIR_STRDUP(x, s) = 0) -return x; -vshError(ctl, _(%s: %d: failed to allocate %lu bytes), - filename, line, (unsigned long)strlen(s)); -exit(EXIT_FAILURE); -} - -/* Poison the raw allocating identifiers in favor of our vsh variants. */ -#define strdup use_vshStrdup_instead_of_strdup - -int -vshNameSorter(const void *a, const void *b) -{ -const char **sa = (const char**)a; -const char **sb = (const char**)b; - -return vshStrcasecmp(*sa, *sb); -} - double virshPrettyCapacity(unsigned long long val, const char **unit) { @@ -913,25 +858,10 @@ cmdQuit(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) } /* --- - * Utils for work with command definition + * Utils for work with runtime commands data * --- */ -const char * -vshCmddefGetInfo(const vshCmdDef * cmd, const char *name) -{ -const vshCmdInfo *info; - -for (info = cmd-info; info info-name; info++) { -if (STREQ(info-name, name)) -return info-data; -} -return NULL; -} -/* Validate that the options associated with cmd can be parsed. */ -static int -vshCmddefOptParse(const vshCmdDef *cmd, uint32_t *opts_need_arg, - uint32_t *opts_required) /* * virshCommandOptTimeoutToMs: * @ctl virsh control structure @@ -945,2253 +875,211 @@ vshCmddefOptParse(const vshCmdDef *cmd, uint32_t *opts_need_arg, int virshCommandOptTimeoutToMs(vshControl *ctl, const vshCmd *cmd, int *timeout) { -size_t i; -bool optional = false; - -*opts_need_arg = 0; -*opts_required = 0; - -if (!cmd-opts) -return 0; - -for (i = 0; cmd-opts[i].name; i++) { -const vshCmdOptDef *opt = cmd-opts[i]; - -if (i 31) -return -1; /* too many options */ -if (opt-type == VSH_OT_BOOL) { -optional = true; -if (opt-flags VSH_OFLAG_REQ) -return -1; /* bool options can't be mandatory */ -continue; -} -if (opt-type == VSH_OT_ALIAS) { -size_t j; -char *name = (char *)opt-help; /* cast away const */ -char *p; - -if (opt-flags || !opt-help) -return -1; /* alias options are tracked by the original name */ -if ((p = strchr(name, '=')) -VIR_STRNDUP(name, name, p - name) 0) -return -1; -for (j = i + 1; cmd-opts[j].name; j++) { -if (STREQ(name, cmd-opts[j].name) -cmd-opts[j].type != VSH_OT_ALIAS) -break; -} -if (name != opt-help) { -VIR_FREE(name); -/* If alias comes with value, replacement must not be bool */ -if (cmd-opts[j].type == VSH_OT_BOOL) -return -1; -} -if (!cmd-opts[j].name) -return -1; /* alias option must map to a later option name */ -continue; -} -if (opt-flags VSH_OFLAG_REQ_OPT) { -if (opt-flags VSH_OFLAG_REQ) -*opts_required |= 1 i; -else -optional = true; -continue; -} +int ret; +unsigned int utimeout; -*opts_need_arg |= 1 i; -if (opt-flags VSH_OFLAG_REQ) { -
[libvirt] [PATCH 00/13] Move generic virsh data to a separate module vsh
The idea behind this is that in order to introduce virt-admin client (and later some commands/APIs), there are lots of methods in virsh that can be easily reused by other potential clients like command and command argument passing or error reporting. !!! IMPORTANT !!! These patches cannot be compiled separately, the series is split more or less logically into chunks only to be more readable by the reviewer. I started this at least 4 times from scratch and still haven't found a way that splitting virsh could be done with several independent applicable commits, rather than having one massive commit in the end. Erik Skultety (13): tools: Introduce new client generic module vsh vsh: Remove client specific data, only generic data are kept tools: apply s/vshX/virshX to all virsh specific data virsh: remove generic data, only client specific are kept virsh: Rename client specific methods in virsh.h vsh: vshControl now includes client private data and client specific progname vsh: Make use of introduced private data vsh: Introduce client hooks vsh: Make use of newly introduced client side hooks vsh: Introduce new global initializer vsh: Make separated generic methods public virsh: Introduce connection handler tools: Update makefile to include 'vsh' sources as well cfg.mk |2 +- po/POTFILES.in |3 +- tools/Makefile.am|4 + tools/virsh-console.c| 13 +- tools/virsh-console.h|8 +- tools/virsh-domain-monitor.c | 201 ++-- tools/virsh-domain-monitor.h |4 +- tools/virsh-domain.c | 532 + tools/virsh-domain.h | 14 +- tools/virsh-edit.c |8 +- tools/virsh-host.c | 131 ++- tools/virsh-interface.c | 80 +- tools/virsh-interface.h | 12 +- tools/virsh-network.c| 72 +- tools/virsh-network.h| 10 +- tools/virsh-nodedev.c| 37 +- tools/virsh-nwfilter.c | 33 +- tools/virsh-nwfilter.h | 10 +- tools/virsh-pool.c | 104 +- tools/virsh-pool.h | 10 +- tools/virsh-secret.c | 27 +- tools/virsh-snapshot.c | 75 +- tools/virsh-volume.c | 103 +- tools/virsh-volume.h | 14 +- tools/virsh.c| 2673 -- tools/virsh.h| 481 +--- tools/vsh.c | 2332 tools/vsh.h | 489 28 files changed, 3906 insertions(+), 3576 deletions(-) create mode 100644 tools/vsh.c create mode 100644 tools/vsh.h -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 01/13] tools: Introduce new client generic module vsh
In order to share as much virsh' logic as possible with upcomming virt-admin client we need to split virsh logic into virsh specific and client generic features. This patch only introduces these file that are identical to the virsh.{c,h} --- cfg.mk |2 +- po/POTFILES.in |3 +- tools/vsh.c| 3800 tools/vsh.h| 527 4 files changed, 4330 insertions(+), 2 deletions(-) create mode 100644 tools/vsh.c create mode 100644 tools/vsh.h diff --git a/cfg.mk b/cfg.mk index 0d1a03c..f26191f 100644 --- a/cfg.mk +++ b/cfg.mk @@ -1086,7 +1086,7 @@ $(srcdir)/src/admin/admin_client.h: $(srcdir)/src/admin/admin_protocol.x $(MAKE) -C src admin/admin_client.h # List all syntax-check exemptions: -exclude_file_name_regexp--sc_avoid_strcase = ^tools/virsh\.h$$ +exclude_file_name_regexp--sc_avoid_strcase = ^tools/(virsh|vsh)\.h$$ _src1=libvirt-stream|fdstream|qemu/qemu_monitor|util/(vircommand|virfile)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller|locking/lock_daemon _test1=shunloadtest|virnettlscontexttest|virnettlssessiontest|vircgroupmock diff --git a/po/POTFILES.in b/po/POTFILES.in index a75f5ae..e0d1014 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -258,7 +258,6 @@ src/xenconfig/xen_xm.c tests/virpolkittest.c tools/libvirt-guests.sh.in tools/virsh.c -tools/virsh.h tools/virsh-console.c tools/virsh-domain-monitor.c tools/virsh-domain.c @@ -277,3 +276,5 @@ tools/virt-host-validate-lxc.c tools/virt-host-validate-qemu.c tools/virt-host-validate.c tools/virt-login-shell.c +tools/vsh.c +tools/vsh.h diff --git a/tools/vsh.c b/tools/vsh.c new file mode 100644 index 000..609c8f3 --- /dev/null +++ b/tools/vsh.c @@ -0,0 +1,3800 @@ +/* + * vsh.c: common data to be used by clients to exercise the libvirt API + * + * Copyright (C) 2005, 2007-2015 Red Hat, Inc. + * + * 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 should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * http://www.gnu.org/licenses/. + * + * Daniel Veillard veill...@redhat.com + * Karel Zak k...@redhat.com + * Daniel P. Berrange berra...@redhat.com + */ + +#include config.h +#include vsh.h + +#include assert.h +#include stdio.h +#include stdlib.h +#include string.h +#include stdarg.h +#include unistd.h +#include errno.h +#include getopt.h +#include sys/time.h +#include c-ctype.h +#include fcntl.h +#include locale.h +#include time.h +#include limits.h +#include sys/stat.h +#include inttypes.h +#include strings.h +#include signal.h + +#if WITH_READLINE +# include readline/readline.h +# include readline/history.h +#endif + +#include internal.h +#include virerror.h +#include virbuffer.h +#include viralloc.h +#include libvirt/libvirt-qemu.h +#include libvirt/libvirt-lxc.h +#include virfile.h +#include configmake.h +#include virthread.h +#include vircommand.h +#include conf/domain_conf.h +#include virtypedparam.h +#include virstring.h + +#include virsh-console.h +#include virsh-domain.h +#include virsh-domain-monitor.h +#include virsh-host.h +#include virsh-interface.h +#include virsh-network.h +#include virsh-nodedev.h +#include virsh-nwfilter.h +#include virsh-pool.h +#include virsh-secret.h +#include virsh-snapshot.h +#include virsh-volume.h + +/* Gnulib doesn't guarantee SA_SIGINFO support. */ +#ifndef SA_SIGINFO +# define SA_SIGINFO 0 +#endif + +static char *progname; + +static const vshCmdGrp cmdGroups[]; + +/* Bypass header poison */ +#undef strdup + +void * +_vshMalloc(vshControl *ctl, size_t size, const char *filename, int line) +{ +char *x; + +if (VIR_ALLOC_N(x, size) == 0) +return x; +vshError(ctl, _(%s: %d: failed to allocate %d bytes), + filename, line, (int) size); +exit(EXIT_FAILURE); +} + +void * +_vshCalloc(vshControl *ctl, size_t nmemb, size_t size, const char *filename, + int line) +{ +char *x; + +if (!xalloc_oversized(nmemb, size) +VIR_ALLOC_N(x, nmemb * size) == 0) +return x; +vshError(ctl, _(%s: %d: failed to allocate %d bytes), + filename, line, (int) (size*nmemb)); +exit(EXIT_FAILURE); +} + +char * +_vshStrdup(vshControl *ctl, const char *s, const char *filename, int line) +{ +char *x; + +if (VIR_STRDUP(x, s) = 0) +return x; +vshError(ctl, _(%s: %d: failed to allocate %lu bytes), + filename, line, (unsigned long)strlen(s)); +exit(EXIT_FAILURE); +} + +/* Poison
[libvirt] [sandbox v2 09/11] Add function to check if there is a mount with / target
gvir_sandbox_config_has_root_mount is a convenience function to check if there is a mount with target '/' --- libvirt-sandbox/libvirt-sandbox-config.c | 21 + libvirt-sandbox/libvirt-sandbox-config.h | 1 + libvirt-sandbox/libvirt-sandbox.sym | 1 + 3 files changed, 23 insertions(+) diff --git a/libvirt-sandbox/libvirt-sandbox-config.c b/libvirt-sandbox/libvirt-sandbox-config.c index b9c13a7..2506072 100644 --- a/libvirt-sandbox/libvirt-sandbox-config.c +++ b/libvirt-sandbox/libvirt-sandbox-config.c @@ -1561,6 +1561,27 @@ gboolean gvir_sandbox_config_has_mounts_with_type(GVirSandboxConfig *config, } +gboolean gvir_sandbox_config_has_root_mount(GVirSandboxConfig *config) +{ +GList *tmp = NULL, *mounts = NULL; +gboolean hasRoot = FALSE; + +tmp = mounts = gvir_sandbox_config_get_mounts(config); +while (tmp !hasRoot) { +const gchar *target; +GVirSandboxConfigMount *mount = GVIR_SANDBOX_CONFIG_MOUNT(tmp-data); +target = gvir_sandbox_config_mount_get_target(mount); +if (g_str_equal(target, /)) +hasRoot = TRUE; +tmp = tmp-next; +} +g_list_foreach(mounts, (GFunc)g_object_unref, NULL); +g_list_free(mounts); + +return hasRoot; +} + + /** diff --git a/libvirt-sandbox/libvirt-sandbox-config.h b/libvirt-sandbox/libvirt-sandbox-config.h index ebbebf2..2c5f0a6 100644 --- a/libvirt-sandbox/libvirt-sandbox-config.h +++ b/libvirt-sandbox/libvirt-sandbox-config.h @@ -150,6 +150,7 @@ gboolean gvir_sandbox_config_add_mount_strv(GVirSandboxConfig *config, gboolean gvir_sandbox_config_has_mounts(GVirSandboxConfig *config); gboolean gvir_sandbox_config_has_mounts_with_type(GVirSandboxConfig *config, GType type); +gboolean gvir_sandbox_config_has_root_mount(GVirSandboxConfig *config); gboolean gvir_sandbox_config_add_host_include_strv(GVirSandboxConfig *config, gchar **includes, diff --git a/libvirt-sandbox/libvirt-sandbox.sym b/libvirt-sandbox/libvirt-sandbox.sym index e5f8660..65b0db5 100644 --- a/libvirt-sandbox/libvirt-sandbox.sym +++ b/libvirt-sandbox/libvirt-sandbox.sym @@ -212,6 +212,7 @@ LIBVIRT_SANDBOX_0.2.1 { LIBVIRT_SANDBOX_0.5.2 { global: +gvir_sandbox_config_has_root_mount; gvir_sandbox_config_mount_guest_bind_get_format; gvir_sandbox_config_add_disk; gvir_sandbox_config_add_disk_strv; -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox v2 08/11] qemu: use mounts targeting / as root
So far a mount with / as target doesn't change anything: the host / is still the one mounted as /. libvirt-sandbox-init-qemu now detects the presence of a / target in mounts.cfg and mounts it instead of sandbox:root. --- libvirt-sandbox/libvirt-sandbox-init-qemu.c | 79 - 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/libvirt-sandbox/libvirt-sandbox-init-qemu.c b/libvirt-sandbox/libvirt-sandbox-init-qemu.c index 4a3883d..09580da 100644 --- a/libvirt-sandbox/libvirt-sandbox-init-qemu.c +++ b/libvirt-sandbox/libvirt-sandbox-init-qemu.c @@ -52,6 +52,7 @@ #define ATTR_UNUSED __attribute__((__unused__)) #define STREQ(x,y) (strcmp(x,y) == 0) +#define STRNEQ(x,y) (strcmp(x,y) != 0) static void print_uptime (void); static void insmod (const char *filename); @@ -216,6 +217,79 @@ mount_entry(const char *source, } } +static void +mount_root(const char *path) +{ +int foundRoot = 0; + +/* Loop over mounts.cfg to see if we have a candidate for / */ +mount_mkdir(SANDBOXCONFIGDIR, 0755); +mount_9pfs(sandbox:config, SANDBOXCONFIGDIR, 0755, 1); + +FILE *fp = fopen(SANDBOXCONFIGDIR /mounts.cfg, r); +while (fgets(line, sizeof line, fp) !foundRoot) { +char *source = line; +char *target = strchr(source, '\t'); +*target = '\0'; +target++; +char *type = strchr(target, '\t'); +*type = '\0'; +type++; +char *opts = strchr(type, '\t'); +*opts = '\0'; +opts++; +char *tmp = strchr(opts, '\n'); +*tmp = '\0'; + +if (STREQ(target, /)) { +int needsDev = strncmp(source, /dev/, 5) == 0; + +if (debug) +fprintf(stderr, libvirt-sandbox-init-qemu: found root from %s\n, +source); + +/* In this case, we need to have a /dev before the chroot */ +if (needsDev) { +mount_other(/proc, proc, 0755); +mount_other(/dev, devtmpfs, 0755); +} + +mount_entry(source, path, type, opts); + +if (needsDev) { +if (umount(/dev) 0) { +fprintf(stderr, +libvirt-sandbox-init-qemu: %s: +cannot unmount temporary /dev: %s\n, +__func__, strerror(errno)); +exit_poweroff(); +} +if (umount(/proc) 0) { +fprintf(stderr, +libvirt-sandbox-init-qemu: %s: +cannot unmount temporary /proc: %s\n, +__func__, strerror(errno)); +exit_poweroff(); +} +} +foundRoot = 1; +} +} +fclose(fp); + +if (umount(SANDBOXCONFIGDIR) 0) { +fprintf(stderr, +libvirt-sandbox-init-qemu: %s: +cannot unmount temporary %s: %s\n, +__func__, SANDBOXCONFIGDIR, strerror(errno)); +exit_poweroff(); +} + +/* If we couldn't get a / in the mounts, then use the host one */ +if (!foundRoot) +mount_9pfs(sandbox:root, path, 0755, 1); +} + int main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED) { @@ -259,7 +333,7 @@ main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED) if (debug) fprintf(stderr, libvirt-sandbox-init-qemu: mounting new root on /tmproot\n); -mount_9pfs(sandbox:root, /tmproot, 0755, 1); +mount_root(/tmproot); /* Note that pivot_root won't work. See the note in * Documentation/filesystems/ramfs-rootfs-initramfs.txt @@ -318,7 +392,8 @@ main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED) fprintf(stderr, libvirt-sandbox-init-qemu: %s: %s - %s (%s, %s)\n, __func__, source, target, type, opts); -mount_entry(source, target, type, opts); +if (STRNEQ(target, /)) +mount_entry(source, target, type, opts); } fclose(fp); -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox v2 10/11] Don't add sandbox:root device if we have a mount targetting /
There is no need to expose the host file system if the user defined a mount targetting / --- libvirt-sandbox/libvirt-sandbox-builder-machine.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libvirt-sandbox/libvirt-sandbox-builder-machine.c b/libvirt-sandbox/libvirt-sandbox-builder-machine.c index 74ef852..4cbd566 100644 --- a/libvirt-sandbox/libvirt-sandbox-builder-machine.c +++ b/libvirt-sandbox/libvirt-sandbox-builder-machine.c @@ -515,17 +515,19 @@ static gboolean gvir_sandbox_builder_machine_construct_devices(GVirSandboxBuilde construct_devices(builder, config, statedir, domain, error)) goto cleanup; -fs = gvir_config_domain_filesys_new(); -gvir_config_domain_filesys_set_type(fs, GVIR_CONFIG_DOMAIN_FILESYS_MOUNT); -gvir_config_domain_filesys_set_access_type(fs, GVIR_CONFIG_DOMAIN_FILESYS_ACCESS_SQUASH); -gvir_config_domain_filesys_set_source(fs, - gvir_sandbox_config_get_root(config)); -gvir_config_domain_filesys_set_target(fs, sandbox:root); -gvir_config_domain_filesys_set_readonly(fs, TRUE); +if (!gvir_sandbox_config_has_root_mount(config)) { +fs = gvir_config_domain_filesys_new(); +gvir_config_domain_filesys_set_type(fs, GVIR_CONFIG_DOMAIN_FILESYS_MOUNT); +gvir_config_domain_filesys_set_access_type(fs, GVIR_CONFIG_DOMAIN_FILESYS_ACCESS_SQUASH); +gvir_config_domain_filesys_set_source(fs, + gvir_sandbox_config_get_root(config)); +gvir_config_domain_filesys_set_target(fs, sandbox:root); +gvir_config_domain_filesys_set_readonly(fs, TRUE); -gvir_config_domain_add_device(domain, - GVIR_CONFIG_DOMAIN_DEVICE(fs)); -g_object_unref(fs); +gvir_config_domain_add_device(domain, + GVIR_CONFIG_DOMAIN_DEVICE(fs)); +g_object_unref(fs); +} fs = gvir_config_domain_filesys_new(); -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox v2 07/11] init-qemu: extract the mounts.cfg ntry mounting code
Create a mount_entry function from the code mounting the entries defined in mounts.cfg in order to be able to reuse that code. This will later be useful to mount a / from mounts.cfg. --- libvirt-sandbox/libvirt-sandbox-init-qemu.c | 63 - 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/libvirt-sandbox/libvirt-sandbox-init-qemu.c b/libvirt-sandbox/libvirt-sandbox-init-qemu.c index 62e8e40..4a3883d 100644 --- a/libvirt-sandbox/libvirt-sandbox-init-qemu.c +++ b/libvirt-sandbox/libvirt-sandbox-init-qemu.c @@ -181,6 +181,41 @@ mount_9pfs(const char *src, const char *dst, int mode, int readonly) } +static void +mount_entry(const char *source, +const char *target, +const char *type, +const char * opts) +{ +int flags = 0; + +if (STREQ(type, )) { +struct stat st; +type = NULL; +flags |= MS_BIND; +if (stat(source, st) 0) { +fprintf(stderr, libvirt-sandbox-init-qemu: %s: cannot read mount source %s: %s\n, +__func__, source, strerror(errno)); +exit_poweroff(); +} +if (S_ISDIR(st.st_mode)) +mount_mkdir(target, 755); +else +mount_mkfile(target, 644); +} else { +if (STREQ(type, tmpfs)) +flags |= MS_NOSUID | MS_NODEV; + +mount_mkdir(target, 0755); +} + +if (mount(source, target, type, flags, opts) 0) { +fprintf(stderr, libvirt-sandbox-init-qemu: %s: cannot mount %s on %s (%s, %s): %s\n, +__func__, source, target, type, opts, strerror(errno)); +exit_poweroff(); +} +} + int main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED) { @@ -278,38 +313,12 @@ main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED) opts++; char *tmp = strchr(opts, '\n'); *tmp = '\0'; -int flags = 0; if (debug) fprintf(stderr, libvirt-sandbox-init-qemu: %s: %s - %s (%s, %s)\n, __func__, source, target, type, opts); - -if (STREQ(type, )) { -struct stat st; -type = NULL; -flags |= MS_BIND; -if (stat(source, st) 0) { -fprintf(stderr, libvirt-sandbox-init-qemu: %s: cannot read mount source %s: %s\n, -__func__, source, strerror(errno)); -exit_poweroff(); -} -if (S_ISDIR(st.st_mode)) -mount_mkdir(target, 755); -else -mount_mkfile(target, 644); -} else { -if (STREQ(type, tmpfs)) -flags |= MS_NOSUID | MS_NODEV; - -mount_mkdir(target, 0755); -} - -if (mount(source, target, type, flags, opts) 0) { -fprintf(stderr, libvirt-sandbox-init-qemu: %s: cannot mount %s on %s (%s, %s): %s\n, -__func__, source, target, type, opts, strerror(errno)); -exit_poweroff(); -} +mount_entry(source, target, type, opts); } fclose(fp); -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox v2 04/11] Make init-lxc all static
When running a sandbox with a / different from the host one, we will need to copy all init-lxc dependencies into a mounted folder... but we have no way to tell libvirt to set the LD_LIBRARY_PATH for the init command. Turning init-lxc all-static help us work around that problem, and drops the useless dependencies on glib and libvirt-sandbox. --- libvirt-sandbox/Makefile.am| 11 +-- libvirt-sandbox/libvirt-sandbox-init-lxc.c | 8 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/libvirt-sandbox/Makefile.am b/libvirt-sandbox/Makefile.am index b6fcdf7..1cd6ea3 100644 --- a/libvirt-sandbox/Makefile.am +++ b/libvirt-sandbox/Makefile.am @@ -202,22 +202,13 @@ libvirt_sandbox_init_lxc_CFLAGS = \ -DSANDBOXCONFIGDIR=\$(sandboxconfigdir)\ \ -I$(top_srcdir) \ -I$(top_builddir) \ - $(GIO_UNIX_CFLAGS) \ - $(LIBVIRT_GLIB_CFLAGS) \ - $(LIBVIRT_GOBJECT_CFLAGS) \ $(WARN_CFLAGS) \ $(NULL) libvirt_sandbox_init_lxc_LDFLAGS = \ - libvirt-sandbox-1.0.la \ + -all-static \ $(COVERAGE_CFLAGS:-f%=-Wc,f%) \ - $(GIO_UNIX_LIBS) \ - $(LIBVIRT_GLIB_LIBS) \ - $(LIBVIRT_GOBJECT_LIBS) \ $(WARN_CFLAGS) \ $(NULL) -libvirt_sandbox_init_lxc_LDADD = \ - libvirt-sandbox-1.0.la \ - $(NULL) libvirt_sandbox_init_qemu_SOURCES = libvirt-sandbox-init-qemu.c libvirt_sandbox_init_qemu_CFLAGS = \ diff --git a/libvirt-sandbox/libvirt-sandbox-init-lxc.c b/libvirt-sandbox/libvirt-sandbox-init-lxc.c index 61f46a1..798af37 100644 --- a/libvirt-sandbox/libvirt-sandbox-init-lxc.c +++ b/libvirt-sandbox/libvirt-sandbox-init-lxc.c @@ -28,8 +28,6 @@ #include config.h -#include glib.h - #include stdio.h #include sys/wait.h #include termios.h @@ -38,6 +36,8 @@ #include string.h #include errno.h +#define STRNEQ(x,y) (strcmp(x,y) != 0) + static void set_debug(void); static int has_command_arg(const char *name, char **val); @@ -45,7 +45,7 @@ static int has_command_arg(const char *name, static int debug = 0; int -main(int argc G_GNUC_UNUSED, char **argv G_GNUC_UNUSED) +main(int argc, char **argv) { const char *args[50]; int narg = 0; @@ -69,7 +69,7 @@ main(int argc G_GNUC_UNUSED, char **argv G_GNUC_UNUSED) args[narg++] = /tmp/sandbox.log; args[narg++] = -f; args[narg++] = -ff; -if (strace !g_str_equal(strace, 1)) { +if (strace STRNEQ(strace, 1)) { args[narg++] = -e; args[narg++] = strace; } -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox v2 06/11] Remove init-common dependency on libvirt-sandbox.so
Removing this dependency avoids getting all libvirt.so dependencies loaded in our container. --- libvirt-sandbox/Makefile.am| 34 libvirt-sandbox/libvirt-sandbox-config-all.h | 62 ++ libvirt-sandbox/libvirt-sandbox-config-disk.c | 2 +- libvirt-sandbox/libvirt-sandbox-config-initrd.c| 2 +- .../libvirt-sandbox-config-interactive.c | 2 +- .../libvirt-sandbox-config-mount-file.c| 2 +- .../libvirt-sandbox-config-mount-guest-bind.c | 2 +- .../libvirt-sandbox-config-mount-host-bind.c | 2 +- .../libvirt-sandbox-config-mount-host-image.c | 2 +- libvirt-sandbox/libvirt-sandbox-config-mount-ram.c | 2 +- libvirt-sandbox/libvirt-sandbox-config-mount.c | 2 +- .../libvirt-sandbox-config-network-address.c | 2 +- ...rt-sandbox-config-network-filterref-parameter.c | 2 +- .../libvirt-sandbox-config-network-filterref.c | 2 +- .../libvirt-sandbox-config-network-route.c | 2 +- libvirt-sandbox/libvirt-sandbox-config-network.c | 2 +- .../libvirt-sandbox-config-service-generic.c | 2 +- .../libvirt-sandbox-config-service-systemd.c | 2 +- libvirt-sandbox/libvirt-sandbox-config-service.c | 2 +- libvirt-sandbox/libvirt-sandbox-config.c | 2 +- libvirt-sandbox/libvirt-sandbox-init-common.c | 5 +- libvirt-sandbox/libvirt-sandbox-util.c | 2 +- 22 files changed, 105 insertions(+), 34 deletions(-) create mode 100644 libvirt-sandbox/libvirt-sandbox-config-all.h diff --git a/libvirt-sandbox/Makefile.am b/libvirt-sandbox/Makefile.am index 1cd6ea3..7b3ea27 100644 --- a/libvirt-sandbox/Makefile.am +++ b/libvirt-sandbox/Makefile.am @@ -50,10 +50,7 @@ SANDBOX_RPC_FILES = \ libvirt-sandbox-rpcpacket.h \ $(NULL) -SANDBOX_HEADER_FILES = \ - libvirt-sandbox.h \ - libvirt-sandbox-main.h \ - libvirt-sandbox-util.h \ +SANDBOX_CONFIG_HEADER_FILES = \ libvirt-sandbox-config.h \ libvirt-sandbox-config-disk.h \ libvirt-sandbox-config-network.h \ @@ -72,6 +69,12 @@ SANDBOX_HEADER_FILES = \ libvirt-sandbox-config-service.h \ libvirt-sandbox-config-service-systemd.h \ libvirt-sandbox-config-service-generic.h \ + $(NULL) + +SANDBOX_HEADER_FILES = \ + libvirt-sandbox.h \ + libvirt-sandbox-main.h \ + libvirt-sandbox-util.h \ libvirt-sandbox-builder.h \ libvirt-sandbox-builder-initrd.h \ libvirt-sandbox-builder-machine.h \ @@ -82,9 +85,10 @@ SANDBOX_HEADER_FILES = \ libvirt-sandbox-context.h \ libvirt-sandbox-context-interactive.h \ libvirt-sandbox-context-service.h \ + $(SANDBOX_CONFIG_HEADER_FILES) \ $(NULL) -SANDBOX_SOURCE_FILES = \ - libvirt-sandbox-main.c \ + +SANDBOX_CONFIG_SOURCE_FILES = \ libvirt-sandbox-util.c \ libvirt-sandbox-config.c \ libvirt-sandbox-config-disk.c \ @@ -104,6 +108,10 @@ SANDBOX_SOURCE_FILES = \ libvirt-sandbox-config-service.c \ libvirt-sandbox-config-service-systemd.c \ libvirt-sandbox-config-service-generic.c \ + $(NULL) + +SANDBOX_SOURCE_FILES = \ + libvirt-sandbox-main.c \ libvirt-sandbox-builder.c \ libvirt-sandbox-builder-initrd.c \ libvirt-sandbox-builder-machine.c \ @@ -115,6 +123,8 @@ SANDBOX_SOURCE_FILES = \ libvirt-sandbox-context.c \ libvirt-sandbox-context-interactive.c \ libvirt-sandbox-context-service.c \ + libvirt-sandbox-config-all.h \ + $(SANDBOX_CONFIG_SOURCE_FILES) \ $(NULL) libvirt_sandbox_1_0_ladir = $(includedir)/libvirt-sandbox-1.0/libvirt-sandbox @@ -169,31 +179,33 @@ libvirt_sandbox_1_0_la_LDFLAGS = \ libvirt_sandbox_init_common_SOURCES = libvirt-sandbox-init-common.c \ $(SANDBOX_GENERATED_RPC_FILES) \ $(SANDBOX_RPC_FILES) \ + $(SANDBOX_CONFIG_HEADER_FILES) \ + $(SANDBOX_CONFIG_SOURCE_FILES) \ $(NULL) libvirt_sandbox_init_common_CFLAGS = \ -DLIBEXECDIR=\$(libexecdir)\ \ -DSANDBOXCONFIGDIR=\$(sandboxconfigdir)\ \ -DLOCALEDIR=\$(datadir)/locale\ \ +
[libvirt] [sandbox v2 02/11] Allow disabling zlib support.
Some distributions may not have static zlib package. Allow disabling it at build time. --- configure.ac| 16 +++- libvirt-sandbox/libvirt-sandbox-init-qemu.c | 12 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 834a444..99d22d7 100644 --- a/configure.ac +++ b/configure.ac @@ -80,7 +80,16 @@ PKG_CHECK_MODULES(LIBVIRT, libvirt = $LIBVIRT_REQUIRED) PKG_CHECK_MODULES(LIBVIRT_GLIB, libvirt-glib-1.0 = $LIBVIRT_GOBJECT_REQUIRED) PKG_CHECK_MODULES(LIBVIRT_GOBJECT, libvirt-gobject-1.0 = $LIBVIRT_GOBJECT_REQUIRED) PKG_CHECK_MODULES(LIBVIRT_GCONFIG, libvirt-gconfig-1.0 = $LIBVIRT_GCONFIG_REQUIRED) -PKG_CHECK_MODULES(ZLIB, zlib = $ZLIB_REQUIRED) + +AC_ARG_WITH([zlib], + [AS_HELP_STRING([--with-zlib], +[add ZLIB support @:@default=yes@:@])]) +m4_divert_text([DEFAULTS], [with_zlib=yes]) + +if test $with_zlib = yes ; then +PKG_CHECK_MODULES(ZLIB, zlib = $ZLIB_REQUIRED) +fi + AC_ARG_WITH([lzma], [AS_HELP_STRING([--with-lzma], [add LZMA support @:@default=yes@:@])]) @@ -130,6 +139,11 @@ AC_MSG_NOTICE([LZMA: $LZMA_CFLAGS $LZMA_LIBS]) else AC_MSG_NOTICE([LZMA: no]) fi +if test $with_zlib != no ; then +AC_MSG_NOTICE([ZLIB: $ZLIB_CFLAGS $ZLIB_LIBS]) +else +AC_MSG_NOTICE([ZLIB: no]) +fi AC_MSG_NOTICE([ GOBJECT: $GOBJECT_CFLAGS $GOBJECT_LIBS]) AC_MSG_NOTICE([ LIBVIRT_GOBJECT: $LIBVIRT_GOBJECT_CFLAGS $LIBVIRT_GOBJECT_LIBS]) AC_MSG_NOTICE([]) diff --git a/libvirt-sandbox/libvirt-sandbox-init-qemu.c b/libvirt-sandbox/libvirt-sandbox-init-qemu.c index a9e6263..d5a0b7a 100644 --- a/libvirt-sandbox/libvirt-sandbox-init-qemu.c +++ b/libvirt-sandbox/libvirt-sandbox-init-qemu.c @@ -45,7 +45,9 @@ #if WITH_LZMA #include lzma.h #endif /* WITH_LZMA */ +#if WITH_ZLIB #include zlib.h +#endif /* WITH_ZLIB */ #define ATTR_UNUSED __attribute__((__unused__)) @@ -469,6 +471,7 @@ load_module_file_lzma(const char *filename, size_t *len) } #endif /* WITH_LZMA */ +#if WITH_ZLIB static char * load_module_file_zlib(const char *filename, size_t *len) { @@ -519,6 +522,15 @@ load_module_file_zlib(const char *filename, size_t *len) gzclose(fp); return data; } +#else +static char * +load_module_file_zlib(const char *filename, size_t *len) +{ +fprintf(stderr, libvirt-sandbox-init-qemu: %s: +zlib support disabled, can't read module %s\n, __func__, filename); +exit_poweroff(); +} +#endif /* WITH_ZLIB */ static char * load_module_file_raw(const char *filename, size_t *len) -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox v2 00/11] Actually use host-image mounts on /
Hi all, In the virt-sandbox documentation we had examples with host-image mounts targetting /. However the / in the sandbox was still the host one. The main goal of this patch series is to fix that problem. This will also be needed to run docker container with libvirt-sandbox. I also added some configure flags to disable lzma or zlib support at build time. At least opensuse 13.2 doesn't have static lzma. Diff to v1: * Fixed Dan's comments * Fixed the container case: * Made init-lxc all-static * Moved the init copy code to libvirt-sandbox-builder.c * Use setenv to set the LD_LIBRARY_PATH rather than reset the whole environment using execve Cédric Bosdonnat (11): Allow disabling build with lzma. Allow disabling zlib support. Enable strcmp checks in libvirt-sandbox-init-qemu.c Make init-lxc all static Copy all needed init programs and all its deps to config subdir Remove init-common dependency on libvirt-sandbox.so init-qemu: extract the mounts.cfg ntry mounting code qemu: use mounts targeting / as root Add function to check if there is a mount with / target Don't add sandbox:root device if we have a mount targetting / container builder: don't expose host rootfs if unneeded cfg.mk | 2 - configure.ac | 37 - libvirt-sandbox/Makefile.am| 45 +++--- .../libvirt-sandbox-builder-container.c| 37 +++-- libvirt-sandbox/libvirt-sandbox-builder-machine.c | 22 +-- libvirt-sandbox/libvirt-sandbox-builder.c | 159 ++- libvirt-sandbox/libvirt-sandbox-builder.h | 2 + libvirt-sandbox/libvirt-sandbox-config-all.h | 62 libvirt-sandbox/libvirt-sandbox-config-disk.c | 2 +- libvirt-sandbox/libvirt-sandbox-config-initrd.c| 2 +- .../libvirt-sandbox-config-interactive.c | 2 +- .../libvirt-sandbox-config-mount-file.c| 2 +- .../libvirt-sandbox-config-mount-guest-bind.c | 2 +- .../libvirt-sandbox-config-mount-host-bind.c | 2 +- .../libvirt-sandbox-config-mount-host-image.c | 2 +- libvirt-sandbox/libvirt-sandbox-config-mount-ram.c | 2 +- libvirt-sandbox/libvirt-sandbox-config-mount.c | 2 +- .../libvirt-sandbox-config-network-address.c | 2 +- ...rt-sandbox-config-network-filterref-parameter.c | 2 +- .../libvirt-sandbox-config-network-filterref.c | 2 +- .../libvirt-sandbox-config-network-route.c | 2 +- libvirt-sandbox/libvirt-sandbox-config-network.c | 2 +- .../libvirt-sandbox-config-service-generic.c | 2 +- .../libvirt-sandbox-config-service-systemd.c | 2 +- libvirt-sandbox/libvirt-sandbox-config-service.c | 2 +- libvirt-sandbox/libvirt-sandbox-config.c | 23 ++- libvirt-sandbox/libvirt-sandbox-config.h | 1 + libvirt-sandbox/libvirt-sandbox-init-common.c | 5 +- libvirt-sandbox/libvirt-sandbox-init-lxc.c | 16 +- libvirt-sandbox/libvirt-sandbox-init-qemu.c| 175 + libvirt-sandbox/libvirt-sandbox-util.c | 2 +- libvirt-sandbox/libvirt-sandbox.sym| 1 + 32 files changed, 519 insertions(+), 104 deletions(-) create mode 100644 libvirt-sandbox/libvirt-sandbox-config-all.h -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox v2 03/11] Enable strcmp checks in libvirt-sandbox-init-qemu.c
--- cfg.mk | 2 -- libvirt-sandbox/libvirt-sandbox-init-qemu.c | 6 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cfg.mk b/cfg.mk index 83ded15..37e5050 100644 --- a/cfg.mk +++ b/cfg.mk @@ -132,5 +132,3 @@ exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics = ^libvirt-sandbox/tes exclude_file_name_regexp--sc_bindtextdomain = ^(libvirt-sandbox/tests)|(libvirt-sandbox/libvirt-sandbox-init-*)|(bin/virt-sandbox.c)|(bin/virt-sandbox-service-util.c) exclude_file_name_regexp--sc_preprocessor_indentation = ^*/*.[ch] - -exclude_file_name_regexp--sc_prohibit_strcmp = ^libvirt-sandbox/libvirt-sandbox-init-qemu.c diff --git a/libvirt-sandbox/libvirt-sandbox-init-qemu.c b/libvirt-sandbox/libvirt-sandbox-init-qemu.c index d5a0b7a..44305fd 100644 --- a/libvirt-sandbox/libvirt-sandbox-init-qemu.c +++ b/libvirt-sandbox/libvirt-sandbox-init-qemu.c @@ -51,6 +51,8 @@ #define ATTR_UNUSED __attribute__((__unused__)) +#define STREQ(x,y) (strcmp(x,y) == 0) + static void print_uptime (void); static void insmod (const char *filename); static void set_debug(void); @@ -283,7 +285,7 @@ main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED) __func__, source, target, type, opts); -if (strcmp(type, ) == 0) { +if (STREQ(type, )) { struct stat st; type = NULL; flags |= MS_BIND; @@ -297,7 +299,7 @@ main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED) else mount_mkfile(target, 644); } else { -if (strcmp(type, tmpfs) == 0) +if (STREQ(type, tmpfs)) flags |= MS_NOSUID | MS_NODEV; mount_mkdir(target, 0755); -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox v2 11/11] container builder: don't expose host rootfs if unneeded
If the user defined a mount targeting / don't add the host / as mount to /. --- .../libvirt-sandbox-builder-container.c| 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libvirt-sandbox/libvirt-sandbox-builder-container.c b/libvirt-sandbox/libvirt-sandbox-builder-container.c index d226d35..66e1fc6 100644 --- a/libvirt-sandbox/libvirt-sandbox-builder-container.c +++ b/libvirt-sandbox/libvirt-sandbox-builder-container.c @@ -256,17 +256,19 @@ static gboolean gvir_sandbox_builder_container_construct_devices(GVirSandboxBuil g_list_free(disks); -fs = gvir_config_domain_filesys_new(); -gvir_config_domain_filesys_set_type(fs, GVIR_CONFIG_DOMAIN_FILESYS_MOUNT); -gvir_config_domain_filesys_set_access_type(fs, GVIR_CONFIG_DOMAIN_FILESYS_ACCESS_PASSTHROUGH); -gvir_config_domain_filesys_set_source(fs, - gvir_sandbox_config_get_root(config)); -gvir_config_domain_filesys_set_target(fs, /); -gvir_config_domain_filesys_set_readonly(fs, TRUE); +if (!gvir_sandbox_config_has_root_mount(config)) { +fs = gvir_config_domain_filesys_new(); +gvir_config_domain_filesys_set_type(fs, GVIR_CONFIG_DOMAIN_FILESYS_MOUNT); +gvir_config_domain_filesys_set_access_type(fs, GVIR_CONFIG_DOMAIN_FILESYS_ACCESS_PASSTHROUGH); +gvir_config_domain_filesys_set_source(fs, + gvir_sandbox_config_get_root(config)); +gvir_config_domain_filesys_set_target(fs, /); +gvir_config_domain_filesys_set_readonly(fs, TRUE); -gvir_config_domain_add_device(domain, - GVIR_CONFIG_DOMAIN_DEVICE(fs)); -g_object_unref(fs); +gvir_config_domain_add_device(domain, + GVIR_CONFIG_DOMAIN_DEVICE(fs)); +g_object_unref(fs); +} -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox v2 05/11] Copy all needed init programs and all its deps to config subdir
In order to be able to mount a custom host-image as / we need to be able to access libvirt-sandbox-init-common and all its needed dependencies. In the container case we also need to copy libvirt-sandbox-init-lxc. They are now copied into SANDBOXCONFIGDIR /.libs. Hard linking is not possible since we may be working on separate partitions, and symlinks wouldn't help to work with apparmor. Copying makes apparmor happy and solves our problem. --- configure.ac | 7 + .../libvirt-sandbox-builder-container.c| 15 +- libvirt-sandbox/libvirt-sandbox-builder.c | 159 - libvirt-sandbox/libvirt-sandbox-builder.h | 2 + libvirt-sandbox/libvirt-sandbox-init-lxc.c | 8 +- libvirt-sandbox/libvirt-sandbox-init-qemu.c| 9 +- 6 files changed, 196 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 99d22d7..608f56b 100644 --- a/configure.ac +++ b/configure.ac @@ -109,6 +109,13 @@ LIBVIRT_SANDBOX_SELINUX LIBVIRT_SANDBOX_STATIC_LIBC +dnl search for LDD path +AC_PATH_PROG([LDD_PATH], [ldd]) +if test -z $LDD_PATH; then +AC_MSG_ERROR([Failed to find ldd.]) +fi +AC_DEFINE_UNQUOTED([LDD_PATH], $LDD_PATH, [path to ldd binary]) + GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_REQUIRED]) dnl Should be in m4/virt-gettext.m4 but intltoolize is too diff --git a/libvirt-sandbox/libvirt-sandbox-builder-container.c b/libvirt-sandbox/libvirt-sandbox-builder-container.c index c23b82b..d226d35 100644 --- a/libvirt-sandbox/libvirt-sandbox-builder-container.c +++ b/libvirt-sandbox/libvirt-sandbox-builder-container.c @@ -184,7 +184,7 @@ static gboolean gvir_sandbox_builder_container_construct_os(GVirSandboxBuilder * gvir_config_domain_os_set_arch(os, gvir_sandbox_config_get_arch(config)); gvir_config_domain_os_set_init(os, - LIBEXECDIR /libvirt-sandbox-init-lxc); + SANDBOXCONFIGDIR /.libs/libvirt-sandbox-init-lxc); gvir_config_domain_os_set_cmdline(os, cmdline); gvir_config_domain_set_os(domain, os); @@ -444,6 +444,18 @@ static const gchar *gvir_sandbox_builder_container_get_disk_prefix(GVirSandboxBu return sd; } + +static GList *gvir_sandbox_builder_container_get_files_to_copy(GVirSandboxBuilder *builder, + GVirSandboxConfig *config G_GNUC_UNUSED) +{ +GList * tocopy = GVIR_SANDBOX_BUILDER_CLASS(gvir_sandbox_builder_container_parent_class)- + get_files_to_copy(builder, config); +gchar *file = g_strdup_printf(%s/libvirt-sandbox-init-lxc, LIBEXECDIR); + +return g_list_append(tocopy, file); +} + + static void gvir_sandbox_builder_container_class_init(GVirSandboxBuilderContainerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); @@ -458,6 +470,7 @@ static void gvir_sandbox_builder_container_class_init(GVirSandboxBuilderContaine builder_class-construct_features = gvir_sandbox_builder_container_construct_features; builder_class-construct_devices = gvir_sandbox_builder_container_construct_devices; builder_class-get_disk_prefix = gvir_sandbox_builder_container_get_disk_prefix; +builder_class-get_files_to_copy = gvir_sandbox_builder_container_get_files_to_copy; g_type_class_add_private(klass, sizeof(GVirSandboxBuilderContainerPrivate)); } diff --git a/libvirt-sandbox/libvirt-sandbox-builder.c b/libvirt-sandbox/libvirt-sandbox-builder.c index aa932db..2726868 100644 --- a/libvirt-sandbox/libvirt-sandbox-builder.c +++ b/libvirt-sandbox/libvirt-sandbox-builder.c @@ -107,6 +107,8 @@ static gboolean gvir_sandbox_builder_clean_post_stop_default(GVirSandboxBuilder GVirSandboxConfig *config, const gchar *statedir, GError **error); +static GList *gvir_sandbox_builder_get_files_to_copy(GVirSandboxBuilder *builder, + GVirSandboxConfig *config); static void gvir_sandbox_builder_get_property(GObject *object, guint prop_id, @@ -176,6 +178,7 @@ static void gvir_sandbox_builder_class_init(GVirSandboxBuilderClass *klass) klass-construct_security = gvir_sandbox_builder_construct_security; klass-clean_post_start = gvir_sandbox_builder_clean_post_start_default; klass-clean_post_stop = gvir_sandbox_builder_clean_post_stop_default; +klass-get_files_to_copy = gvir_sandbox_builder_get_files_to_copy; g_object_class_install_property(object_class, PROP_CONNECTION, @@ -247,6 +250,108 @@ GVirConnection *gvir_sandbox_builder_get_connection(GVirSandboxBuilder *builder) } +static
[libvirt] [sandbox v2 01/11] Allow disabling build with lzma.
Some linux distributions don't package static lzma library. Allow disabling it. --- configure.ac| 14 +- libvirt-sandbox/libvirt-sandbox-init-qemu.c | 12 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 140fb8c..834a444 100644 --- a/configure.ac +++ b/configure.ac @@ -81,7 +81,14 @@ PKG_CHECK_MODULES(LIBVIRT_GLIB, libvirt-glib-1.0 = $LIBVIRT_GOBJECT_REQUIRED) PKG_CHECK_MODULES(LIBVIRT_GOBJECT, libvirt-gobject-1.0 = $LIBVIRT_GOBJECT_REQUIRED) PKG_CHECK_MODULES(LIBVIRT_GCONFIG, libvirt-gconfig-1.0 = $LIBVIRT_GCONFIG_REQUIRED) PKG_CHECK_MODULES(ZLIB, zlib = $ZLIB_REQUIRED) -PKG_CHECK_MODULES(LZMA, liblzma = $LZMA_REQUIRED) +AC_ARG_WITH([lzma], + [AS_HELP_STRING([--with-lzma], +[add LZMA support @:@default=yes@:@])]) +m4_divert_text([DEFAULTS], [with_lzma=yes]) + +if test $with_lzma = yes ; then +PKG_CHECK_MODULES(LZMA, liblzma = $LZMA_REQUIRED) +fi LIBVIRT_SANDBOX_CAPNG LIBVIRT_SANDBOX_GETTEXT @@ -118,6 +125,11 @@ AC_MSG_NOTICE([]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([ Libraries:]) AC_MSG_NOTICE([]) +if test $with_lzma != no ; then +AC_MSG_NOTICE([LZMA: $LZMA_CFLAGS $LZMA_LIBS]) +else +AC_MSG_NOTICE([LZMA: no]) +fi AC_MSG_NOTICE([ GOBJECT: $GOBJECT_CFLAGS $GOBJECT_LIBS]) AC_MSG_NOTICE([ LIBVIRT_GOBJECT: $LIBVIRT_GOBJECT_CFLAGS $LIBVIRT_GOBJECT_LIBS]) AC_MSG_NOTICE([]) diff --git a/libvirt-sandbox/libvirt-sandbox-init-qemu.c b/libvirt-sandbox/libvirt-sandbox-init-qemu.c index eabf9aa..a9e6263 100644 --- a/libvirt-sandbox/libvirt-sandbox-init-qemu.c +++ b/libvirt-sandbox/libvirt-sandbox-init-qemu.c @@ -42,7 +42,9 @@ #include fcntl.h #include sys/reboot.h #include termios.h +#if WITH_LZMA #include lzma.h +#endif /* WITH_LZMA */ #include zlib.h #define ATTR_UNUSED __attribute__((__unused__)) @@ -400,6 +402,7 @@ has_suffix(const char *filename, const char *ext) offset[strlen(ext)] == '\0'); } +#if WITH_LZMA static char * load_module_file_lzma(const char *filename, size_t *len) { @@ -456,6 +459,15 @@ load_module_file_lzma(const char *filename, size_t *len) free(xzdata); return data; } +#else +static char * +load_module_file_lzma(const char *filename, size_t *len) +{ +fprintf(stderr, libvirt-sandbox-init-qemu: %s: +lzma support disabled, can't read module %s\n, __func__, filename); +exit_poweroff(); +} +#endif /* WITH_LZMA */ static char * load_module_file_zlib(const char *filename, size_t *len) -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/4] libxl: don't remove persistent domain on start failure
libxlDomainCreateXML() would remove a persistent domain if libxlDomainStart() failed. Check if domain is persistent before removing. Signed-off-by: Jim Fehlig jfeh...@suse.com --- src/libxl/libxl_driver.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 8a8d27d..fb9523a 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -918,7 +918,10 @@ libxlDomainCreateXML(virConnectPtr conn, const char *xml, if (libxlDomainStart(driver, vm, (flags VIR_DOMAIN_START_PAUSED) != 0, -1) 0) { -virDomainObjListRemove(driver-domains, vm); +if (!vm-persistent) { +virDomainObjListRemove(driver-domains, vm); +vm = NULL; +} goto endjob; } -- 2.3.7 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/4] libxl: honor domainGetXMLDesc() --inactive flag
The libxl driver always uses virDomainObj-def when formatting the domain XML description. Use virDomainObj-newDef when --inactive flag is set. Signed-off-by: Jim Fehlig jfeh...@suse.com --- src/libxl/libxl_driver.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index fb9523a..1a5b1a7 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -2429,6 +2429,7 @@ static char * libxlDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) { virDomainObjPtr vm; +virDomainDefPtr def; char *ret = NULL; /* Flags checked by virDomainDefFormat */ @@ -2439,8 +2440,13 @@ libxlDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) if (virDomainGetXMLDescEnsureACL(dom-conn, vm-def, flags) 0) goto cleanup; -ret = virDomainDefFormat(vm-def, - virDomainDefFormatConvertXMLFlags(flags)); +if ((flags VIR_DOMAIN_XML_INACTIVE) vm-newDef) +def = vm-newDef; +else +def = vm-def; + +ret = virDomainDefFormat(def, + virDomainDefFormatConvertXMLFlags(flags)); cleanup: if (vm) -- 2.3.7 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/4] libxl: don't overwrite domain state from statedir config
When restarting libvirtd and reconnecting to running domains, libxlReconnectDomain() would unconditionally set the domain state to VIR_DOMAIN_RUNNING, overwriting the state maintained in $statedir/domname.xml. A domain in a paused state would have the state changed to running, even though it was actually in a paused state. Signed-off-by: Jim Fehlig jfeh...@suse.com --- src/libxl/libxl_driver.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index a7be745..8a8d27d 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -372,8 +372,6 @@ libxlReconnectDomain(virDomainObjPtr vm, vm-def, VIR_HOSTDEV_SP_PCI) 0) goto out; -virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNKNOWN); - if (virAtomicIntInc(driver-nactive) == 1 driver-inhibitCallback) driver-inhibitCallback(true, driver-inhibitOpaque); -- 2.3.7 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/4] libxl: Set def-vcpus after successfully modifying live vcpu count
def-vcpus was never updated after successfully changing the live vcpu count of a domain. Subsequent queries for vcpu info would return incorrect results. E.g.: virsh vcpucount test maximum config 4 maximum live 4 current config 4 current live 4 virsh setvcpus test 2 virsh vcpucount test maximum config 4 maximum live 4 current config 4 current live 4 After patch, live current config is reported correctly: virsh vcpucount test maximum config 4 maximum live 4 current config 4 current live 2 While fixing this, noticed that the live config was not saved to cfg-stateDir via virDomainSaveStatus. Save the live config and change error handling of virDomainSave{Config,Status} to log a message via VIR_WARN, instead of failing the entire DomainSetVcpusFlags operation. Signed-off-by: Jim Fehlig jfeh...@suse.com --- src/libxl/libxl_driver.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 1a5b1a7..96c9d96 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -2101,6 +2101,7 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, with libxenlight), vm-def-id); goto endjob; } +vm-def-vcpus = nvcpus; break; case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG: @@ -2110,14 +2111,25 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, with libxenlight), vm-def-id); goto endjob; } +vm-def-vcpus = nvcpus; def-vcpus = nvcpus; break; } ret = 0; -if (flags VIR_DOMAIN_VCPU_CONFIG) -ret = virDomainSaveConfig(cfg-configDir, def); +if (flags VIR_DOMAIN_VCPU_LIVE) { +if (virDomainSaveStatus(driver-xmlopt, cfg-stateDir, vm) 0) { +VIR_WARN(Unable to save status on vm %s after changing vcpus, + vm-def-name); +} +} +if (flags VIR_DOMAIN_VCPU_CONFIG) { +if (virDomainSaveConfig(cfg-configDir, def) 0) { +VIR_WARN(Unable to save configuration of vm %s after changing vcpus, + vm-def-name); +} +} endjob: if (!libxlDomainObjEndJob(driver, vm)) -- 2.3.7 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/4] Some small libxl bug fixes
While working on a patch to add dom0 support to the libxl driver, I noticed a few existing bugs which are fixed by this small series. IMO 1 and 2 are safe even during the freeze as they fix quite annoying bugs. 3 and 4 are probably safe bug fixes too, unless I'm confused about the use of domainObj-{def,newDef,persistentDef} Jim Fehlig (4): libxl: don't overwrite domain state from statedir config libxl: don't remove persistent domain on start failure libxl: honor domainGetXMLDesc() --inactive flag libxl: Set def-vcpus after successfully modifying live vcpu count src/libxl/libxl_driver.c | 33 ++--- 1 file changed, 26 insertions(+), 7 deletions(-) -- 2.3.7 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [[libvirt-php][PATCH v4] qemu-agent-command] add libvirt_domain_qemu_agent_command
On 29.06.2015 11:04, Vasiliy Tolstov wrote: add another missing libvirt command Signed-off-by: Vasiliy Tolstov v.tols...@selfip.ru --- configure.ac | 3 +++ src/Makefile.am | 5 +++-- src/libvirt-php.c | 29 + src/libvirt-php.h | 2 ++ 4 files changed, 37 insertions(+), 2 deletions(-) ACKed and pushed. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/9] support multi-thread compress migration.
These series patches support multi-thread compress during live migration. Eli Qiao (4): Add test cases for qemuMonitorJSONGetMigrationParameter remote: Add support for set and get multil thread migration parameters qemu_driver: Add support to set/get migration parameters. virsh: Add set and get multi-thread migration parameters commands ShaoHe Feng (5): qemu_migration: Add support for mutil-thread compressed migration enable qemu: Add monitor API for get/set migration parameters set multi-thread compress params for Migrate3 during live migration virsh: add multi-thread migration option for live migrate command Implement the public APIs for multi-thread compress parameters. daemon/remote.c | 62 +++ include/libvirt/libvirt-domain.h | 31 ++ src/driver-hypervisor.h | 14 +++ src/libvirt-domain.c | 110 +++ src/libvirt_public.syms | 5 + src/qemu/qemu_domain.h | 3 + src/qemu/qemu_driver.c | 186 src/qemu/qemu_migration.c| 105 ++ src/qemu/qemu_migration.h| 18 +++- src/qemu/qemu_monitor.c | 40 ++- src/qemu/qemu_monitor.h | 11 ++ src/qemu/qemu_monitor_json.c | 93 src/qemu/qemu_monitor_json.h | 9 ++ src/qemu/qemu_monitor_text.c | 95 + src/qemu/qemu_monitor_text.h | 10 ++ src/remote/remote_driver.c | 54 ++ src/remote/remote_protocol.x | 30 +- src/remote_protocol-structs | 26 + tests/qemumonitorjsontest.c | 53 + tools/virsh-domain.c | 225 ++- tools/virsh.pod | 36 +-- 21 files changed, 1206 insertions(+), 10 deletions(-) -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] storage: Set correct vol-type at VolCreate
https://bugzilla.redhat.com/show_bug.cgi?id=1227664 If the requested format type for the new entry in the file system pool is a 'dir', then be sure to set the vol-type correctly as would be done when the pool is refreshed. Signed-off-by: John Ferlan jfer...@redhat.com --- src/storage/storage_backend_fs.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index b751687..0eebac3 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -1051,7 +1051,10 @@ virStorageBackendFileSystemVolCreate(virConnectPtr conn ATTRIBUTE_UNUSED, virStorageVolDefPtr vol) { -vol-type = VIR_STORAGE_VOL_FILE; +if (vol-target.format == VIR_STORAGE_FILE_DIR) +vol-type = VIR_STORAGE_VOL_DIR; +else +vol-type = VIR_STORAGE_VOL_FILE; VIR_FREE(vol-target.path); if (virAsprintf(vol-target.path, %s/%s, -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 2/2] Allow PCI virtio on ARM virt machine
On 06/29/2015 02:52 AM, Pavel Fedin wrote: Hello! PING! We can't apply this without unit test additions. We will at least need a test for qemu 2.3+ defaulting to PCI, and a test to ensure that manually specified virtio-mmio continues to do the correct thing. I'll take a stab at it this week How are things going? Something like 2 weeks have passed. Sorry, I've been slacking. Unfortunately thinking about this some more, the current patch approach might not be acceptable as is, since current distros as a guest don't support -M virt with PCI... for example Fedora 21 or 22. But they _do_ work with virtio-mmio. So I don't know if we can or should change the default outright to virtio-pci when qemu supports it. Maybe when we get versioned -M virt types we can key off a more modern type. Dunno, I have to play with it all first to get a better idea. That said, patches that just allow using pci instead of mmio if the user explicitly requests it should be fine for now before we consider if/how to change the default from mmio to pci. I could write these tests if somebody explains me how our unit-testing works and where to put them. Read HACKING bits about 'make check'. The main tests you'll be extending here are tests/qemuxml2argvtest.c with data in tests/qemuxml2argvdata/. Check the existing aarch64 and arm ones to get an idea, or look at some of my previous commits regarding arm/aarch64 for examples - Cole -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] libvirt/hooks: Static and dynamic hugepage hooks
On Wed, 2015-06-24 at 12:57 -0600, Alex Williamson wrote: This patch provides scripts for hugepage allocation, as well as a bit of infrastructure and common hook config file that I hope may some day be enabled by default in libvirt. For now, we place the files in /usr/share and ask users to install the config file and copy or link the scripts, more like contrib scripts for now. Two methods of hugepage allocation are provided, static and dynamic. The static mechanism allocates pages at libvirt daemon startup and releases them at shutdown. It allows full size, locality, and policy configuration. For instance, if I want to allocate a set of 2M pages exclusively on host NUMA node 1, it can do that, along with plenty more. This is especially useful for 1G hugepages on x86, since they can now be allocated dynamically, but become impractical to allocate due to memory fragmentation as the host runs. Systems dedicated to hosting VMs are also likely to prefer static allocation. Static allocation requires explicit XML entries in the hook config file to be activated. The dynamic method allocates hugepages only around the instantiation of the VM. This is enabled by adding an entry for the domain in the config file and configuring the domain normally for hugepages. The dynamic hugepage script is activated via the QEMU domain prepare hook, reads the domain XML and allocates hugepages as necessary. On domain shutdown, hugepages are freed via the release hook. This model is more appropriate for systems that are not dedicated VM hosts and guests that use hugepage sizes and quantities are are likely to be dynamically allocated as the VM is started. In addition to the documentation provided within each script, a README file is provided with overal instructions and summaries of the individual scripts. Signed-off-by: Alex Williamson alex.william...@redhat.com --- I'm going to self-nak this because I think I've misinterpreted the nodeset on hugepages/page to be host node rather than guest node. I'll need to re-jig the algorithm. Thanks, Alex -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] util:qemu: fix IOThreadinfo always get failed when get running vm status
On Mon, Jun 29, 2015 at 16:22:54 +0800, Luyao Huang wrote: When we use iothreadinfo to get iothread information, we will get error like this: # virsh iothreadinfo rhel7.0 --live error: Unable to get domain IOThreads information error: Unable to encode message payload This is because virProcessGetAffinity() return a bitmap which map_len is too big to send via rpc: (gdb) p *map $7 = {max_bit = 262144, map_len = 4096, map = 0x7f9b6c2c0a20} To fix this issue add a new parameter maxcpu to virProcessGetAffinity() to let callers specify the maxcpu (also in most machine, no need loop 262144 times to check if cpu is set), if set maxcpu to zero, virProcessGetAffinity() will use default value (262144 or 1024) to create bitmap. This issue was introduced in commit 825df8c. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/qemu/qemu_driver.c | 4 ++-- src/util/virprocess.c | 7 --- src/util/virprocess.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) I think a better fix will be to make virBitmapToData smarter when formatting a bitmap by finding the last set bit rather than formatting the full bitmap. This will avoid re-introducing the maxcpu argument. The diff for such change is following: diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c index 9abc807..7234f7e 100644 --- a/src/util/virbitmap.c +++ b/src/util/virbitmap.c @@ -498,9 +498,12 @@ virBitmapPtr virBitmapNewData(void *data, int len) */ int virBitmapToData(virBitmapPtr bitmap, unsigned char **data, int *dataLen) { -int len; +ssize_t len; -len = (bitmap-max_bit + CHAR_BIT - 1) / CHAR_BIT; +if ((len = virBitmapLastSetBit(bitmap)) 0) +len = 1; +else +len = (len + CHAR_BIT - 1) / CHAR_BIT; if (VIR_ALLOC_N(*data, len) 0) return -1; Peter signature.asc Description: Digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 2/2] Allow PCI virtio on ARM virt machine
Hello! PING! We can't apply this without unit test additions. We will at least need a test for qemu 2.3+ defaulting to PCI, and a test to ensure that manually specified virtio-mmio continues to do the correct thing. I'll take a stab at it this week How are things going? Something like 2 weeks have passed. I could write these tests if somebody explains me how our unit-testing works and where to put them. Kind regards, Pavel Fedin Expert Engineer Samsung Electronics Research center Russia -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] util:qemu: fix IOThreadinfo always get failed when get running vm status
On 06/29/2015 04:38 PM, Peter Krempa wrote: On Mon, Jun 29, 2015 at 16:22:54 +0800, Luyao Huang wrote: When we use iothreadinfo to get iothread information, we will get error like this: # virsh iothreadinfo rhel7.0 --live error: Unable to get domain IOThreads information error: Unable to encode message payload This is because virProcessGetAffinity() return a bitmap which map_len is too big to send via rpc: (gdb) p *map $7 = {max_bit = 262144, map_len = 4096, map = 0x7f9b6c2c0a20} To fix this issue add a new parameter maxcpu to virProcessGetAffinity() to let callers specify the maxcpu (also in most machine, no need loop 262144 times to check if cpu is set), if set maxcpu to zero, virProcessGetAffinity() will use default value (262144 or 1024) to create bitmap. This issue was introduced in commit 825df8c. Signed-off-by: Luyao Huanglhu...@redhat.com --- src/qemu/qemu_driver.c | 4 ++-- src/util/virprocess.c | 7 --- src/util/virprocess.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) I think a better fix will be to make virBitmapToData smarter when formatting a bitmap by finding the last set bit rather than formatting the full bitmap. This will avoid re-introducing the maxcpu argument. The diff for such change is following: diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c index 9abc807..7234f7e 100644 --- a/src/util/virbitmap.c +++ b/src/util/virbitmap.c @@ -498,9 +498,12 @@ virBitmapPtr virBitmapNewData(void *data, int len) */ int virBitmapToData(virBitmapPtr bitmap, unsigned char **data, int *dataLen) { -int len; +ssize_t len; -len = (bitmap-max_bit + CHAR_BIT - 1) / CHAR_BIT; +if ((len = virBitmapLastSetBit(bitmap)) 0) +len = 1; +else +len = (len + CHAR_BIT - 1) / CHAR_BIT; if (VIR_ALLOC_N(*data, len) 0) return -1; Okay, i agree with you, and also we need remove the unused parameter in qemuDomainHelperGetVcpus() and qemuDomainGetIOThreadsLive() diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2b530c8..6aa4c90 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1418,13 +1418,9 @@ static int qemuDomainHelperGetVcpus(virDomainObjPtr vm, virVcpuInfoPtr info, int maxinfo, unsigned char *cpumaps, int maplen) { -int hostcpus; size_t i, v; qemuDomainObjPrivatePtr priv = vm-privateData; -if ((hostcpus = nodeGetCPUCount()) 0) -return -1; - if (priv-vcpupids == NULL) { virReportError(VIR_ERR_OPERATION_INVALID, %s, _(cpu affinity is not supported)); @@ -5573,7 +5569,6 @@ qemuDomainGetIOThreadsLive(virQEMUDriverPtr driver, qemuMonitorIOThreadInfoPtr *iothreads = NULL; virDomainIOThreadInfoPtr *info_ret = NULL; int niothreads = 0; -int hostcpus; size_t i; int ret = -1; @@ -5606,9 +5601,6 @@ qemuDomainGetIOThreadsLive(virQEMUDriverPtr driver, goto endjob; } -if ((hostcpus = nodeGetCPUCount()) 0) -goto endjob; - if (VIR_ALLOC_N(info_ret, niothreads) 0) goto endjob; Thanks for your quick review. Peter Luyao -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Revert Introduce QEMU_CAPS_ARM_VIRT_PCI
The capability was not used up to the feature freeze. This reverts commit 7f3515b4bb677d0ead1887547efc844e4761268a. --- src/qemu/qemu_capabilities.c | 4 src/qemu/qemu_capabilities.h | 1 - 2 files changed, 5 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index e7002a3..27686c3 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -287,7 +287,6 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, aarch64-off, vhost-user-multiqueue, /* 190 */ - arm-virt-pci, ); @@ -1337,9 +1336,6 @@ virQEMUCapsComputeCmdFlags(const char *help, virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_SHARE_POLICY); } -if (version = 2003000) -virQEMUCapsSet(qemuCaps, QEMU_CAPS_ARM_VIRT_PCI); - return 0; } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f4180a8..30aa504 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -230,7 +230,6 @@ typedef enum { QEMU_CAPS_DEVICE_PCI_SERIAL = 188, /* -device pci-serial */ QEMU_CAPS_CPU_AARCH64_OFF= 189, /* -cpu ...,aarch64=off */ QEMU_CAPS_VHOSTUSER_MULTIQUEUE = 190, /* vhost-user with -netdev queues= */ -QEMU_CAPS_ARM_VIRT_PCI = 191, /* ARM 'virt' machine has PCI bus */ QEMU_CAPS_LAST, /* this must always be the last item */ } virQEMUCapsFlags; -- 2.4.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [sandbox PATCH 00/10] Patches for Libvirt-sandbox
Hello Eren, Again, to help your patches review, you will need: * to use -vN when running git send-email to get the version of the patch series in the mail subject * Have a diff with the previous version... your diff never changes. Regards, -- Cedric On Fri, 2015-06-26 at 15:27 +0200, Eren Yagdiran wrote: Hello, These patches provide disk support for libvirt-sandbox. Implemented '--disk' parameter will be useful when integrating Docker image support for libvirt-sandbox. --Main diffs compared to previous patches. Since many hypervisors, including kvm, will not even honour requested names for disk devices we link each device under /dev/disk/by-tag e.g /dev/disk/by-tag/foobar - /dev/sda We populate disks.cfg with tag to device mapping when we build the sandbox. After that, in each init-process {Common,Qemu}, we basically read the configuration and populate the right symlinks under /dev/disk/by-tag The common functions for modifying directories are moved under Init-util. {Common,Qemu} inits are using them. Cédric Bosdonnat (2): Add gvir_sandbox_config_has_disks function qemu: use devtmpfs rather than tmpfs to auto-populate /dev Eren Yagdiran (8): Add an utility function for guessing filetype from file extension Add configuration object for disk support Add disk parameter to virt-sandbox Add disk support to the container builder Add disk support to machine builder Init-util : Common directory functions for init-common and init-qemu Common-init: Building symlink from disks.cfg Common-builder: /dev/disk/by-tag/thetag to /dev/vdN bin/virt-sandbox.c | 37 +++ libvirt-sandbox/Makefile.am| 7 +- .../libvirt-sandbox-builder-container.c| 33 ++- libvirt-sandbox/libvirt-sandbox-builder-machine.c | 44 ++- libvirt-sandbox/libvirt-sandbox-builder.c | 73 - libvirt-sandbox/libvirt-sandbox-config-disk.c | 273 +++ libvirt-sandbox/libvirt-sandbox-config-disk.h | 82 ++ libvirt-sandbox/libvirt-sandbox-config.c | 300 + libvirt-sandbox/libvirt-sandbox-config.h | 11 + libvirt-sandbox/libvirt-sandbox-init-common.c | 54 +++- libvirt-sandbox/libvirt-sandbox-init-qemu.c| 145 ++ libvirt-sandbox/libvirt-sandbox-init-util.c| 57 libvirt-sandbox/libvirt-sandbox-init-util.h| 40 +++ libvirt-sandbox/libvirt-sandbox-util.c | 72 + libvirt-sandbox/libvirt-sandbox-util.h | 5 + libvirt-sandbox/libvirt-sandbox.h | 1 + libvirt-sandbox/libvirt-sandbox.sym| 5 + libvirt-sandbox/tests/test-config.c| 11 + po/POTFILES.in | 1 + 19 files changed, 1105 insertions(+), 146 deletions(-) create mode 100644 libvirt-sandbox/libvirt-sandbox-config-disk.c create mode 100644 libvirt-sandbox/libvirt-sandbox-config-disk.h create mode 100644 libvirt-sandbox/libvirt-sandbox-init-util.c create mode 100644 libvirt-sandbox/libvirt-sandbox-init-util.h create mode 100644 libvirt-sandbox/libvirt-sandbox-util.c -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [[libvirt-php][PATCH v4] qemu-agent-command] add libvirt_domain_qemu_agent_command
add another missing libvirt command Signed-off-by: Vasiliy Tolstov v.tols...@selfip.ru --- configure.ac | 3 +++ src/Makefile.am | 5 +++-- src/libvirt-php.c | 29 + src/libvirt-php.h | 2 ++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 04ebbdc..b6ef27a 100644 --- a/configure.ac +++ b/configure.ac @@ -34,6 +34,9 @@ fi LIBVIRT_REQUIRED=1.2.8 PKG_CHECK_MODULES(LIBVIRT, libvirt = $LIBVIRT_REQUIRED) +PKG_CHECK_MODULES(QEMU, libvirt-qemu) +AC_SUBST([QEMU_CFLAGS]) +AC_SUBST([QEMU_LIBS]) dnl == dnl required minimum version of libxml2 diff --git a/src/Makefile.am b/src/Makefile.am index 8e6a800..f270ec2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,13 +27,14 @@ uninstall-local: AM_CFLAGS = \ $(PHPINC) $(LIBXML_CFLAGS) \ - $(LIBVIRT_CFLAGS) $(DEFINES) \ + $(LIBVIRT_CFLAGS) $(QEMU_CFLAGS) $(DEFINES) \ -I$(top_srcdir)/winsrc AM_LDFLAGS = \ $(SHLIB_LDFLAGS) \ $(LIBXML_LIBS) \ - $(LIBVIRT_LIBS) + $(LIBVIRT_LIBS) \ + $(QEMU_LIBS) lib_LTLIBRARIES = libvirt-php.la diff --git a/src/libvirt-php.c b/src/libvirt-php.c index d13e5b4..b018cb0 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -242,6 +242,8 @@ static zend_function_entry libvirt_functions[] = { /* Debugging functions */ PHP_FE(libvirt_logfile_set, NULL) PHP_FE(libvirt_print_binding_resources, NULL) +/* Agent functions */ +PHP_FE(libvirt_domain_qemu_agent_command, NULL) {NULL, NULL, NULL} }; @@ -3611,6 +3613,33 @@ PHP_FUNCTION(libvirt_domain_lookup_by_uuid) } /* + * Function name: libvirt_domain_qemu_agent_command + * Since version: 0.5.2(-1) + * Description:Function is used to send qemu-ga command + * Arguments: @res [resource]: libvirt domain resource, e.g. from libvirt_domain_lookup_by_*() + * @timeout [int] timeout for waiting (-2 block, -1 default, 0 no wait, 0 wait specific time + * @flags [int]: unknown + * Returns:String on success and FALSE on error + */ +PHP_FUNCTION(libvirt_domain_qemu_agent_command) +{ + php_libvirt_domain *domain=NULL; + zval *zdomain; + const char *cmd; + int cmd_len; + char *ret; + long timeout = -1; + long flags = 0; + + GET_DOMAIN_FROM_ARGS(rs|ll, zdomain, cmd, cmd_len, timeout, flags); + + ret = virDomainQemuAgentCommand(domain-domain, cmd, timeout, flags); + if (ret == NULL) RETURN_FALSE; + + RETURN_STRING(ret, 1); +} + +/* * Function name: libvirt_domain_lookup_by_uuid_string * Since version: 0.4.1(-1) * Description: Function is used to get the domain by it's UUID that's accepted in string format diff --git a/src/libvirt-php.h b/src/libvirt-php.h index 8dc5927..eb4b7f4 100644 --- a/src/libvirt-php.h +++ b/src/libvirt-php.h @@ -80,6 +80,7 @@ #include libvirt/libvirt.h #include libvirt/virterror.h +#include libvirt/libvirt-qemu.h #include libxml/parser.h #include libxml/xpath.h #include fcntl.h @@ -423,6 +424,7 @@ PHP_FUNCTION(libvirt_domain_send_keys); PHP_FUNCTION(libvirt_domain_send_pointer_event); PHP_FUNCTION(libvirt_domain_get_metadata); PHP_FUNCTION(libvirt_domain_set_metadata); +PHP_FUNCTION(libvirt_domain_qemu_agent_command); /* Domain snapshot functions */ PHP_FUNCTION(libvirt_domain_has_current_snapshot); PHP_FUNCTION(libvirt_domain_snapshot_create); -- 2.3.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-php][PATCH v1] add libvirt_domain_qemu_agent_command
2015-06-26 11:03 GMT+03:00 Michal Privoznik mpriv...@redhat.com: This does not seem to be rebased. I'm having some difficulties applying the patch. Can you please rebase onto the latest HEAD and resend? Sorry, i miss rebase step. I'm resend new version to the list. -- Vasiliy Tolstov, e-mail: v.tols...@selfip.ru -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] util:qemu: fix IOThreadinfo always get failed when get running vm status
When we use iothreadinfo to get iothread information, we will get error like this: # virsh iothreadinfo rhel7.0 --live error: Unable to get domain IOThreads information error: Unable to encode message payload This is because virProcessGetAffinity() return a bitmap which map_len is too big to send via rpc: (gdb) p *map $7 = {max_bit = 262144, map_len = 4096, map = 0x7f9b6c2c0a20} To fix this issue add a new parameter maxcpu to virProcessGetAffinity() to let callers specify the maxcpu (also in most machine, no need loop 262144 times to check if cpu is set), if set maxcpu to zero, virProcessGetAffinity() will use default value (262144 or 1024) to create bitmap. This issue was introduced in commit 825df8c. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/qemu/qemu_driver.c | 4 ++-- src/util/virprocess.c | 7 --- src/util/virprocess.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2b530c8..e1ad696 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1459,7 +1459,7 @@ qemuDomainHelperGetVcpus(virDomainObjPtr vm, virVcpuInfoPtr info, int maxinfo, unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, v); virBitmapPtr map = NULL; -if (!(map = virProcessGetAffinity(priv-vcpupids[v]))) +if (!(map = virProcessGetAffinity(priv-vcpupids[v], hostcpus))) return -1; virBitmapToDataBuf(map, cpumap, maplen); @@ -5619,7 +5619,7 @@ qemuDomainGetIOThreadsLive(virQEMUDriverPtr driver, goto endjob; info_ret[i]-iothread_id = iothreads[i]-iothread_id; -if (!(map = virProcessGetAffinity(iothreads[i]-thread_id))) +if (!(map = virProcessGetAffinity(iothreads[i]-thread_id, hostcpus))) goto endjob; if (virBitmapToData(map, info_ret[i]-cpumap, diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 8fa7a9b..8800623 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -469,7 +469,8 @@ int virProcessSetAffinity(pid_t pid, virBitmapPtr map) } virBitmapPtr -virProcessGetAffinity(pid_t pid) +virProcessGetAffinity(pid_t pid, + int maxcpu) { size_t i; cpu_set_t *mask; @@ -504,10 +505,10 @@ virProcessGetAffinity(pid_t pid) goto cleanup; } -if (!(ret = virBitmapNew(ncpus))) +if (!(ret = virBitmapNew(maxcpu ? maxcpu : ncpus))) goto cleanup; -for (i = 0; i ncpus; i++) { +for (i = 0; i (maxcpu ? maxcpu : ncpus); i++) { # ifdef CPU_ALLOC /* coverity[overrun-local] */ if (CPU_ISSET_S(i, masklen, mask)) diff --git a/src/util/virprocess.h b/src/util/virprocess.h index 1768009..cc903ac 100644 --- a/src/util/virprocess.h +++ b/src/util/virprocess.h @@ -58,7 +58,7 @@ int virProcessKillPainfully(pid_t pid, bool force); int virProcessSetAffinity(pid_t pid, virBitmapPtr map); -virBitmapPtr virProcessGetAffinity(pid_t pid); +virBitmapPtr virProcessGetAffinity(pid_t pid, int maxcpu); int virProcessGetPids(pid_t pid, size_t *npids, pid_t **pids); -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu: fix not end the job after use OpenGraphics(FD) and get fail when exit monitor
If guest unexpect exit(qemu process be killed) and get failed when exit the monitor, guest job still handled by old function, this will make guest cannot start later. Need call qemuDomainObjEndJob to release job status before unref vm. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/qemu/qemu_driver.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2b530c8..b1c9f08 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17255,10 +17255,8 @@ qemuDomainOpenGraphics(virDomainPtr dom, qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorOpenGraphics(priv-mon, protocol, fd, graphicsfd, (flags VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH) != 0); -if (qemuDomainObjExitMonitor(driver, vm) 0) { +if (qemuDomainObjExitMonitor(driver, vm) 0) ret = -1; -goto cleanup; -} qemuDomainObjEndJob(driver, vm); cleanup: @@ -17327,10 +17325,8 @@ qemuDomainOpenGraphicsFD(virDomainPtr dom, qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorOpenGraphics(priv-mon, protocol, pair[1], graphicsfd, (flags VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH)); -if (qemuDomainObjExitMonitor(driver, vm) 0) { +if (qemuDomainObjExitMonitor(driver, vm) 0) ret = -1; -goto cleanup; -} qemuDomainObjEndJob(driver, vm); if (ret 0) goto cleanup; -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list