diff options
Diffstat (limited to 'lib/libzfs/libzfs_dataset.c')
-rw-r--r-- | lib/libzfs/libzfs_dataset.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index d548cc0ec..2c707f23f 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -4370,14 +4370,14 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force) * Renames the given dataset. */ int -zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive, - boolean_t force_unmount) +zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags) { int ret = 0; zfs_cmd_t zc = {"\0"}; char *delim; prop_changelist_t *cl = NULL; char parent[ZFS_MAX_DATASET_NAME_LEN]; + char property[ZFS_MAXPROPLEN]; libzfs_handle_t *hdl = zhp->zfs_hdl; char errbuf[1024]; @@ -4429,7 +4429,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive, if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE)) return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); } else { - if (recursive) { + if (flags.recursive) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "recursive rename must be a snapshot")); return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); @@ -4470,8 +4470,19 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive, return (zfs_error(hdl, EZFS_ZONED, errbuf)); } - if (recursive) { - zfs_handle_t *zhrp; + /* + * Avoid unmounting file systems with mountpoint property set to + * 'legacy' or 'none' even if -u option is not given. + */ + if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM && + !flags.recursive && !flags.nounmount && + zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, property, + sizeof (property), NULL, NULL, 0, B_FALSE) == 0 && + (strcmp(property, "legacy") == 0 || + strcmp(property, "none") == 0)) { + flags.nounmount = B_TRUE; + } + if (flags.recursive) { char *parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name); if (parentname == NULL) { ret = -1; @@ -4479,7 +4490,8 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive, } delim = strchr(parentname, '@'); *delim = '\0'; - zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_DATASET); + zfs_handle_t *zhrp = zfs_open(zhp->zfs_hdl, parentname, + ZFS_TYPE_DATASET); free(parentname); if (zhrp == NULL) { ret = -1; @@ -4488,8 +4500,9 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive, zfs_close(zhrp); } else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) { if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, + flags.nounmount ? CL_GATHER_DONT_UNMOUNT : CL_GATHER_ITER_MOUNTED, - force_unmount ? MS_FORCE : 0)) == NULL) + flags.forceunmount ? MS_FORCE : 0)) == NULL) return (-1); if (changelist_haszonedchild(cl)) { @@ -4513,7 +4526,8 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive, (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); (void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value)); - zc.zc_cookie = recursive; + zc.zc_cookie = !!flags.recursive; + zc.zc_cookie |= (!!flags.nounmount) << 1; if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) { /* @@ -4523,7 +4537,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive, (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zc.zc_name); - if (recursive && errno == EEXIST) { + if (flags.recursive && errno == EEXIST) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "a child dataset already has a snapshot " "with the new name")); |