From patchwork Fri Oct 25 17:05:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony PERARD X-Patchwork-Id: 11212721 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1AF15112B for ; Fri, 25 Oct 2019 17:06:27 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E9EAC20867 for ; Fri, 25 Oct 2019 17:06:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="bMmjkAGD" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E9EAC20867 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iO31S-0000Cr-U2; Fri, 25 Oct 2019 17:05:10 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iO31R-0000Cb-Kf for xen-devel@lists.xenproject.org; Fri, 25 Oct 2019 17:05:09 +0000 X-Inumbo-ID: 98c37f84-f749-11e9-a531-bc764e2007e4 Received: from esa3.hc3370-68.iphmx.com (unknown [216.71.145.155]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 98c37f84-f749-11e9-a531-bc764e2007e4; Fri, 25 Oct 2019 17:05:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1572023108; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hZArzNpHpPpwto8C5wZO6UU0W8B8tHq5yuGtVwWY6b8=; b=bMmjkAGDa6JTmJlmm+dQFD8ELEWMVJKEBxFhfvQpxJD0B/YCK7IPm8Qi qaadBjLg2r67PDKu1S7cgG01om5DpF4rflmI/t28KzLAouwoMprmj/Xof UZQa2RPgW5rL2rui4LRmrMJWIL4pk4bTIcWWIKLa08ZDNXD54pKRLCrB9 o=; Authentication-Results: esa3.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=anthony.perard@citrix.com; spf=Pass smtp.mailfrom=anthony.perard@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa3.hc3370-68.iphmx.com: no sender authenticity information available from domain of anthony.perard@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa3.hc3370-68.iphmx.com; envelope-from="anthony.perard@citrix.com"; x-sender="anthony.perard@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa3.hc3370-68.iphmx.com: domain of anthony.perard@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa3.hc3370-68.iphmx.com; envelope-from="anthony.perard@citrix.com"; x-sender="anthony.perard@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa3.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa3.hc3370-68.iphmx.com; envelope-from="anthony.perard@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: kbhoLUtLxotktq8FBwJPiHdnAQhZlAT+4Q6jMNzKWpWiVyemnllm7htwrLG85rULg0pGON8CVs ZqYNIQVQFHVvFZ1wNsSMX871S2WWYhRp19+Jb+d172YUwGrsXtH57D4SocDaACqw6Bj5xaGMg7 PV921c1TWEDj5fkBPCiJtkoJctAaOXa1jM4jQwKmko4kFeaPkBRBdlWvKG8QxnSU56hnad/2ZR IP3xdagJbIn0jDoM7O7LoCs5xPJGXcqVNNmFBBc/tP26oP/3mYvg/UuWsKUoqcF8nfgIVE1+2g Z+8= X-SBRS: 2.7 X-MesageID: 7443687 X-Ironport-Server: esa3.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.68,229,1569297600"; d="scan'208";a="7443687" From: Anthony PERARD To: Date: Fri, 25 Oct 2019 18:05:02 +0100 Message-ID: <20191025170505.2834957-2-anthony.perard@citrix.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191025170505.2834957-1-anthony.perard@citrix.com> References: <20191025170505.2834957-1-anthony.perard@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [RFC XEN PATCH for-4.13 1/4] libxl: Introduce libxl__ev_child_kill X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Anthony PERARD , Ian Jackson , Wei Liu Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" 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 --- 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