Print this page
patch zone-auto-create-be


   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  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  27  * Copyright 2015 EveryCity Ltd.

  28  */
  29 
  30 /*
  31  * System includes
  32  */
  33 #include <assert.h>
  34 #include <errno.h>
  35 #include <libgen.h>
  36 #include <libintl.h>
  37 #include <libnvpair.h>
  38 #include <libzfs.h>
  39 #include <stdio.h>
  40 #include <stdlib.h>
  41 #include <string.h>
  42 #include <sys/mntent.h>
  43 #include <sys/mnttab.h>
  44 #include <sys/mount.h>
  45 #include <sys/stat.h>
  46 #include <sys/types.h>
  47 #include <sys/vfstab.h>


2325 /*
2326  * Function:    be_mount_zones
2327  * Description: This function finds all supported non-global zones in the
2328  *              given global BE and mounts them with respect to where the
2329  *              global BE is currently mounted.  The global BE datasets
2330  *              (including its shared datasets) are expected to already
2331  *              be mounted.
2332  * Parameters:
2333  *              be_zhp - zfs_handle_t pointer to the root dataset of the
2334  *                      global BE.
2335  *              md - be_mount_data_t pointer to data for global BE.
2336  * Returns:
2337  *              BE_SUCCESS - Success
2338  *              be_errno_t - Failure
2339  * Scope:
2340  *              Private
2341  */
2342 static int
2343 be_mount_zones(zfs_handle_t *be_zhp, be_mount_data_t *md)
2344 {
2345         zoneBrandList_t *brands = NULL;
2346         zoneList_t      zlst = NULL;
2347         char            *zonename = NULL;
2348         char            *zonepath = NULL;
2349         char            *zonepath_ds = NULL;
2350         int             k;
2351         int             ret = BE_SUCCESS;

2352 
2353         z_set_zone_root(md->altroot);
2354 
2355         if ((brands = be_get_supported_brandlist()) == NULL) {
2356                 be_print_err(gettext("be_mount_zones: "
2357                     "no supported brands\n"));
2358                 return (BE_SUCCESS);
2359         }
2360 
2361         zlst = z_get_nonglobal_zone_list_by_brand(brands);
2362         if (zlst == NULL) {
2363                 z_free_brand_list(brands);
2364                 return (BE_SUCCESS);

2365         }
2366 
2367         for (k = 0; (zonename = z_zlist_get_zonename(zlst, k)) != NULL; k++) {


2368                 if (z_zlist_get_current_state(zlst, k) ==
2369                     ZONE_STATE_INSTALLED) {
2370                         zonepath = z_zlist_get_zonepath(zlst, k);
2371 
2372                         /*
2373                          * Get the dataset of this zonepath in current BE.
2374                          * If its not a dataset, skip it.
2375                          */
2376                         if ((zonepath_ds = be_get_ds_from_dir(zonepath))
2377                             == NULL)
2378                                 continue;
2379 
2380                         /*
2381                          * Check if this zone is supported based on
2382                          * the dataset of its zonepath
2383                          */
2384                         if (!be_zone_supported(zonepath_ds)) {
2385                                 free(zonepath_ds);
2386                                 zonepath_ds = NULL;
2387                                 continue;


2400                         }
2401 
2402 
2403                         /* Mount this zone */
2404                         ret = be_mount_one_zone(be_zhp, md, zonename,
2405                             zonepath, zonepath_ds);
2406 
2407                         free(zonepath_ds);
2408                         zonepath_ds = NULL;
2409 
2410                         if (ret != BE_SUCCESS) {
2411                                 be_print_err(gettext("be_mount_zones: "
2412                                     "failed to mount zone %s under "
2413                                     "altroot %s\n"), zonename, md->altroot);
2414                                 goto done;
2415                         }
2416                 }
2417         }
2418 
2419 done:
2420         z_free_brand_list(brands);
2421         z_free_zone_list(zlst);
2422         /*
2423          * libinstzones caches mnttab and uses cached version for resolving lofs
2424          * mounts when we call z_resolve_lofs. It creates the cached version
2425          * when the first call to z_resolve_lofs happens. So, library's cached
2426          * mnttab doesn't contain entries for lofs mounts created in the above
2427          * loop. Because of this, subsequent calls to z_resolve_lofs would fail
2428          * to resolve these lofs mounts. So, here we destroy library's cached
2429          * mnttab to force its recreation when the next call to z_resolve_lofs
2430          * happens.
2431          */
2432         z_destroyMountTable();
2433         return (ret);
2434 }
2435 
2436 /*
2437  * Function:    be_unmount_zones
2438  * Description: This function finds all supported non-global zones in the
2439  *              given mounted global BE and unmounts them.
2440  * Parameters:
2441  *              ud - unmount_data_t pointer data for the global BE.
2442  * Returns:
2443  *              BE_SUCCESS - Success
2444  *              be_errno_t - Failure
2445  * Scope:
2446  *              Private
2447  */
2448 static int
2449 be_unmount_zones(be_unmount_data_t *ud)
2450 {
2451         zoneBrandList_t         *brands = NULL;
2452         zoneList_t              zlst = NULL;
2453         char                    *zonename = NULL;
2454         char                    *zonepath = NULL;
2455         char                    alt_zonepath[MAXPATHLEN];
2456         char                    *zonepath_ds = NULL;
2457         int                     k;
2458         int                     ret = BE_SUCCESS;

2459 
2460         z_set_zone_root(ud->altroot);
2461 
2462         if ((brands = be_get_supported_brandlist()) == NULL) {
2463                 be_print_err(gettext("be_unmount_zones: "
2464                     "no supported brands\n"));
2465                 return (BE_SUCCESS);
2466         }
2467 
2468         zlst = z_get_nonglobal_zone_list_by_brand(brands);
2469         if (zlst == NULL) {
2470                 z_free_brand_list(brands);
2471                 return (BE_SUCCESS);

2472         }
2473 
2474         for (k = 0; (zonename = z_zlist_get_zonename(zlst, k)) != NULL; k++) {


2475                 if (z_zlist_get_current_state(zlst, k) ==
2476                     ZONE_STATE_INSTALLED) {
2477                         zonepath = z_zlist_get_zonepath(zlst, k);
2478 
2479                         /* Build zone's zonepath wrt the global BE altroot */
2480                         (void) snprintf(alt_zonepath, sizeof (alt_zonepath),
2481                             "%s%s", ud->altroot, zonepath);
2482 
2483                         /*
2484                          * Get the dataset of this zonepath.  If its not
2485                          * a dataset, skip it.
2486                          */
2487                         if ((zonepath_ds = be_get_ds_from_dir(alt_zonepath))
2488                             == NULL)
2489                                 continue;
2490 
2491                         /*
2492                          * Check if this zone is supported based on the
2493                          * dataset of its zonepath.
2494                          */


2498                                 continue;
2499                         }
2500 
2501                         /* Unmount this zone */
2502                         ret = be_unmount_one_zone(ud, zonename, zonepath,
2503                             zonepath_ds);
2504 
2505                         free(zonepath_ds);
2506                         zonepath_ds = NULL;
2507 
2508                         if (ret != BE_SUCCESS) {
2509                                 be_print_err(gettext("be_unmount_zones:"
2510                                     " failed to unmount zone %s from "
2511                                     "altroot %s\n"), zonename, ud->altroot);
2512                                 goto done;
2513                         }
2514                 }
2515         }
2516 
2517 done:
2518         z_free_brand_list(brands);
2519         z_free_zone_list(zlst);
2520         return (ret);
2521 }
2522 
2523 /*
2524  * Function:    be_mount_one_zone
2525  * Description: This function is called to mount one zone for a given
2526  *              global BE.
2527  * Parameters:
2528  *              be_zhp - zfs_handle_t pointer to the root dataset of the
2529  *                      global BE
2530  *              md - be_mount_data_t pointer to data for global BE
2531  *              zonename - name of zone to mount
2532  *              zonepath - zonepath of zone to mount
2533  *              zonepath_ds - dataset for the zonepath
2534  * Returns:
2535  *              BE_SUCCESS - Success
2536  *              be_errno_t - Failure
2537  * Scope:
2538  *              Private




   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  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  27  * Copyright 2015 EveryCity Ltd.
  28  * Copyright 2015 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  29  */
  30 
  31 /*
  32  * System includes
  33  */
  34 #include <assert.h>
  35 #include <errno.h>
  36 #include <libgen.h>
  37 #include <libintl.h>
  38 #include <libnvpair.h>
  39 #include <libzfs.h>
  40 #include <stdio.h>
  41 #include <stdlib.h>
  42 #include <string.h>
  43 #include <sys/mntent.h>
  44 #include <sys/mnttab.h>
  45 #include <sys/mount.h>
  46 #include <sys/stat.h>
  47 #include <sys/types.h>
  48 #include <sys/vfstab.h>


