Print this page
OS-200 need a better mechanism for storing persistent zone_did

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/zoneadm/zoneadm.c
          +++ new/usr/src/cmd/zoneadm/zoneadm.c
↓ open down ↓ 94 lines elided ↑ open up ↑
  95   95  /* Reflects kernel zone entries */
  96   96  typedef struct zone_entry {
  97   97          zoneid_t        zid;
  98   98          char            zname[ZONENAME_MAX];
  99   99          char            *zstate_str;
 100  100          zone_state_t    zstate_num;
 101  101          char            zbrand[MAXNAMELEN];
 102  102          char            zroot[MAXPATHLEN];
 103  103          char            zuuid[UUID_PRINTABLE_STRING_LENGTH];
 104  104          zone_iptype_t   ziptype;
      105 +        zoneid_t        zdid;
 105  106  } zone_entry_t;
 106  107  
 107  108  #define CLUSTER_BRAND_NAME      "cluster"
 108  109  
 109  110  static zone_entry_t *zents;
 110  111  static size_t nzents;
 111  112  
 112  113  #define LOOPBACK_IF     "lo0"
 113  114  #define SOCKET_AF(af)   (((af) == AF_UNSPEC) ? AF_INET : (af))
 114  115  
↓ open down ↓ 322 lines elided ↑ open up ↑
 437  438  
 438  439          assert(!(verbose && parsable));
 439  440          if (firsttime && verbose) {
 440  441                  firsttime = B_FALSE;
 441  442                  (void) printf("%*s %-16s %-10s %-30s %-8s %-6s\n",
 442  443                      ZONEID_WIDTH, "ID", "NAME", "STATUS", "PATH", "BRAND",
 443  444                      "IP");
 444  445          }
 445  446          if (!verbose) {
 446  447                  char *cp, *clim;
      448 +                char zdid[80];
 447  449  
 448  450                  if (!parsable) {
 449  451                          (void) printf("%s\n", zent->zname);
 450  452                          return;
 451  453                  }
 452  454                  if (zent->zid == ZONE_ID_UNDEFINED)
 453  455                          (void) printf("-");
 454  456                  else
 455  457                          (void) printf("%lu", zent->zid);
 456  458                  (void) printf(":%s:%s:", zent->zname, zent->zstate_str);
 457  459                  cp = zent->zroot;
 458  460                  while ((clim = strchr(cp, ':')) != NULL) {
 459  461                          (void) printf("%.*s\\:", clim - cp, cp);
 460  462                          cp = clim + 1;
 461  463                  }
 462      -                (void) printf("%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand,
 463      -                    ip_type_str);
      464 +                if (zent->zdid == -1)
      465 +                        zdid[0] = '\0';
      466 +                else
      467 +                        (void) snprintf(zdid, sizeof (zdid), "%d", zent->zdid);
      468 +                (void) printf("%s:%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand,
      469 +                    ip_type_str, zdid);
 464  470                  return;
 465  471          }
 466  472          if (zent->zstate_str != NULL) {
 467  473                  if (zent->zid == ZONE_ID_UNDEFINED)
 468  474                          (void) printf("%*s", ZONEID_WIDTH, "-");
 469  475                  else
 470  476                          (void) printf("%*lu", ZONEID_WIDTH, zent->zid);
 471  477                  (void) printf(" %-16s %-10s %-30s %-8s %-6s\n", zent->zname,
 472  478                      zent->zstate_str, zent->zroot, zent->zbrand, ip_type_str);
 473  479          }
