Print this page
14249 pseudo-terminal nomenclature should reflect POSIX
Change-Id: Ib4a3cef899ff4c71b09cb0dc6878863c5e8357bc

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/zoneadmd/zcons.c
          +++ new/usr/src/cmd/zoneadmd/zcons.c
↓ open down ↓ 49 lines elided ↑ open up ↑
  50   50   *               [AF_UNIX Socket]   | `--------. .-------------'
  51   51   *                                  |          | |
  52   52   *                                  |          V V
  53   53   *                                  |     +-----------+
  54   54   *                                  |     |  ldterm,  |
  55   55   *                                  |     |   etc.    |
  56   56   *                                  |     +-----------+
  57   57   *                                  |     +-[Anchor]--+
  58   58   *                                  |     |   ptem    |
  59   59   *                                  V     +-----------+
  60      - *                           +---master---+---slave---+
       60 + *                           +---manager--+-subsidiary+
  61   61   *                           |                        |
  62   62   *                           |      zcons driver      |
  63   63   *                           |    zonename="myzone"   |
  64   64   *                           +------------------------+
  65   65   *
  66   66   * There are basically two major tasks which the console subsystem in
  67   67   * zoneadmd accomplishes:
  68   68   *
  69   69   * - Setup and teardown of zcons driver instances.  One zcons instance
  70   70   *   is maintained per zone; we take advantage of the libdevice APIs
  71   71   *   to online new instances of zcons as needed.  Care is taken to
  72   72   *   prune and manage these appropriately; see init_console_dev() and
  73   73   *   destroy_console_dev().  The end result is the creation of the
  74      - *   zcons(7D) instance and an open file descriptor to the master side.
       74 + *   zcons(7D) instance and an open file descriptor to the manager side.
  75   75   *   zcons instances are associated with zones via their zonename device
  76   76   *   property.  This the console instance to persist across reboots,
  77   77   *   and while the zone is halted.
  78   78   *
  79   79   * - Acting as a server for 'zlogin -C' instances.  When zlogin -C is
  80   80   *   run, zlogin connects to zoneadmd via unix domain socket.  zoneadmd
  81   81   *   functions as a two-way proxy for console I/O, relaying user input
  82      - *   to the master side of the console, and relaying output from the
       82 + *   to the manager side of the console, and relaying output from the
  83   83   *   zone to the user.
  84   84   */
  85   85  
  86   86  #include <sys/types.h>
  87   87  #include <sys/socket.h>
  88   88  #include <sys/stat.h>
  89   89  #include <sys/termios.h>
  90   90  #include <sys/zcons.h>
  91   91  #include <sys/mkdev.h>
  92   92  
↓ open down ↓ 165 lines elided ↑ open up ↑
 258  258          devctl_release(hdl);
 259  259          return (DI_WALK_CONTINUE);
 260  260  }
 261  261  
 262  262  static int
 263  263  destroy_console_devs(zlog_t *zlogp)
 264  264  {
 265  265          char conspath[MAXPATHLEN];
 266  266          di_node_t root;
 267  267          struct cb_data cb;
 268      -        int masterfd;
 269      -        int slavefd;
      268 +        int managerfd;
      269 +        int subfd;
 270  270  
 271  271          /*
 272      -         * Signal the master side to release its handle on the slave side by
 273      -         * issuing a ZC_RELEASESLAVE ioctl.
      272 +         * Signal the manager side to release its handle on the subsidiary side
      273 +         * by issuing a ZC_RELEASESUBSID ioctl.
 274  274           */
 275  275          (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
 276      -            zone_name, ZCONS_MASTER_NAME);
 277      -        if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) != -1) {
      276 +            zone_name, ZCONS_MANAGER_NAME);
      277 +        if ((managerfd = open(conspath, O_RDWR | O_NOCTTY)) != -1) {
 278  278                  (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
 279      -                    zone_name, ZCONS_SLAVE_NAME);
 280      -                if ((slavefd = open(conspath, O_RDWR | O_NOCTTY)) != -1) {
 281      -                        if (ioctl(masterfd, ZC_RELEASESLAVE,
 282      -                            (caddr_t)(intptr_t)slavefd) != 0)
      279 +                    zone_name, ZCONS_SUBSIDIARY_NAME);
      280 +                if ((subfd = open(conspath, O_RDWR | O_NOCTTY)) != -1) {
      281 +                        if (ioctl(managerfd, ZC_RELEASESUBSID,
      282 +                            (caddr_t)(intptr_t)subfd) != 0)
 283  283                                  zerror(zlogp, B_TRUE, "WARNING: error while "
 284      -                                    "releasing slave handle of zone console for"
 285      -                                    " %s", zone_name);
 286      -                        (void) close(slavefd);
      284 +                                    "releasing subsidiary handle of zone "
      285 +                                    "console for %s", zone_name);
      286 +                        (void) close(subfd);
 287  287                  } else {
 288      -                        zerror(zlogp, B_TRUE, "WARNING: could not open slave "
 289      -                            "side of zone console for %s to release slave "
 290      -                            "handle", zone_name);
      288 +                        zerror(zlogp, B_TRUE, "WARNING: could not open "
      289 +                            "subsidiary side of zone console for %s to "
      290 +                            "release subsidiary handle", zone_name);
 291  291                  }
 292      -                (void) close(masterfd);
      292 +                (void) close(managerfd);
 293  293          } else {
 294      -                zerror(zlogp, B_TRUE, "WARNING: could not open master side of "
 295      -                    "zone console for %s to release slave handle", zone_name);
      294 +                zerror(zlogp, B_TRUE, "WARNING: could not open manager side of "
      295 +                    "zone console for %s to release subsidiary handle",
      296 +                    zone_name);
 296  297          }
 297  298  
 298  299          bzero(&cb, sizeof (cb));
 299  300          cb.zlogp = zlogp;
 300  301  
 301  302          if ((root = di_init(ZCONSNEX_DEVTREEPATH, DINFOCPYALL)) ==
 302  303              DI_NODE_NIL) {
 303  304                  zerror(zlogp, B_TRUE, "%s failed", "di_init");
 304  305                  return (-1);
 305  306          }
↓ open down ↓ 10 lines elided ↑ open up ↑
 316  317          return (0);
 317  318  }
 318  319  
 319  320  /*
 320  321   * init_console_dev() drives the device-tree configuration of the zone
 321  322   * console device.  The general strategy is to use the libdevice (devctl)
 322  323   * interfaces to instantiate a new zone console node.  We do a lot of
 323  324   * sanity checking, and are careful to reuse a console if one exists.
 324  325   *
 325  326   * Once the device is in the device tree, we kick devfsadm via di_init_devs()
 326      - * to ensure that the appropriate symlinks (to the master and slave console
 327      - * devices) are placed in /dev in the global zone.
      327 + * to ensure that the appropriate symlinks (to the manager and subsidiary
      328 + * console devices) are placed in /dev in the global zone.
 328  329   */
 329  330  static int
 330  331  init_console_dev(zlog_t *zlogp)
 331  332  {
 332  333          char conspath[MAXPATHLEN];
 333  334          devctl_hdl_t bus_hdl = NULL;
 334  335          devctl_hdl_t dev_hdl = NULL;
 335  336          devctl_ddef_t ddef_hdl = NULL;
 336  337          di_devlink_handle_t dl = NULL;
 337  338          int rv = -1;
 338  339          int ndevs;
 339      -        int masterfd;
 340      -        int slavefd;
      340 +        int managerfd;
      341 +        int subfd;
 341  342          int i;
 342  343  
 343  344          /*
 344  345           * Don't re-setup console if it is working and ready already; just
 345  346           * skip ahead to making devlinks, which we do for sanity's sake.
 346  347           */
 347  348          ndevs = count_console_devs(zlogp);
 348  349          if (ndevs == 1) {
 349  350                  goto devlinks;
 350  351          } else if (ndevs > 1 || ndevs == -1) {
↓ open down ↓ 47 lines elided ↑ open up ↑
 398  399  
 399  400  devlinks:
 400  401          if ((dl = di_devlink_init("zcons", DI_MAKE_LINK)) != NULL) {
 401  402                  (void) di_devlink_fini(&dl);
 402  403          } else {
 403  404                  zerror(zlogp, B_TRUE, "failed to create devlinks");
 404  405                  goto error;
 405  406          }
 406  407  
 407  408          /*
 408      -         * Open the master side of the console and issue the ZC_HOLDSLAVE ioctl,
 409      -         * which will cause the master to retain a reference to the slave.
 410      -         * This prevents ttymon from blowing through the slave's STREAMS anchor.
      409 +         * Open the manager side of the console and issue the ZC_HOLDSUBSID
      410 +         * ioctl, which will cause the manager to retain a reference to the
      411 +         * subsidiary.  This prevents ttymon from blowing through the
      412 +         * subsidiary's STREAMS anchor.
 411  413           */
 412  414          (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
 413      -            zone_name, ZCONS_MASTER_NAME);
 414      -        if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
 415      -                zerror(zlogp, B_TRUE, "ERROR: could not open master side of "
 416      -                    "zone console for %s to acquire slave handle", zone_name);
      415 +            zone_name, ZCONS_MANAGER_NAME);
      416 +        if ((managerfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
      417 +                zerror(zlogp, B_TRUE, "ERROR: could not open manager side of "
      418 +                    "zone console for %s to acquire subsidiary handle",
      419 +                    zone_name);
 417  420                  goto error;
 418  421          }
 419  422          (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
 420      -            zone_name, ZCONS_SLAVE_NAME);
 421      -        if ((slavefd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
 422      -                zerror(zlogp, B_TRUE, "ERROR: could not open slave side of zone"
 423      -                    " console for %s to acquire slave handle", zone_name);
 424      -                (void) close(masterfd);
      423 +            zone_name, ZCONS_SUBSIDIARY_NAME);
      424 +        if ((subfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
      425 +                zerror(zlogp, B_TRUE, "ERROR: could not open subsidiary side "
      426 +                    "of zone console for %s to acquire subsidiary handle",
      427 +                    zone_name);
      428 +                (void) close(managerfd);
 425  429                  goto error;
 426  430          }
 427  431          /*
 428  432           * This ioctl can occasionally return ENXIO if devfs doesn't have
 429  433           * everything plumbed up yet due to heavy zone startup load. Wait for
 430  434           * 1 sec. and retry a few times before we fail to boot the zone.
 431  435           */
 432  436          for (i = 0; i < 5; i++) {
 433      -                if (ioctl(masterfd, ZC_HOLDSLAVE, (caddr_t)(intptr_t)slavefd)
      437 +                if (ioctl(managerfd, ZC_HOLDSUBSID, (caddr_t)(intptr_t)subfd)
 434  438                      == 0) {
 435  439                          rv = 0;
 436  440                          break;
 437  441                  } else if (errno != ENXIO) {
 438  442                          break;
 439  443                  }
 440  444                  (void) sleep(1);
 441  445          }
 442  446          if (rv != 0)
 443      -                zerror(zlogp, B_TRUE, "ERROR: error while acquiring slave "
 444      -                    "handle of zone console for %s", zone_name);
      447 +                zerror(zlogp, B_TRUE, "ERROR: error while acquiring "
      448 +                    "subsidiary handle of zone console for %s", zone_name);
 445  449  
 446      -        (void) close(slavefd);
 447      -        (void) close(masterfd);
      450 +        (void) close(subfd);
      451 +        (void) close(managerfd);
 448  452  
 449  453  error:
 450  454          if (ddef_hdl)
 451  455                  devctl_ddef_free(ddef_hdl);
 452  456          if (bus_hdl)
 453  457                  devctl_release(bus_hdl);
 454  458          if (dev_hdl)
 455  459                  devctl_release(dev_hdl);
 456  460          return (rv);
 457  461  }
↓ open down ↓ 235 lines elided ↑ open up ↑
 693  697  static int
 694  698  test_client(int clifd)
 695  699  {
 696  700          if ((write(clifd, "", 0) == -1) && errno == EPIPE)
 697  701                  return (-1);
 698  702          return (0);
 699  703  }
 700  704  
 701  705  /*
 702  706   * This routine drives the console I/O loop.  It polls for input from the
 703      - * master side of the console (output to the console), and from the client
      707 + * manager side of the console (output to the console), and from the client
 704  708   * (input from the console user).  Additionally, it polls on the server fd,
 705  709   * and disconnects any clients that might try to hook up with the zone while
 706  710   * the console is in use.
 707  711   *
 708  712   * When the client first calls us up, it is expected to send a line giving
 709  713   * its "identity"; this consists of the string 'IDENT <pid> <locale>'.
 710  714   * This is so that we can report that the console is busy along with
 711  715   * some diagnostics about who has it busy; the locale is used so that
 712  716   * asynchronous messages about zone state (like the NOTICE: zone halted
 713  717   * messages) can be output in the user's locale.
↓ open down ↓ 183 lines elided ↑ open up ↑
 897  901   * The rules for shutdown are: there must be no console client, and the zone
 898  902   * state must be < ready.  However, we need to give things a chance to actually
 899  903   * get going when the daemon starts up-- otherwise the daemon would immediately
 900  904   * exit on startup if the zone was in the installed state, so we first drop
 901  905   * into the do_console_io() loop in order to give *something* a chance to
 902  906   * happen.
 903  907   */
 904  908  void
 905  909  serve_console(zlog_t *zlogp)
 906  910  {
 907      -        int masterfd;
      911 +        int managerfd;
 908  912          zone_state_t zstate;
 909  913          char conspath[MAXPATHLEN];
 910  914  
 911  915          (void) snprintf(conspath, sizeof (conspath),
 912      -            "/dev/zcons/%s/%s", zone_name, ZCONS_MASTER_NAME);
      916 +            "/dev/zcons/%s/%s", zone_name, ZCONS_MANAGER_NAME);
 913  917  
 914  918          for (;;) {
 915      -                masterfd = open(conspath, O_RDWR|O_NONBLOCK|O_NOCTTY);
 916      -                if (masterfd == -1) {
 917      -                        zerror(zlogp, B_TRUE, "failed to open console master");
      919 +                managerfd = open(conspath, O_RDWR|O_NONBLOCK|O_NOCTTY);
      920 +                if (managerfd == -1) {
      921 +                        zerror(zlogp, B_TRUE, "failed to open console manager");
 918  922                          (void) mutex_lock(&lock);
 919  923                          goto death;
 920  924                  }
 921  925  
 922  926                  /*
 923  927                   * Setting RPROTDIS on the stream means that the control
 924  928                   * portion of messages received (which we don't care about)
 925  929                   * will be discarded by the stream head.  If we allowed such
 926  930                   * messages, we wouldn't be able to use read(2), as it fails
 927  931                   * (EBADMSG) when a message with a control element is received.
 928  932                   */
 929      -                if (ioctl(masterfd, I_SRDOPT, RNORM|RPROTDIS) == -1) {
      933 +                if (ioctl(managerfd, I_SRDOPT, RNORM|RPROTDIS) == -1) {
 930  934                          zerror(zlogp, B_TRUE, "failed to set options on "
 931      -                            "console master");
      935 +                            "console manager");
 932  936                          (void) mutex_lock(&lock);
 933  937                          goto death;
 934  938                  }
 935  939  
 936      -                do_console_io(zlogp, masterfd, serverfd);
      940 +                do_console_io(zlogp, managerfd, serverfd);
 937  941  
 938  942                  /*
 939  943                   * We would prefer not to do this, but hostile zone processes
 940  944                   * can cause the stream to become tainted, and reads will
 941  945                   * fail.  So, in case something has gone seriously ill,
 942  946                   * we dismantle the stream and reopen the console when we
 943  947                   * take another lap.
 944  948                   */
 945      -                (void) close(masterfd);
      949 +                (void) close(managerfd);
 946  950  
 947  951                  (void) mutex_lock(&lock);
 948  952                  /*
 949  953                   * We need to set death_throes (see below) atomically with
 950  954                   * respect to noticing that (a) we have no console client and
 951  955                   * (b) the zone is not installed.  Otherwise we could get a
 952  956                   * request to boot during this time.  Once we set death_throes,
 953  957                   * any incoming door stuff will be turned away.
 954  958                   */
 955  959                  if (zone_get_state(zone_name, &zstate) == Z_OK) {
↓ open down ↓ 22 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX