2377          */
2378         cpucaps_zone_remove(zone);
2379 
2380         ASSERT(zone->zone_cpucap == NULL);
2381 
2382         /* remove from deathrow list */
2383         if (zone_status_get(zone) == ZONE_IS_DEAD) {
2384                 ASSERT(zone->zone_ref == 0);
2385                 mutex_enter(&zone_deathrow_lock);
2386                 list_remove(&zone_deathrow, zone);
2387                 mutex_exit(&zone_deathrow_lock);
2388         }
2389 
2390         list_destroy(&zone->zone_ref_list);
2391         zone_free_zsd(zone);
2392         zone_free_datasets(zone);
2393         list_destroy(&zone->zone_dl_list);
2394 
2395         cpu_uarray_free(zone->zone_ustate);
2396 
2397         if (zone->zone_rootvp != NULL)
2398                 VN_RELE(zone->zone_rootvp);
2399         if (zone->zone_rootpath)
2400                 kmem_free(zone->zone_rootpath, zone->zone_rootpathlen);
2401         if (zone->zone_name != NULL)
2402                 kmem_free(zone->zone_name, ZONENAME_MAX);
2403         if (zone->zone_slabel != NULL)
2404                 label_rele(zone->zone_slabel);
2405         if (zone->zone_nodename != NULL)
2406                 kmem_free(zone->zone_nodename, _SYS_NMLN);
2407         if (zone->zone_domain != NULL)
2408                 kmem_free(zone->zone_domain, _SYS_NMLN);
2409         if (zone->zone_privset != NULL)
2410                 kmem_free(zone->zone_privset, sizeof (priv_set_t));
2411         if (zone->zone_rctls != NULL)
2412                 rctl_set_free(zone->zone_rctls);
2413         if (zone->zone_bootargs != NULL)
2414                 strfree(zone->zone_bootargs);
2415         if (zone->zone_initname != NULL)
2416                 strfree(zone->zone_initname);
2417         if (zone->zone_fs_allowed != NULL)
2418                 strfree(zone->zone_fs_allowed);
 
3461                             (error = traverse(&vp)) == 0)) {
3462                                 pathlen = pn.pn_pathlen + 2;
3463                                 path = kmem_alloc(pathlen, KM_SLEEP);
3464                                 (void) strncpy(path, pn.pn_path,
3465                                     pn.pn_pathlen + 1);
3466                                 path[pathlen - 2] = '/';
3467                                 path[pathlen - 1] = '\0';
3468                                 pn_free(&pn);
3469                                 pn_free(&upn);
3470 
3471                                 /* Success! */
3472                                 break;
3473                         }
3474                         VN_RELE(vp);
3475                 }
3476                 if (error != ESTALE)
3477                         goto out;
3478         }
3479 
3480         ASSERT(error == 0);
3481         zone->zone_rootvp = vp;              /* we hold a reference to vp */
3482         zone->zone_rootpath = path;
3483         zone->zone_rootpathlen = pathlen;
3484         if (pathlen > 5 && strcmp(path + pathlen - 5, "/lu/") == 0)
3485                 zone->zone_flags |= ZF_IS_SCRATCH;
3486         return (0);
3487 
3488 out:
3489         pn_free(&pn);
3490         pn_free(&upn);
3491         return (error);
3492 }
3493 
3494 #define isalnum(c)      (((c) >= '0' && (c) <= '9') || \
3495                         ((c) >= 'a' && (c) <= 'z') || \
3496                         ((c) >= 'A' && (c) <= 'Z'))
3497 
3498 static int
3499 zone_set_name(zone_t *zone, const char *uname)
3500 {
 
5352          * reference goes away.
5353          */
5354         ASSERT(zonecount > 1);       /* must be > 1; can't destroy global zone */
5355         zonecount--;
5356         /* remove from active list and hash tables */
5357         list_remove(&zone_active, zone);
5358         (void) mod_hash_destroy(zonehashbyname,
5359             (mod_hash_key_t)zone->zone_name);
5360         (void) mod_hash_destroy(zonehashbyid,
5361             (mod_hash_key_t)(uintptr_t)zone->zone_id);
5362         if (zone->zone_flags & ZF_HASHED_LABEL)
5363                 (void) mod_hash_destroy(zonehashbylabel,
5364                     (mod_hash_key_t)zone->zone_slabel);
5365         mutex_exit(&zonehash_lock);
5366 
5367         /*
5368          * Release the root vnode; we're not using it anymore.  Nor should any
5369          * other thread that might access it exist.
5370          */
5371         if (zone->zone_rootvp != NULL) {
5372                 VN_RELE(zone->zone_rootvp);
5373                 zone->zone_rootvp = NULL;
5374         }
5375 
5376         /* add to deathrow list */
5377         mutex_enter(&zone_deathrow_lock);
5378         list_insert_tail(&zone_deathrow, zone);
5379         mutex_exit(&zone_deathrow_lock);
5380 
5381         /*
5382          * Drop last reference (which was added by zsched()), this will
5383          * free the zone unless there are outstanding cred references.
5384          */
5385         zone_rele(zone);
5386         return (0);
5387 }
5388 
5389 /*
5390  * Systemcall entry point for zone_getattr(2).
5391  */
5392 static ssize_t
 
 | 
 
 
