4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
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) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26
27 /*
28 * Module: zones.c
29 * Group: libinstzones
30 * Description: Provide "zones" interface for install consolidation code
31 *
32 * Public Methods:
33 * z_create_zone_admin_file - Given a location to create the file, and
34 * optionally an existing administration file, generate an
35 * administration file that can be used to perform "non-interactive"
36 * operations in a non-global zone.
37 * z_free_zone_list - free contents of zoneList_t object
38 * z_get_nonglobal_zone_list - return zoneList_t object describing all
39 * non-global native zones
40 * z_get_nonglobal_zone_list_by_brand - return zoneList_t object describing
41 * all non-global zones matching the list of zone brands passed in.
42 * z_free_brand_list - free contents of a zoneBrandList_t object
43 * z_make_brand_list - return a zoneBrandList_t object describing the list
44 * of all zone brands passed in.
45 * z_get_zonename - return the name of the current zone
46 * z_global_only - Determine if the global zone is only zone on the spec list
47 * z_lock_this_zone - lock this zone
48 * z_lock_zones - lock specified zones
49 * z_mount_in_lz - Mount global zone directory in specified zone's root file
50 * system
51 * z_non_global_zones_exist - Determine if any non-global native zones exist
52 * z_on_zone_spec - Determine if named zone is on the zone_spec list
53 * z_running_in_global_zone - Determine if running in the "global" zone
54 * z_set_output_functions - Link program specific output functions
55 * z_set_zone_root - Set root for zones library operations
56 * z_set_zone_spec - Set list of zones on which actions will be performed
57 * z_umount_lz_mount - Unmount directory mounted with z_mount_in_lz
58 * z_unlock_this_zone - unlock this zone
59 * z_unlock_zones - unlock specified zones
413 head = brand;
414 brand->string_ptr = strdup(str);
415 brand->next = NULL;
416
417 while ((str = strtok(NULL, delim)) != NULL) {
418 if ((brand->next = (zoneBrandList_t *)
419 malloc(sizeof (struct _zoneBrandList))) == NULL) {
420 return (NULL);
421 }
422
423 brand = brand->next;
424 brand->string_ptr = strdup(str);
425 brand->next = NULL;
426 }
427 }
428
429 free(blist);
430 return (head);
431 }
432
433 /*
434 * Name: z_get_nonglobal_zone_list_by_brand
435 * Description: return zoneList_t object describing all non-global
436 * zones matching the list of brands passed in.
437 * Arguments: brands - The list of zone brands to look for.
438 * Returns: zoneList_t
439 * == NULL - error, list could not be generated
440 * != NULL - success, list returned
441 * NOTE: Any zoneList_t returned is placed in new storage for the
442 * calling function. The caller must use 'z_free_zone_list' to
443 * dispose of the storage once the list is no longer needed.
444 */
445 zoneList_t
446 z_get_nonglobal_zone_list_by_brand(zoneBrandList_t *brands)
447 {
448 FILE *zoneIndexFP;
449 int numzones = 0;
450 struct zoneent *ze;
451 zoneList_t zlst = NULL;
452 FILE *mapFP;
453 char zonename[ZONENAME_MAX];
454 zone_spec_t *zent;
455
456 /* if zones are not implemented, return empty list */
457
458 if (!z_zones_are_implemented()) {
459 return ((zoneList_t)NULL);
460 }
461
462 /*
463 * Open the zone index file. Note that getzoneent_private() handles
464 * NULL.
465 */
466 zoneIndexFP = setzoneent();
467
468 mapFP = zonecfg_open_scratch("", B_FALSE);
469
470 /* index file open; scan all zones; see if any are at least installed */
471
472 while ((ze = getzoneent_private(zoneIndexFP)) != NULL) {
473 zone_state_t st;
474
475 /* skip the global zone */
476
477 if (strcmp(ze->zone_name, GLOBAL_ZONENAME) == 0) {
478 free(ze);
479 continue;
480 }
481
482 /*
483 * skip any zones with brands not on the brand list
484 */
485 if (!z_is_zone_brand_in_list(ze->zone_name, brands)) {
486 free(ze);
487 continue;
488 }
489
490 /*
491 * If the user specified an explicit zone list, then ignore any
492 * zones that aren't on that list.
493 */
494 if ((zent = _z_global_data._zone_spec) != NULL) {
495 while (zent != NULL) {
496 if (strcmp(zent->zl_name, ze->zone_name) == 0)
497 break;
498 zent = zent->zl_next;
499 }
500 if (zent == NULL) {
501 free(ze);
502 continue;
503 }
504 }
505
549
550 zlst[numzones]._zlOrigKernelStatus = st;
551 zlst[numzones]._zlCurrKernelStatus = st;
552
553 numzones++;
554 free(ze);
555 }
556
557 /* close the index file */
558 endzoneent(zoneIndexFP);
559
560 if (mapFP != NULL)
561 zonecfg_close_scratch(mapFP);
562
563 /* return generated list */
564
565 return (zlst);
566 }
567
568 /*
569 * Name: z_get_zonename
570 * Description: return the name of the current zone
571 * Arguments: void
572 * Returns: char *
573 * - pointer to string representing the name of the current
574 * zone
575 * NOTE: Any string returned is placed in new storage for the
576 * calling function. The caller must use 'Free' to dispose
577 * of the storage once the string is no longer needed.
578 */
579
580 char *
581 z_get_zonename(void)
582 {
583 ssize_t zonenameLen;
584 char zonename[ZONENAME_MAX];
585 zoneid_t zoneid = (zoneid_t)-1;
586
587 /* if zones are not implemented, return "" */
588
1875
1876 if (a_zlst == (zoneList_t)NULL) {
1877 return ((char *)NULL);
1878 }
1879
1880 /* find the specified zone in the list */
1881
1882 for (i = 0; (i != a_zoneIndex) &&
1883 (a_zlst[i]._zlName != (char *)NULL); i++)
1884 ;
1885
1886 /* return error if the specified zone does not exist */
1887
1888 if (a_zlst[i]._zlName == (char *)NULL) {
1889 return (NULL);
1890 }
1891
1892 /* return selected zone's zonepath */
1893
1894 return (a_zlst[i]._zlPath);
1895 }
1896
1897 boolean_t
1898 z_zlist_is_zone_runnable(zoneList_t a_zlst, int a_zoneIndex)
1899 {
1900 int i;
1901
1902 /* if zones are not implemented, return error */
1903
1904 if (z_zones_are_implemented() == B_FALSE) {
1905 return (B_FALSE);
1906 }
1907
1908 /* ignore empty list */
1909
1910 if (a_zlst == (zoneList_t)NULL) {
1911 return (B_FALSE);
1912 }
1913
1914 /* find the specified zone in the list */
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
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) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
25 */
26
27
28 /*
29 * Module: zones.c
30 * Group: libinstzones
31 * Description: Provide "zones" interface for install consolidation code
32 *
33 * Public Methods:
34 * z_create_zone_admin_file - Given a location to create the file, and
35 * optionally an existing administration file, generate an
36 * administration file that can be used to perform "non-interactive"
37 * operations in a non-global zone.
38 * z_free_zone_list - free contents of zoneList_t object
39 * z_get_nonglobal_zone_list - return zoneList_t object describing all
40 * non-global native zones
41 * z_get_nonglobal_branded_zone_list - return zoneList_t object describing
42 * all branded non-global zones
43 * z_get_nonglobal_zone_list_by_brand - return zoneList_t object describing
44 * all non-global zones matching the list of zone brands passed in.
45 * z_free_brand_list - free contents of a zoneBrandList_t object
46 * z_make_brand_list - return a zoneBrandList_t object describing the list
47 * of all zone brands passed in.
48 * z_get_zonename - return the name of the current zone
49 * z_global_only - Determine if the global zone is only zone on the spec list
50 * z_lock_this_zone - lock this zone
51 * z_lock_zones - lock specified zones
52 * z_mount_in_lz - Mount global zone directory in specified zone's root file
53 * system
54 * z_non_global_zones_exist - Determine if any non-global native zones exist
55 * z_on_zone_spec - Determine if named zone is on the zone_spec list
56 * z_running_in_global_zone - Determine if running in the "global" zone
57 * z_set_output_functions - Link program specific output functions
58 * z_set_zone_root - Set root for zones library operations
59 * z_set_zone_spec - Set list of zones on which actions will be performed
60 * z_umount_lz_mount - Unmount directory mounted with z_mount_in_lz
61 * z_unlock_this_zone - unlock this zone
62 * z_unlock_zones - unlock specified zones
416 head = brand;
417 brand->string_ptr = strdup(str);
418 brand->next = NULL;
419
420 while ((str = strtok(NULL, delim)) != NULL) {
421 if ((brand->next = (zoneBrandList_t *)
422 malloc(sizeof (struct _zoneBrandList))) == NULL) {
423 return (NULL);
424 }
425
426 brand = brand->next;
427 brand->string_ptr = strdup(str);
428 brand->next = NULL;
429 }
430 }
431
432 free(blist);
433 return (head);
434 }
435
436 static zoneList_t
437 i_get_nonglobal_branded_zone_list(boolean_t (*include)(struct zoneent *,
438 void *), void *arg)
439 {
440 FILE *zoneIndexFP;
441 int numzones = 0;
442 struct zoneent *ze;
443 zoneList_t zlst = NULL;
444 FILE *mapFP;
445 char zonename[ZONENAME_MAX];
446 zone_spec_t *zent;
447
448 /* if zones are not implemented, return empty list */
449
450 if (!z_zones_are_implemented()) {
451 return ((zoneList_t)NULL);
452 }
453
454 /*
455 * Open the zone index file. Note that getzoneent_private() handles
456 * NULL.
457 */
458 zoneIndexFP = setzoneent();
459
460 mapFP = zonecfg_open_scratch("", B_FALSE);
461
462 /* index file open; scan all zones; see if any are at least installed */
463
464 while ((ze = getzoneent_private(zoneIndexFP)) != NULL) {
465 zone_state_t st;
466
467 /* skip the global zone */
468
469 if (strcmp(ze->zone_name, GLOBAL_ZONENAME) == 0) {
470 free(ze);
471 continue;
472 }
473
474 /*
475 * skip any zones the filter function doesn't like
476 */
477 if (include != NULL && !include(ze, arg)) {
478 free(ze);
479 continue;
480 }
481
482 /*
483 * If the user specified an explicit zone list, then ignore any
484 * zones that aren't on that list.
485 */
486 if ((zent = _z_global_data._zone_spec) != NULL) {
487 while (zent != NULL) {
488 if (strcmp(zent->zl_name, ze->zone_name) == 0)
489 break;
490 zent = zent->zl_next;
491 }
492 if (zent == NULL) {
493 free(ze);
494 continue;
495 }
496 }
497
541
542 zlst[numzones]._zlOrigKernelStatus = st;
543 zlst[numzones]._zlCurrKernelStatus = st;
544
545 numzones++;
546 free(ze);
547 }
548
549 /* close the index file */
550 endzoneent(zoneIndexFP);
551
552 if (mapFP != NULL)
553 zonecfg_close_scratch(mapFP);
554
555 /* return generated list */
556
557 return (zlst);
558 }
559
560 /*
561 * Name: z_get_nonglobal_branded_zone_list
562 * Description: return zoneList_t object describing all non-global
563 * Returns: zoneList_t
564 * == NULL - error, list could not be generated
565 * != NULL - success, list returned
566 * NOTE: Any zoneList_t returned is placed in new storage for the
567 * calling function. The caller must use 'z_free_zone_list' to
568 * dispose of the storage once the list is no longer needed.
569 */
570 zoneList_t
571 z_get_nonglobal_branded_zone_list(void)
572 {
573 return (i_get_nonglobal_branded_zone_list(NULL, NULL));
574 }
575
576 static boolean_t
577 X(struct zoneent *ze, void *arg)
578 {
579 zoneBrandList_t *brands = arg;
580
581 return (z_is_zone_brand_in_list(ze->zone_name, brands));
582 }
583
584 /*
585 * Name: z_get_nonglobal_zone_list_by_brand
586 * Description: return zoneList_t object describing all non-global
587 * zones matching the list of brands passed in.
588 * Arguments: brands - The list of zone brands to look for.
589 * Returns: zoneList_t
590 * == NULL - error, list could not be generated
591 * != NULL - success, list returned
592 * NOTE: Any zoneList_t returned is placed in new storage for the
593 * calling function. The caller must use 'z_free_zone_list' to
594 * dispose of the storage once the list is no longer needed.
595 */
596 zoneList_t
597 z_get_nonglobal_zone_list_by_brand(zoneBrandList_t *brands)
598 {
599 return (i_get_nonglobal_branded_zone_list(X, brands));
600 }
601
602 /*
603 * Name: z_get_zonename
604 * Description: return the name of the current zone
605 * Arguments: void
606 * Returns: char *
607 * - pointer to string representing the name of the current
608 * zone
609 * NOTE: Any string returned is placed in new storage for the
610 * calling function. The caller must use 'Free' to dispose
611 * of the storage once the string is no longer needed.
612 */
613
614 char *
615 z_get_zonename(void)
616 {
617 ssize_t zonenameLen;
618 char zonename[ZONENAME_MAX];
619 zoneid_t zoneid = (zoneid_t)-1;
620
621 /* if zones are not implemented, return "" */
622
1909
1910 if (a_zlst == (zoneList_t)NULL) {
1911 return ((char *)NULL);
1912 }
1913
1914 /* find the specified zone in the list */
1915
1916 for (i = 0; (i != a_zoneIndex) &&
1917 (a_zlst[i]._zlName != (char *)NULL); i++)
1918 ;
1919
1920 /* return error if the specified zone does not exist */
1921
1922 if (a_zlst[i]._zlName == (char *)NULL) {
1923 return (NULL);
1924 }
1925
1926 /* return selected zone's zonepath */
1927
1928 return (a_zlst[i]._zlPath);
1929 }
1930
1931 int
1932 z_zlist_is_zone_auto_create_be(zoneList_t zlst, int idx, boolean_t *ret)
1933 {
1934 char brandname[MAXNAMELEN];
1935 brand_handle_t bh;
1936
1937 if (zone_get_brand(z_zlist_get_zonename(zlst, idx), brandname,
1938 sizeof (brandname)) != Z_OK)
1939 return (-1);
1940
1941 bh = brand_open(brandname);
1942 if (bh == NULL)
1943 return (-1);
1944
1945 *ret = brand_auto_create_be(bh);
1946
1947 brand_close(bh);
1948
1949 return (0);
1950 }
1951
1952 boolean_t
1953 z_zlist_is_zone_runnable(zoneList_t a_zlst, int a_zoneIndex)
1954 {
1955 int i;
1956
1957 /* if zones are not implemented, return error */
1958
1959 if (z_zones_are_implemented() == B_FALSE) {
1960 return (B_FALSE);
1961 }
1962
1963 /* ignore empty list */
1964
1965 if (a_zlst == (zoneList_t)NULL) {
1966 return (B_FALSE);
1967 }
1968
1969 /* find the specified zone in the list */
|