diff options
author | carlsonj <none@none> | 2006-04-07 13:37:39 -0700 |
---|---|---|
committer | carlsonj <none@none> | 2006-04-07 13:37:39 -0700 |
commit | 48451833426400c4caea45c906663fcdc96fa797 (patch) | |
tree | a80037d8d0d8f4ec6c6278680e2af012551d2dc3 /usr | |
parent | 108ba07164f2a4683cb1eebe5d72f5a391eb7173 (diff) | |
download | illumos-gate-48451833426400c4caea45c906663fcdc96fa797.tar.gz |
6404654 zoneadm mount command fails on labeled systems
Diffstat (limited to 'usr')
-rw-r--r-- | usr/src/cmd/zoneadmd/vplat.c | 18 | ||||
-rw-r--r-- | usr/src/uts/common/fs/lofs/lofs_vfsops.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/os/zone.c | 40 | ||||
-rw-r--r-- | usr/src/uts/common/sys/zone.h | 4 |
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); /* |