Print this page
OS-200 need a better mechanism for storing persistent zone_did
OS-511 make zonecfg device resource extensible, like the net resource
OS-224 add more zonecfg net properties
OS-216 store all net config info on zone
OS-4361 libzonecfg should be aware of branded zone native root
Reviewed by: Robert Mustacchi <rm@joyent.com>
OS-3437 zonecfg failure when pool is full leaves VMs appearing to be missing
OS-399 zone phys. mem. cap should be a rctl and have associated kstat

*** 21,30 **** --- 21,31 ---- /* * Copyright 2014 Gary Mills * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2015 Joyent Inc. */ #include <libsysevent.h> #include <pthread.h> #include <stdlib.h>
*** 57,66 **** --- 58,69 ---- #include <auth_attr.h> #include <auth_list.h> #include <secdb.h> #include <user_attr.h> #include <prof_attr.h> + #include <sys/debug.h> + #include <os_dtd.h> #include <arpa/inet.h> #include <netdb.h> #include <libxml/xmlmemory.h>
*** 77,93 **** --- 80,99 ---- #define _PATH_TMPFILE "/zonecfg.XXXXXX" #define ZONE_CB_RETRY_COUNT 10 #define ZONE_EVENT_PING_SUBCLASS "ping" #define ZONE_EVENT_PING_PUBLISHER "solaris" + #define DEBUGID_FILE "/etc/zones/did.txt" + /* Hard-code the DTD element/attribute/entity names just once, here. */ #define DTD_ELEM_ATTR (const xmlChar *) "attr" #define DTD_ELEM_COMMENT (const xmlChar *) "comment" #define DTD_ELEM_DEVICE (const xmlChar *) "device" #define DTD_ELEM_FS (const xmlChar *) "filesystem" #define DTD_ELEM_FSOPTION (const xmlChar *) "fsoption" #define DTD_ELEM_NET (const xmlChar *) "network" + #define DTD_ELEM_NETATTR (const xmlChar *) "net-attr" #define DTD_ELEM_RCTL (const xmlChar *) "rctl" #define DTD_ELEM_RCTLVALUE (const xmlChar *) "rctl-value" #define DTD_ELEM_ZONE (const xmlChar *) "zone" #define DTD_ELEM_DATASET (const xmlChar *) "dataset" #define DTD_ELEM_TMPPOOL (const xmlChar *) "tmp_pool"
*** 103,125 **** --- 109,134 ---- #define DTD_ATTR_ALLOWED_ADDRESS (const xmlChar *) "allowed-address" #define DTD_ATTR_AUTOBOOT (const xmlChar *) "autoboot" #define DTD_ATTR_IPTYPE (const xmlChar *) "ip-type" #define DTD_ATTR_DEFROUTER (const xmlChar *) "defrouter" #define DTD_ATTR_DIR (const xmlChar *) "directory" + #define DTD_ATTR_GNIC (const xmlChar *) "global-nic" #define DTD_ATTR_LIMIT (const xmlChar *) "limit" #define DTD_ATTR_LIMITPRIV (const xmlChar *) "limitpriv" #define DTD_ATTR_BOOTARGS (const xmlChar *) "bootargs" #define DTD_ATTR_SCHED (const xmlChar *) "scheduling-class" + #define DTD_ATTR_MAC (const xmlChar *) "mac-addr" #define DTD_ATTR_MATCH (const xmlChar *) "match" #define DTD_ATTR_NAME (const xmlChar *) "name" #define DTD_ATTR_PHYSICAL (const xmlChar *) "physical" #define DTD_ATTR_POOL (const xmlChar *) "pool" #define DTD_ATTR_PRIV (const xmlChar *) "priv" #define DTD_ATTR_RAW (const xmlChar *) "raw" #define DTD_ATTR_SPECIAL (const xmlChar *) "special" #define DTD_ATTR_TYPE (const xmlChar *) "type" #define DTD_ATTR_VALUE (const xmlChar *) "value" + #define DTD_ATTR_VLANID (const xmlChar *) "vlan-id" #define DTD_ATTR_ZONEPATH (const xmlChar *) "zonepath" #define DTD_ATTR_NCPU_MIN (const xmlChar *) "ncpu_min" #define DTD_ATTR_NCPU_MAX (const xmlChar *) "ncpu_max" #define DTD_ATTR_IMPORTANCE (const xmlChar *) "importance" #define DTD_ATTR_PHYSCAP (const xmlChar *) "physcap"
*** 128,137 **** --- 137,147 ---- #define DTD_ATTR_UID (const xmlChar *) "uid" #define DTD_ATTR_GID (const xmlChar *) "gid" #define DTD_ATTR_MODE (const xmlChar *) "mode" #define DTD_ATTR_ACL (const xmlChar *) "acl" #define DTD_ATTR_BRAND (const xmlChar *) "brand" + #define DTD_ATTR_DID (const xmlChar *) "debugid" #define DTD_ATTR_HOSTID (const xmlChar *) "hostid" #define DTD_ATTR_USER (const xmlChar *) "user" #define DTD_ATTR_AUTHS (const xmlChar *) "auths" #define DTD_ATTR_FS_ALLOWED (const xmlChar *) "fs-allowed"
*** 174,183 **** --- 184,195 ---- {ALIAS_MAXSHMIDS, "zone.max-shm-ids", "privileged", "deny", 0}, {ALIAS_MAXMSGIDS, "zone.max-msg-ids", "privileged", "deny", 0}, {ALIAS_MAXSEMIDS, "zone.max-sem-ids", "privileged", "deny", 0}, {ALIAS_MAXLOCKEDMEM, "zone.max-locked-memory", "privileged", "deny", 0}, {ALIAS_MAXSWAP, "zone.max-swap", "privileged", "deny", 0}, + {ALIAS_MAXPHYSMEM, "zone.max-physical-memory", "privileged", "deny", + 1048576}, {ALIAS_SHARES, "zone.cpu-shares", "privileged", "none", 0}, {ALIAS_CPUCAP, "zone.cpu-cap", "privileged", "deny", 0}, {ALIAS_MAXPROCS, "zone.max-processes", "privileged", "deny", 100}, {NULL, NULL, NULL, NULL, 0} };
*** 267,289 **** * Callers of the _file_path() functions are expected to have the second * parameter be a (char foo[MAXPATHLEN]). */ static boolean_t ! config_file_path(const char *zonename, char *answer) { ! return (snprintf(answer, MAXPATHLEN, "%s%s/%s.xml", zonecfg_root, ! ZONE_CONFIG_ROOT, zonename) < MAXPATHLEN); } static boolean_t ! snap_file_path(const char *zonename, char *answer) { ! return (snprintf(answer, MAXPATHLEN, "%s%s/%s.snapshot.xml", ! zonecfg_root, ZONE_SNAPSHOT_ROOT, zonename) < MAXPATHLEN); } /*ARGSUSED*/ static void zonecfg_error_func(void *ctx, const char *msg, ...) { /* --- 279,319 ---- * Callers of the _file_path() functions are expected to have the second * parameter be a (char foo[MAXPATHLEN]). */ static boolean_t ! file_path_common(const char *zonename, const char *subdir, const char *stem, ! char *answer, size_t answer_size) { ! const char *native_root = zone_get_nroot(); ! ! if (native_root == NULL || zonecfg_in_alt_root()) { ! /* ! * Do not prepend the native system root (e.g. "/native") if an ! * alternative configuration root has been selected. ! */ ! native_root = ""; ! } ! ! return (snprintf(answer, answer_size, "%s%s%s/%s.%s", native_root, ! zonecfg_root, subdir, zonename, stem) < answer_size); } static boolean_t ! config_file_path(const char *zonename, char *answer, size_t answer_size) { ! return (file_path_common(zonename, ZONE_CONFIG_ROOT, "xml", answer, ! answer_size)); } + static boolean_t + snap_file_path(const char *zonename, char *answer, size_t answer_size) + { + return (file_path_common(zonename, ZONE_SNAPSHOT_ROOT, "snapshot.xml", + answer, answer_size)); + } + /*ARGSUSED*/ static void zonecfg_error_func(void *ctx, const char *msg, ...) { /*
*** 348,358 **** char path[MAXPATHLEN]; struct zoneent ze; int err, state_err; zone_state_t state; ! if (!config_file_path(zonename, path)) return (Z_MISC_FS); state_err = zone_get_state((char *)zonename, &state); err = access(path, W_OK); --- 378,388 ---- char path[MAXPATHLEN]; struct zoneent ze; int err, state_err; zone_state_t state; ! if (!config_file_path(zonename, path, sizeof (path))) return (Z_MISC_FS); state_err = zone_get_state((char *)zonename, &state); err = access(path, W_OK);
*** 405,415 **** int zonecfg_destroy_snapshot(const char *zonename) { char path[MAXPATHLEN]; ! if (!snap_file_path(zonename, path)) return (Z_MISC_FS); return (zonecfg_destroy_impl(path)); } static int --- 435,445 ---- int zonecfg_destroy_snapshot(const char *zonename) { char path[MAXPATHLEN]; ! if (!snap_file_path(zonename, path, sizeof (path))) return (Z_MISC_FS); return (zonecfg_destroy_impl(path)); } static int
*** 572,584 **** static int zonecfg_get_handle_impl(const char *zonename, const char *filename, zone_dochandle_t handle) { - xmlValidCtxtPtr cvp; struct stat statbuf; ! int valid; if (zonename == NULL) return (Z_NO_ZONE); if ((handle->zone_dh_doc = xmlParseFile(filename)) == NULL) { --- 602,613 ---- static int zonecfg_get_handle_impl(const char *zonename, const char *filename, zone_dochandle_t handle) { struct stat statbuf; ! boolean_t valid; if (zonename == NULL) return (Z_NO_ZONE); if ((handle->zone_dh_doc = xmlParseFile(filename)) == NULL) {
*** 585,602 **** /* distinguish file not found vs. found but not parsed */ if (stat(filename, &statbuf) == 0) return (Z_INVALID_DOCUMENT); return (Z_NO_ZONE); } ! if ((cvp = xmlNewValidCtxt()) == NULL) return (Z_NOMEM); ! cvp->error = zonecfg_error_func; ! cvp->warning = zonecfg_error_func; ! valid = xmlValidateDocument(cvp, handle->zone_dh_doc); ! xmlFreeValidCtxt(cvp); ! if (valid == 0) return (Z_INVALID_DOCUMENT); /* delete any comments such as inherited Sun copyright / ident str */ stripcomments(handle); return (Z_OK); } --- 614,630 ---- /* distinguish file not found vs. found but not parsed */ if (stat(filename, &statbuf) == 0) return (Z_INVALID_DOCUMENT); return (Z_NO_ZONE); } ! ! if (os_dtd_validate(handle->zone_dh_doc, B_FALSE, &valid) != 0) { return (Z_NOMEM); ! } ! if (!valid) { return (Z_INVALID_DOCUMENT); + } /* delete any comments such as inherited Sun copyright / ident str */ stripcomments(handle); return (Z_OK); }
*** 604,614 **** int zonecfg_get_handle(const char *zonename, zone_dochandle_t handle) { char path[MAXPATHLEN]; ! if (!config_file_path(zonename, path)) return (Z_MISC_FS); handle->zone_dh_newzone = B_FALSE; return (zonecfg_get_handle_impl(zonename, path, handle)); } --- 632,642 ---- int zonecfg_get_handle(const char *zonename, zone_dochandle_t handle) { char path[MAXPATHLEN]; ! if (!config_file_path(zonename, path, sizeof (path))) return (Z_MISC_FS); handle->zone_dh_newzone = B_FALSE; return (zonecfg_get_handle_impl(zonename, path, handle)); }
*** 648,658 **** int zonecfg_get_snapshot_handle(const char *zonename, zone_dochandle_t handle) { char path[MAXPATHLEN]; ! if (!snap_file_path(zonename, path)) return (Z_MISC_FS); handle->zone_dh_newzone = B_FALSE; return (zonecfg_get_handle_impl(zonename, path, handle)); } --- 676,686 ---- int zonecfg_get_snapshot_handle(const char *zonename, zone_dochandle_t handle) { char path[MAXPATHLEN]; ! if (!snap_file_path(zonename, path, sizeof (path))) return (Z_MISC_FS); handle->zone_dh_newzone = B_FALSE; return (zonecfg_get_handle_impl(zonename, path, handle)); }
*** 661,671 **** zone_dochandle_t handle) { char path[MAXPATHLEN]; int err; ! if (!config_file_path(template, path)) return (Z_MISC_FS); if ((err = zonecfg_get_handle_impl(template, path, handle)) != Z_OK) return (err); handle->zone_dh_newzone = B_TRUE; --- 689,699 ---- zone_dochandle_t handle) { char path[MAXPATHLEN]; int err; ! if (!config_file_path(template, path, sizeof (path))) return (Z_MISC_FS); if ((err = zonecfg_get_handle_impl(template, path, handle)) != Z_OK) return (err); handle->zone_dh_newzone = B_TRUE;
*** 695,719 **** */ int zonecfg_attach_manifest(int fd, zone_dochandle_t local_handle, zone_dochandle_t rem_handle) { ! xmlValidCtxtPtr cvp; ! int valid; /* load the manifest into the handle for the remote system */ if ((rem_handle->zone_dh_doc = xmlReadFd(fd, NULL, NULL, 0)) == NULL) { return (Z_INVALID_DOCUMENT); } ! if ((cvp = xmlNewValidCtxt()) == NULL) return (Z_NOMEM); ! cvp->error = zonecfg_error_func; ! cvp->warning = zonecfg_error_func; ! valid = xmlValidateDocument(cvp, rem_handle->zone_dh_doc); ! xmlFreeValidCtxt(cvp); ! if (valid == 0) return (Z_INVALID_DOCUMENT); /* delete any comments such as inherited Sun copyright / ident str */ stripcomments(rem_handle); rem_handle->zone_dh_newzone = B_TRUE; --- 723,745 ---- */ int zonecfg_attach_manifest(int fd, zone_dochandle_t local_handle, zone_dochandle_t rem_handle) { ! boolean_t valid; /* load the manifest into the handle for the remote system */ if ((rem_handle->zone_dh_doc = xmlReadFd(fd, NULL, NULL, 0)) == NULL) { return (Z_INVALID_DOCUMENT); } ! ! if (os_dtd_validate(rem_handle->zone_dh_doc, B_FALSE, &valid) != 0) { return (Z_NOMEM); ! } ! if (!valid) { return (Z_INVALID_DOCUMENT); + } /* delete any comments such as inherited Sun copyright / ident str */ stripcomments(rem_handle); rem_handle->zone_dh_newzone = B_TRUE;
*** 730,747 **** /* * We need to re-run xmlValidateDocument on local_handle to properly * update the in-core representation of the configuration. */ ! if ((cvp = xmlNewValidCtxt()) == NULL) return (Z_NOMEM); ! cvp->error = zonecfg_error_func; ! cvp->warning = zonecfg_error_func; ! valid = xmlValidateDocument(cvp, local_handle->zone_dh_doc); ! xmlFreeValidCtxt(cvp); ! if (valid == 0) return (Z_INVALID_DOCUMENT); strip_sw_inv(local_handle); local_handle->zone_dh_newzone = B_TRUE; local_handle->zone_dh_sw_inv = B_FALSE; --- 756,771 ---- /* * We need to re-run xmlValidateDocument on local_handle to properly * update the in-core representation of the configuration. */ ! if (os_dtd_validate(local_handle->zone_dh_doc, B_FALSE, &valid) != 0) { return (Z_NOMEM); ! } ! if (!valid) { return (Z_INVALID_DOCUMENT); + } strip_sw_inv(local_handle); local_handle->zone_dh_newzone = B_TRUE; local_handle->zone_dh_sw_inv = B_FALSE;
*** 1191,1203 **** static int zonecfg_save_impl(zone_dochandle_t handle, char *filename) { char tmpfile[MAXPATHLEN]; char bakdir[MAXPATHLEN], bakbase[MAXPATHLEN], bakfile[MAXPATHLEN]; ! int tmpfd, err, valid; ! xmlValidCtxt cvp = { NULL }; boolean_t backup; (void) strlcpy(tmpfile, filename, sizeof (tmpfile)); (void) dirname(tmpfile); (void) strlcat(tmpfile, _PATH_TMPFILE, sizeof (tmpfile)); --- 1215,1227 ---- static int zonecfg_save_impl(zone_dochandle_t handle, char *filename) { char tmpfile[MAXPATHLEN]; char bakdir[MAXPATHLEN], bakbase[MAXPATHLEN], bakfile[MAXPATHLEN]; ! int tmpfd, err; boolean_t backup; + boolean_t valid; (void) strlcpy(tmpfile, filename, sizeof (tmpfile)); (void) dirname(tmpfile); (void) strlcat(tmpfile, _PATH_TMPFILE, sizeof (tmpfile));
*** 1206,1225 **** (void) unlink(tmpfile); return (Z_TEMP_FILE); } (void) close(tmpfd); - cvp.error = zonecfg_error_func; - cvp.warning = zonecfg_error_func; - /* * We do a final validation of the document. Since the library has * malfunctioned if it fails to validate, we follow-up with an * assert() that the doc is valid. */ ! valid = xmlValidateDocument(&cvp, handle->zone_dh_doc); ! assert(valid != 0); if (xmlSaveFormatFile(tmpfile, handle->zone_dh_doc, 1) <= 0) goto err; (void) chmod(tmpfile, 0644); --- 1230,1246 ---- (void) unlink(tmpfile); return (Z_TEMP_FILE); } (void) close(tmpfd); /* * We do a final validation of the document. Since the library has * malfunctioned if it fails to validate, we follow-up with an * assert() that the doc is valid. */ ! VERIFY0(os_dtd_validate(handle->zone_dh_doc, B_FALSE, &valid)); ! VERIFY(valid == B_TRUE); if (xmlSaveFormatFile(tmpfile, handle->zone_dh_doc, 1) <= 0) goto err; (void) chmod(tmpfile, 0644);
*** 1270,1280 **** if ((err = zonecfg_refresh_index_file(handle)) != Z_OK) { if (backup) { /* * Try to restore from our backup. */ - (void) unlink(filename); (void) rename(bakfile, filename); } else { /* * Either the zone is new, in which case we can delete * new.xml, or we're doing a rename, so ditto. --- 1291,1300 ----
*** 1313,1323 **** return (Z_INVAL); if ((err = zonecfg_get_name(handle, zname, sizeof (zname))) != Z_OK) return (err); ! if (!config_file_path(zname, path)) return (Z_MISC_FS); addcomment(handle, "\n DO NOT EDIT THIS " "FILE. Use zonecfg(1M) instead.\n"); --- 1333,1343 ---- return (Z_INVAL); if ((err = zonecfg_get_name(handle, zname, sizeof (zname))) != Z_OK) return (err); ! if (!config_file_path(zname, path, sizeof (path))) return (Z_MISC_FS); addcomment(handle, "\n DO NOT EDIT THIS " "FILE. Use zonecfg(1M) instead.\n");
*** 1334,1371 **** return (err); handle->zone_dh_newzone = B_FALSE; if (is_renaming(handle)) { ! if (config_file_path(handle->zone_dh_delete_name, delpath)) (void) unlink(delpath); handle->zone_dh_delete_name[0] = '\0'; } return (Z_OK); } int zonecfg_verify_save(zone_dochandle_t handle, char *filename) { ! int valid; - xmlValidCtxt cvp = { NULL }; - if (zonecfg_check_handle(handle) != Z_OK) return (Z_BAD_HANDLE); - cvp.error = zonecfg_error_func; - cvp.warning = zonecfg_error_func; - /* * We do a final validation of the document. Since the library has * malfunctioned if it fails to validate, we follow-up with an * assert() that the doc is valid. */ ! valid = xmlValidateDocument(&cvp, handle->zone_dh_doc); ! assert(valid != 0); if (xmlSaveFormatFile(filename, handle->zone_dh_doc, 1) <= 0) return (Z_SAVING_FILE); return (Z_OK); --- 1354,1388 ---- return (err); handle->zone_dh_newzone = B_FALSE; if (is_renaming(handle)) { ! if (config_file_path(handle->zone_dh_delete_name, delpath, ! sizeof (delpath))) { (void) unlink(delpath); + } handle->zone_dh_delete_name[0] = '\0'; } return (Z_OK); } int zonecfg_verify_save(zone_dochandle_t handle, char *filename) { ! boolean_t valid; if (zonecfg_check_handle(handle) != Z_OK) return (Z_BAD_HANDLE); /* * We do a final validation of the document. Since the library has * malfunctioned if it fails to validate, we follow-up with an * assert() that the doc is valid. */ ! VERIFY0(os_dtd_validate(handle->zone_dh_doc, B_FALSE, &valid)); ! VERIFY(valid == B_TRUE); if (xmlSaveFormatFile(filename, handle->zone_dh_doc, 1) <= 0) return (Z_SAVING_FILE); return (Z_OK);
*** 1375,1387 **** zonecfg_detach_save(zone_dochandle_t handle, uint_t flags) { char zname[ZONENAME_MAX]; char path[MAXPATHLEN]; char migpath[MAXPATHLEN]; - xmlValidCtxt cvp = { NULL }; int err = Z_SAVING_FILE; ! int valid; if (zonecfg_check_handle(handle) != Z_OK) return (Z_BAD_HANDLE); if (flags & ZONE_DRY_RUN) { --- 1392,1403 ---- zonecfg_detach_save(zone_dochandle_t handle, uint_t flags) { char zname[ZONENAME_MAX]; char path[MAXPATHLEN]; char migpath[MAXPATHLEN]; int err = Z_SAVING_FILE; ! boolean_t valid; if (zonecfg_check_handle(handle) != Z_OK) return (Z_BAD_HANDLE); if (flags & ZONE_DRY_RUN) {
*** 1404,1423 **** return (err); addcomment(handle, "\n DO NOT EDIT THIS FILE. " "Use zonecfg(1M) and zoneadm(1M) attach.\n"); - cvp.error = zonecfg_error_func; - cvp.warning = zonecfg_error_func; - /* * We do a final validation of the document. Since the library has * malfunctioned if it fails to validate, we follow-up with an * assert() that the doc is valid. */ ! valid = xmlValidateDocument(&cvp, handle->zone_dh_doc); ! assert(valid != 0); if (xmlSaveFormatFile(migpath, handle->zone_dh_doc, 1) <= 0) return (Z_SAVING_FILE); if (!(flags & ZONE_DRY_RUN)) --- 1420,1436 ---- return (err); addcomment(handle, "\n DO NOT EDIT THIS FILE. " "Use zonecfg(1M) and zoneadm(1M) attach.\n"); /* * We do a final validation of the document. Since the library has * malfunctioned if it fails to validate, we follow-up with an * assert() that the doc is valid. */ ! VERIFY0(os_dtd_validate(handle->zone_dh_doc, B_FALSE, &valid)); ! VERIFY(valid == B_TRUE); if (xmlSaveFormatFile(migpath, handle->zone_dh_doc, 1) <= 0) return (Z_SAVING_FILE); if (!(flags & ZONE_DRY_RUN))
*** 1486,1496 **** int zonecfg_access(const char *zonename, int amode) { char path[MAXPATHLEN]; ! if (!config_file_path(zonename, path)) return (Z_INVAL); if (access(path, amode) == 0) return (Z_OK); if (errno == ENOENT) { if (snprintf(path, sizeof (path), "%s%s", zonecfg_root, --- 1499,1509 ---- int zonecfg_access(const char *zonename, int amode) { char path[MAXPATHLEN]; ! if (!config_file_path(zonename, path, sizeof (path))) return (Z_INVAL); if (access(path, amode) == 0) return (Z_OK); if (errno == ENOENT) { if (snprintf(path, sizeof (path), "%s%s", zonecfg_root,
*** 1551,1561 **** if ((mkdir(path, S_IRWXU) == -1) && (errno != EEXIST)) { error = Z_MISC_FS; goto out; } ! if (!snap_file_path(zonename, path)) { error = Z_MISC_FS; goto out; } addcomment(handle, "\n DO NOT EDIT THIS FILE. " --- 1564,1574 ---- if ((mkdir(path, S_IRWXU) == -1) && (errno != EEXIST)) { error = Z_MISC_FS; goto out; } ! if (!snap_file_path(zonename, path, sizeof (path))) { error = Z_MISC_FS; goto out; } addcomment(handle, "\n DO NOT EDIT THIS FILE. "
*** 2082,2098 **** * address, and default router information are stored in 'tabptr'. */ int zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr cur; xmlNodePtr firstmatch; int err; char address[INET6_ADDRSTRLEN]; char physical[LIFNAMSIZ]; size_t addrspec; /* nonzero if tabptr has IP addr */ size_t physspec; /* nonzero if tabptr has interface */ size_t defrouterspec; /* nonzero if tabptr has def. router */ size_t allowed_addrspec; zone_iptype_t iptype; if (tabptr == NULL) --- 2095,2115 ---- * address, and default router information are stored in 'tabptr'. */ int zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr cur, val; xmlNodePtr firstmatch; int err; char address[INET6_ADDRSTRLEN]; char physical[LIFNAMSIZ]; + char mac[MAXMACADDRLEN]; + char gnic[LIFNAMSIZ]; size_t addrspec; /* nonzero if tabptr has IP addr */ size_t physspec; /* nonzero if tabptr has interface */ + size_t macspec; /* nonzero if tabptr has mac addr */ + size_t gnicspec; /* nonzero if tabptr has gnic */ size_t defrouterspec; /* nonzero if tabptr has def. router */ size_t allowed_addrspec; zone_iptype_t iptype; if (tabptr == NULL)
*** 2100,2120 **** /* * Determine the fields that will be searched. There must be at least * one. * ! * zone_nwif_address, zone_nwif_physical, and zone_nwif_defrouter are * arrays, so no NULL checks are necessary. */ addrspec = strlen(tabptr->zone_nwif_address); physspec = strlen(tabptr->zone_nwif_physical); defrouterspec = strlen(tabptr->zone_nwif_defrouter); allowed_addrspec = strlen(tabptr->zone_nwif_allowed_address); if (addrspec != 0 && allowed_addrspec != 0) return (Z_INVAL); /* can't specify both */ if (addrspec == 0 && physspec == 0 && defrouterspec == 0 && ! allowed_addrspec == 0) return (Z_INSUFFICIENT_SPEC); if ((err = operation_prep(handle)) != Z_OK) return (err); --- 2117,2140 ---- /* * Determine the fields that will be searched. There must be at least * one. * ! * zone_nwif_address, zone_nwif_physical, zone_nwif_defrouter, ! * zone_nwif_mac, zone_nwif_vlan_id and zone_nwif_gnic are * arrays, so no NULL checks are necessary. */ addrspec = strlen(tabptr->zone_nwif_address); physspec = strlen(tabptr->zone_nwif_physical); + macspec = strlen(tabptr->zone_nwif_mac); + gnicspec = strlen(tabptr->zone_nwif_gnic); defrouterspec = strlen(tabptr->zone_nwif_defrouter); allowed_addrspec = strlen(tabptr->zone_nwif_allowed_address); if (addrspec != 0 && allowed_addrspec != 0) return (Z_INVAL); /* can't specify both */ if (addrspec == 0 && physspec == 0 && defrouterspec == 0 && ! allowed_addrspec == 0 && macspec == 0 && gnicspec == 0) return (Z_INSUFFICIENT_SPEC); if ((err = operation_prep(handle)) != Z_OK) return (err);
*** 2137,2146 **** --- 2157,2175 ---- */ if (physspec != 0 && (fetchprop(cur, DTD_ATTR_PHYSICAL, physical, sizeof (physical)) != Z_OK || strcmp(tabptr->zone_nwif_physical, physical) != 0)) continue; + if (iptype == ZS_EXCLUSIVE && macspec != 0 && + (fetchprop(cur, DTD_ATTR_MAC, mac, sizeof (mac)) != Z_OK || + strcmp(tabptr->zone_nwif_mac, mac) != 0)) + continue; + if (iptype == ZS_EXCLUSIVE && gnicspec != 0 && + (fetchprop(cur, DTD_ATTR_GNIC, gnic, + sizeof (gnic)) != Z_OK || + strcmp(tabptr->zone_nwif_gnic, gnic) != 0)) + continue; if (iptype == ZS_SHARED && addrspec != 0 && (fetchprop(cur, DTD_ATTR_ADDRESS, address, sizeof (address)) != Z_OK || !zonecfg_same_net_address(tabptr->zone_nwif_address, address)))
*** 2179,2188 **** --- 2208,2232 ---- (err = fetchprop(cur, DTD_ATTR_ADDRESS, tabptr->zone_nwif_address, sizeof (tabptr->zone_nwif_address))) != Z_OK) return (err); if (iptype == ZS_EXCLUSIVE && + (err = fetchprop(cur, DTD_ATTR_MAC, tabptr->zone_nwif_mac, + sizeof (tabptr->zone_nwif_mac))) != Z_OK) + return (err); + + if (iptype == ZS_EXCLUSIVE && + (err = fetchprop(cur, DTD_ATTR_VLANID, tabptr->zone_nwif_vlan_id, + sizeof (tabptr->zone_nwif_vlan_id))) != Z_OK) + return (err); + + if (iptype == ZS_EXCLUSIVE && + (err = fetchprop(cur, DTD_ATTR_GNIC, tabptr->zone_nwif_gnic, + sizeof (tabptr->zone_nwif_gnic))) != Z_OK) + return (err); + + if (iptype == ZS_EXCLUSIVE && (err = fetchprop(cur, DTD_ATTR_ALLOWED_ADDRESS, tabptr->zone_nwif_allowed_address, sizeof (tabptr->zone_nwif_allowed_address))) != Z_OK) return (err);
*** 2189,2205 **** if ((err = fetchprop(cur, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter, sizeof (tabptr->zone_nwif_defrouter))) != Z_OK) return (err); return (Z_OK); } static int zonecfg_add_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr newnode, cur = handle->zone_dh_cur; int err; newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_NET, NULL); if (strlen(tabptr->zone_nwif_address) > 0 && (err = newprop(newnode, DTD_ATTR_ADDRESS, --- 2233,2276 ---- if ((err = fetchprop(cur, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter, sizeof (tabptr->zone_nwif_defrouter))) != Z_OK) return (err); + tabptr->zone_nwif_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + struct zone_res_attrtab *valptr; + + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_nwif_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK)) + break; + if ((fetchprop(val, DTD_ATTR_VALUE, + valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK)) + break; + } + return (Z_OK); } static int zonecfg_add_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr newnode, cur = handle->zone_dh_cur, valnode; ! struct zone_res_attrtab *valptr; int err; newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_NET, NULL); if (strlen(tabptr->zone_nwif_address) > 0 && (err = newprop(newnode, DTD_ATTR_ADDRESS,
*** 2211,2227 **** return (err); if ((err = newprop(newnode, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical)) != Z_OK) return (err); /* ! * Do not add this property when it is not set, for backwards ! * compatibility and because it is optional. */ if ((strlen(tabptr->zone_nwif_defrouter) > 0) && ((err = newprop(newnode, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter)) != Z_OK)) return (err); return (Z_OK); } int zonecfg_add_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) --- 2282,2325 ---- return (err); if ((err = newprop(newnode, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical)) != Z_OK) return (err); /* ! * Do not add these properties when they are not set, for backwards ! * compatibility and because they are optional. */ if ((strlen(tabptr->zone_nwif_defrouter) > 0) && ((err = newprop(newnode, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter)) != Z_OK)) return (err); + if (strlen(tabptr->zone_nwif_mac) > 0 && + (err = newprop(newnode, DTD_ATTR_MAC, + tabptr->zone_nwif_mac)) != Z_OK) + return (err); + if (strlen(tabptr->zone_nwif_vlan_id) > 0 && + (err = newprop(newnode, DTD_ATTR_VLANID, + tabptr->zone_nwif_vlan_id)) != Z_OK) + return (err); + if (strlen(tabptr->zone_nwif_gnic) > 0 && + (err = newprop(newnode, DTD_ATTR_GNIC, + tabptr->zone_nwif_gnic)) != Z_OK) + return (err); + + for (valptr = tabptr->zone_nwif_attrp; valptr != NULL; + valptr = valptr->zone_res_attr_next) { + valnode = xmlNewTextChild(newnode, NULL, DTD_ELEM_NETATTR, + NULL); + err = newprop(valnode, DTD_ATTR_NAME, + valptr->zone_res_attr_name); + if (err != Z_OK) + return (err); + err = newprop(valnode, DTD_ATTR_VALUE, + valptr->zone_res_attr_value); + if (err != Z_OK) + return (err); + } + return (Z_OK); } int zonecfg_add_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
*** 2242,2252 **** static int zonecfg_delete_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { xmlNodePtr cur = handle->zone_dh_cur; ! boolean_t addr_match, phys_match, allowed_addr_match; for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (xmlStrcmp(cur->name, DTD_ELEM_NET)) continue; --- 2340,2351 ---- static int zonecfg_delete_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { xmlNodePtr cur = handle->zone_dh_cur; ! boolean_t addr_match, phys_match, allowed_addr_match, mac_match, ! gnic_match; for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (xmlStrcmp(cur->name, DTD_ELEM_NET)) continue;
*** 2254,2265 **** tabptr->zone_nwif_address); allowed_addr_match = match_prop(cur, DTD_ATTR_ALLOWED_ADDRESS, tabptr->zone_nwif_allowed_address); phys_match = match_prop(cur, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical); ! if (addr_match && allowed_addr_match && phys_match) { xmlUnlinkNode(cur); xmlFreeNode(cur); return (Z_OK); } } --- 2353,2369 ---- tabptr->zone_nwif_address); allowed_addr_match = match_prop(cur, DTD_ATTR_ALLOWED_ADDRESS, tabptr->zone_nwif_allowed_address); phys_match = match_prop(cur, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical); + mac_match = match_prop(cur, DTD_ATTR_MAC, + tabptr->zone_nwif_mac); + gnic_match = match_prop(cur, DTD_ATTR_GNIC, + tabptr->zone_nwif_gnic); ! if ((addr_match || allowed_addr_match || mac_match || ! gnic_match) && phys_match) { xmlUnlinkNode(cur); xmlFreeNode(cur); return (Z_OK); } }
*** 2304,2313 **** --- 2408,2469 ---- return (err); return (Z_OK); } + void + zonecfg_free_res_attr_list(struct zone_res_attrtab *valtab) + { + if (valtab == NULL) + return; + zonecfg_free_res_attr_list(valtab->zone_res_attr_next); + free(valtab); + } + + int + zonecfg_add_res_attr(struct zone_res_attrtab **headptr, + struct zone_res_attrtab *valtabptr) + { + struct zone_res_attrtab *last, *old, *new; + + last = *headptr; + for (old = last; old != NULL; old = old->zone_res_attr_next) + last = old; /* walk to the end of the list */ + new = valtabptr; /* alloc'd by caller */ + new->zone_res_attr_next = NULL; + if (last == NULL) + *headptr = new; + else + last->zone_res_attr_next = new; + return (Z_OK); + } + + int + zonecfg_remove_res_attr(struct zone_res_attrtab **headptr, + struct zone_res_attrtab *valtabptr) + { + struct zone_res_attrtab *last, *this, *next; + + last = *headptr; + for (this = last; this != NULL; this = this->zone_res_attr_next) { + if (strcmp(this->zone_res_attr_name, + valtabptr->zone_res_attr_name) == 0 && + strcmp(this->zone_res_attr_value, + valtabptr->zone_res_attr_value) == 0) { + next = this->zone_res_attr_next; + if (this == *headptr) + *headptr = next; + else + last->zone_res_attr_next = next; + free(this); + return (Z_OK); + } else + last = this; + } + return (Z_NO_PROPERTY_ID); + } + /* * Must be a comma-separated list of alpha-numeric file system names. */ static int zonecfg_valid_fs_allowed(const char *fsallowedp)
*** 2453,2463 **** } int zonecfg_lookup_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr cur, firstmatch; int err; char match[MAXPATHLEN]; if (tabptr == NULL) return (Z_INVAL); --- 2609,2619 ---- } int zonecfg_lookup_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr cur, val, firstmatch; int err; char match[MAXPATHLEN]; if (tabptr == NULL) return (Z_INVAL);
*** 2498,2522 **** if ((err = fetchprop(cur, DTD_ATTR_MATCH, tabptr->zone_dev_match, sizeof (tabptr->zone_dev_match))) != Z_OK) return (err); return (Z_OK); } static int zonecfg_add_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr newnode, cur = handle->zone_dh_cur; int err; newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_DEVICE, NULL); if ((err = newprop(newnode, DTD_ATTR_MATCH, tabptr->zone_dev_match)) != Z_OK) return (err); return (Z_OK); } int zonecfg_add_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) --- 2654,2720 ---- if ((err = fetchprop(cur, DTD_ATTR_MATCH, tabptr->zone_dev_match, sizeof (tabptr->zone_dev_match))) != Z_OK) return (err); + tabptr->zone_dev_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + struct zone_res_attrtab *valptr; + + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_dev_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK)) + break; + if ((fetchprop(val, DTD_ATTR_VALUE, + valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK)) + break; + } + return (Z_OK); } static int zonecfg_add_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr newnode, cur = handle->zone_dh_cur, valnode; ! struct zone_res_attrtab *valptr; int err; newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_DEVICE, NULL); if ((err = newprop(newnode, DTD_ATTR_MATCH, tabptr->zone_dev_match)) != Z_OK) return (err); + for (valptr = tabptr->zone_dev_attrp; valptr != NULL; + valptr = valptr->zone_res_attr_next) { + valnode = xmlNewTextChild(newnode, NULL, DTD_ELEM_NETATTR, + NULL); + err = newprop(valnode, DTD_ATTR_NAME, + valptr->zone_res_attr_name); + if (err != Z_OK) + return (err); + err = newprop(valnode, DTD_ATTR_VALUE, + valptr->zone_res_attr_value); + if (err != Z_OK) + return (err); + } + + return (Z_OK); } int zonecfg_add_dev(zone_dochandle_t handle, struct zone_devtab *tabptr)
*** 4710,4720 **** } int zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr cur; int err; if (handle == NULL) return (Z_INVAL); --- 4908,4919 ---- } int zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr cur, val; ! struct zone_res_attrtab *valptr; int err; if (handle == NULL) return (Z_INVAL);
*** 4746,4762 **** --- 4945,5002 ---- sizeof (tabptr->zone_nwif_physical))) != Z_OK) { handle->zone_dh_cur = handle->zone_dh_top; return (err); } + if ((err = fetchprop(cur, DTD_ATTR_MAC, tabptr->zone_nwif_mac, + sizeof (tabptr->zone_nwif_mac))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + if ((err = fetchprop(cur, DTD_ATTR_VLANID, tabptr->zone_nwif_vlan_id, + sizeof (tabptr->zone_nwif_vlan_id))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + if ((err = fetchprop(cur, DTD_ATTR_GNIC, tabptr->zone_nwif_gnic, + sizeof (tabptr->zone_nwif_gnic))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + if ((err = fetchprop(cur, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter, sizeof (tabptr->zone_nwif_defrouter))) != Z_OK) { handle->zone_dh_cur = handle->zone_dh_top; return (err); } + tabptr->zone_nwif_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_nwif_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if (fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK) + break; + if (fetchprop(val, DTD_ATTR_VALUE, valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK) + break; + } + handle->zone_dh_cur = cur->next; return (Z_OK); } int
*** 4772,4782 **** } int zonecfg_getdevent(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr cur; int err; if (handle == NULL) return (Z_INVAL); --- 5012,5022 ---- } int zonecfg_getdevent(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr cur, val; int err; if (handle == NULL) return (Z_INVAL);
*** 4795,4804 **** --- 5035,5069 ---- sizeof (tabptr->zone_dev_match))) != Z_OK) { handle->zone_dh_cur = handle->zone_dh_top; return (err); } + tabptr->zone_dev_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + struct zone_res_attrtab *valptr; + + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_dev_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK)) + break; + if ((fetchprop(val, DTD_ATTR_VALUE, valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK)) + break; + } + handle->zone_dh_cur = cur->next; return (Z_OK); } int
*** 5523,5532 **** --- 5788,5955 ---- zonecfg_fini_handle(handle); return (err); } /* + * Atomically get a new zone_did value. The currently allocated value + * is stored in /etc/zones/did.txt. Lock the file, read the current value, + * increment, save the new value and unlock the file. Return the new value + * or -1 if there was an error. The ID namespace is large enough that we + * don't worry about recycling an ID when a zone is deleted. + */ + static zoneid_t + new_zone_did() + { + int fd; + int len; + int val; + struct flock lck; + char buf[80]; + + if ((fd = open(DEBUGID_FILE, O_RDWR | O_CREAT, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { + perror("new_zone_did open failed"); + return (-1); + } + + /* Initialize the lock. */ + lck.l_whence = SEEK_SET; + lck.l_start = 0; + lck.l_len = 0; + + /* Wait until we acquire an exclusive lock on the file. */ + lck.l_type = F_WRLCK; + if (fcntl(fd, F_SETLKW, &lck) == -1) { + perror("new_zone_did lock failed"); + (void) close(fd); + return (-1); + } + + /* Get currently allocated value */ + len = read(fd, buf, sizeof (buf)); + if (len == -1) { + perror("new_zone_did read failed"); + val = -1; + } else { + if (lseek(fd, 0L, SEEK_SET) == -1) { + perror("new_zone_did seek failed"); + val = -1; + } else { + if (len == 0) { + /* Just created the file, initialize at 1 */ + val = 1; + } else { + val = atoi(buf); + val++; + } + + (void) snprintf(buf, sizeof (buf), "%d\n", val); + len = strlen(buf); + + /* Save newly allocated value */ + if (write(fd, buf, len) == -1) { + perror("new_zone_did write failed"); + val = -1; + } + } + } + + /* Release the file lock. */ + lck.l_type = F_UNLCK; + if (fcntl(fd, F_SETLK, &lck) == -1) { + perror("new_zone_did unlock failed"); + val = -1; + } + + if (close(fd) != 0) + perror("new_zone_did close failed"); + + return (val); + } + + /* + * Called by zoneadmd to get the zone's debug ID. + * If the zone doesn't already have an ID, a new one is generated and + * persistently saved onto the zone. Normally either zoneadm or zonecfg + * will assign a new ID for the zone, so zoneadmd should never have to + * generate one, but we also handle that here just to be paranoid. + */ + zoneid_t + zone_get_did(char *zone_name) + { + int res; + zoneid_t new_did; + zone_dochandle_t handle; + char did_str[80]; + + if ((handle = zonecfg_init_handle()) == NULL) + return (getpid()); + + if (zonecfg_get_handle((char *)zone_name, handle) != Z_OK) + return (getpid()); + + res = getrootattr(handle, DTD_ATTR_DID, did_str, sizeof (did_str)); + + /* If the zone already has an assigned debug ID, return it. */ + if (res == Z_OK && did_str[0] != '\0') { + zonecfg_fini_handle(handle); + return (atoi(did_str)); + } + + /* + * The zone doesn't have an assigned debug ID yet, generate one and + * save it as part of the zone definition. + */ + if ((new_did = new_zone_did()) == -1) { + /* + * We should really never hit this block of code. + * Generating a new ID failed for some reason. Use the current + * pid as a temporary ID so that the zone can continue to boot + * but we don't persistently save this temporary ID on the zone. + */ + zonecfg_fini_handle(handle); + return (getpid()); + } + + /* Now persistently save this new ID onto the zone. */ + (void) snprintf(did_str, sizeof (did_str), "%d", new_did); + (void) setrootattr(handle, DTD_ATTR_DID, did_str); + (void) zonecfg_save(handle); + + zonecfg_fini_handle(handle); + return (new_did); + } + + zoneid_t + zonecfg_get_did(zone_dochandle_t handle) + { + char did_str[80]; + int err; + zoneid_t did; + + err = getrootattr(handle, DTD_ATTR_DID, did_str, sizeof (did_str)); + if (err == Z_OK && did_str[0] != '\0') + did = atoi(did_str); + else + did = -1; + + return (did); + } + + void + zonecfg_set_did(zone_dochandle_t handle) + { + zoneid_t new_did; + char did_str[80]; + + if ((new_did = new_zone_did()) == -1) + return; + (void) snprintf(did_str, sizeof (did_str), "%d", new_did); + (void) setrootattr(handle, DTD_ATTR_DID, did_str); + } + + /* * Return the appropriate root for the active /dev. * For normal zone, the path is $ZONEPATH/root; * for scratch zone, the dev path is $ZONEPATH/lu. */ int
*** 6837,6973 **** (void) zonecfg_endent(handle); return (err); } ! static int ! add_mcap(zone_dochandle_t handle, struct zone_mcaptab *tabptr) ! { ! xmlNodePtr newnode, cur = handle->zone_dh_cur; ! int err; ! ! newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_MCAP, NULL); ! if ((err = newprop(newnode, DTD_ATTR_PHYSCAP, tabptr->zone_physmem_cap)) ! != Z_OK) ! return (err); ! ! return (Z_OK); ! } ! int ! zonecfg_delete_mcap(zone_dochandle_t handle) { ! int err; ! xmlNodePtr cur = handle->zone_dh_cur; ! ! if ((err = operation_prep(handle)) != Z_OK) ! return (err); ! ! for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { ! if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) != 0) ! continue; ! ! xmlUnlinkNode(cur); ! xmlFreeNode(cur); ! return (Z_OK); ! } ! return (Z_NO_RESOURCE_ID); ! } ! ! int ! zonecfg_modify_mcap(zone_dochandle_t handle, struct zone_mcaptab *tabptr) ! { ! int err; ! ! if (tabptr == NULL) ! return (Z_INVAL); ! ! err = zonecfg_delete_mcap(handle); ! /* it is ok if there is no mcap entry */ ! if (err != Z_OK && err != Z_NO_RESOURCE_ID) ! return (err); ! ! if ((err = add_mcap(handle, tabptr)) != Z_OK) ! return (err); ! ! return (Z_OK); ! } ! ! int ! zonecfg_lookup_mcap(zone_dochandle_t handle, struct zone_mcaptab *tabptr) ! { xmlNodePtr cur; ! int err; ! if (tabptr == NULL) ! return (Z_INVAL); ! if ((err = operation_prep(handle)) != Z_OK) ! return (err); ! cur = handle->zone_dh_cur; for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) != 0) continue; - if ((err = fetchprop(cur, DTD_ATTR_PHYSCAP, - tabptr->zone_physmem_cap, - sizeof (tabptr->zone_physmem_cap))) != Z_OK) { - handle->zone_dh_cur = handle->zone_dh_top; - return (err); - } ! return (Z_OK); } ! return (Z_NO_ENTRY); ! } ! ! static int ! getmcapent_core(zone_dochandle_t handle, struct zone_mcaptab *tabptr) ! { ! xmlNodePtr cur; ! int err; ! ! if (handle == NULL) ! return (Z_INVAL); ! ! if ((cur = handle->zone_dh_cur) == NULL) ! return (Z_NO_ENTRY); ! ! for (; cur != NULL; cur = cur->next) ! if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) == 0) break; - if (cur == NULL) { - handle->zone_dh_cur = handle->zone_dh_top; - return (Z_NO_ENTRY); } ! if ((err = fetchprop(cur, DTD_ATTR_PHYSCAP, tabptr->zone_physmem_cap, ! sizeof (tabptr->zone_physmem_cap))) != Z_OK) { ! handle->zone_dh_cur = handle->zone_dh_top; ! return (err); } ! handle->zone_dh_cur = cur->next; ! return (Z_OK); } - int - zonecfg_getmcapent(zone_dochandle_t handle, struct zone_mcaptab *tabptr) - { - int err; - - if ((err = zonecfg_setent(handle)) != Z_OK) - return (err); - - err = getmcapent_core(handle, tabptr); - - (void) zonecfg_endent(handle); - - return (err); - } - /* * Get the full tree of pkg metadata in a set of nested AVL trees. * pkgs_avl is an AVL tree of pkgs. * * The zone xml data contains DTD_ELEM_PACKAGE elements. --- 7260,7314 ---- (void) zonecfg_endent(handle); return (err); } ! /* ! * Cleanup obsolete constructs in the configuration. ! * Return true of the config has been updated and must be commited. ! */ int ! zonecfg_fix_obsolete(zone_dochandle_t handle) { ! int res = 0; ! int add_physmem_rctl = 0; xmlNodePtr cur; ! char zone_physmem_cap[MAXNAMELEN]; ! if (operation_prep(handle) != Z_OK) ! return (res); ! /* ! * If an obsolete mcap entry exists, convert it to the rctl. ! */ cur = handle->zone_dh_cur; for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) != 0) continue; ! if (fetchprop(cur, DTD_ATTR_PHYSCAP, ! zone_physmem_cap, sizeof (zone_physmem_cap)) == Z_OK) { ! res = 1; ! add_physmem_rctl = 1; } ! xmlUnlinkNode(cur); ! xmlFreeNode(cur); break; } ! if (add_physmem_rctl) { ! uint64_t cap; ! char *endp; ! ! cap = strtoull(zone_physmem_cap, &endp, 10); ! (void) zonecfg_set_aliased_rctl(handle, ALIAS_MAXPHYSMEM, cap); } ! return (res); } /* * Get the full tree of pkg metadata in a set of nested AVL trees. * pkgs_avl is an AVL tree of pkgs. * * The zone xml data contains DTD_ELEM_PACKAGE elements.
*** 7629,7639 **** zerror(zonename, gettext("could not stat file %s: %s"), USERATTR_FILENAME, strerror(errno)); (void) fclose(uaf); return (Z_MISC_FS); } ! if (!config_file_path(zonename, config_file)) { (void) fclose(uaf); return (Z_MISC_FS); } if ((err = stat(config_file, &config_st)) != 0) { --- 7970,7980 ---- zerror(zonename, gettext("could not stat file %s: %s"), USERATTR_FILENAME, strerror(errno)); (void) fclose(uaf); return (Z_MISC_FS); } ! if (!config_file_path(zonename, config_file, sizeof (config_file))) { (void) fclose(uaf); return (Z_MISC_FS); } if ((err = stat(config_file, &config_st)) != 0) {