Print this page
14249 pseudo-terminal nomenclature should reflect POSIX
Change-Id: Ib4a3cef899ff4c71b09cb0dc6878863c5e8357bc
*** 55,65 ****
* | | etc. |
* | +-----------+
* | +-[Anchor]--+
* | | ptem |
* V +-----------+
! * +---master---+---slave---+
* | |
* | zcons driver |
* | zonename="myzone" |
* +------------------------+
*
--- 55,65 ----
* | | etc. |
* | +-----------+
* | +-[Anchor]--+
* | | ptem |
* V +-----------+
! * +---manager--+-subsidiary+
* | |
* | zcons driver |
* | zonename="myzone" |
* +------------------------+
*
*** 69,87 ****
* - Setup and teardown of zcons driver instances. One zcons instance
* is maintained per zone; we take advantage of the libdevice APIs
* to online new instances of zcons as needed. Care is taken to
* prune and manage these appropriately; see init_console_dev() and
* destroy_console_dev(). The end result is the creation of the
! * zcons(7D) instance and an open file descriptor to the master side.
* zcons instances are associated with zones via their zonename device
* property. This the console instance to persist across reboots,
* and while the zone is halted.
*
* - Acting as a server for 'zlogin -C' instances. When zlogin -C is
* run, zlogin connects to zoneadmd via unix domain socket. zoneadmd
* functions as a two-way proxy for console I/O, relaying user input
! * to the master side of the console, and relaying output from the
* zone to the user.
*/
#include <sys/types.h>
#include <sys/socket.h>
--- 69,87 ----
* - Setup and teardown of zcons driver instances. One zcons instance
* is maintained per zone; we take advantage of the libdevice APIs
* to online new instances of zcons as needed. Care is taken to
* prune and manage these appropriately; see init_console_dev() and
* destroy_console_dev(). The end result is the creation of the
! * zcons(7D) instance and an open file descriptor to the manager side.
* zcons instances are associated with zones via their zonename device
* property. This the console instance to persist across reboots,
* and while the zone is halted.
*
* - Acting as a server for 'zlogin -C' instances. When zlogin -C is
* run, zlogin connects to zoneadmd via unix domain socket. zoneadmd
* functions as a two-way proxy for console I/O, relaying user input
! * to the manager side of the console, and relaying output from the
* zone to the user.
*/
#include <sys/types.h>
#include <sys/socket.h>
*** 263,300 ****
destroy_console_devs(zlog_t *zlogp)
{
char conspath[MAXPATHLEN];
di_node_t root;
struct cb_data cb;
! int masterfd;
! int slavefd;
/*
! * Signal the master side to release its handle on the slave side by
! * issuing a ZC_RELEASESLAVE ioctl.
*/
(void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
! zone_name, ZCONS_MASTER_NAME);
! if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) != -1) {
(void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
! zone_name, ZCONS_SLAVE_NAME);
! if ((slavefd = open(conspath, O_RDWR | O_NOCTTY)) != -1) {
! if (ioctl(masterfd, ZC_RELEASESLAVE,
! (caddr_t)(intptr_t)slavefd) != 0)
zerror(zlogp, B_TRUE, "WARNING: error while "
! "releasing slave handle of zone console for"
! " %s", zone_name);
! (void) close(slavefd);
} else {
! zerror(zlogp, B_TRUE, "WARNING: could not open slave "
! "side of zone console for %s to release slave "
! "handle", zone_name);
}
! (void) close(masterfd);
} else {
! zerror(zlogp, B_TRUE, "WARNING: could not open master side of "
! "zone console for %s to release slave handle", zone_name);
}
bzero(&cb, sizeof (cb));
cb.zlogp = zlogp;
--- 263,301 ----
destroy_console_devs(zlog_t *zlogp)
{
char conspath[MAXPATHLEN];
di_node_t root;
struct cb_data cb;
! int managerfd;
! int subfd;
/*
! * Signal the manager side to release its handle on the subsidiary side
! * by issuing a ZC_RELEASESUBSID ioctl.
*/
(void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
! zone_name, ZCONS_MANAGER_NAME);
! if ((managerfd = open(conspath, O_RDWR | O_NOCTTY)) != -1) {
(void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
! zone_name, ZCONS_SUBSIDIARY_NAME);
! if ((subfd = open(conspath, O_RDWR | O_NOCTTY)) != -1) {
! if (ioctl(managerfd, ZC_RELEASESUBSID,
! (caddr_t)(intptr_t)subfd) != 0)
zerror(zlogp, B_TRUE, "WARNING: error while "
! "releasing subsidiary handle of zone "
! "console for %s", zone_name);
! (void) close(subfd);
} else {
! zerror(zlogp, B_TRUE, "WARNING: could not open "
! "subsidiary side of zone console for %s to "
! "release subsidiary handle", zone_name);
}
! (void) close(managerfd);
} else {
! zerror(zlogp, B_TRUE, "WARNING: could not open manager side of "
! "zone console for %s to release subsidiary handle",
! zone_name);
}
bzero(&cb, sizeof (cb));
cb.zlogp = zlogp;
*** 321,332 ****
* console device. The general strategy is to use the libdevice (devctl)
* interfaces to instantiate a new zone console node. We do a lot of
* sanity checking, and are careful to reuse a console if one exists.
*
* Once the device is in the device tree, we kick devfsadm via di_init_devs()
! * to ensure that the appropriate symlinks (to the master and slave console
! * devices) are placed in /dev in the global zone.
*/
static int
init_console_dev(zlog_t *zlogp)
{
char conspath[MAXPATHLEN];
--- 322,333 ----
* console device. The general strategy is to use the libdevice (devctl)
* interfaces to instantiate a new zone console node. We do a lot of
* sanity checking, and are careful to reuse a console if one exists.
*
* Once the device is in the device tree, we kick devfsadm via di_init_devs()
! * to ensure that the appropriate symlinks (to the manager and subsidiary
! * console devices) are placed in /dev in the global zone.
*/
static int
init_console_dev(zlog_t *zlogp)
{
char conspath[MAXPATHLEN];
*** 334,345 ****
devctl_hdl_t dev_hdl = NULL;
devctl_ddef_t ddef_hdl = NULL;
di_devlink_handle_t dl = NULL;
int rv = -1;
int ndevs;
! int masterfd;
! int slavefd;
int i;
/*
* Don't re-setup console if it is working and ready already; just
* skip ahead to making devlinks, which we do for sanity's sake.
--- 335,346 ----
devctl_hdl_t dev_hdl = NULL;
devctl_ddef_t ddef_hdl = NULL;
di_devlink_handle_t dl = NULL;
int rv = -1;
int ndevs;
! int managerfd;
! int subfd;
int i;
/*
* Don't re-setup console if it is working and ready already; just
* skip ahead to making devlinks, which we do for sanity's sake.
*** 403,452 ****
zerror(zlogp, B_TRUE, "failed to create devlinks");
goto error;
}
/*
! * Open the master side of the console and issue the ZC_HOLDSLAVE ioctl,
! * which will cause the master to retain a reference to the slave.
! * This prevents ttymon from blowing through the slave's STREAMS anchor.
*/
(void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
! zone_name, ZCONS_MASTER_NAME);
! if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
! zerror(zlogp, B_TRUE, "ERROR: could not open master side of "
! "zone console for %s to acquire slave handle", zone_name);
goto error;
}
(void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
! zone_name, ZCONS_SLAVE_NAME);
! if ((slavefd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
! zerror(zlogp, B_TRUE, "ERROR: could not open slave side of zone"
! " console for %s to acquire slave handle", zone_name);
! (void) close(masterfd);
goto error;
}
/*
* This ioctl can occasionally return ENXIO if devfs doesn't have
* everything plumbed up yet due to heavy zone startup load. Wait for
* 1 sec. and retry a few times before we fail to boot the zone.
*/
for (i = 0; i < 5; i++) {
! if (ioctl(masterfd, ZC_HOLDSLAVE, (caddr_t)(intptr_t)slavefd)
== 0) {
rv = 0;
break;
} else if (errno != ENXIO) {
break;
}
(void) sleep(1);
}
if (rv != 0)
! zerror(zlogp, B_TRUE, "ERROR: error while acquiring slave "
! "handle of zone console for %s", zone_name);
! (void) close(slavefd);
! (void) close(masterfd);
error:
if (ddef_hdl)
devctl_ddef_free(ddef_hdl);
if (bus_hdl)
--- 404,456 ----
zerror(zlogp, B_TRUE, "failed to create devlinks");
goto error;
}
/*
! * Open the manager side of the console and issue the ZC_HOLDSUBSID
! * ioctl, which will cause the manager to retain a reference to the
! * subsidiary. This prevents ttymon from blowing through the
! * subsidiary's STREAMS anchor.
*/
(void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
! zone_name, ZCONS_MANAGER_NAME);
! if ((managerfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
! zerror(zlogp, B_TRUE, "ERROR: could not open manager side of "
! "zone console for %s to acquire subsidiary handle",
! zone_name);
goto error;
}
(void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
! zone_name, ZCONS_SUBSIDIARY_NAME);
! if ((subfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
! zerror(zlogp, B_TRUE, "ERROR: could not open subsidiary side "
! "of zone console for %s to acquire subsidiary handle",
! zone_name);
! (void) close(managerfd);
goto error;
}
/*
* This ioctl can occasionally return ENXIO if devfs doesn't have
* everything plumbed up yet due to heavy zone startup load. Wait for
* 1 sec. and retry a few times before we fail to boot the zone.
*/
for (i = 0; i < 5; i++) {
! if (ioctl(managerfd, ZC_HOLDSUBSID, (caddr_t)(intptr_t)subfd)
== 0) {
rv = 0;
break;
} else if (errno != ENXIO) {
break;
}
(void) sleep(1);
}
if (rv != 0)
! zerror(zlogp, B_TRUE, "ERROR: error while acquiring "
! "subsidiary handle of zone console for %s", zone_name);
! (void) close(subfd);
! (void) close(managerfd);
error:
if (ddef_hdl)
devctl_ddef_free(ddef_hdl);
if (bus_hdl)
*** 698,708 ****
return (0);
}
/*
* This routine drives the console I/O loop. It polls for input from the
! * master side of the console (output to the console), and from the client
* (input from the console user). Additionally, it polls on the server fd,
* and disconnects any clients that might try to hook up with the zone while
* the console is in use.
*
* When the client first calls us up, it is expected to send a line giving
--- 702,712 ----
return (0);
}
/*
* This routine drives the console I/O loop. It polls for input from the
! * manager side of the console (output to the console), and from the client
* (input from the console user). Additionally, it polls on the server fd,
* and disconnects any clients that might try to hook up with the zone while
* the console is in use.
*
* When the client first calls us up, it is expected to send a line giving
*** 902,922 ****
* happen.
*/
void
serve_console(zlog_t *zlogp)
{
! int masterfd;
zone_state_t zstate;
char conspath[MAXPATHLEN];
(void) snprintf(conspath, sizeof (conspath),
! "/dev/zcons/%s/%s", zone_name, ZCONS_MASTER_NAME);
for (;;) {
! masterfd = open(conspath, O_RDWR|O_NONBLOCK|O_NOCTTY);
! if (masterfd == -1) {
! zerror(zlogp, B_TRUE, "failed to open console master");
(void) mutex_lock(&lock);
goto death;
}
/*
--- 906,926 ----
* happen.
*/
void
serve_console(zlog_t *zlogp)
{
! int managerfd;
zone_state_t zstate;
char conspath[MAXPATHLEN];
(void) snprintf(conspath, sizeof (conspath),
! "/dev/zcons/%s/%s", zone_name, ZCONS_MANAGER_NAME);
for (;;) {
! managerfd = open(conspath, O_RDWR|O_NONBLOCK|O_NOCTTY);
! if (managerfd == -1) {
! zerror(zlogp, B_TRUE, "failed to open console manager");
(void) mutex_lock(&lock);
goto death;
}
/*
*** 924,950 ****
* portion of messages received (which we don't care about)
* will be discarded by the stream head. If we allowed such
* messages, we wouldn't be able to use read(2), as it fails
* (EBADMSG) when a message with a control element is received.
*/
! if (ioctl(masterfd, I_SRDOPT, RNORM|RPROTDIS) == -1) {
zerror(zlogp, B_TRUE, "failed to set options on "
! "console master");
(void) mutex_lock(&lock);
goto death;
}
! do_console_io(zlogp, masterfd, serverfd);
/*
* We would prefer not to do this, but hostile zone processes
* can cause the stream to become tainted, and reads will
* fail. So, in case something has gone seriously ill,
* we dismantle the stream and reopen the console when we
* take another lap.
*/
! (void) close(masterfd);
(void) mutex_lock(&lock);
/*
* We need to set death_throes (see below) atomically with
* respect to noticing that (a) we have no console client and
--- 928,954 ----
* portion of messages received (which we don't care about)
* will be discarded by the stream head. If we allowed such
* messages, we wouldn't be able to use read(2), as it fails
* (EBADMSG) when a message with a control element is received.
*/
! if (ioctl(managerfd, I_SRDOPT, RNORM|RPROTDIS) == -1) {
zerror(zlogp, B_TRUE, "failed to set options on "
! "console manager");
(void) mutex_lock(&lock);
goto death;
}
! do_console_io(zlogp, managerfd, serverfd);
/*
* We would prefer not to do this, but hostile zone processes
* can cause the stream to become tainted, and reads will
* fail. So, in case something has gone seriously ill,
* we dismantle the stream and reopen the console when we
* take another lap.
*/
! (void) close(managerfd);
(void) mutex_lock(&lock);
/*
* We need to set death_throes (see below) atomically with
* respect to noticing that (a) we have no console client and