Print this page
5700 add zlogin -d option to allow graceful disconnect when zone is halted
Reviewed by: Andrew Gabriel <illumos@cucumber.demon.co.uk>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

*** 21,30 **** --- 21,31 ---- /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright 2012 Joyent, Inc. All rights reserved. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* * Console support for zones requires a significant infrastructure. The * core pieces are contained in this file, but other portions of note
*** 507,517 **** * Read the "ident" string from the client's descriptor; this routine also * tolerates being called with pid=NULL, for times when you want to "eat" * the ident string from a client without saving it. */ static int ! get_client_ident(int clifd, pid_t *pid, char *locale, size_t locale_len) { char buf[BUFSIZ], *bufp; size_t buflen = sizeof (buf); char c = '\0'; int i = 0, r; --- 508,519 ---- * Read the "ident" string from the client's descriptor; this routine also * tolerates being called with pid=NULL, for times when you want to "eat" * the ident string from a client without saving it. */ static int ! get_client_ident(int clifd, pid_t *pid, char *locale, size_t locale_len, ! int *disconnect) { char buf[BUFSIZ], *bufp; size_t buflen = sizeof (buf); char c = '\0'; int i = 0, r;
*** 547,557 **** if (c == '\n') break; } /* ! * Parse buffer for message of the form: IDENT <pid> <locale> */ bufp = buf; if (strncmp(bufp, "IDENT ", 6) != 0) return (-1); bufp += 6; --- 549,560 ---- if (c == '\n') break; } /* ! * Parse buffer for message of the form: ! * IDENT <pid> <locale> <disconnect flag> */ bufp = buf; if (strncmp(bufp, "IDENT ", 6) != 0) return (-1); bufp += 6;
*** 560,586 **** if (errno != 0) return (-1); while (*bufp != '\0' && isspace(*bufp)) bufp++; (void) strlcpy(locale, bufp, locale_len); return (0); } static int ! accept_client(int servfd, pid_t *pid, char *locale, size_t locale_len) { int connfd; struct sockaddr_un cliaddr; socklen_t clilen; clilen = sizeof (cliaddr); connfd = accept(servfd, (struct sockaddr *)&cliaddr, &clilen); if (connfd == -1) return (-1); ! if (get_client_ident(connfd, pid, locale, locale_len) == -1) { (void) shutdown(connfd, SHUT_RDWR); (void) close(connfd); return (-1); } (void) write(connfd, "OK\n", 3); --- 563,594 ---- if (errno != 0) return (-1); while (*bufp != '\0' && isspace(*bufp)) bufp++; + buflen = strlen(bufp) - 1; + *disconnect = atoi(&bufp[buflen]); + bufp[buflen - 1] = '\0'; (void) strlcpy(locale, bufp, locale_len); return (0); } static int ! accept_client(int servfd, pid_t *pid, char *locale, size_t locale_len, ! int *disconnect) { int connfd; struct sockaddr_un cliaddr; socklen_t clilen; clilen = sizeof (cliaddr); connfd = accept(servfd, (struct sockaddr *)&cliaddr, &clilen); if (connfd == -1) return (-1); ! if (get_client_ident(connfd, pid, locale, locale_len, ! disconnect) == -1) { (void) shutdown(connfd, SHUT_RDWR); (void) close(connfd); return (-1); } (void) write(connfd, "OK\n", 3);
*** 599,619 **** connfd = accept(servfd, (struct sockaddr *)&cliaddr, &clilen); /* * After hear its ident string, tell client to get lost. */ ! if (get_client_ident(connfd, NULL, NULL, 0) == 0) { (void) snprintf(nak, sizeof (nak), "%lu\n", clientpid); (void) write(connfd, nak, strlen(nak)); } (void) shutdown(connfd, SHUT_RDWR); (void) close(connfd); } static void ! event_message(int clifd, char *clilocale, zone_evt_t evt) { char *str, *lstr = NULL; char lmsg[BUFSIZ]; char outbuf[BUFSIZ]; --- 607,627 ---- connfd = accept(servfd, (struct sockaddr *)&cliaddr, &clilen); /* * After hear its ident string, tell client to get lost. */ ! if (get_client_ident(connfd, NULL, NULL, 0, NULL) == 0) { (void) snprintf(nak, sizeof (nak), "%lu\n", clientpid); (void) write(connfd, nak, strlen(nak)); } (void) shutdown(connfd, SHUT_RDWR); (void) close(connfd); } static void ! event_message(int clifd, char *clilocale, zone_evt_t evt, int dflag) { char *str, *lstr = NULL; char lmsg[BUFSIZ]; char outbuf[BUFSIZ];
*** 633,642 **** --- 641,653 ---- break; case Z_EVT_ZONE_READIED: str = "NOTICE: Zone readied"; break; case Z_EVT_ZONE_HALTED: + if (dflag) + str = "NOTICE: Zone halted. Disconnecting..."; + else str = "NOTICE: Zone halted"; break; case Z_EVT_ZONE_REBOOTING: if (*boot_args == '\0') { str = "NOTICE: Zone rebooting";
*** 649,658 **** --- 660,672 ---- break; case Z_EVT_ZONE_UNINSTALLING: str = "NOTICE: Zone is being uninstalled. Disconnecting..."; break; case Z_EVT_ZONE_BOOTFAILED: + if (dflag) + str = "NOTICE: Zone boot failed. Disconnecting..."; + else str = "NOTICE: Zone boot failed"; break; case Z_EVT_ZONE_BADARGS: /*LINTED*/ (void) snprintf(lmsg, sizeof (lmsg),
*** 706,715 **** --- 720,730 ---- int cc, ret; int clifd = -1; int pollerr = 0; char clilocale[MAXPATHLEN]; pid_t clipid = 0; + int disconnect = 0; /* console side, watch for read events */ pollfds[0].fd = consfd; pollfds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
*** 799,809 **** /* we're already handling a client */ reject_client(servfd, clipid); } else if ((clifd = accept_client(servfd, &clipid, ! clilocale, sizeof (clilocale))) != -1) { pollfds[1].fd = clifd; } else { break; } --- 814,825 ---- /* we're already handling a client */ reject_client(servfd, clipid); } else if ((clifd = accept_client(servfd, &clipid, ! clilocale, sizeof (clilocale), ! &disconnect)) != -1) { pollfds[1].fd = clifd; } else { break; }
*** 825,835 **** * service lap. */ if (clifd == -1) { break; } ! event_message(clifd, clilocale, evt); /* * Special handling for the message that the zone is * uninstalling; we boot the client, then break out * of this function. When we return to the * serve_console loop, we will see that the zone is --- 841,851 ---- * service lap. */ if (clifd == -1) { break; } ! event_message(clifd, clilocale, evt, disconnect); /* * Special handling for the message that the zone is * uninstalling; we boot the client, then break out * of this function. When we return to the * serve_console loop, we will see that the zone is
*** 836,845 **** --- 852,869 ---- * in a state < READY, and so zoneadmd will shutdown. */ if (evt == Z_EVT_ZONE_UNINSTALLING) { break; } + /* + * Diconnect if -C and -d options were specified and + * zone was halted or failed to boot. + */ + if ((evt == Z_EVT_ZONE_HALTED || + evt == Z_EVT_ZONE_BOOTFAILED) && disconnect) { + break; + } } } if (clifd != -1) {