Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Apr 2017 18:01:43 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r316891 - vendor-sys/illumos/dist/common/zfs vendor/illumos/dist/cmd/zfs vendor/illumos/dist/lib/libzfs/common vendor/illumos/dist/man/man1m
Message-ID:  <201704141801.v3EI1hIj060303@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Fri Apr 14 18:01:43 2017
New Revision: 316891
URL: https://svnweb.freebsd.org/changeset/base/316891

Log:
  7386 zfs get does not work properly with bookmarks
  
  illumos/illumos-gate@edb901aab9c738b5eb15aa55933e82b0f2f9d9a2
  https://github.com/illumos/illumos-gate/commit/edb901aab9c738b5eb15aa55933e82b0f2f9d9a2
  
  https://www.illumos.org/issues/7386
    The zfs get command does not work with the bookmark parameter while it works
    properly with both filesystem and snapshot:
    # zfs get -t all -r creation rpool/test
    NAME               PROPERTY  VALUE                  SOURCE
    rpool/test         creation  Fri Sep 16 15:00 2016  -
    rpool/test@snap    creation  Fri Sep 16 15:00 2016  -
    rpool/test#bkmark  creation  Fri Sep 16 15:00 2016  -
    # zfs get -t all -r creation rpool/test@snap
    NAME             PROPERTY  VALUE                  SOURCE
    rpool/test@snap  creation  Fri Sep 16 15:00 2016  -
    # zfs get -t all -r creation rpool/test#bkmark
    cannot open 'rpool/test#bkmark': invalid dataset name
    #
    The zfs get command should be modified to work properly with bookmarks too.
  
  Reviewed by: Simon Klinkert <simon.klinkert@gmail.com>
  Reviewed by: Paul Dagnelie <pcd@delphix.com>
  Approved by: Matthew Ahrens <mahrens@delphix.com>
  Author: Marcel Telka <marcel@telka.sk>

Modified:
  vendor-sys/illumos/dist/common/zfs/zfs_namecheck.c
  vendor-sys/illumos/dist/common/zfs/zfs_namecheck.h

Changes in other areas also in this revision:
Modified:
  vendor/illumos/dist/cmd/zfs/zfs_main.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_pool.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_util.c
  vendor/illumos/dist/man/man1m/zfs.1m

Modified: vendor-sys/illumos/dist/common/zfs/zfs_namecheck.c
==============================================================================
--- vendor-sys/illumos/dist/common/zfs/zfs_namecheck.c	Fri Apr 14 18:00:42 2017	(r316890)
+++ vendor-sys/illumos/dist/common/zfs/zfs_namecheck.c	Fri Apr 14 18:01:43 2017	(r316891)
@@ -120,9 +120,9 @@ permset_namecheck(const char *path, name
 }
 
 /*
- * Dataset names must be of the following form:
+ * Entity names must be of the following form:
  *
- * 	[component][/]*[component][@component]
+ * 	[component/]*[component][(@|#)component]?
  *
  * Where each component is made up of alphanumeric characters plus the following
  * characters:
@@ -133,10 +133,10 @@ permset_namecheck(const char *path, name
  * names for temporary clones (for online recv).
  */
 int
-dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
+entity_namecheck(const char *path, namecheck_err_t *why, char *what)
 {
-	const char *loc, *end;
-	int found_snapshot;
+	const char *start, *end;
+	int found_delim;
 
 	/*
 	 * Make sure the name is not too long.
@@ -161,12 +161,13 @@ dataset_namecheck(const char *path, name
 		return (-1);
 	}
 
-	loc = path;
-	found_snapshot = 0;
+	start = path;
+	found_delim = 0;
 	for (;;) {
 		/* Find the end of this component */
-		end = loc;
-		while (*end != '/' && *end != '@' && *end != '\0')
+		end = start;
+		while (*end != '/' && *end != '@' && *end != '#' &&
+		    *end != '\0')
 			end++;
 
 		if (*end == '\0' && end[-1] == '/') {
@@ -176,25 +177,8 @@ dataset_namecheck(const char *path, name
 			return (-1);
 		}
 
-		/* Zero-length components are not allowed */
-		if (loc == end) {
-			if (why) {
-				/*
-				 * Make sure this is really a zero-length
-				 * component and not a '@@'.
-				 */
-				if (*end == '@' && found_snapshot) {
-					*why = NAME_ERR_MULTIPLE_AT;
-				} else {
-					*why = NAME_ERR_EMPTY_COMPONENT;
-				}
-			}
-
-			return (-1);
-		}
-
 		/* Validate the contents of this component */
-		while (loc != end) {
+		for (const char *loc = start; loc != end; loc++) {
 			if (!valid_char(*loc) && *loc != '%') {
 				if (why) {
 					*why = NAME_ERR_INVALCHAR;
@@ -202,43 +186,64 @@ dataset_namecheck(const char *path, name
 				}
 				return (-1);
 			}
-			loc++;
 		}
 
-		/* If we've reached the end of the string, we're OK */
-		if (*end == '\0')
-			return (0);
-
-		if (*end == '@') {
-			/*
-			 * If we've found an @ symbol, indicate that we're in
-			 * the snapshot component, and report a second '@'
-			 * character as an error.
-			 */
-			if (found_snapshot) {
+		/* Snapshot or bookmark delimiter found */
+		if (*end == '@' || *end == '#') {
+			/* Multiple delimiters are not allowed */
+			if (found_delim != 0) {
 				if (why)
-					*why = NAME_ERR_MULTIPLE_AT;
+					*why = NAME_ERR_MULTIPLE_DELIMITERS;
 				return (-1);
 			}
 
-			found_snapshot = 1;
+			found_delim = 1;
+		}
+
+		/* Zero-length components are not allowed */
+		if (start == end) {
+			if (why)
+				*why = NAME_ERR_EMPTY_COMPONENT;
+			return (-1);
 		}
 
+		/* If we've reached the end of the string, we're OK */
+		if (*end == '\0')
+			return (0);
+
 		/*
-		 * If there is a '/' in a snapshot name
+		 * If there is a '/' in a snapshot or bookmark name
 		 * then report an error
 		 */
-		if (*end == '/' && found_snapshot) {
+		if (*end == '/' && found_delim != 0) {
 			if (why)
 				*why = NAME_ERR_TRAILING_SLASH;
 			return (-1);
 		}
 
 		/* Update to the next component */
-		loc = end + 1;
+		start = end + 1;
 	}
 }
 
+/*
+ * Dataset is any entity, except bookmark
+ */
+int
+dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
+{
+	int ret = entity_namecheck(path, why, what);
+
+	if (ret == 0 && strchr(path, '#') != NULL) {
+		if (why != NULL) {
+			*why = NAME_ERR_INVALCHAR;
+			*what = '#';
+		}
+		return (-1);
+	}
+
+	return (ret);
+}
 
 /*
  * mountpoint names must be of the following form:

Modified: vendor-sys/illumos/dist/common/zfs/zfs_namecheck.h
==============================================================================
--- vendor-sys/illumos/dist/common/zfs/zfs_namecheck.h	Fri Apr 14 18:00:42 2017	(r316890)
+++ vendor-sys/illumos/dist/common/zfs/zfs_namecheck.h	Fri Apr 14 18:01:43 2017	(r316891)
@@ -38,7 +38,7 @@ typedef enum {
 	NAME_ERR_EMPTY_COMPONENT,	/* name contains an empty component */
 	NAME_ERR_TRAILING_SLASH,	/* name ends with a slash */
 	NAME_ERR_INVALCHAR,		/* invalid character found */
-	NAME_ERR_MULTIPLE_AT,		/* multiple '@' characters found */
+	NAME_ERR_MULTIPLE_DELIMITERS,	/* multiple '@'/'#' delimiters found */
 	NAME_ERR_NOLETTER,		/* pool doesn't begin with a letter */
 	NAME_ERR_RESERVED,		/* entire name is reserved */
 	NAME_ERR_DISKLIKE,		/* reserved disk name (c[0-9].*) */
@@ -49,6 +49,7 @@ typedef enum {
 #define	ZFS_PERMSET_MAXLEN	64
 
 int pool_namecheck(const char *, namecheck_err_t *, char *);
+int entity_namecheck(const char *, namecheck_err_t *, char *);
 int dataset_namecheck(const char *, namecheck_err_t *, char *);
 int mountpoint_namecheck(const char *, namecheck_err_t *);
 int zfs_component_namecheck(const char *, namecheck_err_t *, char *);



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