From owner-svn-src-vendor@freebsd.org Fri Apr 14 18:01:45 2017 Return-Path: Delivered-To: svn-src-vendor@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 20BADD3E313; Fri, 14 Apr 2017 18:01:45 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D8353DB6; Fri, 14 Apr 2017 18:01:44 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v3EI1iBs060314; Fri, 14 Apr 2017 18:01:44 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v3EI1h3X060309; Fri, 14 Apr 2017 18:01:43 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201704141801.v3EI1h3X060309@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Fri, 14 Apr 2017 18:01:43 +0000 (UTC) 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 X-SVN-Group: vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Apr 2017 18:01:45 -0000 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 Reviewed by: Paul Dagnelie Approved by: Matthew Ahrens Author: Marcel Telka 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 Changes in other areas also in this revision: Modified: vendor-sys/illumos/dist/common/zfs/zfs_namecheck.c vendor-sys/illumos/dist/common/zfs/zfs_namecheck.h Modified: vendor/illumos/dist/cmd/zfs/zfs_main.c ============================================================================== --- vendor/illumos/dist/cmd/zfs/zfs_main.c Fri Apr 14 18:00:42 2017 (r316890) +++ vendor/illumos/dist/cmd/zfs/zfs_main.c Fri Apr 14 18:01:43 2017 (r316891) @@ -232,7 +232,7 @@ get_usage(zfs_help_t idx) "[-o \"all\" | field[,...]]\n" "\t [-t type[,...]] [-s source[,...]]\n" "\t <\"all\" | property[,...]> " - "[filesystem|volume|snapshot] ...\n")); + "[filesystem|volume|snapshot|bookmark] ...\n")); case HELP_INHERIT: return (gettext("\tinherit [-rS] " " ...\n")); @@ -1594,7 +1594,7 @@ zfs_do_get(int argc, char **argv) { zprop_get_cbdata_t cb = { 0 }; int i, c, flags = ZFS_ITER_ARGS_CAN_BE_PATHS; - int types = ZFS_TYPE_DATASET; + int types = ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK; char *value, *fields; int ret = 0; int limit = 0; Modified: vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c ============================================================================== --- vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c Fri Apr 14 18:00:42 2017 (r316890) +++ vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c Fri Apr 14 18:01:43 2017 (r316891) @@ -105,7 +105,7 @@ zfs_validate_name(libzfs_handle_t *hdl, char what; (void) zfs_prop_get_table(); - if (dataset_namecheck(path, &why, &what) != 0) { + if (entity_namecheck(path, &why, &what) != 0) { if (hdl != NULL) { switch (why) { case NAME_ERR_TOOLONG: @@ -134,9 +134,10 @@ zfs_validate_name(libzfs_handle_t *hdl, "'%c' in name"), what); break; - case NAME_ERR_MULTIPLE_AT: + case NAME_ERR_MULTIPLE_DELIMITERS: zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "multiple '@' delimiters in name")); + "multiple '@' and/or '#' delimiters in " + "name")); break; case NAME_ERR_NOLETTER: @@ -167,7 +168,7 @@ zfs_validate_name(libzfs_handle_t *hdl, if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) { if (hdl != NULL) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "snapshot delimiter '@' in filesystem name")); + "snapshot delimiter '@' is not expected here")); return (0); } @@ -178,6 +179,20 @@ zfs_validate_name(libzfs_handle_t *hdl, return (0); } + if (!(type & ZFS_TYPE_BOOKMARK) && strchr(path, '#') != NULL) { + if (hdl != NULL) + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "bookmark delimiter '#' is not expected here")); + return (0); + } + + if (type == ZFS_TYPE_BOOKMARK && strchr(path, '#') == NULL) { + if (hdl != NULL) + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "missing '#' delimiter in bookmark name")); + return (0); + } + if (modifying && strchr(path, '%') != NULL) { if (hdl != NULL) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, @@ -615,8 +630,36 @@ make_bookmark_handle(zfs_handle_t *paren return (zhp); } +struct zfs_open_bookmarks_cb_data { + const char *path; + zfs_handle_t *zhp; +}; + +static int +zfs_open_bookmarks_cb(zfs_handle_t *zhp, void *data) +{ + struct zfs_open_bookmarks_cb_data *dp = data; + + /* + * Is it the one we are looking for? + */ + if (strcmp(dp->path, zfs_get_name(zhp)) == 0) { + /* + * We found it. Save it and let the caller know we are done. + */ + dp->zhp = zhp; + return (EEXIST); + } + + /* + * Not found. Close the handle and ask for another one. + */ + zfs_close(zhp); + return (0); +} + /* - * Opens the given snapshot, filesystem, or volume. The 'types' + * Opens the given snapshot, bookmark, filesystem, or volume. The 'types' * argument is a mask of acceptable types. The function will print an * appropriate error message and return NULL if it can't be opened. */ @@ -625,6 +668,7 @@ zfs_open(libzfs_handle_t *hdl, const cha { zfs_handle_t *zhp; char errbuf[1024]; + char *bookp; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "cannot open '%s'"), path); @@ -632,20 +676,68 @@ zfs_open(libzfs_handle_t *hdl, const cha /* * Validate the name before we even try to open it. */ - if (!zfs_validate_name(hdl, path, ZFS_TYPE_DATASET, B_FALSE)) { - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "invalid dataset name")); + if (!zfs_validate_name(hdl, path, types, B_FALSE)) { (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf); return (NULL); } /* - * Try to get stats for the dataset, which will tell us if it exists. + * Bookmarks needs to be handled separately. */ - errno = 0; - if ((zhp = make_dataset_handle(hdl, path)) == NULL) { - (void) zfs_standard_error(hdl, errno, errbuf); - return (NULL); + bookp = strchr(path, '#'); + if (bookp == NULL) { + /* + * Try to get stats for the dataset, which will tell us if it + * exists. + */ + errno = 0; + if ((zhp = make_dataset_handle(hdl, path)) == NULL) { + (void) zfs_standard_error(hdl, errno, errbuf); + return (NULL); + } + } else { + char dsname[ZFS_MAX_DATASET_NAME_LEN]; + zfs_handle_t *pzhp; + struct zfs_open_bookmarks_cb_data cb_data = {path, NULL}; + + /* + * We need to cut out '#' and everything after '#' + * to get the parent dataset name only. + */ + assert(bookp - path < sizeof (dsname)); + (void) strncpy(dsname, path, bookp - path); + dsname[bookp - path] = '\0'; + + /* + * Create handle for the parent dataset. + */ + errno = 0; + if ((pzhp = make_dataset_handle(hdl, dsname)) == NULL) { + (void) zfs_standard_error(hdl, errno, errbuf); + return (NULL); + } + + /* + * Iterate bookmarks to find the right one. + */ + errno = 0; + if ((zfs_iter_bookmarks(pzhp, zfs_open_bookmarks_cb, + &cb_data) == 0) && (cb_data.zhp == NULL)) { + (void) zfs_error(hdl, EZFS_NOENT, errbuf); + zfs_close(pzhp); + return (NULL); + } + if (cb_data.zhp == NULL) { + (void) zfs_standard_error(hdl, errno, errbuf); + zfs_close(pzhp); + return (NULL); + } + zhp = cb_data.zhp; + + /* + * Cleanup. + */ + zfs_close(pzhp); } if (!(types & zhp->zfs_type)) { Modified: vendor/illumos/dist/lib/libzfs/common/libzfs_pool.c ============================================================================== --- vendor/illumos/dist/lib/libzfs/common/libzfs_pool.c Fri Apr 14 18:00:42 2017 (r316890) +++ vendor/illumos/dist/lib/libzfs/common/libzfs_pool.c Fri Apr 14 18:01:43 2017 (r316891) @@ -946,9 +946,10 @@ zpool_name_valid(libzfs_handle_t *hdl, b "trailing slash in name")); break; - case NAME_ERR_MULTIPLE_AT: + case NAME_ERR_MULTIPLE_DELIMITERS: zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "multiple '@' delimiters in name")); + "multiple '@' and/or '#' delimiters in " + "name")); break; default: Modified: vendor/illumos/dist/lib/libzfs/common/libzfs_util.c ============================================================================== --- vendor/illumos/dist/lib/libzfs/common/libzfs_util.c Fri Apr 14 18:00:42 2017 (r316890) +++ vendor/illumos/dist/lib/libzfs/common/libzfs_util.c Fri Apr 14 18:01:43 2017 (r316891) @@ -689,7 +689,7 @@ zfs_get_pool_handle(const zfs_handle_t * * Given a name, determine whether or not it's a valid path * (starts with '/' or "./"). If so, walk the mnttab trying * to match the device number. If not, treat the path as an - * fs/vol/snap name. + * fs/vol/snap/bkmark name. */ zfs_handle_t * zfs_path_to_zhandle(libzfs_handle_t *hdl, char *path, zfs_type_t argtype) Modified: vendor/illumos/dist/man/man1m/zfs.1m ============================================================================== --- vendor/illumos/dist/man/man1m/zfs.1m Fri Apr 14 18:00:42 2017 (r316890) +++ vendor/illumos/dist/man/man1m/zfs.1m Fri Apr 14 18:01:43 2017 (r316891) @@ -28,7 +28,7 @@ .\" Copyright (c) 2014 Integros [integros.com] .\" Copyright 2016 Nexenta Systems, Inc. .\" -.Dd September 3, 2016 +.Dd September 16, 2016 .Dt ZFS 1M .Os .Sh NAME @@ -112,7 +112,7 @@ .Oo Fl s Ar source Ns Oo , Ns Ar source Oc Ns ... Oc .Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc .Cm all | Ar property Ns Oo , Ns Ar property Oc Ns ... -.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ... +.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns | Ns Ar bookmark Ns ... .Nm .Cm inherit .Op Fl rS @@ -2122,7 +2122,7 @@ section. .Oo Fl s Ar source Ns Oo , Ns Ar source Oc Ns ... Oc .Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc .Cm all | Ar property Ns Oo , Ns Ar property Oc Ns ... -.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ... +.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns | Ns Ar bookmark Ns ... .Xc Displays properties for the given datasets. If no datasets are specified, then the command displays properties for all datasets on the system. For each