Print this page
patch tsoome-feedback
6659 nvlist_free(NULL) is a no-op


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) {