View | Details | Raw Unified | Return to bug 244465 | Differences between
and this patch

Collapse All | Expand All

(-)zfs_main.c (-10 / +74 lines)
Lines 327-334 Link Here
327
	case HELP_SHARE:
327
	case HELP_SHARE:
328
		return (gettext("\tshare [-l] <-a [nfs|smb] | filesystem>\n"));
328
		return (gettext("\tshare [-l] <-a [nfs|smb] | filesystem>\n"));
329
	case HELP_SNAPSHOT:
329
	case HELP_SNAPSHOT:
330
		return (gettext("\tsnapshot|snap [-r] [-o property=value] ... "
330
		return (gettext("\tsnapshot|snap [-n] [-v] [-r] "
331
		    "<filesystem|volume>@<snap> ...\n"));
331
		    "[-m minfree] [-o property=value]... "
332
		    "... <filesystem|volume>@<snap> ...\n"));
332
	case HELP_UNMOUNT:
333
	case HELP_UNMOUNT:
333
		return (gettext("\tunmount [-fu] "
334
		return (gettext("\tunmount [-fu] "
334
		    "<-a | filesystem|mountpoint>\n"));
335
		    "<-a | filesystem|mountpoint>\n"));
Lines 4076-4081 Link Here
4076
	nvlist_t *sd_nvl;
4077
	nvlist_t *sd_nvl;
4077
	boolean_t sd_recursive;
4078
	boolean_t sd_recursive;
4078
	const char *sd_snapname;
4079
	const char *sd_snapname;
4080
	uint64_t sd_min_avail;
4081
	boolean_t sd_verbose;
4082
	boolean_t sd_no_update;
4079
} snap_cbdata_t;
4083
} snap_cbdata_t;
4080
4084
4081
static int
4085
static int
Lines 4085-4090 Link Here
4085
	char *name;
4089
	char *name;
4086
	int rv = 0;
4090
	int rv = 0;
4087
	int error;
4091
	int error;
4092
	uint64_t avail;
4088
4093
4089
	if (sd->sd_recursive &&
4094
	if (sd->sd_recursive &&
4090
	    zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) != 0) {
4095
	    zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) != 0) {
Lines 4092-4111 Link Here
4092
		return (0);
4097
		return (0);
4093
	}
4098
	}
4094
4099
4095
	error = asprintf(&name, "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
4100
	if (!sd->sd_min_avail ||
4096
	if (error == -1)
4101
	    (avail = zfs_prop_get_int(zhp,
4097
		nomem();
4102
	    ZFS_PROP_AVAILABLE)) >= sd->sd_min_avail) {
4098
	fnvlist_add_boolean(sd->sd_nvl, name);
4103
4099
	free(name);
4104
		error = asprintf(&name, "%s@%s",
4105
		    zfs_get_name(zhp), sd->sd_snapname);
4106
		if (error == -1)
4107
			nomem();
4108
		fnvlist_add_boolean(sd->sd_nvl, name);
4109
		free(name);
4100
4110
4111
	} else if (sd->sd_verbose) {
4112
		fprintf(stderr,
4113
		    gettext("skipping snapshot of '%s'"
4114
		    ": avail (%llu) too low (< %llu)\n"),
4115
		    zfs_get_name(zhp),
4116
		    (unsigned long long) avail,
4117
		    (unsigned long long) sd->sd_min_avail);
4118
	}
4101
	if (sd->sd_recursive)
4119
	if (sd->sd_recursive)
4102
		rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
4120
		rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
4121
4103
	zfs_close(zhp);
4122
	zfs_close(zhp);
4104
	return (rv);
4123
	return (rv);
4105
}
4124
}
4106
4125
4107
/*
4126
/*
4108
 * zfs snapshot [-r] [-o prop=value] ... <fs@snap>
4127
 * zfs snapshot [-v] [-n] [-r] [-o prop=value] [-m minfree] ... <fs@snap>
4109
 *
4128
 *
4110
 * Creates a snapshot with the given name.  While functionally equivalent to
4129
 * Creates a snapshot with the given name.  While functionally equivalent to
4111
 * 'zfs create', it is a separate command to differentiate intent.
4130
 * 'zfs create', it is a separate command to differentiate intent.
Lines 4118-4131 Link Here
4118
	nvlist_t *props;
4137
	nvlist_t *props;
4119
	snap_cbdata_t sd = { 0 };
4138
	snap_cbdata_t sd = { 0 };
4120
	boolean_t multiple_snaps = B_FALSE;
4139
	boolean_t multiple_snaps = B_FALSE;
4140
	char pfx;
4141
	unsigned long avail = 0;
4121
4142
4122
	if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
4143
	if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
4123
		nomem();
4144
		nomem();
4124
	if (nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) != 0)
4145
	if (nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) != 0)
4125
		nomem();
4146
		nomem();
4126
4147
4148
	sd.sd_min_avail = 0;
4149
	sd.sd_verbose = 0;
4150
	sd.sd_no_update = 0;
4151
4127
	/* check options */
