6825097 brand hooks can't read stdin
author<gerald.jelinek@sun.com>
Wed, 08 Apr 2009 07:28:49 -0600
changeset 9310 243a415871cf
parent 9309 d93859e745c4
child 9311 e24814334def
6825097 brand hooks can't read stdin
usr/src/cmd/zoneadm/zfs.c
usr/src/cmd/zoneadm/zoneadm.c
usr/src/cmd/zoneadm/zoneadm.h
--- a/usr/src/cmd/zoneadm/zfs.c	Tue Apr 07 22:50:24 2009 -0700
+++ b/usr/src/cmd/zoneadm/zfs.c	Wed Apr 08 07:28:49 2009 -0600
@@ -206,7 +206,7 @@
 		return (Z_OK);
 
 	/* Run the hook */
-	status = do_subproc_interactive(presnapbuf);
+	status = do_subproc(presnapbuf);
 	if ((status = subproc_status(gettext("brand-specific presnapshot"),
 	    status, B_FALSE)) != ZONE_SUBPROC_OK)
 		return (Z_ERR);
@@ -227,7 +227,7 @@
 		return (Z_OK);
 
 	/* Run the hook */
-	status = do_subproc_interactive(postsnapbuf);
+	status = do_subproc(postsnapbuf);
 	if ((status = subproc_status(gettext("brand-specific postsnapshot"),
 	    status, B_FALSE)) != ZONE_SUBPROC_OK)
 		return (Z_ERR);
@@ -333,7 +333,7 @@
 	}
 
 	/* Run the hook */
-	status = do_subproc_interactive(cmdbuf);
+	status = do_subproc(cmdbuf);
 	if ((status = subproc_status(gettext("brand-specific validatesnapshot"),
 	    status, B_FALSE)) != ZONE_SUBPROC_OK)
 		return (Z_ERR);
--- a/usr/src/cmd/zoneadm/zoneadm.c	Tue Apr 07 22:50:24 2009 -0700
+++ b/usr/src/cmd/zoneadm/zoneadm.c	Wed Apr 08 07:28:49 2009 -0600
@@ -201,16 +201,6 @@
 char *target_zone;
 static char *target_uuid;
 
-/* used in do_subproc() and signal handler */
-static volatile boolean_t child_killed;
-static int do_subproc_cnt = 0;
-
-/*
- * Used to indicate whether this zoneadm instance has another zoneadm
- * instance in its ancestry.
- */
-static boolean_t zoneadm_is_nested = B_FALSE;
-
 char *
 cmd_to_str(int cmd_num)
 {
@@ -1451,69 +1441,15 @@
 	return (output ? Z_OK : Z_ERR);
 }
 
-static void
-sigterm(int sig)
-{
-	/*
-	 * Ignore SIG{INT,TERM}, so we don't end up in an infinite loop,
-	 * then propagate the signal to our process group.
-	 */
-	assert(sig == SIGINT || sig == SIGTERM);
-	(void) sigset(SIGINT, SIG_IGN);
-	(void) sigset(SIGTERM, SIG_IGN);
-	(void) kill(0, sig);
-	child_killed = B_TRUE;
-}
-
-static int
+int
 do_subproc(char *cmdbuf)
 {
-	char inbuf[1024];	/* arbitrary large amount */
-	FILE *file;
-
-	do_subproc_cnt++;
-	child_killed = B_FALSE;
-	/*
-	 * We use popen(3c) to launch child processes for [un]install;
-	 * this library call does not return a PID, so we have to kill
-	 * the whole process group.  To avoid killing our parent, we
-	 * become a process group leader here.  But doing so can wreak
-	 * havoc with reading from stdin when launched by a non-job-control
-	 * shell, so we close stdin and reopen it as /dev/null first.
-	 */
-	(void) close(STDIN_FILENO);
-	(void) openat(STDIN_FILENO, "/dev/null", O_RDONLY);
-	if (!zoneadm_is_nested)
-		(void) setpgid(0, 0);
-	(void) sigset(SIGINT, sigterm);
-	(void) sigset(SIGTERM, sigterm);
-	file = popen(cmdbuf, "r");
-	for (;;) {
-		if (child_killed || fgets(inbuf, sizeof (inbuf), file) == NULL)
-			break;
-		(void) fputs(inbuf, stdout);
-	}
-	(void) sigset(SIGINT, SIG_DFL);
-	(void) sigset(SIGTERM, SIG_DFL);
-	return (pclose(file));
-}
-
-int
-do_subproc_interactive(char *cmdbuf)
-{
 	void (*saveint)(int);
 	void (*saveterm)(int);
 	void (*savequit)(int);
 	void (*savehup)(int);
 	int pid, child, status;
 
-	/*
-	 * do_subproc() links stdin to /dev/null, which would break any
-	 * interactive subprocess we try to launch here.  Similarly, we
-	 * can't have been launched as a subprocess ourselves.
-	 */
-	assert(do_subproc_cnt == 0 && !zoneadm_is_nested);
-
 	if ((child = vfork()) == 0) {
 		(void) execl("/bin/sh", "sh", "-c", cmdbuf, (char *)NULL);
 	}
@@ -1939,10 +1875,7 @@
 			return (Z_ERR);
 	}
 
