[libvirt] [PATCH V2 0/5] support sending sysrq key

xend/libxl support sending sysrq key to guest kernel but not support sending any key sequence as virDomainSendKey is expected to do. To add equivalant sysrq functionality in libvirt for xen/libxl, add a new virDomainSendSysrq API and add related codes to virsh, remote driver, xen/libxl driver. Changes: * add new API virDomainSendSysrq instead of hacking virDomainSendKey. * add related changes according to new API, including libvirt API, remote protocol, virsh and libxl/xen driver. v1 is here: https://www.redhat.com/archives/libvir-list/2014-December/msg00480.html Chunyan Liu (5): Add public API virDomainSendSysrq implement remote protocol for domainSendSysrq virsh: add 'sysrq' command libxl: implement .domainSendSysrq method xen: add .domainSendSysrq method include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 +++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + src/libxl/libxl_driver.c | 23 +++++++++++++++++ src/remote/remote_driver.c | 2 +- src/remote/remote_protocol.x | 13 +++++++++- src/xen/xen_driver.c | 19 ++++++++++++++ src/xen/xend_internal.c | 20 +++++++++++++++ src/xen/xend_internal.h | 2 ++ tools/virsh-domain.c | 54 ++++++++++++++++++++++++++++++++++++++++ 11 files changed, 177 insertions(+), 2 deletions(-) -- 1.8.4.5

Add public API virDomainSendSysrq for sending SysRequest key. Signed-off-by: Chunyan Liu <cyliu@suse.com> --- include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 ++++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 46 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index ae2c49c..73ef6c8 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -3519,6 +3519,9 @@ int virDomainGetFSInfo(virDomainPtr dom, virDomainFSInfoPtr **info, unsigned int flags); +/* virDomainSendSysrq */ +int virDomainSendSysrq(virDomainPtr dom, const char *key); + int virDomainGetTime(virDomainPtr dom, long long *seconds, unsigned int *nseconds, diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 9f26b13..79558c3 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1170,6 +1170,9 @@ typedef int unsigned int cellCount, unsigned int flags); +typedef int +(*virDrvDomainSendSysrq)(virDomainPtr dom, const char *key); + typedef struct _virHypervisorDriver virHypervisorDriver; typedef virHypervisorDriver *virHypervisorDriverPtr; @@ -1396,6 +1399,7 @@ struct _virHypervisorDriver { virDrvConnectGetAllDomainStats connectGetAllDomainStats; virDrvNodeAllocPages nodeAllocPages; virDrvDomainGetFSInfo domainGetFSInfo; + virDrvDomainSendSysrq domainSendSysrq; }; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index cb76d8c..4658fd7 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11192,3 +11192,41 @@ virDomainFSInfoFree(virDomainFSInfoPtr info) VIR_FREE(info->devAlias[i]); VIR_FREE(info->devAlias); } + + +/** + * virDomainSendSysrq: + * @domain: pointer to domain object, or NULL for Domain0 + * @key: SysRq key, like h, c, ... + * + * Send SysRq key to the guest. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainSendSysrq(virDomainPtr domain, const char *key) +{ + virConnectPtr conn; + VIR_DOMAIN_DEBUG(domain, "key=%s", key); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn = domain->conn; + + virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->domainSendSysrq) { + int ret; + ret = conn->driver->domainSendSysrq(domain, key); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index e4c2df1..80d1dd2 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -688,6 +688,7 @@ LIBVIRT_1.2.11 { global: virDomainFSInfoFree; virDomainGetFSInfo; + virDomainSendSysrq; } LIBVIRT_1.2.9; # .... define new API here using predicted next version number .... -- 1.8.4.5

On 12/12/14 10:04, Chunyan Liu wrote:
Add public API virDomainSendSysrq for sending SysRequest key.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 ++++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 46 insertions(+)
[...]
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index cb76d8c..4658fd7 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11192,3 +11192,41 @@ virDomainFSInfoFree(virDomainFSInfoPtr info) VIR_FREE(info->devAlias[i]); VIR_FREE(info->devAlias); } + + +/** + * virDomainSendSysrq: + * @domain: pointer to domain object, or NULL for Domain0 + * @key: SysRq key, like h, c, ... + * + * Send SysRq key to the guest. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainSendSysrq(virDomainPtr domain, const char *key)
The new API should definitely have a 'flags' argument although it may be unused for now.
+{ + virConnectPtr conn; + VIR_DOMAIN_DEBUG(domain, "key=%s", key); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn = domain->conn; + + virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->domainSendSysrq) { + int ret; + ret = conn->driver->domainSendSysrq(domain, key); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index e4c2df1..80d1dd2 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -688,6 +688,7 @@ LIBVIRT_1.2.11 { global: virDomainFSInfoFree; virDomainGetFSInfo; + virDomainSendSysrq;
This needs to be in it's own section according to the release the API will be in (1.2.12 currently)
} LIBVIRT_1.2.9;
# .... define new API here using predicted next version number ....
Peter

On 12/12/14 10:18, Peter Krempa wrote:
On 12/12/14 10:04, Chunyan Liu wrote:
Add public API virDomainSendSysrq for sending SysRequest key.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 ++++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 46 insertions(+)
[...]
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index cb76d8c..4658fd7 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11192,3 +11192,41 @@ virDomainFSInfoFree(virDomainFSInfoPtr info) VIR_FREE(info->devAlias[i]); VIR_FREE(info->devAlias); } + + +/** + * virDomainSendSysrq: + * @domain: pointer to domain object, or NULL for Domain0 + * @key: SysRq key, like h, c, ... + * + * Send SysRq key to the guest. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainSendSysrq(virDomainPtr domain, const char *key)
The new API should definitely have a 'flags' argument although it may be unused for now.
As an additional thought. Isn't this possible with the existing virDomainSendKey API? The sysrq combination is a key code, so you should be able to use that API to do the same thing. In that case all you need is a virsh wrapper and an implementation of the API for the XEN driver. Peter

On Fri, Dec 12, 2014 at 10:18:36 +0100, Peter Krempa wrote:
On 12/12/14 10:04, Chunyan Liu wrote:
Add public API virDomainSendSysrq for sending SysRequest key.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 ++++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 46 insertions(+)
[...]
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index cb76d8c..4658fd7 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11192,3 +11192,41 @@ virDomainFSInfoFree(virDomainFSInfoPtr info) VIR_FREE(info->devAlias[i]); VIR_FREE(info->devAlias); } + + +/** + * virDomainSendSysrq: + * @domain: pointer to domain object, or NULL for Domain0 + * @key: SysRq key, like h, c, ... + * + * Send SysRq key to the guest. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainSendSysrq(virDomainPtr domain, const char *key)
The new API should definitely have a 'flags' argument although it may be unused for now.
Moreover, passing a single character by reference sounds pretty strange, why not just "char key"? Moreover, wouldn't it be better to provide an enum of possible values with meaningful names (rather than keys), such as typedef enum { VIR_DOMAIN_SYSRQ_REBOOT, VIR_DOMAIN_SYSRQ_CRASH, VIR_DOMAIN_SYSRQ_OOM_KILL, VIR_DOMAIN_SYSRQ_SYNC, ... } virDomainSysrqCommand; This way, virDomainSendSysrq(dom, VIR_DOMAIN_SYSRQ_OOM_KILL, 0) would be pretty self-explaining. The prototype would have to change to int virDomainSendSysrq(virDomainPtr domain, int command, /* one of virDomainSysrqCommand */ unsigned int flags); Jirka

On Fri, Dec 12, 2014 at 10:35:45AM +0100, Jiri Denemark wrote:
On Fri, Dec 12, 2014 at 10:18:36 +0100, Peter Krempa wrote:
On 12/12/14 10:04, Chunyan Liu wrote:
Add public API virDomainSendSysrq for sending SysRequest key.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 ++++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 46 insertions(+)
[...]
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index cb76d8c..4658fd7 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11192,3 +11192,41 @@ virDomainFSInfoFree(virDomainFSInfoPtr info) VIR_FREE(info->devAlias[i]); VIR_FREE(info->devAlias); } + + +/** + * virDomainSendSysrq: + * @domain: pointer to domain object, or NULL for Domain0 + * @key: SysRq key, like h, c, ... + * + * Send SysRq key to the guest. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainSendSysrq(virDomainPtr domain, const char *key)
The new API should definitely have a 'flags' argument although it may be unused for now.
Moreover, passing a single character by reference sounds pretty strange, why not just "char key"? Moreover, wouldn't it be better to provide an enum of possible values with meaningful names (rather than keys), such as
typedef enum { VIR_DOMAIN_SYSRQ_REBOOT, VIR_DOMAIN_SYSRQ_CRASH, VIR_DOMAIN_SYSRQ_OOM_KILL, VIR_DOMAIN_SYSRQ_SYNC, ... } virDomainSysrqCommand;
This way, virDomainSendSysrq(dom, VIR_DOMAIN_SYSRQ_OOM_KILL, 0) would be pretty self-explaining. The prototype would have to change to
int virDomainSendSysrq(virDomainPtr domain, int command, /* one of virDomainSysrqCommand */ unsigned int flags);
That would open up greater possibilities for implementing it differently for different guest OS, rather than assuming Linux characters. 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 :|

