Print this page


Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/zoneadm/zoneadm.c
          +++ new/usr/src/cmd/zoneadm/zoneadm.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
  25      - * Copyright 2015, Joyent Inc. All rights reserved.
  26   25   * Copyright (c) 2015 by Delphix. All rights reserved.
       26 + * Copyright 2015, Joyent Inc. All rights reserved.
  27   27   */
  28   28  
  29   29  /*
  30   30   * zoneadm is a command interpreter for zone administration.  It is all in
  31   31   * C (i.e., no lex/yacc), and all the argument passing is argc/argv based.
  32   32   * main() calls parse_and_run() which calls cmd_match(), then invokes the
  33   33   * appropriate command's handler function.  The rest of the program is the
  34   34   * handler functions and their helper functions.
  35   35   *
  36   36   * Some of the helper functions are used largely to simplify I18N: reducing
↓ open down ↓ 63 lines elided ↑ open up ↑
 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  105          zoneid_t        zdid;
 106  106  } zone_entry_t;
 107  107  
 108  108  #define CLUSTER_BRAND_NAME      "cluster"
 109  109  
      110 +static zone_entry_t *zents;
      111 +static size_t nzents;
      112 +
 110  113  #define LOOPBACK_IF     "lo0"
 111  114  #define SOCKET_AF(af)   (((af) == AF_UNSPEC) ? AF_INET : (af))
 112  115  
 113  116  struct net_if {
 114  117          char    *name;
 115  118          int     af;
 116  119  };
 117  120  
 118  121  /* 0755 is the default directory mode. */
 119  122  #define DEFAULT_DIR_MODE \