↓ open down ↓ 74 lines elided ↑ open up ↑
 548  554  
 549  555          /*
 550  556           * Get ip type of the zone.
 551  557           * Note for global zone, ZS_SHARED is set always.
 552  558           */
 553  559          if (zid == GLOBAL_ZONEID) {
 554  560                  zent->ziptype = ZS_SHARED;
 555  561                  return (Z_OK);
 556  562          }
 557  563  
      564 +        if ((handle = zonecfg_init_handle()) == NULL) {
      565 +                zperror2(zent->zname, gettext("could not init handle"));
      566 +                return (Z_ERR);
      567 +        }
      568 +        if ((err = zonecfg_get_handle(zent->zname, handle)) != Z_OK) {
      569 +                zperror2(zent->zname, gettext("could not get handle"));
      570 +                zonecfg_fini_handle(handle);
      571 +                return (Z_ERR);
      572 +        }
      573 +
      574 +        if ((err = zonecfg_get_iptype(handle, &zent->ziptype)) != Z_OK) {
      575 +                zperror2(zent->zname, gettext("could not get ip-type"));
      576 +                zonecfg_fini_handle(handle);
      577 +                return (Z_ERR);
      578 +        }
      579 +
 558  580          /*
 559  581           * There is a race condition where the zone could boot while
 560  582           * we're walking the index file.  In this case the zone state
 561  583           * could be seen as running from the call above, but the zoneid
 562  584           * would be undefined.
 563  585           *
 564  586           * There is also a race condition where the zone could shutdown after
 565  587           * we got its running state above.  This is also not an error and
 566  588           * we fall back to getting the ziptype from the zone configuration.
 567  589           */
 568  590          if (zent->zstate_num == ZONE_STATE_RUNNING &&
 569  591              zid != ZONE_ID_UNDEFINED) {
 570  592                  ushort_t flags;
 571  593  
 572  594                  if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags,
 573  595                      sizeof (flags)) >= 0) {
 574  596                          if (flags & ZF_NET_EXCL)
 575  597                                  zent->ziptype = ZS_EXCLUSIVE;
 576  598                          else
 577  599                                  zent->ziptype = ZS_SHARED;
 578      -                        return (Z_OK);
 579  600                  }
 580  601          }
 581  602  
 582      -        if ((handle = zonecfg_init_handle()) == NULL) {
 583      -                zperror2(zent->zname, gettext("could not init handle"));
 584      -                return (Z_ERR);
 585      -        }
 586      -        if ((err = zonecfg_get_handle(zent->zname, handle)) != Z_OK) {
 587      -                zperror2(zent->zname, gettext("could not get handle"));
 588      -                zonecfg_fini_handle(handle);
 589      -                return (Z_ERR);
 590      -        }
      603 +        zent->zdid = zonecfg_get_did(handle);
 591  604  
 592      -        if ((err = zonecfg_get_iptype(handle, &zent->ziptype)) != Z_OK) {
 593      -                zperror2(zent->zname, gettext("could not get ip-type"));
 594      -                zonecfg_fini_handle(handle);
 595      -                return (Z_ERR);
 596      -        }
 597  605          zonecfg_fini_handle(handle);
 598  606  
 599  607          return (Z_OK);
 600  608  }
 601  609  
 602  610  /*
 603  611   * fetch_zents() calls zone_list(2) to find out how many zones are running
 604  612   * (which is stored in the global nzents), then calls zone_list(2) again
 605  613   * to fetch the list of running zones (stored in the global zents).  This
 606  614   * function may be called multiple times, so if zents is already set, we
↓ open down ↓ 2174 lines elided ↑ open up ↑
2781 2789           * privileges will be used when this zone is created in the
2782 2790           * kernel.
2783 2791           */
2784 2792          if (!in_alt_root && cmd_num != CMD_MOUNT &&
2785 2793              verify_limitpriv(handle) != Z_OK)
2786 2794                  return_code = Z_ERR;
2787 2795  
2788 2796          return (return_code);
2789 2797  }
2790 2798  
     2799 +/*
     2800 + * Called when readying or booting a zone.  We double check that the zone's
     2801 + * debug ID is set and is unique.  This covers the case of pre-existing zones
     2802 + * with no ID.  Also, its possible that a zone was migrated to this host
     2803 + * and as a result it has a duplicate ID.  In this case we preserve the ID
     2804 + * of the first zone we match on in the index file (since it was there before
     2805 + * the current zone) and we assign a new unique ID to the current zone.
     2806 + * Return true if we assigned a new ID, indicating that the zone configuration
     2807 + * needs to be saved.
     2808 + */
     2809 +static boolean_t
     2810 +verify_fix_did(zone_dochandle_t handle)
     2811 +{
     2812 +        zoneid_t mydid;
     2813 +        zone_entry_t zent;
     2814 +        FILE *cookie;
     2815 +        char *name;
     2816 +        boolean_t fix = B_FALSE;
     2817 +
     2818 +        mydid = zonecfg_get_did(handle);
     2819 +        if (mydid == -1) {
     2820 +                zonecfg_set_did(handle);
     2821 +                return (B_TRUE);
     2822 +        }
     2823 +
     2824 +        /* Get the full list of zones from the configuration. */
     2825 +        cookie = setzoneent();
     2826 +        while ((name = getzoneent(cookie)) != NULL) {
     2827 +                if (strcmp(target_zone, name) == 0) {
     2828 +                        free(name);
     2829 +                        break;  /* Once we find our entry, stop. */
     2830 +                }
     2831 +
     2832 +                if (strcmp(name, "global") == 0 ||
     2833 +                    lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) {
     2834 +                        free(name);
     2835 +                        continue;
     2836 +                }
     2837 +
     2838 +                free(name);
     2839 +                if (zent.zdid == mydid) {
     2840 +                        fix = B_TRUE;
     2841 +                        break;
     2842 +                }
     2843 +        }
     2844 +        endzoneent(cookie);
     2845 +
     2846 +        if (fix) {
     2847 +                zonecfg_set_did(handle);
     2848 +                return (B_TRUE);
     2849 +        }
     2850 +
     2851 +        return (B_FALSE);
     2852 +}
     2853 +
2791 2854  static int
2792 2855  verify_details(int cmd_num, char *argv[])
2793 2856  {
2794 2857          zone_dochandle_t handle;
2795 2858          char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN];
2796 2859          int return_code = Z_OK;
2797 2860          int err;
2798 2861  
2799 2862          if ((handle = zonecfg_init_handle()) == NULL) {
2800 2863                  zperror(cmd_to_str(cmd_num), B_TRUE);
↓ open down ↓ 42 lines elided ↑ open up ↑
2843 2906                      "because of the above errors.\n"), zonepath);
2844 2907                  return_code = Z_ERR;
2845 2908          }
2846 2909  
2847 2910          if (verify_handle(cmd_num, handle, argv) != Z_OK)
2848 2911                  return_code = Z_ERR;
2849 2912  
2850 2913          if (cmd_num == CMD_READY || cmd_num == CMD_BOOT) {
2851 2914                  int vcommit = 0, obscommit = 0;
2852 2915  
2853      -#if 0 /* XXX KEBE not yet */
2854 2916                  vcommit = verify_fix_did(handle);
2855      -#endif /* XXX KEBE not yet */
2856 2917                  obscommit = zonecfg_fix_obsolete(handle);
2857 2918  
2858 2919                  if (vcommit || obscommit)
2859 2920                          if (zonecfg_save(handle) != Z_OK)
2860 2921                                  (void) fprintf(stderr, gettext("Could not save "
2861 2922                                      "updated configuration.\n"));
2862 2923          }
2863 2924  
2864 2925          zonecfg_fini_handle(handle);
2865 2926          if (return_code == Z_ERR)
↓ open down ↓ 2943 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX