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
 
 |