Print this page
patch zone

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/os/zone.c
          +++ new/usr/src/uts/common/os/zone.c
↓ open down ↓ 568 lines elided ↑ open up ↑
 569  569  
 570  570  /*
 571  571   * Helper function to find the zsd_entry associated with the key in the
 572  572   * given list.
 573  573   */
 574  574  static struct zsd_entry *
 575  575  zsd_find(list_t *l, zone_key_t key)
 576  576  {
 577  577          struct zsd_entry *zsd;
 578  578  
 579      -        for (zsd = list_head(l); zsd != NULL; zsd = list_next(l, zsd)) {
      579 +        list_for_each(l, zsd) {
 580  580                  if (zsd->zsd_key == key) {
 581  581                          return (zsd);
 582  582                  }
 583  583          }
 584  584          return (NULL);
 585  585  }
 586  586  
 587  587  /*
 588  588   * Helper function to find the zsd_entry associated with the key in the
 589  589   * given list. Move it to the front of the list.
 590  590   */
 591  591  static struct zsd_entry *
 592  592  zsd_find_mru(list_t *l, zone_key_t key)
 593  593  {
 594  594          struct zsd_entry *zsd;
 595  595  
 596      -        for (zsd = list_head(l); zsd != NULL; zsd = list_next(l, zsd)) {
      596 +        list_for_each(l, zsd) {
 597  597                  if (zsd->zsd_key == key) {
 598  598                          /*
 599  599                           * Move to head of list to keep list in MRU order.
 600  600                           */
 601  601                          if (zsd != list_head(l)) {
 602  602                                  list_remove(l, zsd);
 603  603                                  list_insert_head(l, zsd);
 604  604                          }
 605  605                          return (zsd);
 606  606                  }
↓ open down ↓ 24 lines elided ↑ open up ↑
 631  631          key = zsdp->zsd_key = ++zsd_keyval;
 632  632          ASSERT(zsd_keyval != 0);
 633  633          list_insert_tail(&zsd_registered_keys, zsdp);
 634  634          mutex_exit(&zsd_key_lock);
 635  635  
 636  636          /*
 637  637           * Insert for all existing zones and mark them as needing
 638  638           * a create callback.
 639  639           */
 640  640          mutex_enter(&zonehash_lock);    /* stop the world */
 641      -        for (zone = list_head(&zone_active); zone != NULL;
 642      -            zone = list_next(&zone_active, zone)) {
      641 +        list_for_each(&zone_active, zone) {
 643  642                  zone_status_t status;
 644  643  
 645  644                  mutex_enter(&zone->zone_lock);
 646  645  
 647  646                  /* Skip zones that are on the way down or not yet up */
 648  647                  status = zone_status_get(zone);
 649  648                  if (status >= ZONE_IS_DOWN ||
 650  649                      status == ZONE_IS_UNINITIALIZED) {
 651  650                          mutex_exit(&zone->zone_lock);
 652  651                          continue;
↓ open down ↓ 55 lines elided ↑ open up ↑
 708  707          mutex_enter(&zsd_key_lock);
 709  708          zsdp = zsd_find_mru(&zsd_registered_keys, key);
 710  709          if (zsdp == NULL) {
 711  710                  mutex_exit(&zsd_key_lock);
 712  711                  return (-1);
 713  712          }
 714  713          list_remove(&zsd_registered_keys, zsdp);
 715  714          mutex_exit(&zsd_key_lock);
 716  715  
 717  716          mutex_enter(&zonehash_lock);
 718      -        for (zone = list_head(&zone_active); zone != NULL;
 719      -            zone = list_next(&zone_active, zone)) {
      717 +        list_for_each(&zone_active, zone) {
 720  718                  struct zsd_entry *del;
 721  719  
 722  720                  mutex_enter(&zone->zone_lock);
 723  721                  del = zsd_find_mru(&zone->zone_zsd, key);
 724  722                  if (del == NULL) {
 725  723                          /*
 726  724                           * Somebody else got here first e.g the zone going
 727  725                           * away.
 728  726                           */
 729  727                          mutex_exit(&zone->zone_lock);
↓ open down ↓ 17 lines elided ↑ open up ↑
 747  745          }
 748  746          mutex_exit(&zonehash_lock);
 749  747          kmem_free(zsdp, sizeof (*zsdp));
 750  748  
 751  749          /* Now call the shutdown and destroy callback for this key */
 752  750          zsd_apply_all_zones(zsd_apply_shutdown, key);
 753  751          zsd_apply_all_zones(zsd_apply_destroy, key);
 754  752  
 755  753          /* Now we can free up the zsdp structures in each zone */
 756  754          mutex_enter(&zonehash_lock);
 757      -        for (zone = list_head(&zone_active); zone != NULL;
 758      -            zone = list_next(&zone_active, zone)) {
      755 +        list_for_each(&zone_active, zone) {
 759  756                  struct zsd_entry *del;
 760  757  
 761  758                  mutex_enter(&zone->zone_lock);
 762  759                  del = zsd_find(&zone->zone_zsd, key);
 763  760                  if (del != NULL) {
 764  761                          list_remove(&zone->zone_zsd, del);
 765  762                          ASSERT(!(del->zsd_flags & ZSD_ALL_INPROGRESS));
 766  763                          kmem_free(del, sizeof (*del));
 767  764                  }
 768  765                  mutex_exit(&zone->zone_lock);
↓ open down ↓ 55 lines elided ↑ open up ↑
 824  821  static void
 825  822  zone_zsd_configure(zone_t *zone)
 826  823  {
 827  824          struct zsd_entry *zsdp;
 828  825          struct zsd_entry *t;
 829  826  
 830  827          ASSERT(MUTEX_HELD(&zonehash_lock));
 831  828          ASSERT(list_head(&zone->zone_zsd) == NULL);
 832  829          mutex_enter(&zone->zone_lock);
 833  830          mutex_enter(&zsd_key_lock);
 834      -        for (zsdp = list_head(&zsd_registered_keys); zsdp != NULL;
 835      -            zsdp = list_next(&zsd_registered_keys, zsdp)) {
      831 +        list_for_each(&zsd_registered_keys, zsdp) {
 836  832                  /*
 837  833                   * Since this zone is ZONE_IS_UNCONFIGURED, zone_key_create
 838  834                   * should not have added anything to it.
 839  835                   */
 840  836                  ASSERT(zsd_find(&zone->zone_zsd, zsdp->zsd_key) == NULL);
 841  837  
 842  838                  t = kmem_zalloc(sizeof (*t), KM_SLEEP);
 843  839                  t->zsd_key = zsdp->zsd_key;
 844  840                  t->zsd_create = zsdp->zsd_create;
 845  841                  t->zsd_shutdown = zsdp->zsd_shutdown;
↓ open down ↓ 23 lines elided ↑ open up ↑
 869  865          ASSERT(ct != ZSD_SHUTDOWN || zone_status_get(zone) >= ZONE_IS_EMPTY);
 870  866          ASSERT(ct != ZSD_DESTROY || zone_status_get(zone) >= ZONE_IS_DOWN);
 871  867  
 872  868          /*
 873  869           * Run the callback solely based on what is registered for the zone
 874  870           * in zone_zsd. The global list can change independently of this
 875  871           * as keys are registered and unregistered and we don't register new
 876  872           * callbacks for a zone that is in the process of going away.
 877  873           */
 878  874          mutex_enter(&zone->zone_lock);
 879      -        for (t = list_head(&zone->zone_zsd); t != NULL;
 880      -            t = list_next(&zone->zone_zsd, t)) {
      875 +        list_for_each(&zone->zone_zsd, t) {
 881  876                  zone_key_t key = t->zsd_key;
 882  877  
 883  878                  /* Skip if no callbacks registered */
 884  879  
 885  880                  if (ct == ZSD_SHUTDOWN) {
 886  881                          if (t->zsd_shutdown != NULL &&
 887  882                              (t->zsd_flags & ZSD_SHUTDOWN_ALL) == 0) {
 888  883                                  t->zsd_flags |= ZSD_SHUTDOWN_NEEDED;
 889  884                                  DTRACE_PROBE2(zsd__shutdown__needed,
 890  885                                      zone_t *, zone, zone_key_t, key);
↓ open down ↓ 21 lines elided ↑ open up ↑
 912  907   */
 913  908  static void
 914  909  zone_free_zsd(zone_t *zone)
 915  910  {
 916  911          struct zsd_entry *t, *next;
 917  912  
 918  913          /*
 919  914           * Free all the zsd_entry's we had on this zone.
 920  915           */
 921  916          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);
      917 +        list_for_each_safe(&zone->zone_zsd, t, next) {
 924  918                  list_remove(&zone->zone_zsd, t);
 925  919                  ASSERT(!(t->zsd_flags & ZSD_ALL_INPROGRESS));
 926  920                  kmem_free(t, sizeof (*t));
 927  921          }
 928  922          list_destroy(&zone->zone_zsd);
 929  923          mutex_exit(&zone->zone_lock);
 930  924  
 931  925  }
 932  926  
 933  927  /*
↓ open down ↓ 360 lines elided ↑ open up ↑
1294 1288  }
1295 1289  
1296 1290  /*
1297 1291   * Frees memory associated with the zone dataset list.
1298 1292   */
1299 1293  static void
1300 1294  zone_free_datasets(zone_t *zone)
1301 1295  {
1302 1296          zone_dataset_t *t, *next;
1303 1297  
1304      -        for (t = list_head(&zone->zone_datasets); t != NULL; t = next) {
1305      -                next = list_next(&zone->zone_datasets, t);
     1298 +        list_for_each_safe(&zone->zone_datasets, t, next) {
1306 1299                  list_remove(&zone->zone_datasets, t);
1307 1300                  kmem_free(t->zd_dataset, strlen(t->zd_dataset) + 1);
1308 1301                  kmem_free(t, sizeof (*t));
1309 1302          }
1310 1303          list_destroy(&zone->zone_datasets);
1311 1304  }
1312 1305  
1313 1306  /*
1314 1307   * zone.cpu-shares resource control support.
1315 1308   */
↓ open down ↓ 1716 lines elided ↑ open up ↑
3032 3025  
3033 3026          if (path == NULL) {
3034 3027                  /*
3035 3028                   * Call from rootconf().
3036 3029                   */
3037 3030                  zone_hold(global_zone);
3038 3031                  return (global_zone);
3039 3032          }
3040 3033          ASSERT(*path == '/');
3041 3034          mutex_enter(&zonehash_lock);
3042      -        for (zone = list_head(&zone_active); zone != NULL;
3043      -            zone = list_next(&zone_active, zone)) {
     3035 +        list_for_each(&zone_active, zone) {
3044 3036                  if (ZONE_PATH_VISIBLE(path, zone))
3045 3037                          zret = zone;
3046 3038          }
3047 3039          ASSERT(zret != NULL);
3048 3040          status = zone_status_get(zret);
3049 3041          if (status < ZONE_IS_READY || status > ZONE_IS_DOWN) {
3050 3042                  /*
3051 3043                   * Zone practically doesn't exist.
3052 3044                   */
3053 3045                  zret = global_zone;
↓ open down ↓ 197 lines elided ↑ open up ↑
3251 3243   * common locks and their interactions with zones.
3252 3244   */
3253 3245  int
3254 3246  zone_walk(int (*cb)(zone_t *, void *), void *data)
3255 3247  {
3256 3248          zone_t *zone;
3257 3249          int ret = 0;
3258 3250          zone_status_t status;
3259 3251  
3260 3252          mutex_enter(&zonehash_lock);
3261      -        for (zone = list_head(&zone_active); zone != NULL;
3262      -            zone = list_next(&zone_active, zone)) {
     3253 +        list_for_each(&zone_active, zone) {
3263 3254                  /*
3264 3255                   * Skip zones that shouldn't be externally visible.
3265 3256                   */
3266 3257                  status = zone_status_get(zone);
3267 3258                  if (status < ZONE_IS_READY || status > ZONE_IS_DOWN)
3268 3259                          continue;
3269 3260                  /*
3270 3261                   * Bail immediately if any callback invocation returns a
3271 3262                   * non-zero value.
3272 3263                   */
↓ open down ↓ 770 lines elided ↑ open up ↑
4043 4034  
4044 4035          ASSERT(MUTEX_HELD(&zonehash_lock));
4045 4036  
4046 4037          /*
4047 4038           * zone_set_root() appended '/' and '\0' at the end of rootpath
4048 4039           */
4049 4040          if ((rootpathlen <= 3) && (rootpath[0] == '/') &&
4050 4041              (rootpath[1] == '/') && (rootpath[2] == '\0'))
4051 4042                  return (B_TRUE);
4052 4043  
4053      -        for (zone = list_head(&zone_active); zone != NULL;
4054      -            zone = list_next(&zone_active, zone)) {
     4044 +        list_for_each(&zone_active, zone) {
4055 4045                  if (zone == global_zone)
4056 4046                          continue;
4057 4047                  len = strlen(zone->zone_rootpath);
4058 4048                  if (strncmp(rootpath, zone->zone_rootpath,
4059 4049                      MIN(rootpathlen, len)) == 0)
4060 4050                          return (B_TRUE);
4061 4051          }
4062 4052          return (B_FALSE);
4063 4053  }
4064 4054  
↓ open down ↓ 1660 lines elided ↑ open up ↑
5725 5715          /*
5726 5716           * Moreover, we don't allow processes whose encapsulating
5727 5717           * process contracts have inherited extrazonal contracts.
5728 5718           * While it would be easier to eliminate all process contracts
5729 5719           * with inherited contracts, we need to be able to give a
5730 5720           * restarted init (or other zone-penetrating process) its
5731 5721           * predecessor's contracts.
5732 5722           */
5733 5723          if (ctp->conp_ninherited != 0) {
5734 5724                  contract_t *next;
5735      -                for (next = list_head(&ctp->conp_inherited); next;
5736      -                    next = list_next(&ctp->conp_inherited, next)) {
     5725 +                list_for_each(&ctp->conp_inherited, next) {
5737 5726                          if (contract_getzuniqid(next) != zone->zone_uniqid) {
5738 5727                                  mutex_exit(&pp->p_lock);
5739 5728                                  mutex_exit(&ct->ct_lock);
5740 5729                                  mutex_exit(&zonehash_lock);
5741 5730                                  err = EINVAL;
5742 5731                                  goto out;
5743 5732                          }
5744 5733                  }
5745 5734          }
5746 5735  
↓ open down ↓ 337 lines elided ↑ open up ↑
6084 6073                          zoneids[0] = myzone->zone_id;
6085 6074                  } else {
6086 6075                          /* return all zones that are dominated */
6087 6076                          mutex_enter(&zonehash_lock);
6088 6077                          real_nzones = zonecount;
6089 6078                          domi_nzones = 0;
6090 6079                          if (real_nzones > 0) {
6091 6080                                  zoneids = kmem_alloc(real_nzones *
6092 6081                                      sizeof (zoneid_t), KM_SLEEP);
6093 6082                                  mybslab = label2bslabel(myzone->zone_slabel);
6094      -                                for (zone = list_head(&zone_active);
6095      -                                    zone != NULL;
6096      -                                    zone = list_next(&zone_active, zone)) {
     6083 +                                list_for_each(&zone_active, zone) {
6097 6084                                          if (zone->zone_id == GLOBAL_ZONEID)
6098 6085                                                  continue;
6099 6086                                          if (zone != myzone &&
6100 6087                                              (zone->zone_flags & ZF_IS_SCRATCH))
6101 6088                                                  continue;
6102 6089                                          /*
6103 6090                                           * Note that a label always dominates
6104 6091                                           * itself, so myzone is always included
6105 6092                                           * in the list.
6106 6093                                           */
↓ open down ↓ 6 lines elided ↑ open up ↑
6113 6100                          }
6114 6101                          mutex_exit(&zonehash_lock);
6115 6102                  }
6116 6103          } else {
6117 6104                  mutex_enter(&zonehash_lock);
6118 6105                  real_nzones = zonecount;
6119 6106                  domi_nzones = 0;
6120 6107                  if (real_nzones > 0) {
6121 6108                          zoneids = kmem_alloc(real_nzones * sizeof (zoneid_t),
6122 6109                              KM_SLEEP);
6123      -                        for (zone = list_head(&zone_active); zone != NULL;
6124      -                            zone = list_next(&zone_active, zone))
     6110 +                        list_for_each(&zone_active, zone)
6125 6111                                  zoneids[domi_nzones++] = zone->zone_id;
6126 6112                          ASSERT(domi_nzones == real_nzones);
6127 6113                  }
6128 6114                  mutex_exit(&zonehash_lock);
6129 6115          }
6130 6116  
6131 6117          /*
6132 6118           * If user has allocated space for fewer entries than we found, then
6133 6119           * return only up to his limit.  Either way, tell him exactly how many
6134 6120           * we found.
↓ open down ↓ 444 lines elided ↑ open up ↑
6579 6565  
6580 6566          /*
6581 6567           * Now change the states of all running zones to ZONE_IS_SHUTTING_DOWN.
6582 6568           * We don't mark all zones with ZONE_IS_SHUTTING_DOWN because doing so
6583 6569           * could cause assertions to fail (e.g., assertions about a zone's
6584 6570           * state during initialization, readying, or booting) or produce races.
6585 6571           * We'll let threads continue to initialize and ready new zones: they'll
6586 6572           * fail to boot the new zones when they see that the global zone is
6587 6573           * shutting down.
6588 6574           */
6589      -        for (current_zonep = list_head(&zone_active); current_zonep != NULL;
6590      -            current_zonep = list_next(&zone_active, current_zonep)) {
     6575 +        list_for_each(&zone_active, cpurrent_zonep) {
6591 6576                  if (zone_status_get(current_zonep) == ZONE_IS_RUNNING)
6592 6577                          zone_status_set(current_zonep, ZONE_IS_SHUTTING_DOWN);
6593 6578          }
6594 6579          mutex_exit(&zone_status_lock);
6595 6580          mutex_exit(&zonehash_lock);
6596 6581  }
6597 6582  
6598 6583  /*
6599 6584   * Returns true if the named dataset is visible in the current zone.
6600 6585   * The 'write' parameter is set to 1 if the dataset is also writable.
↓ open down ↓ 9 lines elided ↑ open up ↑
6610 6595          vfs_t *vfsp = NULL;
6611 6596  
6612 6597          if (dataset[0] == '\0')
6613 6598                  return (0);
6614 6599  
6615 6600          /*
6616 6601           * Walk the list once, looking for datasets which match exactly, or
6617 6602           * specify a dataset underneath an exported dataset.  If found, return
6618 6603           * true and note that it is writable.
6619 6604           */
6620      -        for (zd = list_head(&zone->zone_datasets); zd != NULL;
6621      -            zd = list_next(&zone->zone_datasets, zd)) {
6622      -
     6605 +        list_for_each(&zone->zone_datasets, zd) {
6623 6606                  len = strlen(zd->zd_dataset);
6624 6607                  if (strlen(dataset) >= len &&
6625 6608                      bcmp(dataset, zd->zd_dataset, len) == 0 &&
6626 6609                      (dataset[len] == '\0' || dataset[len] == '/' ||
6627 6610                      dataset[len] == '@')) {
6628 6611                          if (write)
6629 6612                                  *write = 1;
6630 6613                          return (1);
6631 6614                  }
6632 6615          }
6633 6616  
6634 6617          /*
6635 6618           * Walk the list a second time, searching for datasets which are parents
6636 6619           * of exported datasets.  These should be visible, but read-only.
6637 6620           *
6638 6621           * Note that we also have to support forms such as 'pool/dataset/', with
6639 6622           * a trailing slash.
6640 6623           */
6641      -        for (zd = list_head(&zone->zone_datasets); zd != NULL;
6642      -            zd = list_next(&zone->zone_datasets, zd)) {
6643      -
     6624 +        list_for_each(&zone->zone_dataset, zd) {
6644 6625                  len = strlen(dataset);
6645 6626                  if (dataset[len - 1] == '/')
6646 6627                          len--;  /* Ignore trailing slash */
6647 6628                  if (len < strlen(zd->zd_dataset) &&
6648 6629                      bcmp(dataset, zd->zd_dataset, len) == 0 &&
6649 6630                      zd->zd_dataset[len] == '/') {
6650 6631                          if (write)
6651 6632                                  *write = 0;
6652 6633                          return (1);
6653 6634                  }
↓ open down ↓ 84 lines elided ↑ open up ↑
6738 6719                  zone_hold(global_zone);
6739 6720                  return (global_zone);
6740 6721          }
6741 6722  
6742 6723          if (*path != '/') {
6743 6724                  ASSERT(treat_abs);
6744 6725                  path_offset = 1;
6745 6726          }
6746 6727  
6747 6728          mutex_enter(&zonehash_lock);
6748      -        for (zone = list_head(&zone_active); zone != NULL;
6749      -            zone = list_next(&zone_active, zone)) {
     6729 +        list_for_each(&zone_active, zone) {
6750 6730                  char    *c;
6751 6731                  size_t  pathlen;
6752 6732                  char *rootpath_start;
6753 6733  
6754 6734                  if (zone == global_zone)        /* skip global zone */
6755 6735                          continue;
6756 6736  
6757 6737                  /* scan backwards to find start of last component */
6758 6738                  c = zone->zone_rootpath + zone->zone_rootpathlen - 2;
6759 6739                  do {
↓ open down ↓ 15 lines elided ↑ open up ↑
6775 6755  /*
6776 6756   * Finds a zone_dl_t with the given linkid in the given zone.  Returns the
6777 6757   * zone_dl_t pointer if found, and NULL otherwise.
6778 6758   */
6779 6759  static zone_dl_t *
6780 6760  zone_find_dl(zone_t *zone, datalink_id_t linkid)
6781 6761  {
6782 6762          zone_dl_t *zdl;
6783 6763  
6784 6764          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)) {
     6765 +        list_for_each(&zone->zone_dl_list, zdl) {
6787 6766                  if (zdl->zdl_id == linkid)
6788 6767                          break;
6789 6768          }
6790 6769          return (zdl);
6791 6770  }
6792 6771  
6793 6772  static boolean_t
6794 6773  zone_dl_exists(zone_t *zone, datalink_id_t linkid)
6795 6774  {
6796 6775          boolean_t exists;
↓ open down ↓ 12 lines elided ↑ open up ↑
6809 6788  {
6810 6789          zone_dl_t *zdl;
6811 6790          zone_t *zone;
6812 6791          zone_t *thiszone;
6813 6792  
6814 6793          if ((thiszone = zone_find_by_id(zoneid)) == NULL)
6815 6794                  return (set_errno(ENXIO));
6816 6795  
6817 6796          /* Verify that the datalink ID doesn't already belong to a zone. */
6818 6797          mutex_enter(&zonehash_lock);
6819      -        for (zone = list_head(&zone_active); zone != NULL;
6820      -            zone = list_next(&zone_active, zone)) {
     6798 +        list_for_each(&zone_active, zone) {
6821 6799                  if (zone_dl_exists(zone, linkid)) {
6822 6800                          mutex_exit(&zonehash_lock);
6823 6801                          zone_rele(thiszone);
6824 6802                          return (set_errno((zone == thiszone) ? EEXIST : EPERM));
6825 6803                  }
6826 6804          }
6827 6805  
6828 6806          zdl = kmem_zalloc(sizeof (*zdl), KM_SLEEP);
6829 6807          zdl->zdl_id = linkid;
6830 6808          zdl->zdl_net = NULL;
↓ open down ↓ 43 lines elided ↑ open up ↑
6874 6852          if (*zoneidp != ALL_ZONES) {
6875 6853                  if ((zone = zone_find_by_id(*zoneidp)) != NULL) {
6876 6854                          if (zone_dl_exists(zone, linkid))
6877 6855                                  err = 0;
6878 6856                          zone_rele(zone);
6879 6857                  }
6880 6858                  return (err);
6881 6859          }
6882 6860  
6883 6861          mutex_enter(&zonehash_lock);
6884      -        for (zone = list_head(&zone_active); zone != NULL;
6885      -            zone = list_next(&zone_active, zone)) {
     6862 +        list_for_each(&zone_active, zone) {
6886 6863                  if (zone_dl_exists(zone, linkid)) {
6887 6864                          *zoneidp = zone->zone_id;
6888 6865                          err = 0;
6889 6866                          break;
6890 6867                  }
6891 6868          }
6892 6869          mutex_exit(&zonehash_lock);
6893 6870          return (err);
6894 6871  }
6895 6872  
↓ open down ↓ 14 lines elided ↑ open up ↑
6910 6887          zone_dl_t *zdl;
6911 6888          datalink_id_t *idptr = idarray;
6912 6889  
6913 6890          if (copyin(nump, &dlcount, sizeof (dlcount)) != 0)
6914 6891                  return (set_errno(EFAULT));
6915 6892          if ((zone = zone_find_by_id(zoneid)) == NULL)
6916 6893                  return (set_errno(ENXIO));
6917 6894  
6918 6895          num = 0;
6919 6896          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)) {
     6897 +        list_for_each(&zone->zone_dl_list, zdl) {
6922 6898                  /*
6923 6899                   * If the list is bigger than what the caller supplied, just
6924 6900                   * count, don't do copyout.
6925 6901                   */
6926 6902                  if (++num > dlcount)
6927 6903                          continue;
6928 6904                  if (copyout(&zdl->zdl_id, idptr, sizeof (*idptr)) != 0) {
6929 6905                          mutex_exit(&zone->zone_lock);
6930 6906                          zone_rele(zone);
6931 6907                          return (set_errno(EFAULT));
↓ open down ↓ 53 lines elided ↑ open up ↑
6985 6961          int             i, ret = 0;
6986 6962  
6987 6963          if ((zone = zone_find_by_id(zoneid)) == NULL)
6988 6964                  return (ENOENT);
6989 6965  
6990 6966          /*
6991 6967           * We first build an array of linkid's so that we can walk these and
6992 6968           * execute the callback with the zone_lock dropped.
6993 6969           */
6994 6970          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)) {
     6971 +        list_for_each(&zone->zone_dl_lists, zdl) {
6997 6972                  idcount++;
6998 6973          }
6999 6974  
7000 6975          if (idcount == 0) {
7001 6976                  mutex_exit(&zone->zone_lock);
7002 6977                  zone_rele(zone);
7003 6978                  return (0);
7004 6979          }
7005 6980  
7006 6981          idarray = kmem_alloc(sizeof (datalink_id_t) * idcount, KM_NOSLEEP);
7007 6982          if (idarray == NULL) {
7008 6983                  mutex_exit(&zone->zone_lock);
7009 6984                  zone_rele(zone);
7010 6985                  return (ENOMEM);
7011 6986          }
7012 6987  
7013      -        for (i = 0, zdl = list_head(&zone->zone_dl_list); zdl != NULL;
7014      -            i++, zdl = list_next(&zone->zone_dl_list, zdl)) {
     6988 +        i = 0;
     6989 +        list_for_each(&zone->zone_dl_list, zdl) {
7015 6990                  idarray[i] = zdl->zdl_id;
     6991 +                i++;
7016 6992          }
7017 6993  
7018 6994          mutex_exit(&zone->zone_lock);
7019 6995  
7020 6996          for (i = 0; i < idcount && ret == 0; i++) {
7021 6997                  if ((ret = (*cb)(idarray[i], data)) != 0)
7022 6998                          break;
7023 6999          }
7024 7000  
7025 7001          zone_rele(zone);
↓ open down ↓ 125 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX