Jim Meyering wrote:
> Dave Leskovec <[EMAIL PROTECTED]> wrote:
>> Jim Meyering wrote:
>>> Dave Leskovec <[EMAIL PROTECTED]> wrote:
...
>> Index: b/qemud/qemud.c
>> ===================================================================
> ...
>> +static void sig_handler(int sig, siginfo_t * siginfo,
>> + void* context ATTRIBUTE_UNUSED) {
> ...
>> - unsigned char sigc;
>> + siginfo_t siginfo;
>> int ret;
>>
>> - if (read(server->sigread, &sigc, 1) != 1) {
>> + if (read(server->sigread, &siginfo, sizeof(siginfo)) !=
>> sizeof(siginfo)) {
>
> Looks good, but that should be saferead instead of "read".
> Now that it's reading more than one byte, EINTR can make a difference.
>
This latest version of this patch changes the read() to a saferead() as Jim
points out.
--
Best Regards,
Dave Leskovec
IBM Linux Technology Center
Open Virtualization
---
qemud/qemud.c | 26 ++++++----
src/driver.h | 4 +
src/internal.h | 2
src/libvirt.c | 11 ++++
src/libvirt_sym.version | 1
src/lxc_driver.c | 114 +++++++++++++++++++++++++++++++++++-------------
src/qemu_driver.c | 1
src/remote_internal.c | 1
src/storage_driver.c | 1
9 files changed, 120 insertions(+), 41 deletions(-)
Index: b/qemud/qemud.c
===================================================================
--- a/qemud/qemud.c 2008-04-28 02:09:52.000000000 -0700
+++ b/qemud/qemud.c 2008-05-07 13:03:31.000000000 -0700
@@ -109,16 +109,16 @@
static sig_atomic_t sig_errors = 0;
static int sig_lasterrno = 0;
-static void sig_handler(int sig) {
- unsigned char sigc = sig;
+static void sig_handler(int sig, siginfo_t * siginfo,
+ void* context ATTRIBUTE_UNUSED) {
int origerrno;
int r;
- if (sig == SIGCHLD) /* We explicitly waitpid the child later */
- return;
+ /* set the sig num in the struct */
+ siginfo->si_signo = sig;
origerrno = errno;
- r = safewrite(sigwrite, &sigc, 1);
+ r = safewrite(sigwrite, siginfo, sizeof(*siginfo));
if (r == -1) {
sig_errors++;
sig_lasterrno = errno;
@@ -232,10 +232,10 @@
int events ATTRIBUTE_UNUSED,
void *opaque) {
struct qemud_server *server = (struct qemud_server *)opaque;
- unsigned char sigc;
+ siginfo_t siginfo;
int ret;
- if (read(server->sigread, &sigc, 1) != 1) {
+ if (saferead(server->sigread, &siginfo, sizeof(siginfo)) != sizeof(siginfo)) {
qemudLog(QEMUD_ERR, _("Failed to read from signal pipe: %s"),
strerror(errno));
return;
@@ -243,7 +243,7 @@
ret = 0;
- switch (sigc) {
+ switch (siginfo.si_signo) {
case SIGHUP:
qemudLog(QEMUD_INFO, "%s", _("Reloading configuration on SIGHUP"));
if (virStateReload() < 0)
@@ -253,11 +253,15 @@
case SIGINT:
case SIGQUIT:
case SIGTERM:
- qemudLog(QEMUD_WARN, _("Shutting down on signal %d"), sigc);
+ qemudLog(QEMUD_WARN, _("Shutting down on signal %d"),
+ siginfo.si_signo);
server->shutdown = 1;
break;
default:
+ qemudLog(QEMUD_INFO, _("Received signal %d, dispatching to drivers"),
+ siginfo.si_signo);
+ virStateSigDispatcher(&siginfo);
break;
}
@@ -2186,8 +2190,8 @@
goto error1;
}
- sig_action.sa_handler = sig_handler;
- sig_action.sa_flags = 0;
+ sig_action.sa_sigaction = sig_handler;
+ sig_action.sa_flags = SA_SIGINFO;
sigemptyset(&sig_action.sa_mask);
sigaction(SIGHUP, &sig_action, NULL);
Index: b/src/driver.h
===================================================================
--- a/src/driver.h 2008-04-10 09:54:54.000000000 -0700
+++ b/src/driver.h 2008-05-05 23:28:40.000000000 -0700
@@ -11,6 +11,8 @@
#include <libxml/uri.h>
+#include <signal.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -565,6 +567,7 @@
typedef int (*virDrvStateCleanup) (void);
typedef int (*virDrvStateReload) (void);
typedef int (*virDrvStateActive) (void);
+typedef int (*virDrvSigHandler) (siginfo_t *siginfo);
typedef struct _virStateDriver virStateDriver;
typedef virStateDriver *virStateDriverPtr;
@@ -574,6 +577,7 @@
virDrvStateCleanup cleanup;
virDrvStateReload reload;
virDrvStateActive active;
+ virDrvSigHandler sigHandler;
};
/*
Index: b/src/internal.h
===================================================================
--- a/src/internal.h 2008-04-28 14:44:54.000000000 -0700
+++ b/src/internal.h 2008-04-30 15:01:24.000000000 -0700
@@ -344,10 +344,12 @@
int __virStateCleanup(void);
int __virStateReload(void);
int __virStateActive(void);
+int __virStateSigDispatcher(siginfo_t *siginfo);
#define virStateInitialize() __virStateInitialize()
#define virStateCleanup() __virStateCleanup()
#define virStateReload() __virStateReload()
#define virStateActive() __virStateActive()
+#define virStateSigDispatcher(s) __virStateSigDispatcher(s)
int __virDrvSupportsFeature (virConnectPtr conn, int feature);
Index: b/src/libvirt.c
===================================================================
--- a/src/libvirt.c 2008-04-10 09:54:54.000000000 -0700
+++ b/src/libvirt.c 2008-04-30 15:01:24.000000000 -0700
@@ -607,6 +607,17 @@
return ret;
}
+int __virStateSigDispatcher(siginfo_t *siginfo) {
+ int i, ret = 0;
+
+ for (i = 0 ; i < virStateDriverTabCount ; i++) {
+ if (virStateDriverTab[i]->sigHandler &&
+ virStateDriverTab[i]->sigHandler(siginfo))
+ ret = 1;
+ }
+ return ret;
+}
+
/**
Index: b/src/libvirt_sym.version
===================================================================
--- a/src/libvirt_sym.version 2008-04-28 08:14:59.000000000 -0700
+++ b/src/libvirt_sym.version 2008-04-30 15:01:24.000000000 -0700
@@ -170,6 +170,7 @@
__virStateCleanup;
__virStateReload;
__virStateActive;
+ __virStateSigDispatcher;
__virDrvSupportsFeature;
Index: b/src/lxc_driver.c
===================================================================
--- a/src/lxc_driver.c 2008-04-10 09:53:29.000000000 -0700
+++ b/src/lxc_driver.c 2008-05-07 12:48:06.000000000 -0700
@@ -841,55 +841,42 @@
}
/**
- * lxcDomainDestroy:
- * @dom: Ptr to domain to destroy
+ * lxcVmCleanup:
+ * @vm: Ptr to VM to clean up
*
- * Sends SIGKILL to container root process to terminate the container
+ * waitpid() on the container process. kill and wait the tty process
+ * This is called by boh lxcDomainDestroy and lxcSigHandler when a
+ * container exits.
*
* Returns 0 on success or -1 in case of error
*/
-static int lxcDomainDestroy(virDomainPtr dom)
+static int lxcVMCleanup(lxc_driver_t *driver, lxc_vm_t * vm)
{
int rc = -1;
int waitRc;
- lxc_driver_t *driver = (lxc_driver_t*)dom->conn->privateData;
- lxc_vm_t *vm = lxcFindVMByID(driver, dom->id);
- int childStatus;
-
- if (!vm) {
- lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
- _("no domain with id %d"), dom->id);
- goto error_out;
- }
-
- if (0 > (kill(vm->def->id, SIGKILL))) {
- if (ESRCH != errno) {
- lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
- _("sending SIGKILL failed: %s"), strerror(errno));
-
- goto error_out;
- }
- }
-
- vm->state = VIR_DOMAIN_SHUTDOWN;
+ int childStatus = -1;
while (((waitRc = waitpid(vm->def->id, &childStatus, 0)) == -1) &&
errno == EINTR);
if (waitRc != vm->def->id) {
- lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
+ lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("waitpid failed to wait for container %d: %d %s"),
vm->def->id, waitRc, strerror(errno));
goto kill_tty;
}
- rc = WEXITSTATUS(childStatus);
- DEBUG("container exited with rc: %d", rc);
+ rc = 0;
+
+ if (WIFEXITED(childStatus)) {
+ rc = WEXITSTATUS(childStatus);
+ DEBUG("container exited with rc: %d", rc);
+ }
kill_tty:
if (0 > (kill(vm->pid, SIGKILL))) {
if (ESRCH != errno) {
- lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
+ lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("sending SIGKILL to tty process failed: %s"),
strerror(errno));
@@ -901,7 +888,7 @@
errno == EINTR);
if (waitRc != vm->pid) {
- lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
+ lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("waitpid failed to wait for tty %d: %d %s"),
vm->pid, waitRc, strerror(errno));
}
@@ -912,8 +899,43 @@
vm->def->id = -1;
driver->nactivevms--;
driver->ninactivevms++;
+ lxcSaveConfig(NULL, driver, vm, vm->def);
- rc = 0;
+ return rc;
+ }
+
+/**
+ * lxcDomainDestroy:
+ * @dom: Ptr to domain to destroy
+ *
+ * Sends SIGKILL to container root process to terminate the container
+ *
+ * Returns 0 on success or -1 in case of error
+ */
+static int lxcDomainDestroy(virDomainPtr dom)
+{
+ int rc = -1;
+ lxc_driver_t *driver = (lxc_driver_t*)dom->conn->privateData;
+ lxc_vm_t *vm = lxcFindVMByID(driver, dom->id);
+
+ if (!vm) {
+ lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
+ _("no domain with id %d"), dom->id);
+ goto error_out;
+ }
+
+ if (0 > (kill(vm->def->id, SIGKILL))) {
+ if (ESRCH != errno) {
+ lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
+ _("sending SIGKILL failed: %s"), strerror(errno));
+
+ goto error_out;
+ }
+ }
+
+ vm->state = VIR_DOMAIN_SHUTDOWN;
+
+ rc = lxcVMCleanup(driver, vm);
error_out:
return rc;
@@ -993,6 +1015,37 @@
return 0;
}
+/**
+ * lxcSigHandler:
+ * @siginfo: Pointer to siginfo_t structure
+ *
+ * Handles signals received by libvirtd. Currently this is used to
+ * catch SIGCHLD from an exiting container.
+ *
+ * Returns 0 on success or -1 in case of error
+ */
+static int lxcSigHandler(siginfo_t *siginfo)
+{
+ int rc = -1;
+ lxc_vm_t *vm;
+
+ if (siginfo->si_signo == SIGCHLD) {
+ vm = lxcFindVMByID(lxc_driver, siginfo->si_pid);
+
+ if (NULL == vm) {
+ DEBUG("Ignoring SIGCHLD from non-container process %d\n",
+ siginfo->si_pid);
+ goto cleanup;
+ }
+
+ rc = lxcVMCleanup(lxc_driver, vm);
+
+ }
+
+cleanup:
+ return rc;
+}
+
/* Function Tables */
static virDriver lxcDriver = {
@@ -1061,6 +1114,7 @@
lxcShutdown,
NULL, /* reload */
lxcActive,
+ lxcSigHandler
};
int lxcRegister(void)
Index: b/src/qemu_driver.c
===================================================================
--- a/src/qemu_driver.c 2008-04-25 13:46:13.000000000 -0700
+++ b/src/qemu_driver.c 2008-04-30 15:01:24.000000000 -0700
@@ -3133,6 +3133,7 @@
qemudShutdown,
qemudReload,
qemudActive,
+ NULL
};
int qemudRegister(void) {
Index: b/src/remote_internal.c
===================================================================
--- a/src/remote_internal.c 2008-04-29 12:43:57.000000000 -0700
+++ b/src/remote_internal.c 2008-05-07 12:48:04.000000000 -0700
@@ -4794,6 +4794,7 @@
NULL,
NULL,
NULL,
+ NULL
};
Index: b/src/storage_driver.c
===================================================================
--- a/src/storage_driver.c 2008-04-18 01:33:23.000000000 -0700
+++ b/src/storage_driver.c 2008-05-05 23:35:34.000000000 -0700
@@ -1245,6 +1245,7 @@
storageDriverShutdown,
storageDriverReload,
storageDriverActive,
+ NULL
};
int storageRegister(void) {
--
Libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list