From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Jackson Subject: [PATCH 11/29] libxl: events: Make libxl__async_exec_* pass caller an rc Date: Tue, 10 Feb 2015 20:09:58 +0000 Message-ID: <1423599016-32639-12-git-send-email-ian.jackson@eu.citrix.com> References: <1423599016-32639-1-git-send-email-ian.jackson@eu.citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1423599016-32639-1-git-send-email-ian.jackson@eu.citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xensource.com Cc: Ian Jackson , Euan Harris List-Id: xen-devel@lists.xenproject.org The internal user of libxl__async_exec_start et al now gets an rc as well as the process's exit status. For now this is always either 0 or ERROR_FAIL, but with ao cancellation this will possibly be CANCELLED or TIMEDOUT too. Signed-off-by: Ian Jackson --- v2: New patch due to rebause; v1 had changes to device_hotplug_* scripts instead. Callback now gets unambiguous information about error situation: previously, if only thing that went wrong was that child died badly, rc would be FAILED, which was unambigously; now rc=0. Add a comment document the meaning of the rc and status parameters to the callback. --- tools/libxl/libxl_aoutils.c | 9 ++++++--- tools/libxl/libxl_device.c | 13 +++++++++---- tools/libxl/libxl_internal.h | 11 ++++++++++- tools/libxl/libxl_netbuffer.c | 19 ++++++++++--------- tools/libxl/libxl_remus_disk_drbd.c | 8 +++++--- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/tools/libxl/libxl_aoutils.c b/tools/libxl/libxl_aoutils.c index 754e2d1..891cdb8 100644 --- a/tools/libxl/libxl_aoutils.c +++ b/tools/libxl/libxl_aoutils.c @@ -483,11 +483,12 @@ static void async_exec_done(libxl__egc *egc, libxl__ev_time_deregister(gc, &aes->time); if (status) { - libxl_report_child_exitstatus(CTX, LIBXL__LOG_ERROR, - aes->what, pid, status); + if (!aes->rc) + libxl_report_child_exitstatus(CTX, LIBXL__LOG_ERROR, + aes->what, pid, status); } - aes->callback(egc, aes, status); + aes->callback(egc, aes, aes->rc, status); } void libxl__async_exec_init(libxl__async_exec_state *aes) @@ -506,6 +507,8 @@ int libxl__async_exec_start(libxl__async_exec_state *aes) libxl__ev_child *const child = &aes->child; char ** const args = aes->args; + aes->rc = 0; + /* Set execution timeout */ if (libxl__ev_time_register_rel(ao, &aes->time, async_exec_timeout, diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index c80749f..84114ff 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -729,7 +729,7 @@ static void device_hotplug(libxl__egc *egc, libxl__ao_device *aodev); static void device_hotplug_child_death_cb(libxl__egc *egc, libxl__async_exec_state *aes, - int status); + int rc, int status); static void device_destroy_be_watch_cb(libxl__egc *egc, libxl__xswait_state *xswait, @@ -1052,7 +1052,7 @@ out: static void device_hotplug_child_death_cb(libxl__egc *egc, libxl__async_exec_state *aes, - int status) + int rc, int status) { libxl__ao_device *aodev = CONTAINER_OF(aes, *aodev, aes); STATE_AO_GC(aodev->ao); @@ -1061,12 +1061,17 @@ static void device_hotplug_child_death_cb(libxl__egc *egc, device_hotplug_clean(gc, aodev); - if (status) { + if (status && !rc) { hotplug_error = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/hotplug-error", be_path)); if (hotplug_error) LOG(ERROR, "script: %s", hotplug_error); - aodev->rc = ERROR_FAIL; + rc = ERROR_FAIL; + } + + if (rc) { + if (!aodev->rc) + aodev->rc = rc; if (aodev->action == LIBXL__DEVICE_ACTION_ADD) /* * Only fail on device connection, on disconnection diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index b615fc5..02cac7b 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2089,7 +2089,15 @@ _hidden const char *libxl__run_dir_path(void); typedef struct libxl__async_exec_state libxl__async_exec_state; typedef void libxl__async_exec_callback(libxl__egc *egc, - libxl__async_exec_state *aes, int status); + libxl__async_exec_state *aes, int rc, int status); +/* + * Meaning of status and rc: + * rc==0, status==0 all went well + * rc==0, status!=0 everything OK except child exited nonzero (logged) + * rc!=0 something else went wrong (status is real + * exit status, maybe reflecting SIGKILL if aes + * code killed the child). Logged unless CANCELLED. + */ struct libxl__async_exec_state { /* caller must fill these in */ @@ -2105,6 +2113,7 @@ struct libxl__async_exec_state { /* private */ libxl__ev_time time; libxl__ev_child child; + int rc; }; void libxl__async_exec_init(libxl__async_exec_state *aes); diff --git a/tools/libxl/libxl_netbuffer.c b/tools/libxl/libxl_netbuffer.c index edc6843..ff2d6c7 100644 --- a/tools/libxl/libxl_netbuffer.c +++ b/tools/libxl/libxl_netbuffer.c @@ -219,10 +219,10 @@ out: static void netbuf_setup_script_cb(libxl__egc *egc, libxl__async_exec_state *aes, - int status); + int rc, int status); static void netbuf_teardown_script_cb(libxl__egc *egc, libxl__async_exec_state *aes, - int status); + int rc, int status); /* * the script needs the following env & args @@ -327,14 +327,13 @@ out: */ static void netbuf_setup_script_cb(libxl__egc *egc, libxl__async_exec_state *aes, - int status) + int rc, int status) { libxl__ao_device *aodev = CONTAINER_OF(aes, *aodev, aes); libxl__remus_device *dev = CONTAINER_OF(aodev, *dev, aodev); libxl__remus_device_nic *remus_nic = dev->concrete_data; libxl__remus_devices_state *rds = dev->rds; const char *out_path_base, *hotplug_error = NULL; - int rc; STATE_AO_GC(rds->ao); @@ -344,6 +343,11 @@ static void netbuf_setup_script_cb(libxl__egc *egc, const char *const vif = remus_nic->vif; const char **const ifb = &remus_nic->ifb; + if (status && !rc) + rc = ERROR_FAIL; + if (rc) + goto out; + /* * we need to get ifb first because it's needed for teardown */ @@ -411,17 +415,14 @@ out: static void netbuf_teardown_script_cb(libxl__egc *egc, libxl__async_exec_state *aes, - int status) + int rc, int status) { - int rc; libxl__ao_device *aodev = CONTAINER_OF(aes, *aodev, aes); libxl__remus_device *dev = CONTAINER_OF(aodev, *dev, aodev); libxl__remus_device_nic *remus_nic = dev->concrete_data; - if (status) + if (status && !rc) rc = ERROR_FAIL; - else - rc = 0; free_qdisc(remus_nic); diff --git a/tools/libxl/libxl_remus_disk_drbd.c b/tools/libxl/libxl_remus_disk_drbd.c index 5e0c9a6..fc76b89 100644 --- a/tools/libxl/libxl_remus_disk_drbd.c +++ b/tools/libxl/libxl_remus_disk_drbd.c @@ -78,7 +78,7 @@ out: /* callbacks */ static void match_async_exec_cb(libxl__egc *egc, libxl__async_exec_state *aes, - int status); + int rc, int status); /* implementations */ @@ -133,9 +133,8 @@ out: static void match_async_exec_cb(libxl__egc *egc, libxl__async_exec_state *aes, - int status) + int rc, int status) { - int rc; libxl__ao_device *aodev = CONTAINER_OF(aes, *aodev, aes); libxl__remus_device *dev = CONTAINER_OF(aodev, *dev, aodev); libxl__remus_drbd_disk *drbd_disk; @@ -143,6 +142,9 @@ static void match_async_exec_cb(libxl__egc *egc, STATE_AO_GC(aodev->ao); + if (rc) + goto out; + if (status) { rc = ERROR_REMUS_DEVOPS_DOES_NOT_MATCH; /* BUG: seems to assume that any exit status means `no match' */ -- 1.7.10.4