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;
}