2326 /*
2327  * Function:    be_mount_zones
2328  * Description: This function finds all supported non-global zones in the
2329  *              given global BE and mounts them with respect to where the
2330  *              global BE is currently mounted.  The global BE datasets
2331  *              (including its shared datasets) are expected to already
2332  *              be mounted.
2333  * Parameters:
2334  *              be_zhp - zfs_handle_t pointer to the root dataset of the
2335  *                      global BE.
2336  *              md - be_mount_data_t pointer to data for global BE.
2337  * Returns:
2338  *              BE_SUCCESS - Success
2339  *              be_errno_t - Failure
2340  * Scope:
2341  *              Private
2342  */
2343 static int
2344 be_mount_zones(zfs_handle_t *be_zhp, be_mount_data_t *md)
2345 {

2346         zoneList_t      zlst = NULL;
2347         char            *zonename = NULL;
2348         char            *zonepath = NULL;
2349         char            *zonepath_ds = NULL;
2350         int             k;
2351         int             ret = BE_SUCCESS;
2352         boolean_t       auto_create;
2353 
2354         z_set_zone_root(md->altroot);
2355 
2356         zlst = z_get_nonglobal_branded_zone_list();
2357         if (zlst == NULL)

2358                 return (BE_SUCCESS);

2359 
2360         for (k = 0; (zonename = z_zlist_get_zonename(zlst, k)) != NULL; k++) {
2361                 if (z_zlist_is_zone_auto_create_be(zlst, k, &auto_create) != 0) {
2362                         be_print_err(gettext("be_mount_zones: failed to"
2363                             " get auto-create-be brand property\n"));
2364                         goto done;
2365                 }
2366 
2367                 if (!auto_create)
2368                         continue;
2369 
2370                 if (z_zlist_get_current_state(zlst, k) ==
2371                     ZONE_STATE_INSTALLED) {
2372                         zonepath = z_zlist_get_zonepath(zlst, k);
2373 
2374                         /*
2375                          * Get the dataset of this zonepath in current BE.
2376                          * If its not a dataset, skip it.
2377                          */
2378                         if ((zonepath_ds = be_get_ds_from_dir(zonepath))
2379                             == NULL)
2380                                 continue;
2381 
2382                         /*
2383                          * Check if this zone is supported based on
2384                          * the dataset of its zonepath
2385                          */
2386                         if (!be_zone_supported(zonepath_ds)) {
2387                                 free(zonepath_ds);
2388                                 zonepath_ds = NULL;
2389                                 continue;


2402                         }
2403 
2404 
2405                         /* Mount this zone */
2406                         ret = be_mount_one_zone(be_zhp, md, zonename,
2407                             zonepath, zonepath_ds);
2408 
2409                         free(zonepath_ds);
2410                         zonepath_ds = NULL;
2411 
2412                         if (ret != BE_SUCCESS) {
2413                                 be_print_err(gettext("be_mount_zones: "
2414                                     "failed to mount zone %s under "
2415                                     "altroot %s\n"), zonename, md->altroot);
2416                                 goto done;
2417                         }
2418                 }
2419         }
2420 
2421 done:

2422         z_free_zone_list(zlst);
2423         /*
2424          * libinstzones caches mnttab and uses cached version for resolving lofs
2425          * mounts when we call z_resolve_lofs. It creates the cached version
2426          * when the first call to z_resolve_lofs happens. So, library's cached
2427          * mnttab doesn't contain entries for lofs mounts created in the above
2428          * loop. Because of this, subsequent calls to z_resolve_lofs would fail
2429          * to resolve these lofs mounts. So, here we destroy library's cached
2430          * mnttab to force its recreation when the next call to z_resolve_lofs
2431          * happens.
2432          */
2433         z_destroyMountTable();
2434         return (ret);
2435 }
2436 
2437 /*
2438  * Function:    be_unmount_zones
2439  * Description: This function finds all supported non-global zones in the
2440  *              given mounted global BE and unmounts them.
2441  * Parameters:
2442  *              ud - unmount_data_t pointer data for the global BE.
2443  * Returns:
2444  *              BE_SUCCESS - Success
2445  *              be_errno_t - Failure
2446  * Scope:
2447  *              Private
2448  */
2449 static int
2450 be_unmount_zones(be_unmount_data_t *ud)
2451 {

2452         zoneList_t              zlst = NULL;
2453         char                    *zonename = NULL;
2454         char                    *zonepath = NULL;
2455         char                    alt_zonepath[MAXPATHLEN];
2456         char                    *zonepath_ds = NULL;
2457         int                     k;
2458         int                     ret = BE_SUCCESS;
2459         boolean_t               auto_create;
2460 
2461         z_set_zone_root(ud->altroot);
2462 
2463         zlst = z_get_nonglobal_branded_zone_list();
2464         if (zlst == NULL)

2465                 return (BE_SUCCESS);

2466 
2467         for (k = 0; (zonename = z_zlist_get_zonename(zlst, k)) != NULL; k++) {
2468                 if (z_zlist_is_zone_auto_create_be(zlst, k, &auto_create) != 0) {
2469                         be_print_err(gettext("be_unmount_zones: failed to"
2470                             " get auto-create-be brand property\n"));
2471                         goto done;
2472                 }
2473 
2474                 if (!auto_create)
2475                         continue;
2476 
2477                 if (z_zlist_get_current_state(zlst, k) ==
2478                     ZONE_STATE_INSTALLED) {
2479                         zonepath = z_zlist_get_zonepath(zlst, k);
2480 
2481                         /* Build zone's zonepath wrt the global BE altroot */
2482                         (void) snprintf(alt_zonepath, sizeof (alt_zonepath),
2483                             "%s%s", ud->altroot, zonepath);
2484 
2485                         /*
2486                          * Get the dataset of this zonepath.  If its not
2487                          * a dataset, skip it.
2488                          */
2489                         if ((zonepath_ds = be_get_ds_from_dir(alt_zonepath))
2490                             == NULL)
2491                                 continue;
2492 
2493                         /*
2494                          * Check if this zone is supported based on the
2495                          * dataset of its zonepath.
2496                          */


2500                                 continue;
2501                         }
2502 
2503                         /* Unmount this zone */
2504                         ret = be_unmount_one_zone(ud, zonename, zonepath,
2505                             zonepath_ds);
2506 
2507                         free(zonepath_ds);
2508                         zonepath_ds = NULL;
2509 
2510                         if (ret != BE_SUCCESS) {
2511                                 be_print_err(gettext("be_unmount_zones:"
2512                                     " failed to unmount zone %s from "
2513                                     "altroot %s\n"), zonename, ud->altroot);
2514                                 goto done;
2515                         }
2516                 }
2517         }
2518 
2519 done:

2520         z_free_zone_list(zlst);
2521         return (ret);
2522 }
2523 
2524 /*
2525  * Function:    be_mount_one_zone
2526  * Description: This function is called to mount one zone for a given
2527  *              global BE.
2528  * Parameters:
2529  *              be_zhp - zfs_handle_t pointer to the root dataset of the
2530  *                      global BE
2531  *              md - be_mount_data_t pointer to data for global BE
2532  *              zonename - name of zone to mount
2533  *              zonepath - zonepath of zone to mount
2534  *              zonepath_ds - dataset for the zonepath
2535  * Returns:
2536  *              BE_SUCCESS - Success
2537  *              be_errno_t - Failure
2538  * Scope:
2539  *              Private