changeset 3686:5fd6740801a2

6346003 zlogin exits when faced with too much data. 6440239 A moved zfs zonepath was not removed after uninstallation. 6435940 redundant zfs snapshot was created as cloning zones across different zfs pools. 6486314 zoneadm uninstall following migration does not remove SUNWattached.xml preventing auto zfs removal 6437686 zoneadm attach -n with invalid path reports unmatched error message 6519634 a 0 return handler if added to <verify_adm> in config.xml will make zoneadm clone fail 6525784 getvmusage is a private api
author gjelinek
date Tue, 20 Feb 2007 14:08:22 -0800
parents 7a7a1dd7ce48
children 96d6b6ad3918
files usr/src/cmd/zlogin/zlogin.c usr/src/cmd/zoneadm/zfs.c usr/src/cmd/zoneadm/zoneadm.c usr/src/lib/libc/port/mapfile-vers
diffstat 4 files changed, 102 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/zlogin/zlogin.c	Tue Feb 20 13:19:10 2007 -0800
+++ b/usr/src/cmd/zlogin/zlogin.c	Tue Feb 20 14:08:22 2007 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -559,12 +559,14 @@
  * keystroke at a time, state associated with the user input (are we at the
  * beginning of the line?  are we locally echoing the next character?) is
  * maintained by beginning_of_line and local_echo across calls to the routine.
+ * If the write to outfd fails, we'll try to read from infd in an attempt
+ * to prevent deadlock between the two processes.
  *
  * This routine returns -1 when the 'quit' escape sequence has been issued,
  * and 0 otherwise.
  */
 static int
-process_user_input(int outfd, char *buf, size_t nbytes)
+process_user_input(int outfd, int infd, char *buf, size_t nbytes)
 {
 	static boolean_t beginning_of_line = B_TRUE;
 	static boolean_t local_echo = B_FALSE;
@@ -582,14 +584,49 @@
 			local_echo = B_FALSE;
 			if (c == '.' || c == effective_termios.c_cc[VEOF]) {
 				char cc[CANONIFY_LEN];
+
 				canonify(c, cc);
 				(void) write(STDOUT_FILENO, &cmdchar, 1);
 				(void) write(STDOUT_FILENO, cc, strlen(cc));
 				return (-1);
 			}
 		}
-		if (write(outfd, &c, 1) <= 0)
+retry:
+		if (write(outfd, &c, 1) <= 0) {
+			/*
+			 * Since the fd we are writing to is opened with
+			 * O_NONBLOCK it is possible to get EAGAIN if the
+			 * pipe is full.  One way this could happen is if we
+			 * are writing a lot of data into the pipe in this loop
+			 * and the application on the other end is echoing that
+			 * data back out to its stdout.  The output pipe can
+			 * fill up since we are stuck here in this loop and not
+			 * draining the other pipe.  We can try to read some of
+			 * the data to see if we can drain the pipe so that the
+			 * application can continue to make progress.  The read
+			 * is non-blocking so we won't hang here.  We also wait
+			 * a bit before retrying since there could be other
+			 * reasons why the pipe is full and we don't want to
+			 * continuously retry.
+			 */
+			if (errno == EAGAIN) {
+				struct timespec rqtp;
+				int ln;
+				char ibuf[ZLOGIN_BUFSIZ];
+
+				if ((ln = read(infd, ibuf, ZLOGIN_BUFSIZ)) > 0)
+					(void) write(STDOUT_FILENO, ibuf, ln);
+
+				/* sleep for 10 milliseconds */
+				rqtp.tv_sec = 0;
+				rqtp.tv_nsec = 10 * (NANOSEC / MILLISEC);
+				(void) nanosleep(&rqtp, NULL);
+				if (!dead)
+					goto retry;
+			}
+
 			return (-1);
+		}
 		beginning_of_line = (c == '\r' || c == '\n' ||
 		    c == effective_termios.c_cc[VKILL] ||
 		    c == effective_termios.c_cc[VEOL] ||
@@ -707,8 +744,8 @@
 					if (write(stdin_fd, ibuf, cc) == -1)
 						break;
 				} else {
-					if (process_user_input(stdin_fd, ibuf,
-					    cc) == -1)
+					if (process_user_input(stdin_fd,
+					    stdout_fd, ibuf, cc) == -1)
 						break;
 				}
 			} else if (raw_mode == B_TRUE &&
--- a/usr/src/cmd/zoneadm/zfs.c	Tue Feb 20 13:19:10 2007 -0800
+++ b/usr/src/cmd/zoneadm/zfs.c	Tue Feb 20 14:08:22 2007 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -685,8 +685,17 @@
 	}
 	zfs_close(zhp);
 
