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
|