6347497 'add fs' of a ZFS filesystem doesn't work for a local zone
authorlling
Tue, 07 Feb 2006 08:28:45 -0800
changeset 1393 72ffb78e31b0
parent 1392 ddf13d3c7346
child 1394 e8d500b79ced
6347497 'add fs' of a ZFS filesystem doesn't work for a local zone 6381427 Cannot create filesystem in LZ, permission denied
usr/src/cmd/zoneadm/zoneadm.c
usr/src/lib/libzfs/common/libzfs_dataset.c
--- a/usr/src/cmd/zoneadm/zoneadm.c	Tue Feb 07 02:27:51 2006 -0800
+++ b/usr/src/cmd/zoneadm/zoneadm.c	Tue Feb 07 08:28:45 2006 -0800
@@ -1923,6 +1923,89 @@
 	return (return_code);
 }
 
+/* ARGSUSED */
+static void
+zfs_fs_err_handler(const char *fmt, va_list ap)
+{
+	/*
+	 * Do nothing - do not print the libzfs error messages.
+	 */
+}
+
+/*
+ * Verify that the ZFS dataset exists, and its mountpoint
+ * property is set to "legacy".
+ */
+static int
+verify_fs_zfs(struct zone_fstab *fstab)
+{
+	zfs_handle_t *zhp;
+	char propbuf[ZFS_MAXPROPLEN];
+
+	zfs_set_error_handler(zfs_fs_err_handler);
+
+	if ((zhp = zfs_open(fstab->zone_fs_special, ZFS_TYPE_ANY)) == NULL) {
+		(void) fprintf(stderr, gettext("cannot verify fs %s: "
+			"could not access zfs dataset '%s'\n"),
+			fstab->zone_fs_dir, fstab->zone_fs_special);
+		return (Z_ERR);
+	}
+
+	if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
+		(void) fprintf(stderr, gettext("cannot verify fs %s: "
+			"'%s' is not a filesystem\n"),
+			fstab->zone_fs_dir, fstab->zone_fs_special);
+		zfs_close(zhp);
+		return (Z_ERR);
+	}
+
+	if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, propbuf, sizeof (propbuf),
+	    NULL, NULL, 0, 0) != 0 || strcmp(propbuf, "legacy") != 0) {
+		(void) fprintf(stderr, gettext("cannot verify fs %s: zfs '%s' "
+			"mountpoint is not \"legacy\"\n"),
+			fstab->zone_fs_dir, fstab->zone_fs_special);
+		zfs_close(zhp);
+		return (Z_ERR);
+	}
+
+	zfs_close(zhp);
+	return (Z_OK);
+}
+
+/*
+ * Verify that the special device/filesystem exists and is valid.
+ */
+static int
+verify_fs_special(struct zone_fstab *fstab)
+{
+	struct stat st;
+
+	if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0)
+		return (verify_fs_zfs(fstab));
+
+	if (stat(fstab->zone_fs_special, &st) != 0) {
+		(void) fprintf(stderr, gettext("cannot verify fs "
+		    "%s: could not access %s: %s\n"), fstab->zone_fs_dir,
+		    fstab->zone_fs_special, strerror(errno));
+		return (Z_ERR);
+	}
+
+	if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) {
+		/*
+		 * TRANSLATION_NOTE
+		 * fs and NFS are literals that should
+		 * not be translated.
+		 */
+		(void) fprintf(stderr, gettext("cannot verify "
+		    "fs %s: NFS mounted file-system.\n"
+		    "\tA local file-system must be used.\n"),
+		    fstab->zone_fs_special);
+		return (Z_ERR);
+	}
+
+	return (Z_OK);
+}
+
 static int
 verify_filesystems(zone_dochandle_t handle)
 {
@@ -2007,29 +2090,12 @@
 			return_code = Z_ERR;
 			goto next_fs;
 		}
-		/*
-		 * Verify fs_special and optionally fs_raw, exists.
-		 */
-		if (stat(fstab.zone_fs_special, &st) != 0) {
-			(void) fprintf(stderr, gettext("could not verify fs "
-			    "%s: could not access %s: %s\n"), fstab.zone_fs_dir,
-			    fstab.zone_fs_special, strerror(errno));
-			return_code = Z_ERR;
+
+		/* Verify fs_special. */
+		if ((return_code = verify_fs_special(&fstab)) != Z_OK)
 			goto next_fs;
-		}
-		if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) {
-			/*
-			 * TRANSLATION_NOTE
-			 * fs and NFS are literals that should
-			 * not be translated.
-			 */
-			(void) fprintf(stderr, gettext("cannot verify "
-			    "fs %s: NFS mounted file-system.\n"
-			    "\tA local file-system must be used.\n"),
-			    fstab.zone_fs_special);
-			return_code = Z_ERR;
-			goto next_fs;
-		}
+
+		/* Verify fs_raw. */
 		if (fstab.zone_fs_raw[0] != '\0' &&
 		    stat(fstab.zone_fs_raw, &st) != 0) {
 			/*
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c	Tue Feb 07 02:27:51 2006 -0800
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c	Tue Feb 07 08:28:45 2006 -0800
@@ -1761,7 +1761,7 @@
 
 	/* we are in a non-global zone, but parent is in the global zone */
 	if (getzoneid() != GLOBAL_ZONEID &&
-	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
+	    !zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
 		zfs_error(dgettext(TEXT_DOMAIN,
 		    "cannot create '%s': permission denied"), path);
 		zfs_close(zhp);