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) {