On 12/12/2014 at 05:35 PM, in message <20141212093545.GD136165@orkuz.home>, Jiri Denemark <jdenemar@redhat.com> wrote: On Fri, Dec 12, 2014 at 10:18:36 +0100, Peter Krempa wrote: On 12/12/14 10:04, Chunyan Liu wrote: Add public API virDomainSendSysrq for sending SysRequest key.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 ++++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 46 insertions(+)
[...]
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index cb76d8c..4658fd7 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11192,3 +11192,41 @@ virDomainFSInfoFree(virDomainFSInfoPtr info) VIR_FREE(info->devAlias[i]); VIR_FREE(info->devAlias); } + + +/** + * virDomainSendSysrq: + * @domain: pointer to domain object, or NULL for Domain0 + * @key: SysRq key, like h, c, ... + * + * Send SysRq key to the guest. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainSendSysrq(virDomainPtr domain, const char *key)
The new API should definitely have a 'flags' argument although it may be unused for now.
Moreover, passing a single character by reference sounds pretty strange, why not just "char key"?
I tried to define as 'char key', but meet some trouble in remote protocol, +struct remote_domain_send_sysrq_args { + remote_nonnull_domain dom; + char key; +}; will report 'char key' as unsupported type.
Moreover, wouldn't it be better to provide an enum of possible values with meaningful names (rather than keys), such as
typedef enum { VIR_DOMAIN_SYSRQ_REBOOT, VIR_DOMAIN_SYSRQ_CRASH, VIR_DOMAIN_SYSRQ_OOM_KILL, VIR_DOMAIN_SYSRQ_SYNC, ... } virDomainSysrqCommand;
This way, virDomainSendSysrq(dom, VIR_DOMAIN_SYSRQ_OOM_KILL, 0) would be pretty self-explaining. The prototype would have to change to
Mainly because xen/libxl API both accept letter as parameter directly, so define enum will need to map enum to letter before calling xen/libxl API. Chunyan
int virDomainSendSysrq(virDomainPtr domain, int command, /* one of virDomainSysrqCommand */ unsigned int flags);
Jirka