4152
	/* check options */
4128
	while ((c = getopt(argc, argv, "ro:")) != -1) {
4153
	while ((c = getopt(argc, argv, "nvro:m:")) != -1) {
4129
		switch (c) {
4154
		switch (c) {
4130
		case 'o':
4155
		case 'o':
4131
			if (!parseprop(props, optarg)) {
4156
			if (!parseprop(props, optarg)) {
Lines 4134-4143 Link Here
4134
				return (1);
4159
				return (1);
4135
			}
4160
			}
4136
			break;
4161
			break;
4162
		case 'n':
4163
			sd.sd_no_update = 1;
4164
			break;
4165
		case 'v':
4166
			sd.sd_verbose = 1;
4167
			break;
4137
		case 'r':
4168
		case 'r':
4138
			sd.sd_recursive = B_TRUE;
4169
			sd.sd_recursive = B_TRUE;
4139
			multiple_snaps = B_TRUE;
4170
			multiple_snaps = B_TRUE;
4140
			break;
4171
			break;
4172
		case 'm':
4173
			pfx = 0;
4174
			if (!optarg ||
4175
			    sscanf(optarg, "%lu%c",
4176
			    &avail, &pfx) < 1) {
4177
				(void) fprintf(stderr,
4178
				    gettext("invalid minfree '%s'"), optarg);
4179
				goto usage;
4180
			}
4181
			sd.sd_min_avail = avail;
4182
			switch (toupper(pfx)) {
4183
			case 'K':
4184
				sd.sd_min_avail *= 1000;
4185
				break;
4186
			case 'M':
4187
				sd.sd_min_avail *= 1000000;
4188
				break;
4189
			case 'G':
4190
				sd.sd_min_avail *= 1000000000;
4191
				break;
4192
			case 'T':
4193
				sd.sd_min_avail *= 1000000000000;
4194
				break;
4195
			default:
4196
				(void) fprintf(stderr,
4197
				    gettext("invalid minfree suffix '%s'"),
4198
				    optarg);
4199
				goto usage;
4200
			}
4201
			break;
4141
		case '?':
4202
		case '?':
4142
			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
4203
			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
4143
			    optopt);
4204
			    optopt);
Lines 4173-4179 Link Here
4173
			goto usage;
4234
			goto usage;
4174
	}
4235
	}
4175
4236
4176
	ret = zfs_snapshot_nvl(g_zfs, sd.sd_nvl, props);
4237
	ret = 0;
4238
	if (!sd.sd_no_update && !nvlist_empty(sd.sd_nvl))
4239
		ret = zfs_snapshot_nvl(g_zfs, sd.sd_nvl, props);
4240
4177
	nvlist_free(sd.sd_nvl);
4241
	nvlist_free(sd.sd_nvl);
4178
	nvlist_free(props);
4242
	nvlist_free(props);
4179
	if (ret != 0 && multiple_snaps)
4243
	if (ret != 0 && multiple_snaps)
(-)zfs.8 (+11 lines)
Lines 72-77 Link Here
72
.Nm
72
.Nm
73
.Cm snapshot Ns | Ns Cm snap
73
.Cm snapshot Ns | Ns Cm snap
74
.Op Fl r
74
.Op Fl r
75
.Op Fl n
76
.Op Fl v
77
.Op Fl m Ar minfree
75
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
78
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
76
.Ar filesystem@snapname Ns | Ns Ar volume@snapname
79
.Ar filesystem@snapname Ns | Ns Ar volume@snapname
77
.Ar filesystem@snapname Ns | Ns Ar volume@snapname Ns ...
80
.Ar filesystem@snapname Ns | Ns Ar volume@snapname Ns ...
Lines 1929-1934 Link Here
1929
.Nm
1932
.Nm
1930
.Cm snapshot Ns | Ns Cm snap
1933
.Cm snapshot Ns | Ns Cm snap
1931
.Op Fl r
1934
.Op Fl r
1935
.Oo Fl m Ar minfree
1936
Set a limit on the minimum free space available for
1937
snapshots to be taken. Size suffixes (K, M, G or T) can
1938
be used.
1939
.Oo Fl n
1940
Do a dry-run (do not actually create any snapshots).
1941
.Oo Fl v
1942
Be more verbose (list snapshots skipped due to minfree).
1932
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
1943
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
1933
.Ar filesystem@snapname Ns | Ns volume@snapname
1944
.Ar filesystem@snapname Ns | Ns volume@snapname
1934
.Ar filesystem@snapname Ns | Ns volume@snapname Ns ...
1945
.Ar filesystem@snapname Ns | Ns volume@snapname Ns ...

Return to bug 244465