-	if (zoneadm_is_nested)
-		status = do_subproc(cmdbuf);
-	else
-		status = do_subproc_interactive(cmdbuf);
+	status = do_subproc(cmdbuf);
 	err = subproc_status(gettext("brand-specific verification"),
 	    status, B_FALSE);
 
@@ -3008,7 +2941,7 @@
 			create_zfs_zonepath(zonepath);
 	}
 
-	status = do_subproc_interactive(cmdbuf);
+	status = do_subproc(cmdbuf);
 	if ((subproc_err =
 	    subproc_status(gettext("brand-specific installation"), status,
 	    B_FALSE)) != ZONE_SUBPROC_OK) {
@@ -3800,7 +3733,7 @@
 	 */
 	if (cmdbuf[0] != '\0') {
 		/* Run the clone hook */
-		status = do_subproc_interactive(cmdbuf);
+		status = do_subproc(cmdbuf);
 		if ((status = subproc_status(gettext("brand-specific clone"),
 		    status, B_FALSE)) != ZONE_SUBPROC_OK) {
 			if (status == ZONE_SUBPROC_USAGE && !brand_help)
@@ -4393,7 +4326,7 @@
 
 	if (cmdbuf[0] != '\0') {
 		/* Run the detach hook */
-		status = do_subproc_interactive(cmdbuf);
+		status = do_subproc(cmdbuf);
 		if ((status = subproc_status(gettext("brand-specific detach"),
 		    status, B_FALSE)) != ZONE_SUBPROC_OK) {
 			if (status == ZONE_SUBPROC_USAGE && !brand_help)
@@ -5043,7 +4976,7 @@
 	 */
 	if (cmdbuf[0] != '\0') {
 		/* Run the uninstall hook */
-		status = do_subproc_interactive(cmdbuf);
+		status = do_subproc(cmdbuf);
 		if ((status = subproc_status(gettext("brand-specific "
 		    "uninstall"), status, B_FALSE)) != ZONE_SUBPROC_OK) {
 			if (status == ZONE_SUBPROC_USAGE && !brand_help)
@@ -5636,8 +5569,6 @@
 	 * indicate it.  If not, make that explicit in our environment.
 	 */
 	zonecfg_init_lock_file(target_zone, &zone_lock_env);
-	if (zone_lock_env != NULL)
-		zoneadm_is_nested = B_TRUE;
 
 	/*
 	 * If we are going to be operating on a single zone, retrieve its
--- a/usr/src/cmd/zoneadm/zoneadm.h	Tue Apr 07 22:50:24 2009 -0700
+++ b/usr/src/cmd/zoneadm/zoneadm.h	Wed Apr 08 07:28:49 2009 -0600
@@ -20,15 +20,13 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #ifndef _ZONEADM_H
 #define	_ZONEADM_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #define	CMD_HELP	0
 #define	CMD_BOOT	1
 #define	CMD_HALT	2
@@ -69,7 +67,7 @@
 
 extern int clone_copy(char *source_zonepath, char *zonepath);
 extern char *cmd_to_str(int cmd_num);
-extern int do_subproc_interactive(char *cmdbuf);
+extern int do_subproc(char *cmdbuf);
 extern int subproc_status(const char *cmd, int status,
     boolean_t verbose_failure);
 extern void zerror(const char *fmt, ...);