Print this page
OS-200 need a better mechanism for storing persistent zone_did
Small comment-out because we don't include OS-200
OS-4019 zoneadm is slow with 1000s of zones
OS-3524 in order to support interaction with docker containers, need to be able to connect to stdio for init from GZ
OS-3525 in order to support 'docker logs' need to be able to get stdio from zone to log file
OS-3429 Expose zone's init exit status
OS-399 zone phys. mem. cap should be a rctl and have associated kstat

*** 21,30 **** --- 21,31 ---- /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2015 by Delphix. All rights reserved. + * Copyright 2015, Joyent Inc. All rights reserved. */ /* * zoneadm is a command interpreter for zone administration. It is all in * C (i.e., no lex/yacc), and all the argument passing is argc/argv based.
*** 99,108 **** --- 100,110 ---- zone_state_t zstate_num; char zbrand[MAXNAMELEN]; char zroot[MAXPATHLEN]; char zuuid[UUID_PRINTABLE_STRING_LENGTH]; zone_iptype_t ziptype; + zoneid_t zdid; } zone_entry_t; #define CLUSTER_BRAND_NAME "cluster" static zone_entry_t *zents;
*** 441,450 **** --- 443,453 ---- ZONEID_WIDTH, "ID", "NAME", "STATUS", "PATH", "BRAND", "IP"); } if (!verbose) { char *cp, *clim; + char zdid[80]; if (!parsable) { (void) printf("%s\n", zent->zname); return; }
*** 456,467 **** cp = zent->zroot; while ((clim = strchr(cp, ':')) != NULL) { (void) printf("%.*s\\:", clim - cp, cp); cp = clim + 1; } ! (void) printf("%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand, ! ip_type_str); return; } if (zent->zstate_str != NULL) { if (zent->zid == ZONE_ID_UNDEFINED) (void) printf("%*s", ZONEID_WIDTH, "-"); --- 459,474 ---- cp = zent->zroot; while ((clim = strchr(cp, ':')) != NULL) { (void) printf("%.*s\\:", clim - cp, cp); cp = clim + 1; } ! 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) { if (zent->zid == ZONE_ID_UNDEFINED) (void) printf("%*s", ZONEID_WIDTH, "-");
*** 552,561 **** --- 559,584 ---- if (zid == GLOBAL_ZONEID) { 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); + } + + 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 * could be seen as running from the call above, but the zoneid * would be undefined.
*** 572,601 **** sizeof (flags)) >= 0) { if (flags & ZF_NET_EXCL) 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); ! } - 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); } /* --- 595,610 ---- sizeof (flags)) >= 0) { if (flags & ZF_NET_EXCL) zent->ziptype = ZS_EXCLUSIVE; else zent->ziptype = ZS_SHARED; } } ! zent->zdid = zonecfg_get_did(handle); zonecfg_fini_handle(handle); return (Z_OK); } /*
*** 764,785 **** /* * Retrieve a zone entry by name. Returns NULL if no such zone exists. */ static zone_entry_t * ! lookup_running_zone(const char *str) { ! int i; ! if (fetch_zents() != Z_OK) return (NULL); ! for (i = 0; i < nzents; i++) { ! if (strcmp(str, zents[i].zname) == 0) ! return (&zents[i]); ! } return (NULL); } /* * Check a bit in a mode_t: if on is B_TRUE, that bit should be on; if * B_FALSE, it should be off. Return B_TRUE if the mode is bad (incorrect). --- 773,798 ---- /* * Retrieve a zone entry by name. Returns NULL if no such zone exists. */ static zone_entry_t * ! lookup_running_zone(const char *name) { ! zoneid_t zid; ! zone_entry_t *zent; ! if ((zid = getzoneidbyname(name)) == -1) return (NULL); ! if ((zent = malloc(sizeof (zone_entry_t))) == NULL) return (NULL); + + if (lookup_zone_info(name, zid, zent) != Z_OK) { + free(zent); + return (NULL); + } + return (zent); } /* * Check a bit in a mode_t: if on is B_TRUE, that bit should be on; if * B_FALSE, it should be off. Return B_TRUE if the mode is bad (incorrect).
*** 2781,2790 **** --- 2794,2858 ---- return_code = Z_ERR; 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[]) { zone_dochandle_t handle; char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN];
*** 2840,2849 **** --- 2908,2929 ---- } 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, gettext("%s: zone %s failed to verify\n"), execname, target_zone);
*** 3863,3876 **** /* * The SUNWattached.xml file is expected since it might * 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]; /* * We shouldn't need these checks but lets be paranoid since we * could blow away the whole system here if we got the wrong zonepath. */ --- 3943,3956 ---- /* * The SUNWattached.xml file is expected since it might * exist if the zone was force-attached after a * migration. */ ! 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 * could blow away the whole system here if we got the wrong zonepath. */
*** 5373,5383 **** int err; int res = Z_OK; priv_set_t *privset; zoneid_t zoneid; zone_dochandle_t handle; ! struct zone_mcaptab mcap; char pool_err[128]; zoneid = getzoneid(); if (zonecfg_in_alt_root() || zoneid != GLOBAL_ZONEID || --- 5453,5463 ---- int err; int res = Z_OK; priv_set_t *privset; zoneid_t zoneid; zone_dochandle_t handle; ! uint64_t mcap; char pool_err[128]; zoneid = getzoneid(); if (zonecfg_in_alt_root() || zoneid != GLOBAL_ZONEID ||
*** 5464,5486 **** } } } /* ! * 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 (zonecfg_getmcapent(handle, &mcap) == Z_OK) { ! uint64_t num; 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); res = Z_ERR; } --- 5544,5559 ---- } } } /* ! * If a memory cap is configured, make sure the rcapd SMF service is ! * enabled. */ ! if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, &mcap) == Z_OK) { char smf_err[128]; if (zonecfg_enable_rcapd(smf_err, sizeof (smf_err)) != Z_OK) { zerror(gettext("enabling system/rcap service failed: " "%s"), smf_err); res = Z_ERR; }