Print this page
PSARC 2008/766 native zones p2v
6667924 physical to virtual utility for native zones

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/zoneadm/zoneadm.c
          +++ new/usr/src/cmd/zoneadm/zoneadm.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  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      - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
       23 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27   27  /*
  28   28   * zoneadm is a command interpreter for zone administration.  It is all in
  29   29   * C (i.e., no lex/yacc), and all the argument passing is argc/argv based.
  30   30   * main() calls parse_and_run() which calls cmd_match(), then invokes the
  31   31   * appropriate command's handler function.  The rest of the program is the
  32   32   * handler functions and their helper functions.
  33   33   *
↓ open down ↓ 61 lines elided ↑ open up ↑
  95   95          char            zbrand[MAXNAMELEN];
  96   96          char            zroot[MAXPATHLEN];
  97   97          char            zuuid[UUID_PRINTABLE_STRING_LENGTH];
  98   98          zone_iptype_t   ziptype;
  99   99  } zone_entry_t;
 100  100  
 101  101  #define CLUSTER_BRAND_NAME      "cluster"
 102  102  
 103  103  static zone_entry_t *zents;
 104  104  static size_t nzents;
 105      -static boolean_t is_native_zone = B_TRUE;
 106  105  
 107  106  #define LOOPBACK_IF     "lo0"
 108  107  #define SOCKET_AF(af)   (((af) == AF_UNSPEC) ? AF_INET : (af))
 109  108  
 110  109  struct net_if {
 111  110          char    *name;
 112  111          int     af;
 113  112  };
 114  113  
 115  114  /* 0755 is the default directory mode. */