-	if (clone_snap(snap_name, clone_name) != Z_OK)
+	if (clone_snap(snap_name, clone_name) != Z_OK) {
+		/* Clean up the snapshot we just took. */
+		if ((zhp = zfs_open(g_zfs, snap_name, ZFS_TYPE_SNAPSHOT))
+		    != NULL) {
+			if (zfs_unmount(zhp, NULL, 0) == 0)
+				(void) zfs_destroy(zhp);
+			zfs_close(zhp);
+		}
+
 		return (Z_ERR);
+	}
 
 	(void) printf(gettext("Instead of copying, a ZFS clone has been "
 	    "created for this zone.\n"));
@@ -792,6 +801,13 @@
 		return (Z_ERR);
 	}
 
+	/*
+	 * If the zone has ever been moved then the mountpoint dir will not be
+	 * cleaned up by the zfs_destroy().  To handle this case try to clean
+	 * it up now but don't worry if it fails, that will be normal.
+	 */
+	(void) rmdir(zonepath);
+
 	(void) printf(gettext("The ZFS file system for this zone has been "
 	    "destroyed.\n"));
 
--- a/usr/src/cmd/zoneadm/zoneadm.c	Tue Feb 20 13:19:10 2007 -0800
+++ b/usr/src/cmd/zoneadm/zoneadm.c	Tue Feb 20 14:08:22 2007 -0800
@@ -76,6 +76,7 @@
 #include <libbrand.h>
 #include <libscf.h>
 #include <procfs.h>
+#include <strings.h>
 
 #include <pool.h>
 #include <sys/pool.h>
@@ -2235,7 +2236,10 @@
 			return (Z_ERR);
 	}
 
-	status = do_subproc_interactive(cmdbuf);
+	if (zoneadm_is_nested)
+		status = do_subproc(cmdbuf);
+	else
+		status = do_subproc_interactive(cmdbuf);
 	err = subproc_status(gettext("brand-specific verification"),
 	    status, B_FALSE);
 
@@ -4028,7 +4032,13 @@
 	boolean_t	non_std = B_FALSE;
 	struct dirent	*dp;
 	DIR		*dirp;
-	char		*std_entries[] = {"dev", "lu", "root", NULL};
+			/*
+			 * The SUNWattached.xml file is expected since it might
+			 * exist if the zone was force-attached after a
+			 * migration.
+			 */
+	char		*std_entries[] = {"dev", "lu", "root",
+			    "SUNWattached.xml", NULL};
 			/* (MAXPATHLEN * 3) is for the 3 std_entries dirs */
 	char		cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 3) + 64];
 
@@ -4651,12 +4661,36 @@
 
 	if ((err = zonecfg_attach_manifest(fd, local_handle, rem_handle))
 	    != Z_OK) {
-		if (err == Z_INVALID_DOCUMENT)
-			zerror(gettext("Cannot attach to an earlier release "
-			    "of the operating system"));
-		else
+		res = Z_ERR;
+
+		if (err == Z_INVALID_DOCUMENT) {
+			struct stat st;
+			char buf[6];
+
+			if (strcmp(manifest_path, "-") == 0) {
+				zerror(gettext("Input is not a valid XML "
+				    "file"));
+				goto done;
+			}
+
+			if (fstat(fd, &st) == -1 || !S_ISREG(st.st_mode)) {
+				zerror(gettext("%s is not an XML file"),
+				    manifest_path);
+				goto done;
+			}
+
+			bzero(buf, sizeof (buf));
+			(void) lseek(fd, 0L, SEEK_SET);
+			if (read(fd, buf, sizeof (buf) - 1) < 0 ||
+			    strncmp(buf, "<?xml", 5) != 0)
+				zerror(gettext("%s is not an XML file"),
+				    manifest_path);
+			else
+				zerror(gettext("Cannot attach to an earlier "
+				    "release of the operating system"));
+		} else {
 			zperror(cmd_to_str(CMD_ATTACH), B_TRUE);
-		res = Z_ERR;
+		}
 		goto done;
 	}
 
--- a/usr/src/lib/libc/port/mapfile-vers	Tue Feb 20 13:19:10 2007 -0800
+++ b/usr/src/lib/libc/port/mapfile-vers	Tue Feb 20 14:08:22 2007 -0800
@@ -59,7 +59,6 @@
 	fdatasync;
 	forkallx;
 	forkx;
-	getvmusage;
 	lio_listio;
 	mkdtemp;
 	_mkdtemp;
@@ -1574,6 +1573,7 @@
 	_getvfsent;
 	_getvfsfile;
 	_getvfsspec;
+	getvmusage;
 	__getwchar_xpg5;
 	__getwc_xpg5;
 	_getzoneid;