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
|