Print this page
14019 Allow more control over zone init exit actions (fix mismerge)
14019 Allow more control over zone init exit actions
Portions contributed by: Joshua M. Clulow <jmc@joyent.com>
Portions contributed by: Andy Fiddaman <andy@omnios.org>
Reviewed by: C Fraire <cfraire@me.com>
Reviewed by: Gordon Ross <Gordon.W.Ross@gmail.com>
Approved by: Robert Mustacchi <rm@fingolfin.org>


1275                 return (B_TRUE);
1276         }
1277 
1278         return (B_FALSE);
1279 }
1280 
1281 static int
1282 zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate, boolean_t debug)
1283 {
1284         zoneid_t zoneid;
1285         struct stat st;
1286         char rpath[MAXPATHLEN], initpath[MAXPATHLEN], init_file[MAXPATHLEN];
1287         char nbootargs[BOOTARGS_MAX];
1288         char cmdbuf[MAXPATHLEN];
1289         fs_callback_t cb;
1290         brand_handle_t bh;
1291         zone_iptype_t iptype;
1292         dladm_status_t status;
1293         char errmsg[DLADM_STRSIZE];
1294         int err;
1295         boolean_t restart_init;
1296         boolean_t app_svc_dep;

1297 
1298         if (brand_prestatechg(zlogp, zstate, Z_BOOT, debug) != 0)
1299                 return (-1);
1300 
1301         if ((zoneid = getzoneidbyname(zone_name)) == -1) {
1302                 zerror(zlogp, B_TRUE, "unable to get zoneid");
1303                 goto bad;
1304         }
1305 
1306         cb.zlogp = zlogp;
1307         cb.zoneid = zoneid;
1308         cb.mount_cmd = B_FALSE;
1309 
1310         /* Get a handle to the brand info for this zone */
1311         if ((bh = brand_open(brand_name)) == NULL) {
1312                 zerror(zlogp, B_FALSE, "unable to determine zone brand");
1313                 goto bad;
1314         }
1315 
1316         /*


1328         /*
1329          * Get the brand's boot callback if it exists.
1330          */
1331         (void) strcpy(cmdbuf, EXEC_PREFIX);
1332         if (brand_get_boot(bh, zone_name, zonepath, cmdbuf + EXEC_LEN,
1333             sizeof (cmdbuf) - EXEC_LEN) != 0) {
1334                 zerror(zlogp, B_FALSE,
1335                     "unable to determine branded zone's boot callback");
1336                 brand_close(bh);
1337                 goto bad;
1338         }
1339 
1340         /* Get the path for this zone's init(1M) (or equivalent) process.  */
1341         if (get_initname(bh, init_file, MAXPATHLEN) != 0) {
1342                 zerror(zlogp, B_FALSE,
1343                     "unable to determine zone's init(1M) location");
1344                 brand_close(bh);
1345                 goto bad;
1346         }
1347 
1348         /* See if we should restart init if it dies. */
1349         restart_init = restartinit(bh);


1350 
1351         /*
1352          * See if we need to setup contract dependencies between the zone's
1353          * primary application and any of its services.
1354          */
1355         app_svc_dep = is_app_svc_dep();
1356 
1357         brand_close(bh);
1358 
1359         err = filter_bootargs(zlogp, bootargs, nbootargs, init_file);
1360         if (err != Z_OK)
1361                 goto bad;
1362 
1363         assert(init_file[0] != '\0');
1364 
1365         /*
1366          * Try to anticipate possible problems: If possible, make sure init is
1367          * executable.
1368          */
1369         if (zone_get_rootpath(zone_name, rpath, sizeof (rpath)) != Z_OK) {


1410             (do_subproc(zlogp, cmdbuf, NULL, debug) != Z_OK)) {
1411                 zerror(zlogp, B_FALSE, "%s failed", cmdbuf);
1412                 goto bad;
1413         }
1414 
1415         if (zone_setattr(zoneid, ZONE_ATTR_INITNAME, init_file, 0) == -1) {
1416                 zerror(zlogp, B_TRUE, "could not set zone boot file");
1417                 goto bad;
1418         }
1419 
1420         if (zone_setattr(zoneid, ZONE_ATTR_BOOTARGS, nbootargs, 0) == -1) {
1421                 zerror(zlogp, B_TRUE, "could not set zone boot arguments");
1422                 goto bad;
1423         }
1424 
1425         if (!restart_init && zone_setattr(zoneid, ZONE_ATTR_INITNORESTART,
1426             NULL, 0) == -1) {
1427                 zerror(zlogp, B_TRUE, "could not set zone init-no-restart");
1428                 goto bad;
1429         }











1430 
1431         if (app_svc_dep && zone_setattr(zoneid, ZONE_ATTR_APP_SVC_CT,
1432             (void *)B_TRUE, sizeof (boolean_t)) == -1) {
1433                 zerror(zlogp, B_TRUE, "could not set zone app-die");
1434                 goto bad;
1435         }
1436 
1437         /*
1438          * Inform zonestatd of a new zone so that it can install a door for
1439          * the zone to contact it.
1440          */
1441         notify_zonestatd(zone_id);
1442 
1443         /* Startup a thread to perform zfd logging/tty svc for the zone. */
1444         create_log_thread(zlogp);
1445 
1446         if (zone_boot(zoneid) == -1) {
1447                 zerror(zlogp, B_TRUE, "unable to boot zone");
1448                 destroy_log_thread(zlogp);
1449                 goto bad;




1275                 return (B_TRUE);
1276         }
1277 
1278         return (B_FALSE);
1279 }
1280 
1281 static int
1282 zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate, boolean_t debug)
1283 {
1284         zoneid_t zoneid;
1285         struct stat st;
1286         char rpath[MAXPATHLEN], initpath[MAXPATHLEN], init_file[MAXPATHLEN];
1287         char nbootargs[BOOTARGS_MAX];
1288         char cmdbuf[MAXPATHLEN];
1289         fs_callback_t cb;
1290         brand_handle_t bh;
1291         zone_iptype_t iptype;
1292         dladm_status_t status;
1293         char errmsg[DLADM_STRSIZE];
1294         int err;

1295         boolean_t app_svc_dep;
1296         boolean_t restart_init, restart_init0, restart_initreboot;
1297 
1298         if (brand_prestatechg(zlogp, zstate, Z_BOOT, debug) != 0)
1299                 return (-1);
1300 
1301         if ((zoneid = getzoneidbyname(zone_name)) == -1) {
1302                 zerror(zlogp, B_TRUE, "unable to get zoneid");
1303                 goto bad;
1304         }
1305 
1306         cb.zlogp = zlogp;
1307         cb.zoneid = zoneid;
1308         cb.mount_cmd = B_FALSE;
1309 
1310         /* Get a handle to the brand info for this zone */
1311         if ((bh = brand_open(brand_name)) == NULL) {
1312                 zerror(zlogp, B_FALSE, "unable to determine zone brand");
1313                 goto bad;
1314         }
1315 
1316         /*


1328         /*
1329          * Get the brand's boot callback if it exists.
1330          */
1331         (void) strcpy(cmdbuf, EXEC_PREFIX);
1332         if (brand_get_boot(bh, zone_name, zonepath, cmdbuf + EXEC_LEN,
1333             sizeof (cmdbuf) - EXEC_LEN) != 0) {
1334                 zerror(zlogp, B_FALSE,
1335                     "unable to determine branded zone's boot callback");
1336                 brand_close(bh);
1337                 goto bad;
1338         }
1339 
1340         /* Get the path for this zone's init(1M) (or equivalent) process.  */
1341         if (get_initname(bh, init_file, MAXPATHLEN) != 0) {
1342                 zerror(zlogp, B_FALSE,
1343                     "unable to determine zone's init(1M) location");
1344                 brand_close(bh);
1345                 goto bad;
1346         }
1347 
1348         /* See if this zone's brand should restart init if it dies. */
1349         restart_init = restartinit(bh);
1350         restart_init0 = brand_restartinit0(bh);
1351         restart_initreboot = brand_restartinitreboot(bh);
1352 
1353         /*
1354          * See if we need to setup contract dependencies between the zone's
1355          * primary application and any of its services.
1356          */
1357         app_svc_dep = is_app_svc_dep();
1358 
1359         brand_close(bh);
1360 
1361         err = filter_bootargs(zlogp, bootargs, nbootargs, init_file);
1362         if (err != Z_OK)
1363                 goto bad;
1364 
1365         assert(init_file[0] != '\0');
1366 
1367         /*
1368          * Try to anticipate possible problems: If possible, make sure init is
1369          * executable.
1370          */
1371         if (zone_get_rootpath(zone_name, rpath, sizeof (rpath)) != Z_OK) {


1412             (do_subproc(zlogp, cmdbuf, NULL, debug) != Z_OK)) {
1413                 zerror(zlogp, B_FALSE, "%s failed", cmdbuf);
1414                 goto bad;
1415         }
1416 
1417         if (zone_setattr(zoneid, ZONE_ATTR_INITNAME, init_file, 0) == -1) {
1418                 zerror(zlogp, B_TRUE, "could not set zone boot file");
1419                 goto bad;
1420         }
1421 
1422         if (zone_setattr(zoneid, ZONE_ATTR_BOOTARGS, nbootargs, 0) == -1) {
1423                 zerror(zlogp, B_TRUE, "could not set zone boot arguments");
1424                 goto bad;
1425         }
1426 
1427         if (!restart_init && zone_setattr(zoneid, ZONE_ATTR_INITNORESTART,
1428             NULL, 0) == -1) {
1429                 zerror(zlogp, B_TRUE, "could not set zone init-no-restart");
1430                 goto bad;
1431         }
1432         if (restart_init0 && zone_setattr(zoneid, ZONE_ATTR_INITRESTART0,
1433             NULL, 0) == -1) {
1434                 zerror(zlogp, B_TRUE,
1435                     "could not set zone init-restart-on-exit-0");
1436                 goto bad;
1437         }
1438         if (restart_initreboot && zone_setattr(zoneid, ZONE_ATTR_INITREBOOT,
1439             NULL, 0) == -1) {
1440                 zerror(zlogp, B_TRUE, "could not set zone reboot-on-init-exit");
1441                 goto bad;
1442         }
1443 
1444         if (app_svc_dep && zone_setattr(zoneid, ZONE_ATTR_APP_SVC_CT,
1445             (void *)B_TRUE, sizeof (boolean_t)) == -1) {
1446                 zerror(zlogp, B_TRUE, "could not set zone app-die");
1447                 goto bad;
1448         }
1449 
1450         /*
1451          * Inform zonestatd of a new zone so that it can install a door for
1452          * the zone to contact it.
1453          */
1454         notify_zonestatd(zone_id);
1455 
1456         /* Startup a thread to perform zfd logging/tty svc for the zone. */
1457         create_log_thread(zlogp);
1458 
1459         if (zone_boot(zoneid) == -1) {
1460                 zerror(zlogp, B_TRUE, "unable to boot zone");
1461                 destroy_log_thread(zlogp);
1462                 goto bad;