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) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2015 by Delphix. All rights reserved.
26 */
27
28 /*
29 * zoneadm is a command interpreter for zone administration. It is all in
30 * C (i.e., no lex/yacc), and all the argument passing is argc/argv based.
31 * main() calls parse_and_run() which calls cmd_match(), then invokes the
32 * appropriate command's handler function. The rest of the program is the
33 * handler functions and their helper functions.
34 *
35 * Some of the helper functions are used largely to simplify I18N: reducing
36 * the need for translation notes. This is particularly true of many of
37 * the zerror() calls: doing e.g. zerror(gettext("%s failed"), "foo") rather
38 * than zerror(gettext("foo failed")) with a translation note indicating
39 * that "foo" need not be translated.
40 */
41
42 #include <stdio.h>
43 #include <errno.h>
44 #include <unistd.h>
45 #include <signal.h>
84 #include <pwd.h>
85 #include <auth_list.h>
86 #include <auth_attr.h>
87 #include <secdb.h>
88
89 #include "zoneadm.h"
90
91 #define MAXARGS 8
92 #define SOURCE_ZONE (CMD_MAX + 1)
93
94 /* Reflects kernel zone entries */
95 typedef struct zone_entry {
96 zoneid_t zid;
97 char zname[ZONENAME_MAX];
98 char *zstate_str;
99 zone_state_t zstate_num;
100 char zbrand[MAXNAMELEN];
101 char zroot[MAXPATHLEN];
102 char zuuid[UUID_PRINTABLE_STRING_LENGTH];
103 zone_iptype_t ziptype;
104 } zone_entry_t;
105
106 #define CLUSTER_BRAND_NAME "cluster"
107
108 static zone_entry_t *zents;
109 static size_t nzents;
110
111 #define LOOPBACK_IF "lo0"
112 #define SOCKET_AF(af) (((af) == AF_UNSPEC) ? AF_INET : (af))
113
114 struct net_if {
115 char *name;
116 int af;
117 };
118
119 /* 0755 is the default directory mode. */
120 #define DEFAULT_DIR_MODE \
121 (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
122
123 struct cmd {
426 char *ip_type_str;
427
428 /* Skip a zone that shutdown while we were collecting data. */
429 if (zent->zname[0] == '\0')
430 return;
431
432 if (zent->ziptype == ZS_EXCLUSIVE)
433 ip_type_str = "excl";
434 else
435 ip_type_str = "shared";
436
437 assert(!(verbose && parsable));
438 if (firsttime && verbose) {
439 firsttime = B_FALSE;
440 (void) printf("%*s %-16s %-10s %-30s %-8s %-6s\n",
441 ZONEID_WIDTH, "ID", "NAME", "STATUS", "PATH", "BRAND",
442 "IP");
443 }
444 if (!verbose) {
445 char *cp, *clim;
446
447 if (!parsable) {
448 (void) printf("%s\n", zent->zname);
449 return;
450 }
451 if (zent->zid == ZONE_ID_UNDEFINED)
452 (void) printf("-");
453 else
454 (void) printf("%lu", zent->zid);
455 (void) printf(":%s:%s:", zent->zname, zent->zstate_str);
456 cp = zent->zroot;
457 while ((clim = strchr(cp, ':')) != NULL) {
458 (void) printf("%.*s\\:", clim - cp, cp);
459 cp = clim + 1;
460 }
461 (void) printf("%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand,
462 ip_type_str);
463 return;
464 }
465 if (zent->zstate_str != NULL) {
466 if (zent->zid == ZONE_ID_UNDEFINED)
467 (void) printf("%*s", ZONEID_WIDTH, "-");
468 else
469 (void) printf("%*lu", ZONEID_WIDTH, zent->zid);
470 (void) printf(" %-16s %-10s %-30s %-8s %-6s\n", zent->zname,
471 zent->zstate_str, zent->zroot, zent->zbrand, ip_type_str);
472 }
473 }
474
475 static int
476 lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent)
477 {
478 char root[MAXPATHLEN], *cp;
479 int err;
480 uuid_t uuid;
481 zone_dochandle_t handle;
482
537 */
538 if (getzoneid() != GLOBAL_ZONEID) {
539 assert(is_system_labeled() != 0);
540 (void) strlcpy(zent->zbrand, default_brand,
541 sizeof (zent->zbrand));
542 } else if (zone_get_brand(zent->zname, zent->zbrand,
543 sizeof (zent->zbrand)) != Z_OK) {
544 zperror2(zent->zname, gettext("could not get brand name"));
545 return (Z_ERR);
546 }
547
548 /*
549 * Get ip type of the zone.
550 * Note for global zone, ZS_SHARED is set always.
551 */
552 if (zid == GLOBAL_ZONEID) {
553 zent->ziptype = ZS_SHARED;
554 return (Z_OK);
555 }
556
557 /*
558 * There is a race condition where the zone could boot while
559 * we're walking the index file. In this case the zone state
560 * could be seen as running from the call above, but the zoneid
561 * would be undefined.
562 *
563 * There is also a race condition where the zone could shutdown after
564 * we got its running state above. This is also not an error and
565 * we fall back to getting the ziptype from the zone configuration.
566 */
567 if (zent->zstate_num == ZONE_STATE_RUNNING &&
568 zid != ZONE_ID_UNDEFINED) {
569 ushort_t flags;
570
571 if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags,
572 sizeof (flags)) >= 0) {
573 if (flags & ZF_NET_EXCL)
574 zent->ziptype = ZS_EXCLUSIVE;
575 else
576 zent->ziptype = ZS_SHARED;
577 return (Z_OK);
578 }
579 }
580
581 if ((handle = zonecfg_init_handle()) == NULL) {
582 zperror2(zent->zname, gettext("could not init handle"));
583 return (Z_ERR);
584 }
585 if ((err = zonecfg_get_handle(zent->zname, handle)) != Z_OK) {
586 zperror2(zent->zname, gettext("could not get handle"));
587 zonecfg_fini_handle(handle);
588 return (Z_ERR);
589 }
590
591 if ((err = zonecfg_get_iptype(handle, &zent->ziptype)) != Z_OK) {
592 zperror2(zent->zname, gettext("could not get ip-type"));
593 zonecfg_fini_handle(handle);
594 return (Z_ERR);
595 }
596 zonecfg_fini_handle(handle);
597
598 return (Z_OK);
599 }
600
601 /*
602 * fetch_zents() calls zone_list(2) to find out how many zones are running
603 * (which is stored in the global nzents), then calls zone_list(2) again
604 * to fetch the list of running zones (stored in the global zents). This
605 * function may be called multiple times, so if zents is already set, we
606 * return immediately to save work.
607 *
608 * Note that the data about running zones can change while this function
609 * is running, so its possible that the list of zones will have empty slots
610 * at the end.
611 */
612
613 static int
614 fetch_zents(void)
615 {
616 zoneid_t *zids = NULL;
749 if (i < nzents) {
750 free(name);
751 continue;
752 }
753 if (lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) {
754 free(name);
755 continue;
756 }
757 free(name);
758 if (zent.zstate_num >= min_state)
759 zone_print(&zent, verbose, parsable);
760 }
761 endzoneent(cookie);
762 return (Z_OK);
763 }
764
765 /*
766 * Retrieve a zone entry by name. Returns NULL if no such zone exists.
767 */
768 static zone_entry_t *
769 lookup_running_zone(const char *str)
770 {
771 int i;
772
773 if (fetch_zents() != Z_OK)
774 return (NULL);
775
776 for (i = 0; i < nzents; i++) {
777 if (strcmp(str, zents[i].zname) == 0)
778 return (&zents[i]);
779 }
780 return (NULL);
781 }
782
783 /*
784 * Check a bit in a mode_t: if on is B_TRUE, that bit should be on; if
785 * B_FALSE, it should be off. Return B_TRUE if the mode is bad (incorrect).
786 */
787 static boolean_t
788 bad_mode_bit(mode_t mode, mode_t bit, boolean_t on, char *file)
789 {
790 char *str;
791
792 assert(bit == S_IRUSR || bit == S_IWUSR || bit == S_IXUSR ||
793 bit == S_IRGRP || bit == S_IWGRP || bit == S_IXGRP ||
794 bit == S_IROTH || bit == S_IWOTH || bit == S_IXOTH);
795 /*
796 * TRANSLATION_NOTE
797 * The strings below will be used as part of a larger message,
798 * either:
799 * (file name) must be (owner|group|world) (read|writ|execut)able
800 * or
2766 return_code = Z_ERR;
2767 if (!in_alt_root && verify_brand(handle, cmd_num, argv) != Z_OK)
2768 return_code = Z_ERR;
2769 if (!in_alt_root && verify_datasets(handle) != Z_OK)
2770 return_code = Z_ERR;
2771
2772 /*
2773 * As the "mount" command is used for patching/upgrading of zones
2774 * or other maintenance processes, the zone's privilege set is not
2775 * checked in this case. Instead, the default, safe set of
2776 * privileges will be used when this zone is created in the
2777 * kernel.
2778 */
2779 if (!in_alt_root && cmd_num != CMD_MOUNT &&
2780 verify_limitpriv(handle) != Z_OK)
2781 return_code = Z_ERR;
2782
2783 return (return_code);
2784 }
2785
2786 static int
2787 verify_details(int cmd_num, char *argv[])
2788 {
2789 zone_dochandle_t handle;
2790 char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN];
2791 int return_code = Z_OK;
2792 int err;
2793
2794 if ((handle = zonecfg_init_handle()) == NULL) {
2795 zperror(cmd_to_str(cmd_num), B_TRUE);
2796 return (Z_ERR);
2797 }
2798 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) {
2799 errno = err;
2800 zperror(cmd_to_str(cmd_num), B_TRUE);
2801 zonecfg_fini_handle(handle);
2802 return (Z_ERR);
2803 }
2804 if ((err = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath))) !=
2805 Z_OK) {
2825 * TRANSLATION_NOTE
2826 * XML and zonepath are literals that should not be translated.
2827 */
2828 (void) fprintf(stderr, gettext("The XML repository has "
2829 "zonepath '%s',\nbut the index file has zonepath '%s'.\n"
2830 "These must match, so fix the incorrect entry.\n"),
2831 zonepath, checkpath);
2832 zonecfg_fini_handle(handle);
2833 return (Z_ERR);
2834 }
2835 if (cmd_num != CMD_ATTACH &&
2836 validate_zonepath(zonepath, cmd_num) != Z_OK) {
2837 (void) fprintf(stderr, gettext("could not verify zonepath %s "
2838 "because of the above errors.\n"), zonepath);
2839 return_code = Z_ERR;
2840 }
2841
2842 if (verify_handle(cmd_num, handle, argv) != Z_OK)
2843 return_code = Z_ERR;
2844
2845 zonecfg_fini_handle(handle);
2846 if (return_code == Z_ERR)
2847 (void) fprintf(stderr,
2848 gettext("%s: zone %s failed to verify\n"),
2849 execname, target_zone);
2850 return (return_code);
2851 }
2852
2853 static int
2854 verify_func(int argc, char *argv[])
2855 {
2856 int arg;
2857
2858 optind = 0;
2859 if ((arg = getopt(argc, argv, "?")) != EOF) {
2860 switch (arg) {
2861 case '?':
2862 sub_usage(SHELP_VERIFY, CMD_VERIFY);
2863 return (optopt == '?' ? Z_OK : Z_USAGE);
2864 default:
3848 * If the "all" parameter is true then we should remove the whole zonepath
3849 * even if it has non-standard files/directories in it. This can be used when
3850 * we need to cleanup after moving the zonepath across file systems.
3851 *
3852 * We "exec" the RMCOMMAND so that the returned status is that of RMCOMMAND
3853 * and not the shell.
3854 */
3855 static int
3856 cleanup_zonepath(char *zonepath, boolean_t all)
3857 {
3858 int status;
3859 int i;
3860 boolean_t non_std = B_FALSE;
3861 struct dirent *dp;
3862 DIR *dirp;
3863 /*
3864 * The SUNWattached.xml file is expected since it might
3865 * exist if the zone was force-attached after a
3866 * migration.
3867 */
3868 char *std_entries[] = {"dev", "lu", "root",
3869 "SUNWattached.xml", NULL};
3870 /* (MAXPATHLEN * 3) is for the 3 std_entries dirs */
3871 char cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 3) + 64];
3872
3873 /*
3874 * We shouldn't need these checks but lets be paranoid since we
3875 * could blow away the whole system here if we got the wrong zonepath.
3876 */
3877 if (*zonepath == NULL || strcmp(zonepath, "/") == 0) {
3878 (void) fprintf(stderr, "invalid zonepath '%s'\n", zonepath);
3879 return (Z_INVAL);
3880 }
3881
3882 /*
3883 * If the dirpath is already gone (maybe it was manually removed) then
3884 * we just return Z_OK so that the cleanup is successful.
3885 */
3886 if ((dirp = opendir(zonepath)) == NULL)
3887 return (Z_OK);
3888
3889 /*
3890 * Look through the zonepath directory to see if there are any
3891 * non-standard files/dirs. Also skip .zfs since that might be
5358 /*
5359 * This is an undocumented interface which is currently only used to apply
5360 * the global zone resource management settings when the system boots.
5361 * This function does not yet properly handle updating a running system so
5362 * any projects running in the zone would be trashed if this function
5363 * were to run after the zone had booted. It also does not reset any
5364 * rctl settings that were removed from zonecfg. There is still work to be
5365 * done before we can properly support dynamically updating the resource
5366 * management settings for a running zone (global or non-global). Thus, this
5367 * functionality is undocumented for now.
5368 */
5369 /* ARGSUSED */
5370 static int
5371 apply_func(int argc, char *argv[])
5372 {
5373 int err;
5374 int res = Z_OK;
5375 priv_set_t *privset;
5376 zoneid_t zoneid;
5377 zone_dochandle_t handle;
5378 struct zone_mcaptab mcap;
5379 char pool_err[128];
5380
5381 zoneid = getzoneid();
5382
5383 if (zonecfg_in_alt_root() || zoneid != GLOBAL_ZONEID ||
5384 target_zone == NULL || strcmp(target_zone, GLOBAL_ZONENAME) != 0)
5385 return (usage(B_FALSE));
5386
5387 if ((privset = priv_allocset()) == NULL) {
5388 zerror(gettext("%s failed"), "priv_allocset");
5389 return (Z_ERR);
5390 }
5391
5392 if (getppriv(PRIV_EFFECTIVE, privset) != 0) {
5393 zerror(gettext("%s failed"), "getppriv");
5394 priv_freeset(privset);
5395 return (Z_ERR);
5396 }
5397
5398 if (priv_isfullset(privset) == B_FALSE) {
5449 pool_err);
5450 else
5451 zerror(gettext("could not bind zone to "
5452 "temporary pool: %s"),
5453 zonecfg_strerror(err));
5454 res = Z_ERR;
5455 }
5456
5457 if ((err = zonecfg_bind_pool(handle, zoneid, pool_err,
5458 sizeof (pool_err))) != Z_OK) {
5459 if (err == Z_POOL || err == Z_POOL_BIND)
5460 zerror("%s: %s", zonecfg_strerror(err),
5461 pool_err);
5462 else
5463 zerror("%s", zonecfg_strerror(err));
5464 }
5465 }
5466 }
5467
5468 /*
5469 * If a memory cap is configured, set the cap in the kernel using
5470 * zone_setattr() and make sure the rcapd SMF service is enabled.
5471 */
5472 if (zonecfg_getmcapent(handle, &mcap) == Z_OK) {
5473 uint64_t num;
5474 char smf_err[128];
5475
5476 num = (uint64_t)strtoll(mcap.zone_physmem_cap, NULL, 10);
5477 if (zone_setattr(zoneid, ZONE_ATTR_PHYS_MCAP, &num, 0) == -1) {
5478 zerror(gettext("could not set zone memory cap"));
5479 res = Z_ERR;
5480 }
5481
5482 if (zonecfg_enable_rcapd(smf_err, sizeof (smf_err)) != Z_OK) {
5483 zerror(gettext("enabling system/rcap service failed: "
5484 "%s"), smf_err);
5485 res = Z_ERR;
5486 }
5487 }
5488
5489 zonecfg_fini_handle(handle);
5490
5491 return (res);
5492 }
5493
5494 /*
5495 * This is an undocumented interface that is invoked by the zones SMF service
5496 * for installed zones that won't automatically boot.
5497 */
5498 /* ARGSUSED */
5499 static int
5500 sysboot_func(int argc, char *argv[])
5501 {
|
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) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2015 by Delphix. All rights reserved.
26 * Copyright 2015, Joyent Inc. All rights reserved.
27 */
28
29 /*
30 * zoneadm is a command interpreter for zone administration. It is all in
31 * C (i.e., no lex/yacc), and all the argument passing is argc/argv based.
32 * main() calls parse_and_run() which calls cmd_match(), then invokes the
33 * appropriate command's handler function. The rest of the program is the
34 * handler functions and their helper functions.
35 *
36 * Some of the helper functions are used largely to simplify I18N: reducing
37 * the need for translation notes. This is particularly true of many of
38 * the zerror() calls: doing e.g. zerror(gettext("%s failed"), "foo") rather
39 * than zerror(gettext("foo failed")) with a translation note indicating
40 * that "foo" need not be translated.
41 */
42
43 #include <stdio.h>
44 #include <errno.h>
45 #include <unistd.h>
46 #include <signal.h>
85 #include <pwd.h>
86 #include <auth_list.h>
87 #include <auth_attr.h>
88 #include <secdb.h>
89
90 #include "zoneadm.h"
91
92 #define MAXARGS 8
93 #define SOURCE_ZONE (CMD_MAX + 1)
94
95 /* Reflects kernel zone entries */
96 typedef struct zone_entry {
97 zoneid_t zid;
98 char zname[ZONENAME_MAX];
99 char *zstate_str;
100 zone_state_t zstate_num;
101 char zbrand[MAXNAMELEN];
102 char zroot[MAXPATHLEN];
103 char zuuid[UUID_PRINTABLE_STRING_LENGTH];
104 zone_iptype_t ziptype;
105 zoneid_t zdid;
106 } zone_entry_t;
107
108 #define CLUSTER_BRAND_NAME "cluster"
109
110 static zone_entry_t *zents;
111 static size_t nzents;
112
113 #define LOOPBACK_IF "lo0"
114 #define SOCKET_AF(af) (((af) == AF_UNSPEC) ? AF_INET : (af))
115
116 struct net_if {
117 char *name;
118 int af;
119 };
120
121 /* 0755 is the default directory mode. */
122 #define DEFAULT_DIR_MODE \
123 (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
124
125 struct cmd {
428 char *ip_type_str;
429
430 /* Skip a zone that shutdown while we were collecting data. */
431 if (zent->zname[0] == '\0')
432 return;
433
434 if (zent->ziptype == ZS_EXCLUSIVE)
435 ip_type_str = "excl";
436 else
437 ip_type_str = "shared";
438
439 assert(!(verbose && parsable));
440 if (firsttime && verbose) {
441 firsttime = B_FALSE;
442 (void) printf("%*s %-16s %-10s %-30s %-8s %-6s\n",
443 ZONEID_WIDTH, "ID", "NAME", "STATUS", "PATH", "BRAND",
444 "IP");
445 }
446 if (!verbose) {
447 char *cp, *clim;
448 char zdid[80];
449
450 if (!parsable) {
451 (void) printf("%s\n", zent->zname);
452 return;
453 }
454 if (zent->zid == ZONE_ID_UNDEFINED)
455 (void) printf("-");
456 else
457 (void) printf("%lu", zent->zid);
458 (void) printf(":%s:%s:", zent->zname, zent->zstate_str);
459 cp = zent->zroot;
460 while ((clim = strchr(cp, ':')) != NULL) {
461 (void) printf("%.*s\\:", clim - cp, cp);
462 cp = clim + 1;
463 }
464 if (zent->zdid == -1)
465 zdid[0] = '\0';
466 else
467 (void) snprintf(zdid, sizeof (zdid), "%d", zent->zdid);
468 (void) printf("%s:%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand,
469 ip_type_str, zdid);
470 return;
471 }
472 if (zent->zstate_str != NULL) {
473 if (zent->zid == ZONE_ID_UNDEFINED)
474 (void) printf("%*s", ZONEID_WIDTH, "-");
475 else
476 (void) printf("%*lu", ZONEID_WIDTH, zent->zid);
477 (void) printf(" %-16s %-10s %-30s %-8s %-6s\n", zent->zname,
478 zent->zstate_str, zent->zroot, zent->zbrand, ip_type_str);
479 }
480 }
481
482 static int
483 lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent)
484 {
485 char root[MAXPATHLEN], *cp;
486 int err;
487 uuid_t uuid;
488 zone_dochandle_t handle;
489
544 */
545 if (getzoneid() != GLOBAL_ZONEID) {
546 assert(is_system_labeled() != 0);
547 (void) strlcpy(zent->zbrand, default_brand,
548 sizeof (zent->zbrand));
549 } else if (zone_get_brand(zent->zname, zent->zbrand,
550 sizeof (zent->zbrand)) != Z_OK) {
551 zperror2(zent->zname, gettext("could not get brand name"));
552 return (Z_ERR);
553 }
554
555 /*
556 * Get ip type of the zone.
557 * Note for global zone, ZS_SHARED is set always.
558 */
559 if (zid == GLOBAL_ZONEID) {
560 zent->ziptype = ZS_SHARED;
561 return (Z_OK);
562 }
563
564 if ((handle = zonecfg_init_handle()) == NULL) {
565 zperror2(zent->zname, gettext("could not init handle"));
566 return (Z_ERR);
567 }
568 if ((err = zonecfg_get_handle(zent->zname, handle)) != Z_OK) {
569 zperror2(zent->zname, gettext("could not get handle"));
570 zonecfg_fini_handle(handle);
571 return (Z_ERR);
572 }
573
574 if ((err = zonecfg_get_iptype(handle, &zent->ziptype)) != Z_OK) {
575 zperror2(zent->zname, gettext("could not get ip-type"));
576 zonecfg_fini_handle(handle);
577 return (Z_ERR);
578 }
579
580 /*
581 * There is a race condition where the zone could boot while
582 * we're walking the index file. In this case the zone state
583 * could be seen as running from the call above, but the zoneid
584 * would be undefined.
585 *
586 * There is also a race condition where the zone could shutdown after
587 * we got its running state above. This is also not an error and
588 * we fall back to getting the ziptype from the zone configuration.
589 */
590 if (zent->zstate_num == ZONE_STATE_RUNNING &&
591 zid != ZONE_ID_UNDEFINED) {
592 ushort_t flags;
593
594 if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags,
595 sizeof (flags)) >= 0) {
596 if (flags & ZF_NET_EXCL)
597 zent->ziptype = ZS_EXCLUSIVE;
598 else
599 zent->ziptype = ZS_SHARED;
600 }
601 }
602
603 zent->zdid = zonecfg_get_did(handle);
604
605 zonecfg_fini_handle(handle);
606
607 return (Z_OK);
608 }
609
610 /*
611 * fetch_zents() calls zone_list(2) to find out how many zones are running
612 * (which is stored in the global nzents), then calls zone_list(2) again
613 * to fetch the list of running zones (stored in the global zents). This
614 * function may be called multiple times, so if zents is already set, we
615 * return immediately to save work.
616 *
617 * Note that the data about running zones can change while this function
618 * is running, so its possible that the list of zones will have empty slots
619 * at the end.
620 */
621
622 static int
623 fetch_zents(void)
624 {
625 zoneid_t *zids = NULL;
758 if (i < nzents) {
759 free(name);
760 continue;
761 }
762 if (lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) {
763 free(name);
764 continue;
765 }
766 free(name);
767 if (zent.zstate_num >= min_state)
768 zone_print(&zent, verbose, parsable);
769 }
770 endzoneent(cookie);
771 return (Z_OK);
772 }
773
774 /*
775 * Retrieve a zone entry by name. Returns NULL if no such zone exists.
776 */
777 static zone_entry_t *
778 lookup_running_zone(const char *name)
779 {
780 zoneid_t zid;
781 zone_entry_t *zent;
782
783 if ((zid = getzoneidbyname(name)) == -1)
784 return (NULL);
785
786 if ((zent = malloc(sizeof (zone_entry_t))) == NULL)
787 return (NULL);
788
789 if (lookup_zone_info(name, zid, zent) != Z_OK) {
790 free(zent);
791 return (NULL);
792 }
793 return (zent);
794 }
795
796 /*
797 * Check a bit in a mode_t: if on is B_TRUE, that bit should be on; if
798 * B_FALSE, it should be off. Return B_TRUE if the mode is bad (incorrect).
799 */
800 static boolean_t
801 bad_mode_bit(mode_t mode, mode_t bit, boolean_t on, char *file)
802 {
803 char *str;
804
805 assert(bit == S_IRUSR || bit == S_IWUSR || bit == S_IXUSR ||
806 bit == S_IRGRP || bit == S_IWGRP || bit == S_IXGRP ||
807 bit == S_IROTH || bit == S_IWOTH || bit == S_IXOTH);
808 /*
809 * TRANSLATION_NOTE
810 * The strings below will be used as part of a larger message,
811 * either:
812 * (file name) must be (owner|group|world) (read|writ|execut)able
813 * or
2779 return_code = Z_ERR;
2780 if (!in_alt_root && verify_brand(handle, cmd_num, argv) != Z_OK)
2781 return_code = Z_ERR;
2782 if (!in_alt_root && verify_datasets(handle) != Z_OK)
2783 return_code = Z_ERR;
2784
2785 /*
2786 * As the "mount" command is used for patching/upgrading of zones
2787 * or other maintenance processes, the zone's privilege set is not
2788 * checked in this case. Instead, the default, safe set of
2789 * privileges will be used when this zone is created in the
2790 * kernel.
2791 */
2792 if (!in_alt_root && cmd_num != CMD_MOUNT &&
2793 verify_limitpriv(handle) != Z_OK)
2794 return_code = Z_ERR;
2795
2796 return (return_code);
2797 }
2798
2799 /*
2800 * Called when readying or booting a zone. We double check that the zone's
2801 * debug ID is set and is unique. This covers the case of pre-existing zones
2802 * with no ID. Also, its possible that a zone was migrated to this host
2803 * and as a result it has a duplicate ID. In this case we preserve the ID
2804 * of the first zone we match on in the index file (since it was there before
2805 * the current zone) and we assign a new unique ID to the current zone.
2806 * Return true if we assigned a new ID, indicating that the zone configuration
2807 * needs to be saved.
2808 */
2809 static boolean_t
2810 verify_fix_did(zone_dochandle_t handle)
2811 {
2812 zoneid_t mydid;
2813 zone_entry_t zent;
2814 FILE *cookie;
2815 char *name;
2816 boolean_t fix = B_FALSE;
2817
2818 mydid = zonecfg_get_did(handle);
2819 if (mydid == -1) {
2820 zonecfg_set_did(handle);
2821 return (B_TRUE);
2822 }
2823
2824 /* Get the full list of zones from the configuration. */
2825 cookie = setzoneent();
2826 while ((name = getzoneent(cookie)) != NULL) {
2827 if (strcmp(target_zone, name) == 0) {
2828 free(name);
2829 break; /* Once we find our entry, stop. */
2830 }
2831
2832 if (strcmp(name, "global") == 0 ||
2833 lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) {
2834 free(name);
2835 continue;
2836 }
2837
2838 free(name);
2839 if (zent.zdid == mydid) {
2840 fix = B_TRUE;
2841 break;
2842 }
2843 }
2844 endzoneent(cookie);
2845
2846 if (fix) {
2847 zonecfg_set_did(handle);
2848 return (B_TRUE);
2849 }
2850
2851 return (B_FALSE);
2852 }
2853
2854 static int
2855 verify_details(int cmd_num, char *argv[])
2856 {
2857 zone_dochandle_t handle;
2858 char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN];
2859 int return_code = Z_OK;
2860 int err;
2861
2862 if ((handle = zonecfg_init_handle()) == NULL) {
2863 zperror(cmd_to_str(cmd_num), B_TRUE);
2864 return (Z_ERR);
2865 }
2866 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) {
2867 errno = err;
2868 zperror(cmd_to_str(cmd_num), B_TRUE);
2869 zonecfg_fini_handle(handle);
2870 return (Z_ERR);
2871 }
2872 if ((err = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath))) !=
2873 Z_OK) {
2893 * TRANSLATION_NOTE
2894 * XML and zonepath are literals that should not be translated.
2895 */
2896 (void) fprintf(stderr, gettext("The XML repository has "
2897 "zonepath '%s',\nbut the index file has zonepath '%s'.\n"
2898 "These must match, so fix the incorrect entry.\n"),
2899 zonepath, checkpath);
2900 zonecfg_fini_handle(handle);
2901 return (Z_ERR);
2902 }
2903 if (cmd_num != CMD_ATTACH &&
2904 validate_zonepath(zonepath, cmd_num) != Z_OK) {
2905 (void) fprintf(stderr, gettext("could not verify zonepath %s "
2906 "because of the above errors.\n"), zonepath);
2907 return_code = Z_ERR;
2908 }
2909
2910 if (verify_handle(cmd_num, handle, argv) != Z_OK)
2911 return_code = Z_ERR;
2912
2913 if (cmd_num == CMD_READY || cmd_num == CMD_BOOT) {
2914 int vcommit = 0, obscommit = 0;
2915
2916 vcommit = verify_fix_did(handle);
2917 obscommit = zonecfg_fix_obsolete(handle);
2918
2919 if (vcommit || obscommit)
2920 if (zonecfg_save(handle) != Z_OK)
2921 (void) fprintf(stderr, gettext("Could not save "
2922 "updated configuration.\n"));
2923 }
2924
2925 zonecfg_fini_handle(handle);
2926 if (return_code == Z_ERR)
2927 (void) fprintf(stderr,
2928 gettext("%s: zone %s failed to verify\n"),
2929 execname, target_zone);
2930 return (return_code);
2931 }
2932
2933 static int
2934 verify_func(int argc, char *argv[])
2935 {
2936 int arg;
2937
2938 optind = 0;
2939 if ((arg = getopt(argc, argv, "?")) != EOF) {
2940 switch (arg) {
2941 case '?':
2942 sub_usage(SHELP_VERIFY, CMD_VERIFY);
2943 return (optopt == '?' ? Z_OK : Z_USAGE);
2944 default:
3928 * If the "all" parameter is true then we should remove the whole zonepath
3929 * even if it has non-standard files/directories in it. This can be used when
3930 * we need to cleanup after moving the zonepath across file systems.
3931 *
3932 * We "exec" the RMCOMMAND so that the returned status is that of RMCOMMAND
3933 * and not the shell.
3934 */
3935 static int
3936 cleanup_zonepath(char *zonepath, boolean_t all)
3937 {
3938 int status;
3939 int i;
3940 boolean_t non_std = B_FALSE;
3941 struct dirent *dp;
3942 DIR *dirp;
3943 /*
3944 * The SUNWattached.xml file is expected since it might
3945 * exist if the zone was force-attached after a
3946 * migration.
3947 */
3948 char *std_entries[] = {"dev", "lastexited", "logs", "lu",
3949 "root", "SUNWattached.xml", NULL};
3950 /* (MAXPATHLEN * 5) is for the 5 std_entries dirs */
3951 char cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 5) + 64];
3952
3953 /*
3954 * We shouldn't need these checks but lets be paranoid since we
3955 * could blow away the whole system here if we got the wrong zonepath.
3956 */
3957 if (*zonepath == NULL || strcmp(zonepath, "/") == 0) {
3958 (void) fprintf(stderr, "invalid zonepath '%s'\n", zonepath);
3959 return (Z_INVAL);
3960 }
3961
3962 /*
3963 * If the dirpath is already gone (maybe it was manually removed) then
3964 * we just return Z_OK so that the cleanup is successful.
3965 */
3966 if ((dirp = opendir(zonepath)) == NULL)
3967 return (Z_OK);
3968
3969 /*
3970 * Look through the zonepath directory to see if there are any
3971 * non-standard files/dirs. Also skip .zfs since that might be
5438 /*
5439 * This is an undocumented interface which is currently only used to apply
5440 * the global zone resource management settings when the system boots.
5441 * This function does not yet properly handle updating a running system so
5442 * any projects running in the zone would be trashed if this function
5443 * were to run after the zone had booted. It also does not reset any
5444 * rctl settings that were removed from zonecfg. There is still work to be
5445 * done before we can properly support dynamically updating the resource
5446 * management settings for a running zone (global or non-global). Thus, this
5447 * functionality is undocumented for now.
5448 */
5449 /* ARGSUSED */
5450 static int
5451 apply_func(int argc, char *argv[])
5452 {
5453 int err;
5454 int res = Z_OK;
5455 priv_set_t *privset;
5456 zoneid_t zoneid;
5457 zone_dochandle_t handle;
5458 uint64_t mcap;
5459 char pool_err[128];
5460
5461 zoneid = getzoneid();
5462
5463 if (zonecfg_in_alt_root() || zoneid != GLOBAL_ZONEID ||
5464 target_zone == NULL || strcmp(target_zone, GLOBAL_ZONENAME) != 0)
5465 return (usage(B_FALSE));
5466
5467 if ((privset = priv_allocset()) == NULL) {
5468 zerror(gettext("%s failed"), "priv_allocset");
5469 return (Z_ERR);
5470 }
5471
5472 if (getppriv(PRIV_EFFECTIVE, privset) != 0) {
5473 zerror(gettext("%s failed"), "getppriv");
5474 priv_freeset(privset);
5475 return (Z_ERR);
5476 }
5477
5478 if (priv_isfullset(privset) == B_FALSE) {
5529 pool_err);
5530 else
5531 zerror(gettext("could not bind zone to "
5532 "temporary pool: %s"),
5533 zonecfg_strerror(err));
5534 res = Z_ERR;
5535 }
5536
5537 if ((err = zonecfg_bind_pool(handle, zoneid, pool_err,
5538 sizeof (pool_err))) != Z_OK) {
5539 if (err == Z_POOL || err == Z_POOL_BIND)
5540 zerror("%s: %s", zonecfg_strerror(err),
5541 pool_err);
5542 else
5543 zerror("%s", zonecfg_strerror(err));
5544 }
5545 }
5546 }
5547
5548 /*
5549 * If a memory cap is configured, make sure the rcapd SMF service is
5550 * enabled.
5551 */
5552 if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, &mcap) == Z_OK) {
5553 char smf_err[128];
5554
5555 if (zonecfg_enable_rcapd(smf_err, sizeof (smf_err)) != Z_OK) {
5556 zerror(gettext("enabling system/rcap service failed: "
5557 "%s"), smf_err);
5558 res = Z_ERR;
5559 }
5560 }
5561
5562 zonecfg_fini_handle(handle);
5563
5564 return (res);
5565 }
5566
5567 /*
5568 * This is an undocumented interface that is invoked by the zones SMF service
5569 * for installed zones that won't automatically boot.
5570 */
5571 /* ARGSUSED */
5572 static int
5573 sysboot_func(int argc, char *argv[])
5574 {
|