4384 error = zone_set_label(zone, label, default_doi);
4385 if (error != 0) {
4386 zone_free(zone);
4387 return (set_errno(error));
4388 }
4389 insert_label_hash = B_TRUE;
4390 } else {
4391 /* all zones get an admin_low label if system is not labeled */
4392 zone->zone_slabel = l_admin_low;
4393 label_hold(l_admin_low);
4394 insert_label_hash = B_FALSE;
4395 }
4396
4397 /*
4398 * Stop all lwps since that's what normally happens as part of fork().
4399 * This needs to happen before we grab any locks to avoid deadlock
4400 * (another lwp in the process could be waiting for the held lock).
4401 */
4402 if (curthread != pp->p_agenttp && !holdlwps(SHOLDFORK)) {
4403 zone_free(zone);
4404 if (rctls)
4405 nvlist_free(rctls);
4406 return (zone_create_error(error, 0, extended_error));
4407 }
4408
4409 if (block_mounts(zone) == 0) {
4410 mutex_enter(&pp->p_lock);
4411 if (curthread != pp->p_agenttp)
4412 continuelwps(pp);
4413 mutex_exit(&pp->p_lock);
4414 zone_free(zone);
4415 if (rctls)
4416 nvlist_free(rctls);
4417 return (zone_create_error(error, 0, extended_error));
4418 }
4419
4420 /*
4421 * Set up credential for kernel access. After this, any errors
4422 * should go through the dance in errout rather than calling
4423 * zone_free directly.
4424 */
4425 zone->zone_kcred = crdup(kcred);
4426 crsetzone(zone->zone_kcred, zone);
4427 priv_intersect(zone->zone_privset, &CR_PPRIV(zone->zone_kcred));
4428 priv_intersect(zone->zone_privset, &CR_EPRIV(zone->zone_kcred));
4429 priv_intersect(zone->zone_privset, &CR_IPRIV(zone->zone_kcred));
4430 priv_intersect(zone->zone_privset, &CR_LPRIV(zone->zone_kcred));
4431
4432 mutex_enter(&zonehash_lock);
4433 /*
4434 * Make sure zone doesn't already exist.
4435 *
4541 * Create zone kstats
4542 */
4543 zone_kstat_create(zone);
4544
4545 /*
4546 * Let the other lwps continue.
4547 */
4548 mutex_enter(&pp->p_lock);
4549 if (curthread != pp->p_agenttp)
4550 continuelwps(pp);
4551 mutex_exit(&pp->p_lock);
4552
4553 /*
4554 * Wait for zsched to finish initializing the zone.
4555 */
4556 zone_status_wait(zone, ZONE_IS_READY);
4557 /*
4558 * The zone is fully visible, so we can let mounts progress.
4559 */
4560 resume_mounts(zone);
4561 if (rctls)
4562 nvlist_free(rctls);
4563
4564 return (zoneid);
4565
4566 errout:
4567 mutex_exit(&zonehash_lock);
4568 /*
4569 * Let the other lwps continue.
4570 */
4571 mutex_enter(&pp->p_lock);
4572 if (curthread != pp->p_agenttp)
4573 continuelwps(pp);
4574 mutex_exit(&pp->p_lock);
4575
4576 resume_mounts(zone);
4577 if (rctls)
4578 nvlist_free(rctls);
4579 /*
4580 * There is currently one reference to the zone, a cred_ref from
4581 * zone_kcred. To free the zone, we call crfree, which will call
4582 * zone_cred_rele, which will call zone_free.
4583 */
4584 ASSERT(zone->zone_cred_ref == 1);
4585 ASSERT(zone->zone_kcred->cr_ref == 1);
4586 ASSERT(zone->zone_ref == 0);
4587 zkcr = zone->zone_kcred;
4588 zone->zone_kcred = NULL;
4589 crfree(zkcr); /* triggers call to zone_free */
4590 return (zone_create_error(error, error2, extended_error));
4591 }
4592
4593 /*
4594 * Cause the zone to boot. This is pretty simple, since we let zoneadmd do
4595 * the heavy lifting. initname is the path to the program to launch
4596 * at the "top" of the zone; if this is NULL, we use the system default,
4597 * which is stored at zone_default_initname.
6858 mutex_exit(&zonehash_lock);
6859 zone_rele(thiszone);
6860 return (0);
6861 }
6862
6863 static int
6864 zone_remove_datalink(zoneid_t zoneid, datalink_id_t linkid)
6865 {
6866 zone_dl_t *zdl;
6867 zone_t *zone;
6868 int err = 0;
6869
6870 if ((zone = zone_find_by_id(zoneid)) == NULL)
6871 return (set_errno(EINVAL));
6872
6873 mutex_enter(&zone->zone_lock);
6874 if ((zdl = zone_find_dl(zone, linkid)) == NULL) {
6875 err = ENXIO;
6876 } else {
6877 list_remove(&zone->zone_dl_list, zdl);
6878 if (zdl->zdl_net != NULL)
6879 nvlist_free(zdl->zdl_net);
6880 kmem_free(zdl, sizeof (zone_dl_t));
6881 }
6882 mutex_exit(&zone->zone_lock);
6883 zone_rele(zone);
6884 return (err == 0 ? 0 : set_errno(err));
6885 }
6886
6887 /*
6888 * Using the zoneidp as ALL_ZONES, we can lookup which zone has been assigned
6889 * the linkid. Otherwise we just check if the specified zoneidp has been
6890 * assigned the supplied linkid.
6891 */
6892 int
6893 zone_check_datalink(zoneid_t *zoneidp, datalink_id_t linkid)
6894 {
6895 zone_t *zone;
6896 int err = ENXIO;
6897
6898 if (*zoneidp != ALL_ZONES) {
|
4384 error = zone_set_label(zone, label, default_doi);
4385 if (error != 0) {
4386 zone_free(zone);
4387 return (set_errno(error));
4388 }
4389 insert_label_hash = B_TRUE;
4390 } else {
4391 /* all zones get an admin_low label if system is not labeled */
4392 zone->zone_slabel = l_admin_low;
4393 label_hold(l_admin_low);
4394 insert_label_hash = B_FALSE;
4395 }
4396
4397 /*
4398 * Stop all lwps since that's what normally happens as part of fork().
4399 * This needs to happen before we grab any locks to avoid deadlock
4400 * (another lwp in the process could be waiting for the held lock).
4401 */
4402 if (curthread != pp->p_agenttp && !holdlwps(SHOLDFORK)) {
4403 zone_free(zone);
4404 nvlist_free(rctls);
4405 return (zone_create_error(error, 0, extended_error));
4406 }
4407
4408 if (block_mounts(zone) == 0) {
4409 mutex_enter(&pp->p_lock);
4410 if (curthread != pp->p_agenttp)
4411 continuelwps(pp);
4412 mutex_exit(&pp->p_lock);
4413 zone_free(zone);
4414 nvlist_free(rctls);
4415 return (zone_create_error(error, 0, extended_error));
4416 }
4417
4418 /*
4419 * Set up credential for kernel access. After this, any errors
4420 * should go through the dance in errout rather than calling
4421 * zone_free directly.
4422 */
4423 zone->zone_kcred = crdup(kcred);
4424 crsetzone(zone->zone_kcred, zone);
4425 priv_intersect(zone->zone_privset, &CR_PPRIV(zone->zone_kcred));
4426 priv_intersect(zone->zone_privset, &CR_EPRIV(zone->zone_kcred));
4427 priv_intersect(zone->zone_privset, &CR_IPRIV(zone->zone_kcred));
4428 priv_intersect(zone->zone_privset, &CR_LPRIV(zone->zone_kcred));
4429
4430 mutex_enter(&zonehash_lock);
4431 /*
4432 * Make sure zone doesn't already exist.
4433 *
4539 * Create zone kstats
4540 */
4541 zone_kstat_create(zone);
4542
4543 /*
4544 * Let the other lwps continue.
4545 */
4546 mutex_enter(&pp->p_lock);
4547 if (curthread != pp->p_agenttp)
4548 continuelwps(pp);
4549 mutex_exit(&pp->p_lock);
4550
4551 /*
4552 * Wait for zsched to finish initializing the zone.
4553 */
4554 zone_status_wait(zone, ZONE_IS_READY);
4555 /*
4556 * The zone is fully visible, so we can let mounts progress.
4557 */
4558 resume_mounts(zone);
4559 nvlist_free(rctls);
4560
4561 return (zoneid);
4562
4563 errout:
4564 mutex_exit(&zonehash_lock);
4565 /*
4566 * Let the other lwps continue.
4567 */
4568 mutex_enter(&pp->p_lock);
4569 if (curthread != pp->p_agenttp)
4570 continuelwps(pp);
4571 mutex_exit(&pp->p_lock);
4572
4573 resume_mounts(zone);
4574 nvlist_free(rctls);
4575 /*
4576 * There is currently one reference to the zone, a cred_ref from
4577 * zone_kcred. To free the zone, we call crfree, which will call
4578 * zone_cred_rele, which will call zone_free.
4579 */
4580 ASSERT(zone->zone_cred_ref == 1);
4581 ASSERT(zone->zone_kcred->cr_ref == 1);
4582 ASSERT(zone->zone_ref == 0);
4583 zkcr = zone->zone_kcred;
4584 zone->zone_kcred = NULL;
4585 crfree(zkcr); /* triggers call to zone_free */
4586 return (zone_create_error(error, error2, extended_error));
4587 }
4588
4589 /*
4590 * Cause the zone to boot. This is pretty simple, since we let zoneadmd do
4591 * the heavy lifting. initname is the path to the program to launch
4592 * at the "top" of the zone; if this is NULL, we use the system default,
4593 * which is stored at zone_default_initname.
6854 mutex_exit(&zonehash_lock);
6855 zone_rele(thiszone);
6856 return (0);
6857 }
6858
6859 static int
6860 zone_remove_datalink(zoneid_t zoneid, datalink_id_t linkid)
6861 {
6862 zone_dl_t *zdl;
6863 zone_t *zone;
6864 int err = 0;
6865
6866 if ((zone = zone_find_by_id(zoneid)) == NULL)
6867 return (set_errno(EINVAL));
6868
6869 mutex_enter(&zone->zone_lock);
6870 if ((zdl = zone_find_dl(zone, linkid)) == NULL) {
6871 err = ENXIO;
6872 } else {
6873 list_remove(&zone->zone_dl_list, zdl);
6874 nvlist_free(zdl->zdl_net);
6875 kmem_free(zdl, sizeof (zone_dl_t));
6876 }
6877 mutex_exit(&zone->zone_lock);
6878 zone_rele(zone);
6879 return (err == 0 ? 0 : set_errno(err));
6880 }
6881
6882 /*
6883 * Using the zoneidp as ALL_ZONES, we can lookup which zone has been assigned
6884 * the linkid. Otherwise we just check if the specified zoneidp has been
6885 * assigned the supplied linkid.
6886 */
6887 int
6888 zone_check_datalink(zoneid_t *zoneidp, datalink_id_t linkid)
6889 {
6890 zone_t *zone;
6891 int err = ENXIO;
6892
6893 if (*zoneidp != ALL_ZONES) {
|