static void update_zone(zone_entry_t *zent, void *walk_data) { void(*update_notification_cb)(char *, char *, int, uint64_t, int) = (void(*)(char *, char *, int, uint64_t, int))walk_data; int changes; int64_t max_rss; uint64_t mcap; lcollection_t *lcol; rcid_t colid; if (zone_getattr(zent->zid, ZONE_ATTR_PHYS_MCAP, &mcap, sizeof (mcap)) != -1 && mcap != 0) max_rss = ROUNDUP(mcap, 1024) / 1024; else max_rss = 0; if (zent->zid == GLOBAL_ZONEID) { if (max_rss > 0) gz_capped = B_TRUE; else gz_capped = B_FALSE; } colid.rcid_type = RCIDT_ZONE; colid.rcid_val = zent->zid; lcol = lcollection_insert_update(&colid, max_rss, zent->zname, &changes); if (update_notification_cb != NULL) update_notification_cb("zone", zent->zname, changes, max_rss, (lcol != NULL) ? lcol->lcol_mark : 0); }
/* * -t prints "shared" vs. "exclusive" */ int main(int argc, char *argv[]) { zoneid_t zoneid; char zonename[ZONENAME_MAX]; FILE *fp; int arg; boolean_t stacktype = B_FALSE; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); opterr = 0; while ((arg = getopt(argc, argv, "t")) != EOF) { switch (arg) { case 't': stacktype = B_TRUE; break; } } zoneid = getzoneid(); if (stacktype) { ushort_t flags; if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, sizeof (flags)) < 0) { perror("could not determine zone IP type"); exit(1); } if (flags & ZF_NET_EXCL) (void) puts("exclusive"); else (void) puts("shared"); return (0); } if (getzonenamebyid(zoneid, zonename, sizeof (zonename)) < 0) { (void) fputs(gettext("could not determine zone name\n"), stderr); return (1); } /* * The use of dlopen here is a bit ugly, but it allows zonename to * function properly before /usr is mounted. On such a system, scratch * zones don't exist, so no translation is necessary. */ if (dlopen("libzonecfg.so.1", RTLD_NOW | RTLD_GLOBAL) != NULL && zonecfg_is_scratch(zonename) && (fp = zonecfg_open_scratch("", B_FALSE)) != NULL) { (void) zonecfg_reverse_scratch(fp, zonename, zonename, sizeof (zonename), NULL, 0); zonecfg_close_scratch(fp); } (void) puts(zonename); return (0); }
/* * Return TRUE if running in a Solaris 10 Container. */ static boolean_t i_ipadm_zone_is_s10c(zoneid_t zoneid) { char brand[MAXNAMELEN]; if (zone_getattr(zoneid, ZONE_ATTR_BRAND, brand, sizeof (brand)) < 0) return (B_FALSE); return (strcmp(brand, NATIVE_BRAND_NAME) != 0); }
/* * ipmgmt_ngz_init() initializes exclusive-IP stack non-global zones by * extracting configuration that has been saved in the kernel and applying * it at zone boot. */ static void ipmgmt_ngz_init() { zoneid_t zoneid; boolean_t firstboot = B_TRUE, s10c = B_FALSE; char brand[MAXNAMELEN]; ipadm_status_t ipstatus; zoneid = getzoneid(); if (zoneid != GLOBAL_ZONEID) { if (zone_getattr(zoneid, ZONE_ATTR_BRAND, brand, sizeof (brand)) < 0) { ipmgmt_log(LOG_ERR, "Could not get brand name"); return; } /* * firstboot is always true for S10C zones, where ipadm is not * available for restoring persistent configuration. */ if (strcmp(brand, NATIVE_BRAND_NAME) == 0) firstboot = ipmgmt_ngz_firstboot_postinstall(); else s10c = B_TRUE; if (!firstboot) return; ipstatus = ipadm_open(&iph, IPH_IPMGMTD); if (ipstatus != IPADM_SUCCESS) { ipmgmt_log(LOG_ERR, "could not open ipadm handle", ipadm_status2str(ipstatus)); return; } /* * Only pass down the callback to persist the interface * for NATIVE (ipkg) zones. */ (void) ipadm_init_net_from_gz(iph, NULL, (s10c ? NULL : ipmgmt_persist_if_cb)); ipadm_close(iph); } }
/* * Wrapper function to zone_getattr() for retrieving from-gz attributes that * were made availabe for exclusive IP non-global zones by zoneadmd from teh * global zone. */ static ipadm_status_t i_ipadm_zone_get_network(zoneid_t zoneid, datalink_id_t linkid, int type, void *buf, size_t *bufsize) { zone_net_data_t *zndata; zndata = calloc(1, sizeof (*zndata) + *bufsize); if (zndata == NULL) return (IPADM_NO_MEMORY); zndata->zn_type = type; zndata->zn_linkid = linkid; zndata->zn_len = *bufsize; if (zone_getattr(zoneid, ZONE_ATTR_NETWORK, zndata, sizeof (*zndata) + *bufsize) < 0) { return (ipadm_errno2status(errno)); } *bufsize = zndata->zn_len; bcopy(zndata->zn_val, buf, *bufsize); return (IPADM_SUCCESS); }
ssize_t getzonenamebyid(zoneid_t zoneid, char *buf, size_t buflen) { return (zone_getattr(zoneid, ZONE_ATTR_NAME, buf, buflen)); }
priv_set_t *priv_str_to_set (const char *buf, const char *sep, const char **endptr) { /* Take a copy of the string since strtok_r will modify it. */ char *str = strdup (buf); if (!str) return NULL; priv_set_t *set = priv_allocset (); if (!set) { free (str); return NULL; } priv_emptyset (set); const priv_data_t *data = __priv_parse_data_cached (); if (!data) return NULL; priv_set_t *basic = data->pd_basicprivs; char *saveptr; char *priv = strtok_r (str, sep, &saveptr); if (!priv) return set; do { if (strcmp (priv, "basic") == 0 && basic) priv_union (basic, set); else if (strcmp (priv, "all") == 0) priv_fillset (set); else if (strcmp (priv, "none") == 0) priv_emptyset (set); else if (strcmp (priv, "zone") == 0) { priv_set_t *zone = priv_allocset (); if (!zone) goto inval; if (zone_getattr (getzoneid (), ZONE_ATTR_PRIVSET, zone, __PRIVSETSIZE) == 0) priv_union (zone, set); priv_freeset (zone); } else { int negate = *str == '-' || *str == '!'; if (negate) str++; int res; if (negate) res = priv_delset (set, str); else res = priv_addset (set, str); if (res == -1) goto inval; } } while ((priv = strtok_r (NULL, sep, &saveptr))) ; free (str); return set; inval: priv_freeset (set); free (str); __set_errno (EINVAL); return NULL; }
/* * If the system is labeled then we need to * have a uniquely-named auto_home map for each zone. * The maps are made unique by appending the zonename. * The home directory is made unique by prepending /zone/<zonename> * for each zone that is dominated by the current zone. * The current zone's home directory mount point is not changed. * * For each auto_home_<zonename> a default template map is created * only if it doesn't exist yet. The default entry is used to declare * local home directories created within each zone. For example: * * +auto_home_public * * -fstype=lofs :/zone/public/export/home/& */ static void loadzone_maps(char *mntpnt, char *map, char *opts, char **stack, char ***stkptr) { zoneid_t *zids = NULL; zoneid_t my_zoneid; uint_t nzents_saved; uint_t nzents; int i; if (!priv_ineffect(PRIV_SYS_MOUNT)) return; if (zone_list(NULL, &nzents) != 0) { return; } my_zoneid = getzoneid(); again: if (nzents == 0) return; zids = malloc(nzents * sizeof (zoneid_t)); nzents_saved = nzents; if (zone_list(zids, &nzents) != 0) { free(zids); return; } if (nzents != nzents_saved) { /* list changed, try again */ free(zids); goto again; } for (i = 0; i < nzents; i++) { char zonename[ZONENAME_MAX]; char zoneroot[MAXPATHLEN]; if (getzonenamebyid(zids[i], zonename, ZONENAME_MAX) != -1) { char appended_map[MAXPATHLEN]; char prepended_mntpnt[MAXPATHLEN]; char map_path[MAXPATHLEN]; int fd; (void) snprintf(appended_map, sizeof (appended_map), "%s_%s", map, zonename); /* for current zone, leave mntpnt alone */ if (zids[i] != my_zoneid) { (void) snprintf(prepended_mntpnt, sizeof (prepended_mntpnt), "/zone/%s%s", zonename, mntpnt); if (zone_getattr(zids[i], ZONE_ATTR_ROOT, zoneroot, sizeof (zoneroot)) == -1) continue; } else { (void) strcpy(prepended_mntpnt, mntpnt); zoneroot[0] = '\0'; } dirinit(prepended_mntpnt, appended_map, opts, 0, stack, stkptr); /* * Next create auto_home_<zone> maps for each zone */ (void) snprintf(map_path, sizeof (map_path), "/etc/%s", appended_map); /* * If the map file doesn't exist create a template */ if ((fd = open(map_path, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP| S_IROTH)) != -1) { int len; char map_rec[MAXPATHLEN]; len = snprintf(map_rec, sizeof (map_rec), "+%s\n*\t-fstype=lofs\t:%s/export/home/&\n", appended_map, zoneroot); if (len <= sizeof (map_rec)) (void) write(fd, map_rec, len); (void) close(fd); } } } free(zids); }