Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Oct 2018 21:33:00 +0000 (UTC)
From:      Conrad Meyer <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r339494 - head/sbin/mdmfs
Message-ID:  <201810202133.w9KLX0fR039707@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Sat Oct 20 21:33:00 2018
New Revision: 339494
URL: https://svnweb.freebsd.org/changeset/base/339494

Log:
  mdmfs(8): Check for other types of helper-program failure
  
  Exiting with a signal should not be treated the same as successful exit with
  zero status.
  
  Return signal exit information to the callers via negative integers, to
  enable distinction from normal exit statuses.  (All consumers that check for
  errors don't care what the exact non-zero exit value is -- in such a case
  they print a diagnostic message and either continue or bail.)
  
  Additionally, check for unexpected sources of waitpid() wakeup and bail if
  we encounter them.
  
  Reported by:	lev@
  Reviewed by:	kib, lev, markj (earlier version)
  Sponsored by:	Dell EMC Isilon
  Differential Revision:	https://reviews.freebsd.org/D17035

Modified:
  head/sbin/mdmfs/mdmfs.c

Modified: head/sbin/mdmfs/mdmfs.c
==============================================================================
--- head/sbin/mdmfs/mdmfs.c	Sat Oct 20 21:13:57 2018	(r339493)
+++ head/sbin/mdmfs/mdmfs.c	Sat Oct 20 21:33:00 2018	(r339494)
@@ -90,6 +90,8 @@ static void	 do_mtptsetup(const char *, struct mtpt_in
 static void	 do_newfs(const char *);
 static void	 extract_ugid(const char *, struct mtpt_info *);
 static int	 run(int *, const char *, ...) __printflike(2, 3);
+static const char *run_exitstr(int);
+static int	 run_exitnumber(int);
 static void	 usage(void);
 
 int
@@ -431,7 +433,8 @@ do_mdconfig_attach(const char *args, const enum md_typ
 	rv = run(NULL, "%s -a %s%s -u %s%d", path_mdconfig, ta, args,
 	    mdname, unit);
 	if (rv)
-		errx(1, "mdconfig (attach) exited with error code %d", rv);
+		errx(1, "mdconfig (attach) exited %s %d", run_exitstr(rv),
+		    run_exitnumber(rv));
 }
 
 /*
@@ -464,7 +467,8 @@ do_mdconfig_attach_au(const char *args, const enum md_
 	}
 	rv = run(&fd, "%s -a %s%s", path_mdconfig, ta, args);
 	if (rv)
-		errx(1, "mdconfig (attach) exited with error code %d", rv);
+		errx(1, "mdconfig (attach) exited %s %d", run_exitstr(rv),
+		    run_exitnumber(rv));
 
 	/* Receive the unit number. */
 	if (norun) {	/* Since we didn't run, we can't read.  Fake it. */
@@ -503,8 +507,8 @@ do_mdconfig_detach(void)
 
 	rv = run(NULL, "%s -d -u %s%d", path_mdconfig, mdname, unit);
 	if (rv && debug)	/* This is allowed to fail. */
-		warnx("mdconfig (detach) exited with error code %d (ignored)",
-		    rv);
+		warnx("mdconfig (detach) exited %s %d (ignored)",
+		    run_exitstr(rv), run_exitnumber(rv));
 }
 
 /*
@@ -518,7 +522,8 @@ do_mount_md(const char *args, const char *mtpoint)
 	rv = run(NULL, "%s%s /dev/%s%d%s %s", _PATH_MOUNT, args,
 	    mdname, unit, mdsuffix, mtpoint);
 	if (rv)
-		errx(1, "mount exited with error code %d", rv);
+		errx(1, "mount exited %s %d", run_exitstr(rv),
+		    run_exitnumber(rv));
 }
 
 /*
@@ -531,7 +536,8 @@ do_mount_tmpfs(const char *args, const char *mtpoint)
 
 	rv = run(NULL, "%s -t tmpfs %s tmp %s", _PATH_MOUNT, args, mtpoint);
 	if (rv)
-		errx(1, "tmpfs mount exited with error code %d", rv);
+		errx(1, "tmpfs mount exited %s %d", run_exitstr(rv),
+		    run_exitnumber(rv));
 }
 
 /*
@@ -603,7 +609,8 @@ do_newfs(const char *args)
 
 	rv = run(NULL, "%s%s /dev/%s%d", _PATH_NEWFS, args, mdname, unit);
 	if (rv)
-		errx(1, "newfs exited with error code %d", rv);
+		errx(1, "newfs exited %s %d", run_exitstr(rv),
+		    run_exitnumber(rv));
 }
 
 /*
@@ -674,8 +681,12 @@ extract_ugid(const char *str, struct mtpt_info *mip)
  * Run a process with command name and arguments pointed to by the
  * formatted string 'cmdline'.  Since system(3) is not used, the first
  * space-delimited token of 'cmdline' must be the full pathname of the
- * program to run.  The return value is the return code of the process
- * spawned.  If 'ofd' is non-NULL, it is set to the standard output of
+ * program to run.
+ *
+ * The return value is the return code of the process spawned, or a negative
+ * signal number if the process exited due to an uncaught signal.
+ *
+ * If 'ofd' is non-NULL, it is set to the standard output of
  * the program spawned (i.e., you can read from ofd and get the output
  * of the program).
  */
@@ -771,7 +782,35 @@ run(int *ofd, const char *cmdline, ...)
 	free(argv);
 	while (waitpid(pid, &status, 0) != pid)
 		;
-	return (WEXITSTATUS(status));
+	if (WIFEXITED(status))
+		return (WEXITSTATUS(status));
+	if (WIFSIGNALED(status))
+		return (-WTERMSIG(status));
+	err(1, "unexpected waitpid status: 0x%x", status);
+}
+
+/*
+ * If run() returns non-zero, provide a string explaining why.
+ */
+static const char *
+run_exitstr(int rv)
+{
+	if (rv > 0)
+		return ("with error code");
+	if (rv < 0)
+		return ("with signal");
+	return (NULL);
+}
+
+/*
+ * If run returns non-zero, provide a relevant number.
+ */
+static int
+run_exitnumber(int rv)
+{
+	if (rv < 0)
+		return (-rv);
+	return (rv);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201810202133.w9KLX0fR039707>