From: Hitoshi Mitake <mitake.hitoshi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: Ryusuke Konishi
<konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
Cc: linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Hitoshi Mitake
<mitake.hitoshi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
Hitoshi Mitake
<mitake.hitoshi-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
Subject: Re: [PATCH] lib/cleaner_exec.c: get process ID of cleanerd through pipe
Date: Sun, 26 Jan 2014 01:46:09 +0900 [thread overview]
Message-ID: <87ha8sko1a.wl%mitake.hitoshi@gmail.com> (raw)
In-Reply-To: <1390397720-2259-1-git-send-email-konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
At Wed, 22 Jan 2014 22:35:20 +0900,
Ryusuke Konishi wrote:
>
> After applying commit 8ce4b524a1654ece478f54fce772cc0c16e3c559
> "cleanerd: call _exit(2) twice for ensuring not being a session
> leader", the mount helper program of nilfs2 no longer gets proper
> process ID (pid) of cleaner daemon, and umount.nilfs2 fails to kill
> cleanerd.
>
> This fixes the issue by letting cleanerd print out the pid of spawned
> daemon and letting nilfs_launch_cleanerd() function read it through
> pipe.
>
> Signed-off-by: Ryusuke Konishi <konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
> Cc: Hitoshi Mitake <mitake.hitoshi-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
Looks good to me and sorry for my bug!
Reviewed-by: Hitoshi Mitake <mitake.hitoshi-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
Thanks,
Hitoshi
> ---
> lib/cleaner_exec.c | 84 ++++++++++++++++++++++++++++++++++++++++++----
> man/nilfs_cleanerd.8 | 3 ++
> sbin/cleanerd/cleanerd.c | 3 ++
> 3 files changed, 83 insertions(+), 7 deletions(-)
>
> diff --git a/lib/cleaner_exec.c b/lib/cleaner_exec.c
> index edc55e3..5336c32 100644
> --- a/lib/cleaner_exec.c
> +++ b/lib/cleaner_exec.c
> @@ -114,6 +114,43 @@ static inline int process_is_alive(pid_t pid)
> return (kill(pid, 0) == 0);
> }
>
> +static int receive_pid(int fd, pid_t *ppid)
> +{
> + char buf[100];
> + unsigned long pid;
> + FILE *fp;
> + int ret;
> +
> + fp = fdopen(fd, "r");
> + if (!fp) {
> + nilfs_cleaner_logger(
> + LOG_ERR, _("Error: fdopen failed: %m"));
> + close(fd);
> + goto fail;
> + }
> +
> + /* read process ID of cleanerd through the given fd */
> + while (fgets(buf, sizeof(buf), fp) != NULL) {
> + /*
> + * fgets() is blocked during no child processes
> + * respond, but it will escape returning a NULL value
> + * and terminate the loop when all child processes
> + * close the given pipe (fd) including call of exit().
> + */
> + ret = sscanf(buf, "NILFS_CLEANERD_PID=%lu", &pid);
> + if (ret == 1) {
> + *ppid = pid;
> + fclose(fp); /* this also closes fd */
> + return 0;
> + }
> + }
> + fclose(fp);
> +fail:
> + nilfs_cleaner_logger(
> + LOG_WARNING, _("Warning: cannot get pid of cleanerd"));
> + return -1;
> +}
> +
> int nilfs_launch_cleanerd(const char *device, const char *mntdir,
> unsigned long protperiod, pid_t *ppid)
> {
> @@ -123,6 +160,7 @@ int nilfs_launch_cleanerd(const char *device, const char *mntdir,
> int i = 0;
> int ret;
> char buf[256];
> + int pipes[2];
>
> if (stat(cleanerd, &statbuf) != 0) {
> nilfs_cleaner_logger(LOG_ERR, _("Error: %s not found"),
> @@ -130,8 +168,16 @@ int nilfs_launch_cleanerd(const char *device, const char *mntdir,
> return -1;
> }
>
> + ret = pipe(pipes);
> + if (ret < 0) {
> + nilfs_cleaner_logger(
> + LOG_ERR, _("Error: failed to create pipe: %m"));
> + return -1;
> + }
> +
> ret = fork();
> if (ret == 0) {
> + /* child */
> if (setgid(getgid()) < 0) {
> nilfs_cleaner_logger(
> LOG_ERR,
> @@ -159,16 +205,40 @@ int nilfs_launch_cleanerd(const char *device, const char *mntdir,
> sigdelset(&sigs, SIGSEGV);
> sigprocmask(SIG_UNBLOCK, &sigs, NULL);
>
> + close(pipes[0]);
> + ret = dup2(pipes[1], STDOUT_FILENO);
> + if (ret < 0) {
> + nilfs_cleaner_logger(
> + LOG_ERR,
> + _("Error: failed to duplicate pipe: %m"));
> + exit(1);
> + }
> + close(pipes[1]);
> +
> execv(cleanerd, (char **)dargs);
> exit(1); /* reach only if failed */
> - } else if (ret != -1) {
> - *ppid = ret;
> - return 0; /* cleanerd started */
> + } else if (ret > 0) {
> + /* parent */
> + close(pipes[1]);
> +
> + /*
> + * fork() returns a pid of the child process, but we
> + * cannot use it because cleanerd internally fork()s
> + * and changes pid.
> + */
> + ret = receive_pid(pipes[0], ppid);
> + if (ret < 0)
> + *ppid = 0;
> + /*
> + * always return a success code because cleanerd has
> + * already started.
> + */
> + return 0;
> } else {
> - int errsv = errno;
> - nilfs_cleaner_logger(LOG_ERR,
> - _("Error: could not fork: %s"),
> - strerror(errsv));
> + nilfs_cleaner_logger(
> + LOG_ERR, _("Error: could not fork: %m"));
> + close(pipes[0]);
> + close(pipes[1]);
> }
> return -1;
> }
> diff --git a/man/nilfs_cleanerd.8 b/man/nilfs_cleanerd.8
> index 46caef2..fd1c48a 100644
> --- a/man/nilfs_cleanerd.8
> +++ b/man/nilfs_cleanerd.8
> @@ -24,6 +24,9 @@ users are recommended to invoke \fBnilfs_cleanerd\fP through
> \fBmount.nilfs2\fP(8) or \fBmount\fP(8) and shutdown it through
> \fBumount.nilfs2\fP(8) or \fBumount\fP(8) in order to avoid state
> inconsistencies among administration tools.
> +.PP
> +\fBnilfs_cleanerd\fP displays its process ID (pid) to standard
> +output when it started.
> .SH OPTIONS
> .TP
> \fB\-V\fR, \fB\-\-version\fR
> diff --git a/sbin/cleanerd/cleanerd.c b/sbin/cleanerd/cleanerd.c
> index 86dfcf7..742ab98 100644
> --- a/sbin/cleanerd/cleanerd.c
> +++ b/sbin/cleanerd/cleanerd.c
> @@ -719,6 +719,9 @@ static int daemonize(int nochdir, int noclose)
> if (!nochdir && (chdir(ROOTDIR) < 0))
> return -1;
>
> + printf("NILFS_CLEANERD_PID=%lu\n", (unsigned long)getpid());
> + fflush(stdout);
> +
> if (!noclose) {
> close(0);
> close(1);
> --
> 1.7.9.3
>
--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
prev parent reply other threads:[~2014-01-25 16:46 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-22 13:35 [PATCH] lib/cleaner_exec.c: get process ID of cleanerd through pipe Ryusuke Konishi
[not found] ` <1390397720-2259-1-git-send-email-konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2014-01-25 16:46 ` Hitoshi Mitake [this message]
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=87ha8sko1a.wl%mitake.hitoshi@gmail.com \
--to=mitake.hitoshi-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
--cc=konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org \
--cc=linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=mitake.hitoshi-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.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