On Sun, Dec 14, 2014 at 20:27:09 -0700, Chun Yan Liu wrote:
On 12/12/2014 at 05:35 PM, in message <20141212093545.GD136165@orkuz.home>, Jiri Denemark <jdenemar@redhat.com> wrote: On Fri, Dec 12, 2014 at 10:18:36 +0100, Peter Krempa wrote: On 12/12/14 10:04, Chunyan Liu wrote: Add public API virDomainSendSysrq for sending SysRequest key.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 ++++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 46 insertions(+)
[...]
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index cb76d8c..4658fd7 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11192,3 +11192,41 @@ virDomainFSInfoFree(virDomainFSInfoPtr info) VIR_FREE(info->devAlias[i]); VIR_FREE(info->devAlias); } + + +/** + * virDomainSendSysrq: + * @domain: pointer to domain object, or NULL for Domain0 + * @key: SysRq key, like h, c, ... + * + * Send SysRq key to the guest. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainSendSysrq(virDomainPtr domain, const char *key)
The new API should definitely have a 'flags' argument although it may be unused for now.
Moreover, passing a single character by reference sounds pretty strange, why not just "char key"?
I tried to define as 'char key', but meet some trouble in remote protocol, +struct remote_domain_send_sysrq_args { + remote_nonnull_domain dom; + char key; +}; will report 'char key' as unsupported type.
Moreover, wouldn't it be better to provide an enum of possible values with meaningful names (rather than keys), such as
typedef enum { VIR_DOMAIN_SYSRQ_REBOOT, VIR_DOMAIN_SYSRQ_CRASH, VIR_DOMAIN_SYSRQ_OOM_KILL, VIR_DOMAIN_SYSRQ_SYNC, ... } virDomainSysrqCommand;
This way, virDomainSendSysrq(dom, VIR_DOMAIN_SYSRQ_OOM_KILL, 0) would be pretty self-explaining. The prototype would have to change to
Mainly because xen/libxl API both accept letter as parameter directly, so define enum will need to map enum to letter before calling xen/libxl API.
Yes, but that mapping is trivial. And the API will be much better with the enum. Jirka

On 12/15/2014 at 11:27 AM, in message <548EC58D0200006600084AF9@soto.provo.novell.com>, "Chun Yan Liu" <cyliu@suse.com> wrote:
On 12/12/2014 at 05:35 PM, in message <20141212093545.GD136165@orkuz.home>, Jiri Denemark <jdenemar@redhat.com> wrote: On Fri, Dec 12, 2014 at 10:18:36 +0100, Peter Krempa wrote: On 12/12/14 10:04, Chunyan Liu wrote: Add public API virDomainSendSysrq for sending SysRequest key.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 ++++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 46 insertions(+)
[...]
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index cb76d8c..4658fd7 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11192,3 +11192,41 @@ virDomainFSInfoFree(virDomainFSInfoPtr info) VIR_FREE(info->devAlias[i]); VIR_FREE(info->devAlias); } + + +/** + * virDomainSendSysrq: + * @domain: pointer to domain object, or NULL for Domain0 + * @key: SysRq key, like h, c, ... + * + * Send SysRq key to the guest. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainSendSysrq(virDomainPtr domain, const char *key)
The new API should definitely have a 'flags' argument although it may be unused for now.
Moreover, passing a single character by reference sounds pretty strange, why not just "char key"?
I tried to define as 'char key', but meet some trouble in remote protocol, +struct remote_domain_send_sysrq_args { + remote_nonnull_domain dom; + char key; +}; will report 'char key' as unsupported type.
Any ideas here? With 'char key' in remote_protocol.x, it'll report: "unhandled type for argument value: char key; at ./rpc/gendispatch.pl line 1234." I didn't find a way to avoid that, that's why I turned to use 'char *key' (a string, and when calling libxl API, pass key[0]).
Moreover, wouldn't it be better to provide an enum of possible values with meaningful names (rather than keys), such as
typedef enum { VIR_DOMAIN_SYSRQ_REBOOT, VIR_DOMAIN_SYSRQ_CRASH, VIR_DOMAIN_SYSRQ_OOM_KILL, VIR_DOMAIN_SYSRQ_SYNC, ... } virDomainSysrqCommand;
This way, virDomainSendSysrq(dom, VIR_DOMAIN_SYSRQ_OOM_KILL, 0) would be pretty self-explaining. The prototype would have to change to
Mainly because xen/libxl API both accept letter as parameter directly, so define enum will need to map enum to letter before calling xen/libxl API.
Chunyan
int virDomainSendSysrq(virDomainPtr domain, int command, /* one of virDomainSysrqCommand */ unsigned int flags);
Jirka
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On 12/15/2014 11:51 PM, Chun Yan Liu wrote:
I tried to define as 'char key', but meet some trouble in remote protocol, +struct remote_domain_send_sysrq_args { + remote_nonnull_domain dom; + char key; +}; will report 'char key' as unsupported type.
Any ideas here?
For the remote protocol, either pass 'int key' (three bytes wasted on the wire for the RPC call probably won't hurt, particularly since RPC tends to pad out to multiples of 4 anyways)...
With 'char key' in remote_protocol.x, it'll report: "unhandled type for argument value: char key; at ./rpc/gendispatch.pl line 1234." I didn't find a way to avoid that, that's why I turned to use 'char *key' (a string, and when calling libxl API, pass key[0]).
...or you'll have to edit the guts of gendispatch.pl to teach it to handle a 'char' type.
Moreover, wouldn't it be better to provide an enum of possible values with meaningful names (rather than keys), such as
typedef enum { VIR_DOMAIN_SYSRQ_REBOOT, VIR_DOMAIN_SYSRQ_CRASH, VIR_DOMAIN_SYSRQ_OOM_KILL, VIR_DOMAIN_SYSRQ_SYNC, ... } virDomainSysrqCommand;
This way, virDomainSendSysrq(dom, VIR_DOMAIN_SYSRQ_OOM_KILL, 0) would be pretty self-explaining. The prototype would have to change to
This would be better, in which case you WANT 'int key' in the RPC protocol (since we treat ALL enums as ints for ABI reasons).
Mainly because xen/libxl API both accept letter as parameter directly, so define enum will need to map enum to letter before calling xen/libxl API.
Mapping from decent public API to under-the-hood API is one of the reasons libvirt exists. I'd rather have a decent API with a nice enum, rather than worrying about which magic char* values work for a particular hypervisor. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Fri, Dec 12, 2014 at 05:04:13PM +0800, Chunyan Liu wrote:
Add public API virDomainSendSysrq for sending SysRequest key.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 ++++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 46 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index ae2c49c..73ef6c8 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -3519,6 +3519,9 @@ int virDomainGetFSInfo(virDomainPtr dom, virDomainFSInfoPtr **info, unsigned int flags);
+/* virDomainSendSysrq */ +int virDomainSendSysrq(virDomainPtr dom, const char *key);
Sysrq is just a single key press, so can't we use 'char key' instead of a string. Also you need to add 'unsigned int flags'. 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 :|

On 12/12/2014 04:04 AM, Chunyan Liu wrote:
Add public API virDomainSendSysrq for sending SysRequest key.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- include/libvirt/libvirt-domain.h | 3 +++ src/driver-hypervisor.h | 4 ++++ src/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 46 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index ae2c49c..73ef6c8 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -3519,6 +3519,9 @@ int virDomainGetFSInfo(virDomainPtr dom, virDomainFSInfoPtr **info, unsigned int flags);
+/* virDomainSendSysrq */ +int virDomainSendSysrq(virDomainPtr dom, const char *key); + int virDomainGetTime(virDomainPtr dom, long long *seconds, unsigned int *nseconds, diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 9f26b13..79558c3 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1170,6 +1170,9 @@ typedef int unsigned int cellCount, unsigned int flags);
+typedef int +(*virDrvDomainSendSysrq)(virDomainPtr dom, const char *key); +
typedef struct _virHypervisorDriver virHypervisorDriver; typedef virHypervisorDriver *virHypervisorDriverPtr; @@ -1396,6 +1399,7 @@ struct _virHypervisorDriver { virDrvConnectGetAllDomainStats connectGetAllDomainStats; virDrvNodeAllocPages nodeAllocPages; virDrvDomainGetFSInfo domainGetFSInfo; + virDrvDomainSendSysrq domainSendSysrq; };
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index cb76d8c..4658fd7 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11192,3 +11192,41 @@ virDomainFSInfoFree(virDomainFSInfoPtr info) VIR_FREE(info->devAlias[i]); VIR_FREE(info->devAlias); } + + +/** + * virDomainSendSysrq: + * @domain: pointer to domain object, or NULL for Domain0 + * @key: SysRq key, like h, c, ... + * + * Send SysRq key to the guest. + *
Try to be more descriptive here - having ellipses (...) in the description is perhaps helpful if you know what the end result is. Treat it like you don't know what it does. If it's going to be an enum, then be sure the enum values are listed somewhere in the docs. Based on the list of possible values - it's useful to list each one and what each is expected to do on the target driver.
+ * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainSendSysrq(virDomainPtr domain, const char *key) +{ + virConnectPtr conn; + VIR_DOMAIN_DEBUG(domain, "key=%s", key); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn = domain->conn;
If/when 'key' is changed to some int/enum value - does a virCheckNonZeroArgGoto() on it make sense? Or any sort of range check? John
+ + virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->domainSendSysrq) { + int ret; + ret = conn->driver->domainSendSysrq(domain, key); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index e4c2df1..80d1dd2 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -688,6 +688,7 @@ LIBVIRT_1.2.11 { global: virDomainFSInfoFree; virDomainGetFSInfo; + virDomainSendSysrq; } LIBVIRT_1.2.9;
# .... define new API here using predicted next version number ....

Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/remote/remote_driver.c | 2 +- src/remote/remote_protocol.x | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 999f16d..97ea64b 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -7941,7 +7941,6 @@ remoteDomainGetFSInfo(virDomainPtr dom, return rv; } - /* get_nonnull_domain and get_nonnull_network turn an on-wire * (name, uuid) pair into virDomainPtr or virNetworkPtr object. * These can return NULL if underlying memory allocations fail, @@ -8285,6 +8284,7 @@ static virHypervisorDriver hypervisor_driver = { .connectGetAllDomainStats = remoteConnectGetAllDomainStats, /* 1.2.8 */ .nodeAllocPages = remoteNodeAllocPages, /* 1.2.9 */ .domainGetFSInfo = remoteDomainGetFSInfo, /* 1.2.11 */ + .domainSendSysrq = remoteDomainSendSysrq, /* 1.2.11 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index cbd3ec7..d988182 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -1084,6 +1084,11 @@ struct remote_domain_send_key_args { unsigned int flags; }; +struct remote_domain_send_sysrq_args { + remote_nonnull_domain dom; + remote_nonnull_string key; +}; + struct remote_domain_send_process_signal_args { remote_nonnull_domain dom; hyper pid_value; @@ -5550,5 +5555,11 @@ enum remote_procedure { * @generate: none * @acl: domain:fs_freeze */ - REMOTE_PROC_DOMAIN_GET_FSINFO = 349 + REMOTE_PROC_DOMAIN_GET_FSINFO = 349, + + /** + * @generate: both + * @acl: domain:send_input + */ + REMOTE_PROC_DOMAIN_SEND_SYSRQ = 350 }; -- 1.8.4.5

On 12/12/14 10:04, Chunyan Liu wrote:
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/remote/remote_driver.c | 2 +- src/remote/remote_protocol.x | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 999f16d..97ea64b 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -7941,7 +7941,6 @@ remoteDomainGetFSInfo(virDomainPtr dom, return rv; }
-
Spurious whitespace change.
/* get_nonnull_domain and get_nonnull_network turn an on-wire * (name, uuid) pair into virDomainPtr or virNetworkPtr object. * These can return NULL if underlying memory allocations fail, @@ -8285,6 +8284,7 @@ static virHypervisorDriver hypervisor_driver = { .connectGetAllDomainStats = remoteConnectGetAllDomainStats, /* 1.2.8 */ .nodeAllocPages = remoteNodeAllocPages, /* 1.2.9 */ .domainGetFSInfo = remoteDomainGetFSInfo, /* 1.2.11 */ + .domainSendSysrq = remoteDomainSendSysrq, /* 1.2.11 */
We are now in freeze for 1.2.11, and thus won't take new features. This needs to change to 1.2.12.
};
static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index cbd3ec7..d988182 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -1084,6 +1084,11 @@ struct remote_domain_send_key_args { unsigned int flags; };
+struct remote_domain_send_sysrq_args { + remote_nonnull_domain dom; + remote_nonnull_string key;
Flags argument needs to be added
+}; + struct remote_domain_send_process_signal_args { remote_nonnull_domain dom; hyper pid_value; @@ -5550,5 +5555,11 @@ enum remote_procedure { * @generate: none * @acl: domain:fs_freeze */ - REMOTE_PROC_DOMAIN_GET_FSINFO = 349 + REMOTE_PROC_DOMAIN_GET_FSINFO = 349, + + /** + * @generate: both + * @acl: domain:send_input + */ + REMOTE_PROC_DOMAIN_SEND_SYSRQ = 350 };
Missing change to remote_protocol-structs. Did you run syntax-check? Peter

On 12/12/2014 at 05:20 PM, in message <548AB36E.30808@redhat.com>, Peter Krempa <pkrempa@redhat.com> wrote: On 12/12/14 10:04, Chunyan Liu wrote: Signed-off-by: Chunyan Liu <cyliu@suse.com>
src/remote/remote_driver.c | 2 +- src/remote/remote_protocol.x | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 999f16d..97ea64b 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -7941,7 +7941,6 @@ remoteDomainGetFSInfo(virDomainPtr dom, return rv; }
-
Spurious whitespace change.
/* get_nonnull_domain and get_nonnull_network turn an on-wire * (name, uuid) pair into virDomainPtr or virNetworkPtr object. * These can return NULL if underlying memory allocations fail, @@ -8285,6 +8284,7 @@ static virHypervisorDriver hypervisor_driver = { .connectGetAllDomainStats = remoteConnectGetAllDomainStats, /* 1.2.8 */ .nodeAllocPages = remoteNodeAllocPages, /* 1.2.9 */ .domainGetFSInfo = remoteDomainGetFSInfo, /* 1.2.11 */ + .domainSendSysrq = remoteDomainSendSysrq, /* 1.2.11 */
We are now in freeze for 1.2.11, and thus won't take new features. This needs to change to 1.2.12.
Thanks, will update.
};
static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index cbd3ec7..d988182 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -1084,6 +1084,11 @@ struct remote_domain_send_key_args { unsigned int flags; };
+struct remote_domain_send_sysrq_args { + remote_nonnull_domain dom; + remote_nonnull_string key;
Flags argument needs to be added
Thanks, will update.
+}; + struct remote_domain_send_process_signal_args { remote_nonnull_domain dom; hyper pid_value; @@ -5550,5 +5555,11 @@ enum remote_procedure { * @generate: none * @acl: domain:fs_freeze */ - REMOTE_PROC_DOMAIN_GET_FSINFO = 349 + REMOTE_PROC_DOMAIN_GET_FSINFO = 349, + + /** + * @generate: both + * @acl: domain:send_input + */ + REMOTE_PROC_DOMAIN_SEND_SYSRQ = 350 };
Missing change to remote_protocol-structs. Did you run syntax-check?
Yes. And I tested the command through 'virsh -c xen+ssh:// to a remote host', then 'sysrq', it works. It still needs to change remote_protocol-strcuts?
Peter

On 12/12/2014 04:04 AM, Chunyan Liu wrote:
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/remote/remote_driver.c | 2 +- src/remote/remote_protocol.x | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 999f16d..97ea64b 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -7941,7 +7941,6 @@ remoteDomainGetFSInfo(virDomainPtr dom, return rv; }
- /* get_nonnull_domain and get_nonnull_network turn an on-wire * (name, uuid) pair into virDomainPtr or virNetworkPtr object. * These can return NULL if underlying memory allocations fail, @@ -8285,6 +8284,7 @@ static virHypervisorDriver hypervisor_driver = { .connectGetAllDomainStats = remoteConnectGetAllDomainStats, /* 1.2.8 */ .nodeAllocPages = remoteNodeAllocPages, /* 1.2.9 */ .domainGetFSInfo = remoteDomainGetFSInfo, /* 1.2.11 */ + .domainSendSysrq = remoteDomainSendSysrq, /* 1.2.11 */ };
static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index cbd3ec7..d988182 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -1084,6 +1084,11 @@ struct remote_domain_send_key_args { unsigned int flags; };
+struct remote_domain_send_sysrq_args { + remote_nonnull_domain dom; + remote_nonnull_string key; +}; + struct remote_domain_send_process_signal_args { remote_nonnull_domain dom; hyper pid_value; @@ -5550,5 +5555,11 @@ enum remote_procedure { * @generate: none * @acl: domain:fs_freeze */ - REMOTE_PROC_DOMAIN_GET_FSINFO = 349 + REMOTE_PROC_DOMAIN_GET_FSINFO = 349, + + /** + * @generate: both + * @acl: domain:send_input + */
Just send_input? The result of the send is essentially 'init_control' right? Like a shutdown. Perhaps even like destroy (eg, 'stop'). Or 'shutdown'... I'm not sure of all the options here, but this seems much more invasive than just sending input because the result of the sent key is a bit more "final". John
+ REMOTE_PROC_DOMAIN_SEND_SYSRQ = 350 };

On 12/12/14 12:49, John Ferlan wrote:
On 12/12/2014 04:04 AM, Chunyan Liu wrote:
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/remote/remote_driver.c | 2 +- src/remote/remote_protocol.x | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-)
struct remote_domain_send_process_signal_args { remote_nonnull_domain dom; hyper pid_value; @@ -5550,5 +5555,11 @@ enum remote_procedure { * @generate: none * @acl: domain:fs_freeze */ - REMOTE_PROC_DOMAIN_GET_FSINFO = 349 + REMOTE_PROC_DOMAIN_GET_FSINFO = 349, + + /** + * @generate: both + * @acl: domain:send_input + */
Just send_input? The result of the send is essentially 'init_control' right? Like a shutdown. Perhaps even like destroy (eg, 'stop'). Or 'shutdown'... I'm not sure of all the options here, but this seems much more invasive than just sending input because the result of the sent key is a bit more "final".
Since you are able to do the same thing with the virDomainSendKey API which has the same ACL class: virsh send-key dom KEY_LEFTALT KEY_SYSRQ KEY_O I don't think it should require any other permission since it's just a keystroke basically. Peter
John
+ REMOTE_PROC_DOMAIN_SEND_SYSRQ = 350 };
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On Fri, Dec 12, 2014 at 01:24:57PM +0100, Peter Krempa wrote:
On 12/12/14 12:49, John Ferlan wrote:
On 12/12/2014 04:04 AM, Chunyan Liu wrote:
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/remote/remote_driver.c | 2 +- src/remote/remote_protocol.x | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-)
struct remote_domain_send_process_signal_args { remote_nonnull_domain dom; hyper pid_value; @@ -5550,5 +5555,11 @@ enum remote_procedure { * @generate: none * @acl: domain:fs_freeze */ - REMOTE_PROC_DOMAIN_GET_FSINFO = 349 + REMOTE_PROC_DOMAIN_GET_FSINFO = 349, + + /** + * @generate: both + * @acl: domain:send_input + */
Just send_input? The result of the send is essentially 'init_control' right? Like a shutdown. Perhaps even like destroy (eg, 'stop'). Or 'shutdown'... I'm not sure of all the options here, but this seems much more invasive than just sending input because the result of the sent key is a bit more "final".
Since you are able to do the same thing with the virDomainSendKey API which has the same ACL class:
virsh send-key dom KEY_LEFTALT KEY_SYSRQ KEY_O
I don't think it should require any other permission since it's just a keystroke basically.
Agreed, 'send_input' basically gives away the keys to the kingdom, so there's nothing to gain by having a separate permission for this new API As a general rule we should always seek to reuse existing permissions because we don't want to end up having one permission for each separate API 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 :|

On 12/12/2014 at 09:38 PM, in message <20141212133825.GJ32050@redhat.com>, "Daniel P. Berrange" <berrange@redhat.com> wrote: On Fri, Dec 12, 2014 at 01:24:57PM +0100, Peter Krempa wrote: On 12/12/14 12:49, John Ferlan wrote:
On 12/12/2014 04:04 AM, Chunyan Liu wrote:
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/remote/remote_driver.c | 2 +- src/remote/remote_protocol.x | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-)
struct remote_domain_send_process_signal_args { remote_nonnull_domain dom; hyper pid_value; @@ -5550,5 +5555,11 @@ enum remote_procedure { * @generate: none * @acl: domain:fs_freeze */ - REMOTE_PROC_DOMAIN_GET_FSINFO = 349 + REMOTE_PROC_DOMAIN_GET_FSINFO = 349, + + /** + * @generate: both + * @acl: domain:send_input + */
Just send_input? The result of the send is essentially 'init_control' right? Like a shutdown. Perhaps even like destroy (eg, 'stop'). Or 'shutdown'... I'm not sure of all the options here, but this seems much more invasive than just sending input because the result of the sent key is a bit more "final".
Since you are able to do the same thing with the virDomainSendKey API which has the same ACL class:
virsh send-key dom KEY_LEFTALT KEY_SYSRQ KEY_O
I don't think it should require any other permission since it's just a keystroke basically.
Agreed, 'send_input' basically gives away the keys to the kingdom, so there's nothing to gain by having a separate permission for this new API
As a general rule we should always seek to reuse existing permissions because we don't want to end up having one permission for each separate API
Got it. Thanks.
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 :|

All domainSendSysrq related API should be manageable from the virsh command line. So, expose 'virsh sysrq' command. Signed-off-by: Chunyan Liu <cyliu@suse.com> --- tools/virsh-domain.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 750411b..6a1e4fd 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -12289,6 +12289,54 @@ cmdDomFSInfo(vshControl *ctl, const vshCmd *cmd) return ret >= 0; } +/* + * "sysrq" command + */ +static const vshCmdInfo info_sysrq[] = { + {.name = "help", + .data = N_("Send SysRq key to the guest") + }, + {.name = "desc", + .data = N_("Send SysRq key to the guest") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_sysrq[] = { + {.name = "domain", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("domain name, id or uuid") + }, + {.name = "key", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("the SysRq key") + }, + {.name = NULL} +}; + +static bool +cmdSysrq(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + bool ret = false; + const char *key = NULL; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (vshCommandOptStringReq(ctl, cmd, "key", &key) < 0) + return false; + + if (!(virDomainSendSysrq(dom, key) < 0)) + ret = true; + + virDomainFree(dom); + return ret; +} + + const vshCmdDef domManagementCmds[] = { {.name = "attach-device", .handler = cmdAttachDevice, @@ -12808,5 +12856,11 @@ const vshCmdDef domManagementCmds[] = { .info = info_vncdisplay, .flags = 0 }, + {.name = "sysrq", + .handler = cmdSysrq, + .opts = opts_sysrq, + .info = info_sysrq, + .flags = 0 + }, {.name = NULL} }; -- 1.8.4.5

Support .domainSendSysrq in libxl driver. Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/libxl/libxl_driver.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 53c87ce..0830d68 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -4729,6 +4729,28 @@ libxlDomainMigrateConfirm3Params(virDomainPtr domain, return libxlDomainMigrationConfirm(driver, vm, flags, cancelled); } +static int +libxlDomainSendSysrq(virDomainPtr dom, const char *key) +{ + virDomainObjPtr vm; + libxlDomainObjPrivatePtr priv; + int ret = -1; + + if (!(vm = libxlDomObjFromDomain(dom))) + goto cleanup; + + priv = vm->privateData; + + if (virDomainSendSysrqEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + ret = libxl_send_sysrq(priv->ctx, vm->def->id, key[0]); + + cleanup: + if (vm) + virObjectUnlock(vm); + return ret; +} static virHypervisorDriver libxlDriver = { .no = VIR_DRV_LIBXL, @@ -4824,6 +4846,7 @@ static virHypervisorDriver libxlDriver = { .domainMigratePerform3Params = libxlDomainMigratePerform3Params, /* 1.2.6 */ .domainMigrateFinish3Params = libxlDomainMigrateFinish3Params, /* 1.2.6 */ .domainMigrateConfirm3Params = libxlDomainMigrateConfirm3Params, /* 1.2.6 */ + .domainSendSysrq = libxlDomainSendSysrq, /* 1.2.11 */ }; static virStateDriver libxlStateDriver = { -- 1.8.4.5

Support .domainSendSysrq in xen driver. Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/xen/xen_driver.c | 19 +++++++++++++++++++ src/xen/xend_internal.c | 20 ++++++++++++++++++++ src/xen/xend_internal.h | 2 ++ 3 files changed, 41 insertions(+) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index c9f4159..e2b01cf 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -2738,6 +2738,24 @@ xenUnifiedNodeSuspendForDuration(virConnectPtr conn, return nodeSuspendForDuration(target, duration, flags); } +static int +xenUnifiedDomainSendSysrq(virDomainPtr dom, const char *key) +{ + int ret = -1; + virDomainDefPtr def = NULL; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (virDomainSendSysrqEnsureACL(dom->conn, def) < 0) + goto cleanup; + + ret = xenDaemonDomainSysrq(dom->conn, def, key); + + cleanup: + virDomainDefFree(def); + return ret; +} /*----- Register with libvirt.c, and initialize Xen drivers. -----*/ @@ -2836,6 +2854,7 @@ static virHypervisorDriver xenUnifiedDriver = { .nodeSuspendForDuration = xenUnifiedNodeSuspendForDuration, /* 0.9.8 */ .nodeGetMemoryParameters = xenUnifiedNodeGetMemoryParameters, /* 0.10.2 */ .nodeSetMemoryParameters = xenUnifiedNodeSetMemoryParameters, /* 0.10.2 */ + .domainSendSysrq = xenUnifiedDomainSendSysrq, /* 1.2.11 */ }; /** diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index b233b6b..62b6e31 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -3300,6 +3300,26 @@ xenDaemonDomainBlockPeek(virConnectPtr conn, return ret; } +/* + * xenDaemonDomainSysrq: + * <at> conn: the connection object + * <at> def: the domain to destroy + * + * Send a sysrq to a domain. + * + * Returns 0 in case of success, -1 (with errno) in case of error. + */ +int +xenDaemonDomainSysrq(virConnectPtr conn, virDomainDefPtr def, const char *key) +{ + if (def->id < 0) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("Domain %s isn't running."), def->name); + return -1; + } + + return xend_op(conn, def->name, "op", "sysrq", "key", key, NULL); +} /** * virDomainXMLDevID: diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 814330d..26ab5e3 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -213,5 +213,7 @@ int xenDaemonSetSchedulerParameters(virConnectPtr conn, virDomainDefPtr def, virTypedParameterPtr params, int nparams); +int xenDaemonDomainSysrq(virConnectPtr conn, virDomainDefPtr def, + const char *key); #endif /* __XEND_INTERNAL_H_ */ -- 1.8.4.5
participants (7)
-
Chun Yan Liu
-
Chunyan Liu
-
Daniel P. Berrange
-
Eric Blake
-
Jiri Denemark
-
John Ferlan
-
Peter Krempa