static int be_do_list(int argc, char **argv) { be_node_list_t *be_nodes = NULL; boolean_t all = B_FALSE; boolean_t dsets = B_FALSE; boolean_t snaps = B_FALSE; boolean_t parsable = B_FALSE; int err = 1; int c = 0; char *be_name = NULL; be_sort_t order = BE_SORT_UNSPECIFIED; while ((c = getopt(argc, argv, "adk:svHK:")) != -1) { switch (c) { case 'a': all = B_TRUE; break; case 'd': dsets = B_TRUE; break; case 'k': case 'K': if (order != BE_SORT_UNSPECIFIED) { (void) fprintf(stderr, _("Sort key can be " "specified only once.\n")); usage(); return (1); } if (strcmp(optarg, "date") == 0) { if (c == 'k') order = BE_SORT_DATE; else order = BE_SORT_DATE_REV; break; } if (strcmp(optarg, "name") == 0) { if (c == 'k') order = BE_SORT_NAME; else order = BE_SORT_NAME_REV; break; } if (strcmp(optarg, "space") == 0) { if (c == 'k') order = BE_SORT_SPACE; else order = BE_SORT_SPACE_REV; break; } (void) fprintf(stderr, _("Unknown sort key: %s\n"), optarg); usage(); return (1); case 's': snaps = B_TRUE; break; case 'v': libbe_print_errors(B_TRUE); break; case 'H': parsable = B_TRUE; break; default: usage(); return (1); } } if (all) { if (dsets) { (void) fprintf(stderr, _("Invalid options: -a and %s " "are mutually exclusive.\n"), "-d"); usage(); return (1); } if (snaps) { (void) fprintf(stderr, _("Invalid options: -a and %s " "are mutually exclusive.\n"), "-s"); usage(); return (1); } dsets = B_TRUE; snaps = B_TRUE; } argc -= optind; argv += optind; if (argc == 1) be_name = argv[0]; err = be_list(be_name, &be_nodes); switch (err) { case BE_SUCCESS: /* the default sort is ascending date, no need to sort twice */ if (order == BE_SORT_UNSPECIFIED) order = BE_SORT_DATE; if (order != BE_SORT_DATE) { err = be_sort(&be_nodes, order); if (err != BE_SUCCESS) { (void) fprintf(stderr, _("Unable to sort Boot " "Environment\n")); (void) fprintf(stderr, "%s\n", be_err_to_str(err)); break; } } print_nodes(be_name, dsets, snaps, parsable, be_nodes); break; case BE_ERR_BE_NOENT: if (be_name == NULL) (void) fprintf(stderr, _("No boot environments found " "on this system.\n")); else { (void) fprintf(stderr, _("%s does not exist or appear " "to be a valid BE.\nPlease check that the name of " "the BE provided is correct.\n"), be_name); } break; default: (void) fprintf(stderr, _("Unable to display Boot " "Environment\n")); (void) fprintf(stderr, "%s\n", be_err_to_str(err)); } if (be_nodes != NULL) be_free_list(be_nodes); return (err); }
/* * Function: _be_list * Description: This does the actual work described in be_list. * Parameters: * be_name - The name of the BE to look up. * If NULL a list of all BEs will be returned. * be_nodes - A reference pointer to the list of BEs. The list * structure will be allocated here and must * be freed by a call to be_free_list. If there are no * BEs found on the system this reference will be * set to NULL. * Return: * BE_SUCCESS - Success * be_errno_t - Failure * Scope: * Semi-private (library wide use only) */ int _be_list(char *be_name, be_node_list_t **be_nodes, uint64_t flags) { list_callback_data_t cb = { 0 }; be_transaction_data_t bt = { 0 }; int ret = BE_SUCCESS; int sret; zpool_handle_t *zphp; char *rpool = NULL; if (be_nodes == NULL) return (BE_ERR_INVAL); be_get_defaults(&cb.be_defaults); cb.flags = flags; if (be_find_current_be(&bt) != BE_SUCCESS) { /* * We were unable to find a currently booted BE which * probably means that we're not booted in a BE envoronment. * None of the BE's will be marked as the active BE. */ (void) strcpy(cb.current_be, "-"); } else { (void) strncpy(cb.current_be, bt.obe_name, sizeof (cb.current_be)); rpool = bt.obe_zpool; } /* * If be_name is NULL we'll look for all BE's on the system. * If not then we will only return data for the specified BE. */ if (be_name != NULL) cb.be_name = strdup(be_name); if (cb.be_defaults.be_deflt_rpool_container && rpool != NULL) { if ((zphp = zpool_open(g_zfs, rpool)) == NULL) { be_print_err(gettext("be_list: failed to " "open rpool (%s): %s\n"), rpool, libzfs_error_description(g_zfs)); free(cb.be_name); return (zfs_err_to_be_err(g_zfs)); } ret = be_get_list_callback(zphp, &cb); } else { if ((zpool_iter(g_zfs, be_get_list_callback, &cb)) != 0) { if (cb.be_nodes_head != NULL) { be_free_list(cb.be_nodes_head); cb.be_nodes_head = NULL; cb.be_nodes = NULL; } ret = BE_ERR_BE_NOENT; } } if (cb.be_nodes_head == NULL) { if (be_name != NULL) be_print_err(gettext("be_list: BE (%s) does not " "exist\n"), be_name); else be_print_err(gettext("be_list: No BE's found\n")); ret = BE_ERR_BE_NOENT; } *be_nodes = cb.be_nodes_head; free(cb.be_name); sret = be_sort(be_nodes, BE_SORT_DATE); return ((ret == BE_SUCCESS) ? sret : ret); }