559 * When new zones are created constructor callbacks for all registered ZSD
560 * entries will be called. That also uses the above two phases of marking
561 * what needs to be done, and then running the callbacks without holding
562 * any locks.
563 *
564 * The framework does not provide any locking around zone_getspecific() and
565 * zone_setspecific() apart from that needed for internal consistency, so
566 * callers interested in atomic "test-and-set" semantics will need to provide
567 * their own locking.
568 */
569
570 /*
571 * Helper function to find the zsd_entry associated with the key in the
572 * given list.
573 */
574 static struct zsd_entry *
575 zsd_find(list_t *l, zone_key_t key)
576 {
577 struct zsd_entry *zsd;
578
579 for (zsd = list_head(l); zsd != NULL; zsd = list_next(l, zsd)) {
580 if (zsd->zsd_key == key) {
581 return (zsd);
582 }
583 }
584 return (NULL);
585 }
586
587 /*
588 * Helper function to find the zsd_entry associated with the key in the
589 * given list. Move it to the front of the list.
590 */
591 static struct zsd_entry *
592 zsd_find_mru(list_t *l, zone_key_t key)
593 {
594 struct zsd_entry *zsd;
595
596 for (zsd = list_head(l); zsd != NULL; zsd = list_next(l, zsd)) {
597 if (zsd->zsd_key == key) {
598 /*
599 * Move to head of list to keep list in MRU order.
600 */
601 if (zsd != list_head(l)) {
602 list_remove(l, zsd);
603 list_insert_head(l, zsd);
604 }
605 return (zsd);
606 }
607 }
608 return (NULL);
609 }
610
611 void
612 zone_key_create(zone_key_t *keyp, void *(*create)(zoneid_t),
613 void (*shutdown)(zoneid_t, void *), void (*destroy)(zoneid_t, void *))
614 {
615 struct zsd_entry *zsdp;
616 struct zsd_entry *t;
621 zsdp->zsd_data = NULL;
622 zsdp->zsd_create = create;
623 zsdp->zsd_shutdown = shutdown;
624 zsdp->zsd_destroy = destroy;
625
626 /*
627 * Insert in global list of callbacks. Makes future zone creations
628 * see it.
629 */
630 mutex_enter(&zsd_key_lock);
631 key = zsdp->zsd_key = ++zsd_keyval;
632 ASSERT(zsd_keyval != 0);
633 list_insert_tail(&zsd_registered_keys, zsdp);
634 mutex_exit(&zsd_key_lock);
635
636 /*
637 * Insert for all existing zones and mark them as needing
638 * a create callback.
639 */
640 mutex_enter(&zonehash_lock); /* stop the world */
641 for (zone = list_head(&zone_active); zone != NULL;
642 zone = list_next(&zone_active, zone)) {
643 zone_status_t status;
644
645 mutex_enter(&zone->zone_lock);
646
647 /* Skip zones that are on the way down or not yet up */
648 status = zone_status_get(zone);
649 if (status >= ZONE_IS_DOWN ||
650 status == ZONE_IS_UNINITIALIZED) {
651 mutex_exit(&zone->zone_lock);
652 continue;
653 }
654
655 t = zsd_find_mru(&zone->zone_zsd, key);
656 if (t != NULL) {
657 /*
658 * A zsd_configure already inserted it after
659 * we dropped zsd_key_lock above.
660 */
661 mutex_exit(&zone->zone_lock);
662 continue;
698 * be called under a global lock. Then call the functions without
699 * holding any locks. Finally free up the zone_zsd entries. (The apply
700 * functions need to access the zone_zsd entries to find zsd_data etc.)
701 */
702 int
703 zone_key_delete(zone_key_t key)
704 {
705 struct zsd_entry *zsdp = NULL;
706 zone_t *zone;
707
708 mutex_enter(&zsd_key_lock);
709 zsdp = zsd_find_mru(&zsd_registered_keys, key);
710 if (zsdp == NULL) {
711 mutex_exit(&zsd_key_lock);
712 return (-1);
713 }
714 list_remove(&zsd_registered_keys, zsdp);
715 mutex_exit(&zsd_key_lock);
716
717 mutex_enter(&zonehash_lock);
718 for (zone = list_head(&zone_active); zone != NULL;
719 zone = list_next(&zone_active, zone)) {
720 struct zsd_entry *del;
721
722 mutex_enter(&zone->zone_lock);
723 del = zsd_find_mru(&zone->zone_zsd, key);
724 if (del == NULL) {
725 /*
726 * Somebody else got here first e.g the zone going
727 * away.
728 */
729 mutex_exit(&zone->zone_lock);
730 continue;
731 }
732 ASSERT(del->zsd_shutdown == zsdp->zsd_shutdown);
733 ASSERT(del->zsd_destroy == zsdp->zsd_destroy);
734 if (del->zsd_shutdown != NULL &&
735 (del->zsd_flags & ZSD_SHUTDOWN_ALL) == 0) {
736 del->zsd_flags |= ZSD_SHUTDOWN_NEEDED;
737 DTRACE_PROBE2(zsd__shutdown__needed,
738 zone_t *, zone, zone_key_t, key);
739 }
740 if (del->zsd_destroy != NULL &&
741 (del->zsd_flags & ZSD_DESTROY_ALL) == 0) {
742 del->zsd_flags |= ZSD_DESTROY_NEEDED;
743 DTRACE_PROBE2(zsd__destroy__needed,
744 zone_t *, zone, zone_key_t, key);
745 }
746 mutex_exit(&zone->zone_lock);
747 }
748 mutex_exit(&zonehash_lock);
749 kmem_free(zsdp, sizeof (*zsdp));
750
751 /* Now call the shutdown and destroy callback for this key */
752 zsd_apply_all_zones(zsd_apply_shutdown, key);
753 zsd_apply_all_zones(zsd_apply_destroy, key);
754
755 /* Now we can free up the zsdp structures in each zone */
756 mutex_enter(&zonehash_lock);
757 for (zone = list_head(&zone_active); zone != NULL;
758 zone = list_next(&zone_active, zone)) {
759 struct zsd_entry *del;
760
761 mutex_enter(&zone->zone_lock);
762 del = zsd_find(&zone->zone_zsd, key);
763 if (del != NULL) {
764 list_remove(&zone->zone_zsd, del);
765 ASSERT(!(del->zsd_flags & ZSD_ALL_INPROGRESS));
766 kmem_free(del, sizeof (*del));
767 }
768 mutex_exit(&zone->zone_lock);
769 }
770 mutex_exit(&zonehash_lock);
771
772 return (0);
773 }
774
775 /*
776 * ZSD counterpart of pthread_setspecific().
777 *
778 * Since all zsd callbacks, including those with no create function,
814 mutex_exit(&zone->zone_lock);
815 return (data);
816 }
817
818 /*
819 * Function used to initialize a zone's list of ZSD callbacks and data
820 * when the zone is being created. The callbacks are initialized from
821 * the template list (zsd_registered_keys). The constructor callback is
822 * executed later (once the zone exists and with locks dropped).
823 */
824 static void
825 zone_zsd_configure(zone_t *zone)
826 {
827 struct zsd_entry *zsdp;
828 struct zsd_entry *t;
829
830 ASSERT(MUTEX_HELD(&zonehash_lock));
831 ASSERT(list_head(&zone->zone_zsd) == NULL);
832 mutex_enter(&zone->zone_lock);
833 mutex_enter(&zsd_key_lock);
834 for (zsdp = list_head(&zsd_registered_keys); zsdp != NULL;
835 zsdp = list_next(&zsd_registered_keys, zsdp)) {
836 /*
837 * Since this zone is ZONE_IS_UNCONFIGURED, zone_key_create
838 * should not have added anything to it.
839 */
840 ASSERT(zsd_find(&zone->zone_zsd, zsdp->zsd_key) == NULL);
841
842 t = kmem_zalloc(sizeof (*t), KM_SLEEP);
843 t->zsd_key = zsdp->zsd_key;
844 t->zsd_create = zsdp->zsd_create;
845 t->zsd_shutdown = zsdp->zsd_shutdown;
846 t->zsd_destroy = zsdp->zsd_destroy;
847 if (zsdp->zsd_create != NULL) {
848 t->zsd_flags = ZSD_CREATE_NEEDED;
849 DTRACE_PROBE2(zsd__create__needed,
850 zone_t *, zone, zone_key_t, zsdp->zsd_key);
851 }
852 list_insert_tail(&zone->zone_zsd, t);
853 }
854 mutex_exit(&zsd_key_lock);
855 mutex_exit(&zone->zone_lock);
859
860 /*
861 * Helper function to execute shutdown or destructor callbacks.
862 */
863 static void
864 zone_zsd_callbacks(zone_t *zone, enum zsd_callback_type ct)
865 {
866 struct zsd_entry *t;
867
868 ASSERT(ct == ZSD_SHUTDOWN || ct == ZSD_DESTROY);
869 ASSERT(ct != ZSD_SHUTDOWN || zone_status_get(zone) >= ZONE_IS_EMPTY);
870 ASSERT(ct != ZSD_DESTROY || zone_status_get(zone) >= ZONE_IS_DOWN);
871
872 /*
873 * Run the callback solely based on what is registered for the zone
874 * in zone_zsd. The global list can change independently of this
875 * as keys are registered and unregistered and we don't register new
876 * callbacks for a zone that is in the process of going away.
877 */
878 mutex_enter(&zone->zone_lock);
879 for (t = list_head(&zone->zone_zsd); t != NULL;
880 t = list_next(&zone->zone_zsd, t)) {
881 zone_key_t key = t->zsd_key;
882
883 /* Skip if no callbacks registered */
884
885 if (ct == ZSD_SHUTDOWN) {
886 if (t->zsd_shutdown != NULL &&
887 (t->zsd_flags & ZSD_SHUTDOWN_ALL) == 0) {
888 t->zsd_flags |= ZSD_SHUTDOWN_NEEDED;
889 DTRACE_PROBE2(zsd__shutdown__needed,
890 zone_t *, zone, zone_key_t, key);
891 }
892 } else {
893 if (t->zsd_destroy != NULL &&
894 (t->zsd_flags & ZSD_DESTROY_ALL) == 0) {
895 t->zsd_flags |= ZSD_DESTROY_NEEDED;
896 DTRACE_PROBE2(zsd__destroy__needed,
897 zone_t *, zone, zone_key_t, key);
898 }
899 }
900 }
902
903 /* Now call the shutdown and destroy callback for this key */
904 zsd_apply_all_keys(zsd_apply_shutdown, zone);
905 zsd_apply_all_keys(zsd_apply_destroy, zone);
906
907 }
908
909 /*
910 * Called when the zone is going away; free ZSD-related memory, and
911 * destroy the zone_zsd list.
912 */
913 static void
914 zone_free_zsd(zone_t *zone)
915 {
916 struct zsd_entry *t, *next;
917
918 /*
919 * Free all the zsd_entry's we had on this zone.
920 */
921 mutex_enter(&zone->zone_lock);
922 for (t = list_head(&zone->zone_zsd); t != NULL; t = next) {
923 next = list_next(&zone->zone_zsd, t);
924 list_remove(&zone->zone_zsd, t);
925 ASSERT(!(t->zsd_flags & ZSD_ALL_INPROGRESS));
926 kmem_free(t, sizeof (*t));
927 }
928 list_destroy(&zone->zone_zsd);
929 mutex_exit(&zone->zone_lock);
930
931 }
932
933 /*
934 * Apply a function to all zones for particular key value.
935 *
936 * The applyfn has to drop zonehash_lock if it does some work, and
937 * then reacquire it before it returns.
938 * When the lock is dropped we don't follow list_next even
939 * if it is possible to do so without any hazards. This is
940 * because we want the design to allow for the list of zones
941 * to change in any arbitrary way during the time the
942 * lock was dropped.
943 *
1284 }
1285 cv_wait(&t->zsd_cv, &zone->zone_lock);
1286 if (lockp != NULL) {
1287 /* First drop zone_lock to preserve order */
1288 mutex_exit(&zone->zone_lock);
1289 mutex_enter(lockp);
1290 mutex_enter(&zone->zone_lock);
1291 }
1292 }
1293 return (dropped);
1294 }
1295
1296 /*
1297 * Frees memory associated with the zone dataset list.
1298 */
1299 static void
1300 zone_free_datasets(zone_t *zone)
1301 {
1302 zone_dataset_t *t, *next;
1303
1304 for (t = list_head(&zone->zone_datasets); t != NULL; t = next) {
1305 next = list_next(&zone->zone_datasets, t);
1306 list_remove(&zone->zone_datasets, t);
1307 kmem_free(t->zd_dataset, strlen(t->zd_dataset) + 1);
1308 kmem_free(t, sizeof (*t));
1309 }
1310 list_destroy(&zone->zone_datasets);
1311 }
1312
1313 /*
1314 * zone.cpu-shares resource control support.
1315 */
1316 /*ARGSUSED*/
1317 static rctl_qty_t
1318 zone_cpu_shares_usage(rctl_t *rctl, struct proc *p)
1319 {
1320 ASSERT(MUTEX_HELD(&p->p_lock));
1321 return (p->p_zone->zone_shares);
1322 }
1323
1324 /*ARGSUSED*/
1325 static int
3022 *
3023 * As with the other zone_find_by_*() functions, the caller is
3024 * responsible for zone_rele()ing the return value of this function.
3025 */
3026 zone_t *
3027 zone_find_by_path(const char *path)
3028 {
3029 zone_t *zone;
3030 zone_t *zret = NULL;
3031 zone_status_t status;
3032
3033 if (path == NULL) {
3034 /*
3035 * Call from rootconf().
3036 */
3037 zone_hold(global_zone);
3038 return (global_zone);
3039 }
3040 ASSERT(*path == '/');
3041 mutex_enter(&zonehash_lock);
3042 for (zone = list_head(&zone_active); zone != NULL;
3043 zone = list_next(&zone_active, zone)) {
3044 if (ZONE_PATH_VISIBLE(path, zone))
3045 zret = zone;
3046 }
3047 ASSERT(zret != NULL);
3048 status = zone_status_get(zret);
3049 if (status < ZONE_IS_READY || status > ZONE_IS_DOWN) {
3050 /*
3051 * Zone practically doesn't exist.
3052 */
3053 zret = global_zone;
3054 }
3055 zone_hold(zret);
3056 mutex_exit(&zonehash_lock);
3057 return (zret);
3058 }
3059
3060 /*
3061 * Public interface for updating per-zone load averages. Called once per
3062 * second.
3063 *
3241 zone->zone_ncpus_online = 0;
3242 }
3243 }
3244
3245 /*
3246 * Walk the list of active zones and issue the provided callback for
3247 * each of them.
3248 *
3249 * Caller must not be holding any locks that may be acquired under
3250 * zonehash_lock. See comment at the beginning of the file for a list of
3251 * common locks and their interactions with zones.
3252 */
3253 int
3254 zone_walk(int (*cb)(zone_t *, void *), void *data)
3255 {
3256 zone_t *zone;
3257 int ret = 0;
3258 zone_status_t status;
3259
3260 mutex_enter(&zonehash_lock);
3261 for (zone = list_head(&zone_active); zone != NULL;
3262 zone = list_next(&zone_active, zone)) {
3263 /*
3264 * Skip zones that shouldn't be externally visible.
3265 */
3266 status = zone_status_get(zone);
3267 if (status < ZONE_IS_READY || status > ZONE_IS_DOWN)
3268 continue;
3269 /*
3270 * Bail immediately if any callback invocation returns a
3271 * non-zero value.
3272 */
3273 ret = (*cb)(zone, data);
3274 if (ret != 0)
3275 break;
3276 }
3277 mutex_exit(&zonehash_lock);
3278 return (ret);
3279 }
3280
3281 static int
3282 zone_set_root(zone_t *zone, const char *upath)
4033 /*
4034 * Helper function to make sure that a zone created on 'rootpath'
4035 * wouldn't end up containing other zones' rootpaths.
4036 */
4037 static boolean_t
4038 zone_is_nested(const char *rootpath)
4039 {
4040 zone_t *zone;
4041 size_t rootpathlen = strlen(rootpath);
4042 size_t len;
4043
4044 ASSERT(MUTEX_HELD(&zonehash_lock));
4045
4046 /*
4047 * zone_set_root() appended '/' and '\0' at the end of rootpath
4048 */
4049 if ((rootpathlen <= 3) && (rootpath[0] == '/') &&
4050 (rootpath[1] == '/') && (rootpath[2] == '\0'))
4051 return (B_TRUE);
4052
4053 for (zone = list_head(&zone_active); zone != NULL;
4054 zone = list_next(&zone_active, zone)) {
4055 if (zone == global_zone)
4056 continue;
4057 len = strlen(zone->zone_rootpath);
4058 if (strncmp(rootpath, zone->zone_rootpath,
4059 MIN(rootpathlen, len)) == 0)
4060 return (B_TRUE);
4061 }
4062 return (B_FALSE);
4063 }
4064
4065 static int
4066 zone_set_privset(zone_t *zone, const priv_set_t *zone_privs,
4067 size_t zone_privssz)
4068 {
4069 priv_set_t *privs;
4070
4071 if (zone_privssz < sizeof (priv_set_t))
4072 return (ENOMEM);
4073
4074 privs = kmem_alloc(sizeof (priv_set_t), KM_SLEEP);
5715 mutex_enter(&ct->ct_lock);
5716 mutex_enter(&pp->p_lock);
5717 if ((avl_numnodes(&pp->p_ct_held) != 0) || (ctp->conp_nmembers != 1)) {
5718 mutex_exit(&pp->p_lock);
5719 mutex_exit(&ct->ct_lock);
5720 mutex_exit(&zonehash_lock);
5721 err = EINVAL;
5722 goto out;
5723 }
5724
5725 /*
5726 * Moreover, we don't allow processes whose encapsulating
5727 * process contracts have inherited extrazonal contracts.
5728 * While it would be easier to eliminate all process contracts
5729 * with inherited contracts, we need to be able to give a
5730 * restarted init (or other zone-penetrating process) its
5731 * predecessor's contracts.
5732 */
5733 if (ctp->conp_ninherited != 0) {
5734 contract_t *next;
5735 for (next = list_head(&ctp->conp_inherited); next;
5736 next = list_next(&ctp->conp_inherited, next)) {
5737 if (contract_getzuniqid(next) != zone->zone_uniqid) {
5738 mutex_exit(&pp->p_lock);
5739 mutex_exit(&ct->ct_lock);
5740 mutex_exit(&zonehash_lock);
5741 err = EINVAL;
5742 goto out;
5743 }
5744 }
5745 }
5746
5747 mutex_exit(&pp->p_lock);
5748 mutex_exit(&ct->ct_lock);
5749
5750 status = zone_status_get(zone);
5751 if (status < ZONE_IS_READY || status >= ZONE_IS_SHUTTING_DOWN) {
5752 /*
5753 * Can't join
5754 */
5755 mutex_exit(&zonehash_lock);
5756 err = EINVAL;
6074 return (set_errno(EFAULT));
6075
6076 myzone = curproc->p_zone;
6077 if (myzone != global_zone) {
6078 bslabel_t *mybslab;
6079
6080 if (!is_system_labeled()) {
6081 /* just return current zone */
6082 real_nzones = domi_nzones = 1;
6083 zoneids = kmem_alloc(sizeof (zoneid_t), KM_SLEEP);
6084 zoneids[0] = myzone->zone_id;
6085 } else {
6086 /* return all zones that are dominated */
6087 mutex_enter(&zonehash_lock);
6088 real_nzones = zonecount;
6089 domi_nzones = 0;
6090 if (real_nzones > 0) {
6091 zoneids = kmem_alloc(real_nzones *
6092 sizeof (zoneid_t), KM_SLEEP);
6093 mybslab = label2bslabel(myzone->zone_slabel);
6094 for (zone = list_head(&zone_active);
6095 zone != NULL;
6096 zone = list_next(&zone_active, zone)) {
6097 if (zone->zone_id == GLOBAL_ZONEID)
6098 continue;
6099 if (zone != myzone &&
6100 (zone->zone_flags & ZF_IS_SCRATCH))
6101 continue;
6102 /*
6103 * Note that a label always dominates
6104 * itself, so myzone is always included
6105 * in the list.
6106 */
6107 if (bldominates(mybslab,
6108 label2bslabel(zone->zone_slabel))) {
6109 zoneids[domi_nzones++] =
6110 zone->zone_id;
6111 }
6112 }
6113 }
6114 mutex_exit(&zonehash_lock);
6115 }
6116 } else {
6117 mutex_enter(&zonehash_lock);
6118 real_nzones = zonecount;
6119 domi_nzones = 0;
6120 if (real_nzones > 0) {
6121 zoneids = kmem_alloc(real_nzones * sizeof (zoneid_t),
6122 KM_SLEEP);
6123 for (zone = list_head(&zone_active); zone != NULL;
6124 zone = list_next(&zone_active, zone))
6125 zoneids[domi_nzones++] = zone->zone_id;
6126 ASSERT(domi_nzones == real_nzones);
6127 }
6128 mutex_exit(&zonehash_lock);
6129 }
6130
6131 /*
6132 * If user has allocated space for fewer entries than we found, then
6133 * return only up to his limit. Either way, tell him exactly how many
6134 * we found.
6135 */
6136 if (domi_nzones < user_nzones)
6137 user_nzones = domi_nzones;
6138 error = 0;
6139 if (copyout(&domi_nzones, numzones, sizeof (uint_t)) != 0) {
6140 error = EFAULT;
6141 } else if (zoneidlist != NULL && user_nzones != 0) {
6142 if (copyout(zoneids, zoneidlist,
6143 user_nzones * sizeof (zoneid_t)) != 0)
6144 error = EFAULT;
6569 {
6570 zone_t *current_zonep;
6571
6572 ASSERT(INGLOBALZONE(curproc));
6573 mutex_enter(&zonehash_lock);
6574 mutex_enter(&zone_status_lock);
6575
6576 /* Modify the global zone's status first. */
6577 ASSERT(zone_status_get(global_zone) == ZONE_IS_RUNNING);
6578 zone_status_set(global_zone, ZONE_IS_SHUTTING_DOWN);
6579
6580 /*
6581 * Now change the states of all running zones to ZONE_IS_SHUTTING_DOWN.
6582 * We don't mark all zones with ZONE_IS_SHUTTING_DOWN because doing so
6583 * could cause assertions to fail (e.g., assertions about a zone's
6584 * state during initialization, readying, or booting) or produce races.
6585 * We'll let threads continue to initialize and ready new zones: they'll
6586 * fail to boot the new zones when they see that the global zone is
6587 * shutting down.
6588 */
6589 for (current_zonep = list_head(&zone_active); current_zonep != NULL;
6590 current_zonep = list_next(&zone_active, current_zonep)) {
6591 if (zone_status_get(current_zonep) == ZONE_IS_RUNNING)
6592 zone_status_set(current_zonep, ZONE_IS_SHUTTING_DOWN);
6593 }
6594 mutex_exit(&zone_status_lock);
6595 mutex_exit(&zonehash_lock);
6596 }
6597
6598 /*
6599 * Returns true if the named dataset is visible in the current zone.
6600 * The 'write' parameter is set to 1 if the dataset is also writable.
6601 */
6602 int
6603 zone_dataset_visible(const char *dataset, int *write)
6604 {
6605 static int zfstype = -1;
6606 zone_dataset_t *zd;
6607 size_t len;
6608 zone_t *zone = curproc->p_zone;
6609 const char *name = NULL;
6610 vfs_t *vfsp = NULL;
6611
6612 if (dataset[0] == '\0')
6613 return (0);
6614
6615 /*
6616 * Walk the list once, looking for datasets which match exactly, or
6617 * specify a dataset underneath an exported dataset. If found, return
6618 * true and note that it is writable.
6619 */
6620 for (zd = list_head(&zone->zone_datasets); zd != NULL;
6621 zd = list_next(&zone->zone_datasets, zd)) {
6622
6623 len = strlen(zd->zd_dataset);
6624 if (strlen(dataset) >= len &&
6625 bcmp(dataset, zd->zd_dataset, len) == 0 &&
6626 (dataset[len] == '\0' || dataset[len] == '/' ||
6627 dataset[len] == '@')) {
6628 if (write)
6629 *write = 1;
6630 return (1);
6631 }
6632 }
6633
6634 /*
6635 * Walk the list a second time, searching for datasets which are parents
6636 * of exported datasets. These should be visible, but read-only.
6637 *
6638 * Note that we also have to support forms such as 'pool/dataset/', with
6639 * a trailing slash.
6640 */
6641 for (zd = list_head(&zone->zone_datasets); zd != NULL;
6642 zd = list_next(&zone->zone_datasets, zd)) {
6643
6644 len = strlen(dataset);
6645 if (dataset[len - 1] == '/')
6646 len--; /* Ignore trailing slash */
6647 if (len < strlen(zd->zd_dataset) &&
6648 bcmp(dataset, zd->zd_dataset, len) == 0 &&
6649 zd->zd_dataset[len] == '/') {
6650 if (write)
6651 *write = 0;
6652 return (1);
6653 }
6654 }
6655
6656 /*
6657 * We reach here if the given dataset is not found in the zone_dataset
6658 * list. Check if this dataset was added as a filesystem (ie. "add fs")
6659 * instead of delegation. For this we search for the dataset in the
6660 * zone_vfslist of this zone. If found, return true and note that it is
6661 * not writable.
6662 */
6663
6728 *
6729 * The caller is responsible for zone_rele of the returned zone.
6730 */
6731 zone_t *
6732 zone_find_by_any_path(const char *path, boolean_t treat_abs)
6733 {
6734 zone_t *zone;
6735 int path_offset = 0;
6736
6737 if (path == NULL) {
6738 zone_hold(global_zone);
6739 return (global_zone);
6740 }
6741
6742 if (*path != '/') {
6743 ASSERT(treat_abs);
6744 path_offset = 1;
6745 }
6746
6747 mutex_enter(&zonehash_lock);
6748 for (zone = list_head(&zone_active); zone != NULL;
6749 zone = list_next(&zone_active, zone)) {
6750 char *c;
6751 size_t pathlen;
6752 char *rootpath_start;
6753
6754 if (zone == global_zone) /* skip global zone */
6755 continue;
6756
6757 /* scan backwards to find start of last component */
6758 c = zone->zone_rootpath + zone->zone_rootpathlen - 2;
6759 do {
6760 c--;
6761 } while (*c != '/');
6762
6763 pathlen = c - zone->zone_rootpath + 1 - path_offset;
6764 rootpath_start = (zone->zone_rootpath + path_offset);
6765 if (strncmp(path, rootpath_start, pathlen) == 0)
6766 break;
6767 }
6768 if (zone == NULL)
6769 zone = global_zone;
6770 zone_hold(zone);
6771 mutex_exit(&zonehash_lock);
6772 return (zone);
6773 }
6774
6775 /*
6776 * Finds a zone_dl_t with the given linkid in the given zone. Returns the
6777 * zone_dl_t pointer if found, and NULL otherwise.
6778 */
6779 static zone_dl_t *
6780 zone_find_dl(zone_t *zone, datalink_id_t linkid)
6781 {
6782 zone_dl_t *zdl;
6783
6784 ASSERT(mutex_owned(&zone->zone_lock));
6785 for (zdl = list_head(&zone->zone_dl_list); zdl != NULL;
6786 zdl = list_next(&zone->zone_dl_list, zdl)) {
6787 if (zdl->zdl_id == linkid)
6788 break;
6789 }
6790 return (zdl);
6791 }
6792
6793 static boolean_t
6794 zone_dl_exists(zone_t *zone, datalink_id_t linkid)
6795 {
6796 boolean_t exists;
6797
6798 mutex_enter(&zone->zone_lock);
6799 exists = (zone_find_dl(zone, linkid) != NULL);
6800 mutex_exit(&zone->zone_lock);
6801 return (exists);
6802 }
6803
6804 /*
6805 * Add an data link name for the zone.
6806 */
6807 static int
6808 zone_add_datalink(zoneid_t zoneid, datalink_id_t linkid)
6809 {
6810 zone_dl_t *zdl;
6811 zone_t *zone;
6812 zone_t *thiszone;
6813
6814 if ((thiszone = zone_find_by_id(zoneid)) == NULL)
6815 return (set_errno(ENXIO));
6816
6817 /* Verify that the datalink ID doesn't already belong to a zone. */
6818 mutex_enter(&zonehash_lock);
6819 for (zone = list_head(&zone_active); zone != NULL;
6820 zone = list_next(&zone_active, zone)) {
6821 if (zone_dl_exists(zone, linkid)) {
6822 mutex_exit(&zonehash_lock);
6823 zone_rele(thiszone);
6824 return (set_errno((zone == thiszone) ? EEXIST : EPERM));
6825 }
6826 }
6827
6828 zdl = kmem_zalloc(sizeof (*zdl), KM_SLEEP);
6829 zdl->zdl_id = linkid;
6830 zdl->zdl_net = NULL;
6831 mutex_enter(&thiszone->zone_lock);
6832 list_insert_head(&thiszone->zone_dl_list, zdl);
6833 mutex_exit(&thiszone->zone_lock);
6834 mutex_exit(&zonehash_lock);
6835 zone_rele(thiszone);
6836 return (0);
6837 }
6838
6839 static int
6840 zone_remove_datalink(zoneid_t zoneid, datalink_id_t linkid)
6864 * Using the zoneidp as ALL_ZONES, we can lookup which zone has been assigned
6865 * the linkid. Otherwise we just check if the specified zoneidp has been
6866 * assigned the supplied linkid.
6867 */
6868 int
6869 zone_check_datalink(zoneid_t *zoneidp, datalink_id_t linkid)
6870 {
6871 zone_t *zone;
6872 int err = ENXIO;
6873
6874 if (*zoneidp != ALL_ZONES) {
6875 if ((zone = zone_find_by_id(*zoneidp)) != NULL) {
6876 if (zone_dl_exists(zone, linkid))
6877 err = 0;
6878 zone_rele(zone);
6879 }
6880 return (err);
6881 }
6882
6883 mutex_enter(&zonehash_lock);
6884 for (zone = list_head(&zone_active); zone != NULL;
6885 zone = list_next(&zone_active, zone)) {
6886 if (zone_dl_exists(zone, linkid)) {
6887 *zoneidp = zone->zone_id;
6888 err = 0;
6889 break;
6890 }
6891 }
6892 mutex_exit(&zonehash_lock);
6893 return (err);
6894 }
6895
6896 /*
6897 * Get the list of datalink IDs assigned to a zone.
6898 *
6899 * On input, *nump is the number of datalink IDs that can fit in the supplied
6900 * idarray. Upon return, *nump is either set to the number of datalink IDs
6901 * that were placed in the array if the array was large enough, or to the
6902 * number of datalink IDs that the function needs to place in the array if the
6903 * array is too small.
6904 */
6905 static int
6906 zone_list_datalink(zoneid_t zoneid, int *nump, datalink_id_t *idarray)
6907 {
6908 uint_t num, dlcount;
6909 zone_t *zone;
6910 zone_dl_t *zdl;
6911 datalink_id_t *idptr = idarray;
6912
6913 if (copyin(nump, &dlcount, sizeof (dlcount)) != 0)
6914 return (set_errno(EFAULT));
6915 if ((zone = zone_find_by_id(zoneid)) == NULL)
6916 return (set_errno(ENXIO));
6917
6918 num = 0;
6919 mutex_enter(&zone->zone_lock);
6920 for (zdl = list_head(&zone->zone_dl_list); zdl != NULL;
6921 zdl = list_next(&zone->zone_dl_list, zdl)) {
6922 /*
6923 * If the list is bigger than what the caller supplied, just
6924 * count, don't do copyout.
6925 */
6926 if (++num > dlcount)
6927 continue;
6928 if (copyout(&zdl->zdl_id, idptr, sizeof (*idptr)) != 0) {
6929 mutex_exit(&zone->zone_lock);
6930 zone_rele(zone);
6931 return (set_errno(EFAULT));
6932 }
6933 idptr++;
6934 }
6935 mutex_exit(&zone->zone_lock);
6936 zone_rele(zone);
6937
6938 /* Increased or decreased, caller should be notified. */
6939 if (num != dlcount) {
6940 if (copyout(&num, nump, sizeof (num)) != 0)
6941 return (set_errno(EFAULT));
6975 * Walk the datalinks for a given zone
6976 */
6977 int
6978 zone_datalink_walk(zoneid_t zoneid, int (*cb)(datalink_id_t, void *),
6979 void *data)
6980 {
6981 zone_t *zone;
6982 zone_dl_t *zdl;
6983 datalink_id_t *idarray;
6984 uint_t idcount = 0;
6985 int i, ret = 0;
6986
6987 if ((zone = zone_find_by_id(zoneid)) == NULL)
6988 return (ENOENT);
6989
6990 /*
6991 * We first build an array of linkid's so that we can walk these and
6992 * execute the callback with the zone_lock dropped.
6993 */
6994 mutex_enter(&zone->zone_lock);
6995 for (zdl = list_head(&zone->zone_dl_list); zdl != NULL;
6996 zdl = list_next(&zone->zone_dl_list, zdl)) {
6997 idcount++;
6998 }
6999
7000 if (idcount == 0) {
7001 mutex_exit(&zone->zone_lock);
7002 zone_rele(zone);
7003 return (0);
7004 }
7005
7006 idarray = kmem_alloc(sizeof (datalink_id_t) * idcount, KM_NOSLEEP);
7007 if (idarray == NULL) {
7008 mutex_exit(&zone->zone_lock);
7009 zone_rele(zone);
7010 return (ENOMEM);
7011 }
7012
7013 for (i = 0, zdl = list_head(&zone->zone_dl_list); zdl != NULL;
7014 i++, zdl = list_next(&zone->zone_dl_list, zdl)) {
7015 idarray[i] = zdl->zdl_id;
7016 }
7017
7018 mutex_exit(&zone->zone_lock);
7019
7020 for (i = 0; i < idcount && ret == 0; i++) {
7021 if ((ret = (*cb)(idarray[i], data)) != 0)
7022 break;
7023 }
7024
7025 zone_rele(zone);
7026 kmem_free(idarray, sizeof (datalink_id_t) * idcount);
7027 return (ret);
7028 }
7029
7030 static char *
7031 zone_net_type2name(int type)
7032 {
7033 switch (type) {
7034 case ZONE_NETWORK_ADDRESS:
7035 return (ZONE_NET_ADDRNAME);
|
559 * When new zones are created constructor callbacks for all registered ZSD
560 * entries will be called. That also uses the above two phases of marking
561 * what needs to be done, and then running the callbacks without holding
562 * any locks.
563 *
564 * The framework does not provide any locking around zone_getspecific() and
565 * zone_setspecific() apart from that needed for internal consistency, so
566 * callers interested in atomic "test-and-set" semantics will need to provide
567 * their own locking.
568 */
569
570 /*
571 * Helper function to find the zsd_entry associated with the key in the
572 * given list.
573 */
574 static struct zsd_entry *
575 zsd_find(list_t *l, zone_key_t key)
576 {
577 struct zsd_entry *zsd;
578
579 list_for_each(l, zsd) {
580 if (zsd->zsd_key == key) {
581 return (zsd);
582 }
583 }
584 return (NULL);
585 }
586
587 /*
588 * Helper function to find the zsd_entry associated with the key in the
589 * given list. Move it to the front of the list.
590 */
591 static struct zsd_entry *
592 zsd_find_mru(list_t *l, zone_key_t key)
593 {
594 struct zsd_entry *zsd;
595
596 list_for_each(l, zsd) {
597 if (zsd->zsd_key == key) {
598 /*
599 * Move to head of list to keep list in MRU order.
600 */
601 if (zsd != list_head(l)) {
602 list_remove(l, zsd);
603 list_insert_head(l, zsd);
604 }
605 return (zsd);
606 }
607 }
608 return (NULL);
609 }
610
611 void
612 zone_key_create(zone_key_t *keyp, void *(*create)(zoneid_t),
613 void (*shutdown)(zoneid_t, void *), void (*destroy)(zoneid_t, void *))
614 {
615 struct zsd_entry *zsdp;
616 struct zsd_entry *t;
621 zsdp->zsd_data = NULL;
622 zsdp->zsd_create = create;
623 zsdp->zsd_shutdown = shutdown;
624 zsdp->zsd_destroy = destroy;
625
626 /*
627 * Insert in global list of callbacks. Makes future zone creations
628 * see it.
629 */
630 mutex_enter(&zsd_key_lock);
631 key = zsdp->zsd_key = ++zsd_keyval;
632 ASSERT(zsd_keyval != 0);
633 list_insert_tail(&zsd_registered_keys, zsdp);
634 mutex_exit(&zsd_key_lock);
635
636 /*
637 * Insert for all existing zones and mark them as needing
638 * a create callback.
639 */
640 mutex_enter(&zonehash_lock); /* stop the world */
641 list_for_each(&zone_active, zone) {
642 zone_status_t status;
643
644 mutex_enter(&zone->zone_lock);
645
646 /* Skip zones that are on the way down or not yet up */
647 status = zone_status_get(zone);
648 if (status >= ZONE_IS_DOWN ||
649 status == ZONE_IS_UNINITIALIZED) {
650 mutex_exit(&zone->zone_lock);
651 continue;
652 }
653
654 t = zsd_find_mru(&zone->zone_zsd, key);
655 if (t != NULL) {
656 /*
657 * A zsd_configure already inserted it after
658 * we dropped zsd_key_lock above.
659 */
660 mutex_exit(&zone->zone_lock);
661 continue;
697 * be called under a global lock. Then call the functions without
698 * holding any locks. Finally free up the zone_zsd entries. (The apply
699 * functions need to access the zone_zsd entries to find zsd_data etc.)
700 */
701 int
702 zone_key_delete(zone_key_t key)
703 {
704 struct zsd_entry *zsdp = NULL;
705 zone_t *zone;
706
707 mutex_enter(&zsd_key_lock);
708 zsdp = zsd_find_mru(&zsd_registered_keys, key);
709 if (zsdp == NULL) {
710 mutex_exit(&zsd_key_lock);
711 return (-1);
712 }
713 list_remove(&zsd_registered_keys, zsdp);
714 mutex_exit(&zsd_key_lock);
715
716 mutex_enter(&zonehash_lock);
717 list_for_each(&zone_active, zone) {
718 struct zsd_entry *del;
719
720 mutex_enter(&zone->zone_lock);
721 del = zsd_find_mru(&zone->zone_zsd, key);
722 if (del == NULL) {
723 /*
724 * Somebody else got here first e.g the zone going
725 * away.
726 */
727 mutex_exit(&zone->zone_lock);
728 continue;
729 }
730 ASSERT(del->zsd_shutdown == zsdp->zsd_shutdown);
731 ASSERT(del->zsd_destroy == zsdp->zsd_destroy);
732 if (del->zsd_shutdown != NULL &&
733 (del->zsd_flags & ZSD_SHUTDOWN_ALL) == 0) {
734 del->zsd_flags |= ZSD_SHUTDOWN_NEEDED;
735 DTRACE_PROBE2(zsd__shutdown__needed,
736 zone_t *, zone, zone_key_t, key);
737 }
738 if (del->zsd_destroy != NULL &&
739 (del->zsd_flags & ZSD_DESTROY_ALL) == 0) {
740 del->zsd_flags |= ZSD_DESTROY_NEEDED;
741 DTRACE_PROBE2(zsd__destroy__needed,
742 zone_t *, zone, zone_key_t, key);
743 }
744 mutex_exit(&zone->zone_lock);
745 }
746 mutex_exit(&zonehash_lock);
747 kmem_free(zsdp, sizeof (*zsdp));
748
749 /* Now call the shutdown and destroy callback for this key */
750 zsd_apply_all_zones(zsd_apply_shutdown, key);
751 zsd_apply_all_zones(zsd_apply_destroy, key);
752
753 /* Now we can free up the zsdp structures in each zone */
754 mutex_enter(&zonehash_lock);
755 list_for_each(&zone_active, zone) {
756 struct zsd_entry *del;
757
758 mutex_enter(&zone->zone_lock);
759 del = zsd_find(&zone->zone_zsd, key);
760 if (del != NULL) {
761 list_remove(&zone->zone_zsd, del);
762 ASSERT(!(del->zsd_flags & ZSD_ALL_INPROGRESS));
763 kmem_free(del, sizeof (*del));
764 }
765 mutex_exit(&zone->zone_lock);
766 }
767 mutex_exit(&zonehash_lock);
768
769 return (0);
770 }
771
772 /*
773 * ZSD counterpart of pthread_setspecific().
774 *
775 * Since all zsd callbacks, including those with no create function,
811 mutex_exit(&zone->zone_lock);
812 return (data);
813 }
814
815 /*
816 * Function used to initialize a zone's list of ZSD callbacks and data
817 * when the zone is being created. The callbacks are initialized from
818 * the template list (zsd_registered_keys). The constructor callback is
819 * executed later (once the zone exists and with locks dropped).
820 */
821 static void
822 zone_zsd_configure(zone_t *zone)
823 {
824 struct zsd_entry *zsdp;
825 struct zsd_entry *t;
826
827 ASSERT(MUTEX_HELD(&zonehash_lock));
828 ASSERT(list_head(&zone->zone_zsd) == NULL);
829 mutex_enter(&zone->zone_lock);
830 mutex_enter(&zsd_key_lock);
831 list_for_each(&zsd_registered_keys, zsdp) {
832 /*
833 * Since this zone is ZONE_IS_UNCONFIGURED, zone_key_create
834 * should not have added anything to it.
835 */
836 ASSERT(zsd_find(&zone->zone_zsd, zsdp->zsd_key) == NULL);
837
838 t = kmem_zalloc(sizeof (*t), KM_SLEEP);
839 t->zsd_key = zsdp->zsd_key;
840 t->zsd_create = zsdp->zsd_create;
841 t->zsd_shutdown = zsdp->zsd_shutdown;
842 t->zsd_destroy = zsdp->zsd_destroy;
843 if (zsdp->zsd_create != NULL) {
844 t->zsd_flags = ZSD_CREATE_NEEDED;
845 DTRACE_PROBE2(zsd__create__needed,
846 zone_t *, zone, zone_key_t, zsdp->zsd_key);
847 }
848 list_insert_tail(&zone->zone_zsd, t);
849 }
850 mutex_exit(&zsd_key_lock);
851 mutex_exit(&zone->zone_lock);
855
856 /*
857 * Helper function to execute shutdown or destructor callbacks.
858 */
859 static void
860 zone_zsd_callbacks(zone_t *zone, enum zsd_callback_type ct)
861 {
862 struct zsd_entry *t;
863
864 ASSERT(ct == ZSD_SHUTDOWN || ct == ZSD_DESTROY);
865 ASSERT(ct != ZSD_SHUTDOWN || zone_status_get(zone) >= ZONE_IS_EMPTY);
866 ASSERT(ct != ZSD_DESTROY || zone_status_get(zone) >= ZONE_IS_DOWN);
867
868 /*
869 * Run the callback solely based on what is registered for the zone
870 * in zone_zsd. The global list can change independently of this
871 * as keys are registered and unregistered and we don't register new
872 * callbacks for a zone that is in the process of going away.
873 */
874 mutex_enter(&zone->zone_lock);
875 list_for_each(&zone->zone_zsd, t) {
876 zone_key_t key = t->zsd_key;
877
878 /* Skip if no callbacks registered */
879
880 if (ct == ZSD_SHUTDOWN) {
881 if (t->zsd_shutdown != NULL &&
882 (t->zsd_flags & ZSD_SHUTDOWN_ALL) == 0) {
883 t->zsd_flags |= ZSD_SHUTDOWN_NEEDED;
884 DTRACE_PROBE2(zsd__shutdown__needed,
885 zone_t *, zone, zone_key_t, key);
886 }
887 } else {
888 if (t->zsd_destroy != NULL &&
889 (t->zsd_flags & ZSD_DESTROY_ALL) == 0) {
890 t->zsd_flags |= ZSD_DESTROY_NEEDED;
891 DTRACE_PROBE2(zsd__destroy__needed,
892 zone_t *, zone, zone_key_t, key);
893 }
894 }
895 }
897
898 /* Now call the shutdown and destroy callback for this key */
899 zsd_apply_all_keys(zsd_apply_shutdown, zone);
900 zsd_apply_all_keys(zsd_apply_destroy, zone);
901
902 }
903
904 /*
905 * Called when the zone is going away; free ZSD-related memory, and
906 * destroy the zone_zsd list.
907 */
908 static void
909 zone_free_zsd(zone_t *zone)
910 {
911 struct zsd_entry *t, *next;
912
913 /*
914 * Free all the zsd_entry's we had on this zone.
915 */
916 mutex_enter(&zone->zone_lock);
917 list_for_each_safe(&zone->zone_zsd, t, next) {
918 list_remove(&zone->zone_zsd, t);
919 ASSERT(!(t->zsd_flags & ZSD_ALL_INPROGRESS));
920 kmem_free(t, sizeof (*t));
921 }
922 list_destroy(&zone->zone_zsd);
923 mutex_exit(&zone->zone_lock);
924
925 }
926
927 /*
928 * Apply a function to all zones for particular key value.
929 *
930 * The applyfn has to drop zonehash_lock if it does some work, and
931 * then reacquire it before it returns.
932 * When the lock is dropped we don't follow list_next even
933 * if it is possible to do so without any hazards. This is
934 * because we want the design to allow for the list of zones
935 * to change in any arbitrary way during the time the
936 * lock was dropped.
937 *
1278 }
1279 cv_wait(&t->zsd_cv, &zone->zone_lock);
1280 if (lockp != NULL) {
1281 /* First drop zone_lock to preserve order */
1282 mutex_exit(&zone->zone_lock);
1283 mutex_enter(lockp);
1284 mutex_enter(&zone->zone_lock);
1285 }
1286 }
1287 return (dropped);
1288 }
1289
1290 /*
1291 * Frees memory associated with the zone dataset list.
1292 */
1293 static void
1294 zone_free_datasets(zone_t *zone)
1295 {
1296 zone_dataset_t *t, *next;
1297
1298 list_for_each_safe(&zone->zone_datasets, t, next) {
1299 list_remove(&zone->zone_datasets, t);
1300 kmem_free(t->zd_dataset, strlen(t->zd_dataset) + 1);
1301 kmem_free(t, sizeof (*t));
1302 }
1303 list_destroy(&zone->zone_datasets);
1304 }
1305
1306 /*
1307 * zone.cpu-shares resource control support.
1308 */
1309 /*ARGSUSED*/
1310 static rctl_qty_t
1311 zone_cpu_shares_usage(rctl_t *rctl, struct proc *p)
1312 {
1313 ASSERT(MUTEX_HELD(&p->p_lock));
1314 return (p->p_zone->zone_shares);
1315 }
1316
1317 /*ARGSUSED*/
1318 static int
3015 *
3016 * As with the other zone_find_by_*() functions, the caller is
3017 * responsible for zone_rele()ing the return value of this function.
3018 */
3019 zone_t *
3020 zone_find_by_path(const char *path)
3021 {
3022 zone_t *zone;
3023 zone_t *zret = NULL;
3024 zone_status_t status;
3025
3026 if (path == NULL) {
3027 /*
3028 * Call from rootconf().
3029 */
3030 zone_hold(global_zone);
3031 return (global_zone);
3032 }
3033 ASSERT(*path == '/');
3034 mutex_enter(&zonehash_lock);
3035 list_for_each(&zone_active, zone) {
3036 if (ZONE_PATH_VISIBLE(path, zone))
3037 zret = zone;
3038 }
3039 ASSERT(zret != NULL);
3040 status = zone_status_get(zret);
3041 if (status < ZONE_IS_READY || status > ZONE_IS_DOWN) {
3042 /*
3043 * Zone practically doesn't exist.
3044 */
3045 zret = global_zone;
3046 }
3047 zone_hold(zret);
3048 mutex_exit(&zonehash_lock);
3049 return (zret);
3050 }
3051
3052 /*
3053 * Public interface for updating per-zone load averages. Called once per
3054 * second.
3055 *
3233 zone->zone_ncpus_online = 0;
3234 }
3235 }
3236
3237 /*
3238 * Walk the list of active zones and issue the provided callback for
3239 * each of them.
3240 *
3241 * Caller must not be holding any locks that may be acquired under
3242 * zonehash_lock. See comment at the beginning of the file for a list of
3243 * common locks and their interactions with zones.
3244 */
3245 int
3246 zone_walk(int (*cb)(zone_t *, void *), void *data)
3247 {
3248 zone_t *zone;
3249 int ret = 0;
3250 zone_status_t status;
3251
3252 mutex_enter(&zonehash_lock);
3253 list_for_each(&zone_active, zone) {
3254 /*
3255 * Skip zones that shouldn't be externally visible.
3256 */
3257 status = zone_status_get(zone);
3258 if (status < ZONE_IS_READY || status > ZONE_IS_DOWN)
3259 continue;
3260 /*
3261 * Bail immediately if any callback invocation returns a
3262 * non-zero value.
3263 */
3264 ret = (*cb)(zone, data);
3265 if (ret != 0)
3266 break;
3267 }
3268 mutex_exit(&zonehash_lock);
3269 return (ret);
3270 }
3271
3272 static int
3273 zone_set_root(zone_t *zone, const char *upath)
4024 /*
4025 * Helper function to make sure that a zone created on 'rootpath'
4026 * wouldn't end up containing other zones' rootpaths.
4027 */
4028 static boolean_t
4029 zone_is_nested(const char *rootpath)
4030 {
4031 zone_t *zone;
4032 size_t rootpathlen = strlen(rootpath);
4033 size_t len;
4034
4035 ASSERT(MUTEX_HELD(&zonehash_lock));
4036
4037 /*
4038 * zone_set_root() appended '/' and '\0' at the end of rootpath
4039 */
4040 if ((rootpathlen <= 3) && (rootpath[0] == '/') &&
4041 (rootpath[1] == '/') && (rootpath[2] == '\0'))
4042 return (B_TRUE);
4043
4044 list_for_each(&zone_active, zone) {
4045 if (zone == global_zone)
4046 continue;
4047 len = strlen(zone->zone_rootpath);
4048 if (strncmp(rootpath, zone->zone_rootpath,
4049 MIN(rootpathlen, len)) == 0)
4050 return (B_TRUE);
4051 }
4052 return (B_FALSE);
4053 }
4054
4055 static int
4056 zone_set_privset(zone_t *zone, const priv_set_t *zone_privs,
4057 size_t zone_privssz)
4058 {
4059 priv_set_t *privs;
4060
4061 if (zone_privssz < sizeof (priv_set_t))
4062 return (ENOMEM);
4063
4064 privs = kmem_alloc(sizeof (priv_set_t), KM_SLEEP);
5705 mutex_enter(&ct->ct_lock);
5706 mutex_enter(&pp->p_lock);
5707 if ((avl_numnodes(&pp->p_ct_held) != 0) || (ctp->conp_nmembers != 1)) {
5708 mutex_exit(&pp->p_lock);
5709 mutex_exit(&ct->ct_lock);
5710 mutex_exit(&zonehash_lock);
5711 err = EINVAL;
5712 goto out;
5713 }
5714
5715 /*
5716 * Moreover, we don't allow processes whose encapsulating
5717 * process contracts have inherited extrazonal contracts.
5718 * While it would be easier to eliminate all process contracts
5719 * with inherited contracts, we need to be able to give a
5720 * restarted init (or other zone-penetrating process) its
5721 * predecessor's contracts.
5722 */
5723 if (ctp->conp_ninherited != 0) {
5724 contract_t *next;
5725 list_for_each(&ctp->conp_inherited, next) {
5726 if (contract_getzuniqid(next) != zone->zone_uniqid) {
5727 mutex_exit(&pp->p_lock);
5728 mutex_exit(&ct->ct_lock);
5729 mutex_exit(&zonehash_lock);
5730 err = EINVAL;
5731 goto out;
5732 }
5733 }
5734 }
5735
5736 mutex_exit(&pp->p_lock);
5737 mutex_exit(&ct->ct_lock);
5738
5739 status = zone_status_get(zone);
5740 if (status < ZONE_IS_READY || status >= ZONE_IS_SHUTTING_DOWN) {
5741 /*
5742 * Can't join
5743 */
5744 mutex_exit(&zonehash_lock);
5745 err = EINVAL;
6063 return (set_errno(EFAULT));
6064
6065 myzone = curproc->p_zone;
6066 if (myzone != global_zone) {
6067 bslabel_t *mybslab;
6068
6069 if (!is_system_labeled()) {
6070 /* just return current zone */
6071 real_nzones = domi_nzones = 1;
6072 zoneids = kmem_alloc(sizeof (zoneid_t), KM_SLEEP);
6073 zoneids[0] = myzone->zone_id;
6074 } else {
6075 /* return all zones that are dominated */
6076 mutex_enter(&zonehash_lock);
6077 real_nzones = zonecount;
6078 domi_nzones = 0;
6079 if (real_nzones > 0) {
6080 zoneids = kmem_alloc(real_nzones *
6081 sizeof (zoneid_t), KM_SLEEP);
6082 mybslab = label2bslabel(myzone->zone_slabel);
6083 list_for_each(&zone_active, zone) {
6084 if (zone->zone_id == GLOBAL_ZONEID)
6085 continue;
6086 if (zone != myzone &&
6087 (zone->zone_flags & ZF_IS_SCRATCH))
6088 continue;
6089 /*
6090 * Note that a label always dominates
6091 * itself, so myzone is always included
6092 * in the list.
6093 */
6094 if (bldominates(mybslab,
6095 label2bslabel(zone->zone_slabel))) {
6096 zoneids[domi_nzones++] =
6097 zone->zone_id;
6098 }
6099 }
6100 }
6101 mutex_exit(&zonehash_lock);
6102 }
6103 } else {
6104 mutex_enter(&zonehash_lock);
6105 real_nzones = zonecount;
6106 domi_nzones = 0;
6107 if (real_nzones > 0) {
6108 zoneids = kmem_alloc(real_nzones * sizeof (zoneid_t),
6109 KM_SLEEP);
6110 list_for_each(&zone_active, zone)
6111 zoneids[domi_nzones++] = zone->zone_id;
6112 ASSERT(domi_nzones == real_nzones);
6113 }
6114 mutex_exit(&zonehash_lock);
6115 }
6116
6117 /*
6118 * If user has allocated space for fewer entries than we found, then
6119 * return only up to his limit. Either way, tell him exactly how many
6120 * we found.
6121 */
6122 if (domi_nzones < user_nzones)
6123 user_nzones = domi_nzones;
6124 error = 0;
6125 if (copyout(&domi_nzones, numzones, sizeof (uint_t)) != 0) {
6126 error = EFAULT;
6127 } else if (zoneidlist != NULL && user_nzones != 0) {
6128 if (copyout(zoneids, zoneidlist,
6129 user_nzones * sizeof (zoneid_t)) != 0)
6130 error = EFAULT;
6555 {
6556 zone_t *current_zonep;
6557
6558 ASSERT(INGLOBALZONE(curproc));
6559 mutex_enter(&zonehash_lock);
6560 mutex_enter(&zone_status_lock);
6561
6562 /* Modify the global zone's status first. */
6563 ASSERT(zone_status_get(global_zone) == ZONE_IS_RUNNING);
6564 zone_status_set(global_zone, ZONE_IS_SHUTTING_DOWN);
6565
6566 /*
6567 * Now change the states of all running zones to ZONE_IS_SHUTTING_DOWN.
6568 * We don't mark all zones with ZONE_IS_SHUTTING_DOWN because doing so
6569 * could cause assertions to fail (e.g., assertions about a zone's
6570 * state during initialization, readying, or booting) or produce races.
6571 * We'll let threads continue to initialize and ready new zones: they'll
6572 * fail to boot the new zones when they see that the global zone is
6573 * shutting down.
6574 */
6575 list_for_each(&zone_active, cpurrent_zonep) {
6576 if (zone_status_get(current_zonep) == ZONE_IS_RUNNING)
6577 zone_status_set(current_zonep, ZONE_IS_SHUTTING_DOWN);
6578 }
6579 mutex_exit(&zone_status_lock);
6580 mutex_exit(&zonehash_lock);
6581 }
6582
6583 /*
6584 * Returns true if the named dataset is visible in the current zone.
6585 * The 'write' parameter is set to 1 if the dataset is also writable.
6586 */
6587 int
6588 zone_dataset_visible(const char *dataset, int *write)
6589 {
6590 static int zfstype = -1;
6591 zone_dataset_t *zd;
6592 size_t len;
6593 zone_t *zone = curproc->p_zone;
6594 const char *name = NULL;
6595 vfs_t *vfsp = NULL;
6596
6597 if (dataset[0] == '\0')
6598 return (0);
6599
6600 /*
6601 * Walk the list once, looking for datasets which match exactly, or
6602 * specify a dataset underneath an exported dataset. If found, return
6603 * true and note that it is writable.
6604 */
6605 list_for_each(&zone->zone_datasets, zd) {
6606 len = strlen(zd->zd_dataset);
6607 if (strlen(dataset) >= len &&
6608 bcmp(dataset, zd->zd_dataset, len) == 0 &&
6609 (dataset[len] == '\0' || dataset[len] == '/' ||
6610 dataset[len] == '@')) {
6611 if (write)
6612 *write = 1;
6613 return (1);
6614 }
6615 }
6616
6617 /*
6618 * Walk the list a second time, searching for datasets which are parents
6619 * of exported datasets. These should be visible, but read-only.
6620 *
6621 * Note that we also have to support forms such as 'pool/dataset/', with
6622 * a trailing slash.
6623 */
6624 list_for_each(&zone->zone_dataset, zd) {
6625 len = strlen(dataset);
6626 if (dataset[len - 1] == '/')
6627 len--; /* Ignore trailing slash */
6628 if (len < strlen(zd->zd_dataset) &&
6629 bcmp(dataset, zd->zd_dataset, len) == 0 &&
6630 zd->zd_dataset[len] == '/') {
6631 if (write)
6632 *write = 0;
6633 return (1);
6634 }
6635 }
6636
6637 /*
6638 * We reach here if the given dataset is not found in the zone_dataset
6639 * list. Check if this dataset was added as a filesystem (ie. "add fs")
6640 * instead of delegation. For this we search for the dataset in the
6641 * zone_vfslist of this zone. If found, return true and note that it is
6642 * not writable.
6643 */
6644
6709 *
6710 * The caller is responsible for zone_rele of the returned zone.
6711 */
6712 zone_t *
6713 zone_find_by_any_path(const char *path, boolean_t treat_abs)
6714 {
6715 zone_t *zone;
6716 int path_offset = 0;
6717
6718 if (path == NULL) {
6719 zone_hold(global_zone);
6720 return (global_zone);
6721 }
6722
6723 if (*path != '/') {
6724 ASSERT(treat_abs);
6725 path_offset = 1;
6726 }
6727
6728 mutex_enter(&zonehash_lock);
6729 list_for_each(&zone_active, zone) {
6730 char *c;
6731 size_t pathlen;
6732 char *rootpath_start;
6733
6734 if (zone == global_zone) /* skip global zone */
6735 continue;
6736
6737 /* scan backwards to find start of last component */
6738 c = zone->zone_rootpath + zone->zone_rootpathlen - 2;
6739 do {
6740 c--;
6741 } while (*c != '/');
6742
6743 pathlen = c - zone->zone_rootpath + 1 - path_offset;
6744 rootpath_start = (zone->zone_rootpath + path_offset);
6745 if (strncmp(path, rootpath_start, pathlen) == 0)
6746 break;
6747 }
6748 if (zone == NULL)
6749 zone = global_zone;
6750 zone_hold(zone);
6751 mutex_exit(&zonehash_lock);
6752 return (zone);
6753 }
6754
6755 /*
6756 * Finds a zone_dl_t with the given linkid in the given zone. Returns the
6757 * zone_dl_t pointer if found, and NULL otherwise.
6758 */
6759 static zone_dl_t *
6760 zone_find_dl(zone_t *zone, datalink_id_t linkid)
6761 {
6762 zone_dl_t *zdl;
6763
6764 ASSERT(mutex_owned(&zone->zone_lock));
6765 list_for_each(&zone->zone_dl_list, zdl) {
6766 if (zdl->zdl_id == linkid)
6767 break;
6768 }
6769 return (zdl);
6770 }
6771
6772 static boolean_t
6773 zone_dl_exists(zone_t *zone, datalink_id_t linkid)
6774 {
6775 boolean_t exists;
6776
6777 mutex_enter(&zone->zone_lock);
6778 exists = (zone_find_dl(zone, linkid) != NULL);
6779 mutex_exit(&zone->zone_lock);
6780 return (exists);
6781 }
6782
6783 /*
6784 * Add an data link name for the zone.
6785 */
6786 static int
6787 zone_add_datalink(zoneid_t zoneid, datalink_id_t linkid)
6788 {
6789 zone_dl_t *zdl;
6790 zone_t *zone;
6791 zone_t *thiszone;
6792
6793 if ((thiszone = zone_find_by_id(zoneid)) == NULL)
6794 return (set_errno(ENXIO));
6795
6796 /* Verify that the datalink ID doesn't already belong to a zone. */
6797 mutex_enter(&zonehash_lock);
6798 list_for_each(&zone_active, zone) {
6799 if (zone_dl_exists(zone, linkid)) {
6800 mutex_exit(&zonehash_lock);
6801 zone_rele(thiszone);
6802 return (set_errno((zone == thiszone) ? EEXIST : EPERM));
6803 }
6804 }
6805
6806 zdl = kmem_zalloc(sizeof (*zdl), KM_SLEEP);
6807 zdl->zdl_id = linkid;
6808 zdl->zdl_net = NULL;
6809 mutex_enter(&thiszone->zone_lock);
6810 list_insert_head(&thiszone->zone_dl_list, zdl);
6811 mutex_exit(&thiszone->zone_lock);
6812 mutex_exit(&zonehash_lock);
6813 zone_rele(thiszone);
6814 return (0);
6815 }
6816
6817 static int
6818 zone_remove_datalink(zoneid_t zoneid, datalink_id_t linkid)
6842 * Using the zoneidp as ALL_ZONES, we can lookup which zone has been assigned
6843 * the linkid. Otherwise we just check if the specified zoneidp has been
6844 * assigned the supplied linkid.
6845 */
6846 int
6847 zone_check_datalink(zoneid_t *zoneidp, datalink_id_t linkid)
6848 {
6849 zone_t *zone;
6850 int err = ENXIO;
6851
6852 if (*zoneidp != ALL_ZONES) {
6853 if ((zone = zone_find_by_id(*zoneidp)) != NULL) {
6854 if (zone_dl_exists(zone, linkid))
6855 err = 0;
6856 zone_rele(zone);
6857 }
6858 return (err);
6859 }
6860
6861 mutex_enter(&zonehash_lock);
6862 list_for_each(&zone_active, zone) {
6863 if (zone_dl_exists(zone, linkid)) {
6864 *zoneidp = zone->zone_id;
6865 err = 0;
6866 break;
6867 }
6868 }
6869 mutex_exit(&zonehash_lock);
6870 return (err);
6871 }
6872
6873 /*
6874 * Get the list of datalink IDs assigned to a zone.
6875 *
6876 * On input, *nump is the number of datalink IDs that can fit in the supplied
6877 * idarray. Upon return, *nump is either set to the number of datalink IDs
6878 * that were placed in the array if the array was large enough, or to the
6879 * number of datalink IDs that the function needs to place in the array if the
6880 * array is too small.
6881 */
6882 static int
6883 zone_list_datalink(zoneid_t zoneid, int *nump, datalink_id_t *idarray)
6884 {
6885 uint_t num, dlcount;
6886 zone_t *zone;
6887 zone_dl_t *zdl;
6888 datalink_id_t *idptr = idarray;
6889
6890 if (copyin(nump, &dlcount, sizeof (dlcount)) != 0)
6891 return (set_errno(EFAULT));
6892 if ((zone = zone_find_by_id(zoneid)) == NULL)
6893 return (set_errno(ENXIO));
6894
6895 num = 0;
6896 mutex_enter(&zone->zone_lock);
6897 list_for_each(&zone->zone_dl_list, zdl) {
6898 /*
6899 * If the list is bigger than what the caller supplied, just
6900 * count, don't do copyout.
6901 */
6902 if (++num > dlcount)
6903 continue;
6904 if (copyout(&zdl->zdl_id, idptr, sizeof (*idptr)) != 0) {
6905 mutex_exit(&zone->zone_lock);
6906 zone_rele(zone);
6907 return (set_errno(EFAULT));
6908 }
6909 idptr++;
6910 }
6911 mutex_exit(&zone->zone_lock);
6912 zone_rele(zone);
6913
6914 /* Increased or decreased, caller should be notified. */
6915 if (num != dlcount) {
6916 if (copyout(&num, nump, sizeof (num)) != 0)
6917 return (set_errno(EFAULT));
6951 * Walk the datalinks for a given zone
6952 */
6953 int
6954 zone_datalink_walk(zoneid_t zoneid, int (*cb)(datalink_id_t, void *),
6955 void *data)
6956 {
6957 zone_t *zone;
6958 zone_dl_t *zdl;
6959 datalink_id_t *idarray;
6960 uint_t idcount = 0;
6961 int i, ret = 0;
6962
6963 if ((zone = zone_find_by_id(zoneid)) == NULL)
6964 return (ENOENT);
6965
6966 /*
6967 * We first build an array of linkid's so that we can walk these and
6968 * execute the callback with the zone_lock dropped.
6969 */
6970 mutex_enter(&zone->zone_lock);
6971 list_for_each(&zone->zone_dl_lists, zdl) {
6972 idcount++;
6973 }
6974
6975 if (idcount == 0) {
6976 mutex_exit(&zone->zone_lock);
6977 zone_rele(zone);
6978 return (0);
6979 }
6980
6981 idarray = kmem_alloc(sizeof (datalink_id_t) * idcount, KM_NOSLEEP);
6982 if (idarray == NULL) {
6983 mutex_exit(&zone->zone_lock);
6984 zone_rele(zone);
6985 return (ENOMEM);
6986 }
6987
6988 i = 0;
6989 list_for_each(&zone->zone_dl_list, zdl) {
6990 idarray[i] = zdl->zdl_id;
6991 i++;
6992 }
6993
6994 mutex_exit(&zone->zone_lock);
6995
6996 for (i = 0; i < idcount && ret == 0; i++) {
6997 if ((ret = (*cb)(idarray[i], data)) != 0)
6998 break;
6999 }
7000
7001 zone_rele(zone);
7002 kmem_free(idarray, sizeof (datalink_id_t) * idcount);
7003 return (ret);
7004 }
7005
7006 static char *
7007 zone_net_type2name(int type)
7008 {
7009 switch (type) {
7010 case ZONE_NETWORK_ADDRESS:
7011 return (ZONE_NET_ADDRNAME);
|