summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorcarlsonj <none@none>2006-04-07 13:37:39 -0700
committercarlsonj <none@none>2006-04-07 13:37:39 -0700
commit48451833426400c4caea45c906663fcdc96fa797 (patch)
treea80037d8d0d8f4ec6c6278680e2af012551d2dc3 /usr
parent108ba07164f2a4683cb1eebe5d72f5a391eb7173 (diff)
downloadillumos-gate-48451833426400c4caea45c906663fcdc96fa797.tar.gz
6404654 zoneadm mount command fails on labeled systems
Diffstat (limited to 'usr')
-rw-r--r--usr/src/cmd/zoneadmd/vplat.c18
-rw-r--r--usr/src/uts/common/fs/lofs/lofs_vfsops.c10
-rw-r--r--usr/src/uts/common/os/zone.c40
-rw-r--r--usr/src/uts/common/sys/zone.h4
4 files changed, 49 insertions, 23 deletions
diff --git a/usr/src/cmd/zoneadmd/vplat.c b/usr/src/cmd/zoneadmd/vplat.c
index 13a5507fde..c58eba5397 100644
--- a/usr/src/cmd/zoneadmd/vplat.c
+++ b/usr/src/cmd/zoneadmd/vplat.c
@@ -722,7 +722,8 @@ unmount_filesystems(zlog_t *zlogp, zoneid_t zoneid, boolean_t unmount_cmd)
* For Trusted Extensions unmount each higher level zone's mount
* of our zone's /export/home
*/
- tsol_unmounts(zlogp, zone_name);
+ if (!unmount_cmd)
+ tsol_unmounts(zlogp, zone_name);
if ((mnttab = fopen(MNTTAB, "r")) == NULL) {
zerror(zlogp, B_TRUE, "failed to open %s", MNTTAB);
@@ -1529,7 +1530,7 @@ mount_filesystems(zlog_t *zlogp, boolean_t mount_cmd)
/*
* For Trusted Extensions cross-mount each lower level /export/home
*/
- if (tsol_mounts(zlogp, zone_name, rootpath) != 0)
+ if (!mount_cmd && tsol_mounts(zlogp, zone_name, rootpath) != 0)
goto bad;
free_fs_data(fs_ptr, num_fs);
@@ -2915,12 +2916,10 @@ again:
if (zone_get_state(zid_name, &zid_state) != Z_OK ||
- (zid_state != ZONE_STATE_MOUNTED &&
- zid_state != ZONE_STATE_RUNNING)) {
-
+ (zid_state != ZONE_STATE_READY &&
+ zid_state != ZONE_STATE_RUNNING))
/* Skip over zones without mounted filesystems */
continue;
- }
if (zone_getattr(zids[i], ZONE_ATTR_SLBL, zid_label,
sizeof (m_label_t)) < 0)
@@ -3402,9 +3401,9 @@ vplat_create(zlog_t *zlogp, boolean_t mount_cmd)
goto error;
}
- if (is_system_labeled()) {
+ if (!mount_cmd && is_system_labeled()) {
zcent = get_zone_label(zlogp, privs);
- if (zcent) {
+ if (zcent != NULL) {
match = zcent->zc_match;
doi = zcent->zc_doi;
*zlabel = zcent->zc_label;
@@ -3520,7 +3519,8 @@ vplat_create(zlog_t *zlogp, boolean_t mount_cmd)
if (!mount_cmd && bind_to_pool(zlogp, zoneid) != 0)
zerror(zlogp, B_FALSE, "WARNING: unable to bind zone to "
"requested pool; using default pool.");
- set_mlps(zlogp, zoneid, zcent);
+ if (!mount_cmd)
+ set_mlps(zlogp, zoneid, zcent);
rval = zoneid;
zoneid = -1;
diff --git a/usr/src/uts/common/fs/lofs/lofs_vfsops.c b/usr/src/uts/common/fs/lofs/lofs_vfsops.c
index 7ed3a9c083..35ae3c58ba 100644
--- a/usr/src/uts/common/fs/lofs/lofs_vfsops.c
+++ b/usr/src/uts/common/fs/lofs/lofs_vfsops.c
@@ -256,9 +256,17 @@ lo_mount(struct vfs *vfsp,
* incorrectly appear as the global zone since it's not
* under the zone rootpath. So for zone devfs check allow
* read-write mounts.
+ *
+ * Second special case for scratch zones used for Live Upgrade:
+ * this is used to mount the zone's root from /root to /a in
+ * the scratch zone. As with the other special case, this
+ * appears to be outside of the zone because it's not under
+ * the zone rootpath, which is $ZONEPATH/lu in the scratch
+ * zone case.
*/
- if (from_zptr != to_zptr && !is_zonedevfs) {
+ if (from_zptr != to_zptr && !is_zonedevfs &&
+ !(to_zptr->zone_flags & ZF_IS_SCRATCH)) {
/*
* We know at this point that the labels aren't equal
* because the zone pointers aren't equal, and zones
diff --git a/usr/src/uts/common/os/zone.c b/usr/src/uts/common/os/zone.c
index a34da6e75a..c675393a02 100644
--- a/usr/src/uts/common/os/zone.c
+++ b/usr/src/uts/common/os/zone.c
@@ -1140,9 +1140,11 @@ zone_init(void)
(mod_hash_val_t)&zone0);
(void) mod_hash_insert(zonehashbyname, (mod_hash_key_t)zone0.zone_name,
(mod_hash_val_t)&zone0);
- if (is_system_labeled())
+ if (is_system_labeled()) {
+ zone0.zone_flags |= ZF_HASHED_LABEL;
(void) mod_hash_insert(zonehashbylabel,
(mod_hash_key_t)zone0.zone_slabel, (mod_hash_val_t)&zone0);
+ }
mutex_exit(&zonehash_lock);
/*
@@ -1936,6 +1938,8 @@ zone_set_root(zone_t *zone, const char *upath)
zone->zone_rootvp = vp; /* we hold a reference to vp */
zone->zone_rootpath = path;
zone->zone_rootpathlen = pathlen;
+ if (pathlen > 5 && strcmp(path + pathlen - 5, "/lu/") == 0)
+ zone->zone_flags |= ZF_IS_SCRATCH;
return (0);
out:
@@ -2799,6 +2803,7 @@ zone_create(const char *zone_name, const char *zone_root,
int error2 = 0;
char *str;
cred_t *zkcr;
+ boolean_t insert_label_hash;
if (secpolicy_zone_config(CRED()) != 0)
return (set_errno(EPERM));
@@ -2869,16 +2874,18 @@ zone_create(const char *zone_name, const char *zone_root,
* match flag and sensitivity label.
*/
zone->zone_match = match;
- if (is_system_labeled()) {
+ if (is_system_labeled() && !(zone->zone_flags & ZF_IS_SCRATCH)) {
error = zone_set_label(zone, label, doi);
if (error != 0) {
zone_free(zone);
return (set_errno(error));
}
+ insert_label_hash = B_TRUE;
} else {
/* all zones get an admin_low label if system is not labeled */
zone->zone_slabel = l_admin_low;
label_hold(l_admin_low);
+ insert_label_hash = B_FALSE;
}
/*
@@ -2924,7 +2931,7 @@ zone_create(const char *zone_name, const char *zone_root,
* make sure no other zone exists that has the same label.
*/
if ((ztmp = zone_find_all_by_name(zone->zone_name)) != NULL ||
- (zone->zone_slabel != NULL &&
+ (insert_label_hash &&
(ztmp = zone_find_all_by_label(zone->zone_slabel)) != NULL)) {
zone_status_t status;
@@ -2972,9 +2979,10 @@ zone_create(const char *zone_name, const char *zone_root,
(void) strcpy(str, zone->zone_name);
(void) mod_hash_insert(zonehashbyname, (mod_hash_key_t)str,
(mod_hash_val_t)(uintptr_t)zone);
- if (is_system_labeled()) {
+ if (insert_label_hash) {
(void) mod_hash_insert(zonehashbylabel,
(mod_hash_key_t)zone->zone_slabel, (mod_hash_val_t)zone);
+ zone->zone_flags |= ZF_HASHED_LABEL;
}
/*
@@ -3000,7 +3008,7 @@ zone_create(const char *zone_name, const char *zone_root,
*/
mutex_enter(&zonehash_lock);
list_remove(&zone_active, zone);
- if (is_system_labeled()) {
+ if (zone->zone_flags & ZF_HASHED_LABEL) {
ASSERT(zone->zone_slabel != NULL);
(void) mod_hash_destroy(zonehashbylabel,
(mod_hash_key_t)zone->zone_slabel);
@@ -3168,7 +3176,7 @@ zone_list_access(zone_t *zone)
if (curproc->p_zone == global_zone ||
curproc->p_zone == zone) {
return (B_TRUE);
- } else if (is_system_labeled()) {
+ } else if (is_system_labeled() && !(zone->zone_flags & ZF_IS_SCRATCH)) {
bslabel_t *curproc_label;
bslabel_t *zone_label;
@@ -3442,7 +3450,7 @@ zone_destroy(zoneid_t zoneid)
(mod_hash_key_t)zone->zone_name);
(void) mod_hash_destroy(zonehashbyid,
(mod_hash_key_t)(uintptr_t)zone->zone_id);
- if (is_system_labeled() && zone->zone_slabel != NULL)
+ if (zone->zone_flags & ZF_HASHED_LABEL)
(void) mod_hash_destroy(zonehashbylabel,
(mod_hash_key_t)zone->zone_slabel);
mutex_exit(&zonehash_lock);
@@ -4023,7 +4031,7 @@ static int
zone_list(zoneid_t *zoneidlist, uint_t *numzones)
{
zoneid_t *zoneids;
- zone_t *zone;
+ zone_t *zone, *myzone;
uint_t user_nzones, real_nzones;
uint_t domi_nzones;
int error;
@@ -4031,14 +4039,15 @@ zone_list(zoneid_t *zoneidlist, uint_t *numzones)
if (copyin(numzones, &user_nzones, sizeof (uint_t)) != 0)
return (set_errno(EFAULT));
- if (curproc->p_zone != global_zone) {
+ myzone = curproc->p_zone;
+ if (myzone != global_zone) {
bslabel_t *mybslab;
if (!is_system_labeled()) {
/* just return current zone */
real_nzones = domi_nzones = 1;
zoneids = kmem_alloc(sizeof (zoneid_t), KM_SLEEP);
- zoneids[0] = curproc->p_zone->zone_id;
+ zoneids[0] = myzone->zone_id;
} else {
/* return all zones that are dominated */
mutex_enter(&zonehash_lock);
@@ -4047,13 +4056,20 @@ zone_list(zoneid_t *zoneidlist, uint_t *numzones)
if (real_nzones > 0) {
zoneids = kmem_alloc(real_nzones *
sizeof (zoneid_t), KM_SLEEP);
- mybslab = label2bslabel(curproc->p_zone->
- zone_slabel);
+ mybslab = label2bslabel(myzone->zone_slabel);
for (zone = list_head(&zone_active);
zone != NULL;
zone = list_next(&zone_active, zone)) {
if (zone->zone_id == GLOBAL_ZONEID)
continue;
+ if (zone != myzone &&
+ (zone->zone_flags & ZF_IS_SCRATCH))
+ continue;
+ /*
+ * Note that a label always dominates
+ * itself, so myzone is always included
+ * in the list.
+ */
if (bldominates(mybslab,
label2bslabel(zone->zone_slabel))) {
zoneids[domi_nzones++] =
diff --git a/usr/src/uts/common/sys/zone.h b/usr/src/uts/common/sys/zone.h
index ef07aa2877..43ccc07668 100644
--- a/usr/src/uts/common/sys/zone.h
+++ b/usr/src/uts/common/sys/zone.h
@@ -215,6 +215,8 @@ typedef struct zone_cmd_rval {
/* zone_flags */
#define ZF_DESTROYED 0x1 /* ZSD destructor callbacks run */
+#define ZF_HASHED_LABEL 0x2 /* zone has a unique label */
+#define ZF_IS_SCRATCH 0x4 /* scratch zone */
struct pool;
@@ -334,8 +336,8 @@ extern void zone_task_rele(zone_t *);
extern zone_t *zone_find_by_id(zoneid_t);
extern zone_t *zone_find_by_label(const ts_label_t *);
extern zone_t *zone_find_by_name(char *);
-extern zone_t *zone_find_by_path(const char *);
extern zone_t *zone_find_by_any_path(const char *, boolean_t);
+extern zone_t *zone_find_by_path(const char *);
extern zoneid_t getzoneid(void);
/*