2377          */
2378         cpucaps_zone_remove(zone);
2379 
2380         ASSERT(zone->zone_cpucap == NULL);
2381 
2382         /* remove from deathrow list */
2383         if (zone_status_get(zone) == ZONE_IS_DEAD) {
2384                 ASSERT(zone->zone_ref == 0);
2385                 mutex_enter(&zone_deathrow_lock);
2386                 list_remove(&zone_deathrow, zone);
2387                 mutex_exit(&zone_deathrow_lock);
2388         }
2389 
2390         list_destroy(&zone->zone_ref_list);
2391         zone_free_zsd(zone);
2392         zone_free_datasets(zone);
2393         list_destroy(&zone->zone_dl_list);
2394 
2395         cpu_uarray_free(zone->zone_ustate);
2396 
2397         if (zone->zone_rootvp != NULL) {
2398                 vnode_t *vp = zone->zone_rootvp;
2399 
2400                 mutex_enter(&vp->v_lock);
2401                 vp->v_flag &= ~VZONEROOT;
2402                 mutex_exit(&vp->v_lock);
2403                 VN_RELE(vp);
2404                 /* No need to worry about NULL-ing out zone_rootvp. */
2405         }
2406         if (zone->zone_rootpath)
2407                 kmem_free(zone->zone_rootpath, zone->zone_rootpathlen);
2408         if (zone->zone_name != NULL)
2409                 kmem_free(zone->zone_name, ZONENAME_MAX);
2410         if (zone->zone_slabel != NULL)
2411                 label_rele(zone->zone_slabel);
2412         if (zone->zone_nodename != NULL)
2413                 kmem_free(zone->zone_nodename, _SYS_NMLN);
2414         if (zone->zone_domain != NULL)
2415                 kmem_free(zone->zone_domain, _SYS_NMLN);
2416         if (zone->zone_privset != NULL)
2417                 kmem_free(zone->zone_privset, sizeof (priv_set_t));
2418         if (zone->zone_rctls != NULL)
2419                 rctl_set_free(zone->zone_rctls);
2420         if (zone->zone_bootargs != NULL)
2421                 strfree(zone->zone_bootargs);
2422         if (zone->zone_initname != NULL)
2423                 strfree(zone->zone_initname);
2424         if (zone->zone_fs_allowed != NULL)
2425                 strfree(zone->zone_fs_allowed);
 
3468                             (error = traverse(&vp)) == 0)) {
3469                                 pathlen = pn.pn_pathlen + 2;
3470                                 path = kmem_alloc(pathlen, KM_SLEEP);
3471                                 (void) strncpy(path, pn.pn_path,
3472                                     pn.pn_pathlen + 1);
3473                                 path[pathlen - 2] = '/';
3474                                 path[pathlen - 1] = '\0';
3475                                 pn_free(&pn);
3476                                 pn_free(&upn);
3477 
3478                                 /* Success! */
3479                                 break;
3480                         }
3481                         VN_RELE(vp);
3482                 }
3483                 if (error != ESTALE)
3484                         goto out;
3485         }
3486 
3487         ASSERT(error == 0);
3488         mutex_enter(&vp->v_lock);
3489         if (vp->v_flag & VZONEROOT) {
3490                 /* Wow, someone's already using this zone root! */
3491                 error = EEXIST; /* XXX KEBE ASKS, better errno? */
3492                 mutex_exit(&vp->v_lock);
3493                 VN_RELE(vp);
3494                 goto out;
3495         }
3496         vp->v_flag |= VZONEROOT;
3497         mutex_exit(&vp->v_lock);
3498         zone->zone_rootvp = vp;              /* we hold a reference to vp */
3499         zone->zone_rootpath = path;
3500         zone->zone_rootpathlen = pathlen;
3501         if (pathlen > 5 && strcmp(path + pathlen - 5, "/lu/") == 0)
3502                 zone->zone_flags |= ZF_IS_SCRATCH;
3503         return (0);
3504 
3505 out:
3506         pn_free(&pn);
3507         pn_free(&upn);
3508         return (error);
3509 }
3510 
3511 #define isalnum(c)      (((c) >= '0' && (c) <= '9') || \
3512                         ((c) >= 'a' && (c) <= 'z') || \
3513                         ((c) >= 'A' && (c) <= 'Z'))
3514 
3515 static int
3516 zone_set_name(zone_t *zone, const char *uname)
3517 {
 
5369          * reference goes away.
5370          */
5371         ASSERT(zonecount > 1);       /* must be > 1; can't destroy global zone */
5372         zonecount--;
5373         /* remove from active list and hash tables */
5374         list_remove(&zone_active, zone);
5375         (void) mod_hash_destroy(zonehashbyname,
5376             (mod_hash_key_t)zone->zone_name);
5377         (void) mod_hash_destroy(zonehashbyid,
5378             (mod_hash_key_t)(uintptr_t)zone->zone_id);
5379         if (zone->zone_flags & ZF_HASHED_LABEL)
5380                 (void) mod_hash_destroy(zonehashbylabel,
5381                     (mod_hash_key_t)zone->zone_slabel);
5382         mutex_exit(&zonehash_lock);
5383 
5384         /*
5385          * Release the root vnode; we're not using it anymore.  Nor should any
5386          * other thread that might access it exist.
5387          */
5388         if (zone->zone_rootvp != NULL) {
5389                 vnode_t *vp = zone->zone_rootvp;
5390 
5391                 mutex_enter(&vp->v_lock);
5392                 vp->v_flag &= ~VZONEROOT;
5393                 mutex_exit(&vp->v_lock);
5394                 VN_RELE(vp);
5395                 zone->zone_rootvp = NULL;
5396         }
5397 
5398         /* add to deathrow list */
5399         mutex_enter(&zone_deathrow_lock);
5400         list_insert_tail(&zone_deathrow, zone);
5401         mutex_exit(&zone_deathrow_lock);
5402 
5403         /*
5404          * Drop last reference (which was added by zsched()), this will
5405          * free the zone unless there are outstanding cred references.
5406          */
5407         zone_rele(zone);
5408         return (0);
5409 }
5410 
5411 /*
5412  * Systemcall entry point for zone_getattr(2).
5413  */
5414 static ssize_t
 
 |