Print this page
*** 20,31 ****
*/
/*
* Copyright 2014 Gary Mills
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015 Joyent Inc.
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <libsysevent.h>
#include <pthread.h>
#include <stdlib.h>
--- 20,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>
*** 189,199 ****
{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},
- {ALIAS_ZFSPRI, "zone.zfs-io-priority", "privileged", "none", 0},
{NULL, NULL, NULL, NULL, 0}
};
/*
* Structure for applying rctls to a running zone. It allows important
--- 189,198 ----
*** 237,248 ****
/* used to communicate lock status to children */
#define LOCK_ENV_VAR "_ZONEADM_LOCK_HELD"
static char zoneadm_lock_held[] = LOCK_ENV_VAR"=1";
static char zoneadm_lock_not_held[] = LOCK_ENV_VAR"=0";
- static void zonecfg_notify_delete(const char *);
-
char *zonecfg_root = "";
/*
* For functions which return int, which is most of the functions herein,
* the return values should be from the Z_foo set defined in <libzonecfg.h>.
--- 236,245 ----
*** 428,441 ****
/*
* Treat failure to find the XML file silently, since, well, it's
* gone, and with the index file cleaned up, we're done.
*/
! if (err == Z_OK || err == Z_NO_ZONE) {
! zonecfg_notify_delete(zonename);
return (Z_OK);
- }
return (err);
}
int
zonecfg_destroy_snapshot(const char *zonename)
--- 425,436 ----
/*
* Treat failure to find the XML file silently, since, well, it's
* gone, and with the index file cleaned up, we're done.
*/
! if (err == Z_OK || err == Z_NO_ZONE)
return (Z_OK);
return (err);
}
int
zonecfg_destroy_snapshot(const char *zonename)
*** 1128,1138 ****
* An additional complexity is that when doing a rename, we'd like the entire
* index update operation (rename, and potential state changes) to be atomic.
* In general, the operation of this function should succeed or fail as
* a unit.
*/
! static int
zonecfg_refresh_index_file(zone_dochandle_t handle)
{
char name[ZONENAME_MAX], zonepath[MAXPATHLEN];
struct zoneent ze;
int err;
--- 1123,1133 ----
* An additional complexity is that when doing a rename, we'd like the entire
* index update operation (rename, and potential state changes) to be atomic.
* In general, the operation of this function should succeed or fail as
* a unit.
*/
! int
zonecfg_refresh_index_file(zone_dochandle_t handle)
{
char name[ZONENAME_MAX], zonepath[MAXPATHLEN];
struct zoneent ze;
int err;
*** 1150,1168 ****
sizeof (zonepath))) != Z_OK)
return (err);
(void) strlcpy(ze.zone_path, zonepath + strlen(zonecfg_root),
sizeof (ze.zone_path));
- if ((err = zonecfg_get_brand(handle, ze.zone_brand,
- sizeof (ze.zone_brand))) != 0)
- return (err);
-
- if ((err = zonecfg_get_iptype(handle, &ze.zone_iptype)) != Z_OK)
- return (err);
-
- ze.zone_did = zonecfg_get_did(handle);
-
if (is_renaming(handle)) {
opcode = PZE_MODIFY;
(void) strlcpy(ze.zone_name, handle->zone_dh_delete_name,
sizeof (ze.zone_name));
(void) strlcpy(ze.zone_newname, name, sizeof (ze.zone_newname));
--- 1145,1154 ----
*** 1501,1560 ****
(void) unlink(attached);
(void) unlink(detached);
}
}
- static void
- zonecfg_notify_conf_change(const char *zname, char *os, char *ns)
- {
- evchan_t *ze_chan;
- struct timeval now;
- uint64_t t;
- nvlist_t *nvl = NULL;
-
- if (sysevent_evc_bind(ZONE_EVENT_CHANNEL, &ze_chan, 0) != 0)
- return;
-
- /* Current time since Jan 1 1970 but consumers expect NS */
- gettimeofday(&now, NULL);
- t = (now.tv_sec * NANOSEC) + (now.tv_usec * 1000);
-
- if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) == 0 &&
- nvlist_add_string(nvl, ZONE_CB_NAME, zname) == 0 &&
- nvlist_add_string(nvl, ZONE_CB_NEWSTATE, ns) == 0 &&
- nvlist_add_string(nvl, ZONE_CB_OLDSTATE, os) == 0 &&
- nvlist_add_int32(nvl, ZONE_CB_ZONEID, -1) == 0 &&
- nvlist_add_uint64(nvl, ZONE_CB_TIMESTAMP, t) == 0) {
- (void) sysevent_evc_publish(ze_chan, ZONE_EVENT_STATUS_CLASS,
- ZONE_EVENT_STATUS_SUBCLASS, "sun.com", "zonecfg", nvl,
- EVCH_SLEEP);
- }
-
- nvlist_free(nvl);
- (void) sysevent_evc_unbind(ze_chan);
- }
-
- void
- zonecfg_notify_create(zone_dochandle_t handle)
- {
- char zname[ZONENAME_MAX];
-
- if (zonecfg_check_handle(handle) != Z_OK)
- return;
-
- if (zonecfg_get_name(handle, zname, sizeof (zname)) != Z_OK)
- return;
-
- zonecfg_notify_conf_change(zname, "", ZONE_STATE_STR_CONFIGURED);
- }
-
- static void
- zonecfg_notify_delete(const char *zname)
- {
- zonecfg_notify_conf_change(zname, ZONE_STATE_STR_CONFIGURED, "");
- }
-
/*
* Special case: if access(2) fails with ENOENT, then try again using
* ZONE_CONFIG_ROOT instead of config_file_path(zonename). This is how we
* work around the case of a config file which has not been created yet:
* the user will need access to the directory so use that as a heuristic.
--- 1487,1496 ----
*** 2141,2176 ****
(void) close(so);
return (B_TRUE);
}
/*
- * Turn an addr that looks like f:2:0:44:5:6C into 0f:02:00:44:05:6c
- * We're expecting a dst of at least MAXMACADDRLEN size here.
- */
- static void
- normalize_mac_addr(char *dst, const char *src, int len)
- {
- char *p, *e, *sep = "";
- long n;
- char buf[MAXMACADDRLEN], tmp[4];
-
- *dst = '\0';
- (void) strlcpy(buf, src, sizeof (buf));
- p = strtok(buf, ":");
- while (p != NULL) {
- n = strtol(p, &e, 16);
- if (*e != NULL || n > 0xff)
- return;
- (void) snprintf(tmp, sizeof (tmp), "%s%02x", sep, n);
- (void) strlcat(dst, tmp, len);
-
- sep = ":";
- p = strtok(NULL, ":");
- }
- }
-
- /*
* Determines whether there is a net resource with the physical interface, IP
* address, and default router specified by 'tabptr' in the zone configuration
* to which 'handle' refers. 'tabptr' must have an interface, an address, a
* default router, or a combination of the three. This function returns Z_OK
* iff there is exactly one net resource matching the query specified by
--- 2077,2086 ----
*** 2191,2201 ****
xmlNodePtr firstmatch;
int err;
char address[INET6_ADDRSTRLEN];
char physical[LIFNAMSIZ];
char mac[MAXMACADDRLEN];
- char norm_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 */
--- 2101,2110 ----
*** 2248,2265 ****
*/
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) {
! if (fetchprop(cur, DTD_ATTR_MAC, mac, sizeof (mac)) !=
! Z_OK)
continue;
- normalize_mac_addr(norm_mac, mac, sizeof (norm_mac));
- if (strcmp(tabptr->zone_nwif_mac, norm_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;
--- 2157,2170 ----
*/
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;
*** 2453,2463 ****
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);
}
--- 2358,2368 ----
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);
}
*** 4865,4875 ****
{
int status;
pool_conf_t *poolconf;
pool_t *pool;
pool_elem_t *pe;
! pool_value_t *pv;
const char *sched_str;
if (pool_get_status(&status) != PO_SUCCESS || status != POOL_ENABLED)
return (Z_NO_POOL);
--- 4770,4780 ----
{
int status;
pool_conf_t *poolconf;
pool_t *pool;
pool_elem_t *pe;
! pool_value_t *pv = pool_value_alloc();
const char *sched_str;
if (pool_get_status(&status) != PO_SUCCESS || status != POOL_ENABLED)
return (Z_NO_POOL);
*** 4886,4912 ****
(void) pool_conf_close(poolconf);
pool_conf_free(poolconf);
return (Z_NO_POOL);
}
- if ((pv = pool_value_alloc()) == NULL) {
- (void) pool_conf_close(poolconf);
- pool_conf_free(poolconf);
- return (Z_NO_POOL);
- }
-
pe = pool_to_elem(poolconf, pool);
if (pool_get_property(poolconf, pe, "pool.scheduler", pv) !=
POC_STRING) {
(void) pool_conf_close(poolconf);
- pool_value_free(pv);
pool_conf_free(poolconf);
return (Z_NO_ENTRY);
}
(void) pool_value_get_string(pv, &sched_str);
(void) pool_conf_close(poolconf);
- pool_value_free(pv);
pool_conf_free(poolconf);
if (strlcpy(class, sched_str, clsize) >= clsize)
return (Z_TOO_BIG);
return (Z_OK);
}
--- 4791,4809 ----
*** 6172,6202 ****
int
zone_set_state(char *zone, zone_state_t state)
{
struct zoneent ze;
- int res;
- zone_state_t oldst = (zone_state_t)-1;
if (state != ZONE_STATE_CONFIGURED && state != ZONE_STATE_INSTALLED &&
state != ZONE_STATE_INCOMPLETE)
return (Z_INVAL);
- (void) zone_get_state(zone, &oldst);
-
bzero(&ze, sizeof (ze));
(void) strlcpy(ze.zone_name, zone, sizeof (ze.zone_name));
ze.zone_state = state;
(void) strlcpy(ze.zone_path, "", sizeof (ze.zone_path));
! res = putzoneent(&ze, PZE_MODIFY);
!
! if (res == Z_OK) {
! zonecfg_notify_conf_change(zone, zone_state_str(oldst),
! zone_state_str(state));
! }
!
! return (res);
}
/*
* Get id (if any) for specified zone. There are four possible outcomes:
* - If the string corresponds to the numeric id of an active (booted)
--- 6069,6088 ----
int
zone_set_state(char *zone, zone_state_t state)
{
struct zoneent ze;
if (state != ZONE_STATE_CONFIGURED && state != ZONE_STATE_INSTALLED &&
state != ZONE_STATE_INCOMPLETE)
return (Z_INVAL);
bzero(&ze, sizeof (ze));
(void) strlcpy(ze.zone_name, zone, sizeof (ze.zone_name));
ze.zone_state = state;
(void) strlcpy(ze.zone_path, "", sizeof (ze.zone_path));
! return (putzoneent(&ze, PZE_MODIFY));
}
/*
* Get id (if any) for specified zone. There are four possible outcomes:
* - If the string corresponds to the numeric id of an active (booted)
*** 6341,6374 ****
} else {
return (Z_NO_ZONE);
}
}
- /*
- * Changes a zone's UUID to the given value. Returns an error if the UUID is
- * malformed or if the zone cannot be located.
- */
- int
- zonecfg_set_uuid(const char *zonename, const char *zonepath,
- const char *uuid)
- {
- int err;
- struct zoneent ze;
-
- bzero(&ze, sizeof (ze));
- ze.zone_state = -1; /* Preserve existing state in index */
- (void) strlcpy(ze.zone_name, zonename, sizeof (ze.zone_name));
- (void) strlcpy(ze.zone_path, zonepath, sizeof (ze.zone_path));
- if (uuid_parse((char *)uuid, ze.zone_uuid) == -1)
- return (Z_INVALID_PROPERTY);
-
- if ((err = putzoneent(&ze, PZE_MODIFY)) != Z_OK)
- return (err);
-
- return (Z_OK);
- }
-
/*
* File-system convenience functions.
*/
boolean_t
zonecfg_valid_fs_type(const char *type)
--- 6227,6236 ----