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
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
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.
25 * Copyright (c) 2016 by Delphix. All rights reserved.
26 */
27
28 /*
29 * zoneadmd manages zones; one zoneadmd process is launched for each
30 * non-global zone on the system. This daemon juggles four jobs:
31 *
32 * - Implement setup and teardown of the zone "virtual platform": mount and
33 * unmount filesystems; create and destroy network interfaces; communicate
34 * with devfsadmd to lay out devices for the zone; instantiate the zone
35 * console device; configure process runtime attributes such as resource
36 * controls, pool bindings, fine-grained privileges.
37 *
38 * - Launch the zone's init(1M) process.
39 *
40 * - Implement a door server; clients (like zoneadm) connect to the door
41 * server and request zone state changes. The kernel is also a client of
42 * this door server. A request to halt or reboot the zone which originates
43 * *inside* the zone results in a door upcall from the kernel into zoneadmd.
44 *
45 * One minor problem is that messages emitted by zoneadmd need to be passed
100 #include <sys/contract/process.h>
101 #include <sys/ctfs.h>
102 #include <libdladm.h>
103 #include <sys/dls_mgmt.h>
104 #include <libscf.h>
105
106 #include <libzonecfg.h>
107 #include <zonestat_impl.h>
108 #include "zoneadmd.h"
109
110 static char *progname;
111 char *zone_name; /* zone which we are managing */
112 char pool_name[MAXNAMELEN];
113 char default_brand[MAXNAMELEN];
114 char brand_name[MAXNAMELEN];
115 boolean_t zone_isnative;
116 boolean_t zone_iscluster;
117 boolean_t zone_islabeled;
118 boolean_t shutdown_in_progress;
119 static zoneid_t zone_id;
120 dladm_handle_t dld_handle = NULL;
121
122 static char pre_statechg_hook[2 * MAXPATHLEN];
123 static char post_statechg_hook[2 * MAXPATHLEN];
124 char query_hook[2 * MAXPATHLEN];
125
126 zlog_t logsys;
127
128 mutex_t lock = DEFAULTMUTEX; /* to serialize stuff */
129 mutex_t msglock = DEFAULTMUTEX; /* for calling setlocale() */
130
131 static sema_t scratch_sem; /* for scratch zones */
132
133 static char zone_door_path[MAXPATHLEN];
134 static int zone_door = -1;
135
136 boolean_t in_death_throes = B_FALSE; /* daemon is dying */
137 boolean_t bringup_failure_recovery = B_FALSE; /* ignore certain failures */
138
139 #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
530
531 /*
532 * Bring a zone up to the pre-boot "ready" stage. The mount_cmd argument is
533 * 'true' if this is being invoked as part of the processing for the "mount"
534 * subcommand.
535 */
536 static int
537 zone_ready(zlog_t *zlogp, zone_mnt_t mount_cmd, int zstate)
538 {
539 int err;
540
541 if (brand_prestatechg(zlogp, zstate, Z_READY) != 0)
542 return (-1);
543
544 if ((err = zonecfg_create_snapshot(zone_name)) != Z_OK) {
545 zerror(zlogp, B_FALSE, "unable to create snapshot: %s",
546 zonecfg_strerror(err));
547 goto bad;
548 }
549
550 if ((zone_id = vplat_create(zlogp, mount_cmd)) == -1) {
551 if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
552 zerror(zlogp, B_FALSE, "destroying snapshot: %s",
553 zonecfg_strerror(err));
554 goto bad;
555 }
556 if (vplat_bringup(zlogp, mount_cmd, zone_id) != 0) {
557 bringup_failure_recovery = B_TRUE;
558 (void) vplat_teardown(NULL, (mount_cmd != Z_MNT_BOOT), B_FALSE);
559 if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
560 zerror(zlogp, B_FALSE, "destroying snapshot: %s",
561 zonecfg_strerror(err));
562 goto bad;
563 }
564
565 if (brand_poststatechg(zlogp, zstate, Z_READY) != 0)
566 goto bad;
567
568 return (0);
569
570 bad:
1338 case ZONE_STATE_INCOMPLETE:
1339 /*
1340 * Not our area of expertise; we just print a nice message
1341 * and die off.
1342 */
1343 zerror(zlogp, B_FALSE,
1344 "%s operation is invalid for zones in state '%s'",
1345 z_cmd_name(cmd), zone_state_str(zstate));
1346 break;
1347
1348 case ZONE_STATE_INSTALLED:
1349 switch (cmd) {
1350 case Z_READY:
1351 rval = zone_ready(zlogp, Z_MNT_BOOT, zstate);
1352 if (rval == 0)
1353 eventstream_write(Z_EVT_ZONE_READIED);
1354 break;
1355 case Z_BOOT:
1356 case Z_FORCEBOOT:
1357 eventstream_write(Z_EVT_ZONE_BOOTING);
1358 if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate))
1359 == 0) {
1360 rval = zone_bootup(zlogp, zargp->bootbuf,
1361 zstate);
1362 }
1363 audit_put_record(zlogp, uc, rval, "boot");
1364 if (rval != 0) {
1365 bringup_failure_recovery = B_TRUE;
1366 (void) zone_halt(zlogp, B_FALSE, B_FALSE,
1367 zstate);
1368 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1369 }
1370 break;
1371 case Z_SHUTDOWN:
1372 case Z_HALT:
1373 if (kernelcall) /* Invalid; can't happen */
1374 abort();
1375 /*
1376 * We could have two clients racing to halt this
1377 * zone; the second client loses, but its request
1378 * doesn't fail, since the zone is now in the desired
1379 * state.
1527 break;
1528 default:
1529 if (kernelcall) /* Invalid; can't happen */
1530 abort();
1531 zerror(zlogp, B_FALSE, "%s operation is invalid "
1532 "for zones in state '%s'", z_cmd_name(cmd),
1533 zone_state_str(zstate));
1534 rval = -1;
1535 break;
1536 }
1537 break;
1538
1539 case ZONE_STATE_RUNNING:
1540 case ZONE_STATE_SHUTTING_DOWN:
1541 case ZONE_STATE_DOWN:
1542 switch (cmd) {
1543 case Z_READY:
1544 if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate))
1545 != 0)
1546 break;
1547 if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) == 0)
1548 eventstream_write(Z_EVT_ZONE_READIED);
1549 else
1550 eventstream_write(Z_EVT_ZONE_HALTED);
1551 break;
1552 case Z_BOOT:
1553 /*
1554 * We could have two clients racing to boot this
1555 * zone; the second client loses, but its request
1556 * doesn't fail, since the zone is now in the desired
1557 * state.
1558 */
1559 zerror(zlogp, B_FALSE, "zone is already booted");
1560 rval = 0;
1561 break;
1562 case Z_HALT:
1563 if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate))
1564 != 0)
1565 break;
1566 eventstream_write(Z_EVT_ZONE_HALTED);
1567 break;
|
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
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
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.
25 * Copyright (c) 2016 by Delphix. All rights reserved.
26 * Copyright (c) 2011, Joyent Inc. All rights reserved.
27 */
28
29 /*
30 * zoneadmd manages zones; one zoneadmd process is launched for each
31 * non-global zone on the system. This daemon juggles four jobs:
32 *
33 * - Implement setup and teardown of the zone "virtual platform": mount and
34 * unmount filesystems; create and destroy network interfaces; communicate
35 * with devfsadmd to lay out devices for the zone; instantiate the zone
36 * console device; configure process runtime attributes such as resource
37 * controls, pool bindings, fine-grained privileges.
38 *
39 * - Launch the zone's init(1M) process.
40 *
41 * - Implement a door server; clients (like zoneadm) connect to the door
42 * server and request zone state changes. The kernel is also a client of
43 * this door server. A request to halt or reboot the zone which originates
44 * *inside* the zone results in a door upcall from the kernel into zoneadmd.
45 *
46 * One minor problem is that messages emitted by zoneadmd need to be passed
101 #include <sys/contract/process.h>
102 #include <sys/ctfs.h>
103 #include <libdladm.h>
104 #include <sys/dls_mgmt.h>
105 #include <libscf.h>
106
107 #include <libzonecfg.h>
108 #include <zonestat_impl.h>
109 #include "zoneadmd.h"
110
111 static char *progname;
112 char *zone_name; /* zone which we are managing */
113 char pool_name[MAXNAMELEN];
114 char default_brand[MAXNAMELEN];
115 char brand_name[MAXNAMELEN];
116 boolean_t zone_isnative;
117 boolean_t zone_iscluster;
118 boolean_t zone_islabeled;
119 boolean_t shutdown_in_progress;
120 static zoneid_t zone_id;
121 static zoneid_t zone_did = 0;
122 dladm_handle_t dld_handle = NULL;
123
124 static char pre_statechg_hook[2 * MAXPATHLEN];
125 static char post_statechg_hook[2 * MAXPATHLEN];
126 char query_hook[2 * MAXPATHLEN];
127
128 zlog_t logsys;
129
130 mutex_t lock = DEFAULTMUTEX; /* to serialize stuff */
131 mutex_t msglock = DEFAULTMUTEX; /* for calling setlocale() */
132
133 static sema_t scratch_sem; /* for scratch zones */
134
135 static char zone_door_path[MAXPATHLEN];
136 static int zone_door = -1;
137
138 boolean_t in_death_throes = B_FALSE; /* daemon is dying */
139 boolean_t bringup_failure_recovery = B_FALSE; /* ignore certain failures */
140
141 #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
532
533 /*
534 * Bring a zone up to the pre-boot "ready" stage. The mount_cmd argument is
535 * 'true' if this is being invoked as part of the processing for the "mount"
536 * subcommand.
537 */
538 static int
539 zone_ready(zlog_t *zlogp, zone_mnt_t mount_cmd, int zstate)
540 {
541 int err;
542
543 if (brand_prestatechg(zlogp, zstate, Z_READY) != 0)
544 return (-1);
545
546 if ((err = zonecfg_create_snapshot(zone_name)) != Z_OK) {
547 zerror(zlogp, B_FALSE, "unable to create snapshot: %s",
548 zonecfg_strerror(err));
549 goto bad;
550 }
551
552 if (zone_did == 0)
553 zone_did = zone_get_did(zone_name);
554
555 if ((zone_id = vplat_create(zlogp, mount_cmd, zone_did)) == -1) {
556 if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
557 zerror(zlogp, B_FALSE, "destroying snapshot: %s",
558 zonecfg_strerror(err));
559 goto bad;
560 }
561 if (vplat_bringup(zlogp, mount_cmd, zone_id) != 0) {
562 bringup_failure_recovery = B_TRUE;
563 (void) vplat_teardown(NULL, (mount_cmd != Z_MNT_BOOT), B_FALSE);
564 if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
565 zerror(zlogp, B_FALSE, "destroying snapshot: %s",
566 zonecfg_strerror(err));
567 goto bad;
568 }
569
570 if (brand_poststatechg(zlogp, zstate, Z_READY) != 0)
571 goto bad;
572
573 return (0);
574
575 bad:
1343 case ZONE_STATE_INCOMPLETE:
1344 /*
1345 * Not our area of expertise; we just print a nice message
1346 * and die off.
1347 */
1348 zerror(zlogp, B_FALSE,
1349 "%s operation is invalid for zones in state '%s'",
1350 z_cmd_name(cmd), zone_state_str(zstate));
1351 break;
1352
1353 case ZONE_STATE_INSTALLED:
1354 switch (cmd) {
1355 case Z_READY:
1356 rval = zone_ready(zlogp, Z_MNT_BOOT, zstate);
1357 if (rval == 0)
1358 eventstream_write(Z_EVT_ZONE_READIED);
1359 break;
1360 case Z_BOOT:
1361 case Z_FORCEBOOT:
1362 eventstream_write(Z_EVT_ZONE_BOOTING);
1363 if ((rval = zone_ready(zlogp, Z_MNT_BOOT,
1364 zstate)) == 0) {
1365 rval = zone_bootup(zlogp, zargp->bootbuf,
1366 zstate);
1367 }
1368 audit_put_record(zlogp, uc, rval, "boot");
1369 if (rval != 0) {
1370 bringup_failure_recovery = B_TRUE;
1371 (void) zone_halt(zlogp, B_FALSE, B_FALSE,
1372 zstate);
1373 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1374 }
1375 break;
1376 case Z_SHUTDOWN:
1377 case Z_HALT:
1378 if (kernelcall) /* Invalid; can't happen */
1379 abort();
1380 /*
1381 * We could have two clients racing to halt this
1382 * zone; the second client loses, but its request
1383 * doesn't fail, since the zone is now in the desired
1384 * state.
1532 break;
1533 default:
1534 if (kernelcall) /* Invalid; can't happen */
1535 abort();
1536 zerror(zlogp, B_FALSE, "%s operation is invalid "
1537 "for zones in state '%s'", z_cmd_name(cmd),
1538 zone_state_str(zstate));
1539 rval = -1;
1540 break;
1541 }
1542 break;
1543
1544 case ZONE_STATE_RUNNING:
1545 case ZONE_STATE_SHUTTING_DOWN:
1546 case ZONE_STATE_DOWN:
1547 switch (cmd) {
1548 case Z_READY:
1549 if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate))
1550 != 0)
1551 break;
1552 if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate))
1553 == 0)
1554 eventstream_write(Z_EVT_ZONE_READIED);
1555 else
1556 eventstream_write(Z_EVT_ZONE_HALTED);
1557 break;
1558 case Z_BOOT:
1559 /*
1560 * We could have two clients racing to boot this
1561 * zone; the second client loses, but its request
1562 * doesn't fail, since the zone is now in the desired
1563 * state.
1564 */
1565 zerror(zlogp, B_FALSE, "zone is already booted");
1566 rval = 0;
1567 break;
1568 case Z_HALT:
1569 if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate))
1570 != 0)
1571 break;
1572 eventstream_write(Z_EVT_ZONE_HALTED);
1573 break;
|