2923 * been disabled by SMF.
2924 */
2925 while ((zdl = list_remove_head(&zone->zone_dl_list)) != NULL) {
2926 if (zdl->zdl_net != NULL)
2927 nvlist_free(zdl->zdl_net);
2928 kmem_free(zdl, sizeof (zone_dl_t));
2929 }
2930 list_destroy(&zone->zone_dl_list);
2931
2932 /*
2933 * This zone_t can no longer inhibit creation of another zone_t
2934 * with the same name or debug ID. Generate a sysevent so that
2935 * userspace tools know it is safe to carry on.
2936 */
2937 mutex_enter(&zone_status_lock);
2938 zone_status_set(zone, ZONE_IS_FREE);
2939 mutex_exit(&zone_status_lock);
2940
2941 cpu_uarray_free(zone->zone_ustate);
2942
2943 if (zone->zone_rootvp != NULL)
2944 VN_RELE(zone->zone_rootvp);
2945 if (zone->zone_rootpath)
2946 kmem_free(zone->zone_rootpath, zone->zone_rootpathlen);
2947 if (zone->zone_name != NULL)
2948 kmem_free(zone->zone_name, ZONENAME_MAX);
2949 if (zone->zone_slabel != NULL)
2950 label_rele(zone->zone_slabel);
2951 if (zone->zone_nodename != NULL)
2952 kmem_free(zone->zone_nodename, _SYS_NMLN);
2953 if (zone->zone_domain != NULL)
2954 kmem_free(zone->zone_domain, _SYS_NMLN);
2955 if (zone->zone_privset != NULL)
2956 kmem_free(zone->zone_privset, sizeof (priv_set_t));
2957 if (zone->zone_rctls != NULL)
2958 rctl_set_free(zone->zone_rctls);
2959 if (zone->zone_bootargs != NULL)
2960 strfree(zone->zone_bootargs);
2961 if (zone->zone_initname != NULL)
2962 strfree(zone->zone_initname);
2963 if (zone->zone_fs_allowed != NULL)
2964 strfree(zone->zone_fs_allowed);
4046 (error = traverse(&vp)) == 0)) {
4047 pathlen = pn.pn_pathlen + 2;
4048 path = kmem_alloc(pathlen, KM_SLEEP);
4049 (void) strncpy(path, pn.pn_path,
4050 pn.pn_pathlen + 1);
4051 path[pathlen - 2] = '/';
4052 path[pathlen - 1] = '\0';
4053 pn_free(&pn);
4054 pn_free(&upn);
4055
4056 /* Success! */
4057 break;
4058 }
4059 VN_RELE(vp);
4060 }
4061 if (error != ESTALE)
4062 goto out;
4063 }
4064
4065 ASSERT(error == 0);
4066 zone->zone_rootvp = vp; /* we hold a reference to vp */
4067 zone->zone_rootpath = path;
4068 zone->zone_rootpathlen = pathlen;
4069 if (pathlen > 5 && strcmp(path + pathlen - 5, "/lu/") == 0)
4070 zone->zone_flags |= ZF_IS_SCRATCH;
4071 return (0);
4072
4073 out:
4074 pn_free(&pn);
4075 pn_free(&upn);
4076 return (error);
4077 }
4078
4079 #define isalnum(c) (((c) >= '0' && (c) <= '9') || \
4080 ((c) >= 'a' && (c) <= 'z') || \
4081 ((c) >= 'A' && (c) <= 'Z'))
4082
4083 static int
4084 zone_set_name(zone_t *zone, const char *uname)
4085 {
6027 * reference goes away.
6028 */
6029 ASSERT(zonecount > 1); /* must be > 1; can't destroy global zone */
6030 zonecount--;
6031 /* remove from active list and hash tables */
6032 list_remove(&zone_active, zone);
6033 (void) mod_hash_destroy(zonehashbyname,
6034 (mod_hash_key_t)zone->zone_name);
6035 (void) mod_hash_destroy(zonehashbyid,
6036 (mod_hash_key_t)(uintptr_t)zone->zone_id);
6037 if (zone->zone_flags & ZF_HASHED_LABEL)
6038 (void) mod_hash_destroy(zonehashbylabel,
6039 (mod_hash_key_t)zone->zone_slabel);
6040 mutex_exit(&zonehash_lock);
6041
6042 /*
6043 * Release the root vnode; we're not using it anymore. Nor should any
6044 * other thread that might access it exist.
6045 */
6046 if (zone->zone_rootvp != NULL) {
6047 VN_RELE(zone->zone_rootvp);
6048 zone->zone_rootvp = NULL;
6049 }
6050
6051 /* add to deathrow list */
6052 mutex_enter(&zone_deathrow_lock);
6053 list_insert_tail(&zone_deathrow, zone);
6054 mutex_exit(&zone_deathrow_lock);
6055
6056 /*
6057 * Drop last reference (which was added by zsched()), this will
6058 * free the zone unless there are outstanding cred references.
6059 */
6060 zone_rele(zone);
6061 return (0);
6062 }
6063
6064 /*
6065 * Systemcall entry point for zone_getattr(2).
6066 */
6067 static ssize_t
|
2923 * been disabled by SMF.
2924 */
2925 while ((zdl = list_remove_head(&zone->zone_dl_list)) != NULL) {
2926 if (zdl->zdl_net != NULL)
2927 nvlist_free(zdl->zdl_net);
2928 kmem_free(zdl, sizeof (zone_dl_t));
2929 }
2930 list_destroy(&zone->zone_dl_list);
2931
2932 /*
2933 * This zone_t can no longer inhibit creation of another zone_t
2934 * with the same name or debug ID. Generate a sysevent so that
2935 * userspace tools know it is safe to carry on.
2936 */
2937 mutex_enter(&zone_status_lock);
2938 zone_status_set(zone, ZONE_IS_FREE);
2939 mutex_exit(&zone_status_lock);
2940
2941 cpu_uarray_free(zone->zone_ustate);
2942
2943 if (zone->zone_rootvp != NULL) {
2944 vnode_t *vp = zone->zone_rootvp;
2945
2946 mutex_enter(&vp->v_lock);
2947 vp->v_flag &= ~VZONEROOT;
2948 mutex_exit(&vp->v_lock);
2949 VN_RELE(vp);
2950 /* No need to worry about NULL-ing out zone_rootvp. */
2951 }
2952 if (zone->zone_rootpath)
2953 kmem_free(zone->zone_rootpath, zone->zone_rootpathlen);
2954 if (zone->zone_name != NULL)
2955 kmem_free(zone->zone_name, ZONENAME_MAX);
2956 if (zone->zone_slabel != NULL)
2957 label_rele(zone->zone_slabel);
2958 if (zone->zone_nodename != NULL)
2959 kmem_free(zone->zone_nodename, _SYS_NMLN);
2960 if (zone->zone_domain != NULL)
2961 kmem_free(zone->zone_domain, _SYS_NMLN);
2962 if (zone->zone_privset != NULL)
2963 kmem_free(zone->zone_privset, sizeof (priv_set_t));
2964 if (zone->zone_rctls != NULL)
2965 rctl_set_free(zone->zone_rctls);
2966 if (zone->zone_bootargs != NULL)
2967 strfree(zone->zone_bootargs);
2968 if (zone->zone_initname != NULL)
2969 strfree(zone->zone_initname);
2970 if (zone->zone_fs_allowed != NULL)
2971 strfree(zone->zone_fs_allowed);
4053 (error = traverse(&vp)) == 0)) {
4054 pathlen = pn.pn_pathlen + 2;
4055 path = kmem_alloc(pathlen, KM_SLEEP);
4056 (void) strncpy(path, pn.pn_path,
4057 pn.pn_pathlen + 1);
4058 path[pathlen - 2] = '/';
4059 path[pathlen - 1] = '\0';
4060 pn_free(&pn);
4061 pn_free(&upn);
4062
4063 /* Success! */
4064 break;
4065 }
4066 VN_RELE(vp);
4067 }
4068 if (error != ESTALE)
4069 goto out;
4070 }
4071
4072 ASSERT(error == 0);
4073 mutex_enter(&vp->v_lock);
4074 if (vp->v_flag & VZONEROOT) {
4075 /* Wow, someone's already using this zone root! */
4076 error = EEXIST; /* XXX KEBE ASKS, better errno? */
4077 mutex_exit(&vp->v_lock);
4078 VN_RELE(vp);
4079 goto out;
4080 }
4081 vp->v_flag |= VZONEROOT;
4082 mutex_exit(&vp->v_lock);
4083 zone->zone_rootvp = vp; /* we hold a reference to vp */
4084 zone->zone_rootpath = path;
4085 zone->zone_rootpathlen = pathlen;
4086 if (pathlen > 5 && strcmp(path + pathlen - 5, "/lu/") == 0)
4087 zone->zone_flags |= ZF_IS_SCRATCH;
4088 return (0);
4089
4090 out:
4091 pn_free(&pn);
4092 pn_free(&upn);
4093 return (error);
4094 }
4095
4096 #define isalnum(c) (((c) >= '0' && (c) <= '9') || \
4097 ((c) >= 'a' && (c) <= 'z') || \
4098 ((c) >= 'A' && (c) <= 'Z'))
4099
4100 static int
4101 zone_set_name(zone_t *zone, const char *uname)
4102 {
6044 * reference goes away.
6045 */
6046 ASSERT(zonecount > 1); /* must be > 1; can't destroy global zone */
6047 zonecount--;
6048 /* remove from active list and hash tables */
6049 list_remove(&zone_active, zone);
6050 (void) mod_hash_destroy(zonehashbyname,
6051 (mod_hash_key_t)zone->zone_name);
6052 (void) mod_hash_destroy(zonehashbyid,
6053 (mod_hash_key_t)(uintptr_t)zone->zone_id);
6054 if (zone->zone_flags & ZF_HASHED_LABEL)
6055 (void) mod_hash_destroy(zonehashbylabel,
6056 (mod_hash_key_t)zone->zone_slabel);
6057 mutex_exit(&zonehash_lock);
6058
6059 /*
6060 * Release the root vnode; we're not using it anymore. Nor should any
6061 * other thread that might access it exist.
6062 */
6063 if (zone->zone_rootvp != NULL) {
6064 vnode_t *vp = zone->zone_rootvp;
6065
6066 mutex_enter(&vp->v_lock);
6067 vp->v_flag &= ~VZONEROOT;
6068 mutex_exit(&vp->v_lock);
6069 VN_RELE(vp);
6070 zone->zone_rootvp = NULL;
6071 }
6072
6073 /* add to deathrow list */
6074 mutex_enter(&zone_deathrow_lock);
6075 list_insert_tail(&zone_deathrow, zone);
6076 mutex_exit(&zone_deathrow_lock);
6077
6078 /*
6079 * Drop last reference (which was added by zsched()), this will
6080 * free the zone unless there are outstanding cred references.
6081 */
6082 zone_rele(zone);
6083 return (0);
6084 }
6085
6086 /*
6087 * Systemcall entry point for zone_getattr(2).
6088 */
6089 static ssize_t
|