zoneadmd.c (6a634c9dca3093f3922e4b7ab826d7bdf17bf78e) | zoneadmd.c (3c7284bd3243d42a710edac3a15f6019b4c849be) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 7 unchanged lines hidden (view full) --- 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 7 unchanged lines hidden (view full) --- 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
24 * Copyright 2014 Nexenta Systems, Inc. All rights reserved. |
|
24 */ 25 26/* 27 * zoneadmd manages zones; one zoneadmd process is launched for each 28 * non-global zone on the system. This daemon juggles four jobs: 29 * 30 * - Implement setup and teardown of the zone "virtual platform": mount and 31 * unmount filesystems; create and destroy network interfaces; communicate --- 62 unchanged lines hidden (view full) --- 94#include <sys/brand.h> 95#include <libcontract.h> 96#include <libcontract_priv.h> 97#include <sys/brand.h> 98#include <sys/contract/process.h> 99#include <sys/ctfs.h> 100#include <libdladm.h> 101#include <sys/dls_mgmt.h> | 25 */ 26 27/* 28 * zoneadmd manages zones; one zoneadmd process is launched for each 29 * non-global zone on the system. This daemon juggles four jobs: 30 * 31 * - Implement setup and teardown of the zone "virtual platform": mount and 32 * unmount filesystems; create and destroy network interfaces; communicate --- 62 unchanged lines hidden (view full) --- 95#include <sys/brand.h> 96#include <libcontract.h> 97#include <libcontract_priv.h> 98#include <sys/brand.h> 99#include <sys/contract/process.h> 100#include <sys/ctfs.h> 101#include <libdladm.h> 102#include <sys/dls_mgmt.h> |
103#include <libscf.h> |
|
102 103#include <libzonecfg.h> 104#include <zonestat_impl.h> 105#include "zoneadmd.h" 106 107static char *progname; 108char *zone_name; /* zone which we are managing */ 109char pool_name[MAXNAMELEN]; 110char default_brand[MAXNAMELEN]; 111char brand_name[MAXNAMELEN]; 112boolean_t zone_isnative; 113boolean_t zone_iscluster; 114boolean_t zone_islabeled; | 104 105#include <libzonecfg.h> 106#include <zonestat_impl.h> 107#include "zoneadmd.h" 108 109static char *progname; 110char *zone_name; /* zone which we are managing */ 111char pool_name[MAXNAMELEN]; 112char default_brand[MAXNAMELEN]; 113char brand_name[MAXNAMELEN]; 114boolean_t zone_isnative; 115boolean_t zone_iscluster; 116boolean_t zone_islabeled; |
117boolean_t shutdown_in_progress; |
|
115static zoneid_t zone_id; 116dladm_handle_t dld_handle = NULL; 117 118static char pre_statechg_hook[2 * MAXPATHLEN]; 119static char post_statechg_hook[2 * MAXPATHLEN]; 120char query_hook[2 * MAXPATHLEN]; 121 122zlog_t logsys; --- 16 unchanged lines hidden (view full) --- 139#define DEFAULT_LOCALE "C" 140 141static const char * 142z_cmd_name(zone_cmd_t zcmd) 143{ 144 /* This list needs to match the enum in sys/zone.h */ 145 static const char *zcmdstr[] = { 146 "ready", "boot", "forceboot", "reboot", "halt", | 118static zoneid_t zone_id; 119dladm_handle_t dld_handle = NULL; 120 121static char pre_statechg_hook[2 * MAXPATHLEN]; 122static char post_statechg_hook[2 * MAXPATHLEN]; 123char query_hook[2 * MAXPATHLEN]; 124 125zlog_t logsys; --- 16 unchanged lines hidden (view full) --- 142#define DEFAULT_LOCALE "C" 143 144static const char * 145z_cmd_name(zone_cmd_t zcmd) 146{ 147 /* This list needs to match the enum in sys/zone.h */ 148 static const char *zcmdstr[] = { 149 "ready", "boot", "forceboot", "reboot", "halt", |
147 "note_uninstalling", "mount", "forcemount", "unmount" | 150 "note_uninstalling", "mount", "forcemount", "unmount", 151 "shutdown" |
148 }; 149 150 if (zcmd >= sizeof (zcmdstr) / sizeof (*zcmdstr)) 151 return ("unknown"); 152 else 153 return (zcmdstr[(int)zcmd]); 154} 155 --- 825 unchanged lines hidden (view full) --- 981 zonecfg_strerror(err)); 982 983 if (brand_poststatechg(zlogp, zstate, Z_HALT) != 0) 984 return (-1); 985 986 return (0); 987} 988 | 152 }; 153 154 if (zcmd >= sizeof (zcmdstr) / sizeof (*zcmdstr)) 155 return ("unknown"); 156 else 157 return (zcmdstr[(int)zcmd]); 158} 159 --- 825 unchanged lines hidden (view full) --- 985 zonecfg_strerror(err)); 986 987 if (brand_poststatechg(zlogp, zstate, Z_HALT) != 0) 988 return (-1); 989 990 return (0); 991} 992 |
993static int 994zone_graceful_shutdown(zlog_t *zlogp) 995{ 996 zoneid_t zoneid; 997 pid_t child; 998 char cmdbuf[MAXPATHLEN]; 999 brand_handle_t bh = NULL; 1000 char zpath[MAXPATHLEN]; 1001 ctid_t ct; 1002 int tmpl_fd; 1003 int child_status; 1004 1005 if (shutdown_in_progress) { 1006 zerror(zlogp, B_FALSE, "shutdown already in progress"); 1007 return (-1); 1008 } 1009 1010 if ((zoneid = getzoneidbyname(zone_name)) == -1) { 1011 zerror(zlogp, B_TRUE, "unable to get zoneid"); 1012 return (-1); 1013 } 1014 1015 /* Get a handle to the brand info for this zone */ 1016 if ((bh = brand_open(brand_name)) == NULL) { 1017 zerror(zlogp, B_FALSE, "unable to determine zone brand"); 1018 return (-1); 1019 } 1020 1021 if (zone_get_zonepath(zone_name, zpath, sizeof (zpath)) != Z_OK) { 1022 zerror(zlogp, B_FALSE, "unable to determine zone path"); 1023 brand_close(bh); 1024 return (-1); 1025 } 1026 1027 /* 1028 * If there is a brand 'shutdown' callback, execute it now to give the 1029 * brand a chance to cleanup any custom configuration. 1030 */ 1031 (void) strcpy(cmdbuf, EXEC_PREFIX); 1032 if (brand_get_shutdown(bh, zone_name, zpath, cmdbuf + EXEC_LEN, 1033 sizeof (cmdbuf) - EXEC_LEN) != 0 || strlen(cmdbuf) <= EXEC_LEN) { 1034 (void) strcat(cmdbuf, SHUTDOWN_DEFAULT); 1035 } 1036 brand_close(bh); 1037 1038 if ((tmpl_fd = init_template()) == -1) { 1039 zerror(zlogp, B_TRUE, "failed to create contract"); 1040 return (-1); 1041 } 1042 1043 if ((child = fork()) == -1) { 1044 (void) ct_tmpl_clear(tmpl_fd); 1045 (void) close(tmpl_fd); 1046 zerror(zlogp, B_TRUE, "failed to fork"); 1047 return (-1); 1048 } else if (child == 0) { 1049 (void) ct_tmpl_clear(tmpl_fd); 1050 if (zone_enter(zoneid) == -1) { 1051 _exit(errno); 1052 } 1053 _exit(execl("/bin/sh", "sh", "-c", cmdbuf, (char *)NULL)); 1054 } 1055 1056 if (contract_latest(&ct) == -1) 1057 ct = -1; 1058 (void) ct_tmpl_clear(tmpl_fd); 1059 (void) close(tmpl_fd); 1060 1061 if (waitpid(child, &child_status, 0) != child) { 1062 /* unexpected: we must have been signalled */ 1063 (void) contract_abandon_id(ct); 1064 return (-1); 1065 } 1066 1067 (void) contract_abandon_id(ct); 1068 if (WEXITSTATUS(child_status) != 0) { 1069 errno = WEXITSTATUS(child_status); 1070 zerror(zlogp, B_FALSE, "unable to shutdown zone"); 1071 return (-1); 1072 } 1073 1074 shutdown_in_progress = B_TRUE; 1075 1076 return (0); 1077} 1078 1079static int 1080zone_wait_shutdown(zlog_t *zlogp) 1081{ 1082 zone_state_t zstate; 1083 uint64_t *tm = NULL; 1084 scf_simple_prop_t *prop = NULL; 1085 int timeout; 1086 int tries; 1087 int rc = -1; 1088 1089 /* Get default stop timeout from SMF framework */ 1090 timeout = SHUTDOWN_WAIT; 1091 if ((prop = scf_simple_prop_get(NULL, SHUTDOWN_FMRI, "stop", 1092 SCF_PROPERTY_TIMEOUT)) != NULL) { 1093 if ((tm = scf_simple_prop_next_count(prop)) != NULL) { 1094 if (tm != 0) 1095 timeout = *tm; 1096 } 1097 scf_simple_prop_free(prop); 1098 } 1099 1100 /* allow time for zone to shutdown cleanly */ 1101 for (tries = 0; tries < timeout; tries ++) { 1102 (void) sleep(1); 1103 if (zone_get_state(zone_name, &zstate) == Z_OK && 1104 zstate == ZONE_STATE_INSTALLED) { 1105 rc = 0; 1106 break; 1107 } 1108 } 1109 1110 if (rc != 0) 1111 zerror(zlogp, B_FALSE, "unable to shutdown zone"); 1112 1113 shutdown_in_progress = B_FALSE; 1114 1115 return (rc); 1116} 1117 1118 1119 |
|
989/* 990 * Generate AUE_zone_state for a command that boots a zone. 991 */ 992static void 993audit_put_record(zlog_t *zlogp, ucred_t *uc, int return_val, 994 char *new_state) 995{ 996 adt_session_data_t *ah; --- 59 unchanged lines hidden (view full) --- 1056 uint64_t uniqid; 1057 zoneid_t zoneid = -1; 1058 zlog_t zlog; 1059 zlog_t *zlogp; 1060 zone_cmd_rval_t *rvalp; 1061 size_t rlen = getpagesize(); /* conservative */ 1062 fs_callback_t cb; 1063 brand_handle_t bh; | 1120/* 1121 * Generate AUE_zone_state for a command that boots a zone. 1122 */ 1123static void 1124audit_put_record(zlog_t *zlogp, ucred_t *uc, int return_val, 1125 char *new_state) 1126{ 1127 adt_session_data_t *ah; --- 59 unchanged lines hidden (view full) --- 1187 uint64_t uniqid; 1188 zoneid_t zoneid = -1; 1189 zlog_t zlog; 1190 zlog_t *zlogp; 1191 zone_cmd_rval_t *rvalp; 1192 size_t rlen = getpagesize(); /* conservative */ 1193 fs_callback_t cb; 1194 brand_handle_t bh; |
1195 boolean_t wait_shut = B_FALSE; |
|
1064 1065 /* LINTED E_BAD_PTR_CAST_ALIGN */ 1066 zargp = (zone_cmd_arg_t *)args; 1067 1068 /* 1069 * When we get the door unref message, we've fdetach'd the door, and 1070 * it is time for us to shut down zoneadmd. 1071 */ --- 60 unchanged lines hidden (view full) --- 1132 (void) door_return(NULL, 0, 0, 0); 1133 thr_exit(NULL); 1134 } 1135 1136 /* 1137 * Check for validity of command. 1138 */ 1139 if (cmd != Z_READY && cmd != Z_BOOT && cmd != Z_FORCEBOOT && | 1196 1197 /* LINTED E_BAD_PTR_CAST_ALIGN */ 1198 zargp = (zone_cmd_arg_t *)args; 1199 1200 /* 1201 * When we get the door unref message, we've fdetach'd the door, and 1202 * it is time for us to shut down zoneadmd. 1203 */ --- 60 unchanged lines hidden (view full) --- 1264 (void) door_return(NULL, 0, 0, 0); 1265 thr_exit(NULL); 1266 } 1267 1268 /* 1269 * Check for validity of command. 1270 */ 1271 if (cmd != Z_READY && cmd != Z_BOOT && cmd != Z_FORCEBOOT && |
1140 cmd != Z_REBOOT && cmd != Z_HALT && cmd != Z_NOTE_UNINSTALLING && 1141 cmd != Z_MOUNT && cmd != Z_FORCEMOUNT && cmd != Z_UNMOUNT) { | 1272 cmd != Z_REBOOT && cmd != Z_SHUTDOWN && cmd != Z_HALT && 1273 cmd != Z_NOTE_UNINSTALLING && cmd != Z_MOUNT && 1274 cmd != Z_FORCEMOUNT && cmd != Z_UNMOUNT) { |
1142 zerror(&logsys, B_FALSE, "invalid command %d", (int)cmd); 1143 goto out; 1144 } 1145 1146 if (kernelcall && (cmd != Z_HALT && cmd != Z_REBOOT)) { 1147 /* 1148 * Can't happen 1149 */ --- 69 unchanged lines hidden (view full) --- 1219 audit_put_record(zlogp, uc, rval, "boot"); 1220 if (rval != 0) { 1221 bringup_failure_recovery = B_TRUE; 1222 (void) zone_halt(zlogp, B_FALSE, B_FALSE, 1223 zstate); 1224 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 1225 } 1226 break; | 1275 zerror(&logsys, B_FALSE, "invalid command %d", (int)cmd); 1276 goto out; 1277 } 1278 1279 if (kernelcall && (cmd != Z_HALT && cmd != Z_REBOOT)) { 1280 /* 1281 * Can't happen 1282 */ --- 69 unchanged lines hidden (view full) --- 1352 audit_put_record(zlogp, uc, rval, "boot"); 1353 if (rval != 0) { 1354 bringup_failure_recovery = B_TRUE; 1355 (void) zone_halt(zlogp, B_FALSE, B_FALSE, 1356 zstate); 1357 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 1358 } 1359 break; |
1360 case Z_SHUTDOWN: |
|
1227 case Z_HALT: 1228 if (kernelcall) /* Invalid; can't happen */ 1229 abort(); 1230 /* 1231 * We could have two clients racing to halt this 1232 * zone; the second client loses, but his request 1233 * doesn't fail, since the zone is now in the desired 1234 * state. --- 114 unchanged lines hidden (view full) --- 1349 case Z_HALT: 1350 if (kernelcall) /* Invalid; can't happen */ 1351 abort(); 1352 if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate)) 1353 != 0) 1354 break; 1355 eventstream_write(Z_EVT_ZONE_HALTED); 1356 break; | 1361 case Z_HALT: 1362 if (kernelcall) /* Invalid; can't happen */ 1363 abort(); 1364 /* 1365 * We could have two clients racing to halt this 1366 * zone; the second client loses, but his request 1367 * doesn't fail, since the zone is now in the desired 1368 * state. --- 114 unchanged lines hidden (view full) --- 1483 case Z_HALT: 1484 if (kernelcall) /* Invalid; can't happen */ 1485 abort(); 1486 if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate)) 1487 != 0) 1488 break; 1489 eventstream_write(Z_EVT_ZONE_HALTED); 1490 break; |
1491 case Z_SHUTDOWN: |
|
1357 case Z_REBOOT: 1358 case Z_NOTE_UNINSTALLING: 1359 case Z_MOUNT: 1360 case Z_UNMOUNT: 1361 if (kernelcall) /* Invalid; can't happen */ 1362 abort(); 1363 zerror(zlogp, B_FALSE, "%s operation is invalid " 1364 "for zones in state '%s'", z_cmd_name(cmd), --- 74 unchanged lines hidden (view full) --- 1439 audit_put_record(zlogp, uc, rval, "reboot"); 1440 if (rval != 0) { 1441 (void) zone_halt(zlogp, B_FALSE, B_TRUE, 1442 zstate); 1443 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 1444 } 1445 boot_args[0] = '\0'; 1446 break; | 1492 case Z_REBOOT: 1493 case Z_NOTE_UNINSTALLING: 1494 case Z_MOUNT: 1495 case Z_UNMOUNT: 1496 if (kernelcall) /* Invalid; can't happen */ 1497 abort(); 1498 zerror(zlogp, B_FALSE, "%s operation is invalid " 1499 "for zones in state '%s'", z_cmd_name(cmd), --- 74 unchanged lines hidden (view full) --- 1574 audit_put_record(zlogp, uc, rval, "reboot"); 1575 if (rval != 0) { 1576 (void) zone_halt(zlogp, B_FALSE, B_TRUE, 1577 zstate); 1578 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 1579 } 1580 boot_args[0] = '\0'; 1581 break; |
1582 case Z_SHUTDOWN: 1583 if ((rval = zone_graceful_shutdown(zlogp)) == 0) { 1584 wait_shut = B_TRUE; 1585 } 1586 break; |
|
1447 case Z_NOTE_UNINSTALLING: 1448 case Z_MOUNT: 1449 case Z_UNMOUNT: 1450 zerror(zlogp, B_FALSE, "%s operation is invalid " 1451 "for zones in state '%s'", z_cmd_name(cmd), 1452 zone_state_str(zstate)); 1453 rval = -1; 1454 break; --- 7 unchanged lines hidden (view full) --- 1462 * Because the state of the zone may have changed, we make sure 1463 * to wake the console poller, which is in charge of initiating 1464 * the shutdown procedure as necessary. 1465 */ 1466 eventstream_write(Z_EVT_NULL); 1467 1468out: 1469 (void) mutex_unlock(&lock); | 1587 case Z_NOTE_UNINSTALLING: 1588 case Z_MOUNT: 1589 case Z_UNMOUNT: 1590 zerror(zlogp, B_FALSE, "%s operation is invalid " 1591 "for zones in state '%s'", z_cmd_name(cmd), 1592 zone_state_str(zstate)); 1593 rval = -1; 1594 break; --- 7 unchanged lines hidden (view full) --- 1602 * Because the state of the zone may have changed, we make sure 1603 * to wake the console poller, which is in charge of initiating 1604 * the shutdown procedure as necessary. 1605 */ 1606 eventstream_write(Z_EVT_NULL); 1607 1608out: 1609 (void) mutex_unlock(&lock); |
1610 1611 /* Wait for the Z_SHUTDOWN commands to complete */ 1612 if (wait_shut) 1613 rval = zone_wait_shutdown(zlogp); 1614 |
|
1470 if (kernelcall) { 1471 rvalp = NULL; 1472 rlen = 0; 1473 } else { 1474 rvalp->rval = rval; 1475 } 1476 if (uc != NULL) 1477 ucred_free(uc); --- 659 unchanged lines hidden --- | 1615 if (kernelcall) { 1616 rvalp = NULL; 1617 rlen = 0; 1618 } else { 1619 rvalp->rval = rval; 1620 } 1621 if (uc != NULL) 1622 ucred_free(uc); --- 659 unchanged lines hidden --- |