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