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
|