101 #include <stropts.h>
102 #include <thread.h>
103 #include <ucred.h>
104 #include <unistd.h>
105 #include <zone.h>
106
107 #include <libdevinfo.h>
108 #include <libdevice.h>
109 #include <libzonecfg.h>
110
111 #include <syslog.h>
112 #include <sys/modctl.h>
113
114 #include "zoneadmd.h"
115
116 #define ZCONSNEX_DEVTREEPATH "/pseudo/zconsnex@1"
117 #define ZCONSNEX_FILEPATH "/devices/pseudo/zconsnex@1"
118
119 #define CONSOLE_SOCKPATH ZONES_TMPDIR "/%s.console_sock"
120
121 static int serverfd = -1; /* console server unix domain socket fd */
122 char boot_args[BOOTARGS_MAX];
123
124 /*
125 * The eventstream is a simple one-directional flow of messages from the
126 * door server to the console subsystem, implemented with a pipe.
127 * It is used to wake up the console poller when it needs to take action,
128 * message the user, die off, etc.
129 */
130 static int eventstream[2];
131
132
133
134 int
135 eventstream_init()
136 {
137 if (pipe(eventstream) == -1)
138 return (-1);
139 return (0);
140 }
141
142 void
143 eventstream_write(zone_evt_t evt)
144 {
145 (void) write(eventstream[0], &evt, sizeof (evt));
146 }
147
148 static zone_evt_t
149 eventstream_read(void)
150 {
151 zone_evt_t evt = Z_EVT_NULL;
152
153 (void) read(eventstream[1], &evt, sizeof (evt));
390 "property");
391 goto error;
392 }
393 if (devctl_bus_dev_create(bus_hdl, ddef_hdl, 0, &dev_hdl) == -1) {
394 zerror(zlogp, B_TRUE, "failed to create console node");
395 goto error;
396 }
397
398 devlinks:
399 if ((dl = di_devlink_init("zcons", DI_MAKE_LINK)) != NULL) {
400 (void) di_devlink_fini(&dl);
401 } else {
402 zerror(zlogp, B_TRUE, "failed to create devlinks");
403 goto error;
404 }
405
406 /*
407 * Open the master side of the console and issue the ZC_HOLDSLAVE ioctl,
408 * which will cause the master to retain a reference to the slave.
409 * This prevents ttymon from blowing through the slave's STREAMS anchor.
410 */
411 (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
412 zone_name, ZCONS_MASTER_NAME);
413 if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
414 zerror(zlogp, B_TRUE, "ERROR: could not open master side of "
415 "zone console for %s to acquire slave handle", zone_name);
416 goto error;
417 }
418 (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
419 zone_name, ZCONS_SLAVE_NAME);
420 if ((slavefd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
421 zerror(zlogp, B_TRUE, "ERROR: could not open slave side of zone"
422 " console for %s to acquire slave handle", zone_name);
423 (void) close(masterfd);
424 goto error;
425 }
426 /*
427 * This ioctl can occasionally return ENXIO if devfs doesn't have
428 * everything plumbed up yet due to heavy zone startup load. Wait for
429 * 1 sec. and retry a few times before we fail to boot the zone.
430 */
431 for (i = 0; i < 5; i++) {
432 if (ioctl(masterfd, ZC_HOLDSLAVE, (caddr_t)(intptr_t)slavefd)
433 == 0) {
434 rv = 0;
435 break;
436 } else if (errno != ENXIO) {
437 break;
438 }
439 (void) sleep(1);
440 }
441 if (rv != 0)
442 zerror(zlogp, B_TRUE, "ERROR: error while acquiring slave "
443 "handle of zone console for %s", zone_name);
444
445 (void) close(slavefd);
446 (void) close(masterfd);
447
448 error:
449 if (ddef_hdl)
450 devctl_ddef_free(ddef_hdl);
451 if (bus_hdl)
452 devctl_release(bus_hdl);
453 if (dev_hdl)
454 devctl_release(dev_hdl);
455 return (rv);
456 }
457
458 static int
459 init_console_sock(zlog_t *zlogp)
460 {
461 int servfd;
462 struct sockaddr_un servaddr;
463
464 bzero(&servaddr, sizeof (servaddr));
465 servaddr.sun_family = AF_UNIX;
857 if ((evt == Z_EVT_ZONE_HALTED ||
858 evt == Z_EVT_ZONE_BOOTFAILED) && disconnect) {
859 break;
860 }
861 }
862
863 }
864
865 if (clifd != -1) {
866 (void) shutdown(clifd, SHUT_RDWR);
867 (void) close(clifd);
868 }
869 }
870
871 int
872 init_console(zlog_t *zlogp)
873 {
874 if (init_console_dev(zlogp) == -1) {
875 zerror(zlogp, B_FALSE,
876 "console setup: device initialization failed");
877 return (-1);
878 }
879
880 if ((serverfd = init_console_sock(zlogp)) == -1) {
881 zerror(zlogp, B_FALSE,
882 "console setup: socket initialization failed");
883 return (-1);
884 }
885 return (0);
886 }
887
888 /*
889 * serve_console() is the master loop for driving console I/O. It is also the
890 * routine which is ultimately responsible for "pulling the plug" on zoneadmd
891 * when it realizes that the daemon should shut down.
892 *
893 * The rules for shutdown are: there must be no console client, and the zone
894 * state must be < ready. However, we need to give things a chance to actually
895 * get going when the daemon starts up-- otherwise the daemon would immediately
896 * exit on startup if the zone was in the installed state, so we first drop
897 * into the do_console_io() loop in order to give *something* a chance to
898 * happen.
899 */
900 void
901 serve_console(zlog_t *zlogp)
902 {
903 int masterfd;
904 zone_state_t zstate;
905 char conspath[MAXPATHLEN];
906
907 (void) snprintf(conspath, sizeof (conspath),
908 "/dev/zcons/%s/%s", zone_name, ZCONS_MASTER_NAME);
909
910 for (;;) {
911 masterfd = open(conspath, O_RDWR|O_NONBLOCK|O_NOCTTY);
912 if (masterfd == -1) {
913 zerror(zlogp, B_TRUE, "failed to open console master");
914 (void) mutex_lock(&lock);
915 goto death;
916 }
917
918 /*
919 * Setting RPROTDIS on the stream means that the control
920 * portion of messages received (which we don't care about)
921 * will be discarded by the stream head. If we allowed such
922 * messages, we wouldn't be able to use read(2), as it fails
923 * (EBADMSG) when a message with a control element is received.
924 */
925 if (ioctl(masterfd, I_SRDOPT, RNORM|RPROTDIS) == -1) {
926 zerror(zlogp, B_TRUE, "failed to set options on "
927 "console master");
928 (void) mutex_lock(&lock);
929 goto death;
930 }
931
932 do_console_io(zlogp, masterfd, serverfd);
|
101 #include <stropts.h>
102 #include <thread.h>
103 #include <ucred.h>
104 #include <unistd.h>
105 #include <zone.h>
106
107 #include <libdevinfo.h>
108 #include <libdevice.h>
109 #include <libzonecfg.h>
110
111 #include <syslog.h>
112 #include <sys/modctl.h>
113
114 #include "zoneadmd.h"
115
116 #define ZCONSNEX_DEVTREEPATH "/pseudo/zconsnex@1"
117 #define ZCONSNEX_FILEPATH "/devices/pseudo/zconsnex@1"
118
119 #define CONSOLE_SOCKPATH ZONES_TMPDIR "/%s.console_sock"
120
121 #define ZCONS_RETRY 10
122
123 static int serverfd = -1; /* console server unix domain socket fd */
124 char boot_args[BOOTARGS_MAX];
125
126 /*
127 * The eventstream is a simple one-directional flow of messages from the
128 * door server to the console subsystem, implemented with a pipe.
129 * It is used to wake up the console poller when it needs to take action,
130 * message the user, die off, etc.
131 */
132 static int eventstream[2];
133
134 /* flag used to cope with race creating master zcons devlink */
135 static boolean_t master_zcons_failed = B_FALSE;
136 /* flag to track if we've seen a state change when there is no master zcons */
137 static boolean_t state_changed = B_FALSE;
138
139 int
140 eventstream_init()
141 {
142 if (pipe(eventstream) == -1)
143 return (-1);
144 return (0);
145 }
146
147 void
148 eventstream_write(zone_evt_t evt)
149 {
150 (void) write(eventstream[0], &evt, sizeof (evt));
151 }
152
153 static zone_evt_t
154 eventstream_read(void)
155 {
156 zone_evt_t evt = Z_EVT_NULL;
157
158 (void) read(eventstream[1], &evt, sizeof (evt));
395 "property");
396 goto error;
397 }
398 if (devctl_bus_dev_create(bus_hdl, ddef_hdl, 0, &dev_hdl) == -1) {
399 zerror(zlogp, B_TRUE, "failed to create console node");
400 goto error;
401 }
402
403 devlinks:
404 if ((dl = di_devlink_init("zcons", DI_MAKE_LINK)) != NULL) {
405 (void) di_devlink_fini(&dl);
406 } else {
407 zerror(zlogp, B_TRUE, "failed to create devlinks");
408 goto error;
409 }
410
411 /*
412 * Open the master side of the console and issue the ZC_HOLDSLAVE ioctl,
413 * which will cause the master to retain a reference to the slave.
414 * This prevents ttymon from blowing through the slave's STREAMS anchor.
415 *
416 * In very rare cases the open returns ENOENT if devfs doesn't have
417 * everything setup yet due to heavy zone startup load. Wait for
418 * 1 sec. and retry a few times. Even if we can't setup the zone's
419 * console, we still go ahead and boot the zone.
420 */
421 (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
422 zone_name, ZCONS_MASTER_NAME);
423 if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) {
424 zerror(zlogp, B_TRUE, "ERROR: could not open master side of "
425 "zone console for %s to acquire slave handle", zone_name);
426 master_zcons_failed = B_TRUE;
427 }
428 (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s",
429 zone_name, ZCONS_SLAVE_NAME);
430 for (i = 0; i < ZCONS_RETRY; i++) {
431 slavefd = open(conspath, O_RDWR | O_NOCTTY);
432 if (slavefd >= 0 || errno != ENOENT)
433 break;
434 (void) sleep(1);
435 }
436 if (slavefd == -1)
437 zerror(zlogp, B_TRUE, "ERROR: could not open slave side of zone"
438 " console for %s to acquire slave handle", zone_name);
439
440 /*
441 * This ioctl can occasionally return ENXIO if devfs doesn't have
442 * everything plumbed up yet due to heavy zone startup load. Wait for
443 * 1 sec. and retry a few times before we fail to boot the zone.
444 */
445 if (masterfd != -1 && slavefd != -1) {
446 for (i = 0; i < ZCONS_RETRY; i++) {
447 if (ioctl(masterfd, ZC_HOLDSLAVE,
448 (caddr_t)(intptr_t)slavefd) == 0) {
449 rv = 0;
450 break;
451 } else if (errno != ENXIO) {
452 break;
453 }
454 (void) sleep(1);
455 }
456 if (rv != 0)
457 zerror(zlogp, B_TRUE, "ERROR: error while acquiring "
458 "slave handle of zone console for %s", zone_name);
459 }
460
461 if (slavefd != -1)
462 (void) close(slavefd);
463 if (masterfd != -1)
464 (void) close(masterfd);
465
466 error:
467 if (ddef_hdl)
468 devctl_ddef_free(ddef_hdl);
469 if (bus_hdl)
470 devctl_release(bus_hdl);
471 if (dev_hdl)
472 devctl_release(dev_hdl);
473 return (rv);
474 }
475
476 static int
477 init_console_sock(zlog_t *zlogp)
478 {
479 int servfd;
480 struct sockaddr_un servaddr;
481
482 bzero(&servaddr, sizeof (servaddr));
483 servaddr.sun_family = AF_UNIX;
875 if ((evt == Z_EVT_ZONE_HALTED ||
876 evt == Z_EVT_ZONE_BOOTFAILED) && disconnect) {
877 break;
878 }
879 }
880
881 }
882
883 if (clifd != -1) {
884 (void) shutdown(clifd, SHUT_RDWR);
885 (void) close(clifd);
886 }
887 }
888
889 int
890 init_console(zlog_t *zlogp)
891 {
892 if (init_console_dev(zlogp) == -1) {
893 zerror(zlogp, B_FALSE,
894 "console setup: device initialization failed");
895 }
896
897 if ((serverfd = init_console_sock(zlogp)) == -1) {
898 zerror(zlogp, B_FALSE,
899 "console setup: socket initialization failed");
900 return (-1);
901 }
902 return (0);
903 }
904
905 /*
906 * Maintain a simple flag that tracks if we have seen at least one state
907 * change. This is currently only used to handle the special case where we are
908 * running without a console device, which is what normally drives shutdown.
909 */
910 void
911 zcons_statechanged()
912 {
913 state_changed = B_TRUE;
914 }
915
916 /*
917 * serve_console() is the master loop for driving console I/O. It is also the
918 * routine which is ultimately responsible for "pulling the plug" on zoneadmd
919 * when it realizes that the daemon should shut down.
920 *
921 * The rules for shutdown are: there must be no console client, and the zone
922 * state must be < ready. However, we need to give things a chance to actually
923 * get going when the daemon starts up-- otherwise the daemon would immediately
924 * exit on startup if the zone was in the installed state, so we first drop
925 * into the do_console_io() loop in order to give *something* a chance to
926 * happen.
927 */
928 void
929 serve_console(zlog_t *zlogp)
930 {
931 int masterfd;
932 zone_state_t zstate;
933 char conspath[MAXPATHLEN];
934 static boolean_t cons_warned = B_FALSE;
935
936 (void) snprintf(conspath, sizeof (conspath),
937 "/dev/zcons/%s/%s", zone_name, ZCONS_MASTER_NAME);
938
939 for (;;) {
940 masterfd = open(conspath, O_RDWR|O_NONBLOCK|O_NOCTTY);
941 if (masterfd == -1) {
942 if (master_zcons_failed) {
943 /*
944 * If we don't have a console and the zone is
945 * not shutting down, there may have been a
946 * race/failure with devfs while creating the
947 * console. In this case we want to leave the
948 * zone up, even without a console, so
949 * periodically recheck.
950 */
951 int i;
952
953 /*
954 * In the normal flow of this loop, we use
955 * do_console_io to give things a chance to get
956 * going first. However, in this case we can't
957 * use that, so we have to wait for at least
958 * one state change before checking the state.
959 */
960 for (i = 0; i < 60; i++) {
961 if (state_changed)
962 break;
963 (void) sleep(1);
964 }
965
966 if (i < 60 && zone_get_state(zone_name,
967 &zstate) == Z_OK &&
968 (zstate == ZONE_STATE_READY ||
969 zstate == ZONE_STATE_RUNNING)) {
970 if (!cons_warned) {
971 zerror(zlogp, B_FALSE,
972 "WARNING: missing zone "
973 "console for %s",
974 zone_name);
975 cons_warned = B_TRUE;
976 }
977 (void) sleep(ZCONS_RETRY);
978 continue;
979 }
980 }
981
982 zerror(zlogp, B_TRUE, "failed to open console master");
983 (void) mutex_lock(&lock);
984 goto death;
985 }
986
987 /*
988 * Setting RPROTDIS on the stream means that the control
989 * portion of messages received (which we don't care about)
990 * will be discarded by the stream head. If we allowed such
991 * messages, we wouldn't be able to use read(2), as it fails
992 * (EBADMSG) when a message with a control element is received.
993 */
994 if (ioctl(masterfd, I_SRDOPT, RNORM|RPROTDIS) == -1) {
995 zerror(zlogp, B_TRUE, "failed to set options on "
996 "console master");
997 (void) mutex_lock(&lock);
998 goto death;
999 }
1000
1001 do_console_io(zlogp, masterfd, serverfd);
|