7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2012 by Delphix. All rights reserved.
25 * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
26 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
27 */
28
29 #include <ctype.h>
30 #include <errno.h>
31 #include <libintl.h>
32 #include <math.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <strings.h>
36 #include <unistd.h>
37 #include <stddef.h>
38 #include <zone.h>
39 #include <fcntl.h>
40 #include <sys/mntent.h>
41 #include <sys/mount.h>
42 #include <priv.h>
43 #include <pwd.h>
44 #include <grp.h>
45 #include <stddef.h>
46 #include <ucred.h>
4099 zfs_close(zhp);
4100 return (rv);
4101 }
4102
4103 int
4104 zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
4105 boolean_t recursive, boolean_t enoent_ok, int cleanup_fd)
4106 {
4107 int ret;
4108 struct holdarg ha;
4109 nvlist_t *errors;
4110 libzfs_handle_t *hdl = zhp->zfs_hdl;
4111 char errbuf[1024];
4112 nvpair_t *elem;
4113
4114 ha.nvl = fnvlist_alloc();
4115 ha.snapname = snapname;
4116 ha.tag = tag;
4117 ha.recursive = recursive;
4118 (void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
4119 ret = lzc_hold(ha.nvl, cleanup_fd, &errors);
4120 fnvlist_free(ha.nvl);
4121
4122 if (ret == 0)
4123 return (0);
4124
4125 if (nvlist_next_nvpair(errors, NULL) == NULL) {
4126 /* no hold-specific errors */
4127 (void) snprintf(errbuf, sizeof (errbuf),
4128 dgettext(TEXT_DOMAIN, "cannot hold"));
4129 switch (ret) {
4130 case ENOTSUP:
4131 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4132 "pool must be upgraded"));
4133 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4134 break;
4135 case EINVAL:
4136 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4137 break;
4138 default:
4200 fnvlist_add_boolean(holds, ha->tag);
4201 fnvlist_add_nvlist(ha->nvl, name, holds);
4202 zfs_close(szhp);
4203 }
4204
4205 if (ha->recursive)
4206 rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
4207 zfs_close(zhp);
4208 return (rv);
4209 }
4210
4211 int
4212 zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
4213 boolean_t recursive)
4214 {
4215 int ret;
4216 struct holdarg ha;
4217 nvlist_t *errors;
4218 nvpair_t *elem;
4219 libzfs_handle_t *hdl = zhp->zfs_hdl;
4220
4221 ha.nvl = fnvlist_alloc();
4222 ha.snapname = snapname;
4223 ha.tag = tag;
4224 ha.recursive = recursive;
4225 (void) zfs_release_one(zfs_handle_dup(zhp), &ha);
4226 ret = lzc_release(ha.nvl, &errors);
4227 fnvlist_free(ha.nvl);
4228
4229 if (ret == 0)
4230 return (0);
4231
4232 if (nvlist_next_nvpair(errors, NULL) == NULL) {
4233 /* no hold-specific errors */
4234 char errbuf[1024];
4235
4236 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4237 "cannot release"));
4238 switch (errno) {
4239 case ENOTSUP:
4240 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4241 "pool must be upgraded"));
4242 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4243 break;
4244 default:
4245 (void) zfs_standard_error_fmt(hdl, errno, errbuf);
4246 }
4247 }
4248
4249 for (elem = nvlist_next_nvpair(errors, NULL);
4250 elem != NULL;
4251 elem = nvlist_next_nvpair(errors, elem)) {
4252 char errbuf[1024];
4253
4254 (void) snprintf(errbuf, sizeof (errbuf),
4255 dgettext(TEXT_DOMAIN,
4256 "cannot release hold from snapshot '%s'"),
4257 nvpair_name(elem));
4258 switch (fnvpair_value_int32(elem)) {
4259 case ESRCH:
4260 (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
4261 break;
4262 case EINVAL:
4263 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4264 break;
4265 default:
4266 (void) zfs_standard_error_fmt(hdl,
4267 fnvpair_value_int32(elem), errbuf);
4268 }
4269 }
4270
4271 fnvlist_free(errors);
4272 return (ret);
4273 }
|
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2012 by Delphix. All rights reserved.
25 * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
26 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
27 * Copyright (c) 2013 Martin Matuska. All rights reserved.
28 */
29
30 #include <ctype.h>
31 #include <errno.h>
32 #include <libintl.h>
33 #include <math.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <strings.h>
37 #include <unistd.h>
38 #include <stddef.h>
39 #include <zone.h>
40 #include <fcntl.h>
41 #include <sys/mntent.h>
42 #include <sys/mount.h>
43 #include <priv.h>
44 #include <pwd.h>
45 #include <grp.h>
46 #include <stddef.h>
47 #include <ucred.h>
4100 zfs_close(zhp);
4101 return (rv);
4102 }
4103
4104 int
4105 zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
4106 boolean_t recursive, boolean_t enoent_ok, int cleanup_fd)
4107 {
4108 int ret;
4109 struct holdarg ha;
4110 nvlist_t *errors;
4111 libzfs_handle_t *hdl = zhp->zfs_hdl;
4112 char errbuf[1024];
4113 nvpair_t *elem;
4114
4115 ha.nvl = fnvlist_alloc();
4116 ha.snapname = snapname;
4117 ha.tag = tag;
4118 ha.recursive = recursive;
4119 (void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
4120
4121 if (nvlist_next_nvpair(ha.nvl, NULL) == NULL) {
4122 fnvlist_free(ha.nvl);
4123 ret = ENOENT;
4124 if (!enoent_ok) {
4125 (void) snprintf(errbuf, sizeof (errbuf),
4126 dgettext(TEXT_DOMAIN,
4127 "cannot hold snapshot '%s@%s'"),
4128 zhp->zfs_name, snapname);
4129 (void) zfs_standard_error(hdl, ret, errbuf);
4130 }
4131 return (ret);
4132 }
4133
4134 ret = lzc_hold(ha.nvl, cleanup_fd, &errors);
4135 fnvlist_free(ha.nvl);
4136
4137 if (ret == 0)
4138 return (0);
4139
4140 if (nvlist_next_nvpair(errors, NULL) == NULL) {
4141 /* no hold-specific errors */
4142 (void) snprintf(errbuf, sizeof (errbuf),
4143 dgettext(TEXT_DOMAIN, "cannot hold"));
4144 switch (ret) {
4145 case ENOTSUP:
4146 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4147 "pool must be upgraded"));
4148 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4149 break;
4150 case EINVAL:
4151 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4152 break;
4153 default:
4215 fnvlist_add_boolean(holds, ha->tag);
4216 fnvlist_add_nvlist(ha->nvl, name, holds);
4217 zfs_close(szhp);
4218 }
4219
4220 if (ha->recursive)
4221 rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
4222 zfs_close(zhp);
4223 return (rv);
4224 }
4225
4226 int
4227 zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
4228 boolean_t recursive)
4229 {
4230 int ret;
4231 struct holdarg ha;
4232 nvlist_t *errors;
4233 nvpair_t *elem;
4234 libzfs_handle_t *hdl = zhp->zfs_hdl;
4235 char errbuf[1024];
4236
4237 ha.nvl = fnvlist_alloc();
4238 ha.snapname = snapname;
4239 ha.tag = tag;
4240 ha.recursive = recursive;
4241 (void) zfs_release_one(zfs_handle_dup(zhp), &ha);
4242
4243 if (nvlist_next_nvpair(ha.nvl, NULL) == NULL) {
4244 fnvlist_free(ha.nvl);
4245 ret = ENOENT;
4246 (void) snprintf(errbuf, sizeof (errbuf),
4247 dgettext(TEXT_DOMAIN,
4248 "cannot release hold from snapshot '%s@%s'"),
4249 zhp->zfs_name, snapname);
4250 (void) zfs_standard_error(hdl, ret, errbuf);
4251 return (ret);
4252 }
4253
4254 ret = lzc_release(ha.nvl, &errors);
4255 fnvlist_free(ha.nvl);
4256
4257 if (ret == 0)
4258 return (0);
4259
4260 if (nvlist_next_nvpair(errors, NULL) == NULL) {
4261 /* no hold-specific errors */
4262 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4263 "cannot release"));
4264 switch (errno) {
4265 case ENOTSUP:
4266 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4267 "pool must be upgraded"));
4268 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4269 break;
4270 default:
4271 (void) zfs_standard_error_fmt(hdl, errno, errbuf);
4272 }
4273 }
4274
4275 for (elem = nvlist_next_nvpair(errors, NULL);
4276 elem != NULL;
4277 elem = nvlist_next_nvpair(errors, elem)) {
4278 (void) snprintf(errbuf, sizeof (errbuf),
4279 dgettext(TEXT_DOMAIN,
4280 "cannot release hold from snapshot '%s'"),
4281 nvpair_name(elem));
4282 switch (fnvpair_value_int32(elem)) {
4283 case ESRCH:
4284 (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
4285 break;
4286 case EINVAL:
4287 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4288 break;
4289 default:
4290 (void) zfs_standard_error_fmt(hdl,
4291 fnvpair_value_int32(elem), errbuf);
4292 }
4293 }
4294
4295 fnvlist_free(errors);
4296 return (ret);
4297 }
|