All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony PERARD <anthony.perard@citrix.com>
To: <xen-devel@lists.xenproject.org>
Cc: Anthony PERARD <anthony.perard@citrix.com>,
	Ian Jackson <ian.jackson@eu.citrix.com>, Wei Liu <wl@xen.org>
Subject: [Xen-devel] [RFC XEN PATCH for-4.13 1/4] libxl: Introduce libxl__ev_child_kill
Date: Fri, 25 Oct 2019 18:05:02 +0100	[thread overview]
Message-ID: <20191025170505.2834957-2-anthony.perard@citrix.com> (raw)
In-Reply-To: <20191025170505.2834957-1-anthony.perard@citrix.com>

Allow to kill a child and deregister the callback associated with it.

The death isn't immediate will need to be collected later, so the
ev_child machinery register its own callback.

libxl__ev_child_kill() might be called by an AO operation that is
finishing/cleaning up without a chance for libxl to be notified of the
child death (via SIGCHLD). So it is possible that the application
calls libxl_ctx_free() while there are still child around. To avoid
the application getting unexpected SIGCHLD, the libxl__ao responsible
for killing a child will have to wait until it has been properly
reaped.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 tools/libxl/libxl_event.c    |  3 +-
 tools/libxl/libxl_fork.c     | 55 ++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h |  8 ++++++
 3 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 0370b6acdd1c..f57c16da1fd9 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -1891,7 +1891,8 @@ static bool ao_work_outstanding(libxl__ao *ao)
      * decrement progress_reports_outstanding, and call
      * libxl__ao_complete_check_progress_reports.
      */
-    return !ao->complete || ao->progress_reports_outstanding;
+    return !ao->complete || ao->progress_reports_outstanding
+        || ao->outstanding_killed_child;
 }
 
 void libxl__ao_complete_check_progress_reports(libxl__egc *egc, libxl__ao *ao)
diff --git a/tools/libxl/libxl_fork.c b/tools/libxl/libxl_fork.c
index eea3d5d4e68e..d99d40107f71 100644
--- a/tools/libxl/libxl_fork.c
+++ b/tools/libxl/libxl_fork.c
@@ -678,6 +678,61 @@ int libxl__ev_child_xenstore_reopen(libxl__gc *gc, const char *what) {
     return rc;
 }
 
+typedef struct ev_child_killed {
+    libxl__ao *ao;
+    libxl__ev_child ch;
+} ev_child_killed;
+static void deregistered_child_callback(libxl__egc *, libxl__ev_child *,
+                                        pid_t, int status);
+
+/*
+ * Allow to send a SIGKILL signal to a child and deregister the death
+ * callback.
+ * state: Active/Idle -> Idle
+ */
+void libxl__ev_child_kill(libxl__ao *ao, libxl__ev_child *ch)
+{
+    AO_GC;
+
+    if (!libxl__ev_child_inuse(ch))
+        return;
+
+    pid_t pid = ch->pid;
+
+    ev_child_killed *new_ch = GCNEW(new_ch);
+    new_ch->ao = ao;
+    new_ch->ch.pid = pid;
+    new_ch->ch.callback = deregistered_child_callback;
+    LIBXL_LIST_INSERT_HEAD(&CTX->children, &new_ch->ch, entry);
+    ao->outstanding_killed_child++;
+
+    LIBXL_LIST_REMOVE(ch, entry);
+    ch->pid = -1;
+    int r = kill(pid, SIGKILL);
+    if (r)
+        LOGE(ERROR, "failed to kill child [%ld]",
+             (unsigned long)pid);
+}
+
+static void deregistered_child_callback(libxl__egc *egc,
+                                        libxl__ev_child *ch,
+                                        pid_t pid,
+                                        int status)
+{
+    ev_child_killed *ck = CONTAINER_OF(ch, *ck, ch);
+    EGC_GC;
+
+    if (status) {
+        libxl_report_child_exitstatus(CTX, XTL_ERROR,
+                                      "killed fork (dying as expected)",
+                                      pid, status);
+    } else {
+        LOG(DEBUG, "killed child exit cleanly, unexpected");
+    }
+    ck->ao->outstanding_killed_child--;
+    libxl__ao_complete_check_progress_reports(egc, ck->ao);
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index d2d5af746b50..5823890703ad 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -727,6 +727,7 @@ struct libxl__ao {
     libxl__poller *poller;
     uint32_t domid;
     LIBXL_TAILQ_ENTRY(libxl__ao) entry_for_callback;
+    int outstanding_killed_child;
 };
 
 #define LIBXL_INIT_GC(gc,ctx) do{               \
@@ -1168,6 +1169,13 @@ static inline int libxl__ev_child_inuse(const libxl__ev_child *childw_out)
  * message>". */
 _hidden int libxl__ev_child_xenstore_reopen(libxl__gc *gc, const char *what);
 
+/*
+ * Allow to send a SIGKILL signal to a child and deregister the death
+ * callback.
+ * state: Active/Idle -> Idle
+ */
+_hidden void libxl__ev_child_kill(libxl__ao *ao, libxl__ev_child *ch);
+
 
 /*
  * Other event-handling support provided by the libxl event core to
-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  reply	other threads:[~2019-10-25 17:05 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-25 17:05 [Xen-devel] [RFC XEN PATCH for-4.13 0/4] Fix: libxl workaround, multiple connection to single QMP socket Anthony PERARD
2019-10-25 17:05 ` Anthony PERARD [this message]
2019-10-28 11:26   ` [Xen-devel] [RFC XEN PATCH for-4.13 1/4] libxl: Introduce libxl__ev_child_kill Ian Jackson
2019-10-28 17:01     ` Anthony PERARD
2019-10-29 14:17       ` Ian Jackson
2019-10-25 17:05 ` [Xen-devel] [RFC XEN PATCH for-4.13 2/4] libxl: Introduce libxl__ev_qmplock Anthony PERARD
2019-10-28 11:40   ` Ian Jackson
2019-10-25 17:05 ` [Xen-devel] [RFC XEN PATCH for-4.13 3/4] libxl: libxl__ev_qmp_send now takes an egc Anthony PERARD
2019-10-28 11:30   ` Ian Jackson
2019-10-25 17:05 ` [Xen-devel] [RFC XEN PATCH for-4.13 4/4] libxl_qmp: Have a lock for QMP socket access Anthony PERARD
2019-10-28 11:41   ` Ian Jackson
2019-10-26 18:45 ` [Xen-devel] [RFC XEN PATCH for-4.13 0/4] Fix: libxl workaround, multiple connection to single QMP socket Sander Eikelenboom
2019-10-28 11:25 ` Ian Jackson
2019-10-28 16:27   ` Anthony PERARD
2019-10-29 14:14     ` Ian Jackson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191025170505.2834957-2-anthony.perard@citrix.com \
    --to=anthony.perard@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.