↓ open down ↓ 964 lines elided ↑ open up ↑
1080 1079                      sizeof (rootpath)) {
1081 1080                          /*
1082 1081                           * TRANSLATION_NOTE
1083 1082                           * Zonepath is a literal that should not be translated.
1084 1083                           */
1085 1084                          (void) fprintf(stderr,
1086 1085                              gettext("Zonepath %s is too long.\n"), rpath);
1087 1086                          return (Z_ERR);
1088 1087                  }
1089 1088                  if ((res = stat(rootpath, &stbuf)) == 0) {
1090      -                        struct dirent   *dp;
1091      -                        DIR             *dirp;
1092      -                        boolean_t       empty = B_TRUE;
1093      -
1094 1089                          if (zonecfg_detached(rpath)) {
1095 1090                                  (void) fprintf(stderr,
1096 1091                                      gettext("Cannot %s detached "
1097 1092                                      "zone.\nUse attach or remove %s "
1098 1093                                      "directory.\n"), cmd_to_str(cmd_num),
1099 1094                                      rpath);
1100 1095                                  return (Z_ERR);
1101 1096                          }
1102 1097  
1103 1098                          /* Not detached, check if it really looks ok. */
↓ open down ↓ 8 lines elided ↑ open up ↑
1112 1107                                  (void) fprintf(stderr, gettext("%s is not "
1113 1108                                      "owned by root.\n"), rootpath);
1114 1109                                  return (Z_ERR);
1115 1110                          }
1116 1111  
1117 1112                          if ((stbuf.st_mode & 0777) != 0755) {
1118 1113                                  (void) fprintf(stderr, gettext("%s mode is not "
1119 1114                                      "0755.\n"), rootpath);
1120 1115                                  return (Z_ERR);
1121 1116                          }
1122      -
1123      -                        if ((dirp = opendir(rootpath)) == NULL) {
1124      -                                (void) fprintf(stderr, gettext("Could not "
1125      -                                    "open rootpath %s\n"), rootpath);
1126      -                                return (Z_ERR);
1127      -                        }
1128      -
1129      -                        /* Verify that the dir is empty. */
1130      -                        while ((dp = readdir(dirp)) != NULL) {
1131      -                                if (strcmp(dp->d_name, ".") == 0 ||
1132      -                                    strcmp(dp->d_name, "..") == 0)
1133      -                                        continue;
1134      -
1135      -                                empty = B_FALSE;
1136      -                                break;
1137      -                        }
1138      -                        (void) closedir(dirp);
1139      -
1140      -                        if (!empty) {
1141      -                                (void) fprintf(stderr, gettext("Rootpath %s "
1142      -                                    "exists and contains data; remove or move "
1143      -                                    "aside prior to %s.\n"), rootpath,
1144      -                                    cmd_to_str(cmd_num));
1145      -                                return (Z_ERR);
1146      -                        }
1147      -
1148 1117                  }
1149 1118          }
1150 1119  
1151 1120          return (err ? Z_ERR : Z_OK);
1152 1121  }
1153 1122  
1154 1123  static int
1155 1124  invoke_brand_handler(int cmd_num, char *argv[])
1156 1125  {
1157 1126          zone_dochandle_t handle;
↓ open down ↓ 548 lines elided ↑ open up ↑
1706 1675                  }
1707 1676                  switch (cmd_num) {
1708 1677                  case CMD_UNINSTALL:
1709 1678                          if (state == ZONE_STATE_CONFIGURED) {
1710 1679                                  zerror(gettext("is already in state '%s'."),
1711 1680                                      zone_state_str(ZONE_STATE_CONFIGURED));
1712 1681                                  return (Z_ERR);
1713 1682                          }
1714 1683                          break;
1715 1684                  case CMD_ATTACH:
     1685 +                        if (state == ZONE_STATE_INSTALLED) {
     1686 +                                zerror(gettext("is already %s."),
     1687 +                                    zone_state_str(ZONE_STATE_INSTALLED));
     1688 +                                return (Z_ERR);
     1689 +                        } else if (state == ZONE_STATE_INCOMPLETE && !force) {
     1690 +                                zerror(gettext("zone is %s; %s required."),
     1691 +                                    zone_state_str(ZONE_STATE_INCOMPLETE),
     1692 +                                    cmd_to_str(CMD_UNINSTALL));
     1693 +                                return (Z_ERR);
     1694 +                        }
     1695 +                        break;
1716 1696                  case CMD_CLONE:
1717 1697                  case CMD_INSTALL:
1718 1698                          if (state == ZONE_STATE_INSTALLED) {
1719 1699                                  zerror(gettext("is already %s."),
1720 1700                                      zone_state_str(ZONE_STATE_INSTALLED));
1721 1701                                  return (Z_ERR);
1722 1702                          } else if (state == ZONE_STATE_INCOMPLETE) {
1723 1703                                  zerror(gettext("zone is %s; %s required."),
1724 1704                                      zone_state_str(ZONE_STATE_INCOMPLETE),
1725 1705                                      cmd_to_str(CMD_UNINSTALL));
↓ open down ↓ 2 lines elided ↑ open up ↑
1728 1708                          break;
1729 1709                  case CMD_DETACH:
1730 1710                  case CMD_MOVE:
1731 1711                  case CMD_READY:
1732 1712                  case CMD_BOOT:
1733 1713                  case CMD_MOUNT:
1734 1714                  case CMD_MARK:
1735 1715                          if ((cmd_num == CMD_BOOT || cmd_num == CMD_MOUNT) &&
1736 1716                              force)
1737 1717                                  min_state = ZONE_STATE_INCOMPLETE;
     1718 +                        else if (cmd_num == CMD_MARK)
     1719 +                                min_state = ZONE_STATE_CONFIGURED;
1738 1720                          else
1739 1721                                  min_state = ZONE_STATE_INSTALLED;
1740 1722  
1741      -                        if (force && cmd_num == CMD_BOOT && is_native_zone) {
1742      -                                zerror(gettext("Only branded zones may be "
1743      -                                    "force-booted."));
1744      -                                return (Z_ERR);
1745      -                        }
1746      -
1747 1723                          if (state < min_state) {
1748 1724                                  zerror(gettext("must be %s before %s."),
1749 1725                                      zone_state_str(min_state),
1750 1726                                      cmd_to_str(cmd_num));
1751 1727                                  return (Z_ERR);
1752 1728                          }
1753 1729                          break;
1754 1730                  case CMD_VERIFY:
1755 1731                          if (state == ZONE_STATE_INCOMPLETE) {
1756 1732                                  zerror(gettext("zone is %s; %s required."),
↓ open down ↓ 2861 lines elided ↑ open up ↑
4618 4594          char zonepath[MAXPATHLEN];
4619 4595          char cmdbuf[MAXPATHLEN];
4620 4596          char postcmdbuf[MAXPATHLEN];
4621 4597          boolean_t execute = B_TRUE;
4622 4598          boolean_t brand_help = B_FALSE;
4623 4599          char *manifest_path;
4624 4600          char tmpmanifest[80];
4625 4601          int manifest_pos;
4626 4602          brand_handle_t bh = NULL;
4627 4603          int status;
     4604 +        int last_index = 0;
     4605 +        int offset;
     4606 +        char *up;
     4607 +        boolean_t forced_update = B_FALSE;
4628 4608  
4629 4609          if (zonecfg_in_alt_root()) {
4630 4610                  zerror(gettext("cannot attach zone in alternate root"));
4631 4611                  return (Z_ERR);
4632 4612          }
4633 4613  
4634 4614          /* Check the argv string for args we handle internally */
4635 4615          optind = 0;
4636 4616          opterr = 0;
4637      -        while ((arg = getopt(argc, argv, "?Fn:")) != EOF) {
     4617 +        while ((arg = getopt(argc, argv, "?Fn:U")) != EOF) {
4638 4618                  switch (arg) {
4639 4619                  case '?':
4640 4620                          if (optopt == '?') {
4641 4621                                  sub_usage(SHELP_ATTACH, CMD_ATTACH);
4642 4622                                  brand_help = B_TRUE;
4643 4623                          }
4644 4624                          /* Ignore unknown options - may be brand specific. */
4645 4625                          break;
4646 4626                  case 'F':
4647 4627                          force = B_TRUE;
4648 4628                          break;
4649 4629                  case 'n':
4650 4630                          execute = B_FALSE;
4651 4631                          manifest_path = optarg;
4652 4632                          manifest_pos = optind - 1;
4653 4633                          break;
     4634 +                case 'U':
     4635 +                        /*
     4636 +                         * Undocumented 'force update' option for p2v update on
     4637 +                         * attach when zone is in the incomplete state.  Change
     4638 +                         * the option back to 'u' and set forced_update flag.
     4639 +                         */
     4640 +                        if (optind == last_index)
     4641 +                                offset = optind;
     4642 +                        else
     4643 +                                offset = optind - 1;
     4644 +                        if ((up = index(argv[offset], 'U')) != NULL)
     4645 +                                *up = 'u';
     4646 +                        forced_update = B_TRUE;
     4647 +                        break;
4654 4648                  default:
4655 4649                          /* Ignore unknown options - may be brand specific. */
4656 4650                          break;
4657 4651                  }
     4652 +                last_index = optind;
4658 4653          }
4659 4654  
4660 4655          if (brand_help) {
4661 4656                  force = B_FALSE;
4662 4657                  execute = B_TRUE;
4663 4658          }
4664 4659  
4665 4660          /* dry-run and force flags are mutually exclusive */
4666 4661          if (!execute && force) {
4667 4662                  zerror(gettext("-F and -n flags are mutually exclusive"));
↓ open down ↓ 1 lines elided ↑ open up ↑
4669 4664          }
4670 4665  
4671 4666          /*
4672 4667           * If the no-execute option was specified, we don't do validation and
4673 4668           * need to figure out the brand, since there is no zone required to be
4674 4669           * configured for this option.
4675 4670           */
4676 4671          if (execute) {
4677 4672                  if (!brand_help) {
4678 4673                          if (sanity_check(target_zone, CMD_ATTACH, B_FALSE,
4679      -                            B_TRUE, B_FALSE) != Z_OK)
     4674 +                            B_TRUE, forced_update) != Z_OK)
4680 4675                                  return (Z_ERR);
4681 4676                          if (verify_details(CMD_ATTACH, argv) != Z_OK)
4682 4677                                  return (Z_ERR);
4683 4678                  }
4684 4679  
4685 4680                  if ((err = zone_get_zonepath(target_zone, zonepath,
4686 4681                      sizeof (zonepath))) != Z_OK) {
4687 4682                          errno = err;
4688 4683                          zperror2(target_zone,
4689 4684                              gettext("could not get zone path"));
↓ open down ↓ 52 lines elided ↑ open up ↑
4742 4737                          return (Z_ERR);
4743 4738                  }
4744 4739          }
4745 4740  
4746 4741          if (!force) {
4747 4742                  /*
4748 4743                   * Not a force-attach, so we need to actually do the work.
4749 4744                   */
4750 4745                  if (cmdbuf[0] != '\0') {
4751 4746                          /* Run the attach hook */
4752      -                        status = do_subproc_interactive(cmdbuf);
     4747 +                        status = do_subproc(cmdbuf);
4753 4748                          if ((status = subproc_status(gettext("brand-specific "
4754 4749                              "attach"), status, B_FALSE)) != ZONE_SUBPROC_OK) {
4755 4750                                  if (status == ZONE_SUBPROC_USAGE && !brand_help)
4756 4751                                          sub_usage(SHELP_ATTACH, CMD_ATTACH);
4757 4752  
4758 4753                                  if (execute && !brand_help) {
4759      -                                        assert(lockfd >= 0);
     4754 +                                        assert(zonecfg_lock_file_held(&lockfd));
4760 4755                                          zonecfg_release_lock_file(target_zone,
4761 4756                                              lockfd);
4762 4757                                          lockfd = -1;
4763 4758                                  }
4764 4759  
4765 4760                                  assert(lockfd == -1);
4766 4761                                  return (Z_ERR);
4767 4762                          }
4768 4763                  }
4769 4764  
↓ open down ↓ 22 lines elided ↑ open up ↑
4792 4787                  zonecfg_rm_detached(handle, force);
4793 4788                  zonecfg_fini_handle(handle);
4794 4789          }
4795 4790  
4796 4791          if (err == Z_OK &&
4797 4792              (err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) {
4798 4793                  errno = err;
4799 4794                  zperror(gettext("could not reset state"), B_TRUE);
4800 4795          }
4801 4796  
4802      -        assert(lockfd >= 0);
     4797 +        assert(zonecfg_lock_file_held(&lockfd));
4803 4798          zonecfg_release_lock_file(target_zone, lockfd);
4804 4799          lockfd = -1;
4805 4800  
4806 4801          /* If we have a brand postattach hook, run it. */
4807 4802          if (err == Z_OK && !force && postcmdbuf[0] != '\0') {
4808 4803                  status = do_subproc(postcmdbuf);
4809 4804                  if (subproc_status(gettext("brand-specific postattach"),
4810 4805                      status, B_FALSE) != ZONE_SUBPROC_OK) {
4811 4806                          if ((err = zone_set_state(target_zone,
4812 4807                              ZONE_STATE_CONFIGURED)) != Z_OK) {
↓ open down ↓ 298 lines elided ↑ open up ↑
5111 5106                  zerror(gettext("call to %s failed"), "zoneadmd");
5112 5107                  return (Z_ERR);
5113 5108          }
5114 5109          return (Z_OK);
5115 5110  }
5116 5111  
5117 5112  static int
5118 5113  mark_func(int argc, char *argv[])
5119 5114  {
5120 5115          int err, lockfd;
     5116 +        int arg;
     5117 +        boolean_t force = B_FALSE;
     5118 +        int state;
5121 5119  
5122      -        if (argc != 1 || strcmp(argv[0], "incomplete") != 0)
     5120 +        optind = 0;
     5121 +        opterr = 0;
     5122 +        while ((arg = getopt(argc, argv, "F")) != EOF) {
     5123 +                switch (arg) {
     5124 +                case 'F':
     5125 +                        force = B_TRUE;
     5126 +                        break;
     5127 +                default:
     5128 +                        return (Z_USAGE);
     5129 +                }
     5130 +        }
     5131 +
     5132 +        if (argc != (optind + 1))
5123 5133                  return (Z_USAGE);
5124      -        if (sanity_check(target_zone, CMD_MARK, B_FALSE, B_FALSE, B_FALSE)
     5134 +
     5135 +        if (strcmp(argv[optind], "configured") == 0)
     5136 +                state = ZONE_STATE_CONFIGURED;
     5137 +        else if (strcmp(argv[optind], "incomplete") == 0)
     5138 +                state = ZONE_STATE_INCOMPLETE;
     5139 +        else if (strcmp(argv[optind], "installed") == 0)
     5140 +                state = ZONE_STATE_INSTALLED;
     5141 +        else
     5142 +                return (Z_USAGE);
     5143 +
     5144 +        if (state != ZONE_STATE_INCOMPLETE && !force)
     5145 +                return (Z_USAGE);
     5146 +
     5147 +        if (sanity_check(target_zone, CMD_MARK, B_FALSE, B_TRUE, B_FALSE)
5125 5148              != Z_OK)
5126 5149                  return (Z_ERR);
5127 5150  
5128 5151          /*
5129 5152           * Invoke brand-specific handler.
5130 5153           */
5131 5154          if (invoke_brand_handler(CMD_MARK, argv) != Z_OK)
5132 5155                  return (Z_ERR);
5133 5156  
5134 5157          if (zonecfg_grab_lock_file(target_zone, &lockfd) != Z_OK) {
5135 5158                  zerror(gettext("another %s may have an operation in progress."),
5136 5159                      "zoneadm");
5137 5160                  return (Z_ERR);
5138 5161          }
5139 5162  
5140      -        err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE);
     5163 +        err = zone_set_state(target_zone, state);
5141 5164          if (err != Z_OK) {
5142 5165                  errno = err;
5143 5166                  zperror2(target_zone, gettext("could not set state"));
5144 5167          }
5145 5168          zonecfg_release_lock_file(target_zone, lockfd);
5146 5169  
5147 5170          return (err);
5148 5171  }
5149 5172  
5150 5173  /*
↓ open down ↓ 434 lines elided ↑ open up ↑
5585 5608           * If we are going to be operating on a single zone, retrieve its
5586 5609           * brand type and determine whether it is native or not.
5587 5610           */
5588 5611          if ((target_zone != NULL) &&
5589 5612              (strcmp(target_zone, GLOBAL_ZONENAME) != 0)) {
5590 5613                  if (zone_get_brand(target_zone, target_brand,
5591 5614                      sizeof (target_brand)) != Z_OK) {
5592 5615                          zerror(gettext("missing or invalid brand"));
5593 5616                          exit(Z_ERR);
5594 5617                  }
5595      -                is_native_zone = (strcmp(target_brand, NATIVE_BRAND_NAME) == 0);
5596 5618          }
5597 5619  
5598 5620          err = parse_and_run(argc - optind, &argv[optind]);
5599 5621  
5600 5622          return (err);
5601 5623  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX