From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Add an API for sending signals to arbitrary processes in the guest OS. This is primarily useful for container based virt, but can be used for machine virt too, if there is a suitable guest agent, * include/libvirt/libvirt.h.in: Add virDomainSendProcessSignal and virDomainProcessSignal enum * src/driver.h: Driver entry point * src/libvirt.c, src/libvirt_public.syms: Impl for new API --- include/libvirt/libvirt.h.in | 60 ++++++++++++++++++++++++++++++++++++ src/driver.h | 7 +++++ src/libvirt.c | 72 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ 4 files changed, 144 insertions(+) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 84dcde1..38ffebb 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2989,6 +2989,66 @@ int virDomainSendKey(virDomainPtr domain, unsigned int flags); /* + * These just happen to match Linux signal numbers. The numbers + * will be mapped to whatever the SIGNUM is in the guest OS in + * question by the agent delivering the signal. The names are + * based on the POSIX / XSI signal standard though. + * + * Values over VIR_DOMAIN_PROCESS_SIGNAL_RTMIN are allowed, + * and will be mapped to the corresponding offset of the + * OS specific SIGRTMIN value + */ +typedef enum { + VIR_DOMAIN_PROCESS_SIGNAL_NOP = 0, /* No constant in POSIX/Linux */ + VIR_DOMAIN_PROCESS_SIGNAL_HUP = 1, /* SIGHUP */ + VIR_DOMAIN_PROCESS_SIGNAL_INT = 2, /* SIGINT */ + VIR_DOMAIN_PROCESS_SIGNAL_QUIT = 3, /* SIGQUIT */ + VIR_DOMAIN_PROCESS_SIGNAL_ILL = 4, /* SIGILL */ + VIR_DOMAIN_PROCESS_SIGNAL_TRAP = 5, /* SIGTRAP */ + VIR_DOMAIN_PROCESS_SIGNAL_ABRT = 6, /* SIGABRT */ + VIR_DOMAIN_PROCESS_SIGNAL_BUS = 7, /* SIGBUS */ + VIR_DOMAIN_PROCESS_SIGNAL_FPE = 8, /* SIGFPE */ + VIR_DOMAIN_PROCESS_SIGNAL_KILL = 9, /* SIGKILL */ + VIR_DOMAIN_PROCESS_SIGNAL_USR1 = 10, /* SIGUSR1 */ + VIR_DOMAIN_PROCESS_SIGNAL_SEGV = 11, /* SIGSEGV */ + VIR_DOMAIN_PROCESS_SIGNAL_USR2 = 12, /* SIGUSR2 */ + VIR_DOMAIN_PROCESS_SIGNAL_PIPE = 13, /* SIGPIPE */ + VIR_DOMAIN_PROCESS_SIGNAL_ALRM = 14, /* SIGALRM */ + VIR_DOMAIN_PROCESS_SIGNAL_TERM = 15, /* SIGTERM */ + VIR_DOMAIN_PROCESS_SIGNAL_STKFLT = 16, /* Not in POSIX (SIGSTKFLT on Linux )*/ + VIR_DOMAIN_PROCESS_SIGNAL_CHLD = 17, /* SIGCHLD */ + VIR_DOMAIN_PROCESS_SIGNAL_CONT = 18, /* SIGCONT */ + VIR_DOMAIN_PROCESS_SIGNAL_STOP = 19, /* SIGSTOP */ + VIR_DOMAIN_PROCESS_SIGNAL_TSTP = 20, /* SIGTSTP */ + VIR_DOMAIN_PROCESS_SIGNAL_TTIN = 21, /* SIGTTIN */ + VIR_DOMAIN_PROCESS_SIGNAL_TTOU = 22, /* SIGTTOU */ + VIR_DOMAIN_PROCESS_SIGNAL_URG = 23, /* SIGURG */ + VIR_DOMAIN_PROCESS_SIGNAL_XCPU = 24, /* SIGXCPU */ + VIR_DOMAIN_PROCESS_SIGNAL_XFSZ = 25, /* SIGXFSZ */ + VIR_DOMAIN_PROCESS_SIGNAL_VTALRM = 26, /* SIGVTALRM */ + VIR_DOMAIN_PROCESS_SIGNAL_PROF = 27, /* SIGPROF */ + VIR_DOMAIN_PROCESS_SIGNAL_WINCH = 28, /* Not in POSIX (SIGWINCH on Linux) */ + VIR_DOMAIN_PROCESS_SIGNAL_POLL = 29, /* SIGPOLL (also known as SIGIO on Linux) */ + VIR_DOMAIN_PROCESS_SIGNAL_PWR = 30, /* Not in POSIX (SIGPWR on Linux */ + VIR_DOMAIN_PROCESS_SIGNAL_SYS = 31, /* SIGSYS (also known as SIGUNUSED on Linux ) */ + + VIR_DOMAIN_PROCESS_SIGNAL_RTMIN = 32, /* SIGRTMIN */ + +#ifdef VIR_ENUM_SENTINELS + /* This is the "last" signal only in so much as none + * of the latter ones have named constants. They are + * just numeric offsets from RTMIN upwards + */ + VIR_DOMAIN_PROCESS_SIGNAL_LAST +#endif +} virDomainProcessSignal; + +int virDomainSendProcessSignal(virDomainPtr domain, + unsigned int pid_value, + unsigned int signum, + unsigned int flags); + +/* * Deprecated calls */ virDomainPtr virDomainCreateLinux (virConnectPtr conn, diff --git a/src/driver.h b/src/driver.h index 7ba66ad..de58628 100644 --- a/src/driver.h +++ b/src/driver.h @@ -732,6 +732,12 @@ typedef int int nkeycodes, unsigned int flags); +typedef int + (*virDrvDomainSendProcessSignal)(virDomainPtr dom, + unsigned int pid_value, + unsigned int signum, + unsigned int flags); + typedef char * (*virDrvDomainMigrateBegin3) (virDomainPtr domain, @@ -1094,6 +1100,7 @@ struct _virDriver { virDrvNodeGetMemoryParameters nodeGetMemoryParameters; virDrvNodeSetMemoryParameters nodeSetMemoryParameters; virDrvNodeGetCPUMap nodeGetCPUMap; + virDrvDomainSendProcessSignal domainSendProcessSignal; }; typedef int diff --git a/src/libvirt.c b/src/libvirt.c index 4af6089..83550cd 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -8589,6 +8589,78 @@ error: return -1; } + +/** + * virDomainSendProcessSignal: + * @domain: pointer to domain object + * @pid_value: a positive integer process ID greater than zero + * @signum: a signal from the virDomainProcessSignal enum + * @flags: one of the virDomainProcessSignalFlag values + * + * Send a signal to the designated process in the guest + * + * The signal numbers must be taken from the virDomainProcessSignal + * enum. These will be translated to the corresponding signal + * number for the guest OS, by the guest agent delivering the + * signal. + * + * The @pid_value must specify a process ID greater than zero. The + * @pid_value numbers are from the container/guest namespace. + * + * If the @signum is VIR_DOMAIN_PROCESS_SIGNAL_NOP then this + * API will simply report whether the process is running in + * the container/guest + * + * Returns 0 in case of success, -1 in case of failure. + */ +int virDomainSendProcessSignal(virDomainPtr domain, + unsigned int pid_value, + unsigned int signum, + unsigned int flags) +{ + virConnectPtr conn; + VIR_DOMAIN_DEBUG(domain, "pid=%u, signum=%u flags=%x", + pid_value, signum, flags); + + virResetLastError(); + + if (pid_value == 0) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + if (domain->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + conn = domain->conn; + + if (conn->driver->domainSendProcessSignal) { + int ret; + ret = conn->driver->domainSendProcessSignal(domain, + pid_value, + signum, + flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + + /** * virDomainSetVcpus: * @domain: pointer to domain object, or NULL for Domain0 diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index f494821..302fce5 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -574,4 +574,9 @@ LIBVIRT_1.0.0 { virNodeGetCPUMap; } LIBVIRT_0.10.2; +LIBVIRT_1.0.1 { + global: + virDomainSendProcessSignal; +} LIBVIRT_1.0.0; + # .... define new API here using predicted next version number .... -- 1.7.11.7 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list