[libvirt] [PATCH] maint: drop spurious semicolons
by Eric Blake
Detected with:
git grep ';;$' -- '**/*.[ch]'
* src/network/bridge_driver.c (networkRadvdConfContents): Fix
harmless typo.
* src/phyp/phyp_driver.c (phypUUIDTable_Pull): Likewise.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONDriveDel):
Likewise.
---
Pushing under the trivial rule.
src/network/bridge_driver.c | 2 +-
src/phyp/phyp_driver.c | 2 +-
src/qemu/qemu_monitor_json.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 0c4b0b0..5578373 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -981,7 +981,7 @@ networkRestartDhcpDaemon(virNetworkObjPtr network)
static int
networkRadvdConfContents(virNetworkObjPtr network, char **configstr)
{
- virBuffer configbuf = VIR_BUFFER_INITIALIZER;;
+ virBuffer configbuf = VIR_BUFFER_INITIALIZER;
int ret = -1, ii;
virNetworkIpDefPtr ipdef;
bool v6present = false;
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index a1724ca..a3885a7 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -736,7 +736,7 @@ phypUUIDTable_Pull(virConnectPtr conn)
if (!channel) {
if (libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN) {
- goto err;;
+ goto err;
} else {
waitsocket(sock, session);
}
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index c35948e..2daf8ea 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3068,7 +3068,7 @@ int qemuMonitorJSONDriveDel(qemuMonitorPtr mon,
_("deleting disk is not supported. "
"This may leak data if disk is reassigned"));
ret = 1;
- virResetLastError();;
+ virResetLastError();
}
}
} else if (qemuMonitorJSONHasError(reply, "DeviceNotFound")) {
--
1.7.11.7
12 years, 1 month
[libvirt] [PATCH 3/3] Take the forwarding family into account
by Benjamin Cama
Only add iptables rules for this family, and also only check for
forwarding for this family.
---
src/network/bridge_driver.c | 27 +++++++++++++++++++++------
1 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index e3e8dc2..6bd4217 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1788,7 +1788,9 @@ networkAddIptablesRules(struct network_driver *driver,
return -1;
for (ii = 0;
- (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
+ (ipdef = virNetworkDefGetIpByIndex(network->def,
+ network->def->forwardFamily,
+ ii));
ii++) {
/* Add address-specific iptables rules */
if (networkAddIpSpecificIptablesRules(driver, network, ipdef) < 0) {
@@ -1803,7 +1805,9 @@ err:
* added for previous IP addresses.
*/
while ((--ii >= 0) &&
- (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii))) {
+ (ipdef = virNetworkDefGetIpByIndex(network->def,
+ network->def->forwardFamily,
+ ii))) {
networkRemoveIpSpecificIptablesRules(driver, network, ipdef);
}
networkRemoveGeneralIptablesRules(driver, network);
@@ -1819,7 +1823,9 @@ networkRemoveIptablesRules(struct network_driver *driver,
virNetworkIpDefPtr ipdef;
for (ii = 0;
- (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
+ (ipdef = virNetworkDefGetIpByIndex(network->def,
+ network->def->forwardFamily,
+ ii));
ii++) {
networkRemoveIpSpecificIptablesRules(driver, network, ipdef);
}
@@ -2173,9 +2179,18 @@ networkStartNetworkVirtual(struct network_driver *driver,
goto err2;
/* If forwardType != NONE, check for IP forwarding */
- if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE &&
- networkCheckIpForwarding(v4present, v6present) < 0) {
- goto err3;
+ if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) {
+ if (network->def->forwardFamily) {
+ /* if forwardFamily is set, we have at least a corresponding
+ * family's address
+ */
+ if (networkCheckIpForwarding(network->def->forwardFamily == AF_INET,
+ network->def->forwardFamily == AF_INET6) < 0)
+ goto err3;
+ } else {
+ if (networkCheckIpForwarding(v4present, v6present) < 0)
+ goto err3;
+ }
}
--
1.7.2.5
12 years, 1 month
[libvirt] [PATCH 0/8] RFC New API to retrieve host node CPU map
by Viktor Mihajlovski
Rationale:
In order to use the APIs listed below it is necessary for a client
to know the maximum number of node CPUs which is passed via the
maplen argument.
virDomainGetEmulatorPinInfo
virDomainGetVcpuPinInfo
virDomainGetVcpus
virDomainPinEmulator
virDomainPinVcpu
virDomainPinVcpuFlags
The current approach uses virNodeGetInfo to determine the maximum CPU number.
This can lead to incorrect results if not all node CPUs are online.
The maximum CPU number should always be the number of CPUs present on the
host, regardless of their online/offline state.
The following example illustrates the issue:
Host has 3 logical CPUs, 1 socket, 3 cores, 1 thread.
Guest has 1 virtual CPU and is started while all 3 host CPUs are
online.
$ virsh vcpuinfo guest
VCPU: 0
CPU: 0
State: running
CPU time: 35.4s
CPU Affinity: yyy
$ echo 0 > /sys/devices/system/cpu/cpu1/online
$ virsh vcpuinfo guest
VCPU: 0
CPU: 0
State: running
CPU time: 35.5s
CPU Affinity: y-
The correct display for CPU affinity would have been y-y, as the guest
continues to use CPUs 0 and 2.
This is not a display problem only, because it is also not possible to
explicitly pin the virtual CPU to host CPUs 0 and 2, due to the
truncated CPU mask.
PROPOSAL:
To help solve the issue above I suggest a new public API:
int virNodeGetCPUMapFlags(virConnectPtr conn,
unsigned char **cpumap,
unsigned int *online,
unsigned int flags);
The function will return the number of CPUs present on the host
or -1 on failure;
If cpumap is non-NULL virNodeGetCPUMapFlags will allocate an array
containing a bit map representation of the online CPUs. It's
the callers responsibility to deallocate cpumap using free().
If online is non-NULL, the variable pointed to will contain
the number of online host node CPUs.
The variable flags has been added to support future extensions
and must be set to 0.
Clients can use virNodeGetCPUMapFlags to properly determine the maximum
number of node CPUs and their online/offline state.
Remarks:
This series implements the QEMU and test drivers.
This series doesn't introduce changes to the existing vcpu pinning,
which I would submit as a succeeding patch set.
No python binding yet.
Viktor Mihajlovski (8):
virNodeGetCPUMapFlags: Define public API.
virNodeGetCPUMapFlags: Define driver API.
virNodeGetCPUMapFlags: Implement public API.
virNodeGetCPUMapFlags: Implement wire protocol.
libvirt.h.in: Add new cpumap macro VIR_CPU_USED
virNodeGetCPUMapFlags: Implement virsh support.
virNodeGetCPUMapFlags: Implement support function in nodeinfo
virNodeGetCPUMapFlags: Implement driver support
daemon/remote.c | 44 +++++++++++++++++++++++++++++++++
include/libvirt/libvirt.h.in | 28 ++++++++++++++++++---
python/generator.py | 1 +
src/driver.h | 7 +++++
src/libvirt.c | 56 ++++++++++++++++++++++++++++++++++++++++++
src/libvirt_private.syms | 1 +
src/libvirt_public.syms | 5 +++
src/nodeinfo.c | 49 ++++++++++++++++++++++++++++++++++++
src/nodeinfo.h | 6 ++++
src/qemu/qemu_driver.c | 1 +
src/remote/remote_driver.c | 49 ++++++++++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 13 +++++++++-
src/remote_protocol-structs | 12 +++++++++
src/test/test_driver.c | 30 ++++++++++++++++++++++
tools/virsh-host.c | 41 ++++++++++++++++++++++++++++++
tools/virsh.pod | 5 +++
16 files changed, 343 insertions(+), 5 deletions(-)
12 years, 1 month
[libvirt] [PATCH] RFC: Clarify the relationship between <vcpu>, <vcpupin>, and <emulatorpin>
by Osier Yang
These 3 elements conflicts with each other in either the doc
or the underlying codes are. This is to propse a solution.
Before writing any codes, I want to see if the principle is
correct, any advise is welcomed.
Current problems:
Problem 1:
The doc shouldn't simply say "These settings are superseded
by CPU tuning. " for element <vcpu>. As except the tuning, <vcpu>
allows to specify the current, maxmum vcpu number. Apart from that,
<vcpu> also allows to specify the placement as "auto", which binds
the domain process to the advisory nodeset from numad.
Problem 2:
Doc for <vcpu> says its "cpuset" specify the physical CPUs
that the vcpus can be pinned. But it's not the truth, as
actually it only pin domain process to the specified physical
CPUs. So either it's a document bug, or code bug.
Problem 3:
Doc for <vcpupin> says it supersed "cpuset" of <vcpu>, it's
not quite correct, as each <vcpupin> specify the pinning policy
only for one vcpu. How about the ones which doesn't have
<vcpupin> specified? it says the vcpu will be pinned to all
available physical CPUs, but what's the meaning of attribute
"cpuset" of <vcpu> then?
Problem 4:
Doc for <emulatorpin> says it pin the emulator threads (domain
process in other context, perhaps another follow up patch to
cleanup the inconsistency is needed) to the physical CPUs
specified its attribute "cpuset". Which conflicts with
<vcpu>'s "cpuset". And actually in the underlying codes,
it set the affinity for domain process twice if both
"cpuset" for <vcpu> and <emulatorpin> are specified,
and <emulatorpin>'s pinning will override <vcpu>'s.
Problem 5:
When "placement" of <vcpu> is "auto" (I.e. uses numad to
get the advisory nodeset to which the domain process is
pinned to), it will also be overridden by <emulatorpin>,
This patch is trying to sort out the conflicts or bugs by:
1) Don't say <vcpu> is superseded by <cputune>
2) Keep the semanteme for "cpuset" of <vcpu> (I.e. Still says it
specify the physical CPUs the virtual CPUs). But modifying it
to mention it also set the pinning policy for domain process,
and the CPU placement of domain process specified by "cpuset"
of <vcpu> will be ingored if <emulatorpin> specified, and
similary, the CPU placement of vcpu thread will be ignored
if it has <vcpupin> specified, for vcpu which doesn't have
<vcpupin> specified, it inherits "cpuset" of <vcpu>.
3) Don't say <vcpu> is supersed by <vcpupin>. If neither <vcpupin>
nor "cpuset" of <vcpu> is specified, the vcpu will be pinned
to all available pCPUs.
4) If neither <emulatorpin> nor "cpuset" of <vcpu> is specified,
the domain process (emulator threads in the context) will be
pinned to all available pCPUs.
5) If "placement" of <vcpu> is "auto", <emulatorpin> is not allowed.
6) hotplugged vcpus will also inherit "cpuset" of <vcpu>
Codes changes above document changes will cause:
1) Inherit def->cpumask for each vcpu which doesn't have <vcpupin>
specified, during parsing.
2) ping the vcpu which doesn't have <vcpupin> specified to def->cpumask
either by cgroup for sched_setaffinity(2), which is actually done
by 1).
3) Error out if "placement" == "auto", and <emulatorpin> is specified.
Otherwise, <emulatorpin> is honored, and "cpuset" of <cpuset> is
ignored.
4) Setup cgroup for each hotplugged vcpu, and setup the pinning policy
by either cgroup or sched_setaffinity(2).
5) Remove cgroup and <vcpupin> for each hot unplugged vcpu.
---
docs/formatdomain.html.in | 42 +++++++++++++++++++++++++++---------------
1 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index d664e7e..1ae8cf4 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -357,8 +357,18 @@
the maximum supported by the hypervisor. <span class="since">Since
0.4.4</span>, this element can contain an optional
<code>cpuset</code> attribute, which is a comma-separated
- list of physical CPU numbers that virtual CPUs can be pinned
- to. Each element in that list is either a single CPU number,
+ list of physical CPU numbers that domain process and virtual CPUs
+ can be pinned to by default. (NB: The pinning policy of domain
+ process and virtual CPUs can be specified separately by
+ <code>cputune</code>. If attribute <code>emulatorpin</code>
+ of <code>cputune</code> is specified, <code>cpuset</code>
+ specified by <code>vcpu</code> here will be ingored; Similarly,
+ For virtual CPUs which has <code>vcpupin</code> specified,
+ <code>cpuset</code> specified by <code>cpuset</code> here
+ will be ignored; For virtual CPUs which doesn't have
+ <code>vcpupin</code> specified, it will be pinned to the physical
+ CPUs specified by <code>cpuset</code> here).
+ Each element in that list is either a single CPU number,
a range of CPU numbers, or a caret followed by a CPU number to
be excluded from a previous range. <span class="since">Since
0.8.5</span>, the optional attribute <code>current</code> can
@@ -374,8 +384,7 @@
if it's specified. If both <code>cpuset</code> and <code>placement</code>
are not specified, or if <code>placement</code> is "static", but no
<code>cpuset</code> is specified, the domain process will be pinned to
- all the available physical CPUs. These settings are superseded
- by <a href="#elementsCPUTuning">CPU tuning</a>.
+ all the available physical CPUs.
</dd>
</dl>
@@ -411,23 +420,26 @@
<dt><code>vcpupin</code></dt>
<dd>
The optional <code>vcpupin</code> element specifies which of host's
- physical CPUs the domain VCPU will be pinned to. This setting supersedes
- previous VCPU placement specified in <a href="#elementsCPUAllocation">CPU
- Allocation</a> using <code>vcpu</code> element. If this is omitted,
- each VCPU is pinned to all the physical CPUs by default. It contains two
- required attributes, the attribute <code>vcpu</code> specifies vcpu id,
- and the attribute <code>cpuset</code> is same as
- attribute <code>cpuset</code>
- of element <code>vcpu</code>. (NB: Only qemu driver support)
+ physical CPUs the domain VCPU will be pinned to. If this is omitted,
+ and attribute <code>cpuset</code> of element <code>vcpu</code> is
+ not specified, the vCPU is pinned to all the physical CPUs by default.
+ It contains two required attributes, the attribute <code>vcpu</code>
+ specifies vcpu id, and the attribute <code>cpuset</code> is same as
+ attribute <code>cpuset</code> of element <code>vcpu</code>.
+ (NB: Only qemu driver support)
<span class="since">Since 0.9.0</span>
</dd>
<dt><code>emulatorpin</code></dt>
<dd>
The optional <code>emulatorpin</code> element specifies which of host
physical CPUs the "emulator", a subset of a domain not including vcpu,
- will be pinned to. If this is omitted, "emulator" is pinned to all
- the physical CPUs by default. It contains one required attribute
- <code>cpuset</code> specifying which physical CPUs to pin to.
+ will be pinned to. If this is omitted, and attribute
+ <code>cpuset</code> of element <code>vcpu</code> is not specified,
+ "emulator" is pinned to all the physical CPUs by default. It contains
+ one required attribute <code>cpuset</code> specifying which physical
+ CPUs to pin to. NB, <code>emulatorpin</code> is not allowed if
+ attribute <code>placement</code> of element <code>vcpu</code> is
+ "auto".
</dd>
<dt><code>shares</code></dt>
<dd>
--
1.7.7.6
12 years, 1 month
[libvirt] Some questions about virConnectAuthCallbackPtr
by Richard W.M. Jones
Some questions which seem to be left ambigious by the documentation
for virConnectAuthCallbackPtr:
http://libvirt.org/html/libvirt-libvirt.html#virConnectAuthCallbackPtr
(1) For a single open, can this be called multiple times? I'm
thinking, some authentication methods might give the user N attempts
at typing the password, which might result in N callbacks here.
(2) The documentation says: "Returns: 0 if all interactions were
filled, or -1 upon error". However it also says "If an interaction
cannot be filled, fill in NULL and 0". Does that mean it's OK (not an
error, return 0) if a result field is set to NULL?
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://et.redhat.com/~rjones/virt-top
12 years, 1 month
[libvirt] [PATCH 0/3] Add option to selectively enable IPv4/v6 forwarding
by Benjamin Cama
Hi,
Currently, when IP forwarding is enabled in a network element, libvirt enables
forwarding for IPv4/v6 on the OS if the bridge has some IP address of that
family. In some circumstances, one could only want forwarding for one family
and not the other, even if both address families are present; for example,
forwarding only IPv6 but still have some RFC1918 addresses on the “local”
network as a backup stack, or playing with IPv6 using (not forwarded) ULA
addresses, having some IPv4 NATed forwarding, without loosing IPv6 connectivity
because enabling it will disable auto-configuration (my case).
This patch adds a new optional "family" attribute to the "forward" element,
allowing selective forwarding: it can be set to "ipv4" or "ipv6". If not
present, the usual behavior of libvirt is kept, forwarding trafic for whichever
family there is an address on the bridge.
The first patch also remove libvirt's ability to set forwarding; I think it
should only check for it, letting the administrator enable it the usual way
(/etc/sysctl.conf or wathever) if he really wants it. In my case, this behavior
caused me to loose IPv6 connectivity when adding some ULA addresse to my VMs
bridge, because IPv6 forwarding was enabled in my back.
Regards,
Benjamin Cama (3):
Only check for IP forwarding, do not enable it
Add a "forward family" option
Take the forwarding family into account
src/conf/network_conf.c | 58 ++++++++++++++++++++++++++++++-
src/conf/network_conf.h | 1 +
src/network/bridge_driver.c | 81 +++++++++++++++++++++++++++++++++---------
3 files changed, 121 insertions(+), 19 deletions(-)
--
1.7.2.5
12 years, 1 month
[libvirt] [PATCHv3] Add support for SUSPEND_DISK event
by Martin Kletzander
This patch adds support for SUSPEND_DISK event; both lifecycle and
separated. The support is added for QEMU, machines are changed to
PMSUSPENDED, but as QEMU sends SHUTDOWN afterwards, the state changes
to shut-off. This and much more needs to be done in order for libvirt
to work with transient devices, wake-ups etc. This patch is not
aiming for that functionality.
---
daemon/remote.c | 25 +++++++++++
examples/domain-events/events-c/event-test.c | 22 +++++++++-
examples/domain-events/events-python/event-test.py | 3 +-
include/libvirt/libvirt.h.in | 29 +++++++++++++
python/libvirt-override-virConnect.py | 9 ++++
python/libvirt-override.c | 50 ++++++++++++++++++++++
src/conf/domain_event.c | 30 ++++++++++++-
src/conf/domain_event.h | 4 ++
src/libvirt_private.syms | 2 +
src/qemu/qemu_monitor.c | 10 +++++
src/qemu/qemu_monitor.h | 3 ++
src/qemu/qemu_monitor_json.c | 9 ++++
src/qemu/qemu_process.c | 47 ++++++++++++++++++++
src/remote/remote_driver.c | 31 ++++++++++++++
src/remote/remote_protocol.x | 7 ++-
src/remote_protocol-structs | 4 ++
16 files changed, 281 insertions(+), 4 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index e7fe128..2d3f401 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -608,6 +608,30 @@ remoteRelayDomainEventBalloonChange(virConnectPtr conn ATTRIBUTE_UNUSED,
}
+static int remoteRelayDomainEventPMSuspendDisk(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque) {
+ virNetServerClientPtr client = opaque;
+ remote_domain_event_pmsuspend_disk_msg data;
+
+ if (!client)
+ return -1;
+
+ VIR_DEBUG("Relaying domain %s %d system suspend-disk", dom->name, dom->id);
+
+ /* build return data */
+ memset(&data, 0, sizeof(data));
+ make_nonnull_domain(&data.dom, dom);
+
+ remoteDispatchDomainEventSend(client, remoteProgram,
+ REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK,
+ (xdrproc_t)xdr_remote_domain_event_pmsuspend_disk_msg, &data);
+
+ return 0;
+}
+
+
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
@@ -623,6 +647,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMWakeup),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMSuspend),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBalloonChange),
+ VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMSuspendDisk),
};
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c
index cde60fb..94104a0 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -201,6 +201,9 @@ static const char *eventDetailToString(int event, int detail) {
case VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY:
ret = "Memory";
break;
+ case VIR_DOMAIN_EVENT_PMSUSPENDED_DISK:
+ ret = "Disk";
+ break;
}
break;
}
@@ -402,6 +405,16 @@ static int myDomainEventPMSuspendCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
return 0;
}
+static int myDomainEventPMSuspendDiskCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) system suspend-disk\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom));
+ return 0;
+}
+
static void myFreeFunc(void *opaque)
{
char *str = opaque;
@@ -440,6 +453,7 @@ int main(int argc, char **argv)
int callback11ret = -1;
int callback12ret = -1;
int callback13ret = -1;
+ int callback14ret = -1;
struct sigaction action_stop;
memset(&action_stop, 0, sizeof(action_stop));
@@ -533,6 +547,11 @@ int main(int argc, char **argv)
VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventBalloonChangeCallback),
strdup("callback balloonchange"), myFreeFunc);
+ callback14ret = virConnectDomainEventRegisterAny(dconn,
+ NULL,
+ VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK,
+ VIR_DOMAIN_EVENT_CALLBACK(myDomainEventPMSuspendDiskCallback),
+ strdup("suspend-disk"), myFreeFunc);
if ((callback1ret != -1) &&
(callback2ret != -1) &&
(callback3ret != -1) &&
@@ -544,7 +563,8 @@ int main(int argc, char **argv)
(callback10ret != -1) &&
(callback11ret != -1) &&
(callback12ret != -1) &&
- (callback13ret != -1)) {
+ (callback13ret != -1) &&
+ (callback14ret != -1)) {
if (virConnectSetKeepAlive(dconn, 5, 3) < 0) {
virErrorPtr err = virGetLastError();
fprintf(stderr, "Failed to start keepalive protocol: %s\n",
diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py
index 27e74c4..813b1c2 100644
--- a/examples/domain-events/events-python/event-test.py
+++ b/examples/domain-events/events-python/event-test.py
@@ -449,7 +449,7 @@ def detailToString(event, detail):
( "Unpaused", "Migrated", "Snapshot" ),
( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot"),
( "Finished", ),
- ( "Memory", )
+ ( "Memory", "Disk" )
)
return eventStrings[event][detail]
@@ -554,6 +554,7 @@ def main():
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback, None)
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND, myDomainEventPMSuspendCallback, None)
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE, myDomainEventBalloonChangeCallback, None)
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK, myDomainEventPMSuspendDiskCallback, None)
vc.setKeepAlive(5, 3)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index a4e8ca9..5858c44 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -225,6 +225,14 @@ typedef enum {
#endif
} virDomainPMSuspendedReason;
+typedef enum {
+ VIR_DOMAIN_PMSUSPENDED_DISK_UNKNOWN = 0,
+
+#ifdef VIR_ENUM_SENTINELS
+ VIR_DOMAIN_PMSUSPENDED_DISK_LAST
+#endif
+} virDomainPMSuspendedDiskReason;
+
/**
* virDomainControlState:
*
@@ -3114,6 +3122,7 @@ typedef enum {
*/
typedef enum {
VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY = 0, /* Guest was PM suspended to memory */
+ VIR_DOMAIN_EVENT_PMSUSPENDED_DISK = 1, /* Guest was PM suspended to disk */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_PMSUSPENDED_LAST
@@ -4164,6 +4173,25 @@ typedef void (*virConnectDomainEventBalloonChangeCallback)(virConnectPtr conn,
void *opaque);
/**
+ * virConnectDomainEventPMSuspendDiskCallback:
+ * @conn: connection object
+ * @dom: domain on which the event occurred
+ * @reason: reason why the callback was called, unused currently,
+ * always passes 0
+ * @opaque: application specified data
+ *
+ * This callback occurs when the guest is suspended to disk.
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK with virConnectDomainEventRegisterAny()
+ */
+typedef void (*virConnectDomainEventPMSuspendDiskCallback)(virConnectPtr conn,
+ virDomainPtr dom,
+ int reason,
+ void *opaque);
+
+
+/**
* VIR_DOMAIN_EVENT_CALLBACK:
*
* Used to cast the event specific callback into the generic one
@@ -4187,6 +4215,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_PMWAKEUP = 11, /* virConnectDomainEventPMWakeupCallback */
VIR_DOMAIN_EVENT_ID_PMSUSPEND = 12, /* virConnectDomainEventPMSuspendCallback */
VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE = 13, /* virConnectDomainEventBalloonChangeCallback */
+ VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK = 14, /* virConnectDomainEventPMSuspendDiskCallback */
#ifdef VIR_ENUM_SENTINELS
/*
diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py
index 6bec66d..00bfcaf 100644
--- a/python/libvirt-override-virConnect.py
+++ b/python/libvirt-override-virConnect.py
@@ -170,6 +170,15 @@
cb(self, virDomain(self, _obj=dom), actual, opaque)
return 0
+ def _dispatchDomainEventPMSuspendDiskCallback(self, dom, reason, cbData):
+ """Dispatches event to python user domain suspend-disk event callbacks
+ """
+ cb = cbData["cb"]
+ opaque = cbData["opaque"]
+
+ cb(self, virDomain(self, _obj=dom), reason, opaque)
+ return 0;
+
def domainEventDeregisterAny(self, callbackID):
"""Removes a Domain Event Callback. De-registering for a
domain callback will disable delivery of this event type """
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 81099b1..83dc925 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -5812,6 +5812,53 @@ libvirt_virConnectDomainEventBalloonChangeCallback(virConnectPtr conn ATTRIBUTE_
return ret;
}
+static int
+libvirt_virConnectDomainEventPMSuspendDiskCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason,
+ void *opaque)
+{
+ PyObject *pyobj_cbData = (PyObject*)opaque;
+ PyObject *pyobj_dom;
+ PyObject *pyobj_ret;
+ PyObject *pyobj_conn;
+ PyObject *dictKey;
+ int ret = -1;
+
+ LIBVIRT_ENSURE_THREAD_STATE;
+ /* Create a python instance of this virDomainPtr */
+ virDomainRef(dom);
+
+ pyobj_dom = libvirt_virDomainPtrWrap(dom);
+ Py_INCREF(pyobj_cbData);
+
+ dictKey = libvirt_constcharPtrWrap("conn");
+ pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey);
+ Py_DECREF(dictKey);
+
+ /* Call the Callback Dispatcher */
+ pyobj_ret = PyObject_CallMethod(pyobj_conn,
+ (char*)"_dispatchDomainEventPMSuspendDiskCallback",
+ (char*)"OiO",
+ pyobj_dom,
+ reason,
+ pyobj_cbData);
+
+ Py_DECREF(pyobj_cbData);
+ Py_DECREF(pyobj_dom);
+
+ if(!pyobj_ret) {
+ DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
+ PyErr_Print();
+ } else {
+ Py_DECREF(pyobj_ret);
+ ret = 0;
+ }
+
+ LIBVIRT_RELEASE_THREAD_STATE;
+ return ret;
+}
+
static PyObject *
libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
PyObject * args)
@@ -5884,6 +5931,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventBalloonChangeCallback);
break;
+ case VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK:
+ cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMSuspendDiskCallback);
+ break;
}
if (!cb) {
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 7da4a1e..062752a 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -1,7 +1,7 @@
/*
* domain_event.c: domain event queue processing helpers
*
- * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010-2012 Red Hat, Inc.
* Copyright (C) 2008 VirtualIron
*
* This library is free software; you can redistribute it and/or
@@ -1125,6 +1125,30 @@ virDomainEventPMSuspendNewFromDom(virDomainPtr dom)
return virDomainEventPMSuspendNew(dom->id, dom->name, dom->uuid);
}
+static virDomainEventPtr
+virDomainEventPMSuspendDiskNew(int id, const char *name,
+ unsigned char *uuid)
+{
+ virDomainEventPtr ev =
+ virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK,
+ id, name, uuid);
+ return ev;
+}
+
+virDomainEventPtr
+virDomainEventPMSuspendDiskNewFromObj(virDomainObjPtr obj)
+{
+ return virDomainEventPMSuspendDiskNew(obj->def->id,
+ obj->def->name,
+ obj->def->uuid);
+}
+
+virDomainEventPtr
+virDomainEventPMSuspendDiskNewFromDom(virDomainPtr dom)
+{
+ return virDomainEventPMSuspendDiskNew(dom->id, dom->name, dom->uuid);
+}
+
virDomainEventPtr virDomainEventBalloonChangeNewFromDom(virDomainPtr dom,
unsigned long long actual)
{
@@ -1294,6 +1318,10 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
cbopaque);
break;
+ case VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK:
+ ((virConnectDomainEventPMSuspendDiskCallback)cb)(conn, dom, 0, cbopaque);
+ break;
+
default:
VIR_WARN("Unexpected event ID %d", event->eventID);
break;
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index 995b655..5f64a47 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -1,6 +1,7 @@
/*
* domain_event.h: domain event queue processing helpers
*
+ * Copyright (C) 2012 Red Hat, Inc.
* Copyright (C) 2008 VirtualIron
*
* This library is free software; you can redistribute it and/or
@@ -128,6 +129,9 @@ virDomainEventPtr virDomainEventPMSuspendNewFromDom(virDomainPtr dom);
virDomainEventPtr virDomainEventBalloonChangeNewFromDom(virDomainPtr dom, unsigned long long actual);
virDomainEventPtr virDomainEventBalloonChangeNewFromObj(virDomainObjPtr obj, unsigned long long actual);
+virDomainEventPtr virDomainEventPMSuspendDiskNewFromObj(virDomainObjPtr obj);
+virDomainEventPtr virDomainEventPMSuspendDiskNewFromDom(virDomainPtr dom);
+
void virDomainEventFree(virDomainEventPtr event);
void virDomainEventStateFree(virDomainEventStatePtr state);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fe31bbe..fdf4b8b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -585,6 +585,8 @@ virDomainEventStateRegisterID;
virDomainEventStateFree;
virDomainEventStateNew;
virDomainEventStateQueue;
+virDomainEventPMSuspendDiskNewFromDom;
+virDomainEventPMSuspendDiskNewFromObj;
virDomainEventTrayChangeNewFromDom;
virDomainEventTrayChangeNewFromObj;
virDomainEventWatchdogNewFromDom;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 85b0bc2..4313451 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1111,6 +1111,16 @@ int qemuMonitorEmitPMSuspend(qemuMonitorPtr mon)
return ret;
}
+int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon)
+{
+ int ret = -1;
+ VIR_DEBUG("mon=%p", mon);
+
+ QEMU_MONITOR_CALLBACK(mon, ret, domainPMSuspendDisk, mon->vm);
+
+ return ret;
+}
+
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
const char *diskAlias,
int type,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 54b3a99..f33b94c 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -136,6 +136,8 @@ struct _qemuMonitorCallbacks {
int (*domainBalloonChange)(qemuMonitorPtr mon,
virDomainObjPtr vm,
unsigned long long actual);
+ int (*domainPMSuspendDisk)(qemuMonitorPtr mon,
+ virDomainObjPtr vm);
};
char *qemuMonitorEscapeArg(const char *in);
@@ -213,6 +215,7 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
int status);
int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
unsigned long long actual);
+int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon);
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
virConnectPtr conn);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index bd52ce4..c35948e 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -70,6 +70,7 @@ static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr d
static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValuePtr data);
+static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data);
typedef struct {
const char *type;
@@ -91,6 +92,7 @@ static qemuEventHandler eventHandlers[] = {
{ "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
{ "STOP", qemuMonitorJSONHandleStop, },
{ "SUSPEND", qemuMonitorJSONHandlePMSuspend, },
+ { "SUSPEND_DISK", qemuMonitorJSONHandlePMSuspendDisk, },
{ "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
{ "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
{ "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
@@ -891,6 +893,13 @@ qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon,
qemuMonitorEmitBalloonChange(mon, actual);
}
+static void
+qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon,
+ virJSONValuePtr data ATTRIBUTE_UNUSED)
+{
+ qemuMonitorEmitPMSuspendDisk(mon);
+}
+
int
qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
const char *cmd_str,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f8a2bfd..4c6c7d7 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1178,6 +1178,52 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
return 0;
}
+static int
+qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm)
+{
+ struct qemud_driver *driver = qemu_driver;
+ virDomainEventPtr event = NULL;
+ virDomainEventPtr lifecycleEvent = NULL;
+
+ virDomainObjLock(vm);
+ event = virDomainEventPMSuspendDiskNewFromObj(vm);
+
+ if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ VIR_DEBUG("Transitioned guest %s to pmsuspended state due to "
+ "QMP suspend_disk event", vm->def->name);
+
+ virDomainObjSetState(vm, VIR_DOMAIN_PMSUSPENDED,
+ VIR_DOMAIN_PMSUSPENDED_UNKNOWN);
+ lifecycleEvent =
+ virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_PMSUSPENDED,
+ VIR_DOMAIN_EVENT_PMSUSPENDED_DISK);
+
+ if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+ VIR_WARN("Unable to save status on vm %s after suspend event",
+ vm->def->name);
+ }
+
+ if (priv->agent)
+ qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND);
+ }
+
+ virDomainObjUnlock(vm);
+
+ if (event || lifecycleEvent) {
+ qemuDriverLock(driver);
+ if (event)
+ qemuDomainEventQueue(driver, event);
+ if (lifecycleEvent)
+ qemuDomainEventQueue(driver, lifecycleEvent);
+ qemuDriverUnlock(driver);
+ }
+
+ return 0;
+}
+
static qemuMonitorCallbacks monitorCallbacks = {
.destroy = qemuProcessHandleMonitorDestroy,
@@ -1196,6 +1242,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.domainPMWakeup = qemuProcessHandlePMWakeup,
.domainPMSuspend = qemuProcessHandlePMSuspend,
.domainBalloonChange = qemuProcessHandleBalloonChange,
+ .domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
};
static int
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index fc4c696..3253de7 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -253,6 +253,10 @@ static void
remoteDomainBuildEventBalloonChange(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
+static void
+remoteDomainBuildEventPMSuspendDisk(virNetClientProgramPtr prog,
+ virNetClientPtr client,
+ void *evdata, void *opaque);
static virNetClientProgramEvent remoteDomainEvents[] = {
{ REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
@@ -311,6 +315,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = {
remoteDomainBuildEventBalloonChange,
sizeof(remote_domain_event_balloon_change_msg),
(xdrproc_t)xdr_remote_domain_event_balloon_change_msg },
+ { REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK,
+ remoteDomainBuildEventPMSuspendDisk,
+ sizeof(remote_domain_event_pmsuspend_disk_msg),
+ (xdrproc_t)xdr_remote_domain_event_pmsuspend_disk_msg },
};
enum virDrvOpenRemoteFlags {
@@ -4575,6 +4583,29 @@ remoteDomainBuildEventBalloonChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
}
+static void
+remoteDomainBuildEventPMSuspendDisk(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
+ virNetClientPtr client ATTRIBUTE_UNUSED,
+ void *evdata, void *opaque)
+{
+ virConnectPtr conn = opaque;
+ struct private_data *priv = conn->privateData;
+ remote_domain_event_pmsuspend_disk_msg *msg = evdata;
+ virDomainPtr dom;
+ virDomainEventPtr event = NULL;
+
+ dom = get_nonnull_domain(conn, msg->dom);
+ if (!dom)
+ return;
+
+ event = virDomainEventPMSuspendDiskNewFromDom(dom);
+
+ virDomainFree(dom);
+
+ remoteDomainEventQueue(priv, event);
+}
+
+
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth,
unsigned int flags)
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index b0b530c..4359c82 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2259,6 +2259,10 @@ struct remote_domain_event_balloon_change_msg {
unsigned hyper actual;
};
+struct remote_domain_event_pmsuspend_disk_msg {
+ remote_nonnull_domain dom;
+};
+
struct remote_domain_managed_save_args {
remote_nonnull_domain dom;
unsigned int flags;
@@ -3008,7 +3012,8 @@ enum remote_procedure {
REMOTE_PROC_NODE_GET_MEMORY_PARAMETERS = 289, /* skipgen skipgen */
REMOTE_PROC_DOMAIN_BLOCK_COMMIT = 290, /* autogen autogen */
- REMOTE_PROC_NETWORK_UPDATE = 291 /* autogen autogen priority:high */
+ REMOTE_PROC_NETWORK_UPDATE = 291, /* autogen autogen priority:high */
+ REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK = 292 /* autogen autogen */
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 4d2627a..0c0a317 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1718,6 +1718,9 @@ struct remote_domain_event_balloon_change_msg {
remote_nonnull_domain dom;
uint64_t actual;
};
+struct remote_domain_event_pmsuspend_disk_msg {
+ remote_nonnull_domain dom;
+};
struct remote_domain_managed_save_args {
remote_nonnull_domain dom;
u_int flags;
@@ -2415,4 +2418,5 @@ enum remote_procedure {
REMOTE_PROC_NODE_GET_MEMORY_PARAMETERS = 289,
REMOTE_PROC_DOMAIN_BLOCK_COMMIT = 290,
REMOTE_PROC_NETWORK_UPDATE = 291,
+ REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK = 292,
};
--
1.7.12.3
12 years, 1 month
[libvirt] [PATCH] Add support for SUSPEND_DISK event
by Martin Kletzander
This patch adds support for SUSPEND_DISK event; both lifecycle and
separated. The support is added for QEMU, machines are changed to
PMSUSPENDED, but as QEMU sends SHUTDOWN afterwards, the state changes
to shut-off. This and much more needs to be done in order for libvirt
to work with transient devices, wake-ups etc. This patch is not
aiming for that functionality.
---
daemon/remote.c | 25 +++++++++++
examples/domain-events/events-c/event-test.c | 22 +++++++++-
examples/domain-events/events-python/event-test.py | 3 +-
include/libvirt/libvirt.h.in | 29 +++++++++++++
python/libvirt-override-virConnect.py | 9 ++++
python/libvirt-override.c | 50 ++++++++++++++++++++++
src/conf/domain_event.c | 32 +++++++++++++-
src/conf/domain_event.h | 4 ++
src/libvirt_private.syms | 2 +
src/qemu/qemu_monitor.c | 10 +++++
src/qemu/qemu_monitor.h | 3 ++
src/qemu/qemu_monitor_json.c | 9 ++++
src/qemu/qemu_process.c | 47 ++++++++++++++++++++
src/remote/remote_driver.c | 31 ++++++++++++++
src/remote/remote_protocol.x | 7 ++-
src/remote_protocol-structs | 4 ++
16 files changed, 282 insertions(+), 5 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index e7fe128..58017e5 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -608,6 +608,30 @@ remoteRelayDomainEventBalloonChange(virConnectPtr conn ATTRIBUTE_UNUSED,
}
+static int remoteRelayDomainEventSuspendDisk(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque) {
+ virNetServerClientPtr client = opaque;
+ remote_domain_event_suspend_disk_msg data;
+
+ if (!client)
+ return -1;
+
+ VIR_DEBUG("Relaying domain %s %d system suspend-disk", dom->name, dom->id);
+
+ /* build return data */
+ memset(&data, 0, sizeof(data));
+ make_nonnull_domain(&data.dom, dom);
+
+ remoteDispatchDomainEventSend(client, remoteProgram,
+ REMOTE_PROC_DOMAIN_EVENT_SUSPEND_DISK,
+ (xdrproc_t)xdr_remote_domain_event_suspend_disk_msg, &data);
+
+ return 0;
+}
+
+
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
@@ -623,6 +647,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMWakeup),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMSuspend),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBalloonChange),
+ VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventSuspendDisk),
};
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c
index cde60fb..856eb4f 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -201,6 +201,9 @@ static const char *eventDetailToString(int event, int detail) {
case VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY:
ret = "Memory";
break;
+ case VIR_DOMAIN_EVENT_PMSUSPENDED_DISK:
+ ret = "Disk";
+ break;
}
break;
}
@@ -402,6 +405,16 @@ static int myDomainEventPMSuspendCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
return 0;
}
+static int myDomainEventSuspendDiskCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) system suspend-disk\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom));
+ return 0;
+}
+
static void myFreeFunc(void *opaque)
{
char *str = opaque;
@@ -440,6 +453,7 @@ int main(int argc, char **argv)
int callback11ret = -1;
int callback12ret = -1;
int callback13ret = -1;
+ int callback14ret = -1;
struct sigaction action_stop;
memset(&action_stop, 0, sizeof(action_stop));
@@ -533,6 +547,11 @@ int main(int argc, char **argv)
VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventBalloonChangeCallback),
strdup("callback balloonchange"), myFreeFunc);
+ callback14ret = virConnectDomainEventRegisterAny(dconn,
+ NULL,
+ VIR_DOMAIN_EVENT_ID_SUSPEND_DISK,
+ VIR_DOMAIN_EVENT_CALLBACK(myDomainEventSuspendDiskCallback),
+ strdup("suspend-disk"), myFreeFunc);
if ((callback1ret != -1) &&
(callback2ret != -1) &&
(callback3ret != -1) &&
@@ -544,7 +563,8 @@ int main(int argc, char **argv)
(callback10ret != -1) &&
(callback11ret != -1) &&
(callback12ret != -1) &&
- (callback13ret != -1)) {
+ (callback13ret != -1) &&
+ (callback14ret != -1)) {
if (virConnectSetKeepAlive(dconn, 5, 3) < 0) {
virErrorPtr err = virGetLastError();
fprintf(stderr, "Failed to start keepalive protocol: %s\n",
diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py
index 27e74c4..bf11fb9 100644
--- a/examples/domain-events/events-python/event-test.py
+++ b/examples/domain-events/events-python/event-test.py
@@ -449,7 +449,7 @@ def detailToString(event, detail):
( "Unpaused", "Migrated", "Snapshot" ),
( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot"),
( "Finished", ),
- ( "Memory", )
+ ( "Memory", "Disk" )
)
return eventStrings[event][detail]
@@ -554,6 +554,7 @@ def main():
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback, None)
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND, myDomainEventPMSuspendCallback, None)
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE, myDomainEventBalloonChangeCallback, None)
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_SUSPEND_DISK, myDomainEventSuspendDiskCallback, None)
vc.setKeepAlive(5, 3)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index a4e8ca9..422819c 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -225,6 +225,14 @@ typedef enum {
#endif
} virDomainPMSuspendedReason;
+typedef enum {
+ VIR_DOMAIN_SUSPENDED_DISK_UNKNOWN = 0,
+
+#ifdef VIR_ENUM_SENTINELS
+ VIR_DOMAIN_SUSPENDED_DISK_LAST
+#endif
+} virDomainSuspendedDiskReason;
+
/**
* virDomainControlState:
*
@@ -3114,6 +3122,7 @@ typedef enum {
*/
typedef enum {
VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY = 0, /* Guest was PM suspended to memory */
+ VIR_DOMAIN_EVENT_PMSUSPENDED_DISK = 1, /* Guest was PM suspended to disk */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_PMSUSPENDED_LAST
@@ -4164,6 +4173,25 @@ typedef void (*virConnectDomainEventBalloonChangeCallback)(virConnectPtr conn,
void *opaque);
/**
+ * virConnectDomainEventSuspendDiskCallback:
+ * @conn: connection object
+ * @dom: domain on which the event occurred
+ * @reason: reason why the callback was called, unused currently,
+ * always passes 0
+ * @opaque: application specified data
+ *
+ * This callback occurs when the guest is suspended to disk.
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_DOMAIN_EVENT_ID_SUSPEND_DISK with virConnectDomainEventRegisterAny()
+ */
+typedef void (*virConnectDomainEventSuspendDiskCallback)(virConnectPtr conn,
+ virDomainPtr dom,
+ int reason,
+ void *opaque);
+
+
+/**
* VIR_DOMAIN_EVENT_CALLBACK:
*
* Used to cast the event specific callback into the generic one
@@ -4187,6 +4215,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_PMWAKEUP = 11, /* virConnectDomainEventPMWakeupCallback */
VIR_DOMAIN_EVENT_ID_PMSUSPEND = 12, /* virConnectDomainEventPMSuspendCallback */
VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE = 13, /* virConnectDomainEventBalloonChangeCallback */
+ VIR_DOMAIN_EVENT_ID_SUSPEND_DISK = 14, /* virConnectDomainEventSuspendDiskCallback */
#ifdef VIR_ENUM_SENTINELS
/*
diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py
index 6bec66d..3136841 100644
--- a/python/libvirt-override-virConnect.py
+++ b/python/libvirt-override-virConnect.py
@@ -170,6 +170,15 @@
cb(self, virDomain(self, _obj=dom), actual, opaque)
return 0
+ def _dispatchDomainEventSuspendDiskCallback(self, dom, reason, cbData):
+ """Dispatches event to python user domain suspend-disk event callbacks
+ """
+ cb = cbData["cb"]
+ opaque = cbData["opaque"]
+
+ cb(self, virDomain(self, _obj=dom), reason, opaque)
+ return 0;
+
def domainEventDeregisterAny(self, callbackID):
"""Removes a Domain Event Callback. De-registering for a
domain callback will disable delivery of this event type """
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 81099b1..bc73ad0 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -5812,6 +5812,53 @@ libvirt_virConnectDomainEventBalloonChangeCallback(virConnectPtr conn ATTRIBUTE_
return ret;
}
+static int
+libvirt_virConnectDomainEventSuspendDiskCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason,
+ void *opaque)
+{
+ PyObject *pyobj_cbData = (PyObject*)opaque;
+ PyObject *pyobj_dom;
+ PyObject *pyobj_ret;
+ PyObject *pyobj_conn;
+ PyObject *dictKey;
+ int ret = -1;
+
+ LIBVIRT_ENSURE_THREAD_STATE;
+ /* Create a python instance of this virDomainPtr */
+ virDomainRef(dom);
+
+ pyobj_dom = libvirt_virDomainPtrWrap(dom);
+ Py_INCREF(pyobj_cbData);
+
+ dictKey = libvirt_constcharPtrWrap("conn");
+ pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey);
+ Py_DECREF(dictKey);
+
+ /* Call the Callback Dispatcher */
+ pyobj_ret = PyObject_CallMethod(pyobj_conn,
+ (char*)"_dispatchDomainEventSuspendDiskCallback",
+ (char*)"OiO",
+ pyobj_dom,
+ reason,
+ pyobj_cbData);
+
+ Py_DECREF(pyobj_cbData);
+ Py_DECREF(pyobj_dom);
+
+ if(!pyobj_ret) {
+ DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
+ PyErr_Print();
+ } else {
+ Py_DECREF(pyobj_ret);
+ ret = 0;
+ }
+
+ LIBVIRT_RELEASE_THREAD_STATE;
+ return ret;
+}
+
static PyObject *
libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
PyObject * args)
@@ -5884,6 +5931,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventBalloonChangeCallback);
break;
+ case VIR_DOMAIN_EVENT_ID_SUSPEND_DISK:
+ cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventSuspendDiskCallback);
+ break;
}
if (!cb) {
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 7da4a1e..c7010c8 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -1,7 +1,7 @@
/*
* domain_event.c: domain event queue processing helpers
*
- * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010-2012 Red Hat, Inc.
* Copyright (C) 2008 VirtualIron
*
* This library is free software; you can redistribute it and/or
@@ -1107,10 +1107,10 @@ virDomainEventPMSuspendNew(int id, const char *name,
virDomainEventPtr ev =
virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_PMSUSPEND,
id, name, uuid);
-
return ev;
}
+
virDomainEventPtr
virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj)
{
@@ -1125,6 +1125,30 @@ virDomainEventPMSuspendNewFromDom(virDomainPtr dom)
return virDomainEventPMSuspendNew(dom->id, dom->name, dom->uuid);
}
+static virDomainEventPtr
+virDomainEventSuspendDiskNew(int id, const char *name,
+ unsigned char *uuid)
+{
+ virDomainEventPtr ev =
+ virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_SUSPEND_DISK,
+ id, name, uuid);
+ return ev;
+}
+
+virDomainEventPtr
+virDomainEventSuspendDiskNewFromObj(virDomainObjPtr obj)
+{
+ return virDomainEventSuspendDiskNew(obj->def->id,
+ obj->def->name,
+ obj->def->uuid);
+}
+
+virDomainEventPtr
+virDomainEventSuspendDiskNewFromDom(virDomainPtr dom)
+{
+ return virDomainEventSuspendDiskNew(dom->id, dom->name, dom->uuid);
+}
+
virDomainEventPtr virDomainEventBalloonChangeNewFromDom(virDomainPtr dom,
unsigned long long actual)
{
@@ -1294,6 +1318,10 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
cbopaque);
break;
+ case VIR_DOMAIN_EVENT_ID_SUSPEND_DISK:
+ ((virConnectDomainEventSuspendDiskCallback)cb)(conn, dom, 0, cbopaque);
+ break;
+
default:
VIR_WARN("Unexpected event ID %d", event->eventID);
break;
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index 995b655..173eba8 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -1,6 +1,7 @@
/*
* domain_event.h: domain event queue processing helpers
*
+ * Copyright (C) 2012 Red Hat, Inc.
* Copyright (C) 2008 VirtualIron
*
* This library is free software; you can redistribute it and/or
@@ -128,6 +129,9 @@ virDomainEventPtr virDomainEventPMSuspendNewFromDom(virDomainPtr dom);
virDomainEventPtr virDomainEventBalloonChangeNewFromDom(virDomainPtr dom, unsigned long long actual);
virDomainEventPtr virDomainEventBalloonChangeNewFromObj(virDomainObjPtr obj, unsigned long long actual);
+virDomainEventPtr virDomainEventSuspendDiskNewFromObj(virDomainObjPtr obj);
+virDomainEventPtr virDomainEventSuspendDiskNewFromDom(virDomainPtr dom);
+
void virDomainEventFree(virDomainEventPtr event);
void virDomainEventStateFree(virDomainEventStatePtr state);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fe31bbe..c1f08e0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -585,6 +585,8 @@ virDomainEventStateRegisterID;
virDomainEventStateFree;
virDomainEventStateNew;
virDomainEventStateQueue;
+virDomainEventSuspendDiskNewFromDom;
+virDomainEventSuspendDiskNewFromObj;
virDomainEventTrayChangeNewFromDom;
virDomainEventTrayChangeNewFromObj;
virDomainEventWatchdogNewFromDom;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 85b0bc2..b0fa682 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1111,6 +1111,16 @@ int qemuMonitorEmitPMSuspend(qemuMonitorPtr mon)
return ret;
}
+int qemuMonitorEmitSuspendDisk(qemuMonitorPtr mon)
+{
+ int ret = -1;
+ VIR_DEBUG("mon=%p", mon);
+
+ QEMU_MONITOR_CALLBACK(mon, ret, domainSuspendDisk, mon->vm);
+
+ return ret;
+}
+
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
const char *diskAlias,
int type,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 54b3a99..f4dc94f 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -136,6 +136,8 @@ struct _qemuMonitorCallbacks {
int (*domainBalloonChange)(qemuMonitorPtr mon,
virDomainObjPtr vm,
unsigned long long actual);
+ int (*domainSuspendDisk)(qemuMonitorPtr mon,
+ virDomainObjPtr vm);
};
char *qemuMonitorEscapeArg(const char *in);
@@ -213,6 +215,7 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
int status);
int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
unsigned long long actual);
+int qemuMonitorEmitSuspendDisk(qemuMonitorPtr mon);
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
virConnectPtr conn);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index bd52ce4..d0fd23a 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -70,6 +70,7 @@ static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr d
static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValuePtr data);
+static void qemuMonitorJSONHandleSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data);
typedef struct {
const char *type;
@@ -91,6 +92,7 @@ static qemuEventHandler eventHandlers[] = {
{ "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
{ "STOP", qemuMonitorJSONHandleStop, },
{ "SUSPEND", qemuMonitorJSONHandlePMSuspend, },
+ { "SUSPEND_DISK", qemuMonitorJSONHandleSuspendDisk, },
{ "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
{ "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
{ "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
@@ -891,6 +893,13 @@ qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon,
qemuMonitorEmitBalloonChange(mon, actual);
}
+static void
+qemuMonitorJSONHandleSuspendDisk(qemuMonitorPtr mon,
+ virJSONValuePtr data ATTRIBUTE_UNUSED)
+{
+ qemuMonitorEmitSuspendDisk(mon);
+}
+
int
qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
const char *cmd_str,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f8a2bfd..02beb5d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1178,6 +1178,52 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
return 0;
}
+static int
+qemuProcessHandleSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm)
+{
+ struct qemud_driver *driver = qemu_driver;
+ virDomainEventPtr event = NULL;
+ virDomainEventPtr lifecycleEvent = NULL;
+
+ virDomainObjLock(vm);
+ event = virDomainEventSuspendDiskNewFromObj(vm);
+
+ if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ VIR_DEBUG("Transitioned guest %s to pmsuspended state due to "
+ "QMP suspend_disk event", vm->def->name);
+
+ virDomainObjSetState(vm, VIR_DOMAIN_PMSUSPENDED,
+ VIR_DOMAIN_PMSUSPENDED_UNKNOWN);
+ lifecycleEvent =
+ virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_PMSUSPENDED,
+ VIR_DOMAIN_EVENT_PMSUSPENDED_DISK);
+
+ if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+ VIR_WARN("Unable to save status on vm %s after suspend event",
+ vm->def->name);
+ }
+
+ if (priv->agent)
+ qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND);
+ }
+
+ virDomainObjUnlock(vm);
+
+ if (event || lifecycleEvent) {
+ qemuDriverLock(driver);
+ if (event)
+ qemuDomainEventQueue(driver, event);
+ if (lifecycleEvent)
+ qemuDomainEventQueue(driver, lifecycleEvent);
+ qemuDriverUnlock(driver);
+ }
+
+ return 0;
+}
+
static qemuMonitorCallbacks monitorCallbacks = {
.destroy = qemuProcessHandleMonitorDestroy,
@@ -1196,6 +1242,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.domainPMWakeup = qemuProcessHandlePMWakeup,
.domainPMSuspend = qemuProcessHandlePMSuspend,
.domainBalloonChange = qemuProcessHandleBalloonChange,
+ .domainSuspendDisk = qemuProcessHandleSuspendDisk,
};
static int
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index fc4c696..741c159 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -253,6 +253,10 @@ static void
remoteDomainBuildEventBalloonChange(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
+static void
+remoteDomainBuildEventSuspendDisk(virNetClientProgramPtr prog,
+ virNetClientPtr client,
+ void *evdata, void *opaque);
static virNetClientProgramEvent remoteDomainEvents[] = {
{ REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
@@ -311,6 +315,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = {
remoteDomainBuildEventBalloonChange,
sizeof(remote_domain_event_balloon_change_msg),
(xdrproc_t)xdr_remote_domain_event_balloon_change_msg },
+ { REMOTE_PROC_DOMAIN_EVENT_SUSPEND_DISK,
+ remoteDomainBuildEventSuspendDisk,
+ sizeof(remote_domain_event_suspend_disk_msg),
+ (xdrproc_t)xdr_remote_domain_event_suspend_disk_msg },
};
enum virDrvOpenRemoteFlags {
@@ -4575,6 +4583,29 @@ remoteDomainBuildEventBalloonChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
}
+static void
+remoteDomainBuildEventSuspendDisk(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
+ virNetClientPtr client ATTRIBUTE_UNUSED,
+ void *evdata, void *opaque)
+{
+ virConnectPtr conn = opaque;
+ struct private_data *priv = conn->privateData;
+ remote_domain_event_suspend_disk_msg *msg = evdata;
+ virDomainPtr dom;
+ virDomainEventPtr event = NULL;
+
+ dom = get_nonnull_domain(conn, msg->dom);
+ if (!dom)
+ return;
+
+ event = virDomainEventSuspendDiskNewFromDom(dom);
+
+ virDomainFree(dom);
+
+ remoteDomainEventQueue(priv, event);
+}
+
+
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth,
unsigned int flags)
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index b0b530c..94ea947 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2259,6 +2259,10 @@ struct remote_domain_event_balloon_change_msg {
unsigned hyper actual;
};
+struct remote_domain_event_suspend_disk_msg {
+ remote_nonnull_domain dom;
+};
+
struct remote_domain_managed_save_args {
remote_nonnull_domain dom;
unsigned int flags;
@@ -3008,7 +3012,8 @@ enum remote_procedure {
REMOTE_PROC_NODE_GET_MEMORY_PARAMETERS = 289, /* skipgen skipgen */
REMOTE_PROC_DOMAIN_BLOCK_COMMIT = 290, /* autogen autogen */
- REMOTE_PROC_NETWORK_UPDATE = 291 /* autogen autogen priority:high */
+ REMOTE_PROC_NETWORK_UPDATE = 291, /* autogen autogen priority:high */
+ REMOTE_PROC_DOMAIN_EVENT_SUSPEND_DISK = 292 /* autogen autogen */
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 4d2627a..cbdd27c 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1718,6 +1718,9 @@ struct remote_domain_event_balloon_change_msg {
remote_nonnull_domain dom;
uint64_t actual;
};
+struct remote_domain_event_suspend_disk_msg {
+ remote_nonnull_domain dom;
+};
struct remote_domain_managed_save_args {
remote_nonnull_domain dom;
u_int flags;
@@ -2415,4 +2418,5 @@ enum remote_procedure {
REMOTE_PROC_NODE_GET_MEMORY_PARAMETERS = 289,
REMOTE_PROC_DOMAIN_BLOCK_COMMIT = 290,
REMOTE_PROC_NETWORK_UPDATE = 291,
+ REMOTE_PROC_DOMAIN_EVENT_SUSPEND_DISK = 292,
};
--
1.7.12.3
12 years, 1 month
[libvirt] [PATCH] Autogenerate AUTHORS
by Cole Robinson
We add a helper python script build-aux/make-authors.py The .mailmap
is expanded to give output as close to the original AUTHORS file as
possible. Drop the syntax-check that validated AUTHORS is up to date.
AUTHORS.in tracks the maintainers, as well as some folks who were
previously in AUTHORS but don't have a git commit with proper
attribution.
---
.gitignore | 1 +
.mailmap | 13 +++
AUTHORS | 279 ----------------------------------------------
AUTHORS.in | 86 ++++++++++++++
Makefile.am | 12 +-
bootstrap.conf | 3 +-
build-aux/make-authors.py | 44 ++++++++
cfg.mk | 15 ---
8 files changed, 157 insertions(+), 296 deletions(-)
delete mode 100644 AUTHORS
create mode 100644 AUTHORS.in
create mode 100644 build-aux/make-authors.py
If someone wants to suggest a perl or shell script replacement I'm all ears.
Or we could just commit to sorting AUTHORS alphabetically and let sort +
uniq do all the work.
diff --git a/.gitignore b/.gitignore
index 1cd2d45..004bc76 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,7 @@
.memdump
.sc-start-sc_*
/ABOUT-NLS
+/AUTHORS
/COPYING
/ChangeLog
/GNUmakefile
diff --git a/.mailmap b/.mailmap
index 76e6513..924c501 100644
--- a/.mailmap
+++ b/.mailmap
@@ -34,6 +34,8 @@
<gerd(a)egidy.de> <lists(a)egidy.de>
<gerd(a)egidy.de> <gerd.von.egidy(a)intra2net.com>
<benoar(a)dolka.fr> <benjamin.cama(a)telecom-bretagne.eu>
+<serge.hallyn(a)canonical.com> <serue(a)us.ibm.com>
+<pritesh.kothari(a)sun.com> <Pritesh.Kothari(a)Sun.COM>
# Name consolidation:
# Preferred author spelling <preferred email>
@@ -42,3 +44,14 @@ Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Daniel J Walsh <dwalsh(a)redhat.com>
Ján Tomko <jtomko(a)redhat.com>
Gerd von Egidy <gerd(a)egidy.de>
+MATSUDA Daiki <matsudadik(a)intellilink.co.jp>
+Tang Chen <tangchen(a)cn.fujitsu.com>
+Peng Zhou <ailvpeng25(a)gmail.com>
+Dirk Herrendoerfer <d.herrendoerfer(a)herrendoerfer.name>
+Thibault VINCENT <thibault.vincent(a)smartjog.com>
+Aurelien Rougemont <beorn(a)binaries.fr>
+Serge E. Hallyn <serge.hallyn(a)canonical.com>
+Henrik Persson E <henrik.e.persson(a)ericsson.com>
+Philipp Hahn <hahn(a)univention.de>
+Marco Bozzolan <bozzolan(a)gmail.com>
+Pritesh Kothari <pritesh.kothari(a)sun.com>
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index 27c4eda..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,279 +0,0 @@
- libvirt Authors
- ===============
-
-The libvirt project was initiated by:
-
- Daniel Veillard <veillard(a)redhat.com> or <daniel(a)veillard.com>
-
-The primary maintainers and people with commit access rights:
-
- Daniel Veillard <veillard(a)redhat.com>
- Daniel Berrange <berrange(a)redhat.com>
- Richard W.M. Jones <rjones(a)redhat.com>
- Mark McLoughlin <markmc(a)redhat.com>
- Anthony Liguori <aliguori(a)us.ibm.com>
- Jim Meyering <meyering(a)redhat.com>
- Jim Fehlig <jfehlig(a)suse.com>
- Chris Lalancette <clalance(a)redhat.com>
- Cole Robinson <crobinso(a)redhat.com>
- Guido Günther <agx(a)sigxcpu.org>
- John Levon <john.levon(a)sun.com>
- Matthias Bolte <matthias.bolte(a)googlemail.com>
- Jiří Denemark <jdenemar(a)redhat.com>
- Dave Allan <dallan(a)redhat.com>
- Laine Stump <laine(a)redhat.com>
- Stefan Berger <stefanb(a)us.ibm.com>
- Eric Blake <eblake(a)redhat.com>
- Justin Clift <jclift(a)redhat.com>
- Osier Yang <jyang(a)redhat.com>
- Wen Congyang <wency(a)cn.fujitsu.com>
- Michal Prívozník <mprivozn(a)redhat.com>
- Peter Krempa <pkrempa(a)redhat.com>
- Christophe Fergeau <cfergeau(a)redhat.com>
- Alex Jia <ajia(a)redhat.com>
- Martin Kletzander <mkletzan(a)redhat.com>
-
-Previous maintainers:
- Karel Zak <kzak(a)redhat.com>
- Atsushi SAKAI <sakaia(a)jp.fujitsu.com>
- Dave Leskovec <dlesko(a)linux.vnet.ibm.com>
- Dan Smith <danms(a)us.ibm.com>
-
-Patches have also been contributed by:
-
- David Lutterkort <dlutter(a)redhat.com>
- Andrew Puch <apuch(a)redhat.com>
- Philippe Berthault <philippe.berthault(a)Bull.net>
- Hugh Brock <hbrock(a)redhat.com>
- Michel Ponceau <michel.ponceau(a)bull.net>
- Jeremy Katz <katzj(a)redhat.com>
- Pete Vetere <pvetere(a)redhat.com>
- Kazuki Mizushima <mizushima.kazuk(a)jp.fujitsu.com>
- Saori Fukuta <fukuta.saori(a)jp.fujitsu.com>
- Tatsuro Enokura <fj7716hz(a)aa.jp.fujitsu.com>
- Takahashi Tomohiro <takatom(a)jp.fujitsu.com>
- Nobuhiro Itou <fj0873gn(a)aa.jp.fujitsu.com>
- Masayuki Sunou <fj1826dm(a)aa.jp.fujitsu.com>
- Mark Johnson <johnson.nh(a)gmail.com>
- Christian Ehrhardt <ehrhardt(a)linux.vnet.ibm.com>
- Shuveb Hussain <shuveb(a)binarykarma.com>
- Jim Paris <jim(a)jtan.com>
- Daniel Hokka Zakrisson <daniel(a)hozac.com>
- Mads Chr. Olesen <shiyee(a)shiyee.dk>
- Anton Protopopov <aspsk2(a)gmail.com>
- Stefan de Konink <dekonink(a)kinkrsoftware.nl>
- Kaitlin Rupert <kaitlin(a)linux.vnet.ibm.com>
- Evgeniy Sokolov <evg(a)openvz.org>
- David Lively <dlively(a)virtualiron.com>
- Charles Duffy <Charles_Duffy(a)messageone.com>
- Nguyen Anh Quynh <aquynh(a)gmail.com>
- James Morris <jmorris(a)namei.org>
- Chris Wright <chrisw(a)redhat.com>
- Ben Guthro <ben.guthro(a)gmail.com>
- Shigeki Sakamoto <fj0588di(a)aa.jp.fujitsu.com>
- Gerd von Egidy <gerd(a)egidy.de>
- Itamar Heim <iheim(a)redhat.com>
- Markus Armbruster <armbru(a)redhat.com>
- Ryota Ozaki <ozaki.ryota(a)gmail.com>
- Daniel J Walsh <dwalsh(a)redhat.com>
- Maximilian Wilhelm <max(a)rfc2324.org>
- Pritesh Kothari <Pritesh.Kothari(a)Sun.COM>
- Amit Shah <amit.shah(a)redhat.com>
- Florian Vichot <florian.vichot(a)diateam.net>
- Serge E. Hallyn <serue(a)us.ibm.com>
- Soren Hansen <soren(a)linux2go.dk>
- Abel Míguez Rodríguez<amiguezr(a)pdi.ucm.es>
- Doug Goldstein <cardoe(a)cardoe.com>
- Javier Fontan <jfontan(a)gmail.com>
- Federico Simoncelli <fsimonce(a)redhat.com>
- Amy Griffis <amy.griffis(a)hp.com>
- Henrik Persson E <henrik.e.persson(a)ericsson.com>
- Satoru SATOH <satoru.satoh(a)gmail.com>
- Paolo Bonzini <pbonzini(a)redhat.com>
- Miloslav Trmač <mitr(a)redhat.com>
- Jamie Strandboge <jamie(a)canonical.com>
- Gerhard Stenzel <gerhard.stenzel(a)de.ibm.com>
- Matthew Booth <mbooth(a)redhat.com>
- Diego Elio Pettenò <flameeyes(a)gmail.com>
- Adam Litke <agl(a)us.ibm.com>
- Steve Yarmie <steve.yarmie(a)gmail.com>
- Dan Kenigsberg <danken(a)redhat.com>
- Yuji NISHIDA <nishidy(a)nict.go.jp>
- Dustin Xiong <x_k_123(a)hotmail.com>
- Rolf Eike Beer <eike(a)sf-mail.de>
- Wolfgang Mauerer <wolfgang.mauerer(a)siemens.com>
- Philipp Hahn <hahn(a)univention.de>
- Ed Swierk <eswierk(a)aristanetworks.com>
- Paolo Smiraglia <paolo.smiraglia(a)gmail.com>
- Sharadha Prabhakar <sharadha.prabhakar(a)citrix.com>
- Chris Wong <wongc-redhat(a)hoku.net>
- Daniel Berteaud <daniel(a)firewall-services.com>
- Dustin Kirkland <kirkland(a)canonical.com>
- Luiz Capitulino <lcapitulino(a)redhat.com>
- Ryan Harper <ryanh(a)us.ibm.com>
- Spencer Shimko <sshimko(a)tresys.com>
- Marco Bozzolan <bozzolan(a)gmail.com>
- Alex Williamson <alex.williamson(a)redhat.com>
- Ersek Laszlo <lacos(a)caesar.elte.hu>
- Kenneth Nagin <NAGIN(a)il.ibm.com>
- Klaus Ethgen <Klaus(a)Ethgen.de>
- Bryan Kearney <bkearney(a)redhat.com>
- Darry L. Pierce <dpierce(a)redhat.com>
- David Jorm <dfj(a)redhat.com>
- Eduardo Otubo <otubo(a)linux.vnet.ibm.com>
- Garry Dolley <gdolley(a)arpnetworks.com>
- Harshavardhana <harsha(a)gluster.com>
- Jonas Eriksson <jonas.j.eriksson(a)ericsson.com>
- Jun Koi <junkoi2004(a)gmail.com>
- Olivier Fourdan <ofourdan(a)redhat.com>
- Ron Yorston <rmy(a)tigress.co.uk>
- Shahar Klein <shaharklein(a)yahoo.com>
- Taizo ITO <taizo.ito(a)hde.co.jp>
- Thomas Treutner <thomas(a)scripty.at>
- Jean-Baptiste Rouault <jean-baptiste.rouault(a)diateam.net>
- Марк Коренберг <socketpair(a)gmail.com>
- Alan Pevec <apevec(a)redhat.com>
- Aurelien Rougemont <beorn(a)binaries.fr>
- Patrick Dignan <pat_dignan(a)dell.com>
- Serge Hallyn <serge.hallyn(a)canonical.com>
- Nikunj A. Dadhania <nikunj(a)linux.vnet.ibm.com>
- Lai Jiangshan <laijs(a)cn.fujitsu.com>
- Harsh Prateek Bora <harsh(a)linux.vnet.ibm.com>
- John Morrissey <jwm(a)horde.net>
- KAMEZAWA Hiroyuki <kamezawa.hiroyu(a)jp.fujitsu.com>
- Hu Tao <hutao(a)cn.fujitsu.com>
- Laurent Léonard <laurent(a)open-minds.org>
- MORITA Kazutaka <morita.kazutaka(a)lab.ntt.co.jp>
- Josh Durgin <josh.durgin(a)inktank.com>
- Roopa Prabhu <roprabhu(a)cisco.com>
- Paweł Krześniak <pawel.krzesniak(a)gmail.com>
- Kay Schubert <kayegypt(a)web.de>
- Marc-André Lureau <marcandre.lureau(a)redhat.com>
- Juerg Haefliger <juerg.haefliger(a)hp.com>
- Matthias Dahl <mdvirt(a)designassembly.de>
- Niels de Vos <ndevos(a)redhat.com>
- Davidlohr Bueso <dave(a)gnu.org>
- Alon Levy <alevy(a)redhat.com>
- Hero Phương <herophuong93(a)gmail.com>
- Zdenek Styblik <stybla(a)turnovfree.net>
- Gui Jianfeng <guijianfeng(a)cn.fujitsu.com>
- Michal Novotny <minovotn(a)redhat.com>
- Markus Groß <gross(a)univention.de>
- Phil Petty <phpetty(a)cisco.com>
- Taku Izumi <izumi.taku(a)jp.fujitsu.com>
- Minoru Usui <usui(a)mxm.nes.nec.co.jp>
- Tiziano Mueller <dev-zero(a)gentoo.org>
- Thibault VINCENT <thibault.vincent(a)smartjog.com>
- Naoya Horiguchi <n-horiguchi(a)ah.jp.nec.com>
- Jesse Cook <code.crashenx(a)gmail.com>
- Alexander Todorov <atodorov(a)otb.bg>
- Richard Laager <rlaager(a)wiktel.com>
- Mark Wu <dwu(a)redhat.com>
- Yufang Zhang <yuzhang(a)redhat.com>
- Supriya Kannery <supriyak(a)linux.vnet.ibm.com>
- Dirk Herrendoerfer <d.herrendoerfer(a)herrendoerfer.name>
- Taisuke Yamada <tai(a)rakugaki.org>
- Heath Petersen <HeathPetersen(a)Kandre.com>
- Neil Wilson <neil(a)aldur.co.uk>
- Ohad Levy <ohadlevy(a)gmail.com>
- Michael Chapman <mike(a)very.puzzling.org>
- Daniel Gollub <gollub(a)b1-systems.de>
- David S. Wang <dwang2(a)cisco.com>
- Ruben Kerkhof <ruben(a)rubenkerkhof.com>
- Scott Moser <smoser(a)ubuntu.com>
- Guannan Ren <gren(a)redhat.com>
- John Williams <john.williams(a)petalogix.com>
- Michael Santos <michael.santos(a)gmail.com>
- Oskari Saarenmaa <os(a)ohmu.fi>
- Nan Zhang <nzhang(a)redhat.com>
- Wieland Hoffmann <themineo(a)googlemail.com>
- Douglas Schilling Landgraf <dougsland(a)redhat.com>
- Tom Vijlbrief <tom.vijlbrief(a)xs4all.nl>
- Shradha Shah <sshah(a)solarflare.com>
- Steve Hodgson <shodgson(a)solarflare.com>
- Xu He Jie <xuhj(a)linux.vnet.ibm.com>
- Lei Li <lilei(a)linux.vnet.ibm.com>
- Matthias Witte <witte(a)netzquadrat.de>
- Tang Chen <tangchen(a)cn.fujitsu.com>
- Dan Horák <dan(a)danny.cz>
- Sage Weil <sage(a)newdream.net>
- David L Stevens <dlstevens(a)us.ibm.com>
- Tyler Coumbes <coumbes(a)gmail.com>
- Royce Lv <lvroyce(a)linux.vnet.ibm.com>
- Patrice LACHANCE <patlachance(a)gmail.com>
- Eli Qiao <taget(a)linux.vnet.ibm.com>
- Michael Wood <esiotrot(a)gmail.com>
- Bharata B Rao <bharata(a)linux.vnet.ibm.com>
- Srivatsa S. Bhat <srivatsa.bhat(a)linux.vnet.ibm.com>
- Chang Liu <lingjiao.lc(a)taobao.com>
- Lorin Hochstein <lorin(a)isi.edu>
- Christian Franke <nobody(a)nowhere.ws>
- Prerna Saxena <prerna(a)linux.vnet.ibm.com>
- Michael Ellerman <michael(a)ellerman.id.au>
- Rommer <rommer(a)active.by>
- Yuri Chornoivan <yurchor(a)ukr.net>
- Deepak C Shetty <deepakcs(a)linux.vnet.ibm.com>
- Laszlo Ersek <lersek(a)redhat.com>
- Zeeshan Ali (Khattak) <zeeshanak(a)gnome.org>
- Marcelo Cerri <mhcerri(a)linux.vnet.ibm.com>
- Hendrik Schwartke <hendrik(a)os-t.de>
- Ansis Atteka <aatteka(a)nicira.com>
- Dan Wendlandt <dan(a)nicira.com>
- Kyle Mestery <kmestery(a)cisco.com>
- Lincoln Myers <lincoln_myers(a)yahoo.com>
- Peter Robinson <pbrobinson(a)gmail.com>
- Benjamin Cama <benoar(a)dolka.fr>
- Duncan Rance <libvirt(a)dunquino.com>
- Peng Zhou <ailvpeng25(a)gmail.com>
- Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
- Stef Walter <stefw(a)gnome.org>
- Christian Benvenuti <benve(a)cisco.com>
- Ilja Livenson <ilja.livenson(a)gmail.com>
- Stefan Bader <stefan.bader(a)canonical.com>
- MATSUDA Daiki <matsudadik(a)intellilink.co.jp>
- Jan Kiszka <jan.kiszka(a)siemens.com>
- Ryan Woodsmall <rwoodsmall(a)gmail.com>
- Wido den Hollander <wido(a)widodh.nl>
- Eugen Feller <eugen.feller(a)inria.fr>
- Dmitry Guryanov <dguryanov(a)parallels.com>
- William Jon McCann <william.jon.mccann(a)gmail.com>
- David Weber <wb(a)munzinger.de>
- Marti Raudsepp <marti(a)juffo.org>
- Radu Caragea <dmns_serp(a)yahoo.com>
- Beat Jörg <Beat.Joerg(a)ssatr.ch>
- Gao feng <gaofeng(a)cn.fujitsu.com>
- Dipankar Sarma <dipankar(a)in.ibm.com>
- Gerd Hoffmann <kraxel(a)redhat.com>
- Viktor Mihajlovski <mihajlov(a)linux.vnet.ibm.com>
- Thang Pham <thang.pham(a)us.ibm.com>
- Eiichi Tsukata <eiichi.tsukata.xh(a)hitachi.com>
- Sascha Peilicke <saschpe(a)suse.de>
- Chuck Short <chuck.short(a)canonical.com>
- Sebastian Wiedenroth <wiedi(a)frubar.net>
- Ata E Husain Bohra <ata.husain(a)hotmail.com>
- Ján Tomko <jtomko(a)redhat.com>
- Richa Marwaha <rmarwah(a)linux.vnet.ibm.com>
- Peter Feiner <peter(a)gridcentric.ca>
- Frido Roose <frido.roose(a)gmail.com>
- Asad Saeed <asad.saeed(a)acidseed.com>
- Sukadev Bhattiprolu <sukadev(a)linux.vnet.ibm.com>
- Thomas Woerner <twoerner(a)redhat.com>
- J.B. Joret <jb(a)linux.vnet.ibm.com>
- Stefan Hajnoczi <stefanha(a)linux.vnet.ibm.com>
- Gene Czarcinski <gene(a)czarc.net>
- Nishank Trivedi <nistrive(a)cisco.com>
- Jasper Lievisse Adriaanse <jasper(a)humppa.nl>
- Paul Eggert <eggert(a)cs.ucla.edu>
- Dwight Engen <dwight.engen(a)oracle.com>
- liguang <lig.fnst(a)cn.fujitsu.com>
- Chuck Short <zulcss(a)gmail.com>
- Alexander Larsson <alexl(a)redhat.com>
-
- [....send patches to get your name here....]
-
-The libvirt Logo was designed by Diana Fong
-
--- End
-;; Local Variables:
-;; coding: utf-8
-;; End:
diff --git a/AUTHORS.in b/AUTHORS.in
new file mode 100644
index 0000000..849badf
--- /dev/null
+++ b/AUTHORS.in
@@ -0,0 +1,86 @@
+ libvirt Authors
+ ===============
+
+The libvirt project was initiated by:
+
+ Daniel Veillard <veillard(a)redhat.com> or <daniel(a)veillard.com>
+
+The primary maintainers and people with commit access rights:
+
+ Daniel Veillard <veillard(a)redhat.com>
+ Daniel Berrange <berrange(a)redhat.com>
+ Richard W.M. Jones <rjones(a)redhat.com>
+ Mark McLoughlin <markmc(a)redhat.com>
+ Anthony Liguori <aliguori(a)us.ibm.com>
+ Jim Meyering <meyering(a)redhat.com>
+ Jim Fehlig <jfehlig(a)suse.com>
+ Chris Lalancette <clalance(a)redhat.com>
+ Cole Robinson <crobinso(a)redhat.com>
+ Guido Günther <agx(a)sigxcpu.org>
+ John Levon <john.levon(a)sun.com>
+ Matthias Bolte <matthias.bolte(a)googlemail.com>
+ Jiří Denemark <jdenemar(a)redhat.com>
+ Dave Allan <dallan(a)redhat.com>
+ Laine Stump <laine(a)redhat.com>
+ Stefan Berger <stefanb(a)us.ibm.com>
+ Eric Blake <eblake(a)redhat.com>
+ Justin Clift <jclift(a)redhat.com>
+ Osier Yang <jyang(a)redhat.com>
+ Wen Congyang <wency(a)cn.fujitsu.com>
+ Michal Prívozník <mprivozn(a)redhat.com>
+ Peter Krempa <pkrempa(a)redhat.com>
+ Christophe Fergeau <cfergeau(a)redhat.com>
+ Alex Jia <ajia(a)redhat.com>
+ Martin Kletzander <mkletzan(a)redhat.com>
+
+Previous maintainers:
+ Karel Zak <kzak(a)redhat.com>
+ Atsushi SAKAI <sakaia(a)jp.fujitsu.com>
+ Dave Leskovec <dlesko(a)linux.vnet.ibm.com>
+ Dan Smith <danms(a)us.ibm.com>
+
+Patches have also been contributed by:
+
+ David Lutterkort <dlutter(a)redhat.com>
+ Andrew Puch <apuch(a)redhat.com>
+ Philippe Berthault <philippe.berthault(a)Bull.net>
+ Hugh Brock <hbrock(a)redhat.com>
+ Michel Ponceau <michel.ponceau(a)bull.net>
+ Jeremy Katz <katzj(a)redhat.com>
+ Pete Vetere <pvetere(a)redhat.com>
+ Kazuki Mizushima <mizushima.kazuk(a)jp.fujitsu.com>
+ Saori Fukuta <fukuta.saori(a)jp.fujitsu.com>
+ Tatsuro Enokura <fj7716hz(a)aa.jp.fujitsu.com>
+ Takahashi Tomohiro <takatom(a)jp.fujitsu.com>
+ Nobuhiro Itou <fj0873gn(a)aa.jp.fujitsu.com>
+ Masayuki Sunou <fj1826dm(a)aa.jp.fujitsu.com>
+ Mark Johnson <johnson.nh(a)gmail.com>
+ Christian Ehrhardt <ehrhardt(a)linux.vnet.ibm.com>
+ Shuveb Hussain <shuveb(a)binarykarma.com>
+ Daniel Hokka Zakrisson <daniel(a)hozac.com>
+ Mads Chr. Olesen <shiyee(a)shiyee.dk>
+ Anton Protopopov <aspsk2(a)gmail.com>
+ Stefan de Konink <dekonink(a)kinkrsoftware.nl>
+ Kaitlin Rupert <kaitlin(a)linux.vnet.ibm.com>
+ Evgeniy Sokolov <evg(a)openvz.org>
+ David Lively <dlively(a)virtualiron.com>
+ James Morris <jmorris(a)namei.org>
+ Ben Guthro <ben.guthro(a)gmail.com>
+ Shigeki Sakamoto <fj0588di(a)aa.jp.fujitsu.com>
+ Amit Shah <amit.shah(a)redhat.com>
+ Itamar Heim <iheim(a)redhat.com>
+ Markus Armbruster <armbru(a)redhat.com>
+ Abel Míguez Rodríguez<amiguezr(a)pdi.ucm.es>
+ Javier Fontan <jfontan(a)gmail.com>
+ Matthias Witte <witte(a)netzquadrat.de>
+ Dan Wendlandt <dan(a)nicira.com>
+@authorlist@
+
+ [....send patches to get your name here....]
+
+The libvirt Logo was designed by Diana Fong
+
+-- End
+;; Local Variables:
+;; coding: utf-8
+;; End:
diff --git a/Makefile.am b/Makefile.am
index 333e300..73d6a00 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -28,6 +28,7 @@ EXTRA_DIST = \
cfg.mk \
examples/domain-events/events-python \
run.in \
+ AUTHORS.in \
$(XML_EXAMPLES)
pkgconfigdir = $(libdir)/pkgconfig
@@ -78,7 +79,7 @@ MAINTAINERCLEANFILES = .git-module-status
# disable this check
distuninstallcheck:
-dist-hook: gen-ChangeLog
+dist-hook: gen-ChangeLog gen-AUTHORS
# Generate the ChangeLog file (with all entries since the switch to git)
# and insert it into the directory we're about to use to create a tarball.
@@ -91,3 +92,12 @@ gen-ChangeLog:
rm -f $(distdir)/ChangeLog; \
mv $(distdir)/cl-t $(distdir)/ChangeLog; \
fi
+
+.PHONY: gen-AUTHORS
+gen-AUTHORS:
+ if test -d .git; then \
+ git log --pretty=format:"%aN@@@%aE" | \
+ python $(top_srcdir)/build-aux/make-authors.py > \
+ $(distdir)/AUTHORS-tmp && \
+ mv -f $(distdir)/AUTHORS-tmp $(distdir)/AUTHORS ; \
+ fi
diff --git a/bootstrap.conf b/bootstrap.conf
index f8b7c4d..c40db3d 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -223,7 +223,8 @@ if `(${PYTHON_CONFIG-python-config} --version;
PYTHON_CONFIG=true
fi
-# Automake requires that ChangeLog exist.
+# Automake requires that ChangeLog and AUTHORS exist.
+touch AUTHORS || exit 1
touch ChangeLog || exit 1
# Override bootstrap's list - we don't use mdate-sh or texinfo.tex.
diff --git a/build-aux/make-authors.py b/build-aux/make-authors.py
new file mode 100644
index 0000000..f1df62f
--- /dev/null
+++ b/build-aux/make-authors.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+#
+# make-authors.py: Generate AUTHORS file from AUTHORS.in and git
+# log output on stdin
+#
+# 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/>.
+#
+
+import sys
+
+lines = sys.stdin.read().splitlines()
+lines.reverse()
+template = file("AUTHORS.in").read()
+
+authlist = ""
+authlist = []
+for line in lines:
+ name, email = line.split("@@@")
+ if email in template:
+ continue
+
+ entry = " %-20s <%s>" % (name.decode("utf-8"), email)
+ if entry in authlist:
+ continue
+ authlist.append(entry)
+
+template = template.split("@authorlist@")
+output = "%s%s%s" % (template[0],
+ "\n".join(authlist).encode("utf-8"),
+ template[1])
+sys.stdout.write(output)
diff --git a/cfg.mk b/cfg.mk
index e1fbf4f..eed7fd8 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -43,7 +43,6 @@ _test_script_regex = \<\(init\|test-lib\)\.sh\>
# Tests not to run as part of "make distcheck".
local-checks-to-skip = \
changelog-check \
- check-AUTHORS \
makefile-check \
makefile_path_separator_check \
patch-check \
@@ -711,20 +710,6 @@ _autogen:
$(srcdir)/autogen.sh
./config.status
-# Give credit where due:
-# Ensure that each commit author email address (possibly mapped via
-# git log's .mailmap) appears in our AUTHORS file.
-sc_check_author_list:
- @fail=0; \
- for i in $$(git log --pretty=format:%aE%n|sort -u|grep -v '^$$'); do \
- sanitized=$$(echo "$$i"|LC_ALL=C sed 's/\([^a-zA-Z0-9_@-]\)/\\\1/g'); \
- grep -iq "<$$sanitized>" $(srcdir)/AUTHORS \
- || { printf '%s\n' "$$i" >&2; fail=1; }; \
- done; \
- test $$fail = 1 \
- && echo '$(ME): committer(s) not listed in AUTHORS' >&2; \
- test $$fail = 0
-
# regenerate HACKING as part of the syntax-check
syntax-check: $(top_srcdir)/HACKING
--
1.7.11.4
12 years, 1 month