↓ open down ↓ 278 lines elided ↑ open up ↑
 398  401  
 399  402          va_start(alist, fmt);
 400  403          (void) fprintf(stderr, "%s: ", execname);
 401  404          if (target_zone != NULL)
 402  405                  (void) fprintf(stderr, "zone '%s': ", target_zone);
 403  406          (void) vfprintf(stderr, fmt, alist);
 404  407          (void) fprintf(stderr, "\n");
 405  408          va_end(alist);
 406  409  }
 407  410  
      411 +static void *
      412 +safe_calloc(size_t nelem, size_t elsize)
      413 +{
      414 +        void *r = calloc(nelem, elsize);
      415 +
      416 +        if (r == NULL) {
      417 +                zerror(gettext("failed to allocate %lu bytes: %s"),
      418 +                    (ulong_t)nelem * elsize, strerror(errno));
      419 +                exit(Z_ERR);
      420 +        }
      421 +        return (r);
      422 +}
      423 +
 408  424  static void
 409  425  zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable)
 410  426  {
 411  427          static boolean_t firsttime = B_TRUE;
 412  428          char *ip_type_str;
 413  429  
 414  430          /* Skip a zone that shutdown while we were collecting data. */
 415  431          if (zent->zname[0] == '\0')
 416  432                  return;
 417  433  
↓ open down ↓ 51 lines elided ↑ open up ↑
 469  485          char root[MAXPATHLEN], *cp;
 470  486          int err;
 471  487          uuid_t uuid;
 472  488          zone_dochandle_t handle;
 473  489  
 474  490          (void) strlcpy(zent->zname, zone_name, sizeof (zent->zname));
 475  491          (void) strlcpy(zent->zroot, "???", sizeof (zent->zroot));
 476  492          (void) strlcpy(zent->zbrand, "???", sizeof (zent->zbrand));
 477  493          zent->zstate_str = "???";
 478  494  
 479      -        if (strcmp(zone_name, GLOBAL_ZONENAME) == 0)
 480      -                zid = zent->zdid = GLOBAL_ZONEID;
 481      -
 482  495          zent->zid = zid;
 483  496  
 484  497          if (zonecfg_get_uuid(zone_name, uuid) == Z_OK &&
 485  498              !uuid_is_null(uuid))
 486  499                  uuid_unparse(uuid, zent->zuuid);
 487  500          else
 488  501                  zent->zuuid[0] = '\0';
 489  502  
 490  503          /*
 491  504           * For labeled zones which query the zone path of lower-level
↓ open down ↓ 24 lines elided ↑ open up ↑
 516  529          }
 517  530  
 518  531          if ((err = zone_get_state(zent->zname, &zent->zstate_num)) != Z_OK) {
 519  532                  errno = err;
 520  533                  zperror2(zent->zname, gettext("could not get state"));
 521  534                  return (Z_ERR);
 522  535          }
 523  536          zent->zstate_str = zone_state_str(zent->zstate_num);
 524  537  
 525  538          /*
 526      -         * A zone's brand might only be available in the .xml file describing
 527      -         * it, which is only visible to the global zone.  This causes
      539 +         * A zone's brand is only available in the .xml file describing it,
      540 +         * which is only visible to the global zone.  This causes
 528  541           * zone_get_brand() to fail when called from within a non-global
 529  542           * zone.  Fortunately we only do this on labeled systems, where we
 530  543           * know all zones are native.
 531  544           */
 532  545          if (getzoneid() != GLOBAL_ZONEID) {
 533  546                  assert(is_system_labeled() != 0);
 534  547                  (void) strlcpy(zent->zbrand, default_brand,
 535  548                      sizeof (zent->zbrand));
 536  549          } else if (zone_get_brand(zent->zname, zent->zbrand,
 537  550              sizeof (zent->zbrand)) != Z_OK) {
↓ open down ↓ 49 lines elided ↑ open up ↑
 587  600                  }
 588  601          }
 589  602  
 590  603          zent->zdid = zonecfg_get_did(handle);
 591  604  
 592  605          zonecfg_fini_handle(handle);
 593  606  
 594  607          return (Z_OK);
 595  608  }
 596  609  
      610 +/*
      611 + * fetch_zents() calls zone_list(2) to find out how many zones are running
      612 + * (which is stored in the global nzents), then calls zone_list(2) again
      613 + * to fetch the list of running zones (stored in the global zents).  This
      614 + * function may be called multiple times, so if zents is already set, we
      615 + * return immediately to save work.
      616 + *
      617 + * Note that the data about running zones can change while this function
      618 + * is running, so its possible that the list of zones will have empty slots
      619 + * at the end.
      620 + */
      621 +
 597  622  static int
 598      -zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable)
      623 +fetch_zents(void)
 599  624  {
 600      -        zone_entry_t zent;
 601      -        FILE *cookie;
 602      -        struct zoneent *ze;
      625 +        zoneid_t *zids = NULL;
      626 +        uint_t nzents_saved;
      627 +        int i, retv;
      628 +        FILE *fp;
      629 +        boolean_t inaltroot;
      630 +        zone_entry_t *zentp;
      631 +        const char *altroot;
 603  632  
 604      -        /*
 605      -         * Get the full list of zones from the configuration.
 606      -         */
 607      -        cookie = setzoneent();
 608      -        while ((ze = getzoneent_private(cookie)) != NULL) {
 609      -                char *name = ze->zone_name;
 610      -                zoneid_t zid;
      633 +        if (nzents > 0)
      634 +                return (Z_OK);
 611  635  
 612      -                zid = getzoneidbyname(name);
      636 +        if (zone_list(NULL, &nzents) != 0) {
      637 +                zperror(gettext("failed to get zoneid list"), B_FALSE);
      638 +                return (Z_ERR);
      639 +        }
 613  640  
 614      -                if (ze->zone_brand[0] == '\0') {
 615      -                        /* old, incomplete index entry */
 616      -                        if (lookup_zone_info(name, zid, &zent) != Z_OK) {
 617      -                                free(ze);
      641 +again:
      642 +        if (nzents == 0)
      643 +                return (Z_OK);
      644 +
      645 +        zids = safe_calloc(nzents, sizeof (zoneid_t));
      646 +        nzents_saved = nzents;
      647 +
      648 +        if (zone_list(zids, &nzents) != 0) {
      649 +                zperror(gettext("failed to get zone list"), B_FALSE);
      650 +                free(zids);
      651 +                return (Z_ERR);
      652 +        }
      653 +        if (nzents != nzents_saved) {
      654 +                /* list changed, try again */
      655 +                free(zids);
      656 +                goto again;
      657 +        }
      658 +
      659 +        zents = safe_calloc(nzents, sizeof (zone_entry_t));
      660 +
      661 +        inaltroot = zonecfg_in_alt_root();
      662 +        if (inaltroot) {
      663 +                fp = zonecfg_open_scratch("", B_FALSE);
      664 +                altroot = zonecfg_get_root();
      665 +        } else {
      666 +                fp = NULL;
      667 +        }
      668 +        zentp = zents;
      669 +        retv = Z_OK;
      670 +        for (i = 0; i < nzents; i++) {
      671 +                char name[ZONENAME_MAX];
      672 +                char altname[ZONENAME_MAX];
      673 +                char rev_altroot[MAXPATHLEN];
      674 +
      675 +                if (getzonenamebyid(zids[i], name, sizeof (name)) < 0) {
      676 +                        /*
      677 +                         * There is a race condition where the zone may have
      678 +                         * shutdown since we retrieved the number of running
      679 +                         * zones above.  This is not an error, there will be
      680 +                         * an empty slot at the end of the list.
      681 +                         */
      682 +                        continue;
      683 +                }
      684 +                if (zonecfg_is_scratch(name)) {
      685 +                        /* Ignore scratch zones by default */
      686 +                        if (!inaltroot)
 618  687                                  continue;
      688 +                        if (fp == NULL ||
      689 +                            zonecfg_reverse_scratch(fp, name, altname,
      690 +                            sizeof (altname), rev_altroot,
      691 +                            sizeof (rev_altroot)) == -1) {
      692 +                                zerror(gettext("could not resolve scratch "
      693 +                                    "zone %s"), name);
      694 +                                retv = Z_ERR;
      695 +                                continue;
 619  696                          }
      697 +                        /* Ignore zones in other alternate roots */
      698 +                        if (strcmp(rev_altroot, altroot) != 0)
      699 +                                continue;
      700 +                        (void) strcpy(name, altname);
 620  701                  } else {
 621      -                        /* new, full index entry */
 622      -                        (void) strlcpy(zent.zname, name, sizeof (zent.zname));
 623      -                        (void) strlcpy(zent.zroot, ze->zone_path,
 624      -                            sizeof (zent.zroot));
 625      -                        uuid_unparse(ze->zone_uuid, zent.zuuid);
 626      -                        (void) strlcpy(zent.zbrand, ze->zone_brand,
 627      -                            sizeof (zent.zbrand));
 628      -                        zent.ziptype = ze->zone_iptype;
 629      -                        zent.zdid = ze->zone_did;
 630      -                        zent.zid = zid;
      702 +                        /* Ignore non-scratch when in an alternate root */
      703 +                        if (inaltroot && strcmp(name, GLOBAL_ZONENAME) != 0)
      704 +                                continue;
      705 +                }
      706 +                if (lookup_zone_info(name, zids[i], zentp) != Z_OK) {
      707 +                        /*
      708 +                         * There is a race condition where the zone may have
      709 +                         * shutdown since we retrieved the number of running
      710 +                         * zones above.  This is not an error, there will be
      711 +                         * an empty slot at the end of the list.
      712 +                         */
      713 +                        continue;
      714 +                }
      715 +                zentp++;
      716 +        }
      717 +        nzents = zentp - zents;
      718 +        if (fp != NULL)
      719 +                zonecfg_close_scratch(fp);
 631  720  
 632      -                        if (zid != -1) {
 633      -                                int err;
      721 +        free(zids);
      722 +        return (retv);
      723 +}
 634  724  
 635      -                                err = zone_get_state(name,
 636      -                                    (zone_state_t *)&ze->zone_state);
 637      -                                if (err != Z_OK) {
 638      -                                        errno = err;
 639      -                                        zperror2(name, gettext("could not get "
 640      -                                            "state"));
 641      -                                        free(ze);
 642      -                                        continue;
 643      -                                }
 644      -                        }
      725 +static int
      726 +zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable)
      727 +{
      728 +        int i;
      729 +        zone_entry_t zent;
      730 +        FILE *cookie;
      731 +        char *name;
 645  732  
 646      -                        zent.zstate_num = ze->zone_state;
 647      -                        zent.zstate_str = zone_state_str(zent.zstate_num);
      733 +        /*
      734 +         * First get the list of running zones from the kernel and print them.
      735 +         * If that is all we need, then return.
      736 +         */
      737 +        if ((i = fetch_zents()) != Z_OK) {
      738 +                /*
      739 +                 * No need for error messages; fetch_zents() has already taken
      740 +                 * care of this.
      741 +                 */
      742 +                return (i);
      743 +        }
      744 +        for (i = 0; i < nzents; i++)
      745 +                zone_print(&zents[i], verbose, parsable);
      746 +        if (min_state >= ZONE_STATE_RUNNING)
      747 +                return (Z_OK);
      748 +        /*
      749 +         * Next, get the full list of zones from the configuration, skipping
      750 +         * any we have already printed.
      751 +         */
      752 +        cookie = setzoneent();
      753 +        while ((name = getzoneent(cookie)) != NULL) {
      754 +                for (i = 0; i < nzents; i++) {
      755 +                        if (strcmp(zents[i].zname, name) == 0)
      756 +                                break;
 648  757                  }
 649      -
      758 +                if (i < nzents) {
      759 +                        free(name);
      760 +                        continue;
      761 +                }
      762 +                if (lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) {
      763 +                        free(name);
      764 +                        continue;
      765 +                }
      766 +                free(name);
 650  767                  if (zent.zstate_num >= min_state)
 651  768                          zone_print(&zent, verbose, parsable);
 652      -
 653      -                free(ze);
 654  769          }
 655  770          endzoneent(cookie);
 656  771          return (Z_OK);
 657  772  }
 658  773  
 659  774  /*
 660  775   * Retrieve a zone entry by name.  Returns NULL if no such zone exists.
 661  776   */
 662  777  static zone_entry_t *
 663  778  lookup_running_zone(const char *name)
↓ open down ↓ 240 lines elided ↑ open up ↑
 904 1019          }
 905 1020          if (!S_ISDIR(stbuf.st_mode)) {
 906 1021                  (void) fprintf(stderr, gettext("%s is not a directory.\n"),
 907 1022                      rpath);
 908 1023                  return (Z_ERR);
 909 1024          }
 910 1025          if (strcmp(stbuf.st_fstype, MNTTYPE_TMPFS) == 0) {
 911 1026                  (void) printf(gettext("WARNING: %s is on a temporary "
 912 1027                      "file system.\n"), rpath);
 913 1028          }
 914      -        if (cmd_num != CMD_BOOT && cmd_num != CMD_REBOOT &&
 915      -            cmd_num != CMD_READY) {
 916      -                /* we checked when we installed, no need to check each boot */
 917      -                if (crosscheck_zonepaths(rpath) != Z_OK)
 918      -                        return (Z_ERR);
 919      -        }
     1029 +        if (crosscheck_zonepaths(rpath) != Z_OK)
     1030 +                return (Z_ERR);
 920 1031          /*
 921 1032           * Try to collect and report as many minor errors as possible
 922 1033           * before returning, so the user can learn everything that needs
 923 1034           * to be fixed up front.
 924 1035           */
 925 1036          if (stbuf.st_uid != 0) {
 926 1037                  (void) fprintf(stderr, gettext("%s is not owned by root.\n"),
 927 1038                      rpath);
 928 1039                  err = B_TRUE;
 929 1040  
↓ open down ↓ 166 lines elided ↑ open up ↑
1096 1207                  return (Z_ERR);
1097 1208          }
1098 1209          zonecfg_fini_handle(handle);
1099 1210          return (Z_OK);
1100 1211  }
1101 1212  
1102 1213  static int
1103 1214  ready_func(int argc, char *argv[])
1104 1215  {
1105 1216          zone_cmd_arg_t zarg;
1106      -        boolean_t debug = B_FALSE;
1107 1217          int arg;
1108 1218  
1109 1219          if (zonecfg_in_alt_root()) {
1110 1220                  zerror(gettext("cannot ready zone in alternate root"));
1111 1221                  return (Z_ERR);
1112 1222          }
1113 1223  
1114 1224          optind = 0;
1115      -        if ((arg = getopt(argc, argv, "?X")) != EOF) {
     1225 +        if ((arg = getopt(argc, argv, "?")) != EOF) {
1116 1226                  switch (arg) {
1117 1227                  case '?':
1118 1228                          sub_usage(SHELP_READY, CMD_READY);
1119 1229                          return (optopt == '?' ? Z_OK : Z_USAGE);
1120      -                case 'X':
1121      -                        debug = B_TRUE;
1122      -                        break;
1123 1230                  default:
1124 1231                          sub_usage(SHELP_READY, CMD_READY);
1125 1232                          return (Z_USAGE);
1126 1233                  }
1127 1234          }
1128 1235          if (argc > optind) {
1129 1236                  sub_usage(SHELP_READY, CMD_READY);
1130 1237                  return (Z_USAGE);
1131 1238          }
1132 1239          if (sanity_check(target_zone, CMD_READY, B_FALSE, B_FALSE, B_FALSE)
1133 1240              != Z_OK)
1134 1241                  return (Z_ERR);
1135 1242          if (verify_details(CMD_READY, argv) != Z_OK)
1136 1243                  return (Z_ERR);
1137 1244  
1138 1245          zarg.cmd = Z_READY;
1139      -        zarg.debug = debug;
1140 1246          if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
1141 1247                  zerror(gettext("call to %s failed"), "zoneadmd");
1142 1248                  return (Z_ERR);
1143 1249          }
1144 1250          return (Z_OK);
1145 1251  }
1146 1252  
1147 1253  static int
1148 1254  boot_func(int argc, char *argv[])
1149 1255  {
1150 1256          zone_cmd_arg_t zarg;
1151 1257          boolean_t force = B_FALSE;
1152      -        boolean_t debug = B_FALSE;
1153 1258          int arg;
1154 1259  
1155 1260          if (zonecfg_in_alt_root()) {
1156 1261                  zerror(gettext("cannot boot zone in alternate root"));
1157 1262                  return (Z_ERR);
1158 1263          }
1159 1264  
1160 1265          zarg.bootbuf[0] = '\0';
1161 1266  
1162 1267          /*
↓ open down ↓ 6 lines elided ↑ open up ↑
1169 1274           * and print usage), -f (a private option to indicate that the
1170 1275           * boot operation should be 'forced'), or -s.  Support for -s is
1171 1276           * vestigal and obsolete, but is retained because it was a
1172 1277           * documented interface and there are known consumers including
1173 1278           * admin/install; the proper way to specify boot arguments like -s
1174 1279           * is:
1175 1280           *
1176 1281           *      zoneadm -z myzone boot -- -s -v -m verbose.
1177 1282           */
1178 1283          optind = 0;
1179      -        while ((arg = getopt(argc, argv, "?fsX")) != EOF) {
     1284 +        while ((arg = getopt(argc, argv, "?fs")) != EOF) {
1180 1285                  switch (arg) {
1181 1286                  case '?':
1182 1287                          sub_usage(SHELP_BOOT, CMD_BOOT);
1183 1288                          return (optopt == '?' ? Z_OK : Z_USAGE);
1184 1289                  case 's':
1185 1290                          (void) strlcpy(zarg.bootbuf, "-s",
1186 1291                              sizeof (zarg.bootbuf));
1187 1292                          break;
1188 1293                  case 'f':
1189 1294                          force = B_TRUE;
1190 1295                          break;
1191      -                case 'X':
1192      -                        debug = B_TRUE;
1193      -                        break;
1194 1296                  default:
1195 1297                          sub_usage(SHELP_BOOT, CMD_BOOT);
1196 1298                          return (Z_USAGE);
1197 1299                  }
1198 1300          }
1199 1301  
1200 1302          for (; optind < argc; optind++) {
1201 1303                  if (strlcat(zarg.bootbuf, argv[optind],
1202 1304                      sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) {
1203 1305                          zerror(gettext("Boot argument list too long"));
↓ open down ↓ 5 lines elided ↑ open up ↑
1209 1311                                  zerror(gettext("Boot argument list too long"));
1210 1312                                  return (Z_ERR);
1211 1313                          }
1212 1314          }
1213 1315          if (sanity_check(target_zone, CMD_BOOT, B_FALSE, B_FALSE, force)
1214 1316              != Z_OK)
1215 1317                  return (Z_ERR);
1216 1318          if (verify_details(CMD_BOOT, argv) != Z_OK)
1217 1319                  return (Z_ERR);
1218 1320          zarg.cmd = force ? Z_FORCEBOOT : Z_BOOT;
1219      -        zarg.debug = debug;
1220 1321          if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
1221 1322                  zerror(gettext("call to %s failed"), "zoneadmd");
1222 1323                  return (Z_ERR);
1223 1324          }
1224 1325  
1225 1326          return (Z_OK);
1226 1327  }
1227 1328  
1228 1329  static void
1229 1330  fake_up_local_zone(zoneid_t zid, zone_entry_t *zeptr)
↓ open down ↓ 289 lines elided ↑ open up ↑
1519 1620   * 1. We're in the global zone.
1520 1621   * 2. The calling user has sufficient privilege.
1521 1622   * 3. The target zone is neither the global zone nor anything starting with
1522 1623   *    "SUNW".
1523 1624   * 4a. If we're looking for a 'not running' (i.e., configured or installed)
1524 1625   *     zone, the name service knows about it.
1525 1626   * 4b. For some operations which expect a zone not to be running, that it is
1526 1627   *     not already running (or ready).
1527 1628   */
1528 1629  static int
1529      -sanity_check(char *zone, int cmd_num, boolean_t need_running,
     1630 +sanity_check(char *zone, int cmd_num, boolean_t running,
1530 1631      boolean_t unsafe_when_running, boolean_t force)
1531 1632  {
1532      -        boolean_t is_running = B_FALSE;
     1633 +        zone_entry_t *zent;
1533 1634          priv_set_t *privset;
1534 1635          zone_state_t state, min_state;
1535 1636          char kernzone[ZONENAME_MAX];
1536 1637          FILE *fp;
1537 1638  
1538 1639          if (getzoneid() != GLOBAL_ZONEID) {
1539 1640                  switch (cmd_num) {
1540 1641                  case CMD_HALT:
1541 1642                          zerror(gettext("use %s to %s this zone."), "halt(1M)",
1542 1643                              cmd_to_str(cmd_num));
↓ open down ↓ 50 lines elided ↑ open up ↑
1593 1694                  return (Z_ERR);
1594 1695          }
1595 1696  
1596 1697          if (strncmp(zone, "SUNW", 4) == 0) {
1597 1698                  zerror(gettext("%s operation is invalid for zones starting "
1598 1699                      "with SUNW."), cmd_to_str(cmd_num));
1599 1700                  return (Z_ERR);
1600 1701          }
1601 1702  
1602 1703          if (!zonecfg_in_alt_root()) {
1603      -                /* Avoid the xml read overhead of lookup_running_zone */
1604      -                if (getzoneidbyname(zone) != -1)
1605      -                        is_running = B_TRUE;
1606      -
1607      -        } else if ((fp = zonecfg_open_scratch("", B_FALSE)) != NULL) {
1608      -                if (zonecfg_find_scratch(fp, zone, zonecfg_get_root(), kernzone,
1609      -                    sizeof (kernzone)) == 0 && getzoneidbyname(kernzone) != -1)
1610      -                        is_running = B_TRUE;
1611      -
     1704 +                zent = lookup_running_zone(zone);
     1705 +        } else if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) {
     1706 +                zent = NULL;
     1707 +        } else {
     1708 +                if (zonecfg_find_scratch(fp, zone, zonecfg_get_root(),
     1709 +                    kernzone, sizeof (kernzone)) == 0)
     1710 +                        zent = lookup_running_zone(kernzone);
     1711 +                else
     1712 +                        zent = NULL;
1612 1713                  zonecfg_close_scratch(fp);
1613 1714          }
1614 1715  
1615 1716          /*
1616 1717           * Look up from the kernel for 'running' zones.
1617 1718           */
1618      -        if (need_running && !force) {
1619      -                if (!is_running) {
     1719 +        if (running && !force) {
     1720 +                if (zent == NULL) {
1620 1721                          zerror(gettext("not running"));
1621 1722                          return (Z_ERR);
1622 1723                  }
1623 1724          } else {
1624 1725                  int err;
1625 1726  
1626      -                err = zone_get_state(zone, &state);
1627      -
1628      -                if (unsafe_when_running && is_running) {
     1727 +                if (unsafe_when_running && zent != NULL) {
1629 1728                          /* check whether the zone is ready or running */
1630      -                        char *zstate_str;
1631      -
1632      -                        if (err != Z_OK) {
     1729 +                        if ((err = zone_get_state(zent->zname,
     1730 +                            &zent->zstate_num)) != Z_OK) {
1633 1731                                  errno = err;
1634      -                                zperror2(zone, gettext("could not get state"));
     1732 +                                zperror2(zent->zname,
     1733 +                                    gettext("could not get state"));
1635 1734                                  /* can't tell, so hedge */
1636      -                                zstate_str = "ready/running";
     1735 +                                zent->zstate_str = "ready/running";
1637 1736                          } else {
1638      -                                zstate_str = zone_state_str(state);
     1737 +                                zent->zstate_str =
     1738 +                                    zone_state_str(zent->zstate_num);
1639 1739                          }
1640 1740                          zerror(gettext("%s operation is invalid for %s zones."),
1641      -                            cmd_to_str(cmd_num), zstate_str);
     1741 +                            cmd_to_str(cmd_num), zent->zstate_str);
1642 1742                          return (Z_ERR);
1643 1743                  }
1644      -
1645      -                if (err != Z_OK) {
     1744 +                if ((err = zone_get_state(zone, &state)) != Z_OK) {
1646 1745                          errno = err;
1647 1746                          zperror2(zone, gettext("could not get state"));
1648 1747                          return (Z_ERR);
1649 1748                  }
1650      -
1651 1749                  switch (cmd_num) {
1652 1750                  case CMD_UNINSTALL:
1653 1751                          if (state == ZONE_STATE_CONFIGURED) {
1654 1752                                  zerror(gettext("is already in state '%s'."),
1655 1753                                      zone_state_str(ZONE_STATE_CONFIGURED));
1656 1754                                  return (Z_ERR);
1657 1755                          }
1658 1756                          break;
1659 1757                  case CMD_ATTACH:
1660 1758                          if (state == ZONE_STATE_INSTALLED) {
↓ open down ↓ 67 lines elided ↑ open up ↑
1728 1826                          break;
1729 1827                  }
1730 1828          }
1731 1829          return (Z_OK);
1732 1830  }
1733 1831  
1734 1832  static int
1735 1833  halt_func(int argc, char *argv[])
1736 1834  {
1737 1835          zone_cmd_arg_t zarg;
1738      -        boolean_t debug = B_FALSE;
1739 1836          int arg;
1740 1837  
1741 1838          if (zonecfg_in_alt_root()) {
1742 1839                  zerror(gettext("cannot halt zone in alternate root"));
1743 1840                  return (Z_ERR);
1744 1841          }
1745 1842  
1746 1843          optind = 0;
1747      -        if ((arg = getopt(argc, argv, "?X")) != EOF) {
     1844 +        if ((arg = getopt(argc, argv, "?")) != EOF) {
1748 1845                  switch (arg) {
1749 1846                  case '?':
1750 1847                          sub_usage(SHELP_HALT, CMD_HALT);
1751 1848                          return (optopt == '?' ? Z_OK : Z_USAGE);
1752      -                case 'X':
1753      -                        debug = B_TRUE;
1754      -                        break;
1755 1849                  default:
1756 1850                          sub_usage(SHELP_HALT, CMD_HALT);
1757 1851                          return (Z_USAGE);
1758 1852                  }
1759 1853          }
1760 1854          if (argc > optind) {
1761 1855                  sub_usage(SHELP_HALT, CMD_HALT);
1762 1856                  return (Z_USAGE);
1763 1857          }
1764 1858          /*
↓ open down ↓ 5 lines elided ↑ open up ↑
1770 1864              != Z_OK)
1771 1865                  return (Z_ERR);
1772 1866  
1773 1867          /*
1774 1868           * Invoke brand-specific handler.
1775 1869           */
1776 1870          if (invoke_brand_handler(CMD_HALT, argv) != Z_OK)
1777 1871                  return (Z_ERR);
1778 1872  
1779 1873          zarg.cmd = Z_HALT;
1780      -        zarg.debug = debug;
1781 1874          return ((zonecfg_call_zoneadmd(target_zone, &zarg, locale,
1782 1875              B_TRUE) == 0) ?  Z_OK : Z_ERR);
1783 1876  }
1784 1877  
1785 1878  static int
1786 1879  shutdown_func(int argc, char *argv[])
1787 1880  {
1788 1881          zone_cmd_arg_t zarg;
1789 1882          int arg;
1790 1883          boolean_t reboot = B_FALSE;
↓ open down ↓ 57 lines elided ↑ open up ↑
1848 1941                      B_TRUE) != Z_OK)
1849 1942                          return (Z_ERR);
1850 1943          }
1851 1944          return (Z_OK);
1852 1945  }
1853 1946  
1854 1947  static int
1855 1948  reboot_func(int argc, char *argv[])
1856 1949  {
1857 1950          zone_cmd_arg_t zarg;
1858      -        boolean_t debug = B_FALSE;
1859 1951          int arg;
1860 1952  
1861 1953          if (zonecfg_in_alt_root()) {
1862 1954                  zerror(gettext("cannot reboot zone in alternate root"));
1863 1955                  return (Z_ERR);
1864 1956          }
1865 1957  
1866 1958          optind = 0;
1867      -        if ((arg = getopt(argc, argv, "?X")) != EOF) {
     1959 +        if ((arg = getopt(argc, argv, "?")) != EOF) {
1868 1960                  switch (arg) {
1869 1961                  case '?':
1870 1962                          sub_usage(SHELP_REBOOT, CMD_REBOOT);
1871 1963                          return (optopt == '?' ? Z_OK : Z_USAGE);
1872      -                case 'X':
1873      -                        debug = B_TRUE;
1874      -                        break;
1875 1964                  default:
1876 1965                          sub_usage(SHELP_REBOOT, CMD_REBOOT);
1877 1966                          return (Z_USAGE);
1878 1967                  }
1879 1968          }
1880 1969  
1881 1970          zarg.bootbuf[0] = '\0';
1882 1971          for (; optind < argc; optind++) {
1883 1972                  if (strlcat(zarg.bootbuf, argv[optind],
1884 1973                      sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) {
↓ open down ↓ 14 lines elided ↑ open up ↑
1899 1988           * so even though it seems that the fourth parameter below should
1900 1989           * perhaps be B_TRUE, it really shouldn't be.
1901 1990           */
1902 1991          if (sanity_check(target_zone, CMD_REBOOT, B_TRUE, B_FALSE, B_FALSE)
1903 1992              != Z_OK)
1904 1993                  return (Z_ERR);
1905 1994          if (verify_details(CMD_REBOOT, argv) != Z_OK)
1906 1995                  return (Z_ERR);
1907 1996  
1908 1997          zarg.cmd = Z_REBOOT;
1909      -        zarg.debug = debug;
1910 1998          return ((zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) == 0)
1911 1999              ? Z_OK : Z_ERR);
1912 2000  }
1913 2001  
1914 2002  static int
1915 2003  get_hook(brand_handle_t bh, char *cmd, size_t len, int (*bp)(brand_handle_t,
1916 2004      const char *, const char *, char *, size_t), char *zonename, char *zonepath)
1917 2005  {
1918 2006          if (strlcpy(cmd, EXEC_PREFIX, len) >= len)
1919 2007                  return (Z_ERR);
↓ open down ↓ 207 lines elided ↑ open up ↑
2127 2215           * This validation is really intended for standard zone administration.
2128 2216           * If we are in a mini-root or some other upgrade situation where
2129 2217           * we are using the scratch zone, just by-pass this.
2130 2218           */
2131 2219          if (zonecfg_in_alt_root())
2132 2220                  return (Z_OK);
2133 2221  
2134 2222          if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0)
2135 2223                  return (verify_fs_zfs(fstab));
2136 2224  
2137      -        if (strcmp(fstab->zone_fs_type, MNTTYPE_HYPRLOFS) == 0 &&
2138      -            strcmp(fstab->zone_fs_special, "swap") == 0)
2139      -                        return (Z_OK);
2140      -
2141 2225          if (stat64(fstab->zone_fs_special, &st) != 0) {
2142 2226                  (void) fprintf(stderr, gettext("could not verify fs "
2143 2227                      "%s: could not access %s: %s\n"), fstab->zone_fs_dir,
2144 2228                      fstab->zone_fs_special, strerror(errno));
2145 2229                  return (Z_ERR);
2146 2230          }
2147 2231  
2148 2232          if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) {
2149 2233                  /*
2150 2234                   * TRANSLATION_NOTE
↓ open down ↓ 383 lines elided ↑ open up ↑
2534 2618  verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[])
2535 2619  {
2536 2620          struct zone_nwiftab nwiftab;
2537 2621          int return_code = Z_OK;
2538 2622          int err;
2539 2623          boolean_t in_alt_root;
2540 2624          zone_iptype_t iptype;
2541 2625          dladm_handle_t dh;
2542 2626          dladm_status_t status;
2543 2627          datalink_id_t linkid;
     2628 +        char errmsg[DLADM_STRSIZE];
2544 2629  
2545 2630          in_alt_root = zonecfg_in_alt_root();
2546 2631          if (in_alt_root)
2547 2632                  goto no_net;
2548 2633  
2549 2634          if ((err = zonecfg_get_iptype(handle, &iptype)) != Z_OK) {
2550 2635                  errno = err;
2551 2636                  zperror(cmd_to_str(cmd_num), B_TRUE);
2552 2637                  zonecfg_fini_handle(handle);
2553 2638                  return (Z_ERR);
↓ open down ↓ 62 lines elided ↑ open up ↑
2616 2701                           * Verify that the datalink exists and that it isn't
2617 2702                           * already assigned to a zone.
2618 2703                           */
2619 2704                          if ((status = dladm_open(&dh)) == DLADM_STATUS_OK) {
2620 2705                                  status = dladm_name2info(dh,
2621 2706                                      nwiftab.zone_nwif_physical, &linkid, NULL,
2622 2707                                      NULL, NULL);
2623 2708                                  dladm_close(dh);
2624 2709                          }
2625 2710                          if (status != DLADM_STATUS_OK) {
     2711 +                                (void) fprintf(stderr,
     2712 +                                    gettext("WARNING: skipping network "
     2713 +                                    "interface '%s': %s\n"),
     2714 +                                    nwiftab.zone_nwif_physical,
     2715 +                                    dladm_status2str(status, errmsg));
2626 2716                                  break;
2627 2717                          }
2628 2718                          dl_owner_zid = ALL_ZONES;
2629 2719                          if (zone_check_datalink(&dl_owner_zid, linkid) != 0)
2630 2720                                  break;
2631 2721  
2632 2722                          /*
2633 2723                           * If the zone being verified is
2634 2724                           * running and owns the interface
2635 2725                           */
↓ open down ↓ 77 lines elided ↑ open up ↑
2713 2803   * and as a result it has a duplicate ID.  In this case we preserve the ID
2714 2804   * of the first zone we match on in the index file (since it was there before
2715 2805   * the current zone) and we assign a new unique ID to the current zone.
2716 2806   * Return true if we assigned a new ID, indicating that the zone configuration
2717 2807   * needs to be saved.
2718 2808   */
2719 2809  static boolean_t
2720 2810  verify_fix_did(zone_dochandle_t handle)
2721 2811  {
2722 2812          zoneid_t mydid;
2723      -        struct zoneent *ze;
     2813 +        zone_entry_t zent;
2724 2814          FILE *cookie;
     2815 +        char *name;
2725 2816          boolean_t fix = B_FALSE;
2726 2817  
2727 2818          mydid = zonecfg_get_did(handle);
2728 2819          if (mydid == -1) {
2729 2820                  zonecfg_set_did(handle);
2730 2821                  return (B_TRUE);
2731 2822          }
2732 2823  
2733 2824          /* Get the full list of zones from the configuration. */
2734 2825          cookie = setzoneent();
2735      -        while ((ze = getzoneent_private(cookie)) != NULL) {
2736      -                char *name;
2737      -                zoneid_t did;
     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 +                }
2738 2831  
2739      -                name = ze->zone_name;
2740      -                if (strcmp(name, GLOBAL_ZONENAME) == 0 ||
2741      -                    strcmp(name, target_zone) == 0) {
2742      -                        free(ze);
     2832 +                if (strcmp(name, "global") == 0 ||
     2833 +                    lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) {
     2834 +                        free(name);
2743 2835                          continue;
2744 2836                  }
2745 2837  
2746      -                if (ze->zone_brand[0] == '\0') {
2747      -                        /* old, incomplete index entry */
2748      -                        zone_entry_t zent;
2749      -
2750      -                        if (lookup_zone_info(name, ZONE_ID_UNDEFINED,
2751      -                            &zent) != Z_OK) {
2752      -                                free(ze);
2753      -                                continue;
2754      -                        }
2755      -                        did = zent.zdid;
2756      -                } else {
2757      -                        /* new, full index entry */
2758      -                        did = ze->zone_did;
2759      -                }
2760      -                free(ze);
2761      -
2762      -                if (did == mydid) {
     2838 +                free(name);
     2839 +                if (zent.zdid == mydid) {
2763 2840                          fix = B_TRUE;
2764 2841                          break;
2765 2842                  }
2766 2843          }
2767 2844          endzoneent(cookie);
2768 2845  
2769 2846          if (fix) {
2770 2847                  zonecfg_set_did(handle);
2771 2848                  return (B_TRUE);
2772 2849          }
↓ open down ↓ 150 lines elided ↑ open up ↑
2923 3000  {
2924 3001          char cmdbuf[MAXPATHLEN];
2925 3002          char postcmdbuf[MAXPATHLEN];
2926 3003          int lockfd;
2927 3004          int arg, err, subproc_err;
2928 3005          char zonepath[MAXPATHLEN];
2929 3006          brand_handle_t bh = NULL;
2930 3007          int status;
2931 3008          boolean_t do_postinstall = B_FALSE;
2932 3009          boolean_t brand_help = B_FALSE;
2933      -        boolean_t do_dataset = B_TRUE;
2934 3010          char opts[128];
2935 3011  
2936 3012          if (target_zone == NULL) {
2937 3013                  sub_usage(SHELP_INSTALL, CMD_INSTALL);
2938 3014                  return (Z_USAGE);
2939 3015          }
2940 3016  
2941 3017          if (zonecfg_in_alt_root()) {
2942 3018                  zerror(gettext("cannot install zone in alternate root"));
2943 3019                  return (Z_ERR);
↓ open down ↓ 55 lines elided ↑ open up ↑
2999 3075          opterr = 0;
3000 3076          while ((arg = getopt(argc, argv, opts)) != EOF) {
3001 3077                  switch (arg) {
3002 3078                  case '?':
3003 3079                          if (optopt == '?') {
3004 3080                                  sub_usage(SHELP_INSTALL, CMD_INSTALL);
3005 3081                                  brand_help = B_TRUE;
3006 3082                          }
3007 3083                          /* Ignore unknown options - may be brand specific. */
3008 3084                          break;
3009      -                case 'x':
3010      -                        if (strcmp(optarg, "nodataset") == 0) {
3011      -                                do_dataset = B_FALSE;
3012      -                                continue; /* internal arg, don't pass thru */
3013      -                        }
3014      -                        break;
3015 3085                  default:
3016 3086                          /* Ignore unknown options - may be brand specific. */
3017 3087                          break;
3018 3088                  }
3019 3089  
3020 3090                  /*
3021 3091                   * Append the option to the command line passed to the
3022 3092                   * brand-specific install and postinstall routines.
3023 3093                   */
3024 3094                  if (addopt(cmdbuf, optopt, optarg, sizeof (cmdbuf)) != Z_OK) {
↓ open down ↓ 32 lines elided ↑ open up ↑
3057 3127                              "progress."), "zoneadm");
3058 3128                          return (Z_ERR);
3059 3129                  }
3060 3130                  err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE);
3061 3131                  if (err != Z_OK) {
3062 3132                          errno = err;
3063 3133                          zperror2(target_zone, gettext("could not set state"));
3064 3134                          goto done;
3065 3135                  }
3066 3136  
3067      -                if (do_dataset)
3068      -                        create_zfs_zonepath(zonepath);
     3137 +                create_zfs_zonepath(zonepath);
3069 3138          }
3070 3139  
3071 3140          status = do_subproc(cmdbuf);
3072 3141          if ((subproc_err =
3073 3142              subproc_status(gettext("brand-specific installation"), status,
3074 3143              B_FALSE)) != ZONE_SUBPROC_OK) {
3075 3144                  if (subproc_err == ZONE_SUBPROC_USAGE && !brand_help) {
3076 3145                          sub_usage(SHELP_INSTALL, CMD_INSTALL);
3077 3146                          zonecfg_release_lock_file(target_zone, lockfd);
3078 3147                          return (Z_ERR);
↓ open down ↓ 1943 lines elided ↑ open up ↑
5022 5091                  }
5023 5092  
5024 5093                  /*
5025 5094                   * If there seems to be a zoneadmd running for this zone, call
5026 5095                   * it to tell it that an uninstall is happening; if all goes
5027 5096                   * well it will then shut itself down.
5028 5097                   */
5029 5098                  if (zonecfg_ping_zoneadmd(target_zone) == Z_OK) {
5030 5099                          zone_cmd_arg_t zarg;
5031 5100                          zarg.cmd = Z_NOTE_UNINSTALLING;
5032      -                        zarg.debug = B_FALSE;
5033 5101                          /* we don't care too much if this fails, just plow on */
5034 5102                          (void) zonecfg_call_zoneadmd(target_zone, &zarg, locale,
5035 5103                              B_TRUE);
5036 5104                  }
5037 5105  
5038 5106                  if (zonecfg_grab_lock_file(target_zone, &lockfd) != Z_OK) {
5039 5107                          zerror(gettext("another %s may have an operation in "
5040 5108                              "progress."), "zoneadm");
5041 5109                          return (Z_ERR);
5042 5110                  }
↓ open down ↓ 95 lines elided ↑ open up ↑
5138 5206          if (argc > optind)
5139 5207                  return (Z_USAGE);
5140 5208  
5141 5209          if (sanity_check(target_zone, CMD_MOUNT, B_FALSE, B_FALSE, force)
5142 5210              != Z_OK)
5143 5211                  return (Z_ERR);
5144 5212          if (verify_details(CMD_MOUNT, argv) != Z_OK)
5145 5213                  return (Z_ERR);
5146 5214  
5147 5215          zarg.cmd = force ? Z_FORCEMOUNT : Z_MOUNT;
5148      -        zarg.debug = B_FALSE;
5149 5216          zarg.bootbuf[0] = '\0';
5150 5217          if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
5151 5218                  zerror(gettext("call to %s failed"), "zoneadmd");
5152 5219                  return (Z_ERR);
5153 5220          }
5154 5221          return (Z_OK);
5155 5222  }
5156 5223  
5157 5224  /* ARGSUSED */
5158 5225  static int
↓ open down ↓ 1 lines elided ↑ open up ↑
5160 5227  {
5161 5228          zone_cmd_arg_t zarg;
5162 5229  
5163 5230          if (argc > 0)
5164 5231                  return (Z_USAGE);
5165 5232          if (sanity_check(target_zone, CMD_UNMOUNT, B_FALSE, B_FALSE, B_FALSE)
5166 5233              != Z_OK)
5167 5234                  return (Z_ERR);
5168 5235  
5169 5236          zarg.cmd = Z_UNMOUNT;
5170      -        zarg.debug = B_FALSE;
5171 5237          if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
5172 5238                  zerror(gettext("call to %s failed"), "zoneadmd");
5173 5239                  return (Z_ERR);
5174 5240          }
5175 5241          return (Z_OK);
5176 5242  }
5177 5243  
5178 5244  static int
5179 5245  mark_func(int argc, char *argv[])
5180 5246  {
↓ open down ↓ 623 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX