Print this page
Merge cleanup from previous six commits
OS-2564 zone boot failed: could not start zoneadmd


 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);