63 static int zpool_do_online(int, char **);
64 static int zpool_do_offline(int, char **);
65 static int zpool_do_clear(int, char **);
66
67 static int zpool_do_attach(int, char **);
68 static int zpool_do_detach(int, char **);
69 static int zpool_do_replace(int, char **);
70
71 static int zpool_do_scrub(int, char **);
72
73 static int zpool_do_import(int, char **);
74 static int zpool_do_export(int, char **);
75
76 static int zpool_do_upgrade(int, char **);
77
78 static int zpool_do_history(int, char **);
79
80 static int zpool_do_get(int, char **);
81 static int zpool_do_set(int, char **);
82
83 /*
84 * These libumem hooks provide a reasonable set of defaults for the allocator's
85 * debugging facilities.
86 */
87
88 #ifdef DEBUG
89 const char *
90 _umem_debug_init(void)
91 {
92 return ("default,verbose"); /* $UMEM_DEBUG setting */
93 }
94
95 const char *
96 _umem_logging_init(void)
97 {
98 return ("fail,contents"); /* $UMEM_LOGGING setting */
99 }
100 #endif
101
102 typedef enum {
103 HELP_ADD,
104 HELP_ATTACH,
105 HELP_CLEAR,
106 HELP_CREATE,
107 HELP_DESTROY,
108 HELP_DETACH,
109 HELP_EXPORT,
110 HELP_HISTORY,
111 HELP_IMPORT,
112 HELP_IOSTAT,
113 HELP_LIST,
114 HELP_OFFLINE,
115 HELP_ONLINE,
116 HELP_REPLACE,
117 HELP_REMOVE,
118 HELP_SCRUB,
119 HELP_STATUS,
120 HELP_UPGRADE,
121 HELP_GET,
122 HELP_SET
123 } zpool_help_t;
124
125
126 typedef struct zpool_command {
127 const char *name;
128 int (*func)(int, char **);
129 zpool_help_t usage;
130 } zpool_command_t;
131
132 /*
133 * Master command table. Each ZFS command has a name, associated function, and
134 * usage message. The usage messages need to be internationalized, so we have
135 * to have a function to return the usage message based on a command index.
136 *
137 * These commands are organized according to how they are displayed in the usage
138 * message. An empty command (one with a NULL name) indicates an empty line in
139 * the generic usage message.
140 */
141 static zpool_command_t command_table[] = {
142 { "create", zpool_do_create, HELP_CREATE },
149 { "iostat", zpool_do_iostat, HELP_IOSTAT },
150 { "status", zpool_do_status, HELP_STATUS },
151 { NULL },
152 { "online", zpool_do_online, HELP_ONLINE },
153 { "offline", zpool_do_offline, HELP_OFFLINE },
154 { "clear", zpool_do_clear, HELP_CLEAR },
155 { NULL },
156 { "attach", zpool_do_attach, HELP_ATTACH },
157 { "detach", zpool_do_detach, HELP_DETACH },
158 { "replace", zpool_do_replace, HELP_REPLACE },
159 { NULL },
160 { "scrub", zpool_do_scrub, HELP_SCRUB },
161 { NULL },
162 { "import", zpool_do_import, HELP_IMPORT },
163 { "export", zpool_do_export, HELP_EXPORT },
164 { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
165 { NULL },
166 { "history", zpool_do_history, HELP_HISTORY },
167 { "get", zpool_do_get, HELP_GET },
168 { "set", zpool_do_set, HELP_SET },
169 };
170
171 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
172
173 zpool_command_t *current_command;
174 static char history_str[HIS_MAX_RECORD_LEN];
175
176 static const char *
177 get_usage(zpool_help_t idx) {
178 switch (idx) {
179 case HELP_ADD:
180 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
181 case HELP_ATTACH:
182 return (gettext("\tattach [-f] <pool> <device> "
183 "<new-device>\n"));
184 case HELP_CLEAR:
185 return (gettext("\tclear <pool> [device]\n"));
186 case HELP_CREATE:
187 return (gettext("\tcreate [-fn] [-o property=value] ... \n"
188 "\t [-O file-system-property=value] ... \n"
213 case HELP_ONLINE:
214 return (gettext("\tonline <pool> <device> ...\n"));
215 case HELP_REPLACE:
216 return (gettext("\treplace [-f] <pool> <device> "
217 "[new-device]\n"));
218 case HELP_REMOVE:
219 return (gettext("\tremove <pool> <device> ...\n"));
220 case HELP_SCRUB:
221 return (gettext("\tscrub [-s] <pool> ...\n"));
222 case HELP_STATUS:
223 return (gettext("\tstatus [-vx] [pool] ...\n"));
224 case HELP_UPGRADE:
225 return (gettext("\tupgrade\n"
226 "\tupgrade -v\n"
227 "\tupgrade [-V version] <-a | pool ...>\n"));
228 case HELP_GET:
229 return (gettext("\tget <\"all\" | property[,...]> "
230 "<pool> ...\n"));
231 case HELP_SET:
232 return (gettext("\tset <property=value> <pool> \n"));
233 }
234
235 abort();
236 /* NOTREACHED */
237 }
238
239
240 /*
241 * Callback routine that will print out a pool property value.
242 */
243 static int
244 print_prop_cb(int prop, void *cb)
245 {
246 FILE *fp = cb;
247
248 (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop));
249
250 if (zpool_prop_readonly(prop))
251 (void) fprintf(fp, " NO ");
252 else
790 nvlist_free(props);
791 return (ret);
792 badusage:
793 nvlist_free(fsprops);
794 nvlist_free(props);
795 usage(B_FALSE);
796 return (2);
797 }
798
799 /*
800 * zpool destroy <pool>
801 *
802 * -f Forcefully unmount any datasets
803 *
804 * Destroy the given pool. Automatically unmounts any datasets in the pool.
805 */
806 int
807 zpool_do_destroy(int argc, char **argv)
808 {
809 boolean_t force = B_FALSE;
810 int c;
811 char *pool;
812 zpool_handle_t *zhp;
813 int ret;
814
815 /* check options */
816 while ((c = getopt(argc, argv, "f")) != -1) {
817 switch (c) {
818 case 'f':
819 force = B_TRUE;
820 break;
821 case '?':
822 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
823 optopt);
824 usage(B_FALSE);
825 }
826 }
827
828 argc -= optind;
829 argv += optind;
834 usage(B_FALSE);
835 }
836 if (argc > 1) {
837 (void) fprintf(stderr, gettext("too many arguments\n"));
838 usage(B_FALSE);
839 }
840
841 pool = argv[0];
842
843 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
844 /*
845 * As a special case, check for use of '/' in the name, and
846 * direct the user to use 'zfs destroy' instead.
847 */
848 if (strchr(pool, '/') != NULL)
849 (void) fprintf(stderr, gettext("use 'zfs destroy' to "
850 "destroy a dataset\n"));
851 return (1);
852 }
853
854 if (zpool_disable_datasets(zhp, force) != 0) {
855 (void) fprintf(stderr, gettext("could not destroy '%s': "
856 "could not unmount datasets\n"), zpool_get_name(zhp));
857 return (1);
858 }
859
860 ret = (zpool_destroy(zhp) != 0);
861
862 zpool_close(zhp);
863
864 return (ret);
865 }
866
867 /*
868 * zpool export [-f] <pool> ...
869 *
870 * -f Forcefully unmount datasets
871 *
872 * Export the given pools. By default, the command will attempt to cleanly
873 * unmount any active datasets within the pool. If the '-f' flag is specified,
874 * then the datasets will be forcefully unmounted.
875 */
876 int
877 zpool_do_export(int argc, char **argv)
878 {
879 boolean_t force = B_FALSE;
880 boolean_t hardforce = B_FALSE;
881 int c;
882 zpool_handle_t *zhp;
883 int ret;
884 int i;
885
886 /* check options */
887 while ((c = getopt(argc, argv, "fF")) != -1) {
888 switch (c) {
889 case 'f':
890 force = B_TRUE;
891 break;
892 case 'F':
893 hardforce = B_TRUE;
894 break;
895 case '?':
896 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
897 optopt);
898 usage(B_FALSE);
899 }
900 }
901
902 argc -= optind;
903 argv += optind;
904
905 /* check arguments */
906 if (argc < 1) {
907 (void) fprintf(stderr, gettext("missing pool argument\n"));
908 usage(B_FALSE);
909 }
910
911 ret = 0;
912 for (i = 0; i < argc; i++) {
913 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
914 ret = 1;
915 continue;
916 }
917
918 if (zpool_disable_datasets(zhp, force) != 0) {
919 ret = 1;
920 zpool_close(zhp);
921 continue;
922 }
923
924 if (hardforce) {
925 if (zpool_export_force(zhp) != 0)
926 ret = 1;
927 } else if (zpool_export(zhp, force) != 0) {
928 ret = 1;
929 }
930
931 zpool_close(zhp);
932 }
933
934 return (ret);
935 }
936
937 /*
938 * Given a vdev configuration, determine the maximum width needed for the device
1246 (void) printf(gettext("\tlogs\n"));
1247 print_import_config(name, nvroot, namewidth, 0, B_TRUE);
1248 }
1249
1250 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1251 (void) printf(gettext("\n\tAdditional devices are known to "
1252 "be part of this pool, though their\n\texact "
1253 "configuration cannot be determined.\n"));
1254 }
1255 }
1256
1257 /*
1258 * Perform the import for the given configuration. This passes the heavy
1259 * lifting off to zpool_import_props(), and then mounts the datasets contained
1260 * within the pool.
1261 */
1262 static int
1263 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1264 int force, nvlist_t *props, boolean_t allowfaulted)
1265 {
1266 zpool_handle_t *zhp;
1267 char *name;
1268 uint64_t state;
1269 uint64_t version;
1270 int error = 0;
1271
1272 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1273 &name) == 0);
1274
1275 verify(nvlist_lookup_uint64(config,
1276 ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1277 verify(nvlist_lookup_uint64(config,
1278 ZPOOL_CONFIG_VERSION, &version) == 0);
1279 if (version > SPA_VERSION) {
1280 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1281 "is formatted using a newer ZFS version\n"), name);
1282 return (1);
1283 } else if (state != POOL_STATE_EXPORTED && !force) {
1284 uint64_t hostid;
1285
1306 return (1);
1307 }
1308 } else {
1309 (void) fprintf(stderr, gettext("cannot import '%s': "
1310 "pool may be in use from other system\n"), name);
1311 (void) fprintf(stderr, gettext("use '-f' to import "
1312 "anyway\n"));
1313 return (1);
1314 }
1315 }
1316
1317 if (zpool_import_props(g_zfs, config, newname, props,
1318 allowfaulted) != 0)
1319 return (1);
1320
1321 if (newname != NULL)
1322 name = (char *)newname;
1323
1324 verify((zhp = zpool_open_canfail(g_zfs, name)) != NULL);
1325
1326 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1327 zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1328 zpool_close(zhp);
1329 return (1);
1330 }
1331
1332 zpool_close(zhp);
1333 return (error);
1334 }
1335
1336 /*
1337 * zpool import [-d dir] [-D]
1338 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1339 * [-d dir | -c cachefile] [-f] -a
1340 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1341 * [-d dir | -c cachefile] [-f] <pool | id> [newpool]
1342 *
1343 * -c Read pool information from a cachefile instead of searching
1344 * devices.
1345 *
1346 * -d Scan in a specific directory, other than /dev/dsk. More than
1347 * one directory can be specified using multiple '-d' options.
1348 *
1349 * -D Scan for previously destroyed pools or import all or only
1350 * specified destroyed pools.
1351 *
1352 * -R Temporarily import the pool, with all mountpoints relative to
1353 * the given root. The pool will remain exported when the machine
2973 * reason: One or more devices ...
2974 * see: http://www.sun.com/msg/ZFS-xxxx-01
2975 * config:
2976 * mirror DEGRADED
2977 * c1t0d0 OK
2978 * c2t0d0 UNAVAIL
2979 *
2980 * When given the '-v' option, we print out the complete config. If the '-e'
2981 * option is specified, then we print out error rate information as well.
2982 */
2983 int
2984 status_callback(zpool_handle_t *zhp, void *data)
2985 {
2986 status_cbdata_t *cbp = data;
2987 nvlist_t *config, *nvroot;
2988 char *msgid;
2989 int reason;
2990 const char *health;
2991 uint_t c;
2992 vdev_stat_t *vs;
2993
2994 config = zpool_get_config(zhp, NULL);
2995 reason = zpool_get_status(zhp, &msgid);
2996
2997 cbp->cb_count++;
2998
2999 /*
3000 * If we were given 'zpool status -x', only report those pools with
3001 * problems.
3002 */
3003 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3004 if (!cbp->cb_allpools) {
3005 (void) printf(gettext("pool '%s' is healthy\n"),
3006 zpool_get_name(zhp));
3007 if (cbp->cb_first)
3008 cbp->cb_first = B_FALSE;
3009 }
3010 return (0);
3011 }
3012
3013 if (cbp->cb_first)
3014 cbp->cb_first = B_FALSE;
3015 else
3016 (void) printf("\n");
3017
3018 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3019 &nvroot) == 0);
3020 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
3021 (uint64_t **)&vs, &c) == 0);
3022 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3023
3024 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
3025 (void) printf(gettext(" state: %s\n"), health);
3026
3027 switch (reason) {
3028 case ZPOOL_STATUS_MISSING_DEV_R:
3029 (void) printf(gettext("status: One or more devices could not "
3030 "be opened. Sufficient replicas exist for\n\tthe pool to "
3031 "continue functioning in a degraded state.\n"));
3032 (void) printf(gettext("action: Attach the missing device and "
3033 "online it using 'zpool online'.\n"));
3034 break;
3035
3036 case ZPOOL_STATUS_MISSING_DEV_NR:
3037 (void) printf(gettext("status: One or more devices could not "
3038 "be opened. There are insufficient\n\treplicas for the "
3039 "pool to continue functioning.\n"));
3040 (void) printf(gettext("action: Attach the missing device and "
3041 "online it using 'zpool online'.\n"));
3042 break;
3043
3044 case ZPOOL_STATUS_CORRUPT_LABEL_R:
3045 (void) printf(gettext("status: One or more devices could not "
3046 "be used because the label is missing or\n\tinvalid. "
3480 "---------------\n");
3481 (void) printf(gettext(" 1 Initial ZFS version\n"));
3482 (void) printf(gettext(" 2 Ditto blocks "
3483 "(replicated metadata)\n"));
3484 (void) printf(gettext(" 3 Hot spares and double parity "
3485 "RAID-Z\n"));
3486 (void) printf(gettext(" 4 zpool history\n"));
3487 (void) printf(gettext(" 5 Compression using the gzip "
3488 "algorithm\n"));
3489 (void) printf(gettext(" 6 bootfs pool property\n"));
3490 (void) printf(gettext(" 7 Separate intent log devices\n"));
3491 (void) printf(gettext(" 8 Delegated administration\n"));
3492 (void) printf(gettext(" 9 refquota and refreservation "
3493 "properties\n"));
3494 (void) printf(gettext(" 10 Cache devices\n"));
3495 (void) printf(gettext(" 11 Improved scrub performance\n"));
3496 (void) printf(gettext(" 12 Snapshot properties\n"));
3497 (void) printf(gettext(" 13 snapused property\n"));
3498 (void) printf(gettext(" 14 passthrough-x aclinherit "
3499 "support\n"));
3500 (void) printf(gettext("For more information on a particular "
3501 "version, including supported releases, see:\n\n"));
3502 (void) printf("http://www.opensolaris.org/os/community/zfs/"
3503 "version/N\n\n");
3504 (void) printf(gettext("Where 'N' is the version number.\n"));
3505 } else if (argc == 0) {
3506 int notfound;
3507
3508 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3509 notfound = cb.cb_first;
3510
3511 if (!cb.cb_all && ret == 0) {
3512 if (!cb.cb_first)
3513 (void) printf("\n");
3514 cb.cb_first = B_TRUE;
3515 cb.cb_newer = B_TRUE;
3516 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3517 if (!cb.cb_first) {
3518 notfound = B_FALSE;
3519 (void) printf("\n");
3565 "destroy",
3566 "destroy_begin_sync",
3567 "inherit",
3568 "property set",
3569 "quota set",
3570 "permission update",
3571 "permission remove",
3572 "permission who remove",
3573 "promote",
3574 "receive",
3575 "rename",
3576 "reservation set",
3577 "replay_inc_sync",
3578 "replay_full_sync",
3579 "rollback",
3580 "snapshot",
3581 "filesystem version upgrade",
3582 "refquota set",
3583 "refreservation set",
3584 "pool scrub done",
3585 };
3586
3587 /*
3588 * Print out the command history for a specific pool.
3589 */
3590 static int
3591 get_history_one(zpool_handle_t *zhp, void *data)
3592 {
3593 nvlist_t *nvhis;
3594 nvlist_t **records;
3595 uint_t numrecords;
3596 char *cmdstr;
3597 char *pathstr;
3598 uint64_t dst_time;
3599 time_t tsec;
3600 struct tm t;
3601 char tbuf[30];
3602 int ret, i;
3603 uint64_t who;
3604 struct passwd *pwd;
3794 zprop_free_list(fake_name.pl_next);
3795 else
3796 zprop_free_list(cb.cb_proplist);
3797
3798 return (ret);
3799 }
3800
3801 typedef struct set_cbdata {
3802 char *cb_propname;
3803 char *cb_value;
3804 boolean_t cb_any_successful;
3805 } set_cbdata_t;
3806
3807 int
3808 set_callback(zpool_handle_t *zhp, void *data)
3809 {
3810 int error;
3811 set_cbdata_t *cb = (set_cbdata_t *)data;
3812
3813 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3814
3815 if (!error)
3816 cb->cb_any_successful = B_TRUE;
3817
3818 return (error);
3819 }
3820
3821 int
3822 zpool_do_set(int argc, char **argv)
3823 {
3824 set_cbdata_t cb = { 0 };
3825 int error;
3826
3827 if (argc > 1 && argv[1][0] == '-') {
3828 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3829 argv[1][1]);
3830 usage(B_FALSE);
3831 }
3832
3833 if (argc < 2) {
3834 (void) fprintf(stderr, gettext("missing property=value "
3846 usage(B_FALSE);
3847 }
3848
3849 cb.cb_propname = argv[1];
3850 cb.cb_value = strchr(cb.cb_propname, '=');
3851 if (cb.cb_value == NULL) {
3852 (void) fprintf(stderr, gettext("missing value in "
3853 "property=value argument\n"));
3854 usage(B_FALSE);
3855 }
3856
3857 *(cb.cb_value) = '\0';
3858 cb.cb_value++;
3859
3860 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3861 set_callback, &cb);
3862
3863 return (error);
3864 }
3865
3866 static int
3867 find_command_idx(char *command, int *idx)
3868 {
3869 int i;
3870
3871 for (i = 0; i < NCOMMAND; i++) {
3872 if (command_table[i].name == NULL)
3873 continue;
3874
3875 if (strcmp(command, command_table[i].name) == 0) {
3876 *idx = i;
3877 return (0);
3878 }
3879 }
3880 return (1);
3881 }
3882
3883 int
3884 main(int argc, char **argv)
3885 {
|
63 static int zpool_do_online(int, char **);
64 static int zpool_do_offline(int, char **);
65 static int zpool_do_clear(int, char **);
66
67 static int zpool_do_attach(int, char **);
68 static int zpool_do_detach(int, char **);
69 static int zpool_do_replace(int, char **);
70
71 static int zpool_do_scrub(int, char **);
72
73 static int zpool_do_import(int, char **);
74 static int zpool_do_export(int, char **);
75
76 static int zpool_do_upgrade(int, char **);
77
78 static int zpool_do_history(int, char **);
79
80 static int zpool_do_get(int, char **);
81 static int zpool_do_set(int, char **);
82
83 static int zpool_do_key(int, char **);
84
85 /*
86 * These libumem hooks provide a reasonable set of defaults for the allocator's
87 * debugging facilities.
88 */
89
90 #ifdef DEBUG
91 const char *
92 _umem_debug_init(void)
93 {
94 return ("default,verbose"); /* $UMEM_DEBUG setting */
95 }
96
97 const char *
98 _umem_logging_init(void)
99 {
100 return ("fail,contents"); /* $UMEM_LOGGING setting */
101 }
102 #endif
103
104 typedef enum {
105 HELP_ADD,
106 HELP_ATTACH,
107 HELP_CLEAR,
108 HELP_CREATE,
109 HELP_DESTROY,
110 HELP_DETACH,
111 HELP_EXPORT,
112 HELP_HISTORY,
113 HELP_IMPORT,
114 HELP_IOSTAT,
115 HELP_LIST,
116 HELP_OFFLINE,
117 HELP_ONLINE,
118 HELP_REPLACE,
119 HELP_REMOVE,
120 HELP_SCRUB,
121 HELP_STATUS,
122 HELP_UPGRADE,
123 HELP_GET,
124 HELP_SET,
125 HELP_KEY
126 } zpool_help_t;
127
128
129 typedef struct zpool_command {
130 const char *name;
131 int (*func)(int, char **);
132 zpool_help_t usage;
133 } zpool_command_t;
134
135 /*
136 * Master command table. Each ZFS command has a name, associated function, and
137 * usage message. The usage messages need to be internationalized, so we have
138 * to have a function to return the usage message based on a command index.
139 *
140 * These commands are organized according to how they are displayed in the usage
141 * message. An empty command (one with a NULL name) indicates an empty line in
142 * the generic usage message.
143 */
144 static zpool_command_t command_table[] = {
145 { "create", zpool_do_create, HELP_CREATE },
152 { "iostat", zpool_do_iostat, HELP_IOSTAT },
153 { "status", zpool_do_status, HELP_STATUS },
154 { NULL },
155 { "online", zpool_do_online, HELP_ONLINE },
156 { "offline", zpool_do_offline, HELP_OFFLINE },
157 { "clear", zpool_do_clear, HELP_CLEAR },
158 { NULL },
159 { "attach", zpool_do_attach, HELP_ATTACH },
160 { "detach", zpool_do_detach, HELP_DETACH },
161 { "replace", zpool_do_replace, HELP_REPLACE },
162 { NULL },
163 { "scrub", zpool_do_scrub, HELP_SCRUB },
164 { NULL },
165 { "import", zpool_do_import, HELP_IMPORT },
166 { "export", zpool_do_export, HELP_EXPORT },
167 { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
168 { NULL },
169 { "history", zpool_do_history, HELP_HISTORY },
170 { "get", zpool_do_get, HELP_GET },
171 { "set", zpool_do_set, HELP_SET },
172 { NULL },
173 { "key", zpool_do_key, HELP_KEY },
174 };
175
176 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
177
178 zpool_command_t *current_command;
179 static char history_str[HIS_MAX_RECORD_LEN];
180
181 static const char *
182 get_usage(zpool_help_t idx) {
183 switch (idx) {
184 case HELP_ADD:
185 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
186 case HELP_ATTACH:
187 return (gettext("\tattach [-f] <pool> <device> "
188 "<new-device>\n"));
189 case HELP_CLEAR:
190 return (gettext("\tclear <pool> [device]\n"));
191 case HELP_CREATE:
192 return (gettext("\tcreate [-fn] [-o property=value] ... \n"
193 "\t [-O file-system-property=value] ... \n"
218 case HELP_ONLINE:
219 return (gettext("\tonline <pool> <device> ...\n"));
220 case HELP_REPLACE:
221 return (gettext("\treplace [-f] <pool> <device> "
222 "[new-device]\n"));
223 case HELP_REMOVE:
224 return (gettext("\tremove <pool> <device> ...\n"));
225 case HELP_SCRUB:
226 return (gettext("\tscrub [-s] <pool> ...\n"));
227 case HELP_STATUS:
228 return (gettext("\tstatus [-vx] [pool] ...\n"));
229 case HELP_UPGRADE:
230 return (gettext("\tupgrade\n"
231 "\tupgrade -v\n"
232 "\tupgrade [-V version] <-a | pool ...>\n"));
233 case HELP_GET:
234 return (gettext("\tget <\"all\" | property[,...]> "
235 "<pool> ...\n"));
236 case HELP_SET:
237 return (gettext("\tset <property=value> <pool> \n"));
238 case HELP_KEY:
239 return (gettext("\tkey <-l | -u | -c [ -o <property=value>]> "
240 "<-a | pool>\n"));
241 }
242
243 abort();
244 /* NOTREACHED */
245 }
246
247
248 /*
249 * Callback routine that will print out a pool property value.
250 */
251 static int
252 print_prop_cb(int prop, void *cb)
253 {
254 FILE *fp = cb;
255
256 (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop));
257
258 if (zpool_prop_readonly(prop))
259 (void) fprintf(fp, " NO ");
260 else
798 nvlist_free(props);
799 return (ret);
800 badusage:
801 nvlist_free(fsprops);
802 nvlist_free(props);
803 usage(B_FALSE);
804 return (2);
805 }
806
807 /*
808 * zpool destroy <pool>
809 *
810 * -f Forcefully unmount any datasets
811 *
812 * Destroy the given pool. Automatically unmounts any datasets in the pool.
813 */
814 int
815 zpool_do_destroy(int argc, char **argv)
816 {
817 boolean_t force = B_FALSE;
818 boolean_t encrypted_only = B_FALSE;
819 int c;
820 char *pool;
821 zpool_handle_t *zhp;
822 int ret;
823
824 /* check options */
825 while ((c = getopt(argc, argv, "f")) != -1) {
826 switch (c) {
827 case 'f':
828 force = B_TRUE;
829 break;
830 case '?':
831 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
832 optopt);
833 usage(B_FALSE);
834 }
835 }
836
837 argc -= optind;
838 argv += optind;
843 usage(B_FALSE);
844 }
845 if (argc > 1) {
846 (void) fprintf(stderr, gettext("too many arguments\n"));
847 usage(B_FALSE);
848 }
849
850 pool = argv[0];
851
852 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
853 /*
854 * As a special case, check for use of '/' in the name, and
855 * direct the user to use 'zfs destroy' instead.
856 */
857 if (strchr(pool, '/') != NULL)
858 (void) fprintf(stderr, gettext("use 'zfs destroy' to "
859 "destroy a dataset\n"));
860 return (1);
861 }
862
863 if (zpool_disable_datasets(zhp, force, encrypted_only) != 0) {
864 (void) fprintf(stderr, gettext("could not destroy '%s': "
865 "could not unmount datasets\n"), zpool_get_name(zhp));
866 return (1);
867 }
868
869 ret = (zpool_destroy(zhp) != 0);
870
871 zpool_close(zhp);
872
873 return (ret);
874 }
875
876 /*
877 * zpool export [-f] <pool> ...
878 *
879 * -f Forcefully unmount datasets
880 *
881 * Export the given pools. By default, the command will attempt to cleanly
882 * unmount any active datasets within the pool. If the '-f' flag is specified,
883 * then the datasets will be forcefully unmounted.
884 */
885 int
886 zpool_do_export(int argc, char **argv)
887 {
888 boolean_t force = B_FALSE;
889 boolean_t hardforce = B_FALSE;
890 boolean_t encrypted_only = B_FALSE;
891 int c;
892 zpool_handle_t *zhp;
893 int ret;
894 int i;
895
896 /* check options */
897 while ((c = getopt(argc, argv, "fF")) != -1) {
898 switch (c) {
899 case 'f':
900 force = B_TRUE;
901 break;
902 case 'F':
903 hardforce = B_TRUE;
904 break;
905 case '?':
906 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
907 optopt);
908 usage(B_FALSE);
909 }
910 }
911
912 argc -= optind;
913 argv += optind;
914
915 /* check arguments */
916 if (argc < 1) {
917 (void) fprintf(stderr, gettext("missing pool argument\n"));
918 usage(B_FALSE);
919 }
920
921 ret = 0;
922 for (i = 0; i < argc; i++) {
923 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
924 ret = 1;
925 continue;
926 }
927
928 if (zpool_disable_datasets(zhp, force, encrypted_only) != 0) {
929 ret = 1;
930 zpool_close(zhp);
931 continue;
932 }
933
934 if (hardforce) {
935 if (zpool_export_force(zhp) != 0)
936 ret = 1;
937 } else if (zpool_export(zhp, force) != 0) {
938 ret = 1;
939 }
940
941 zpool_close(zhp);
942 }
943
944 return (ret);
945 }
946
947 /*
948 * Given a vdev configuration, determine the maximum width needed for the device
1256 (void) printf(gettext("\tlogs\n"));
1257 print_import_config(name, nvroot, namewidth, 0, B_TRUE);
1258 }
1259
1260 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1261 (void) printf(gettext("\n\tAdditional devices are known to "
1262 "be part of this pool, though their\n\texact "
1263 "configuration cannot be determined.\n"));
1264 }
1265 }
1266
1267 /*
1268 * Perform the import for the given configuration. This passes the heavy
1269 * lifting off to zpool_import_props(), and then mounts the datasets contained
1270 * within the pool.
1271 */
1272 static int
1273 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1274 int force, nvlist_t *props, boolean_t allowfaulted)
1275 {
1276 boolean_t encrypted_only = B_FALSE;
1277 zpool_handle_t *zhp;
1278 char *name;
1279 uint64_t state;
1280 uint64_t version;
1281 int error = 0;
1282
1283 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1284 &name) == 0);
1285
1286 verify(nvlist_lookup_uint64(config,
1287 ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1288 verify(nvlist_lookup_uint64(config,
1289 ZPOOL_CONFIG_VERSION, &version) == 0);
1290 if (version > SPA_VERSION) {
1291 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1292 "is formatted using a newer ZFS version\n"), name);
1293 return (1);
1294 } else if (state != POOL_STATE_EXPORTED && !force) {
1295 uint64_t hostid;
1296
1317 return (1);
1318 }
1319 } else {
1320 (void) fprintf(stderr, gettext("cannot import '%s': "
1321 "pool may be in use from other system\n"), name);
1322 (void) fprintf(stderr, gettext("use '-f' to import "
1323 "anyway\n"));
1324 return (1);
1325 }
1326 }
1327
1328 if (zpool_import_props(g_zfs, config, newname, props,
1329 allowfaulted) != 0)
1330 return (1);
1331
1332 if (newname != NULL)
1333 name = (char *)newname;
1334
1335 verify((zhp = zpool_open_canfail(g_zfs, name)) != NULL);
1336
1337 /*
1338 * Attempt to load the crypto keys before mounting up the datasets
1339 * Note that depending on the value of the keysource property
1340 * this could cause us to go interactive.
1341 * We don't mind if this falls though and continue to enable what
1342 * datasets we can if it does.
1343 *
1344 * Use zpool_load_key() and tell it we are doing an import rather than
1345 * zpool_cmd_key_load().
1346 *
1347 * We then attempt enable all datasets not just the encrypted ones.
1348 */
1349
1350 error = zpool_load_key(zhp, B_TRUE);
1351 if (error != 0 && error != ENOTSUP) {
1352 libzfs_handle_t *zpool_hdl = zpool_get_handle(zhp);
1353 (void) fprintf(stderr, gettext(
1354 "%s.\nEncrypted datasets with keyscope=pool "
1355 "will not be mounted.\n"),
1356 libzfs_error_description(zpool_hdl));
1357 }
1358
1359 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1360 zpool_enable_datasets(zhp, mntopts, 0, encrypted_only) != 0) {
1361 zpool_close(zhp);
1362 return (1);
1363 }
1364
1365 zpool_close(zhp);
1366 return (0);
1367 }
1368
1369 /*
1370 * zpool import [-d dir] [-D]
1371 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1372 * [-d dir | -c cachefile] [-f] -a
1373 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1374 * [-d dir | -c cachefile] [-f] <pool | id> [newpool]
1375 *
1376 * -c Read pool information from a cachefile instead of searching
1377 * devices.
1378 *
1379 * -d Scan in a specific directory, other than /dev/dsk. More than
1380 * one directory can be specified using multiple '-d' options.
1381 *
1382 * -D Scan for previously destroyed pools or import all or only
1383 * specified destroyed pools.
1384 *
1385 * -R Temporarily import the pool, with all mountpoints relative to
1386 * the given root. The pool will remain exported when the machine
3006 * reason: One or more devices ...
3007 * see: http://www.sun.com/msg/ZFS-xxxx-01
3008 * config:
3009 * mirror DEGRADED
3010 * c1t0d0 OK
3011 * c2t0d0 UNAVAIL
3012 *
3013 * When given the '-v' option, we print out the complete config. If the '-e'
3014 * option is specified, then we print out error rate information as well.
3015 */
3016 int
3017 status_callback(zpool_handle_t *zhp, void *data)
3018 {
3019 status_cbdata_t *cbp = data;
3020 nvlist_t *config, *nvroot;
3021 char *msgid;
3022 int reason;
3023 const char *health;
3024 uint_t c;
3025 vdev_stat_t *vs;
3026 char keystatus[MAXNAMELEN];
3027 zprop_source_t srctype;
3028
3029 config = zpool_get_config(zhp, NULL);
3030 reason = zpool_get_status(zhp, &msgid);
3031
3032 cbp->cb_count++;
3033
3034 /*
3035 * If we were given 'zpool status -x', only report those pools with
3036 * problems.
3037 */
3038 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3039 if (!cbp->cb_allpools) {
3040 (void) printf(gettext("pool '%s' is healthy\n"),
3041 zpool_get_name(zhp));
3042 if (cbp->cb_first)
3043 cbp->cb_first = B_FALSE;
3044 }
3045 return (0);
3046 }
3047
3048 if (cbp->cb_first)
3049 cbp->cb_first = B_FALSE;
3050 else
3051 (void) printf("\n");
3052
3053 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3054 &nvroot) == 0);
3055 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
3056 (uint64_t **)&vs, &c) == 0);
3057 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3058
3059 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
3060 (void) printf(gettext(" state: %s\n"), health);
3061
3062 (void) zpool_get_prop(zhp, ZPOOL_PROP_KEYSTATUS, keystatus,
3063 sizeof (keystatus), &srctype);
3064
3065 (void) printf(gettext(" key: %s\n"), keystatus);
3066
3067 switch (reason) {
3068 case ZPOOL_STATUS_MISSING_DEV_R:
3069 (void) printf(gettext("status: One or more devices could not "
3070 "be opened. Sufficient replicas exist for\n\tthe pool to "
3071 "continue functioning in a degraded state.\n"));
3072 (void) printf(gettext("action: Attach the missing device and "
3073 "online it using 'zpool online'.\n"));
3074 break;
3075
3076 case ZPOOL_STATUS_MISSING_DEV_NR:
3077 (void) printf(gettext("status: One or more devices could not "
3078 "be opened. There are insufficient\n\treplicas for the "
3079 "pool to continue functioning.\n"));
3080 (void) printf(gettext("action: Attach the missing device and "
3081 "online it using 'zpool online'.\n"));
3082 break;
3083
3084 case ZPOOL_STATUS_CORRUPT_LABEL_R:
3085 (void) printf(gettext("status: One or more devices could not "
3086 "be used because the label is missing or\n\tinvalid. "
3520 "---------------\n");
3521 (void) printf(gettext(" 1 Initial ZFS version\n"));
3522 (void) printf(gettext(" 2 Ditto blocks "
3523 "(replicated metadata)\n"));
3524 (void) printf(gettext(" 3 Hot spares and double parity "
3525 "RAID-Z\n"));
3526 (void) printf(gettext(" 4 zpool history\n"));
3527 (void) printf(gettext(" 5 Compression using the gzip "
3528 "algorithm\n"));
3529 (void) printf(gettext(" 6 bootfs pool property\n"));
3530 (void) printf(gettext(" 7 Separate intent log devices\n"));
3531 (void) printf(gettext(" 8 Delegated administration\n"));
3532 (void) printf(gettext(" 9 refquota and refreservation "
3533 "properties\n"));
3534 (void) printf(gettext(" 10 Cache devices\n"));
3535 (void) printf(gettext(" 11 Improved scrub performance\n"));
3536 (void) printf(gettext(" 12 Snapshot properties\n"));
3537 (void) printf(gettext(" 13 snapused property\n"));
3538 (void) printf(gettext(" 14 passthrough-x aclinherit "
3539 "support\n"));
3540 (void) printf(gettext(" 15 Cryptographic support.\n"));
3541 (void) printf(gettext("For more information on a particular "
3542 "version, including supported releases, see:\n\n"));
3543 (void) printf("http://www.opensolaris.org/os/community/zfs/"
3544 "version/N\n\n");
3545 (void) printf(gettext("Where 'N' is the version number.\n"));
3546 } else if (argc == 0) {
3547 int notfound;
3548
3549 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3550 notfound = cb.cb_first;
3551
3552 if (!cb.cb_all && ret == 0) {
3553 if (!cb.cb_first)
3554 (void) printf("\n");
3555 cb.cb_first = B_TRUE;
3556 cb.cb_newer = B_TRUE;
3557 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3558 if (!cb.cb_first) {
3559 notfound = B_FALSE;
3560 (void) printf("\n");
3606 "destroy",
3607 "destroy_begin_sync",
3608 "inherit",
3609 "property set",
3610 "quota set",
3611 "permission update",
3612 "permission remove",
3613 "permission who remove",
3614 "promote",
3615 "receive",
3616 "rename",
3617 "reservation set",
3618 "replay_inc_sync",
3619 "replay_full_sync",
3620 "rollback",
3621 "snapshot",
3622 "filesystem version upgrade",
3623 "refquota set",
3624 "refreservation set",
3625 "pool scrub done",
3626 "crypto key create",
3627 };
3628
3629 /*
3630 * Print out the command history for a specific pool.
3631 */
3632 static int
3633 get_history_one(zpool_handle_t *zhp, void *data)
3634 {
3635 nvlist_t *nvhis;
3636 nvlist_t **records;
3637 uint_t numrecords;
3638 char *cmdstr;
3639 char *pathstr;
3640 uint64_t dst_time;
3641 time_t tsec;
3642 struct tm t;
3643 char tbuf[30];
3644 int ret, i;
3645 uint64_t who;
3646 struct passwd *pwd;
3836 zprop_free_list(fake_name.pl_next);
3837 else
3838 zprop_free_list(cb.cb_proplist);
3839
3840 return (ret);
3841 }
3842
3843 typedef struct set_cbdata {
3844 char *cb_propname;
3845 char *cb_value;
3846 boolean_t cb_any_successful;
3847 } set_cbdata_t;
3848
3849 int
3850 set_callback(zpool_handle_t *zhp, void *data)
3851 {
3852 int error;
3853 set_cbdata_t *cb = (set_cbdata_t *)data;
3854
3855 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3856 if (!error)
3857 cb->cb_any_successful = B_TRUE;
3858
3859 return (error);
3860 }
3861
3862 int
3863 zpool_do_set(int argc, char **argv)
3864 {
3865 set_cbdata_t cb = { 0 };
3866 int error;
3867
3868 if (argc > 1 && argv[1][0] == '-') {
3869 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3870 argv[1][1]);
3871 usage(B_FALSE);
3872 }
3873
3874 if (argc < 2) {
3875 (void) fprintf(stderr, gettext("missing property=value "
3887 usage(B_FALSE);
3888 }
3889
3890 cb.cb_propname = argv[1];
3891 cb.cb_value = strchr(cb.cb_propname, '=');
3892 if (cb.cb_value == NULL) {
3893 (void) fprintf(stderr, gettext("missing value in "
3894 "property=value argument\n"));
3895 usage(B_FALSE);
3896 }
3897
3898 *(cb.cb_value) = '\0';
3899 cb.cb_value++;
3900
3901 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3902 set_callback, &cb);
3903
3904 return (error);
3905 }
3906
3907
3908 static int
3909 /* LINTED E_FUNC_ARG_UNUSED */
3910 key_callback_load(zpool_handle_t *zhp, void *data)
3911 {
3912 int ret;
3913 if (zpool_keysource_prompt(zhp)) {
3914 char *smf_fmri = getenv("SMF_FMRI");
3915
3916 if (smf_fmri != NULL &&
3917 strcmp(smf_fmri, "svc:/system/device/local") == 0) {
3918 return (0);
3919 }
3920 }
3921 ret = zpool_cmd_key_load(zhp);
3922 if (ret != 0 && !(ret == EEXIST || ret == ENOTSUP)) {
3923 return (1);
3924 }
3925
3926 return (0);
3927 }
3928
3929 static int
3930 /* LINTED E_FUNC_ARG_UNUSED */
3931 key_callback_unload(zpool_handle_t *zhp, void *data)
3932 {
3933 int ret;
3934
3935 ret = zpool_cmd_key_unload(zhp);
3936 if (ret != 0 && !(ret == ENOENT || ret == ENOTSUP)) {
3937 return (1);
3938 }
3939
3940 return (0);
3941 }
3942
3943
3944 static int
3945 zpool_do_key(int argc, char **argv)
3946 {
3947 int error = 1, options = 0;
3948 nvlist_t *props = NULL;
3949 char c, *propval = NULL;
3950 boolean_t load = B_FALSE, unload = B_FALSE, change = B_FALSE;
3951 boolean_t do_all = B_FALSE;
3952 zpool_handle_t *zhp = NULL;
3953
3954 while ((c = getopt(argc, argv, "aluco:")) != -1) {
3955 switch (c) {
3956 case 'a':
3957 do_all = B_TRUE;
3958 break;
3959
3960 case 'l':
3961 load = B_TRUE;
3962 break;
3963
3964 case 'u':
3965 unload = B_TRUE;
3966 break;
3967
3968 case 'c':
3969 change = B_TRUE;
3970 break;
3971
3972 case 'o':
3973 if ((propval = strchr(optarg, '=')) == NULL) {
3974 (void) fprintf(stderr, gettext("missing "
3975 "'=' for -o option\n"));
3976 return (error);
3977 }
3978
3979 *propval = '\0';
3980 propval++;
3981 if (strcmp(optarg, "keysource") != 0) {
3982 (void) fprintf(stderr, gettext(
3983 "Invalid property for key change: "
3984 "\"%s\"\n"),
3985 optarg);
3986 return (error);
3987 }
3988 if (add_prop_list(optarg, propval, &props, B_TRUE))
3989 return (error);
3990
3991 options += 2;
3992 break;
3993
3994 }
3995 }
3996
3997 if (!change && props != NULL) {
3998 (void) fprintf(stderr, gettext("Properties are not allowed to "
3999 "be used in this command.\n"));
4000 goto error;
4001 }
4002
4003 if (((load || unload) && (argc > 3)) ||
4004 (change && ((argc - options) > 3))) {
4005 (void) fprintf(stderr,
4006 gettext("too many arguments\n"));
4007 usage(B_FALSE);
4008 goto error;
4009 } else if ((load || unload) && (argc < 3)) {
4010 (void) fprintf(stderr, gettext("missing dataset "
4011 "argument (specify -a for all)\n"));
4012 usage(B_FALSE);
4013 goto error;
4014 } else if (change && ((argc - options) < 3)) {
4015 (void) fprintf(stderr, gettext("missing dataset "
4016 "argument\n"));
4017 usage(B_FALSE);
4018 goto error;
4019 }
4020
4021 if (do_all == B_FALSE) {
4022 zhp = zpool_open(g_zfs, argv[argc - 1]);
4023 if (zhp == NULL)
4024 goto error;
4025 }
4026
4027 if (load) {
4028 if (do_all)
4029 error = for_each_pool(0, NULL, B_TRUE, NULL,
4030 key_callback_load, NULL);
4031 else
4032 error = zpool_cmd_key_load(zhp);
4033
4034 } else if (unload) {
4035 if (do_all)
4036 error = for_each_pool(0, NULL, B_TRUE, NULL,
4037 key_callback_unload, NULL);
4038 else
4039 error = zpool_cmd_key_unload(zhp);
4040
4041 } else if (change) {
4042 if (do_all) {
4043 (void) fprintf(stderr, gettext("cannot use '-a' with "
4044 "change operation.\n"));
4045 usage(B_FALSE);
4046 goto error;
4047 }
4048
4049 error = zpool_cmd_key_change(zhp, props);
4050
4051 } else
4052 usage(B_FALSE);
4053
4054 if (zhp != NULL && !do_all)
4055 zpool_close(zhp);
4056
4057 error:
4058 nvlist_free(props);
4059 if (error != 0)
4060 return (1);
4061 return (0);
4062 }
4063
4064 static int
4065 find_command_idx(char *command, int *idx)
4066 {
4067 int i;
4068
4069 for (i = 0; i < NCOMMAND; i++) {
4070 if (command_table[i].name == NULL)
4071 continue;
4072
4073 if (strcmp(command, command_table[i].name) == 0) {
4074 *idx = i;
4075 return (0);
4076 }
4077 }
4078 return (1);
4079 }
4080
4081 int
4082 main(int argc, char **argv)
4083 {
|