usr/src/lib/libzfs/common/libzfs_dataset.c
author eschrock
Tue, 05 Sep 2006 11:37:36 -0700
changeset 2676 5cee47eddab6
parent 2665 7b208a92357b
child 2744 0a6f00b6a209
permissions -rw-r--r--
PSARC 2006/486 ZFS canmount property PSARC 2006/497 ZFS create time properties PSARC 2006/502 ZFS get all datasets PSARC 2006/504 ZFS user properties 6269805 properties should be set via an nvlist. 6281585 user defined properties 6349494 'zfs list' output annoying for even moderately long dataset names 6366244 'canmount' option for container-like functionality 6367103 create-time properties 6416639 RFE: provide zfs get -a 6437808 ZFS module version should match on-disk version 6454551 'zfs create -b blocksize filesystem' should fail. 6457478 unrecognized character in error message with 'zpool create -R' command 6457865 missing device name in the error message of 'zpool clear' command 6458571 zfs_ioc_set_prop() doesn't validate input 6458614 zfs ACL #defines should use prefix 6458638 get_configs() accesses bogus memory 6458678 zvol functions should be moved out of zfs_ioctl.h 6458683 zfs_cmd_t could use more cleanup 6458691 common routines to manage zfs_cmd_t nvlists 6460398 zpool import cores on zfs_prop_get 6461029 zpool status -x noexisting-pool has incorrect error message. 6461223 index translations should live with property definitions 6461424 zpool_unmount_datasets() has some busted logic 6461427 zfs_realloc() would be useful 6461757 'zpool status' can report the wrong number of persistent errors 6461784 recursive zfs_snapshot() leaks memory
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
1294
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <assert.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <ctype.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <errno.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <libdevinfo.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <libintl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <math.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <stdio.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <stdlib.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
#include <strings.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <unistd.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
#include <zone.h>
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
    39
#include <fcntl.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
#include <sys/mntent.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#include <sys/mnttab.h>
1294
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
    42
#include <sys/mount.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
#include <sys/zio.h>
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
    46
#include <sys/zap.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
#include <libzfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
#include "zfs_namecheck.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
#include "zfs_prop.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
#include "libzfs_impl.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
 * Given a single type (not a mask of types), return the type in a human
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
 * readable form.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
