1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2011 by Delphix. All rights reserved.
24 */
25
26 /*
27 * Internal utility routines for the ZFS library.
28 */
29
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <libintl.h>
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <strings.h>
37 #include <unistd.h>
38 #include <ctype.h>
39 #include <math.h>
40 #include <sys/mnttab.h>
41 #include <sys/mntent.h>
42 #include <sys/types.h>
43
44 #include <libzfs.h>
45
46 #include "libzfs_impl.h"
47 #include "zfs_prop.h"
48
49 int
50 libzfs_errno(libzfs_handle_t *hdl)
51 {
52 return (hdl->libzfs_error);
53 }
54
55 const char *
56 libzfs_error_action(libzfs_handle_t *hdl)
57 {
58 return (hdl->libzfs_action);
59 }
60
61 const char *
62 libzfs_error_description(libzfs_handle_t *hdl)
63 {
64 if (hdl->libzfs_desc[0] != '\0')
65 return (hdl->libzfs_desc);
66
67 switch (hdl->libzfs_error) {
95 return (dgettext(TEXT_DOMAIN, "volume size exceeds limit for "
96 "this system"));
97 case EZFS_INVALIDNAME:
98 return (dgettext(TEXT_DOMAIN, "invalid name"));
99 case EZFS_BADRESTORE:
100 return (dgettext(TEXT_DOMAIN, "unable to restore to "
101 "destination"));
102 case EZFS_BADBACKUP:
103 return (dgettext(TEXT_DOMAIN, "backup failed"));
104 case EZFS_BADTARGET:
105 return (dgettext(TEXT_DOMAIN, "invalid target vdev"));
106 case EZFS_NODEVICE:
107 return (dgettext(TEXT_DOMAIN, "no such device in pool"));
108 case EZFS_BADDEV:
109 return (dgettext(TEXT_DOMAIN, "invalid device"));
110 case EZFS_NOREPLICAS:
111 return (dgettext(TEXT_DOMAIN, "no valid replicas"));
112 case EZFS_RESILVERING:
113 return (dgettext(TEXT_DOMAIN, "currently resilvering"));
114 case EZFS_BADVERSION:
115 return (dgettext(TEXT_DOMAIN, "unsupported version"));
116 case EZFS_POOLUNAVAIL:
117 return (dgettext(TEXT_DOMAIN, "pool is unavailable"));
118 case EZFS_DEVOVERFLOW:
119 return (dgettext(TEXT_DOMAIN, "too many devices in one vdev"));
120 case EZFS_BADPATH:
121 return (dgettext(TEXT_DOMAIN, "must be an absolute path"));
122 case EZFS_CROSSTARGET:
123 return (dgettext(TEXT_DOMAIN, "operation crosses datasets or "
124 "pools"));
125 case EZFS_ZONED:
126 return (dgettext(TEXT_DOMAIN, "dataset in use by local zone"));
127 case EZFS_MOUNTFAILED:
128 return (dgettext(TEXT_DOMAIN, "mount failed"));
129 case EZFS_UMOUNTFAILED:
130 return (dgettext(TEXT_DOMAIN, "umount failed"));
131 case EZFS_UNSHARENFSFAILED:
132 return (dgettext(TEXT_DOMAIN, "unshare(1M) failed"));
133 case EZFS_SHARENFSFAILED:
134 return (dgettext(TEXT_DOMAIN, "share(1M) failed"));
135 case EZFS_UNSHARESMBFAILED:
612
613 if ((hdl = calloc(1, sizeof (libzfs_handle_t))) == NULL) {
614 return (NULL);
615 }
616
617 if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
618 free(hdl);
619 return (NULL);
620 }
621
622 if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) {
623 (void) close(hdl->libzfs_fd);
624 free(hdl);
625 return (NULL);
626 }
627
628 hdl->libzfs_sharetab = fopen("/etc/dfs/sharetab", "r");
629
630 zfs_prop_init();
631 zpool_prop_init();
632 libzfs_mnttab_init(hdl);
633
634 return (hdl);
635 }
636
637 void
638 libzfs_fini(libzfs_handle_t *hdl)
639 {
640 (void) close(hdl->libzfs_fd);
641 if (hdl->libzfs_mnttab)
642 (void) fclose(hdl->libzfs_mnttab);
643 if (hdl->libzfs_sharetab)
644 (void) fclose(hdl->libzfs_sharetab);
645 zfs_uninit_libshare(hdl);
646 if (hdl->libzfs_log_str)
647 (void) free(hdl->libzfs_log_str);
648 zpool_free_handles(hdl);
649 libzfs_fru_clear(hdl, B_TRUE);
650 namespace_clear(hdl);
651 libzfs_mnttab_fini(hdl);
1265 return (-1);
1266 }
1267
1268 static int
1269 addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
1270 zfs_type_t type)
1271 {
1272 int prop;
1273 zprop_list_t *entry;
1274
1275 prop = zprop_name_to_prop(propname, type);
1276
1277 if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type))
1278 prop = ZPROP_INVAL;
1279
1280 /*
1281 * When no property table entry can be found, return failure if
1282 * this is a pool property or if this isn't a user-defined
1283 * dataset property,
1284 */
1285 if (prop == ZPROP_INVAL && (type == ZFS_TYPE_POOL ||
1286 (!zfs_prop_user(propname) && !zfs_prop_userquota(propname) &&
1287 !zfs_prop_written(propname)))) {
1288 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1289 "invalid property '%s'"), propname);
1290 return (zfs_error(hdl, EZFS_BADPROP,
1291 dgettext(TEXT_DOMAIN, "bad property list")));
1292 }
1293
1294 if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
1295 return (-1);
1296
1297 entry->pl_prop = prop;
1298 if (prop == ZPROP_INVAL) {
1299 if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) == NULL) {
1300 free(entry);
1301 return (-1);
1302 }
1303 entry->pl_width = strlen(propname);
1304 } else {
1305 entry->pl_width = zprop_width(prop, &entry->pl_fixed,
1306 type);
1307 }
1308
1309 *listp = entry;
1310
1311 return (0);
1312 }
1313
1314 /*
1315 * Given a comma-separated list of properties, construct a property list
1316 * containing both user-defined and native properties. This function will
1317 * return a NULL list if 'all' is specified, which can later be expanded
1318 * by zprop_expand_list().
1319 */
|
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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 */
26
27 /*
28 * Internal utility routines for the ZFS library.
29 */
30
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <libintl.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <strings.h>
38 #include <unistd.h>
39 #include <ctype.h>
40 #include <math.h>
41 #include <sys/mnttab.h>
42 #include <sys/mntent.h>
43 #include <sys/types.h>
44
45 #include <libzfs.h>
46
47 #include "libzfs_impl.h"
48 #include "zfs_prop.h"
49 #include "zfeature_common.h"
50
51 int
52 libzfs_errno(libzfs_handle_t *hdl)
53 {
54 return (hdl->libzfs_error);
55 }
56
57 const char *
58 libzfs_error_action(libzfs_handle_t *hdl)
59 {
60 return (hdl->libzfs_action);
61 }
62
63 const char *
64 libzfs_error_description(libzfs_handle_t *hdl)
65 {
66 if (hdl->libzfs_desc[0] != '\0')
67 return (hdl->libzfs_desc);
68
69 switch (hdl->libzfs_error) {
97 return (dgettext(TEXT_DOMAIN, "volume size exceeds limit for "
98 "this system"));
99 case EZFS_INVALIDNAME:
100 return (dgettext(TEXT_DOMAIN, "invalid name"));
101 case EZFS_BADRESTORE:
102 return (dgettext(TEXT_DOMAIN, "unable to restore to "
103 "destination"));
104 case EZFS_BADBACKUP:
105 return (dgettext(TEXT_DOMAIN, "backup failed"));
106 case EZFS_BADTARGET:
107 return (dgettext(TEXT_DOMAIN, "invalid target vdev"));
108 case EZFS_NODEVICE:
109 return (dgettext(TEXT_DOMAIN, "no such device in pool"));
110 case EZFS_BADDEV:
111 return (dgettext(TEXT_DOMAIN, "invalid device"));
112 case EZFS_NOREPLICAS:
113 return (dgettext(TEXT_DOMAIN, "no valid replicas"));
114 case EZFS_RESILVERING:
115 return (dgettext(TEXT_DOMAIN, "currently resilvering"));
116 case EZFS_BADVERSION:
117 return (dgettext(TEXT_DOMAIN, "unsupported version or "
118 "feature"));
119 case EZFS_POOLUNAVAIL:
120 return (dgettext(TEXT_DOMAIN, "pool is unavailable"));
121 case EZFS_DEVOVERFLOW:
122 return (dgettext(TEXT_DOMAIN, "too many devices in one vdev"));
123 case EZFS_BADPATH:
124 return (dgettext(TEXT_DOMAIN, "must be an absolute path"));
125 case EZFS_CROSSTARGET:
126 return (dgettext(TEXT_DOMAIN, "operation crosses datasets or "
127 "pools"));
128 case EZFS_ZONED:
129 return (dgettext(TEXT_DOMAIN, "dataset in use by local zone"));
130 case EZFS_MOUNTFAILED:
131 return (dgettext(TEXT_DOMAIN, "mount failed"));
132 case EZFS_UMOUNTFAILED:
133 return (dgettext(TEXT_DOMAIN, "umount failed"));
134 case EZFS_UNSHARENFSFAILED:
135 return (dgettext(TEXT_DOMAIN, "unshare(1M) failed"));
136 case EZFS_SHARENFSFAILED:
137 return (dgettext(TEXT_DOMAIN, "share(1M) failed"));
138 case EZFS_UNSHARESMBFAILED:
615
616 if ((hdl = calloc(1, sizeof (libzfs_handle_t))) == NULL) {
617 return (NULL);
618 }
619
620 if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
621 free(hdl);
622 return (NULL);
623 }
624
625 if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) {
626 (void) close(hdl->libzfs_fd);
627 free(hdl);
628 return (NULL);
629 }
630
631 hdl->libzfs_sharetab = fopen("/etc/dfs/sharetab", "r");
632
633 zfs_prop_init();
634 zpool_prop_init();
635 zpool_feature_init();
636 libzfs_mnttab_init(hdl);
637
638 return (hdl);
639 }
640
641 void
642 libzfs_fini(libzfs_handle_t *hdl)
643 {
644 (void) close(hdl->libzfs_fd);
645 if (hdl->libzfs_mnttab)
646 (void) fclose(hdl->libzfs_mnttab);
647 if (hdl->libzfs_sharetab)
648 (void) fclose(hdl->libzfs_sharetab);
649 zfs_uninit_libshare(hdl);
650 if (hdl->libzfs_log_str)
651 (void) free(hdl->libzfs_log_str);
652 zpool_free_handles(hdl);
653 libzfs_fru_clear(hdl, B_TRUE);
654 namespace_clear(hdl);
655 libzfs_mnttab_fini(hdl);
1269 return (-1);
1270 }
1271
1272 static int
1273 addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
1274 zfs_type_t type)
1275 {
1276 int prop;
1277 zprop_list_t *entry;
1278
1279 prop = zprop_name_to_prop(propname, type);
1280
1281 if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type))
1282 prop = ZPROP_INVAL;
1283
1284 /*
1285 * When no property table entry can be found, return failure if
1286 * this is a pool property or if this isn't a user-defined
1287 * dataset property,
1288 */
1289 if (prop == ZPROP_INVAL && ((type == ZFS_TYPE_POOL &&
1290 !zpool_prop_feature(propname) &&
1291 !zpool_prop_unsupported(propname)) ||
1292 (type == ZFS_TYPE_DATASET && !zfs_prop_user(propname) &&
1293 !zfs_prop_userquota(propname) && !zfs_prop_written(propname)))) {
1294 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1295 "invalid property '%s'"), propname);
1296 return (zfs_error(hdl, EZFS_BADPROP,
1297 dgettext(TEXT_DOMAIN, "bad property list")));
1298 }
1299
1300 if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
1301 return (-1);
1302
1303 entry->pl_prop = prop;
1304 if (prop == ZPROP_INVAL) {
1305 if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) ==
1306 NULL) {
1307 free(entry);
1308 return (-1);
1309 }
1310 entry->pl_width = strlen(propname);
1311 } else {
1312 entry->pl_width = zprop_width(prop, &entry->pl_fixed,
1313 type);
1314 }
1315
1316 *listp = entry;
1317
1318 return (0);
1319 }
1320
1321 /*
1322 * Given a comma-separated list of properties, construct a property list
1323 * containing both user-defined and native properties. This function will
1324 * return a NULL list if 'all' is specified, which can later be expanded
1325 * by zprop_expand_list().
1326 */
|