Print this page
*** NO COMMENTS ***


   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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  28  */
  29 
  30 #include <assert.h>
  31 #include <libintl.h>
  32 #include <libnvpair.h>
  33 #include <libzfs.h>
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <string.h>
  37 #include <strings.h>
  38 #include <sys/types.h>
  39 #include <sys/stat.h>
  40 #include <unistd.h>
  41 #include <errno.h>
  42 
  43 #include <libbe.h>
  44 #include <libbe_priv.h>
  45 
  46 /*
  47  * Callback data used for zfs_iter calls.


 171                  * We were unable to find a currently booted BE which
 172                  * probably means that we're not booted in a BE envoronment.
 173                  * None of the BE's will be marked as the active BE.
 174                  */
 175                 (void) strcpy(cb.current_be, "-");
 176         } else {
 177                 (void) strncpy(cb.current_be, bt.obe_name,
 178                     sizeof (cb.current_be));
 179                 rpool = bt.obe_zpool;
 180         }
 181 
 182         /*
 183          * If be_name is NULL we'll look for all BE's on the system.
 184          * If not then we will only return data for the specified BE.
 185          */
 186         if (be_name != NULL)
 187                 cb.be_name = strdup(be_name);
 188 
 189         if (be_defaults.be_deflt_rpool_container && rpool != NULL) {
 190                 if ((zphp = zpool_open(g_zfs, rpool)) == NULL) {
 191                         be_print_err(gettext("be_get_node_data: failed to "
 192                             "open rpool (%s): %s\n"), rpool,
 193                             libzfs_error_description(g_zfs));
 194                         free(cb.be_name);
 195                         return (zfs_err_to_be_err(g_zfs));
 196                 }
 197 
 198                 ret = be_get_list_callback(zphp, &cb);
 199         } else {
 200                 if ((zpool_iter(g_zfs, be_get_list_callback, &cb)) != 0) {
 201                         if (cb.be_nodes_head != NULL) {
 202                                 be_free_list(cb.be_nodes_head);
 203                                 cb.be_nodes_head = NULL;
 204                                 cb.be_nodes = NULL;
 205                         }
 206                         ret = BE_ERR_BE_NOENT;
 207                 }
 208         }
 209 
 210         if (cb.be_nodes_head == NULL) {
 211                 if (be_name != NULL)


 807  *              be_ds - The dataset name for the BE.
 808  *
 809  * Returns:
 810  *              BE_SUCCESS - Success
 811  *              be_errno_t - Failure
 812  * Scope:
 813  *              Private
 814  */
 815 static int
 816 be_get_node_data(
 817         zfs_handle_t *zhp,
 818         be_node_list_t *be_node,
 819         char *be_name,
 820         const char *rpool,
 821         char *current_be,
 822         char *be_ds)
 823 {
 824         char prop_buf[MAXPATHLEN];
 825         nvlist_t *userprops = NULL;
 826         nvlist_t *propval = NULL;

 827         char *prop_str = NULL;

 828         char *grub_default_bootfs = NULL;
 829         zpool_handle_t *zphp = NULL;
 830         int err = 0;
 831 
 832         if (be_node == NULL || be_name == NULL || current_be == NULL ||
 833             be_ds == NULL) {
 834                 be_print_err(gettext("be_get_node_data: invalid arguments, "
 835                     "can not be NULL\n"));
 836                 return (BE_ERR_INVAL);
 837         }
 838 
 839         errno = 0;
 840 
 841         be_node->be_root_ds = strdup(be_ds);
 842         if ((err = errno) != 0 || be_node->be_root_ds == NULL) {
 843                 be_print_err(gettext("be_get_node_data: failed to "
 844                     "copy root dataset name\n"));
 845                 return (errno_to_be_err(err));
 846         }
 847 
 848         be_node->be_node_name = strdup(be_name);
 849         if ((err = errno) != 0 || be_node->be_node_name == NULL) {
 850                 be_print_err(gettext("be_get_node_data: failed to "
 851                     "copy BE name\n"));
 852                 return (errno_to_be_err(err));
 853         }
 854         if (strncmp(be_name, current_be, MAXPATHLEN) == 0)
 855                 be_node->be_active = B_TRUE;
 856         else
 857                 be_node->be_active = B_FALSE;
 858 
 859         be_node->be_rpool = strdup(rpool);
 860         if (be_node->be_rpool == NULL || (err = errno) != 0) {
 861                 be_print_err(gettext("be_get_node_data: failed to "
 862                     "copy root pool name\n"));
 863                 return (errno_to_be_err(err));
 864         }
 865 
 866         be_node->be_space_used = zfs_prop_get_int(zhp, ZFS_PROP_USED);
 867 

 868         if ((zphp = zpool_open(g_zfs, rpool)) == NULL) {
 869                 be_print_err(gettext("be_get_node_data: failed to open pool "
 870                     "(%s): %s\n"), rpool, libzfs_error_description(g_zfs));

 871                 return (zfs_err_to_be_err(g_zfs));
 872         }
 873 
 874         (void) zpool_get_prop(zphp, ZPOOL_PROP_BOOTFS, prop_buf, ZFS_MAXPROPLEN,
 875             NULL);
 876         if (be_has_grub() &&
 877             (be_default_grub_bootfs(rpool, &grub_default_bootfs)
 878             == BE_SUCCESS) && grub_default_bootfs != NULL)
 879                 if (strcmp(grub_default_bootfs, be_ds) == 0)
 880                         be_node->be_active_on_boot = B_TRUE;
 881                 else
 882                         be_node->be_active_on_boot = B_FALSE;
 883         else if (prop_buf != NULL && strcmp(prop_buf, be_ds) == 0)
 884                 be_node->be_active_on_boot = B_TRUE;
 885         else
 886                 be_node->be_active_on_boot = B_FALSE;



 887         free(grub_default_bootfs);
 888         zpool_close(zphp);






 889 
 890         /*
 891          * If the dataset is mounted use the mount point
 892          * returned from the zfs_is_mounted call. If the
 893          * dataset is not mounted then pull the mount
 894          * point information out of the zfs properties.
 895          */
 896         be_node->be_mounted = zfs_is_mounted(zhp,
 897             &(be_node->be_mntpt));
 898         if (!be_node->be_mounted) {
 899                 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop_buf,
 900                     ZFS_MAXPROPLEN, NULL, NULL, 0, B_FALSE) == 0)
 901                         be_node->be_mntpt = strdup(prop_buf);
 902                 else
 903                         return (zfs_err_to_be_err(g_zfs));
 904         }
 905 
 906         be_node->be_node_creation = (time_t)zfs_prop_get_int(zhp,
 907             ZFS_PROP_CREATION);
 908 
 909         /* Get all user properties used for libbe */
 910         if ((userprops = zfs_get_user_props(zhp)) == NULL) {
 911                 be_node->be_policy_type = strdup(be_default_policy());
 912         } else {
















 913                 if (nvlist_lookup_nvlist(userprops, BE_POLICY_PROPERTY,
 914                     &propval) != 0 || propval == NULL) {
 915                         be_node->be_policy_type =
 916                             strdup(be_default_policy());
 917                 } else {
 918                         verify(nvlist_lookup_string(propval, ZPROP_VALUE,
 919                             &prop_str) == 0);
 920                         if (prop_str == NULL || strcmp(prop_str, "-") == 0 ||
 921                             strcmp(prop_str, "") == 0)
 922                                 be_node->be_policy_type =
 923                                     strdup(be_default_policy());
 924                         else
 925                                 be_node->be_policy_type = strdup(prop_str);
 926                 }
 927 
 928                 if (nvlist_lookup_nvlist(userprops, BE_UUID_PROPERTY, &propval)
 929                     == 0 && nvlist_lookup_string(propval, ZPROP_VALUE,

 930                     &prop_str) == 0) {
 931                         be_node->be_uuid_str = strdup(prop_str);
 932                 }





 933         }


 934 
 935         /*
 936          * Increment the dataset counter to include the root dataset
 937          * of the BE.
 938          */
 939         be_node->be_node_num_datasets++;
 940 
 941         return (BE_SUCCESS);
 942 }
 943 
 944 /*
 945  * Function:    be_get_ds_data
 946  * Description: Helper function used by be_add_children_callback to collect
 947  *              the dataset related information that will be returned by
 948  *              be_list.
 949  * Parameters:
 950  *              zhp - Handle to the zfs dataset whose information we're
 951  *                    collecting.
 952  *              name - The name of the dataset we're processing.
 953  *              dataset - A pointer to the be_dataset_list structure




   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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  28  */
  29 
  30 #include <assert.h>
  31 #include <libintl.h>
  32 #include <libnvpair.h>
  33 #include <libzfs.h>
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <string.h>
  37 #include <strings.h>
  38 #include <sys/types.h>
  39 #include <sys/stat.h>
  40 #include <unistd.h>
  41 #include <errno.h>
  42 
  43 #include <libbe.h>
  44 #include <libbe_priv.h>
  45 
  46 /*
  47  * Callback data used for zfs_iter calls.


 171                  * We were unable to find a currently booted BE which
 172                  * probably means that we're not booted in a BE envoronment.
 173                  * None of the BE's will be marked as the active BE.
 174                  */
 175                 (void) strcpy(cb.current_be, "-");
 176         } else {
 177                 (void) strncpy(cb.current_be, bt.obe_name,
 178                     sizeof (cb.current_be));
 179                 rpool = bt.obe_zpool;
 180         }
 181 
 182         /*
 183          * If be_name is NULL we'll look for all BE's on the system.
 184          * If not then we will only return data for the specified BE.
 185          */
 186         if (be_name != NULL)
 187                 cb.be_name = strdup(be_name);
 188 
 189         if (be_defaults.be_deflt_rpool_container && rpool != NULL) {
 190                 if ((zphp = zpool_open(g_zfs, rpool)) == NULL) {
 191                         be_print_err(gettext("be_list: failed to "
 192                             "open rpool (%s): %s\n"), rpool,
 193                             libzfs_error_description(g_zfs));
 194                         free(cb.be_name);
 195                         return (zfs_err_to_be_err(g_zfs));
 196                 }
 197 
 198                 ret = be_get_list_callback(zphp, &cb);
 199         } else {
 200                 if ((zpool_iter(g_zfs, be_get_list_callback, &cb)) != 0) {
 201                         if (cb.be_nodes_head != NULL) {
 202                                 be_free_list(cb.be_nodes_head);
 203                                 cb.be_nodes_head = NULL;
 204                                 cb.be_nodes = NULL;
 205                         }
 206                         ret = BE_ERR_BE_NOENT;
 207                 }
 208         }
 209 
 210         if (cb.be_nodes_head == NULL) {
 211                 if (be_name != NULL)


 807  *              be_ds - The dataset name for the BE.
 808  *
 809  * Returns:
 810  *              BE_SUCCESS - Success
 811  *              be_errno_t - Failure
 812  * Scope:
 813  *              Private
 814  */
 815 static int
 816 be_get_node_data(
 817         zfs_handle_t *zhp,
 818         be_node_list_t *be_node,
 819         char *be_name,
 820         const char *rpool,
 821         char *current_be,
 822         char *be_ds)
 823 {
 824         char prop_buf[MAXPATHLEN];
 825         nvlist_t *userprops = NULL;
 826         nvlist_t *propval = NULL;
 827         nvlist_t *zone_propval = NULL;
 828         char *prop_str = NULL;
 829         char *zone_prop_str = NULL;
 830         char *grub_default_bootfs = NULL;
 831         zpool_handle_t *zphp = NULL;
 832         int err = 0;
 833 
 834         if (be_node == NULL || be_name == NULL || current_be == NULL ||
 835             be_ds == NULL) {
 836                 be_print_err(gettext("be_get_node_data: invalid arguments, "
 837                     "can not be NULL\n"));
 838                 return (BE_ERR_INVAL);
 839         }
 840 
 841         errno = 0;
 842 
 843         be_node->be_root_ds = strdup(be_ds);
 844         if ((err = errno) != 0 || be_node->be_root_ds == NULL) {
 845                 be_print_err(gettext("be_get_node_data: failed to "
 846                     "copy root dataset name\n"));
 847                 return (errno_to_be_err(err));
 848         }
 849 
 850         be_node->be_node_name = strdup(be_name);
 851         if ((err = errno) != 0 || be_node->be_node_name == NULL) {
 852                 be_print_err(gettext("be_get_node_data: failed to "
 853                     "copy BE name\n"));
 854                 return (errno_to_be_err(err));
 855         }
 856         if (strncmp(be_name, current_be, MAXPATHLEN) == 0)
 857                 be_node->be_active = B_TRUE;
 858         else
 859                 be_node->be_active = B_FALSE;
 860 
 861         be_node->be_rpool = strdup(rpool);
 862         if (be_node->be_rpool == NULL || (err = errno) != 0) {
 863                 be_print_err(gettext("be_get_node_data: failed to "
 864                     "copy root pool name\n"));
 865                 return (errno_to_be_err(err));
 866         }
 867 
 868         be_node->be_space_used = zfs_prop_get_int(zhp, ZFS_PROP_USED);
 869 
 870         if (getzoneid() == GLOBAL_ZONEID) {
 871                 if ((zphp = zpool_open(g_zfs, rpool)) == NULL) {
 872                         be_print_err(gettext("be_get_node_data: failed to open "
 873                             "pool (%s): %s\n"), rpool,
 874                             libzfs_error_description(g_zfs));
 875                         return (zfs_err_to_be_err(g_zfs));
 876                 }
 877 
 878                 (void) zpool_get_prop(zphp, ZPOOL_PROP_BOOTFS, prop_buf,
 879                     ZFS_MAXPROPLEN, NULL);
 880                 if (be_has_grub() && (be_default_grub_bootfs(rpool,
 881                     &grub_default_bootfs) == BE_SUCCESS) &&
 882                     grub_default_bootfs != NULL)
 883                         if (strcmp(grub_default_bootfs, be_ds) == 0)
 884                                 be_node->be_active_on_boot = B_TRUE;
 885                         else
 886                                 be_node->be_active_on_boot = B_FALSE;
 887                 else if (prop_buf != NULL && strcmp(prop_buf, be_ds) == 0)
 888                         be_node->be_active_on_boot = B_TRUE;
 889                 else
 890                         be_node->be_active_on_boot = B_FALSE;
 891 
 892                 be_node->be_global_active = B_TRUE;
 893 
 894                 free(grub_default_bootfs);
 895                 zpool_close(zphp);
 896         } else {
 897                 if (be_zone_compare_uuids(be_node->be_root_ds))
 898                         be_node->be_global_active = B_TRUE;
 899                 else
 900                         be_node->be_global_active = B_FALSE;
 901         }
 902 
 903         /*
 904          * If the dataset is mounted use the mount point
 905          * returned from the zfs_is_mounted call. If the
 906          * dataset is not mounted then pull the mount
 907          * point information out of the zfs properties.
 908          */
 909         be_node->be_mounted = zfs_is_mounted(zhp,
 910             &(be_node->be_mntpt));
 911         if (!be_node->be_mounted) {
 912                 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop_buf,
 913                     ZFS_MAXPROPLEN, NULL, NULL, 0, B_FALSE) == 0)
 914                         be_node->be_mntpt = strdup(prop_buf);
 915                 else
 916                         return (zfs_err_to_be_err(g_zfs));
 917         }
 918 
 919         be_node->be_node_creation = (time_t)zfs_prop_get_int(zhp,
 920             ZFS_PROP_CREATION);
 921 
 922         /* Get all user properties used for libbe */
 923         if ((userprops = zfs_get_user_props(zhp)) == NULL) {
 924                 be_node->be_policy_type = strdup(be_default_policy());
 925         } else {
 926                 if (getzoneid() != GLOBAL_ZONEID) {
 927                         if (nvlist_lookup_nvlist(userprops,
 928                             BE_ZONE_ACTIVE_PROPERTY, &zone_propval) != 0 ||
 929                             zone_propval == NULL) {
 930                                 be_node->be_active_on_boot = B_FALSE;
 931                         } else {
 932                                 verify(nvlist_lookup_string(zone_propval,
 933                                     ZPROP_VALUE, &zone_prop_str) == 0);
 934                                 if (strcmp(zone_prop_str, "on") == 0) {
 935                                         be_node->be_active_on_boot = B_TRUE;
 936                                 } else {
 937                                         be_node->be_active_on_boot = B_FALSE;
 938                                 }
 939                         }
 940                 }
 941 
 942                 if (nvlist_lookup_nvlist(userprops, BE_POLICY_PROPERTY,
 943                     &propval) != 0 || propval == NULL) {
 944                         be_node->be_policy_type =
 945                             strdup(be_default_policy());
 946                 } else {
 947                         verify(nvlist_lookup_string(propval, ZPROP_VALUE,
 948                             &prop_str) == 0);
 949                         if (prop_str == NULL || strcmp(prop_str, "-") == 0 ||
 950                             strcmp(prop_str, "") == 0)
 951                                 be_node->be_policy_type =
 952                                     strdup(be_default_policy());
 953                         else
 954                                 be_node->be_policy_type = strdup(prop_str);
 955                 }
 956                 if (getzoneid() != GLOBAL_ZONEID) {
 957                         if (nvlist_lookup_nvlist(userprops,
 958                             BE_ZONE_PARENTBE_PROPERTY, &propval) != 0 &&
 959                             nvlist_lookup_string(propval, ZPROP_VALUE,
 960                             &prop_str) == 0) {
 961                                 be_node->be_uuid_str = strdup(prop_str);
 962                         }
 963                 } else {
 964                         if (nvlist_lookup_nvlist(userprops, BE_UUID_PROPERTY,
 965                             &propval) == 0 && nvlist_lookup_string(propval,
 966                             ZPROP_VALUE, &prop_str) == 0) {
 967                                 be_node->be_uuid_str = strdup(prop_str);
 968                         }
 969                 }
 970         }
 971 
 972         /*
 973          * Increment the dataset counter to include the root dataset
 974          * of the BE.
 975          */
 976         be_node->be_node_num_datasets++;
 977 
 978         return (BE_SUCCESS);
 979 }
 980 
 981 /*
 982  * Function:    be_get_ds_data
 983  * Description: Helper function used by be_add_children_callback to collect
 984  *              the dataset related information that will be returned by
 985  *              be_list.
 986  * Parameters:
 987  *              zhp - Handle to the zfs dataset whose information we're
 988  *                    collecting.
 989  *              name - The name of the dataset we're processing.
 990  *              dataset - A pointer to the be_dataset_list structure