const char *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
zfs_type_to_name(zfs_type_t type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
	switch (type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
	case ZFS_TYPE_FILESYSTEM:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
		return (dgettext(TEXT_DOMAIN, "filesystem"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
	case ZFS_TYPE_SNAPSHOT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
		return (dgettext(TEXT_DOMAIN, "snapshot"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
	case ZFS_TYPE_VOLUME:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
		return (dgettext(TEXT_DOMAIN, "volume"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
	return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
 * Given a path and mask of ZFS types, return a string describing this dataset.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
 * This is used when we fail to open a dataset and we cannot get an exact type.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
 * We guess what the type would have been based on the path and the mask of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
 * acceptable types.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
static const char *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
path_to_str(const char *path, int types)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
	 * When given a single type, always report the exact type.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
	if (types == ZFS_TYPE_SNAPSHOT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
		return (dgettext(TEXT_DOMAIN, "snapshot"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
	if (types == ZFS_TYPE_FILESYSTEM)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
		return (dgettext(TEXT_DOMAIN, "filesystem"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
	if (types == ZFS_TYPE_VOLUME)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
		return (dgettext(TEXT_DOMAIN, "volume"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
	 * The user is requesting more than one type of dataset.  If this is the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
	 * case, consult the path itself.  If we're looking for a snapshot, and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
	 * a '@' is found, then report it as "snapshot".  Otherwise, remove the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
	 * snapshot attribute and try again.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
	if (types & ZFS_TYPE_SNAPSHOT) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
		if (strchr(path, '@') != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
			return (dgettext(TEXT_DOMAIN, "snapshot"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
		return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
	 * The user has requested either filesystems or volumes.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
	 * We have no way of knowing a priori what type this would be, so always
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
	 * report it as "filesystem" or "volume", our two primitive types.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
	if (types & ZFS_TYPE_FILESYSTEM)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
		return (dgettext(TEXT_DOMAIN, "filesystem"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
	assert(types & ZFS_TYPE_VOLUME);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
	return (dgettext(TEXT_DOMAIN, "volume"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
 * Validate a ZFS path.  This is used even before trying to open the dataset, to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
 * provide a more meaningful error message.  We place a more useful message in
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
 * 'buf' detailing exactly why the name was not valid.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
static int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   122
zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
	namecheck_err_t why;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
	char what;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
	if (dataset_namecheck(path, &why, &what) != 0) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   128
		if (hdl != NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
			switch (why) {
1003
ce99098d6a9b 6350417 long name will cause rename a dataset panic
lling
parents: 905
diff changeset
   130
			case NAME_ERR_TOOLONG:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   131
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   132
				    "name is too long"));
1003
ce99098d6a9b 6350417 long name will cause rename a dataset panic
lling
parents: 905
diff changeset
   133
				break;
ce99098d6a9b 6350417 long name will cause rename a dataset panic
lling
parents: 905
diff changeset
   134
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
			case NAME_ERR_LEADING_SLASH:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   136
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   137
				    "leading slash in name"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
			case NAME_ERR_EMPTY_COMPONENT:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   141
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   142
				    "empty component in name"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
			case NAME_ERR_TRAILING_SLASH:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   146
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   147
				    "trailing slash in name"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
			case NAME_ERR_INVALCHAR:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   151
				zfs_error_aux(hdl,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
				    dgettext(TEXT_DOMAIN, "invalid character "
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   153
				    "'%c' in name"), what);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
			case NAME_ERR_MULTIPLE_AT:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   157
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   158
				    "multiple '@' delimiters in name"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
	if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   167
		if (hdl != NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   168
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   169
			    "snapshot delimiter '@' in filesystem name"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
   173
	if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) {
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
   174
		if (hdl != NULL)
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
   175
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
   176
			    "missing '@' delimeter in snapshot name"));
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
   177
		return (0);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
   178
	}
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
   179
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   180
	return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
zfs_name_valid(const char *name, zfs_type_t type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
{
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   186
	return (zfs_validate_name(NULL, name, type));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
/*
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   190
 * This function takes the raw DSL properties, and filters out the user-defined
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   191
 * properties into a separate nvlist.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   192
 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   193
static int
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   194
process_user_props(zfs_handle_t *zhp)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   195
{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   196
	libzfs_handle_t *hdl = zhp->zfs_hdl;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   197
	nvpair_t *elem;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   198
	nvlist_t *propval;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   199
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   200
	nvlist_free(zhp->zfs_user_props);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   201
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   202
	if (nvlist_alloc(&zhp->zfs_user_props, NV_UNIQUE_NAME, 0) != 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   203
		return (no_memory(hdl));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   204
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   205
	elem = NULL;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   206
	while ((elem = nvlist_next_nvpair(zhp->zfs_props, elem)) != NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   207
		if (!zfs_prop_user(nvpair_name(elem)))
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   208
			continue;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   209
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   210
		verify(nvpair_value_nvlist(elem, &propval) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   211
		if (nvlist_add_nvlist(zhp->zfs_user_props,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   212
		    nvpair_name(elem), propval) != 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   213
			return (no_memory(hdl));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   214
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   215
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   216
	return (0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   217
}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   218
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   219
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
 * Utility function to gather stats (objset and zpl) for the given object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
get_stats(zfs_handle_t *zhp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
	zfs_cmd_t zc = { 0 };
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   226
	libzfs_handle_t *hdl = zhp->zfs_hdl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   230
	if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   231
		return (-1);
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
   232
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   233
	while (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
   234
		if (errno == ENOMEM) {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   235
			if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   236
				zcmd_free_nvlists(&zc);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   237
				return (-1);
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   238
			}
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
   239
		} else {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   240
			zcmd_free_nvlists(&zc);
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
   241
			return (-1);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
   242
		}
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
   243
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
	bcopy(&zc.zc_objset_stats, &zhp->zfs_dmustats,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
	    sizeof (zc.zc_objset_stats));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   248
	(void) strlcpy(zhp->zfs_root, zc.zc_value, sizeof (zhp->zfs_root));
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
   249
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   250
	if (zhp->zfs_props) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   251
		nvlist_free(zhp->zfs_props);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   252
		zhp->zfs_props = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   253
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   254
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   255
	if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zfs_props) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   256
		zcmd_free_nvlists(&zc);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   257
		return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   258
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   260
	zcmd_free_nvlists(&zc);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   261
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   262
	zhp->zfs_volstats = zc.zc_vol_stats;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   263
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   264
	if (process_user_props(zhp) != 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   265
		return (-1);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   266
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
 * Refresh the properties currently stored in the handle.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
zfs_refresh_properties(zfs_handle_t *zhp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
	(void) get_stats(zhp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
 * Makes a handle from the given dataset name.  Used by zfs_open() and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
 * zfs_iter_* to create child handles on the fly.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
zfs_handle_t *
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   284
make_dataset_handle(libzfs_handle_t *hdl, const char *path)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
{
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   286
	zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   287
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   288
	if (zhp == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   289
		return (NULL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   290
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   291
	zhp->zfs_hdl = hdl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
1758
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   293
top:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
	(void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
	if (get_stats(zhp) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
		free(zhp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
1758
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   301
	if (zhp->zfs_dmustats.dds_inconsistent) {
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   302
		zfs_cmd_t zc = { 0 };
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   303
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   304
		/*
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   305
		 * If it is dds_inconsistent, then we've caught it in
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   306
		 * the middle of a 'zfs receive' or 'zfs destroy', and
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   307
		 * it is inconsistent from the ZPL's point of view, so
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   308
		 * can't be mounted.  However, it could also be that we
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   309
		 * have crashed in the middle of one of those
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   310
		 * operations, in which case we need to get rid of the
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   311
		 * inconsistent state.  We do that by either rolling
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   312
		 * back to the previous snapshot (which will fail if
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   313
		 * there is none), or destroying the filesystem.  Note
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   314
		 * that if we are still in the middle of an active
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   315
		 * 'receive' or 'destroy', then the rollback and destroy
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   316
		 * will fail with EBUSY and we will drive on as usual.
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   317
		 */
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   318
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   319
		(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   320
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   321
		if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   322
			(void) zvol_remove_link(hdl, zhp->zfs_name);
1758
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   323
			zc.zc_objset_type = DMU_OST_ZVOL;
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   324
		} else {
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   325
			zc.zc_objset_type = DMU_OST_ZFS;
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   326
		}
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   327
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   328
		/* If we can successfully roll it back, reget the stats */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   329
		if (ioctl(hdl->libzfs_fd, ZFS_IOC_ROLLBACK, &zc) == 0)
1758
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   330
			goto top;
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   331
		/*
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   332
		 * If we can sucessfully destroy it, pretend that it
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   333
		 * never existed.
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   334
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   335
		if (ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc) == 0) {
1758
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   336
			free(zhp);
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   337
			errno = ENOENT;
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   338
			return (NULL);
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   339
		}
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   340
	}
d0750a16db04 6397267 assertion failed: (link->list_next == 0) == (link->list_prev == 0)
ahrens
parents: 1749
diff changeset
   341
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
	 * We've managed to open the dataset and gather statistics.  Determine
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
	 * the high-level type.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
	if (zhp->zfs_dmustats.dds_is_snapshot)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
		zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
	else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
		zhp->zfs_type = ZFS_TYPE_VOLUME;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
	else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
		zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
	else
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   353
		abort();	/* we should never see any other types */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
	return (zhp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
 * Opens the given snapshot, filesystem, or volume.   The 'types'
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
 * argument is a mask of acceptable types.  The function will print an
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
 * appropriate error message and return NULL if it can't be opened.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
zfs_handle_t *
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   364
zfs_open(libzfs_handle_t *hdl, const char *path, int types)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
	zfs_handle_t *zhp;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   367
	char errbuf[1024];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   368
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   369
	(void) snprintf(errbuf, sizeof (errbuf),
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   370
	    dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   373
	 * Validate the name before we even try to open it.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
	 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   375
	if (!zfs_validate_name(hdl, path, ZFS_TYPE_ANY)) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   376
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   377
		    "invalid dataset name"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   378
		(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
	 * Try to get stats for the dataset, which will tell us if it exists.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
	errno = 0;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   386
	if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   387
		(void) zfs_standard_error(hdl, errno, errbuf, path);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
	if (!(types & zhp->zfs_type)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   392
		(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
2142
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   393
		zfs_close(zhp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
	return (zhp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
 * Release a ZFS handle.  Nothing to do but free the associated memory.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
zfs_close(zfs_handle_t *zhp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
	if (zhp->zfs_mntopts)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
		free(zhp->zfs_mntopts);
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   408
	nvlist_free(zhp->zfs_props);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   409
	nvlist_free(zhp->zfs_user_props);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
	free(zhp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
 * Given a numeric suffix, convert the value into a number of bits that the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
 * resulting value must be shifted.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
static int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   418
str2shift(libzfs_handle_t *hdl, const char *buf)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
	const char *ends = "BKMGTPEZ";
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
	if (buf[0] == '\0')
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
	for (i = 0; i < strlen(ends); i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   426
		if (toupper(buf[0]) == ends[i])
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
	if (i == strlen(ends)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   430
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   431
		    "invalid numeric suffix '%s'"), buf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
	 * We want to allow trailing 'b' characters for 'GB' or 'Mb'.  But don't
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
	 * allow 'BB' - that's just weird.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
	if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   440
	    toupper(buf[0]) != 'B'))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
		return (10*i);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   442
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   443
	zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   444
	    "invalid numeric suffix '%s'"), buf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
	return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   446
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   449
 * Convert a string of the form '100G' into a real number.  Used when setting
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
 * properties or creating a volume.  'buf' is used to place an extended error
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
 * message for the caller to use.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
static int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   454
nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
	char *end;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
	int shift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
	*num = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
	/* Check to see if this looks like a number.  */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
	if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   463
		if (hdl)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   464
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   465
			    "bad numeric value '%s'"), value);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
	/* Rely on stroll() to process the numeric portion.  */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
	errno = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
	*num = strtoll(value, &end, 10);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
	 * Check for ERANGE, which indicates that the value is too large to fit
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
	 * in a 64-bit value.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
	if (errno == ERANGE) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   478
		if (hdl)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   479
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   480
			    "numeric value is too large"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
	 * If we have a decimal value, then do the computation with floating
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
	 * point arithmetic.  Otherwise, use standard arithmetic.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
	if (*end == '.') {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
		double fval = strtod(value, &end);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   491
		if ((shift = str2shift(hdl, end)) == -1)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
		fval *= pow(2, shift);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
		if (fval > UINT64_MAX) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   497
			if (hdl)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   498
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   499
				    "numeric value is too large"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
		*num = (uint64_t)fval;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
	} else {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   505
		if ((shift = str2shift(hdl, end)) == -1)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
		/* Check for overflow */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
		if (shift >= 64 || (*num << shift) >> shift != *num) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   510
			if (hdl)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   511
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   512
				    "numeric value is too large"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
		*num <<= shift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   523
zfs_nicestrtonum(libzfs_handle_t *hdl, const char *str, uint64_t *val)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   524
{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   525
	return (nicestrtonum(hdl, str, val));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   526
}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   527
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   528
/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   529
 * The prop_parse_*() functions are designed to allow flexibility in callers
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   530
 * when setting properties.  At the DSL layer, all properties are either 64-bit
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   531
 * numbers or strings.  We want the user to be able to ignore this fact and
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   532
 * specify properties as native values (boolean, for example) or as strings (to
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   533
 * simplify command line utilities).  This also handles converting index types
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   534
 * (compression, checksum, etc) from strings to their on-disk index.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   535
 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   536
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   537
static int
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   538
prop_parse_boolean(libzfs_handle_t *hdl, nvpair_t *elem, uint64_t *val)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
{
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   540
	uint64_t ret;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   541
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   542
	switch (nvpair_type(elem)) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   543
	case DATA_TYPE_STRING:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   544
		{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   545
			char *value;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   546
			VERIFY(nvpair_value_string(elem, &value) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   547
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   548
			if (strcmp(value, "on") == 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   549
				ret = 1;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   550
			} else if (strcmp(value, "off") == 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   551
				ret = 0;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   552
			} else {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   553
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   554
				    "property '%s' must be 'on' or 'off'"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   555
				    nvpair_name(elem));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   556
				return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   557
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   558
			break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   559
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   560
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   561
	case DATA_TYPE_UINT64:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   562
		{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   563
			VERIFY(nvpair_value_uint64(elem, &ret) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   564
			if (ret > 1) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   565
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   566
				    "'%s' must be a boolean value"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   567
				    nvpair_name(elem));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   568
				return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   569
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   570
			break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   571
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   572
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   573
	case DATA_TYPE_BOOLEAN_VALUE:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   574
		{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   575
			boolean_t value;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   576
			VERIFY(nvpair_value_boolean_value(elem, &value) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   577
			ret = value;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   578
			break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   579
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   580
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   581
	default:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   582
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   583
		    "'%s' must be a boolean value"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   584
		    nvpair_name(elem));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   585
		return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   586
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   587
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   588
	*val = ret;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   589
	return (0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   590
}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   591
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   592
static int
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   593
prop_parse_number(libzfs_handle_t *hdl, nvpair_t *elem, zfs_prop_t prop,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   594
    uint64_t *val)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   595
{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   596
	uint64_t ret;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   597
	boolean_t isnone = B_FALSE;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   598
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   599
	switch (nvpair_type(elem)) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   600
	case DATA_TYPE_STRING:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   601
		{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   602
			char *value;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   603
			(void) nvpair_value_string(elem, &value);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   604
			if (strcmp(value, "none") == 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   605
				isnone = B_TRUE;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   606
				ret = 0;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   607
			} else if (nicestrtonum(hdl, value, &ret) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   608
				return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   609
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   610
			break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   611
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   612
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   613
	case DATA_TYPE_UINT64:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   614
		(void) nvpair_value_uint64(elem, &ret);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   615
		break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   616
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   617
	default:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   618
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   619
		    "'%s' must be a number"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   620
		    nvpair_name(elem));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   621
		return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   622
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   623
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   624
	/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   625
	 * Quota special: force 'none' and don't allow 0.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   626
	 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   627
	if (ret == 0 && !isnone && prop == ZFS_PROP_QUOTA) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   628
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   629
		    "use 'none' to disable quota"));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   630
		return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   631
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   632
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   633
	*val = ret;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   634
	return (0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   635
}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   636
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   637
static int
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   638
prop_parse_index(libzfs_handle_t *hdl, nvpair_t *elem, zfs_prop_t prop,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   639
    uint64_t *val)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   640
{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   641
	char *propname = nvpair_name(elem);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   642
	char *value;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   643
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   644
	if (nvpair_type(elem) != DATA_TYPE_STRING) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   645
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   646
		    "'%s' must be a string"), propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   647
		return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   648
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   649
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   650
	(void) nvpair_value_string(elem, &value);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   651
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   652
	if (zfs_prop_string_to_index(prop, value, val) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   653
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   654
		    "'%s' must be one of '%s'"), propname,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   655
		    zfs_prop_values(prop));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   656
		return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   657
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   658
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   659
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
/*
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   663
 * Given an nvlist of properties to set, validates that they are correct, and
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   664
 * parses any numeric properties (index, boolean, etc) if they are specified as
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   665
 * strings.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
 */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   667
static nvlist_t *
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   668
zfs_validate_properties(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   669
    uint64_t zoned, zfs_handle_t *zhp, const char *errbuf)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
{
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   671
	nvpair_t *elem;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   672
	const char *propname;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   673
	zfs_prop_t prop;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   674
	uint64_t intval;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   675
	char *strval;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   676
	nvlist_t *ret;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   677
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   678
	if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   679
		(void) no_memory(hdl);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   680
		return (NULL);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   681
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   682
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   683
	if (type == ZFS_TYPE_SNAPSHOT) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   684
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   685
		    "snaphot properties cannot be modified"));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   686
		(void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   687
		goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   689
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   690
	elem = NULL;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   691
	while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   692
		propname = nvpair_name(elem);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   693
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   694
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   695
		 * Make sure this property is valid and applies to this type.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   696
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   697
		if ((prop = zfs_name_to_prop(propname)) == ZFS_PROP_INVAL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   698
			if (!zfs_prop_user(propname)) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   699
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   700
				    "invalid property '%s'"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   701
				    propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   702
				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   703
				goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   704
			} else {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   705
				/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   706
				 * If this is a user property, make sure it's a
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   707
				 * string, and that it's less than
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   708
				 * ZAP_MAXNAMELEN.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   709
				 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   710
				if (nvpair_type(elem) != DATA_TYPE_STRING) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   711
					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   712
					    "'%s' must be a string"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   713
					    propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   714
					(void) zfs_error(hdl, EZFS_BADPROP,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   715
					    errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   716
					goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   717
				}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   718
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   719
				if (strlen(nvpair_name(elem)) >=
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   720
				    ZAP_MAXNAMELEN) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   721
					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   722
					    "property name '%s' is too long"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   723
					    propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   724
					(void) zfs_error(hdl, EZFS_BADPROP,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   725
					    errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   726
					goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   727
				}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   728
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   729
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   730
			(void) nvpair_value_string(elem, &strval);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   731
			if (nvlist_add_string(ret, propname, strval) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   732
				(void) no_memory(hdl);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   733
				goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   734
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   735
			continue;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   736
		}
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   737
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   738
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   739
		 * Normalize the name, to get rid of shorthand abbrevations.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   740
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   741
		propname = zfs_prop_to_name(prop);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   742
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   743
		if (!zfs_prop_valid_for_type(prop, type)) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   744
			zfs_error_aux(hdl,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   745
			    dgettext(TEXT_DOMAIN, "'%s' does not "
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   746
			    "apply to datasets of this type"), propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   747
			(void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   748
			goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   749
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   750
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   751
		if (zfs_prop_readonly(prop) &&
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   752
		    (prop != ZFS_PROP_VOLBLOCKSIZE || zhp != NULL)) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   753
			zfs_error_aux(hdl,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   754
			    dgettext(TEXT_DOMAIN, "'%s' is readonly"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   755
			    propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   756
			(void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   757
			goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   758
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   759
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   760
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   761
		 * Convert any properties to the internal DSL value types.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   762
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   763
		strval = NULL;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   764
		switch (zfs_prop_get_type(prop)) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   765
		case prop_type_boolean:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   766
			if (prop_parse_boolean(hdl, elem, &intval) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   767
				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   768
				goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   769
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   770
			break;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   771
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   772
		case prop_type_string:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   773
			if (nvpair_type(elem) != DATA_TYPE_STRING) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   774
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   775
				    "'%s' must be a string"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   776
				    propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   777
				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   778
				goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   779
			}
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   780
			(void) nvpair_value_string(elem, &strval);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   781
			if (strlen(strval) >= ZFS_MAXPROPLEN) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   782
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   783
				    "'%s' is too long"), propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   784
				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   785
				goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   786
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   787
			break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   788
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   789
		case prop_type_number:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   790
			if (prop_parse_number(hdl, elem, prop, &intval) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   791
				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   792
				goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   793
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   794
			break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   795
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   796
		case prop_type_index:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   797
			if (prop_parse_index(hdl, elem, prop, &intval) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   798
				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   799
				goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   803
		default:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   804
			abort();
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   805
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   806
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   807
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   808
		 * Add the result to our return set of properties.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   809
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   810
		if (strval) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   811
			if (nvlist_add_string(ret, propname, strval) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   812
				(void) no_memory(hdl);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   813
				goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
			}
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   815
		} else if (nvlist_add_uint64(ret, propname, intval) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   816
			(void) no_memory(hdl);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   817
			goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   818
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   819
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   820
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   821
		 * Perform some additional checks for specific properties.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   822
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   823
		switch (prop) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   824
		case ZFS_PROP_RECORDSIZE:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   825
		case ZFS_PROP_VOLBLOCKSIZE:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   826
			/* must be power of two within SPA_{MIN,MAX}BLOCKSIZE */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   827
			if (intval < SPA_MINBLOCKSIZE ||
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   828
			    intval > SPA_MAXBLOCKSIZE || !ISP2(intval)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   829
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   830
				    "'%s' must be power of 2 from %u "
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   831
				    "to %uk"), propname,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   832
				    (uint_t)SPA_MINBLOCKSIZE,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   833
				    (uint_t)SPA_MAXBLOCKSIZE >> 10);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   834
				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   835
				goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   839
		case ZFS_PROP_MOUNTPOINT:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   840
			if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 ||
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   841
			    strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   842
				break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   843
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   844
			if (strval[0] != '/') {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   845
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   846
				    "'%s' must be an absolute path, "
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   847
				    "'none', or 'legacy'"), propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   848
				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   849
				goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
			break;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   852
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   853
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   854
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   855
		 * For the mountpoint and sharenfs properties, check if it can
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   856
		 * be set in a global/non-global zone based on the zoned
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   857
		 * property value:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   858
		 *
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   859
		 *		global zone	    non-global zone
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   860
		 * -----------------------------------------------------
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   861
		 * zoned=on	mountpoint (no)	    mountpoint (yes)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   862
		 *		sharenfs (no)	    sharenfs (no)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   863
		 *
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   864
		 * zoned=off	mountpoint (yes)	N/A
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   865
		 *		sharenfs (yes)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   866
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   867
		if (prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   868
			if (zoned) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   869
				if (getzoneid() == GLOBAL_ZONEID) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   870
					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   871
					    "'%s' cannot be set on "
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   872
					    "dataset in a non-global zone"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   873
					    propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   874
					(void) zfs_error(hdl, EZFS_ZONED,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   875
					    errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   876
					goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   877
				} else if (prop == ZFS_PROP_SHARENFS) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   878
					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   879
					    "'%s' cannot be set in "
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   880
					    "a non-global zone"), propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   881
					(void) zfs_error(hdl, EZFS_ZONED,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   882
					    errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   883
					goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   884
				}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   885
			} else if (getzoneid() != GLOBAL_ZONEID) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   886
				/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   887
				 * If zoned property is 'off', this must be in
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   888
				 * a globle zone. If not, something is wrong.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   889
				 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   890
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   891
				    "'%s' cannot be set while dataset "
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   892
				    "'zoned' property is set"), propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   893
				(void) zfs_error(hdl, EZFS_ZONED, errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   894
				goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   895
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   896
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   897
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   898
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   899
		 * For changes to existing volumes, we have some additional
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   900
		 * checks to enforce.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   901
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   902
		if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   903
			uint64_t volsize = zfs_prop_get_int(zhp,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   904
			    ZFS_PROP_VOLSIZE);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   905
			uint64_t blocksize = zfs_prop_get_int(zhp,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   906
			    ZFS_PROP_VOLBLOCKSIZE);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   907
			char buf[64];
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   908
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   909
			switch (prop) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   910
			case ZFS_PROP_RESERVATION:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   911
				if (intval > volsize) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   912
					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   913
					    "'%s' is greater than current "
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   914
					    "volume size"), propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   915
					(void) zfs_error(hdl, EZFS_BADPROP,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   916
					    errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   917
					goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   918
				}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   919
				break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   920
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   921
			case ZFS_PROP_VOLSIZE:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   922
				if (intval % blocksize != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   923
					zfs_nicenum(blocksize, buf,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   924
					    sizeof (buf));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   925
					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   926
					    "'%s' must be a multiple of "
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   927
					    "volume block size (%s)"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   928
					    propname, buf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   929
					(void) zfs_error(hdl, EZFS_BADPROP,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   930
					    errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   931
					goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   932
				}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   933
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   934
				if (intval == 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   935
					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   936
					    "'%s' cannot be zero"),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   937
					    propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   938
					(void) zfs_error(hdl, EZFS_BADPROP,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   939
					    errbuf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   940
					goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   941
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   942
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   943
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   944
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   946
	/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   947
	 * If this is an existing volume, and someone is setting the volsize,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   948
	 * make sure that it matches the reservation, or add it if necessary.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   949
	 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   950
	if (zhp != NULL && type == ZFS_TYPE_VOLUME &&
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   951
	    nvlist_lookup_uint64(ret, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   952
	    &intval) == 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   953
		uint64_t old_volsize = zfs_prop_get_int(zhp,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   954
		    ZFS_PROP_VOLSIZE);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   955
		uint64_t old_reservation = zfs_prop_get_int(zhp,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   956
		    ZFS_PROP_RESERVATION);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   957
		uint64_t new_reservation;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   958
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   959
		if (old_volsize == old_reservation &&
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   960
		    nvlist_lookup_uint64(ret,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   961
		    zfs_prop_to_name(ZFS_PROP_RESERVATION),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   962
		    &new_reservation) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   963
			if (nvlist_add_uint64(ret,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   964
			    zfs_prop_to_name(ZFS_PROP_RESERVATION),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   965
			    intval) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   966
				(void) no_memory(hdl);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   967
				goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   968
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   969
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   970
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   971
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   972
	return (ret);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   973
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   974
error:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   975
	nvlist_free(ret);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   976
	return (NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   977
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   978
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   979
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   980
 * Given a property name and value, set the property for the given dataset.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   981
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   982
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   983
zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   984
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   985
	zfs_cmd_t zc = { 0 };
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   986
	int ret = -1;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   987
	prop_changelist_t *cl = NULL;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   988
	char errbuf[1024];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   989
	libzfs_handle_t *hdl = zhp->zfs_hdl;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   990
	nvlist_t *nvl = NULL, *realprops;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   991
	zfs_prop_t prop;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   992
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   993
	(void) snprintf(errbuf, sizeof (errbuf),
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   994
	    dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   995
	    zhp->zfs_name);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
   996
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   997
	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   998
	    nvlist_add_string(nvl, propname, propval) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
   999
		(void) no_memory(hdl);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1000
		goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1001
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1002
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1003
	if ((realprops = zfs_validate_properties(hdl, zhp->zfs_type, nvl,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1004
	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1005
		goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1006
	nvlist_free(nvl);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1007
	nvl = realprops;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1008
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1009
	prop = zfs_name_to_prop(propname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1010
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1011
	if ((cl = changelist_gather(zhp, prop, 0)) == NULL)
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1012
		goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1013
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1014
	if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1015
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1016
		    "child dataset with inherited mountpoint is used "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1017
		    "in a non-global zone"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1018
		ret = zfs_error(hdl, EZFS_ZONED, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
		goto error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1022
	if ((ret = changelist_prefix(cl)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1023
		goto error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1024
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1025
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1026
	 * Execute the corresponding ioctl() to set this property.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1027
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1028
	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1029
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1030
	if (zcmd_write_src_nvlist(hdl, &zc, nvl, NULL) != 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1031
		goto error;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1032
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1033
	ret = ioctl(hdl->libzfs_fd, ZFS_IOC_SET_PROP, &zc);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1034
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1035
	if (ret != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1036
		switch (errno) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1037
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1038
		case ENOSPC:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1039
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1040
			 * For quotas and reservations, ENOSPC indicates
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1041
			 * something different; setting a quota or reservation
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1042
			 * doesn't use any disk space.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1043
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1044
			switch (prop) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1045
			case ZFS_PROP_QUOTA:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1046
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1047
				    "size is less than current used or "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1048
				    "reserved space"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1049
				(void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1050
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1051
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1052
			case ZFS_PROP_RESERVATION:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1053
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1054
				    "size is greater than available space"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1055
				(void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1056
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1057
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1058
			default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1059
				(void) zfs_standard_error(hdl, errno, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1060
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1061
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1062
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1063
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1064
		case EBUSY:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1065
			if (prop == ZFS_PROP_VOLBLOCKSIZE)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1066
				(void) zfs_error(hdl, EZFS_VOLHASDATA, errbuf);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1067
			else
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1068
				(void) zfs_standard_error(hdl, EBUSY, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1069
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1070
1175
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1133
diff changeset
  1071
		case EROFS:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1072
			(void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
1175
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1133
diff changeset
  1073
			break;
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 1133
diff changeset
  1074
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1075
		case EOVERFLOW:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1076
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1077
			 * This platform can't address a volume this big.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1078
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1079
#ifdef _ILP32
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1080
			if (prop == ZFS_PROP_VOLSIZE) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1081
				(void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1082
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1083
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1084
#endif
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1085
			/* FALLTHROUGH */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1086
		default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1087
			(void) zfs_standard_error(hdl, errno, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1088
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1089
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1090
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1091
		 * Refresh the statistics so the new property value
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1092
		 * is reflected.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1093
		 */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1094
		if ((ret = changelist_postfix(cl)) == 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1095
			(void) get_stats(zhp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1096
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1097
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1098
error:
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1099
	nvlist_free(nvl);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1100
	zcmd_free_nvlists(&zc);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1101
	if (cl)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1102
		changelist_free(cl);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1103
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1104
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1105
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1106
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
 * Given a property, inherit the value from the parent dataset.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1108
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1109
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1110
zfs_prop_inherit(zfs_handle_t *zhp, const char *propname)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1112
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
	prop_changelist_t *cl;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1115
	libzfs_handle_t *hdl = zhp->zfs_hdl;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1116
	char errbuf[1024];
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1117
	zfs_prop_t prop;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1118
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1119
	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1120
	    "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1121
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1122
	if ((prop = zfs_name_to_prop(propname)) == ZFS_PROP_INVAL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1123
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1124
		 * For user properties, the amount of work we have to do is very
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1125
		 * small, so just do it here.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1126
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1127
		if (!zfs_prop_user(propname)) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1128
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1129
			    "invalid property"));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1130
			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1131
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1132
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1133
		(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1134
		(void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1135
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1136
		if (ioctl(zhp->zfs_hdl->libzfs_fd,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1137
		    ZFS_IOC_SET_PROP, &zc) != 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1138
			return (zfs_standard_error(hdl, errno, errbuf));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1139
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1140
		return (0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1141
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1142
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1144
	 * Verify that this property is inheritable.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1145
	 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1146
	if (zfs_prop_readonly(prop))
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1147
		return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1148
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1149
	if (!zfs_prop_inheritable(prop))
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1150
		return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1151
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1152
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1153
	 * Check to see if the value applies to this type
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1154
	 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1155
	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1156
		return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1157
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1158
	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1159
	(void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1160
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1161
	if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1162
	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1163
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1164
		    "dataset is used in a non-global zone"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1165
		return (zfs_error(hdl, EZFS_ZONED, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1166
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1167
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1168
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1169
	 * Determine datasets which will be affected by this change, if any.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1170
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1171
	if ((cl = changelist_gather(zhp, prop, 0)) == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1172
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1173
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1174
	if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1175
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1176
		    "child dataset with inherited mountpoint is used "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1177
		    "in a non-global zone"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1178
		ret = zfs_error(hdl, EZFS_ZONED, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1179
		goto error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1180
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1181
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1182
	if ((ret = changelist_prefix(cl)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1183
		goto error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1184
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1185
	if ((ret = ioctl(zhp->zfs_hdl->libzfs_fd,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1186
	    ZFS_IOC_SET_PROP, &zc)) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1187
		return (zfs_standard_error(hdl, errno, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1188
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1189
2169
0152c8ed1663 6385436 zfs set <property> returns an error, but still sets property value (fix build)
nd150628
parents: 2166
diff changeset
  1190
		if ((ret = changelist_postfix(cl)) != 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1191
			goto error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1192
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1193
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1194
		 * Refresh the statistics so the new property is reflected.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1195
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1196
		(void) get_stats(zhp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1197
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1198
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1199
error:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1200
	changelist_free(cl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1201
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1202
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1203
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1204
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1205
nicebool(int value, char *buf, size_t buflen)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1206
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1207
	if (value)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1208
		(void) strlcpy(buf, "on", buflen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1209
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1210
		(void) strlcpy(buf, "off", buflen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1211
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1212
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1213
/*
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1214
 * True DSL properties are stored in an nvlist.  The following two functions
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1215
 * extract them appropriately.
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1216
 */
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1217
static uint64_t
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1218
getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1219
{
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1220
	nvlist_t *nv;
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1221
	uint64_t value;
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1222
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1223
	if (nvlist_lookup_nvlist(zhp->zfs_props,
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1224
	    zfs_prop_to_name(prop), &nv) == 0) {
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1225
		verify(nvlist_lookup_uint64(nv, ZFS_PROP_VALUE, &value) == 0);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1226
		verify(nvlist_lookup_string(nv, ZFS_PROP_SOURCE, source) == 0);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1227
	} else {
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1228
		value = zfs_prop_default_numeric(prop);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1229
		*source = "";
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1230
	}
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1231
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1232
	return (value);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1233
}
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1234
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1235
static char *
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1236
getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1237
{
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1238
	nvlist_t *nv;
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1239
	char *value;
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1240
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1241
	if (nvlist_lookup_nvlist(zhp->zfs_props,
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1242
	    zfs_prop_to_name(prop), &nv) == 0) {
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1243
		verify(nvlist_lookup_string(nv, ZFS_PROP_VALUE, &value) == 0);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1244
		verify(nvlist_lookup_string(nv, ZFS_PROP_SOURCE, source) == 0);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1245
	} else {
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1246
		if ((value = (char *)zfs_prop_default_string(prop)) == NULL)
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1247
			value = "";
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1248
		*source = "";
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1249
	}
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1250
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1251
	return (value);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1252
}
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1253
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1254
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1255
 * Internal function for getting a numeric property.  Both zfs_prop_get() and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1256
 * zfs_prop_get_int() are built using this interface.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1257
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1258
 * Certain properties can be overridden using 'mount -o'.  In this case, scan
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1259
 * the contents of the /etc/mnttab entry, searching for the appropriate options.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1260
 * If they differ from the on-disk values, report the current values and mark
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1261
 * the source "temporary".
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1262
 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1263
static int
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1264
get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zfs_source_t *src,
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1265
    char **source, uint64_t *val)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1266
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1267
	struct mnttab mnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1268
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1269
	*source = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1270
2474
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1271
	/*
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1272
	 * Because looking up the mount options is potentially expensive
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1273
	 * (iterating over all of /etc/mnttab), we defer its calculation until
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1274
	 * we're looking up a property which requires its presence.
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1275
	 */
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1276
	if (!zhp->zfs_mntcheck &&
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1277
	    (prop == ZFS_PROP_ATIME ||
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1278
	    prop == ZFS_PROP_DEVICES ||
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1279
	    prop == ZFS_PROP_EXEC ||
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1280
	    prop == ZFS_PROP_READONLY ||
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1281
	    prop == ZFS_PROP_SETUID ||
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1282
	    prop == ZFS_PROP_MOUNTED)) {
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1283
		struct mnttab search = { 0 }, entry;
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1284
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1285
		search.mnt_special = (char *)zhp->zfs_name;
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1286
		search.mnt_fstype = MNTTYPE_ZFS;
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1287
		rewind(zhp->zfs_hdl->libzfs_mnttab);
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1288
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1289
		if (getmntany(zhp->zfs_hdl->libzfs_mnttab, &entry,
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1290
		    &search) == 0 && (zhp->zfs_mntopts =
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1291
		    zfs_strdup(zhp->zfs_hdl,
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1292
		    entry.mnt_mntopts)) == NULL)
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1293
			return (-1);
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1294
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1295
		zhp->zfs_mntcheck = B_TRUE;
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1296
	}
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  1297
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1298
	if (zhp->zfs_mntopts == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1299
		mnt.mnt_mntopts = "";
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1300
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1301
		mnt.mnt_mntopts = zhp->zfs_mntopts;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1302
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1303
	switch (prop) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1304
	case ZFS_PROP_ATIME:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1305
		*val = getprop_uint64(zhp, prop, source);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1306
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1307
		if (hasmntopt(&mnt, MNTOPT_ATIME) && !*val) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1308
			*val = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1309
			if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1310
				*src = ZFS_SRC_TEMPORARY;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1311
		} else if (hasmntopt(&mnt, MNTOPT_NOATIME) && *val) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1312
			*val = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1313
			if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1314
				*src = ZFS_SRC_TEMPORARY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1315
		}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1316
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1317
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1318
	case ZFS_PROP_AVAILABLE:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1319
		*val = zhp->zfs_dmustats.dds_available;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1320
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1321
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1322
	case ZFS_PROP_DEVICES:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1323
		*val = getprop_uint64(zhp, prop, source);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1324
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1325
		if (hasmntopt(&mnt, MNTOPT_DEVICES) && !*val) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1326
			*val = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1327
			if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1328
				*src = ZFS_SRC_TEMPORARY;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1329
		} else if (hasmntopt(&mnt, MNTOPT_NODEVICES) && *val) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1330
			*val = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1331
			if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1332
				*src = ZFS_SRC_TEMPORARY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1333
		}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1334
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1335
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1336
	case ZFS_PROP_EXEC:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1337
		*val = getprop_uint64(zhp, prop, source);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1338
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1339
		if (hasmntopt(&mnt, MNTOPT_EXEC) && !*val) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1340
			*val = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1341
			if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1342
				*src = ZFS_SRC_TEMPORARY;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1343
		} else if (hasmntopt(&mnt, MNTOPT_NOEXEC) && *val) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1344
			*val = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1345
			if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1346
				*src = ZFS_SRC_TEMPORARY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1347
		}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1348
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1349
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1350
	case ZFS_PROP_RECORDSIZE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1351
	case ZFS_PROP_COMPRESSION:
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1352
	case ZFS_PROP_ZONED:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1353
		*val = getprop_uint64(zhp, prop, source);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1354
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1355
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1356
	case ZFS_PROP_READONLY:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1357
		*val = getprop_uint64(zhp, prop, source);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1358
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1359
		if (hasmntopt(&mnt, MNTOPT_RO) && !*val) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1360
			*val = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1361
			if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1362
				*src = ZFS_SRC_TEMPORARY;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1363
		} else if (hasmntopt(&mnt, MNTOPT_RW) && *val) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1364
			*val = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1365
			if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1366
				*src = ZFS_SRC_TEMPORARY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1367
		}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1368
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1369
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  1370
	case ZFS_PROP_CREATION:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1371
		*val = zhp->zfs_dmustats.dds_creation_time;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1372
		break;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  1373
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1374
	case ZFS_PROP_QUOTA:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1375
		if (zhp->zfs_dmustats.dds_quota == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1376
			*source = "";	/* default */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1377
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1378
			*source = zhp->zfs_name;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1379
		*val = zhp->zfs_dmustats.dds_quota;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1380
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1381
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1382
	case ZFS_PROP_RESERVATION:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1383
		if (zhp->zfs_dmustats.dds_reserved == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1384
			*source = "";	/* default */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1385
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1386
			*source = zhp->zfs_name;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1387
		*val = zhp->zfs_dmustats.dds_reserved;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1388
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1389
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1390
	case ZFS_PROP_COMPRESSRATIO:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1391
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1392
		 * Using physical space and logical space, calculate the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1393
		 * compression ratio.  We return the number as a multiple of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1394
		 * 100, so '2.5x' would be returned as 250.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1395
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1396
		if (zhp->zfs_dmustats.dds_compressed_bytes == 0)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1397
			*val = 100ULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1398
		else
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1399
			*val =
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1400
			    (zhp->zfs_dmustats.dds_uncompressed_bytes * 100 /
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1401
			    zhp->zfs_dmustats.dds_compressed_bytes);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1402
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1403
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1404
	case ZFS_PROP_REFERENCED:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1405
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1406
		 * 'referenced' refers to the amount of physical space
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1407
		 * referenced (possibly shared) by this object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1408
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1409
		*val = zhp->zfs_dmustats.dds_space_refd;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1410
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1411
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1412
	case ZFS_PROP_SETUID:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1413
		*val = getprop_uint64(zhp, prop, source);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1414
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1415
		if (hasmntopt(&mnt, MNTOPT_SETUID) && !*val) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1416
			*val = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1417
			if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1418
				*src = ZFS_SRC_TEMPORARY;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1419
		} else if (hasmntopt(&mnt, MNTOPT_NOSETUID) && *val) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1420
			*val = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1421
			if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1422
				*src = ZFS_SRC_TEMPORARY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1423
		}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1424
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1425
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1426
	case ZFS_PROP_VOLSIZE:
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1427
		*val = zhp->zfs_volstats.zv_volsize;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1428
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1429
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1430
	case ZFS_PROP_VOLBLOCKSIZE:
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1431
		*val = zhp->zfs_volstats.zv_volblocksize;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1432
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1433
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1434
	case ZFS_PROP_USED:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1435
		*val = zhp->zfs_dmustats.dds_space_used;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1436
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1437
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1438
	case ZFS_PROP_CREATETXG:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1439
		*val = zhp->zfs_dmustats.dds_creation_txg;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1440
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1441
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1442
	case ZFS_PROP_MOUNTED:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1443
		*val = (zhp->zfs_mntopts != NULL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1444
		break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1445
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1446
	case ZFS_PROP_CANMOUNT:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1447
		*val = getprop_uint64(zhp, prop, source);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1448
		break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1449
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1450
	default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1451
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1452
		    "cannot get non-numeric property"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1453
		return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1454
		    dgettext(TEXT_DOMAIN, "internal error")));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1455
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1456
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1457
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1458
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1459
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1460
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1461
 * Calculate the source type, given the raw source string.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1462
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1463
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1464
get_source(zfs_handle_t *zhp, zfs_source_t *srctype, char *source,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1465
    char *statbuf, size_t statlen)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1466
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1467
	if (statbuf == NULL || *srctype == ZFS_SRC_TEMPORARY)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1468
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1469
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1470
	if (source == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1471
		*srctype = ZFS_SRC_NONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1472
	} else if (source[0] == '\0') {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1473
		*srctype = ZFS_SRC_DEFAULT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1474
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1475
		if (strcmp(source, zhp->zfs_name) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1476
			*srctype = ZFS_SRC_LOCAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1477
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1478
			(void) strlcpy(statbuf, source, statlen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1479
			*srctype = ZFS_SRC_INHERITED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1480
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1481
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1482
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1483
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1484
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1485
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1486
 * Retrieve a property from the given object.  If 'literal' is specified, then
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1487
 * numbers are left as exact values.  Otherwise, numbers are converted to a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1488
 * human-readable form.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1489
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1490
 * Returns 0 on success, or -1 on error.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1491
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1492
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1493
zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1494
    zfs_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1495
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1496
	char *source = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1497
	uint64_t val;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1498
	char *str;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1499
	const char *root;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1500
	const char *strval;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1501
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1502
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1503
	 * Check to see if this property applies to our object
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1504
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1505
	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1506
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1507
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1508
	if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1509
		*src = ZFS_SRC_NONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1510
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1511
	switch (prop) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1512
	case ZFS_PROP_ATIME:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1513
	case ZFS_PROP_READONLY:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1514
	case ZFS_PROP_SETUID:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1515
	case ZFS_PROP_ZONED:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1516
	case ZFS_PROP_DEVICES:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1517
	case ZFS_PROP_EXEC:
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1518
	case ZFS_PROP_CANMOUNT:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1519
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1520
		 * Basic boolean values are built on top of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1521
		 * get_numeric_property().
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1522
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1523
		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1524
			return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1525
		nicebool(val, propbuf, proplen);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1526
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1527
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1528
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1529
	case ZFS_PROP_AVAILABLE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1530
	case ZFS_PROP_RECORDSIZE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1531
	case ZFS_PROP_CREATETXG:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1532
	case ZFS_PROP_REFERENCED:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1533
	case ZFS_PROP_USED:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1534
	case ZFS_PROP_VOLSIZE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1535
	case ZFS_PROP_VOLBLOCKSIZE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1536
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1537
		 * Basic numeric values are built on top of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1538
		 * get_numeric_property().
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1539
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1540
		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1541
			return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1542
		if (literal)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1543
			(void) snprintf(propbuf, proplen, "%llu", val);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1544
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1545
			zfs_nicenum(val, propbuf, proplen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1546
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1547
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1548
	case ZFS_PROP_COMPRESSION:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1549
	case ZFS_PROP_CHECKSUM:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1550
	case ZFS_PROP_SNAPDIR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1551
	case ZFS_PROP_ACLMODE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1552
	case ZFS_PROP_ACLINHERIT:
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1553
		val = getprop_uint64(zhp, prop, &source);
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1554
		verify(zfs_prop_index_to_string(prop, val, &strval) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1555
		(void) strlcpy(propbuf, strval, proplen);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1556
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1557
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1558
	case ZFS_PROP_CREATION:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1559
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1560
		 * 'creation' is a time_t stored in the statistics.  We convert
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1561
		 * this into a string unless 'literal' is specified.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1562
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1563
		{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1564
			time_t time = (time_t)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1565
			    zhp->zfs_dmustats.dds_creation_time;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1566
			struct tm t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1567
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1568
			if (literal ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1569
			    localtime_r(&time, &t) == NULL ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1570
			    strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1571
			    &t) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1572
				(void) snprintf(propbuf, proplen, "%llu",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1573
				    zhp->zfs_dmustats.dds_creation_time);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1574
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1575
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1576
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1577
	case ZFS_PROP_MOUNTPOINT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1578
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1579
		 * Getting the precise mountpoint can be tricky.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1580
		 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1581
		 *  - for 'none' or 'legacy', return those values.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1582
		 *  - for default mountpoints, construct it as /zfs/<dataset>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1583
		 *  - for inherited mountpoints, we want to take everything
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1584
		 *    after our ancestor and append it to the inherited value.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1585
		 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1586
		 * If the pool has an alternate root, we want to prepend that
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1587
		 * root to any values we return.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1588
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  1589
		root = zhp->zfs_root;
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1590
		str = getprop_string(zhp, prop, &source);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1591
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1592
		if (str[0] == '\0') {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1593
			(void) snprintf(propbuf, proplen, "%s/zfs/%s",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1594
			    root, zhp->zfs_name);
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1595
		} else if (str[0] == '/') {
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1596
			const char *relpath = zhp->zfs_name + strlen(source);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1597
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1598
			if (relpath[0] == '/')
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1599
				relpath++;
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1600
			if (str[1] == '\0')
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1601
				str++;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1602
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1603
			if (relpath[0] == '\0')
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1604
				(void) snprintf(propbuf, proplen, "%s%s",
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1605
				    root, str);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1606
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1607
				(void) snprintf(propbuf, proplen, "%s%s%s%s",
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1608
				    root, str, relpath[0] == '@' ? "" : "/",
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1609
				    relpath);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1610
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1611
			/* 'legacy' or 'none' */
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1612
			(void) strlcpy(propbuf, str, proplen);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1613
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1614
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1615
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1616
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1617
	case ZFS_PROP_SHARENFS:
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1618
		(void) strlcpy(propbuf, getprop_string(zhp, prop, &source),
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1619
		    proplen);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1620
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1621
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1622
	case ZFS_PROP_ORIGIN:
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  1623
		(void) strlcpy(propbuf, zhp->zfs_dmustats.dds_clone_of,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1624
		    proplen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1625
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1626
		 * If there is no parent at all, return failure to indicate that
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1627
		 * it doesn't apply to this dataset.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1628
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1629
		if (propbuf[0] == '\0')
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1630
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1631
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1632
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1633
	case ZFS_PROP_QUOTA:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1634
	case ZFS_PROP_RESERVATION:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1635
		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1636
			return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1637
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1638
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1639
		 * If quota or reservation is 0, we translate this into 'none'
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1640
		 * (unless literal is set), and indicate that it's the default
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1641
		 * value.  Otherwise, we print the number nicely and indicate
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1642
		 * that its set locally.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1643
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1644
		if (val == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1645
			if (literal)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1646
				(void) strlcpy(propbuf, "0", proplen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1647
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1648
				(void) strlcpy(propbuf, "none", proplen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1649
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1650
			if (literal)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1651
				(void) snprintf(propbuf, proplen, "%llu", val);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1652
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1653
				zfs_nicenum(val, propbuf, proplen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1654
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1655
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1656
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1657
	case ZFS_PROP_COMPRESSRATIO:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1658
		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1659
			return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1660
		(void) snprintf(propbuf, proplen, "%lld.%02lldx", val / 100,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1661
		    val % 100);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1662
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1663
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1664
	case ZFS_PROP_TYPE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1665
		switch (zhp->zfs_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1666
		case ZFS_TYPE_FILESYSTEM:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1667
			str = "filesystem";
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1668
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1669
		case ZFS_TYPE_VOLUME:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1670
			str = "volume";
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1671
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1672
		case ZFS_TYPE_SNAPSHOT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1673
			str = "snapshot";
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1674
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1675
		default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1676
			abort();
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1677
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1678
		(void) snprintf(propbuf, proplen, "%s", str);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1679
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1680
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1681
	case ZFS_PROP_MOUNTED:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1682
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1683
		 * The 'mounted' property is a pseudo-property that described
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1684
		 * whether the filesystem is currently mounted.  Even though
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1685
		 * it's a boolean value, the typical values of "on" and "off"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1686
		 * don't make sense, so we translate to "yes" and "no".
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1687
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1688
		if (get_numeric_property(zhp, ZFS_PROP_MOUNTED,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1689
		    src, &source, &val) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1690
			return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1691
		if (val)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1692
			(void) strlcpy(propbuf, "yes", proplen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1693
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1694
			(void) strlcpy(propbuf, "no", proplen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1695
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1696
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1697
	case ZFS_PROP_NAME:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1698
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1699
		 * The 'name' property is a pseudo-property derived from the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1700
		 * dataset name.  It is presented as a real property to simplify
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1701
		 * consumers.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1702
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1703
		(void) strlcpy(propbuf, zhp->zfs_name, proplen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1704
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1705
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1706
	default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1707
		abort();
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1708
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1709
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1710
	get_source(zhp, src, source, statbuf, statlen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1711
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1712
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1713
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1714
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1715
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1716
 * Utility function to get the given numeric property.  Does no validation that
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1717
 * the given property is the appropriate type; should only be used with
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1718
 * hard-coded property types.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1719
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1720
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1721
zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1722
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1723
	char *source;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1724
	zfs_source_t sourcetype = ZFS_SRC_NONE;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1725
	uint64_t val;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1726
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1727
	(void) get_numeric_property(zhp, prop, &sourcetype, &source, &val);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1728
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1729
	return (val);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1730
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1731
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1732
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1733
 * Similar to zfs_prop_get(), but returns the value as an integer.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1734
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1735
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1736
zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1737
    zfs_source_t *src, char *statbuf, size_t statlen)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1738
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1739
	char *source;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1740
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1741
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1742
	 * Check to see if this property applies to our object
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1743
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1744
	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1745
		return (zfs_error(zhp->zfs_hdl, EZFS_PROPTYPE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1746
		    dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1747
		    zfs_prop_to_name(prop)));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1748
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1749
	if (src)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1750
		*src = ZFS_SRC_NONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1751
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1752
	if (get_numeric_property(zhp, prop, src, &source, value) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1753
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1754
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1755
	get_source(zhp, src, source, statbuf, statlen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1756
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1757
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1758
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1759
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1760
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1761
 * Returns the name of the given zfs handle.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1762
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1763
const char *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1764
zfs_get_name(const zfs_handle_t *zhp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1765
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1766
	return (zhp->zfs_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1767
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1768
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1769
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1770
 * Returns the type of the given zfs handle.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1771
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1772
zfs_type_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1773
zfs_get_type(const zfs_handle_t *zhp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1774
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1775
	return (zhp->zfs_type);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1776
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1777
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1778
/*
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1779
 * Iterate over all child filesystems
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1780
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1781
int
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1782
zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1783
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1784
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1785
	zfs_handle_t *nzhp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1786
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1787
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1788
	for ((void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1789
	    ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DATASET_LIST_NEXT, &zc) == 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1790
	    (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1791
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1792
		 * Ignore private dataset names.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1793
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1794
		if (dataset_name_hidden(zc.zc_name))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1795
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1796
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1797
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1798
		 * Silently ignore errors, as the only plausible explanation is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1799
		 * that the pool has since been removed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1800
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1801
		if ((nzhp = make_dataset_handle(zhp->zfs_hdl,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1802
		    zc.zc_name)) == NULL)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1803
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1804
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1805
		if ((ret = func(nzhp, data)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1806
			return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1807
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1808
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1809
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1810
	 * An errno value of ESRCH indicates normal completion.  If ENOENT is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1811
	 * returned, then the underlying dataset has been removed since we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1812
	 * obtained the handle.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1813
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1814
	if (errno != ESRCH && errno != ENOENT)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1815
		return (zfs_standard_error(zhp->zfs_hdl, errno,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1816
		    dgettext(TEXT_DOMAIN, "cannot iterate filesystems")));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1817
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1818
	return (0);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1819
}
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1820
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1821
/*
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1822
 * Iterate over all snapshots
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1823
 */
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1824
int
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1825
zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data)
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1826
{
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1827
	zfs_cmd_t zc = { 0 };
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1828
	zfs_handle_t *nzhp;
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1829
	int ret;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1830
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1831
	for ((void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1832
	    ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1833
	    &zc) == 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1834
	    (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1835
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1836
		if ((nzhp = make_dataset_handle(zhp->zfs_hdl,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1837
		    zc.zc_name)) == NULL)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1838
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1839
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1840
		if ((ret = func(nzhp, data)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1841
			return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1842
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1843
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1844
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1845
	 * An errno value of ESRCH indicates normal completion.  If ENOENT is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1846
	 * returned, then the underlying dataset has been removed since we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1847
	 * obtained the handle.  Silently ignore this case, and return success.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1848
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1849
	if (errno != ESRCH && errno != ENOENT)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1850
		return (zfs_standard_error(zhp->zfs_hdl, errno,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1851
		    dgettext(TEXT_DOMAIN, "cannot iterate filesystems")));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1852
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1853
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1854
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1855
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1856
/*
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1857
 * Iterate over all children, snapshots and filesystems
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1858
 */
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1859
int
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1860
zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1861
{
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1862
	int ret;
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1863
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1864
	if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1865
		return (ret);
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1866
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1867
	return (zfs_iter_snapshots(zhp, func, data));
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1868
}
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1869
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1870
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1871
 * Given a complete name, return just the portion that refers to the parent.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1872
 * Can return NULL if this is a pool.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1873
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1874
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1875
parent_name(const char *path, char *buf, size_t buflen)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1876
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1877
	char *loc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1878
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1879
	if ((loc = strrchr(path, '/')) == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1880
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1881
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1882
	(void) strncpy(buf, path, MIN(buflen, loc - path));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1883
	buf[loc - path] = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1884
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1885
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1886
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1887
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1888
/*
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1889
 * Checks to make sure that the given path has a parent, and that it exists.  We
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1890
 * also fetch the 'zoned' property, which is used to validate property settings
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1891
 * when creating new datasets.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1892
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1893
static int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1894
check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1895
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1896
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1897
	char parent[ZFS_MAXNAMELEN];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1898
	char *slash;
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1899
	zfs_handle_t *zhp;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1900
	char errbuf[1024];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1901
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1902
	(void) snprintf(errbuf, sizeof (errbuf), "cannot create '%s'",
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1903
	    path);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1904
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1905
	/* get parent, and check to see if this is just a pool */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1906
	if (parent_name(path, parent, sizeof (parent)) != 0) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1907
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1908
		    "missing dataset name"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1909
		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1910
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1911
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1912
	/* check to see if the pool exists */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1913
	if ((slash = strchr(parent, '/')) == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1914
		slash = parent + strlen(parent);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1915
	(void) strncpy(zc.zc_name, parent, slash - parent);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1916
	zc.zc_name[slash - parent] = '\0';
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1917
	if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1918
	    errno == ENOENT) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1919
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1920
		    "no such pool '%s'"), zc.zc_name);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1921
		return (zfs_error(hdl, EZFS_NOENT, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1922
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1923
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1924
	/* check to see if the parent dataset exists */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1925
	if ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1926
		switch (errno) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1927
		case ENOENT:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1928
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1929
			    "parent does not exist"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1930
			return (zfs_error(hdl, EZFS_NOENT, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1931
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1932
		default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1933
			return (zfs_standard_error(hdl, errno, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1934
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1935
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1936
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1937
	*zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1938
	/* we are in a non-global zone, but parent is in the global zone */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1939
	if (getzoneid() != GLOBAL_ZONEID && !(*zoned)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1940
		(void) zfs_standard_error(hdl, EPERM, errbuf);
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1941
		zfs_close(zhp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1942
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1943
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1944
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1945
	/* make sure parent is a filesystem */
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1946
	if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1947
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1948
		    "parent is not a filesystem"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1949
		(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1950
		zfs_close(zhp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1951
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1952
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1953
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 1294
diff changeset
  1954
	zfs_close(zhp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1955
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1956
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1957
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1958
/*
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1959
 * Create a new filesystem or volume.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1960
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1961
int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1962
zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1963
    nvlist_t *props)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1964
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1965
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1966
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1967
	uint64_t size = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1968
	uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1969
	char errbuf[1024];
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1970
	uint64_t zoned;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1971
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1972
	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1973
	    "cannot create '%s'"), path);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1974
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1975
	/* validate the path, taking care to note the extended error message */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1976
	if (!zfs_validate_name(hdl, path, type))
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1977
		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1978
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1979
	/* validate parents exist */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  1980
	if (check_parents(hdl, path, &zoned) != 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1981
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1982
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1983
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1984
	 * The failure modes when creating a dataset of a different type over
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1985
	 * one that already exists is a little strange.  In particular, if you
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1986
	 * try to create a dataset on top of an existing dataset, the ioctl()
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1987
	 * will return ENOENT, not EEXIST.  To prevent this from happening, we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1988
	 * first try to see if the dataset exists.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1989
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1990
	(void) strlcpy(zc.zc_name, path, sizeof (zc.zc_name));
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1991
	if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1992
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1993
		    "dataset already exists"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  1994
		return (zfs_error(hdl, EZFS_EXISTS, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1995
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1996
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1997
	if (type == ZFS_TYPE_VOLUME)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1998
		zc.zc_objset_type = DMU_OST_ZVOL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1999
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2000
		zc.zc_objset_type = DMU_OST_ZFS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2001
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2002
	if (props && (props = zfs_validate_properties(hdl, type, props, zoned,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2003
	    NULL, errbuf)) == 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2004
		return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2005
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2006
	if (type == ZFS_TYPE_VOLUME) {
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2007
		/*
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2008
		 * If we are creating a volume, the size and block size must
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2009
		 * satisfy a few restraints.  First, the blocksize must be a
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2010
		 * valid block size between SPA_{MIN,MAX}BLOCKSIZE.  Second, the
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2011
		 * volsize must be a multiple of the block size, and cannot be
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2012
		 * zero.
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2013
		 */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2014
		if (props == NULL || nvlist_lookup_uint64(props,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2015
		    zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2016
			nvlist_free(props);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2017
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2018
			    "missing volume size"));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2019
			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2020
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2021
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2022
		if ((ret = nvlist_lookup_uint64(props,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2023
		    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2024
		    &blocksize)) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2025
			if (ret == ENOENT) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2026
				blocksize = zfs_prop_default_numeric(
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2027
				    ZFS_PROP_VOLBLOCKSIZE);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2028
			} else {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2029
				nvlist_free(props);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2030
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2031
				    "missing volume block size"));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2032
				return (zfs_error(hdl, EZFS_BADPROP, errbuf));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2033
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2034
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2035
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2036
		if (size == 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2037
			nvlist_free(props);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2038
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2039
			    "volume size cannot be zero"));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2040
			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2041
		}
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2042
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2043
		if (size % blocksize != 0) {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2044
			nvlist_free(props);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2045
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2046
			    "volume size must be a multiple of volume block "
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2047
			    "size"));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2048
			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
  2049
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2050
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2051
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2052
	if (props &&
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2053
	    zcmd_write_src_nvlist(hdl, &zc, props, NULL) != 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2054
		return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2055
	nvlist_free(props);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2056
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2057
	/* create the dataset */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2058
	ret = ioctl(hdl->libzfs_fd, ZFS_IOC_CREATE, &zc);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2059
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2060
	if (ret == 0 && type == ZFS_TYPE_VOLUME)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2061
		ret = zvol_create_link(hdl, path);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2062
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2063
	zcmd_free_nvlists(&zc);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2064
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2065
	/* check for failure */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2066
	if (ret != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2067
		char parent[ZFS_MAXNAMELEN];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2068
		(void) parent_name(path, parent, sizeof (parent));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2069
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2070
		switch (errno) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2071
		case ENOENT:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2072
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2073
			    "no such parent '%s'"), parent);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2074
			return (zfs_error(hdl, EZFS_NOENT, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2075
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2076
		case EINVAL:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2077
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2078
			    "parent '%s' is not a filesysem"), parent);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2079
			return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2080
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2081
		case EDOM:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2082
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2083
			    "volume block size must be power of 2 from "
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2084
			    "%u to %uk"),
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2085
			    (uint_t)SPA_MINBLOCKSIZE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2086
			    (uint_t)SPA_MAXBLOCKSIZE >> 10);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2087
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2088
			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2089
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2090
#ifdef _ILP32
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2091
		case EOVERFLOW:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2092
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2093
			 * This platform can't address a volume this big.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2094
			 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2095
			if (type == ZFS_TYPE_VOLUME)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2096
				return (zfs_error(hdl, EZFS_VOLTOOBIG,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2097
				    errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2098
#endif
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2099
			/* FALLTHROUGH */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2100
		default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2101
			return (zfs_standard_error(hdl, errno, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2102
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2103
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2104
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2105
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2106
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2107
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2108
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2109
 * Destroys the given dataset.  The caller must make sure that the filesystem
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2110
 * isn't mounted, and that there are no active dependents.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2111
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2112
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2113
zfs_destroy(zfs_handle_t *zhp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2114
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2115
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2116
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2117
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2118
	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2119
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2120
	if (ZFS_IS_VOLUME(zhp)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2121
		if (zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2122
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2123
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2124
		zc.zc_objset_type = DMU_OST_ZVOL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2125
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2126
		zc.zc_objset_type = DMU_OST_ZFS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2127
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2128
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2129
	ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc);
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2130
	if (ret != 0) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2131
		return (zfs_standard_error(zhp->zfs_hdl, errno,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2132
		    dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2133
		    zhp->zfs_name));
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2134
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2135
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2136
	remove_mountpoint(zhp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2137
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2138
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2139
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2140
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2141
struct destroydata {
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2142
	char *snapname;
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2143
	boolean_t gotone;
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2144
};
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2145
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2146
static int
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2147
zfs_remove_link_cb(zfs_handle_t *zhp, void *arg)
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2148
{
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2149
	struct destroydata *dd = arg;
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2150
	zfs_handle_t *szhp;
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2151
	char name[ZFS_MAXNAMELEN];
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2152
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2153
	(void) strlcpy(name, zhp->zfs_name, sizeof (name));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2154
	(void) strlcat(name, "@", sizeof (name));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2155
	(void) strlcat(name, dd->snapname, sizeof (name));
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2156
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2157
	szhp = make_dataset_handle(zhp->zfs_hdl, name);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2158
	if (szhp) {
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2159
		dd->gotone = B_TRUE;
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2160
		zfs_close(szhp);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2161
	}
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2162
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2163
	if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2164
		(void) zvol_remove_link(zhp->zfs_hdl, name);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2165
		/*
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2166
		 * NB: this is simply a best-effort.  We don't want to
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2167
		 * return an error, because then we wouldn't visit all
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2168
		 * the volumes.
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2169
		 */
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2170
	}
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2171
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2172
	return (zfs_iter_filesystems(zhp, zfs_remove_link_cb, arg));
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2173
}
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2174
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2175
/*
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2176
 * Destroys all snapshots with the given name in zhp & descendants.
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2177
 */
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2178
int
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2179
zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname)
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2180
{
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2181
	zfs_cmd_t zc = { 0 };
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2182
	int ret;
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2183
	struct destroydata dd = { 0 };
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2184
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2185
	dd.snapname = snapname;
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2186
	(void) zfs_remove_link_cb(zhp, &dd);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2187
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2188
	if (!dd.gotone) {
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2189
		return (zfs_standard_error(zhp->zfs_hdl, ENOENT,
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2190
		    dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2191
		    zhp->zfs_name, snapname));
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2192
	}
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2193
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2194
	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2195
	(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2196
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2197
	ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DESTROY_SNAPS, &zc);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2198
	if (ret != 0) {
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2199
		char errbuf[1024];
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2200
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2201
		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2202
		    "cannot destroy '%s@%s'"), zc.zc_name, snapname);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2203
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2204
		switch (errno) {
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2205
		case EEXIST:
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2206
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2207
			    "snapshot is cloned"));
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2208
			return (zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf));
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2209
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2210
		default:
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2211
			return (zfs_standard_error(zhp->zfs_hdl, errno,
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2212
			    errbuf));
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2213
		}
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2214
	}
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2215
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2216
	return (0);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2217
}
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2218
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2219
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2220
 * Clones the given dataset.  The target must be of the same type as the source.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2221
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2222
int
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2223
zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2224
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2225
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2226
	char parent[ZFS_MAXNAMELEN];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2227
	int ret;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2228
	char errbuf[1024];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2229
	libzfs_handle_t *hdl = zhp->zfs_hdl;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2230
	zfs_type_t type;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2231
	uint64_t zoned;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2232
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2233
	assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2234
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2235
	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2236
	    "cannot create '%s'"), target);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2237
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2238
	/* validate the target name */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2239
	if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM))
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2240
		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2241
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2242
	/* validate parents exist */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2243
	if (check_parents(hdl, target, &zoned) != 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2244
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2245
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2246
	(void) parent_name(target, parent, sizeof (parent));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2247
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2248
	/* do the clone */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2249
	if (ZFS_IS_VOLUME(zhp)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2250
		zc.zc_objset_type = DMU_OST_ZVOL;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2251
		type = ZFS_TYPE_FILESYSTEM;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2252
	} else {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2253
		zc.zc_objset_type = DMU_OST_ZFS;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2254
		type = ZFS_TYPE_VOLUME;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2255
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2256
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2257
	if (props) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2258
		if ((props = zfs_validate_properties(hdl, type, props, zoned,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2259
		    zhp, errbuf)) == NULL)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2260
			return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2261
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2262
		if (zcmd_write_src_nvlist(hdl, &zc, props, NULL) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2263
			nvlist_free(props);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2264
			return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2265
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2266
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2267
		nvlist_free(props);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2268
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2269
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2270
	(void) strlcpy(zc.zc_name, target, sizeof (zc.zc_name));
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2271
	(void) strlcpy(zc.zc_value, zhp->zfs_name, sizeof (zc.zc_value));
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2272
	ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_CREATE, &zc);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2273
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2274
	zcmd_free_nvlists(&zc);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2275
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2276
	if (ret != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2277
		switch (errno) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2278
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2279
		case ENOENT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2280
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2281
			 * The parent doesn't exist.  We should have caught this
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2282
			 * above, but there may a race condition that has since
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2283
			 * destroyed the parent.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2284
			 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2285
			 * At this point, we don't know whether it's the source
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2286
			 * that doesn't exist anymore, or whether the target
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2287
			 * dataset doesn't exist.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2288
			 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2289
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2290
			    "no such parent '%s'"), parent);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2291
			return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2292
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2293
		case EXDEV:
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2294
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2295
			    "source and target pools differ"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2296
			return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2297
			    errbuf));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2298
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2299
		default:
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2300
			return (zfs_standard_error(zhp->zfs_hdl, errno,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2301
			    errbuf));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2302
		}
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2303
	} else if (ZFS_IS_VOLUME(zhp)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2304
		ret = zvol_create_link(zhp->zfs_hdl, target);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2305
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2306
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2307
	return (ret);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2308
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2309
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2310
typedef struct promote_data {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2311
	char cb_mountpoint[MAXPATHLEN];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2312
	const char *cb_target;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2313
	const char *cb_errbuf;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2314
	uint64_t cb_pivot_txg;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2315
} promote_data_t;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2316
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2317
static int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2318
promote_snap_cb(zfs_handle_t *zhp, void *data)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2319
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2320
	promote_data_t *pd = data;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2321
	zfs_handle_t *szhp;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2322
	char snapname[MAXPATHLEN];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2323
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2324
	/* We don't care about snapshots after the pivot point */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2325
	if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > pd->cb_pivot_txg)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2326
		return (0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2327
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2328
	/* Remove the device link if it's a zvol. */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2329
	if (ZFS_IS_VOLUME(zhp))
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2330
		(void) zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2331
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2332
	/* Check for conflicting names */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2333
	(void) strlcpy(snapname, pd->cb_target, sizeof (snapname));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2334
	(void) strlcat(snapname, strchr(zhp->zfs_name, '@'), sizeof (snapname));
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2335
	szhp = make_dataset_handle(zhp->zfs_hdl, snapname);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2336
	if (szhp != NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2337
		zfs_close(szhp);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2338
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2339
		    "snapshot name '%s' from origin \n"
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2340
		    "conflicts with '%s' from target"),
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2341
		    zhp->zfs_name, snapname);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2342
		return (zfs_error(zhp->zfs_hdl, EZFS_EXISTS, pd->cb_errbuf));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2343
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2344
	return (0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2345
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2346
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2347
static int
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2348
promote_snap_done_cb(zfs_handle_t *zhp, void *data)
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2349
{
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2350
	promote_data_t *pd = data;
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2351
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2352
	/* We don't care about snapshots after the pivot point */
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2353
	if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > pd->cb_pivot_txg)
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2354
		return (0);
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2355
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2356
	/* Create the device link if it's a zvol. */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2357
	if (ZFS_IS_VOLUME(zhp))
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2358
		(void) zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2359
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2360
	return (0);
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2361
}
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2362
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2363
/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2364
 * Promotes the given clone fs to be the clone parent.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2365
 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2366
int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2367
zfs_promote(zfs_handle_t *zhp)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2368
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2369
	libzfs_handle_t *hdl = zhp->zfs_hdl;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2370
	zfs_cmd_t zc = { 0 };
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2371
	char parent[MAXPATHLEN];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2372
	char *cp;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2373
	int ret;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2374
	zfs_handle_t *pzhp;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2375
	promote_data_t pd;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2376
	char errbuf[1024];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2377
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2378
	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2379
	    "cannot promote '%s'"), zhp->zfs_name);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2380
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2381
	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2382
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2383
		    "snapshots can not be promoted"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2384
		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2385
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2386
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2387
	(void) strlcpy(parent, zhp->zfs_dmustats.dds_clone_of, sizeof (parent));
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2388
	if (parent[0] == '\0') {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2389
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2390
		    "not a cloned filesystem"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2391
		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2392
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2393
	cp = strchr(parent, '@');
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2394
	*cp = '\0';
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2395
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2396
	/* Walk the snapshots we will be moving */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2397
	pzhp = zfs_open(hdl, zhp->zfs_dmustats.dds_clone_of, ZFS_TYPE_SNAPSHOT);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2398
	if (pzhp == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2399
		return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2400
	pd.cb_pivot_txg = zfs_prop_get_int(pzhp, ZFS_PROP_CREATETXG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2401
	zfs_close(pzhp);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2402
	pd.cb_target = zhp->zfs_name;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2403
	pd.cb_errbuf = errbuf;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2404
	pzhp = zfs_open(hdl, parent, ZFS_TYPE_ANY);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2405
	if (pzhp == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2406
		return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2407
	(void) zfs_prop_get(pzhp, ZFS_PROP_MOUNTPOINT, pd.cb_mountpoint,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2408
	    sizeof (pd.cb_mountpoint), NULL, NULL, 0, FALSE);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2409
	ret = zfs_iter_snapshots(pzhp, promote_snap_cb, &pd);
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2410
	if (ret != 0) {
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2411
		zfs_close(pzhp);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2412
		return (-1);
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2413
	}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2414
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2415
	/* issue the ioctl */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2416
	(void) strlcpy(zc.zc_value, zhp->zfs_dmustats.dds_clone_of,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2417
	    sizeof (zc.zc_value));
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2418
	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2419
	ret = ioctl(hdl->libzfs_fd, ZFS_IOC_PROMOTE, &zc);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2420
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2421
	if (ret != 0) {
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2422
		int save_errno = errno;
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2423
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2424
		(void) zfs_iter_snapshots(pzhp, promote_snap_done_cb, &pd);
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2425
		zfs_close(pzhp);
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2426
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2427
		switch (save_errno) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2428
		case EEXIST:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2429
			/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2430
			 * There is a conflicting snapshot name.  We
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2431
			 * should have caught this above, but they could
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2432
			 * have renamed something in the mean time.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2433
			 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2434
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2435
			    "conflicting snapshot name from parent '%s'"),
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2436
			    parent);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2437
			return (zfs_error(hdl, EZFS_EXISTS, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2438
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2439
		default:
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2440
			return (zfs_standard_error(hdl, save_errno, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2441
		}
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2442
	} else {
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2443
		(void) zfs_iter_snapshots(zhp, promote_snap_done_cb, &pd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2444
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2445
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2199
diff changeset
  2446
	zfs_close(pzhp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2447
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2448
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2449
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2450
static int
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2451
zfs_create_link_cb(zfs_handle_t *zhp, void *arg)
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2452
{
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2453
	char *snapname = arg;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2454
	int ret;
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2455
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2456
	if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2457
		char name[MAXPATHLEN];
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2458
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2459
		(void) strlcpy(name, zhp->zfs_name, sizeof (name));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2460
		(void) strlcat(name, "@", sizeof (name));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2461
		(void) strlcat(name, snapname, sizeof (name));
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2462
		(void) zvol_create_link(zhp->zfs_hdl, name);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2463
		/*
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2464
		 * NB: this is simply a best-effort.  We don't want to
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2465
		 * return an error, because then we wouldn't visit all
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2466
		 * the volumes.
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2467
		 */
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2468
	}
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2469
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2470
	ret = zfs_iter_filesystems(zhp, zfs_create_link_cb, snapname);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2471
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2472
	zfs_close(zhp);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2473
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2474
	return (ret);
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2475
}
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2476
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2477
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2478
 * Takes a snapshot of the given dataset
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2479
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2480
int
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2481
zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2482
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2483
	const char *delim;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2484
	char *parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2485
	zfs_handle_t *zhp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2486
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2487
	int ret;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2488
	char errbuf[1024];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2489
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2490
	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2491
	    "cannot snapshot '%s'"), path);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2492
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2493
	/* validate the target name */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2494
	if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT))
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2495
		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2496
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2497
	/* make sure the parent exists and is of the appropriate type */
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2498
	delim = strchr(path, '@');
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2499
	if ((parent = zfs_alloc(hdl, delim - path + 1)) == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2500
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2501
	(void) strncpy(parent, path, delim - path);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2502
	parent[delim - path] = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2503
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2504
	if ((zhp = zfs_open(hdl, parent, ZFS_TYPE_FILESYSTEM |
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2505
	    ZFS_TYPE_VOLUME)) == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2506
		free(parent);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2507
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2508
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2509
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2510
	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2511
	(void) strlcpy(zc.zc_value, delim+1, sizeof (zc.zc_value));
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2512
	zc.zc_cookie = recursive;
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2513
	ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SNAPSHOT, &zc);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2514
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2515
	/*
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2516
	 * if it was recursive, the one that actually failed will be in
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2517
	 * zc.zc_name.
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2518
	 */
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2519
	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2520
	    "cannot create snapshot '%s@%s'"), zc.zc_name, zc.zc_value);
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2521
	if (ret == 0 && recursive) {
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2522
		(void) zfs_iter_filesystems(zhp,
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2523
		    zfs_create_link_cb, (char *)delim+1);
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2524
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2525
	if (ret == 0 && zhp->zfs_type == ZFS_TYPE_VOLUME) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2526
		ret = zvol_create_link(zhp->zfs_hdl, path);
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2527
		if (ret != 0) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2528
			(void) ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DESTROY,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2529
			    &zc);
2199
712a788c2dfd PSARC 2006/388 snapshot -r
ahrens
parents: 2169
diff changeset
  2530
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2531
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2532
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2533
	if (ret != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2534
		(void) zfs_standard_error(hdl, errno, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2535
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2536
	free(parent);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2537
	zfs_close(zhp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2538
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2539
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2540
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2541
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2542
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2543
 * Dumps a backup of tosnap, incremental from fromsnap if it isn't NULL.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2544
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2545
int
1749
cc180b13f4b8 PSARC 2006/185 zfs send/receive
ahrens
parents: 1566
diff changeset
  2546
zfs_send(zfs_handle_t *zhp_to, zfs_handle_t *zhp_from)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2547
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2548
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2549
	int ret;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2550
	char errbuf[1024];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2551
	libzfs_handle_t *hdl = zhp_to->zfs_hdl;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2552
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2553
	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2554
	    "cannot send '%s'"), zhp_to->zfs_name);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2555
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2556
	/* do the ioctl() */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2557
	(void) strlcpy(zc.zc_name, zhp_to->zfs_name, sizeof (zc.zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2558
	if (zhp_from) {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2559
		(void) strlcpy(zc.zc_value, zhp_from->zfs_name,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2560
		    sizeof (zc.zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2561
	} else {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2562
		zc.zc_value[0] = '\0';
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2563
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2564
	zc.zc_cookie = STDOUT_FILENO;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2565
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2566
	ret = ioctl(zhp_to->zfs_hdl->libzfs_fd, ZFS_IOC_SENDBACKUP, &zc);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2567
	if (ret != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2568
		switch (errno) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2569
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2570
		case EXDEV:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2571
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2572
			    "not an ealier snapshot from the same fs"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2573
			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2574
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2575
		case EDQUOT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2576
		case EFBIG:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2577
		case EIO:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2578
		case ENOLINK:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2579
		case ENOSPC:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2580
		case ENOSTR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2581
		case ENXIO:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2582
		case EPIPE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2583
		case ERANGE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2584
		case EFAULT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2585
		case EROFS:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2586
			zfs_error_aux(hdl, strerror(errno));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2587
			return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2588
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2589
		default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2590
			return (zfs_standard_error(hdl, errno, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2591
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2592
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2593
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2594
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2595
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2596
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2597
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2598
 * Restores a backup of tosnap from stdin.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2599
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2600
int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2601
zfs_receive(libzfs_handle_t *hdl, const char *tosnap, int isprefix,
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2602
    int verbose, int dryrun, boolean_t force)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2603
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2604
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2605
	time_t begin_time;
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2606
	int ioctl_err, err, bytes, size;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2607
	char *cp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2608
	dmu_replay_record_t drr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2609
	struct drr_begin *drrb = &zc.zc_begin_record;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2610
	char errbuf[1024];
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2611
	prop_changelist_t *clp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2612
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2613
	begin_time = time(NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2614
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2615
	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2616
	    "cannot receive"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2617
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2618
	/* trim off snapname, if any */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2619
	(void) strlcpy(zc.zc_name, tosnap, sizeof (zc.zc_name));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2620
	cp = strchr(zc.zc_name, '@');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2621
	if (cp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2622
		*cp = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2623
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2624
	/* read in the BEGIN record */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2625
	cp = (char *)&drr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2626
	bytes = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2627
	do {
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2628
		size = read(STDIN_FILENO, cp, sizeof (drr) - bytes);
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2629
		cp += size;
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2630
		bytes += size;
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2631
	} while (size > 0);
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2632
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2633
	if (size < 0 || bytes != sizeof (drr)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2634
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2635
		    "stream (failed to read first record)"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2636
		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2637
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2638
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2639
	zc.zc_begin_record = drr.drr_u.drr_begin;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2640
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2641
	if (drrb->drr_magic != DMU_BACKUP_MAGIC &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2642
	    drrb->drr_magic != BSWAP_64(DMU_BACKUP_MAGIC)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2643
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2644
		    "stream (bad magic number)"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2645
		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2646
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2647
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2648
	if (drrb->drr_version != DMU_BACKUP_VERSION &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2649
	    drrb->drr_version != BSWAP_64(DMU_BACKUP_VERSION)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2650
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only version "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2651
		    "0x%llx is supported (stream is version 0x%llx)"),
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2652
		    DMU_BACKUP_VERSION, drrb->drr_version);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2653
		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2654
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2655
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2656
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2657
	 * Determine name of destination snapshot.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2658
	 */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2659
	(void) strlcpy(zc.zc_value, tosnap, sizeof (zc.zc_value));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2660
	if (isprefix) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2661
		if (strchr(tosnap, '@') != NULL) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2662
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2663
			    "destination must be a filesystem"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2664
			return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2665
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2666
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2667
		cp = strchr(drr.drr_u.drr_begin.drr_toname, '/');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2668
		if (cp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2669
			cp = drr.drr_u.drr_begin.drr_toname;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2670
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2671
			cp++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2672
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2673
		(void) strcat(zc.zc_value, "/");
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2674
		(void) strcat(zc.zc_value, cp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2675
	} else if (strchr(tosnap, '@') == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2676
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2677
		 * they specified just a filesystem; tack on the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2678
		 * snapname from the backup.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2679
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2680
		cp = strchr(drr.drr_u.drr_begin.drr_toname, '@');
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2681
		if (cp == NULL || strlen(tosnap) + strlen(cp) >= MAXNAMELEN)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2682
			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2683
		(void) strcat(zc.zc_value, cp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2684
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2685
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2686
	if (drrb->drr_fromguid) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2687
		zfs_handle_t *h;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2688
		/* incremental backup stream */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2689
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2690
		/* do the ioctl to the containing fs */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2691
		(void) strlcpy(zc.zc_name, zc.zc_value, sizeof (zc.zc_name));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2692
		cp = strchr(zc.zc_name, '@');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2693
		*cp = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2694
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2695
		/* make sure destination fs exists */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2696
		h = zfs_open(hdl, zc.zc_name,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2697
		    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2698
		if (h == NULL)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2699
			return (-1);
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2700
		if (!dryrun) {
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2701
			/*
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2702
			 * We need to unmount all the dependents of the dataset
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2703
			 * and the dataset itself. If it's a volume
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2704
			 * then remove device link.
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2705
			 */
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2706
			if (h->zfs_type == ZFS_TYPE_FILESYSTEM) {
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2707
				clp = changelist_gather(h, ZFS_PROP_NAME, 0);
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2708
				if (clp == NULL)
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2709
					return (-1);
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2710
				if (changelist_prefix(clp) != 0) {
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2711
					changelist_free(clp);
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2712
					return (-1);
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2713
				}
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2714
			} else {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2715
				(void) zvol_remove_link(hdl, h->zfs_name);
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2716
			}
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2717
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2718
		zfs_close(h);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2719
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2720
		/* full backup stream */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2721
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2722
		(void) strlcpy(zc.zc_name, zc.zc_value, sizeof (zc.zc_name));
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2723
1749
cc180b13f4b8 PSARC 2006/185 zfs send/receive
ahrens
parents: 1566
diff changeset
  2724
		/* make sure they aren't trying to receive into the root */
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2725
		if (strchr(zc.zc_name, '/') == NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2726
			cp = strchr(zc.zc_name, '@');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2727
			if (cp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2728
				*cp = '\0';
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2729
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2730
			    "destination '%s' already exists"), zc.zc_name);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2731
			return (zfs_error(hdl, EZFS_EXISTS, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2732
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2733
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2734
		if (isprefix) {
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2735
			zfs_handle_t *h;
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2736
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2737
			/* make sure prefix exists */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2738
			h = zfs_open(hdl, tosnap, ZFS_TYPE_FILESYSTEM);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2739
			if (h == NULL)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2740
				return (-1);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2741
			zfs_close(h);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2742
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2743
			/* create any necessary ancestors up to prefix */
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2744
			zc.zc_objset_type = DMU_OST_ZFS;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2745
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2746
			/*
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2747
			 * zc.zc_name is now the full name of the snap
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2748
			 * we're restoring into.  Attempt to create,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2749
			 * mount, and share any ancestor filesystems, up
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2750
			 * to the one that was named.
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2751
			 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2752
			for (cp = zc.zc_name + strlen(tosnap) + 1;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2753
			    cp = strchr(cp, '/'); *cp = '/', cp++) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2754
				const char *opname;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2755
				*cp = '\0';
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2756
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2757
				opname = dgettext(TEXT_DOMAIN, "create");
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2758
				if (zfs_create(hdl, zc.zc_name,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2759
				    ZFS_TYPE_FILESYSTEM, NULL) != 0) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2760
					if (errno == EEXIST)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2761
						continue;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2762
					goto ancestorerr;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2763
				}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2764
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2765
				opname = dgettext(TEXT_DOMAIN, "open");
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2766
				h = zfs_open(hdl, zc.zc_name,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2767
				    ZFS_TYPE_FILESYSTEM);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2768
				if (h == NULL)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2769
					goto ancestorerr;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2770
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2771
				opname = dgettext(TEXT_DOMAIN, "mount");
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2772
				if (zfs_mount(h, NULL, 0) != 0)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2773
					goto ancestorerr;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2774
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2775
				opname = dgettext(TEXT_DOMAIN, "share");
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2776
				if (zfs_share(h) != 0)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2777
					goto ancestorerr;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2778
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2779
				zfs_close(h);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2780
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2781
				continue;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2782
ancestorerr:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2783
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2784
				    "failed to %s ancestor '%s'"), opname,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2785
				    zc.zc_name);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2786
				return (zfs_error(hdl, EZFS_BADRESTORE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2787
				    errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2788
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2789
		}
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2790
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2791
		/* Make sure destination fs does not exist */
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2792
		cp = strchr(zc.zc_name, '@');
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2793
		*cp = '\0';
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2794
		if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2795
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2796
			    "destination '%s' exists"), zc.zc_name);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2797
			return (zfs_error(hdl, EZFS_EXISTS, errbuf));
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2798
		}
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2799
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2800
		/* Do the recvbackup ioctl to the fs's parent. */
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2801
		cp = strrchr(zc.zc_name, '/');
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2802
		*cp = '\0';
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2803
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2804
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2805
	zc.zc_cookie = STDIN_FILENO;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2806
	zc.zc_guid = force;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2807
	if (verbose) {
1749
cc180b13f4b8 PSARC 2006/185 zfs send/receive
ahrens
parents: 1566
diff changeset
  2808
		(void) printf("%s %s stream of %s into %s\n",
cc180b13f4b8 PSARC 2006/185 zfs send/receive
ahrens
parents: 1566
diff changeset
  2809
		    dryrun ? "would receive" : "receiving",
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2810
		    drrb->drr_fromguid ? "incremental" : "full",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2811
		    drr.drr_u.drr_begin.drr_toname,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2812
		    zc.zc_value);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2813
		(void) fflush(stdout);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2814
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2815
	if (dryrun)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2816
		return (0);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2817
	err = ioctl_err = ioctl(hdl->libzfs_fd, ZFS_IOC_RECVBACKUP, &zc);
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2818
	if (ioctl_err != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2819
		switch (errno) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2820
		case ENODEV:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2821
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2822
			    "most recent snapshot does not match incremental "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2823
			    "source"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2824
			(void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2825
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2826
		case ETXTBSY:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2827
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2828
			    "destination has been modified since most recent "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2829
			    "snapshot"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2830
			(void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2831
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2832
		case EEXIST:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2833
			if (drrb->drr_fromguid == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2834
				/* it's the containing fs that exists */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2835
				cp = strchr(zc.zc_value, '@');
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2836
				*cp = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2837
			}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2838
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2839
			    "destination already exists"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2840
			(void) zfs_error(hdl, EZFS_EXISTS, dgettext(TEXT_DOMAIN,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2841
			    "cannot restore to %s"), zc.zc_value);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2842
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2843
		case EINVAL:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2844
			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2845
			break;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2846
		case ECKSUM:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2847
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2848
			    "invalid stream (checksum mismatch)"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2849
			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2850
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2851
		default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2852
			(void) zfs_standard_error(hdl, errno, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2853
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2854
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2855
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2856
	/*
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2857
	 * Mount or recreate the /dev links for the target filesystem
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2858
	 * (if created, or if we tore them down to do an incremental
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2859
	 * restore), and the /dev links for the new snapshot (if
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2860
	 * created). Also mount any children of the target filesystem
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2861
	 * if we did an incremental receive.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2862
	 */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2863
	cp = strchr(zc.zc_value, '@');
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2864
	if (cp && (ioctl_err == 0 || drrb->drr_fromguid)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2865
		zfs_handle_t *h;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2866
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2867
		*cp = '\0';
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2868
		h = zfs_open(hdl, zc.zc_value,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2869
		    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2870
		*cp = '@';
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2871
		if (h) {
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2872
			if (h->zfs_type == ZFS_TYPE_VOLUME) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2873
				err = zvol_create_link(hdl, h->zfs_name);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1407
diff changeset
  2874
				if (err == 0 && ioctl_err == 0)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2875
					err = zvol_create_link(hdl,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2876
					    zc.zc_value);
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2877
			} else {
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2878
				if (drrb->drr_fromguid) {
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2879
					err = changelist_postfix(clp);
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2880
					changelist_free(clp);
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2881
				} else {
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2882
					err = zfs_mount(h, NULL, 0);
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2883
				}
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2884
			}
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2885
		zfs_close(h);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2886
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2887
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2888
868
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2889
	if (err || ioctl_err)
09ef7c98db8f 6344651 LZ, 'zfs restore', internal error: unexpected error 1 ...
ahrens
parents: 849
diff changeset
  2890
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2891
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2892
	if (verbose) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2893
		char buf1[64];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2894
		char buf2[64];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2895
		uint64_t bytes = zc.zc_cookie;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2896
		time_t delta = time(NULL) - begin_time;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2897
		if (delta == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2898
			delta = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2899
		zfs_nicenum(bytes, buf1, sizeof (buf1));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2900
		zfs_nicenum(bytes/delta, buf2, sizeof (buf1));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2901
1749
cc180b13f4b8 PSARC 2006/185 zfs send/receive
ahrens
parents: 1566
diff changeset
  2902
		(void) printf("received %sb stream in %lu seconds (%sb/sec)\n",
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2903
		    buf1, delta, buf2);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2904
	}
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  2905
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2906
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2907
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2908
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2909
/*
1294
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2910
 * Destroy any more recent snapshots.  We invoke this callback on any dependents
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2911
 * of the snapshot first.  If the 'cb_dependent' member is non-zero, then this
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2912
 * is a dependent and we should just destroy it without checking the transaction
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2913
 * group.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2914
 */
1294
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2915
typedef struct rollback_data {
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2916
	const char	*cb_target;		/* the snapshot */
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2917
	uint64_t	cb_create;		/* creation time reference */
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2918
	prop_changelist_t *cb_clp;		/* changelist pointer */
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2919
	int		cb_error;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2920
	boolean_t	cb_dependent;
1294
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2921
} rollback_data_t;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2922
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2923
static int
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2924
rollback_destroy(zfs_handle_t *zhp, void *data)
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2925
{
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2926
	rollback_data_t *cbp = data;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2927
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2928
	if (!cbp->cb_dependent) {
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2929
		if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 &&
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2930
		    zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2931
		    zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2932
		    cbp->cb_create) {
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2933
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2934
			cbp->cb_dependent = B_TRUE;
2474
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  2935
			if (zfs_iter_dependents(zhp, B_FALSE, rollback_destroy,
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  2936
			    cbp) != 0)
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  2937
				cbp->cb_error = 1;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2938
			cbp->cb_dependent = B_FALSE;
1294
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2939
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2940
			if (zfs_destroy(zhp) != 0)
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2941
				cbp->cb_error = 1;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2942
			else
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2943
				changelist_remove(zhp, cbp->cb_clp);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2944
		}
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2945
	} else {
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2946
		if (zfs_destroy(zhp) != 0)
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2947
			cbp->cb_error = 1;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2948
		else
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2949
			changelist_remove(zhp, cbp->cb_clp);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2950
	}
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2951
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2952
	zfs_close(zhp);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2953
	return (0);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2954
}
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2955
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2956
/*
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2957
 * Rollback the dataset to its latest snapshot.
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2958
 */
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2959
static int
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2960
do_rollback(zfs_handle_t *zhp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2961
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2962
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2963
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2964
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2965
	assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2966
	    zhp->zfs_type == ZFS_TYPE_VOLUME);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2967
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2968
	if (zhp->zfs_type == ZFS_TYPE_VOLUME &&
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2969
	    zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2970
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2971
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2972
	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2973
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  2974
	if (ZFS_IS_VOLUME(zhp))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2975
		zc.zc_objset_type = DMU_OST_ZVOL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2976
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2977
		zc.zc_objset_type = DMU_OST_ZFS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2978
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2979
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2980
	 * We rely on the consumer to verify that there are no newer snapshots
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2981
	 * for the given dataset.  Given these constraints, we can simply pass
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2982
	 * the name on to the ioctl() call.  There is still an unlikely race
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2983
	 * condition where the user has taken a snapshot since we verified that
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2984
	 * this was the most recent.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2985
	 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2986
	if ((ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_ROLLBACK,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2987
	    &zc)) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2988
		(void) zfs_standard_error(zhp->zfs_hdl, errno,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2989
		    dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2990
		    zhp->zfs_name);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2991
	} else if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  2992
		ret = zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2993
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2994
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2995
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2996
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2997
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2998
/*
1294
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  2999
 * Given a dataset, rollback to a specific snapshot, discarding any
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3000
 * data changes since then and making it the active dataset.
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3001
 *
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3002
 * Any snapshots more recent than the target are destroyed, along with
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3003
 * their dependents.
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3004
 */
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3005
int
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3006
zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, int flag)
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3007
{
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3008
	int ret;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3009
	rollback_data_t cb = { 0 };
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3010
	prop_changelist_t *clp;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3011
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3012
	/*
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3013
	 * Unmount all dependendents of the dataset and the dataset itself.
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3014
	 * The list we need to gather is the same as for doing rename
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3015
	 */
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3016
	clp = changelist_gather(zhp, ZFS_PROP_NAME, flag ? MS_FORCE: 0);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3017
	if (clp == NULL)
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3018
		return (-1);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3019
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3020
	if ((ret = changelist_prefix(clp)) != 0)
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3021
		goto out;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3022
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3023
	/*
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3024
	 * Destroy all recent snapshots and its dependends.
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3025
	 */
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3026
	cb.cb_target = snap->zfs_name;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3027
	cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3028
	cb.cb_clp = clp;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3029
	(void) zfs_iter_children(zhp, rollback_destroy, &cb);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3030
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3031
	if ((ret = cb.cb_error) != 0) {
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3032
		(void) changelist_postfix(clp);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3033
		goto out;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3034
	}
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3035
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3036
	/*
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3037
	 * Now that we have verified that the snapshot is the latest,
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3038
	 * rollback to the given snapshot.
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3039
	 */
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3040
	ret = do_rollback(zhp);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3041
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3042
	if (ret != 0) {
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3043
		(void) changelist_postfix(clp);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3044
		goto out;
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3045
	}
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3046
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3047
	/*
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3048
	 * We only want to re-mount the filesystem if it was mounted in the
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3049
	 * first place.
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3050
	 */
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3051
	ret = changelist_postfix(clp);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3052
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3053
out:
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3054
	changelist_free(clp);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3055
	return (ret);
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3056
}
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3057
87b43e5de5ee 6364129 need to unmount any child datasets before doing the rollback
lling
parents: 1175
diff changeset
  3058
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3059
 * Iterate over all dependents for a given dataset.  This includes both
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3060
 * hierarchical dependents (children) and data dependents (snapshots and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3061
 * clones).  The bulk of the processing occurs in get_dependents() in
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3062
 * libzfs_graph.c.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3063
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3064
int
2474
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  3065
zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion,
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  3066
    zfs_iter_f func, void *data)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3067
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3068
	char **dependents;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3069
	size_t count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3070
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3071
	zfs_handle_t *child;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3072
	int ret = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3073
2474
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  3074
	if (get_dependents(zhp->zfs_hdl, allowrecursion, zhp->zfs_name,
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  3075
	    &dependents, &count) != 0)
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  3076
		return (-1);
c001ad7e0c25 6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents: 2440
diff changeset
  3077
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3078
	for (i = 0; i < count; i++) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3079
		if ((child = make_dataset_handle(zhp->zfs_hdl,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3080
		    dependents[i])) == NULL)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3081
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3082
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3083
		if ((ret = func(child, data)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3084
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3085
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3086
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3087
	for (i = 0; i < count; i++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3088
		free(dependents[i]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3089
	free(dependents);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3090
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3091
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3092
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3093
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3094
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3095
 * Renames the given dataset.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3096
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3097
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3098
zfs_rename(zfs_handle_t *zhp, const char *target)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3099
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3100
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3101
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3102
	char *delim;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3103
	prop_changelist_t *cl;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3104
	char parent[ZFS_MAXNAMELEN];
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3105
	libzfs_handle_t *hdl = zhp->zfs_hdl;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3106
	char errbuf[1024];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3107
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3108
	/* if we have the same exact name, just return success */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3109
	if (strcmp(zhp->zfs_name, target) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3110
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3111
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3112
	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3113
	    "cannot rename to '%s'"), target);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3114
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3115
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3116
	 * Make sure the target name is valid
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3117
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3118
	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3119
		if ((strchr(target, '@') == NULL) ||
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3120
		    *target == '@') {
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3121
			/*
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3122
			 * Snapshot target name is abbreviated,
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3123
			 * reconstruct full dataset name
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3124
			 */
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3125
			(void) strlcpy(parent, zhp->zfs_name,
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3126
			    sizeof (parent));
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3127
			delim = strchr(parent, '@');
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3128
			if (strchr(target, '@') == NULL)
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3129
				*(++delim) = '\0';
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3130
			else
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3131
				*delim = '\0';
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3132
			(void) strlcat(parent, target, sizeof (parent));
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3133
			target = parent;
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3134
		} else {
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3135
			/*
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3136
			 * Make sure we're renaming within the same dataset.
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3137
			 */
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3138
			delim = strchr(target, '@');
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3139
			if (strncmp(zhp->zfs_name, target, delim - target)
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3140
			    != 0 || zhp->zfs_name[delim - target] != '@') {
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3141
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3142
				    "snapshots must be part of same "
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3143
				    "dataset"));
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3144
				return (zfs_error(hdl, EZFS_CROSSTARGET,
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3145
					    errbuf));
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3146
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3147
		}
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3148
		if (!zfs_validate_name(hdl, target, zhp->zfs_type))
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3149
			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3150
	} else {
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3151
		if (!zfs_validate_name(hdl, target, zhp->zfs_type))
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3152
			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3153
		uint64_t unused;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3154
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3155
		/* validate parents */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3156
		if (check_parents(hdl, target, &unused) != 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3157
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3158
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3159
		(void) parent_name(target, parent, sizeof (parent));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3160
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3161
		/* make sure we're in the same pool */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3162
		verify((delim = strchr(target, '/')) != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3163
		if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3164
		    zhp->zfs_name[delim - target] != '/') {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3165
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3166
			    "datasets must be within same pool"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3167
			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3168
		}
2440
9281a87e8a9e 6451860 zfs rename' a filesystem|clone to its direct child will cause internal error
nd150628
parents: 2417
diff changeset
  3169
9281a87e8a9e 6451860 zfs rename' a filesystem|clone to its direct child will cause internal error
nd150628
parents: 2417
diff changeset
  3170
		/* new name cannot be a child of the current dataset name */
9281a87e8a9e 6451860 zfs rename' a filesystem|clone to its direct child will cause internal error
nd150628
parents: 2417
diff changeset
  3171
		if (strncmp(parent, zhp->zfs_name,
9281a87e8a9e 6451860 zfs rename' a filesystem|clone to its direct child will cause internal error
nd150628
parents: 2417
diff changeset
  3172
			    strlen(zhp->zfs_name)) == 0) {
9281a87e8a9e 6451860 zfs rename' a filesystem|clone to its direct child will cause internal error
nd150628
parents: 2417
diff changeset
  3173
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
9281a87e8a9e 6451860 zfs rename' a filesystem|clone to its direct child will cause internal error
nd150628
parents: 2417
diff changeset
  3174
			    "New dataset name cannot be a descendent of "
9281a87e8a9e 6451860 zfs rename' a filesystem|clone to its direct child will cause internal error
nd150628
parents: 2417
diff changeset
  3175
			    "current dataset name"));
9281a87e8a9e 6451860 zfs rename' a filesystem|clone to its direct child will cause internal error
nd150628
parents: 2417
diff changeset
  3176
			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
9281a87e8a9e 6451860 zfs rename' a filesystem|clone to its direct child will cause internal error
nd150628
parents: 2417
diff changeset
  3177
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3178
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3179
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3180
	(void) snprintf(errbuf, sizeof (errbuf),
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3181
	    dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3182
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3183
	if (getzoneid() == GLOBAL_ZONEID &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3184
	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3185
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3186
		    "dataset is used in a non-global zone"));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3187
		return (zfs_error(hdl, EZFS_ZONED, errbuf));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3188
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3189
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3190
	if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0)) == NULL)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3191
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3192
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3193
	if (changelist_haszonedchild(cl)) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3194
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3195
		    "child dataset with inherited mountpoint is used "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3196
		    "in a non-global zone"));
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3197
		(void) zfs_error(hdl, EZFS_ZONED, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3198
		goto error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3199
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3200
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3201
	if ((ret = changelist_prefix(cl)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3202
		goto error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3203
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3204
	if (ZFS_IS_VOLUME(zhp))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3205
		zc.zc_objset_type = DMU_OST_ZVOL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3206
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3207
		zc.zc_objset_type = DMU_OST_ZFS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3208
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3209
	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3210
	(void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
2665
7b208a92357b PSARC 2006/479 zfs receive -F
nd150628
parents: 2474
diff changeset
  3211
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3212
	if ((ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_RENAME, &zc)) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3213
		(void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3214
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3215
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3216
		 * On failure, we still want to remount any filesystems that
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3217
		 * were previously mounted, so we don't alter the system state.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3218
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3219
		(void) changelist_postfix(cl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3220
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3221
		changelist_rename(cl, zfs_get_name(zhp), target);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3222
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3223
		ret = changelist_postfix(cl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3224
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3225
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3226
error:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3227
	changelist_free(cl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3228
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3229
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3230
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3231
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3232
 * Given a zvol dataset, issue the ioctl to create the appropriate minor node,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3233
 * poke devfsadm to create the /dev link, and then wait for the link to appear.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3234
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3235
int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3236
zvol_create_link(libzfs_handle_t *hdl, const char *dataset)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3237
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3238
	zfs_cmd_t zc = { 0 };
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3239
	di_devlink_handle_t dhdl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3240
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3241
	(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3242
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3243
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3244
	 * Issue the appropriate ioctl.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3245
	 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3246
	if (ioctl(hdl->libzfs_fd, ZFS_IOC_CREATE_MINOR, &zc) != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3247
		switch (errno) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3248
		case EEXIST:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3249
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3250
			 * Silently ignore the case where the link already
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3251
			 * exists.  This allows 'zfs volinit' to be run multiple
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3252
			 * times without errors.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3253
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3254
			return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3255
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3256
		default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3257
			return (zfs_standard_error(hdl, errno,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3258
			    dgettext(TEXT_DOMAIN, "cannot create device links "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3259
			    "for '%s'"), dataset));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3260
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3261
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3262
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3263
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3264
	 * Call devfsadm and wait for the links to magically appear.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3265
	 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3266
	if ((dhdl = di_devlink_init(ZFS_DRIVER, DI_MAKE_LINK)) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3267
		zfs_error_aux(hdl, strerror(errno));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3268
		(void) zfs_error(hdl, EZFS_DEVLINKS,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3269
		    dgettext(TEXT_DOMAIN, "cannot create device links "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3270
		    "for '%s'"), dataset);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3271
		(void) ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3272
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3273
	} else {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3274
		(void) di_devlink_fini(&dhdl);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3275
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3276
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3277
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3278
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3279
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3280
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3281
 * Remove a minor node for the given zvol and the associated /dev links.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3282
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3283
int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3284
zvol_remove_link(libzfs_handle_t *hdl, const char *dataset)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3285
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3286
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3287
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3288
	(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3289
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3290
	if (ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc) != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3291
		switch (errno) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3292
		case ENXIO:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3293
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3294
			 * Silently ignore the case where the link no longer
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3295
			 * exists, so that 'zfs volfini' can be run multiple
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3296
			 * times without errors.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3297
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3298
			return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3299
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3300
		default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3301
			return (zfs_standard_error(hdl, errno,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3302
			    dgettext(TEXT_DOMAIN, "cannot remove device "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1793
diff changeset
  3303
			    "links for '%s'"), dataset));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3304
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3305
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3306
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3307
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3308
}
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3309
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3310
nvlist_t *
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3311
zfs_get_user_props(zfs_handle_t *zhp)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3312
{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3313
	return (zhp->zfs_user_props);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3314
}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3315
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3316
/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3317
 * Given a comma-separated list of properties, contruct a property list
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3318
 * containing both user-defined and native properties.  This function will
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3319
 * return a NULL list if 'all' is specified, which can later be expanded on a
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3320
 * per-dataset basis by zfs_expand_proplist().
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3321
 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3322
int
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3323
zfs_get_proplist(libzfs_handle_t *hdl, char *fields, zfs_proplist_t **listp)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3324
{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3325
	int i;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3326
	size_t len;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3327
	char *s, *p;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3328
	char c;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3329
	zfs_prop_t prop;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3330
	zfs_proplist_t *entry;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3331
	zfs_proplist_t **last;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3332
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3333
	*listp = NULL;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3334
	last = listp;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3335
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3336
	/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3337
	 * If 'all' is specified, return a NULL list.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3338
	 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3339
	if (strcmp(fields, "all") == 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3340
		return (0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3341
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3342
	/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3343
	 * If no fields were specified, return an error.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3344
	 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3345
	if (fields[0] == '\0') {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3346
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3347
		    "no properties specified"));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3348
		return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3349
		    "bad property list")));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3350
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3351
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3352
	/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3353
	 * It would be nice to use getsubopt() here, but the inclusion of column
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3354
	 * aliases makes this more effort than it's worth.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3355
	 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3356
	s = fields;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3357
	while (*s != '\0') {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3358
		if ((p = strchr(s, ',')) == NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3359
			len = strlen(s);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3360
			p = s + len;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3361
		} else {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3362
			len = p - s;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3363
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3364
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3365
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3366
		 * Check for empty options.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3367
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3368
		if (len == 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3369
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3370
			    "empty property name"));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3371
			return (zfs_error(hdl, EZFS_BADPROP,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3372
			    dgettext(TEXT_DOMAIN, "bad property list")));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3373
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3374
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3375
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3376
		 * Check all regular property names.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3377
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3378
		c = s[len];
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3379
		s[len] = '\0';
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3380
		for (i = 0; i < ZFS_NPROP_ALL; i++) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3381
			if ((prop = zfs_name_to_prop(s)) != ZFS_PROP_INVAL)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3382
				break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3383
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3384
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3385
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3386
		 * If no column is specified, and this isn't a user property,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3387
		 * return failure.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3388
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3389
		if (i == ZFS_NPROP_ALL && !zfs_prop_user(s)) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3390
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3391
			    "invalid property '%s'"), s);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3392
			return (zfs_error(hdl, EZFS_BADPROP,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3393
			    dgettext(TEXT_DOMAIN, "bad property list")));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3394
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3395
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3396
		if ((entry = zfs_alloc(hdl, sizeof (zfs_proplist_t))) == NULL)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3397
			return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3398
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3399
		entry->pl_prop = prop;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3400
		if (prop == ZFS_PROP_INVAL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3401
			if ((entry->pl_user_prop =
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3402
			    zfs_strdup(hdl, s)) == NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3403
				free(entry);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3404
				return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3405
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3406
			entry->pl_width = strlen(s);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3407
		} else {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3408
			entry->pl_width = zfs_prop_width(prop,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3409
			    &entry->pl_fixed);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3410
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3411
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3412
		*last = entry;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3413
		last = &entry->pl_next;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3414
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3415
		s = p;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3416
		if (c == ',')
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3417
			s++;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3418
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3419
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3420
	return (0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3421
}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3422
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3423
void
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3424
zfs_free_proplist(zfs_proplist_t *pl)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3425
{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3426
	zfs_proplist_t *next;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3427
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3428
	while (pl != NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3429
		next = pl->pl_next;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3430
		free(pl->pl_user_prop);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3431
		free(pl);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3432
		pl = next;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3433
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3434
}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3435
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3436
/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3437
 * This function is used by 'zfs list' to determine the exact set of columns to
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3438
 * display, and their maximum widths.  This does two main things:
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3439
 *
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3440
 * 	- If this is a list of all properties, then expand the list to include
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3441
 *	  all native properties, and set a flag so that for each dataset we look
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3442
 *	  for new unique user properties and add them to the list.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3443
 *
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3444
 * 	- For non fixed-width properties, keep track of the maximum width seen
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3445
 *	  so that we can size the column appropriately.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3446
 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3447
int
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3448
zfs_expand_proplist(zfs_handle_t *zhp, zfs_proplist_t **plp)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3449
{
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3450
	libzfs_handle_t *hdl = zhp->zfs_hdl;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3451
	zfs_prop_t prop;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3452
	zfs_proplist_t *entry;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3453
	zfs_proplist_t **last, **start;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3454
	nvlist_t *userprops, *propval;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3455
	nvpair_t *elem;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3456
	char *strval;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3457
	char buf[ZFS_MAXPROPLEN];
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3458
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3459
	if (*plp == NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3460
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3461
		 * If this is the very first time we've been called for an 'all'
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3462
		 * specification, expand the list to include all native
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3463
		 * properties.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3464
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3465
		last = plp;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3466
		for (prop = 0; prop < ZFS_NPROP_VISIBLE; prop++) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3467
			if ((entry = zfs_alloc(hdl,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3468
			    sizeof (zfs_proplist_t))) == NULL)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3469
				return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3470
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3471
			entry->pl_prop = prop;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3472
			entry->pl_width = zfs_prop_width(prop,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3473
			    &entry->pl_fixed);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3474
			entry->pl_all = B_TRUE;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3475
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3476
			*last = entry;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3477
			last = &entry->pl_next;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3478
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3479
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3480
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3481
		 * Add 'name' to the beginning of the list, which is handled
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3482
		 * specially.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3483
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3484
		if ((entry = zfs_alloc(hdl,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3485
		    sizeof (zfs_proplist_t))) == NULL)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3486
			return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3487
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3488
		entry->pl_prop = ZFS_PROP_NAME;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3489
		entry->pl_width = zfs_prop_width(ZFS_PROP_NAME,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3490
		    &entry->pl_fixed);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3491
		entry->pl_all = B_TRUE;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3492
		entry->pl_next = *plp;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3493
		*plp = entry;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3494
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3495
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3496
	userprops = zfs_get_user_props(zhp);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3497
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3498
	entry = *plp;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3499
	if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3500
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3501
		 * Go through and add any user properties as necessary.  We
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3502
		 * start by incrementing our list pointer to the first
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3503
		 * non-native property.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3504
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3505
		start = plp;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3506
		while (*start != NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3507
			if ((*start)->pl_prop == ZFS_PROP_INVAL)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3508
				break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3509
			start = &(*start)->pl_next;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3510
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3511
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3512
		elem = NULL;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3513
		while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3514
			/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3515
			 * See if we've already found this property in our list.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3516
			 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3517
			for (last = start; *last != NULL;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3518
			    last = &(*last)->pl_next) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3519
				if (strcmp((*last)->pl_user_prop,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3520
				    nvpair_name(elem)) == 0)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3521
					break;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3522
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3523
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3524
			if (*last == NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3525
				if ((entry = zfs_alloc(hdl,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3526
				    sizeof (zfs_proplist_t))) == NULL ||
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3527
				    ((entry->pl_user_prop = zfs_strdup(hdl,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3528
				    nvpair_name(elem)))) == NULL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3529
					free(entry);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3530
					return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3531
				}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3532
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3533
				entry->pl_prop = ZFS_PROP_INVAL;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3534
				entry->pl_width = strlen(nvpair_name(elem));
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3535
				entry->pl_all = B_TRUE;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3536
				*last = entry;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3537
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3538
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3539
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3540
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3541
	/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3542
	 * Now go through and check the width of any non-fixed columns
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3543
	 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3544
	for (entry = *plp; entry != NULL; entry = entry->pl_next) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3545
		if (entry->pl_fixed)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3546
			continue;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3547
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3548
		if (entry->pl_prop != ZFS_PROP_INVAL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3549
			if (zfs_prop_get(zhp, entry->pl_prop,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3550
			    buf, sizeof (buf), NULL, NULL, 0, B_FALSE) == 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3551
				if (strlen(buf) > entry->pl_width)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3552
					entry->pl_width = strlen(buf);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3553
			}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3554
		} else if (nvlist_lookup_nvlist(userprops,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3555
		    entry->pl_user_prop, &propval)  == 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3556
			verify(nvlist_lookup_string(propval,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3557
			    ZFS_PROP_VALUE, &strval) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3558
			if (strlen(strval) > entry->pl_width)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3559
				entry->pl_width = strlen(strval);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3560
		}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3561
	}
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3562
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3563
	return (0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2665
diff changeset
  3564
}