diff options
Diffstat (limited to 'usr/src/cmd/zoneadm')
-rw-r--r-- | usr/src/cmd/zoneadm/Makefile | 11 | ||||
-rw-r--r-- | usr/src/cmd/zoneadm/svc-zones | 2 | ||||
-rw-r--r-- | usr/src/cmd/zoneadm/zfs.c | 16 | ||||
-rw-r--r-- | usr/src/cmd/zoneadm/zoneadm.c | 210 | ||||
-rw-r--r-- | usr/src/cmd/zoneadm/zones.xml | 10 |
5 files changed, 190 insertions, 59 deletions
diff --git a/usr/src/cmd/zoneadm/Makefile b/usr/src/cmd/zoneadm/Makefile index 2b01078aec..fba7809c71 100644 --- a/usr/src/cmd/zoneadm/Makefile +++ b/usr/src/cmd/zoneadm/Makefile @@ -21,14 +21,18 @@ # # Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, Joyent, Inc. All rights reserved. # PROG= zoneadm +SCRIPTS= MANIFEST= zones.xml resource-mgmt.xml SVCMETHOD= svc-zones svc-resource-mgmt include ../Makefile.cmd +include ../Makefile.ctf +ROOTUSRSBINSCRIPTS= $(SCRIPTS:%=$(ROOTUSRSBIN)/%) ROOTMANIFESTDIR= $(ROOTSVCSYSTEM) OBJS= zoneadm.o zfs.o @@ -42,13 +46,14 @@ CERRWARN += -_gcc=-Wno-uninitialized .KEEP_STATE: -all: $(PROG) +all: $(PROG) $(SCRIPTS) $(PROG): $(OBJS) $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(POST_PROCESS) -install: all $(ROOTUSRSBINPROG) $(ROOTMANIFEST) $(ROOTSVCMETHOD) +install: all $(ROOTUSRSBINPROG) $(ROOTUSRSBINSCRIPTS) $(ROOTMANIFEST) \ + $(ROOTSVCMETHOD) check: $(PROG).c $(CHKMANIFEST) $(CSTYLE) -pP $(SRCS:%=%) @@ -58,7 +63,7 @@ $(POFILE): $(POFILES) $(CAT) $(POFILES) > $@ clean: - $(RM) $(OBJS) $(POFILES) + $(RM) $(OBJS) $(POFILES) $(SCRIPTS) lint: lint_SRCS diff --git a/usr/src/cmd/zoneadm/svc-zones b/usr/src/cmd/zoneadm/svc-zones index 9d307835bd..30d54f5272 100644 --- a/usr/src/cmd/zoneadm/svc-zones +++ b/usr/src/cmd/zoneadm/svc-zones @@ -32,7 +32,7 @@ shutdown_zones() { zoneadm list -p | nawk -F: '{ - if ($2 != "global") { + if (($5 != "lx") && ($2 != "global")) { print $2 } }' diff --git a/usr/src/cmd/zoneadm/zfs.c b/usr/src/cmd/zoneadm/zfs.c index d27b9c4678..78c165ffd1 100644 --- a/usr/src/cmd/zoneadm/zfs.c +++ b/usr/src/cmd/zoneadm/zfs.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ /* @@ -968,6 +968,7 @@ create_zfs_zonepath(char *zonepath) zfs_handle_t *zhp; char zfs_name[MAXPATHLEN]; nvlist_t *props = NULL; + int i; if (path2name(zonepath, zfs_name, sizeof (zfs_name)) != Z_OK) return; @@ -1004,9 +1005,20 @@ create_zfs_zonepath(char *zonepath) nvlist_free(props); - if (zfs_mount(zhp, NULL, 0) != 0) { + /* + * A monitoring tool might race with us and touch the mountpoint just + * as we're trying to mount, blocking the mount. We wait and retry a + * few times to workaround this race. + */ + for (i = 0; i < 5; i++) { + if (zfs_mount(zhp, NULL, 0) == 0) + break; (void) fprintf(stderr, gettext("cannot mount ZFS dataset %s: " "%s\n"), zfs_name, libzfs_error_description(g_zfs)); + (void) sleep(1); + } + + if (i >= 5) { (void) zfs_destroy(zhp, B_FALSE); } else { if (chmod(zonepath, S_IRWXU) != 0) { diff --git a/usr/src/cmd/zoneadm/zoneadm.c b/usr/src/cmd/zoneadm/zoneadm.c index 6d80fcd8c3..70962d1ea3 100644 --- a/usr/src/cmd/zoneadm/zoneadm.c +++ b/usr/src/cmd/zoneadm/zoneadm.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2015, Joyent Inc. All rights reserved. */ /* @@ -100,6 +101,7 @@ typedef struct zone_entry { char zroot[MAXPATHLEN]; char zuuid[UUID_PRINTABLE_STRING_LENGTH]; zone_iptype_t ziptype; + zoneid_t zdid; } zone_entry_t; #define CLUSTER_BRAND_NAME "cluster" @@ -442,6 +444,7 @@ zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable) } if (!verbose) { char *cp, *clim; + char zdid[80]; if (!parsable) { (void) printf("%s\n", zent->zname); @@ -457,8 +460,12 @@ zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable) (void) printf("%.*s\\:", clim - cp, cp); cp = clim + 1; } - (void) printf("%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand, - ip_type_str); + if (zent->zdid == -1) + zdid[0] = '\0'; + else + (void) snprintf(zdid, sizeof (zdid), "%d", zent->zdid); + (void) printf("%s:%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand, + ip_type_str, zdid); return; } if (zent->zstate_str != NULL) { @@ -553,6 +560,22 @@ lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent) return (Z_OK); } + if ((handle = zonecfg_init_handle()) == NULL) { + zperror2(zent->zname, gettext("could not init handle")); + return (Z_ERR); + } + if ((err = zonecfg_get_handle(zent->zname, handle)) != Z_OK) { + zperror2(zent->zname, gettext("could not get handle")); + zonecfg_fini_handle(handle); + return (Z_ERR); + } + + if ((err = zonecfg_get_iptype(handle, &zent->ziptype)) != Z_OK) { + zperror2(zent->zname, gettext("could not get ip-type")); + zonecfg_fini_handle(handle); + return (Z_ERR); + } + /* * There is a race condition where the zone could boot while * we're walking the index file. In this case the zone state @@ -573,25 +596,11 @@ lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent) zent->ziptype = ZS_EXCLUSIVE; else zent->ziptype = ZS_SHARED; - return (Z_OK); } } - if ((handle = zonecfg_init_handle()) == NULL) { - zperror2(zent->zname, gettext("could not init handle")); - return (Z_ERR); - } - if ((err = zonecfg_get_handle(zent->zname, handle)) != Z_OK) { - zperror2(zent->zname, gettext("could not get handle")); - zonecfg_fini_handle(handle); - return (Z_ERR); - } + zent->zdid = zonecfg_get_did(handle); - if ((err = zonecfg_get_iptype(handle, &zent->ziptype)) != Z_OK) { - zperror2(zent->zname, gettext("could not get ip-type")); - zonecfg_fini_handle(handle); - return (Z_ERR); - } zonecfg_fini_handle(handle); return (Z_OK); @@ -765,18 +774,22 @@ zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable) * Retrieve a zone entry by name. Returns NULL if no such zone exists. */ static zone_entry_t * -lookup_running_zone(const char *str) +lookup_running_zone(const char *name) { - int i; + zoneid_t zid; + zone_entry_t *zent; - if (fetch_zents() != Z_OK) + if ((zid = getzoneidbyname(name)) == -1) return (NULL); - for (i = 0; i < nzents; i++) { - if (strcmp(str, zents[i].zname) == 0) - return (&zents[i]); + if ((zent = malloc(sizeof (zone_entry_t))) == NULL) + return (NULL); + + if (lookup_zone_info(name, zid, zent) != Z_OK) { + free(zent); + return (NULL); } - return (NULL); + return (zent); } /* @@ -1012,8 +1025,12 @@ validate_zonepath(char *path, int cmd_num) (void) printf(gettext("WARNING: %s is on a temporary " "file system.\n"), rpath); } - if (crosscheck_zonepaths(rpath) != Z_OK) - return (Z_ERR); + if (cmd_num != CMD_BOOT && cmd_num != CMD_REBOOT && + cmd_num != CMD_READY) { + /* we checked when we installed, no need to check each boot */ + if (crosscheck_zonepaths(rpath) != Z_OK) + return (Z_ERR); + } /* * Try to collect and report as many minor errors as possible * before returning, so the user can learn everything that needs @@ -1200,6 +1217,7 @@ static int ready_func(int argc, char *argv[]) { zone_cmd_arg_t zarg; + boolean_t debug = B_FALSE; int arg; if (zonecfg_in_alt_root()) { @@ -1208,11 +1226,14 @@ ready_func(int argc, char *argv[]) } optind = 0; - if ((arg = getopt(argc, argv, "?")) != EOF) { + if ((arg = getopt(argc, argv, "?X")) != EOF) { switch (arg) { case '?': sub_usage(SHELP_READY, CMD_READY); return (optopt == '?' ? Z_OK : Z_USAGE); + case 'X': + debug = B_TRUE; + break; default: sub_usage(SHELP_READY, CMD_READY); return (Z_USAGE); @@ -1229,6 +1250,7 @@ ready_func(int argc, char *argv[]) return (Z_ERR); zarg.cmd = Z_READY; + zarg.debug = debug; if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) { zerror(gettext("call to %s failed"), "zoneadmd"); return (Z_ERR); @@ -1241,6 +1263,7 @@ boot_func(int argc, char *argv[]) { zone_cmd_arg_t zarg; boolean_t force = B_FALSE; + boolean_t debug = B_FALSE; int arg; if (zonecfg_in_alt_root()) { @@ -1267,7 +1290,7 @@ boot_func(int argc, char *argv[]) * zoneadm -z myzone boot -- -s -v -m verbose. */ optind = 0; - while ((arg = getopt(argc, argv, "?fs")) != EOF) { + while ((arg = getopt(argc, argv, "?fsX")) != EOF) { switch (arg) { case '?': sub_usage(SHELP_BOOT, CMD_BOOT); @@ -1279,6 +1302,9 @@ boot_func(int argc, char *argv[]) case 'f': force = B_TRUE; break; + case 'X': + debug = B_TRUE; + break; default: sub_usage(SHELP_BOOT, CMD_BOOT); return (Z_USAGE); @@ -1304,6 +1330,7 @@ boot_func(int argc, char *argv[]) if (verify_details(CMD_BOOT, argv) != Z_OK) return (Z_ERR); zarg.cmd = force ? Z_FORCEBOOT : Z_BOOT; + zarg.debug = debug; if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) { zerror(gettext("call to %s failed"), "zoneadmd"); return (Z_ERR); @@ -1819,6 +1846,7 @@ static int halt_func(int argc, char *argv[]) { zone_cmd_arg_t zarg; + boolean_t debug = B_FALSE; int arg; if (zonecfg_in_alt_root()) { @@ -1827,11 +1855,14 @@ halt_func(int argc, char *argv[]) } optind = 0; - if ((arg = getopt(argc, argv, "?")) != EOF) { + if ((arg = getopt(argc, argv, "?X")) != EOF) { switch (arg) { case '?': sub_usage(SHELP_HALT, CMD_HALT); return (optopt == '?' ? Z_OK : Z_USAGE); + case 'X': + debug = B_TRUE; + break; default: sub_usage(SHELP_HALT, CMD_HALT); return (Z_USAGE); @@ -1857,6 +1888,7 @@ halt_func(int argc, char *argv[]) return (Z_ERR); zarg.cmd = Z_HALT; + zarg.debug = debug; return ((zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) == 0) ? Z_OK : Z_ERR); } @@ -1934,6 +1966,7 @@ static int reboot_func(int argc, char *argv[]) { zone_cmd_arg_t zarg; + boolean_t debug = B_FALSE; int arg; if (zonecfg_in_alt_root()) { @@ -1942,11 +1975,14 @@ reboot_func(int argc, char *argv[]) } optind = 0; - if ((arg = getopt(argc, argv, "?")) != EOF) { + if ((arg = getopt(argc, argv, "?X")) != EOF) { switch (arg) { case '?': sub_usage(SHELP_REBOOT, CMD_REBOOT); return (optopt == '?' ? Z_OK : Z_USAGE); + case 'X': + debug = B_TRUE; + break; default: sub_usage(SHELP_REBOOT, CMD_REBOOT); return (Z_USAGE); @@ -1981,6 +2017,7 @@ reboot_func(int argc, char *argv[]) return (Z_ERR); zarg.cmd = Z_REBOOT; + zarg.debug = debug; return ((zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) == 0) ? Z_OK : Z_ERR); } @@ -2208,6 +2245,10 @@ verify_fs_special(struct zone_fstab *fstab) if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0) return (verify_fs_zfs(fstab)); + if (strcmp(fstab->zone_fs_type, MNTTYPE_HYPRLOFS) == 0 && + strcmp(fstab->zone_fs_special, "swap") == 0) + return (Z_OK); + if (stat64(fstab->zone_fs_special, &st) != 0) { (void) fprintf(stderr, gettext("could not verify fs " "%s: could not access %s: %s\n"), fstab->zone_fs_dir, @@ -2611,7 +2652,6 @@ verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[]) dladm_handle_t dh; dladm_status_t status; datalink_id_t linkid; - char errmsg[DLADM_STRSIZE]; in_alt_root = zonecfg_in_alt_root(); if (in_alt_root) @@ -2694,11 +2734,6 @@ verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[]) dladm_close(dh); } if (status != DLADM_STATUS_OK) { - (void) fprintf(stderr, - gettext("WARNING: skipping network " - "interface '%s': %s\n"), - nwiftab.zone_nwif_physical, - dladm_status2str(status, errmsg)); break; } dl_owner_zid = ALL_ZONES; @@ -2782,6 +2817,61 @@ no_net: return (return_code); } +/* + * Called when readying or booting a zone. We double check that the zone's + * debug ID is set and is unique. This covers the case of pre-existing zones + * with no ID. Also, its possible that a zone was migrated to this host + * and as a result it has a duplicate ID. In this case we preserve the ID + * of the first zone we match on in the index file (since it was there before + * the current zone) and we assign a new unique ID to the current zone. + * Return true if we assigned a new ID, indicating that the zone configuration + * needs to be saved. + */ +static boolean_t +verify_fix_did(zone_dochandle_t handle) +{ + zoneid_t mydid; + zone_entry_t zent; + FILE *cookie; + char *name; + boolean_t fix = B_FALSE; + + mydid = zonecfg_get_did(handle); + if (mydid == -1) { + zonecfg_set_did(handle); + return (B_TRUE); + } + + /* Get the full list of zones from the configuration. */ + cookie = setzoneent(); + while ((name = getzoneent(cookie)) != NULL) { + if (strcmp(target_zone, name) == 0) { + free(name); + break; /* Once we find our entry, stop. */ + } + + if (strcmp(name, "global") == 0 || + lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) { + free(name); + continue; + } + + free(name); + if (zent.zdid == mydid) { + fix = B_TRUE; + break; + } + } + endzoneent(cookie); + + if (fix) { + zonecfg_set_did(handle); + return (B_TRUE); + } + + return (B_FALSE); +} + static int verify_details(int cmd_num, char *argv[]) { @@ -2841,6 +2931,18 @@ verify_details(int cmd_num, char *argv[]) if (verify_handle(cmd_num, handle, argv) != Z_OK) return_code = Z_ERR; + if (cmd_num == CMD_READY || cmd_num == CMD_BOOT) { + int vcommit = 0, obscommit = 0; + + vcommit = verify_fix_did(handle); + obscommit = zonecfg_fix_obsolete(handle); + + if (vcommit || obscommit) + if (zonecfg_save(handle) != Z_OK) + (void) fprintf(stderr, gettext("Could not save " + "updated configuration.\n")); + } + zonecfg_fini_handle(handle); if (return_code == Z_ERR) (void) fprintf(stderr, @@ -2926,6 +3028,7 @@ install_func(int argc, char *argv[]) int status; boolean_t do_postinstall = B_FALSE; boolean_t brand_help = B_FALSE; + boolean_t do_dataset = B_TRUE; char opts[128]; if (target_zone == NULL) { @@ -3001,6 +3104,12 @@ install_func(int argc, char *argv[]) } /* Ignore unknown options - may be brand specific. */ break; + case 'x': + if (strcmp(optarg, "nodataset") == 0) { + do_dataset = B_FALSE; + continue; /* internal arg, don't pass thru */ + } + break; default: /* Ignore unknown options - may be brand specific. */ break; @@ -3053,7 +3162,8 @@ install_func(int argc, char *argv[]) goto done; } - create_zfs_zonepath(zonepath); + if (do_dataset) + create_zfs_zonepath(zonepath); } status = do_subproc(cmdbuf); @@ -3863,10 +3973,10 @@ cleanup_zonepath(char *zonepath, boolean_t all) * exist if the zone was force-attached after a * migration. */ - char *std_entries[] = {"dev", "lu", "root", - "SUNWattached.xml", NULL}; - /* (MAXPATHLEN * 3) is for the 3 std_entries dirs */ - char cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 3) + 64]; + char *std_entries[] = {"dev", "lastexited", "logs", "lu", + "root", "SUNWattached.xml", NULL}; + /* (MAXPATHLEN * 5) is for the 5 std_entries dirs */ + char cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 5) + 64]; /* * We shouldn't need these checks but lets be paranoid since we @@ -5016,6 +5126,7 @@ uninstall_func(int argc, char *argv[]) if (zonecfg_ping_zoneadmd(target_zone) == Z_OK) { zone_cmd_arg_t zarg; zarg.cmd = Z_NOTE_UNINSTALLING; + zarg.debug = B_FALSE; /* we don't care too much if this fails, just plow on */ (void) zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE); @@ -5131,6 +5242,7 @@ mount_func(int argc, char *argv[]) return (Z_ERR); zarg.cmd = force ? Z_FORCEMOUNT : Z_MOUNT; + zarg.debug = B_FALSE; zarg.bootbuf[0] = '\0'; if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) { zerror(gettext("call to %s failed"), "zoneadmd"); @@ -5152,6 +5264,7 @@ unmount_func(int argc, char *argv[]) return (Z_ERR); zarg.cmd = Z_UNMOUNT; + zarg.debug = B_FALSE; if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) { zerror(gettext("call to %s failed"), "zoneadmd"); return (Z_ERR); @@ -5373,7 +5486,7 @@ apply_func(int argc, char *argv[]) priv_set_t *privset; zoneid_t zoneid; zone_dochandle_t handle; - struct zone_mcaptab mcap; + uint64_t mcap; char pool_err[128]; zoneid = getzoneid(); @@ -5464,19 +5577,12 @@ apply_func(int argc, char *argv[]) } /* - * If a memory cap is configured, set the cap in the kernel using - * zone_setattr() and make sure the rcapd SMF service is enabled. + * If a memory cap is configured, make sure the rcapd SMF service is + * enabled. */ - if (zonecfg_getmcapent(handle, &mcap) == Z_OK) { - uint64_t num; + if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, &mcap) == Z_OK) { char smf_err[128]; - num = (uint64_t)strtoll(mcap.zone_physmem_cap, NULL, 10); - if (zone_setattr(zoneid, ZONE_ATTR_PHYS_MCAP, &num, 0) == -1) { - zerror(gettext("could not set zone memory cap")); - res = Z_ERR; - } - if (zonecfg_enable_rcapd(smf_err, sizeof (smf_err)) != Z_OK) { zerror(gettext("enabling system/rcap service failed: " "%s"), smf_err); diff --git a/usr/src/cmd/zoneadm/zones.xml b/usr/src/cmd/zoneadm/zones.xml index 9c8e305f89..1b6f8cd49b 100644 --- a/usr/src/cmd/zoneadm/zones.xml +++ b/usr/src/cmd/zoneadm/zones.xml @@ -54,11 +54,19 @@ <service_fmri value='svc:/milestone/multi-user-server' /> </dependency> + <dependency + name='metadata' + type='service' + grouping='require_all' + restart_on='none'> + <service_fmri value='svc:/system/smartdc/metadata' /> + </dependency> + <exec_method type='method' name='start' exec='/lib/svc/method/svc-zones %m' - timeout_seconds='60'> + timeout_seconds='0'> </exec_method> <!-- |