From: Ian Jackson <ian.jackson@eu.citrix.com>
To: xen-devel@lists.xen.org
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Subject: [PATCH 23/24] libxl: child processes cleanups
Date: Mon, 16 Apr 2012 18:18:05 +0100 [thread overview]
Message-ID: <1334596686-8479-24-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1334596686-8479-1-git-send-email-ian.jackson@eu.citrix.com>
Abolish libxl_fork. Its only callers were in xl. Its functionality
is now moved elsewhere, as follows:
* The "logging version of fork", which is what it was billed as, is now
xl_fork, which also dies on failure.
* Closing the xenstore handle in the child is now done in
libxl__ev_child_fork, which is the only remaining place where fork
is called in libxl.
* We provide a new function libxl__ev_child_xenstore_reopen for
in-libxl children to make the ctx useable for xenstore again.
* Consequently libxl__spawn_record_pid now no longer needs to mess
about with its own xenstore handle. As a bonus it can now just use
libxl__xs_write.
Also, since we have now converted all the forkers in libxl, we can
always honour the fork_replacement childproc hook - so do so.
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
tools/libxl/libxl_exec.c | 35 ++++++++++++++++-------------------
tools/libxl/libxl_fork.c | 25 ++++++++++++++++++++++++-
tools/libxl/libxl_internal.h | 5 +++++
tools/libxl/libxl_utils.c | 21 ---------------------
tools/libxl/libxl_utils.h | 3 +--
tools/libxl/xl.c | 12 ++++++++++++
tools/libxl/xl.h | 1 +
tools/libxl/xl_cmdimpl.c | 5 ++---
8 files changed, 61 insertions(+), 46 deletions(-)
diff --git a/tools/libxl/libxl_exec.c b/tools/libxl/libxl_exec.c
index d44b702..d681736 100644
--- a/tools/libxl/libxl_exec.c
+++ b/tools/libxl/libxl_exec.c
@@ -127,34 +127,23 @@ void libxl_report_child_exitstatus(libxl_ctx *ctx,
}
}
-int libxl__spawn_record_pid(libxl__gc *gc, libxl__spawn_state *spawn,
- pid_t innerchild)
+int libxl__spawn_record_pid(libxl__gc *gc, libxl__spawn_state *spawn, pid_t pid)
{
- struct xs_handle *xsh = NULL;
- const char *pid = NULL;
- int rc, xsok;
+ int r, rc;
- pid = GCSPRINTF("%d", innerchild);
+ rc = libxl__ev_child_xenstore_reopen(gc, spawn->what);
+ if (rc) goto out;
- /* we mustn't use the parent's handle in the child */
- xsh = xs_daemon_open();
- if (!xsh) {
- LOGE(ERROR, "write %s = %s: xenstore reopen failed",
- spawn->pidpath, pid);
- rc = ERROR_FAIL; goto out;
- }
-
- xsok = xs_write(xsh, XBT_NULL, spawn->pidpath, pid, strlen(pid));
- if (!xsok) {
+ r = libxl__xs_write(gc, XBT_NULL, spawn->pidpath, "%d", pid);
+ if (r) {
LOGE(ERROR,
- "write %s = %s: xenstore write failed", spawn->pidpath, pid);
+ "write %s = %d: xenstore write failed", spawn->pidpath, pid);
rc = ERROR_FAIL; goto out;
}
rc = 0;
out:
- if (xsh) xs_daemon_close(xsh);
return rc ? SIGTERM : 0;
}
@@ -302,7 +291,15 @@ int libxl__spawn_spawn(libxl__egc *egc, libxl__spawn_state *ss)
/* we are now the middle process */
- child = fork();
+ pid_t (*fork_replacement)(void*) =
+ CTX->childproc_hooks
+ ? CTX->childproc_hooks->fork_replacement
+ : 0;
+ child =
+ fork_replacement
+ ? fork_replacement(CTX->childproc_user)
+ : fork();
+
if (child == -1)
exit(255);
if (!child) {
diff --git a/tools/libxl/libxl_fork.c b/tools/libxl/libxl_fork.c
index 35c8bdd..9ff99e0 100644
--- a/tools/libxl/libxl_fork.c
+++ b/tools/libxl/libxl_fork.c
@@ -347,7 +347,12 @@ pid_t libxl__ev_child_fork(libxl__gc *gc, libxl__ev_child *ch,
if (!pid) {
/* woohoo! */
- return 0; /* Yes, CTX is left locked in the child. */
+ if (CTX->xsh) {
+ xs_daemon_destroy_postfork(CTX->xsh);
+ CTX->xsh = NULL; /* turns mistakes into crashes */
+ }
+ /* Yes, CTX is left locked in the child. */
+ return 0;
}
ch->pid = pid;
@@ -395,6 +400,24 @@ const libxl_childproc_hooks libxl__childproc_default_hooks = {
libxl_sigchld_owner_libxl, 0, 0
};
+int libxl__ev_child_xenstore_reopen(libxl__gc *gc, const char *what) {
+ int rc;
+
+ assert(!CTX->xsh);
+ CTX->xsh = xs_daemon_open();
+ if (!CTX->xsh) {
+ LOGE(ERROR, "%s: xenstore reopen failed", what);
+ rc = ERROR_FAIL; goto out;
+ }
+
+ libxl_fd_set_cloexec(CTX, xs_fileno(CTX->xsh), 1);
+
+ return 0;
+
+ out:
+ return rc;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index fb4dee8..3e90ac4 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -627,6 +627,11 @@ static inline void libxl__ev_child_init(libxl__ev_child *childw_out)
static inline int libxl__ev_child_inuse(libxl__ev_child *childw_out)
{ return childw_out->pid >= 0; }
+/* Useable (only) in the child to once more make the ctx useable for
+ * xenstore operations. logs failure in the form "what: <error
+ * message>". */
+_hidden int libxl__ev_child_xenstore_reopen(libxl__gc *gc, const char *what);
+
/*
* Other event-handling support provided by the libxl event core to
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index f0d94c6..858410e 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -444,27 +444,6 @@ int libxl__remove_directory(libxl__gc *gc, const char *dirpath)
return rc;
}
-pid_t libxl_fork(libxl_ctx *ctx)
-{
- pid_t pid;
-
- pid = fork();
- if (pid == -1) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "fork failed");
- return -1;
- }
-
- if (!pid) {
- if (ctx->xsh) xs_daemon_destroy_postfork(ctx->xsh);
- ctx->xsh = 0;
- /* This ensures that anyone who forks but doesn't exec,
- * and doesn't reinitialise the libxl_ctx, is OK.
- * It also means they can safely call libxl_ctx_free. */
- }
-
- return pid;
-}
-
int libxl_pipe(libxl_ctx *ctx, int pipes[2])
{
if (pipe(pipes) < 0) {
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 2b47622..74beb52 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -47,9 +47,8 @@ int libxl_write_exactly(libxl_ctx *ctx, int fd, const void *data,
* logged using filename (which is only used for logging) and what
* (which may be 0). */
-pid_t libxl_fork(libxl_ctx *ctx);
int libxl_pipe(libxl_ctx *ctx, int pipes[2]);
- /* Just like fork(2), pipe(2), but log errors. */
+ /* Just like pipe(2), but log errors. */
void libxl_report_child_exitstatus(libxl_ctx *ctx, xentoollog_level,
const char *what, pid_t pid, int status);
diff --git a/tools/libxl/xl.c b/tools/libxl/xl.c
index a6ffd25..d4db1f8 100644
--- a/tools/libxl/xl.c
+++ b/tools/libxl/xl.c
@@ -105,6 +105,18 @@ void postfork(void)
}
}
+pid_t xl_fork(libxl_ctx *ctx) {
+ pid_t pid;
+
+ pid = fork();
+ if (pid == -1) {
+ perror("fork failed");
+ exit(-1);
+ }
+
+ return pid;
+}
+
int main(int argc, char **argv)
{
int opt = 0;
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
index 7e258d5..c031bb3 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -105,6 +105,7 @@ struct cmd_spec *cmdtable_lookup(const char *s);
extern libxl_ctx *ctx;
extern xentoollog_logger_stdiostream *logger;
+pid_t xl_fork(libxl_ctx *ctx); /* like fork, but prints and dies if it fails */
void postfork(void);
/* global options */
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index ce52599..ebfd4fe 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1709,7 +1709,7 @@ start:
pid_t child1, got_child;
int nullfd;
- child1 = libxl_fork(ctx);
+ child1 = xl_fork(ctx);
if (child1) {
printf("Daemon running with PID %d\n", child1);
@@ -2748,8 +2748,7 @@ static void migrate_domain(const char *domain_spec, const char *rune,
MUST( libxl_pipe(ctx, sendpipe) );
MUST( libxl_pipe(ctx, recvpipe) );
- child = libxl_fork(ctx);
- if (child==-1) exit(1);
+ child = xl_fork(ctx);
if (!child) {
dup2(sendpipe[0], 0);
--
1.7.2.5
next prev parent reply other threads:[~2012-04-16 17:18 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-16 17:17 [PATCH v7 00/24] libxl: subprocess handling Ian Jackson
2012-04-16 17:17 ` [PATCH 01/24] libxl: handle POLLERR, POLLHUP, POLLNVAL properly Ian Jackson
2012-04-16 17:17 ` [PATCH 02/24] libxl: support multiple libxl__ev_fds for the same fd Ian Jackson
2012-04-16 17:17 ` [PATCH 03/24] libxl: event API: new facilities for waiting for subprocesses Ian Jackson
2012-04-16 17:17 ` [PATCH 04/24] autoconf: trim the configure script; use autoheader Ian Jackson
2012-04-17 9:18 ` Ian Campbell
2012-04-17 13:18 ` Ian Jackson
2012-04-17 13:22 ` Ian Campbell
2012-04-17 14:07 ` Roger Pau Monne
2012-04-16 17:17 ` [PATCH 05/24] autoconf: New test for openpty et al Ian Jackson
2012-04-17 9:20 ` Ian Campbell
2012-04-16 17:17 ` [PATCH 06/24] libxl: provide libxl__remove_file " Ian Jackson
2012-04-16 17:17 ` [PATCH 07/24] libxl: Introduce libxl__sendmsg_fds and libxl__recvmsg_fds Ian Jackson
2012-04-16 17:17 ` [PATCH 08/24] libxl: Clean up setdefault in do_domain_create Ian Jackson
2012-04-16 17:17 ` [PATCH 09/24] libxl: provide libxl__datacopier_* Ian Jackson
2012-04-17 9:37 ` Ian Campbell
2012-04-16 17:17 ` [PATCH 10/24] libxl: provide libxl__openpty_* Ian Jackson
2012-04-16 17:17 ` [PATCH 11/24] libxl: ao: Convert libxl_run_bootloader Ian Jackson
2012-04-16 17:17 ` [PATCH 12/24] libxl: make libxl_create_logfile const-correct Ian Jackson
2012-04-16 17:17 ` [PATCH 13/24] libxl: log bootloader output Ian Jackson
2012-04-16 17:17 ` [PATCH 14/24] libxl: Allow AO_GC and EGC_GC even if not used Ian Jackson
2012-04-16 17:17 ` [PATCH 15/24] libxl: remove ctx->waitpid_instead Ian Jackson
2012-04-17 9:40 ` Ian Campbell
2012-04-17 13:24 ` Ian Jackson
2012-04-16 17:17 ` [PATCH 16/24] libxl: change some structures to unit arrays Ian Jackson
2012-04-17 9:41 ` Ian Campbell
2012-04-16 17:17 ` [PATCH 17/24] libxl: ao: convert libxl__spawn_* Ian Jackson
2012-04-17 15:17 ` Ian Campbell
2012-04-17 17:03 ` Ian Jackson
2012-04-18 10:12 ` Ian Campbell
2012-04-18 10:52 ` Ian Jackson
2012-04-18 11:07 ` Ian Campbell
2012-04-16 17:18 ` [PATCH 18/24] libxl: make libxl_create run bootloader via callback Ian Jackson
2012-04-24 13:46 ` Ian Campbell
2012-04-24 13:54 ` Ian Jackson
2012-04-16 17:18 ` [PATCH 19/24] libxl: provide progress reporting for long-running operations Ian Jackson
2012-04-24 13:59 ` Ian Campbell
2012-04-25 13:38 ` Ian Jackson
2012-04-16 17:18 ` [PATCH 20/24] libxl: remove malloc failure handling from NEW_EVENT Ian Jackson
2012-04-24 14:01 ` Ian Campbell
2012-04-16 17:18 ` [PATCH 21/24] libxl: convert console callback to libxl_asyncprogress_how Ian Jackson
2012-04-24 14:05 ` Ian Campbell
2012-04-16 17:18 ` [PATCH 22/24] libxl: clarify definition of "slow" operation Ian Jackson
2012-04-24 14:06 ` Ian Campbell
2012-04-16 17:18 ` Ian Jackson [this message]
2012-04-24 14:12 ` [PATCH 23/24] libxl: child processes cleanups Ian Campbell
2012-04-24 14:27 ` Ian Jackson
2012-04-24 15:05 ` Ian Campbell
2012-04-24 15:07 ` Ian Campbell
2012-04-24 15:22 ` Ian Jackson
2012-04-24 15:32 ` Ian Campbell
2012-04-16 17:18 ` [PATCH 24/24] libxl: aborting bootloader invocation when domain dioes Ian Jackson
2012-04-24 14:18 ` Ian Campbell
2012-04-24 14:38 ` Ian Jackson
2012-04-24 15:08 ` Ian Campbell
2012-04-24 15:26 ` 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=1334596686-8479-24-git-send-email-ian.jackson@eu.citrix.com \
--to=ian.jackson@eu.citrix.com \
--cc=xen-devel@lists.xen.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).