Linux NFS development
 help / color / mirror / Atom feed
From: Steve Dickson <SteveD@redhat.com>
To: nfs@lists.sourceforge.net
Subject: [PATCH] nfs-utils - 3 of 6 -statd - Ensure child process is running for before the parent exits
Date: Wed, 18 Jun 2003 13:54:35 -0400	[thread overview]
Message-ID: <3EF0A75B.6010307@RedHat.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 326 bytes --]

To make sure the correct start-up status is returned
to the rc script during boot, the parent statd process
must know if the child process (i.e. "real" daemon)
was able to successfully start. Otherwise, the
child can die and the parent will returns success which
would cause networks lock to hang (unexplainable)....

SteveD.

[-- Attachment #2: nfs-utils-1.0.3-03-statd-pipe.patch --]
[-- Type: text/plain, Size: 3263 bytes --]

--- ./utils/statd/statd.c.org	2003-06-02 15:20:53.000000000 -0400
+++ ./utils/statd/statd.c	2003-06-02 15:25:07.000000000 -0400
@@ -46,6 +46,7 @@ char *  SM_STAT_PATH = DEFAULT_SM_STAT_P
 
 short int restart = 0;
 int	run_mode = 0;		/* foreground logging mode */
+int pfds[2] = {-1, -1};            /* pipe fds */
 
 /* LH - I had these local to main, but it seemed silly to have 
  * two copies of each - one in main(), one static in log.c... 
@@ -79,14 +80,20 @@ extern void simulator (int, char **);
  */
 static const char *piddir="/var/run/rpc.statd";
 static const char *pidfile="/var/run/rpc.statd/rpc.statd.pid";
+static const char *mypidfile = NULL;
 static void
 delete_pidfile(void)
 {
-	if (unlink(pidfile) < 0) {
-		log(L_WARNING,"Unlinking %s failed: errno %d (%s)\n", pidfile,
-			errno, strerror(errno));
+	/*
+	 * Only delete the pidfile if this is
+	 * the process that created it
+	 */ 
+	if (mypidfile) {
+		if (unlink(mypidfile) < 0) {
+			log(L_WARNING,"Unlinking %s failed: errno %d (%s)\n", mypidfile,
+				errno, strerror(errno));
+		}
 	}
-
 	return;
 }
 static void
@@ -115,9 +122,20 @@ create_pidfile(void)
 		log(L_WARNING,"Closing %s failed: errno %d (%s)\n", pidfile,
 			errno, strerror(errno));
 	}
+	mypidfile = pidfile;
 
 	return;
 }
+/*
+ * Called when the child exits
+ */
+static void
+child_exit(void)
+{
+	delete_pidfile();
+	if (pfds[1] > -1)
+		close(pfds[1]);
+}
 
 /*
  * Privilege dropper
@@ -254,6 +272,7 @@ int main (int argc, char **argv)
 	int pid;
 	int arg;
 	int port = 0, out_port = 0;
+	int status=-1;
 
 	/* Default: daemon mode, no other options */
 	run_mode = 0;
@@ -373,11 +392,24 @@ int main (int argc, char **argv)
 	if (!(run_mode & MODE_NODAEMON)) {
 		int filedes, fdmax, tempfd;
 
+		if (pipe(pfds) < 0) {
+			fprintf(stderr, "Unable to create a pipe(2):"
+				" errno %d (%s)\n", errno, strerror(errno));
+			exit(-1);
+		}
 		if ((pid = fork ()) < 0) {
 			perror ("Could not fork");
-			exit (1);
+			exit(-1);
 		} else if (pid != 0) {
 			/* Parent. */
+			/*
+			 * Wait for status from the child 
+			 */
+			close(pfds[1]);
+			if (read(pfds[0], &status, sizeof(status)) < 1)
+				exit(-1); /* the child died */
+			if (status != 0)
+				exit(-1); /* the child failed */
 			exit (0);
 		}
 		/* Child.	*/
@@ -390,13 +422,16 @@ int main (int argc, char **argv)
 		close(2); dup2(tempfd, 2);
 		fdmax = sysconf (_SC_OPEN_MAX);
 		for (filedes = 3; filedes < fdmax; filedes++) {
-			close (filedes);
+			if (filedes != pfds[1]) 
+				close (filedes);
 		}
+		atexit(child_exit);
 	}
 
 	log_init (name_p, version_p);
 	create_pidfile();
-	atexit(delete_pidfile);
+	if (run_mode & MODE_NODAEMON)
+		atexit(delete_pidfile);
 
 	/* Child. */
 	signal (SIGHUP, killer);
@@ -432,6 +467,15 @@ int main (int argc, char **argv)
 	if (access(".", R_OK|W_OK|X_OK) != 0)
 		die("Cannot access current directory after dropping privs: access()\n");
 
+	/* Tell the parent everthing is ok... */
+	status=0;
+	if (write(pfds[1], &status, sizeof(status)) < 0) {
+		log(L_WARNING,"Writting to pipe[1] failed: errno %d (%s)\n",
+		errno, strerror(errno));
+	}
+	close(pfds[1]);
+	pfds[1] = -1;
+
 	for (;;) {
 		if (!(run_mode & MODE_NOTIFY_ONLY)) {
 			/* Do not do pmap_unset() when running in notify mode.

                 reply	other threads:[~2003-06-18 17:53 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=3EF0A75B.6010307@RedHat.com \
    --to=steved@redhat.com \
    --cc=nfs@lists.sourceforge.net \
    /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