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) |