Print this page
*** NO COMMENTS ***


   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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 




  26 #include <assert.h>
  27 #include <libintl.h>
  28 #include <libnvpair.h>
  29 #include <libzfs.h>
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <string.h>
  33 #include <errno.h>
  34 #include <sys/mnttab.h>
  35 #include <sys/types.h>
  36 #include <sys/stat.h>
  37 #include <unistd.h>
  38 
  39 #include <libbe.h>
  40 #include <libbe_priv.h>
  41 
  42 char    *mnttab = MNTTAB;
  43 
  44 /*
  45  * Private function prototypes


 114 /* ******************************************************************** */
 115 
 116 /*
 117  * Function:    _be_activate
 118  * Description: This does the actual work described in be_activate.
 119  * Parameters:
 120  *              be_name - pointer to the name of BE to activate.
 121  *
 122  * Return:
 123  *              BE_SUCCESS - Success
 124  *              be_errnot_t - Failure
 125  * Scope:
 126  *              Public
 127  */
 128 int
 129 _be_activate(char *be_name)
 130 {
 131         be_transaction_data_t cb = { 0 };
 132         zfs_handle_t    *zhp = NULL;
 133         char            root_ds[MAXPATHLEN];

 134         char            *cur_vers = NULL, *new_vers = NULL;
 135         be_node_list_t  *be_nodes = NULL;
 136         uuid_t          uu = {0};
 137         int             entry, ret = BE_SUCCESS;
 138         int             zret = 0;
 139 
 140         /*
 141          * TODO: The BE needs to be validated to make sure that it is actually
 142          * a bootable BE.
 143          */
 144 
 145         if (be_name == NULL)
 146                 return (BE_ERR_INVAL);
 147 
 148         /* Set obe_name to be_name in the cb structure */
 149         cb.obe_name = be_name;
 150 
 151         /* find which zpool the be is in */
 152         if ((zret = zpool_iter(g_zfs, be_find_zpool_callback, &cb)) == 0) {
 153                 be_print_err(gettext("be_activate: failed to "


 207                 if (be_has_grub()) {
 208                         if ((ret = be_change_grub_default(cb.obe_name,
 209                             cb.obe_zpool)) != BE_SUCCESS) {
 210                                 be_print_err(gettext("be_activate: failed to "
 211                                     "change the default entry in menu.lst\n"));
 212                                 goto done;
 213                         }
 214                 }
 215         }
 216 
 217         if ((ret = _be_list(cb.obe_name, &be_nodes)) != BE_SUCCESS) {
 218                 return (ret);
 219         }
 220 
 221         if ((ret = set_canmount(be_nodes, "noauto")) != BE_SUCCESS) {
 222                 be_print_err(gettext("be_activate: failed to set "
 223                     "canmount dataset property\n"));
 224                 goto done;
 225         }
 226 
 227         if ((ret = set_bootfs(be_nodes->be_rpool, root_ds)) != BE_SUCCESS) {


 228                 be_print_err(gettext("be_activate: failed to set "
 229                     "bootfs pool property for %s\n"), root_ds);
 230                 goto done;
 231         }

 232 
 233         if ((zhp = zfs_open(g_zfs, root_ds, ZFS_TYPE_FILESYSTEM)) != NULL) {
 234                 /*
 235                  * We don't need to close the zfs handle at this
 236                  * point because The callback funtion
 237                  * be_promote_ds_callback() will close it for us.
 238                  */
 239                 if (be_promote_ds_callback(zhp, NULL) != 0) {
 240                         be_print_err(gettext("be_activate: "
 241                             "failed to activate the "
 242                             "datasets for %s: %s\n"),
 243                             root_ds,
 244                             libzfs_error_description(g_zfs));
 245                         ret = BE_ERR_PROMOTE;
 246                         goto done;
 247                 }
 248         } else {
 249                 be_print_err(gettext("be_activate:: failed to open "
 250                     "dataset (%s): %s\n"), root_ds,
 251                     libzfs_error_description(g_zfs));
 252                 ret = zfs_err_to_be_err(g_zfs);
 253                 goto done;
 254         }
 255 
 256         if (getzoneid() == GLOBAL_ZONEID &&
 257             be_get_uuid(cb.obe_root_ds, &uu) == BE_SUCCESS &&
 258             (ret = be_promote_zone_ds(cb.obe_name, cb.obe_root_ds))
 259             != BE_SUCCESS) {
 260                 be_print_err(gettext("be_activate: failed to promote "
 261                     "the active zonepath datasets for zones in BE %s\n"),
 262                     cb.obe_name);
 263         }
 264 





























































 265 done:
 266         be_free_list(be_nodes);
 267         return (ret);
 268 }
 269 
 270 /*
 271  * Function:    be_activate_current_be
 272  * Description: Set the currently "active" BE to be "active on boot"
 273  * Paramters:
 274  *              none
 275  * Returns:
 276  *              BE_SUCCESS - Success
 277  *              be_errnot_t - Failure
 278  * Scope:
 279  *              Semi-private (library wide use only)
 280  */
 281 int
 282 be_activate_current_be(void)
 283 {
 284         int ret = BE_SUCCESS;




   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) 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 <errno.h>
  38 #include <sys/mnttab.h>
  39 #include <sys/types.h>
  40 #include <sys/stat.h>
  41 #include <unistd.h>
  42 
  43 #include <libbe.h>
  44 #include <libbe_priv.h>
  45 
  46 char    *mnttab = MNTTAB;
  47 
  48 /*
  49  * Private function prototypes


 118 /* ******************************************************************** */
 119 
 120 /*
 121  * Function:    _be_activate
 122  * Description: This does the actual work described in be_activate.
 123  * Parameters:
 124  *              be_name - pointer to the name of BE to activate.
 125  *
 126  * Return:
 127  *              BE_SUCCESS - Success
 128  *              be_errnot_t - Failure
 129  * Scope:
 130  *              Public
 131  */
 132 int
 133 _be_activate(char *be_name)
 134 {
 135         be_transaction_data_t cb = { 0 };
 136         zfs_handle_t    *zhp = NULL;
 137         char            root_ds[MAXPATHLEN];
 138         char            active_ds[MAXPATHLEN];
 139         char            *cur_vers = NULL, *new_vers = NULL;
 140         be_node_list_t  *be_nodes = NULL;
 141         uuid_t          uu = {0};
 142         int             entry, ret = BE_SUCCESS;
 143         int             zret = 0;
 144 
 145         /*
 146          * TODO: The BE needs to be validated to make sure that it is actually
 147          * a bootable BE.
 148          */
 149 
 150         if (be_name == NULL)
 151                 return (BE_ERR_INVAL);
 152 
 153         /* Set obe_name to be_name in the cb structure */
 154         cb.obe_name = be_name;
 155 
 156         /* find which zpool the be is in */
 157         if ((zret = zpool_iter(g_zfs, be_find_zpool_callback, &cb)) == 0) {
 158                 be_print_err(gettext("be_activate: failed to "


 212                 if (be_has_grub()) {
 213                         if ((ret = be_change_grub_default(cb.obe_name,
 214                             cb.obe_zpool)) != BE_SUCCESS) {
 215                                 be_print_err(gettext("be_activate: failed to "
 216                                     "change the default entry in menu.lst\n"));
 217                                 goto done;
 218                         }
 219                 }
 220         }
 221 
 222         if ((ret = _be_list(cb.obe_name, &be_nodes)) != BE_SUCCESS) {
 223                 return (ret);
 224         }
 225 
 226         if ((ret = set_canmount(be_nodes, "noauto")) != BE_SUCCESS) {
 227                 be_print_err(gettext("be_activate: failed to set "
 228                     "canmount dataset property\n"));
 229                 goto done;
 230         }
 231 
 232         if (getzoneid() == GLOBAL_ZONEID) {
 233                 if ((ret = set_bootfs(be_nodes->be_rpool,
 234                     root_ds)) != BE_SUCCESS) {
 235                         be_print_err(gettext("be_activate: failed to set "
 236                             "bootfs pool property for %s\n"), root_ds);
 237                         goto done;
 238                 }
 239         }
 240 
 241         if ((zhp = zfs_open(g_zfs, root_ds, ZFS_TYPE_FILESYSTEM)) != NULL) {
 242                 /*
 243                  * We don't need to close the zfs handle at this
 244                  * point because The callback funtion
 245                  * be_promote_ds_callback() will close it for us.
 246                  */
 247                 if (be_promote_ds_callback(zhp, NULL) != 0) {
 248                         be_print_err(gettext("be_activate: "
 249                             "failed to activate the "
 250                             "datasets for %s: %s\n"),
 251                             root_ds,
 252                             libzfs_error_description(g_zfs));
 253                         ret = BE_ERR_PROMOTE;
 254                         goto done;
 255                 }
 256         } else {
 257                 be_print_err(gettext("be_activate: failed to open "
 258                     "dataset (%s): %s\n"), root_ds,
 259                     libzfs_error_description(g_zfs));
 260                 ret = zfs_err_to_be_err(g_zfs);
 261                 goto done;
 262         }
 263 
 264         if (getzoneid() == GLOBAL_ZONEID &&
 265             be_get_uuid(cb.obe_root_ds, &uu) == BE_SUCCESS &&
 266             (ret = be_promote_zone_ds(cb.obe_name, cb.obe_root_ds))
 267             != BE_SUCCESS) {
 268                 be_print_err(gettext("be_activate: failed to promote "
 269                     "the active zonepath datasets for zones in BE %s\n"),
 270                     cb.obe_name);
 271         }
 272 
 273         if (getzoneid() != GLOBAL_ZONEID) {
 274                 if (!be_zone_compare_uuids(root_ds)) {
 275                         be_print_err(gettext("be_activate: activating zone "
 276                             "root dataset from non-active global BE is not "
 277                             "supported\n"));
 278                         ret = BE_ERR_NOTSUP;
 279                         goto done;
 280                 }
 281                 if ((zhp = zfs_open(g_zfs, root_ds,
 282                     ZFS_TYPE_FILESYSTEM)) == NULL) {
 283                         be_print_err(gettext("be_activate: failed to open "
 284                             "dataset (%s): %s\n"), root_ds,
 285                             libzfs_error_description(g_zfs));
 286                         ret = zfs_err_to_be_err(g_zfs);
 287                         goto done;
 288                 }
 289                 /* Find current active zone root dataset */
 290                 if ((ret = be_find_active_zone_root(zhp, cb.obe_zpool,
 291                     active_ds, sizeof (active_ds))) != BE_SUCCESS) {
 292                         be_print_err(gettext("be_activate: failed to find "
 293                             "active zone root dataset\n"));
 294                         ZFS_CLOSE(zhp);
 295                         goto done;
 296                 }
 297                 /* Do nothing if requested BE is already active */
 298                 if (strcmp(root_ds, active_ds) == 0) {
 299                         ret = BE_SUCCESS;
 300                         ZFS_CLOSE(zhp);
 301                         goto done;
 302                 }
 303 
 304                 /* Set active property for BE */
 305                 if (zfs_prop_set(zhp, BE_ZONE_ACTIVE_PROPERTY, "on") != 0) {
 306                         be_print_err(gettext("be_activate: failed to set "
 307                             "active property (%s): %s\n"), root_ds,
 308                             libzfs_error_description(g_zfs));
 309                         ret = zfs_err_to_be_err(g_zfs);
 310                         ZFS_CLOSE(zhp);
 311                         goto done;
 312                 }
 313                 ZFS_CLOSE(zhp);
 314 
 315                 /* Unset active property for old active root dataset */
 316                 if ((zhp = zfs_open(g_zfs, active_ds,
 317                     ZFS_TYPE_FILESYSTEM)) == NULL) {
 318                         be_print_err(gettext("be_activate: failed to open "
 319                             "dataset (%s): %s\n"), active_ds,
 320                             libzfs_error_description(g_zfs));
 321                         ret = zfs_err_to_be_err(g_zfs);
 322                         goto done;
 323                 }
 324                 if (zfs_prop_set(zhp, BE_ZONE_ACTIVE_PROPERTY, "off") != 0) {
 325                         be_print_err(gettext("be_activate: failed to unset "
 326                             "active property (%s): %s\n"), active_ds,
 327                             libzfs_error_description(g_zfs));
 328                         ret = zfs_err_to_be_err(g_zfs);
 329                         ZFS_CLOSE(zhp);
 330                         goto done;
 331                 }
 332                 ZFS_CLOSE(zhp);
 333         }
 334 done:
 335         be_free_list(be_nodes);
 336         return (ret);
 337 }
 338 
 339 /*
 340  * Function:    be_activate_current_be
 341  * Description: Set the currently "active" BE to be "active on boot"
 342  * Paramters:
 343  *              none
 344  * Returns:
 345  *              BE_SUCCESS - Success
 346  *              be_errnot_t - Failure
 347  * Scope:
 348  *              Semi-private (library wide use only)
 349  */
 350 int
 351 be_activate_current_be(void)
 352 {
 353         int ret = BE_SUCCESS;