diff options
| author | Dan McDonald <danmcd@joyent.com> | 2021-10-25 11:37:01 -0400 |
|---|---|---|
| committer | Dan McDonald <danmcd@joyent.com> | 2021-10-25 11:37:01 -0400 |
| commit | a13af751641959037ad97975673e381167ef2d2b (patch) | |
| tree | 5fe12039129a807c3b2887cdae4b7bbed3da8354 | |
| parent | 8670ecf7cf83864d6cefc939dbe8d114948999d7 (diff) | |
| parent | 55fcd84f321375248464013e08f0ff6d6e00fffe (diff) | |
| download | illumos-joyent-a13af751641959037ad97975673e381167ef2d2b.tar.gz | |
[illumos-gate merge]
commit 55fcd84f321375248464013e08f0ff6d6e00fffe
14019 Allow more control over zone init exit actions
commit ba5494d78f75a2e62b09b817fc6abf7351a952c2
14163 zfs-tests: remove_raidz.ksh is broken
Conflicts:
usr/src/uts/common/sys/zone.h
usr/src/uts/common/os/zone.c
usr/src/uts/common/os/exit.c
usr/src/cmd/zoneadmd/zoneadmd.c
| -rw-r--r-- | usr/src/cmd/zoneadmd/zoneadmd.c | 19 | ||||
| -rw-r--r-- | usr/src/lib/libbrand/common/libbrand.c | 29 | ||||
| -rw-r--r-- | usr/src/lib/libbrand/common/libbrand.h | 2 | ||||
| -rw-r--r-- | usr/src/lib/libbrand/common/mapfile-vers | 2 | ||||
| -rw-r--r-- | usr/src/lib/libbrand/dtd/brand.dtd.1 | 37 | ||||
| -rw-r--r-- | usr/src/test/zfs-tests/tests/functional/removal/remove_raidz.ksh | 6 | ||||
| -rw-r--r-- | usr/src/uts/common/os/exit.c | 29 |
7 files changed, 99 insertions, 25 deletions
diff --git a/usr/src/cmd/zoneadmd/zoneadmd.c b/usr/src/cmd/zoneadmd/zoneadmd.c index 0c24c1a0e7..8566e9683e 100644 --- a/usr/src/cmd/zoneadmd/zoneadmd.c +++ b/usr/src/cmd/zoneadmd/zoneadmd.c @@ -1292,8 +1292,8 @@ zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate, boolean_t debug) dladm_status_t status; char errmsg[DLADM_STRSIZE]; int err; - boolean_t restart_init; boolean_t app_svc_dep; + boolean_t restart_init, restart_init0, restart_initreboot; if (brand_prestatechg(zlogp, zstate, Z_BOOT, debug) != 0) return (-1); @@ -1345,8 +1345,10 @@ zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate, boolean_t debug) goto bad; } - /* See if we should restart init if it dies. */ - restart_init = restartinit(bh); + /* See if this zone's brand should restart init if it dies. */ + restart_init = brand_restartinit(bh); + restart_init0 = brand_restartinit0(bh); + restart_initreboot = brand_restartinitreboot(bh); /* * See if we need to setup contract dependencies between the zone's @@ -1427,6 +1429,17 @@ zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate, boolean_t debug) zerror(zlogp, B_TRUE, "could not set zone init-no-restart"); goto bad; } + if (restart_init0 && zone_setattr(zoneid, ZONE_ATTR_INITRESTART0, + NULL, 0) == -1) { + zerror(zlogp, B_TRUE, + "could not set zone init-restart-on-exit-0"); + goto bad; + } + if (restart_initreboot && zone_setattr(zoneid, ZONE_ATTR_INITREBOOT, + NULL, 0) == -1) { + zerror(zlogp, B_TRUE, "could not set zone reboot-on-init-exit"); + goto bad; + } if (app_svc_dep && zone_setattr(zoneid, ZONE_ATTR_APP_SVC_CT, (void *)B_TRUE, sizeof (boolean_t)) == -1) { diff --git a/usr/src/lib/libbrand/common/libbrand.c b/usr/src/lib/libbrand/common/libbrand.c index dc406d60a0..682d0fe32d 100644 --- a/usr/src/lib/libbrand/common/libbrand.c +++ b/usr/src/lib/libbrand/common/libbrand.c @@ -63,6 +63,8 @@ #define DTD_ELEM_MODNAME ((const xmlChar *) "modname") #define DTD_ELEM_MOUNT ((const xmlChar *) "mount") #define DTD_ELEM_RESTARTINIT ((const xmlChar *) "restartinit") +#define DTD_ELEM_RESTARTINIT0 ((const xmlChar *) "restartinit0") +#define DTD_ELEM_RESTARTINITREBOOT ((const xmlChar *) "restartinitreboot") #define DTD_ELEM_POSTATTACH ((const xmlChar *) "postattach") #define DTD_ELEM_POSTCLONE ((const xmlChar *) "postclone") #define DTD_ELEM_POSTINSTALL ((const xmlChar *) "postinstall") @@ -530,21 +532,40 @@ brand_get_initname(brand_handle_t bh, char *buf, size_t len) buf, len, DTD_ELEM_INITNAME, B_FALSE, B_FALSE)); } -boolean_t -brand_restartinit(brand_handle_t bh) +static boolean_t +i_brand_restartinit(brand_handle_t bh, const xmlChar *tagname, boolean_t deflt) { struct brand_handle *bhp = (struct brand_handle *)bh; char val[80]; if (brand_get_value(bhp, NULL, NULL, NULL, NULL, - val, sizeof (val), DTD_ELEM_RESTARTINIT, B_FALSE, B_FALSE) != 0) - return (B_TRUE); + val, sizeof (val), tagname, B_FALSE, B_FALSE) != 0) { + return (deflt); + } if (strcmp(val, "false") == 0) return (B_FALSE); return (B_TRUE); } +boolean_t +brand_restartinit(brand_handle_t bh) +{ + return (i_brand_restartinit(bh, DTD_ELEM_RESTARTINIT, B_TRUE)); +} + +boolean_t +brand_restartinit0(brand_handle_t bh) +{ + return (i_brand_restartinit(bh, DTD_ELEM_RESTARTINIT0, B_FALSE)); +} + +boolean_t +brand_restartinitreboot(brand_handle_t bh) +{ + return (i_brand_restartinit(bh, DTD_ELEM_RESTARTINITREBOOT, B_FALSE)); +} + int brand_get_login_cmd(brand_handle_t bh, const char *username, char *buf, size_t len) diff --git a/usr/src/lib/libbrand/common/libbrand.h b/usr/src/lib/libbrand/common/libbrand.h index 30accf95ba..2dc064481f 100644 --- a/usr/src/lib/libbrand/common/libbrand.h +++ b/usr/src/lib/libbrand/common/libbrand.h @@ -62,6 +62,8 @@ extern int brand_get_halt(brand_handle_t, const char *, const char *, char *, size_t); extern int brand_get_initname(brand_handle_t, char *, size_t); extern boolean_t brand_restartinit(brand_handle_t); +extern boolean_t brand_restartinit0(brand_handle_t); +extern boolean_t brand_restartinitreboot(brand_handle_t); extern int brand_get_install(brand_handle_t, const char *, const char *, char *, size_t); extern int brand_get_installopts(brand_handle_t, char *, size_t); diff --git a/usr/src/lib/libbrand/common/mapfile-vers b/usr/src/lib/libbrand/common/mapfile-vers index be79ae12b7..27999af434 100644 --- a/usr/src/lib/libbrand/common/mapfile-vers +++ b/usr/src/lib/libbrand/common/mapfile-vers @@ -80,6 +80,8 @@ SYMBOL_VERSION SUNWprivate { brand_platform_iter_link; brand_platform_iter_mounts; brand_restartinit; + brand_restartinit0; + brand_restartinitreboot; local: *; }; diff --git a/usr/src/lib/libbrand/dtd/brand.dtd.1 b/usr/src/lib/libbrand/dtd/brand.dtd.1 index a579bee93c..78c30a8355 100644 --- a/usr/src/lib/libbrand/dtd/brand.dtd.1 +++ b/usr/src/lib/libbrand/dtd/brand.dtd.1 @@ -212,17 +212,36 @@ <!ATTLIST initname> <!-- - restartinit + restartinit, restartinit0 and restartinitreboot - Boolean indicating that the program specified by the initname attr - should be restarted, or not, if it exits. By default, the init program - will be restarted if this attribute is not provided. Specifying false - for this attr will prevent that. + These three boolean elements control what action is taken when the + program specified by the 'initname' element exits. - It has no attributes. + The default values are: + + restartinit: true + restartinit0: false + restartinitreboot: false + + If 'restartinit' is set to false then the init process will never be + restarted and the zone will shut down once init exits. In this case, the + other restartinit elements are ignored. + + When 'restartinit0' is set, init will only be restarted if it exited with + an exit status of 0, otherwise the zone will shut down. + + If 'restartinitreboot' is set to true then whenever init should be + restarted, based on the other restartinit elements, the zone will instead + be rebooted. + + These have no attributes. --> <!ELEMENT restartinit (#PCDATA) > <!ATTLIST restartinit> +<!ELEMENT restartinit0 (#PCDATA) > +<!ATTLIST restartinit0> +<!ELEMENT restartinitreboot (#PCDATA) > +<!ATTLIST restartinitreboot> <!-- login_cmd @@ -627,7 +646,7 @@ --> <!ELEMENT privilege (#PCDATA) > -<!ATTLIST privilege set ( default | prohibited | required ) #REQUIRED +<!ATTLIST privilege set ( default | prohibited | required ) #REQUIRED name CDATA #REQUIRED ip-type ( shared | exclusive ) "all" > @@ -642,7 +661,9 @@ directory in which the configuration file is stored. --> -<!ELEMENT brand (modname?, initname, restartinit?, login_cmd, +<!ELEMENT brand (modname?, initname, restartinit?, + restartinit0?, restartinitreboot?, + login_cmd, forcedlogin_cmd, user_cmd, install, installopts?, boot?, sysboot?, halt?, shutdown?, verify_cfg?, verify_adm?, postattach?, postclone?, diff --git a/usr/src/test/zfs-tests/tests/functional/removal/remove_raidz.ksh b/usr/src/test/zfs-tests/tests/functional/removal/remove_raidz.ksh index 73540f8b4b..d23311bfe9 100644 --- a/usr/src/test/zfs-tests/tests/functional/removal/remove_raidz.ksh +++ b/usr/src/test/zfs-tests/tests/functional/removal/remove_raidz.ksh @@ -25,7 +25,9 @@ TMPDIR=${TMPDIR:-/tmp} log_must mkfile $MINVDEVSIZE $TMPDIR/dsk1 log_must mkfile $MINVDEVSIZE $TMPDIR/dsk2 log_must mkfile $MINVDEVSIZE $TMPDIR/dsk3 -DISKS="$TMPDIR/dsk1 raidz $TMPDIR/dsk2 $TMPDIR/dsk3" +DISKS1="$TMPDIR/dsk1" +DISKS2="$TMPDIR/dsk2 $TMPDIR/dsk3" +DISKS="$DISKS1 $DISKS2" function cleanup { @@ -33,7 +35,7 @@ function cleanup log_must rm -f $DISKS } -log_must default_setup_noexit "$DISKS" +log_must default_setup_noexit "$DISKS1 raidz $DISKS2" log_onexit cleanup # Attempt to remove the non raidz disk. diff --git a/usr/src/uts/common/os/exit.c b/usr/src/uts/common/os/exit.c index 46e588c926..d1d0fe4765 100644 --- a/usr/src/uts/common/os/exit.c +++ b/usr/src/uts/common/os/exit.c @@ -166,7 +166,7 @@ restart_init_notify(zone_t *zone) * it failed. As long as the given zone is still in the "running" * state, we will re-exec() init, but first we need to reset things * which are usually inherited across exec() but will break init's - * assumption that it is being exec()'d from a virgin process. Most + * assumption that it is being exec()'d from a virgin process. Most * importantly this includes closing all file descriptors (exec only * closes those marked close-on-exec) and resetting signals (exec only * resets handled signals, and we need to clear any signals which @@ -343,7 +343,7 @@ exit(int why, int what) /* * If proc_exit() fails, then some other lwp in the process * got there first. We just have to call lwp_exit() to allow - * the other lwp to finish exiting the process. Otherwise we're + * the other lwp to finish exiting the process. Otherwise we're * restarting init, and should return. */ if (proc_exit(why, what) != 0) { @@ -356,7 +356,7 @@ exit(int why, int what) /* * Set the SEXITING flag on the process, after making sure /proc does - * not have it locked. This is done in more places than proc_exit(), + * not have it locked. This is done in more places than proc_exit(), * so it is a separate function. */ void @@ -471,9 +471,9 @@ zone_init_exit(zone_t *z, int why, int what) } } - /* - * The restart failed, the zone will shut down. + * The restart failed, or the criteria for a restart are not met; + * the zone will shut down. */ z->zone_init_status = wstat(why, what); (void) zone_kadmin(A_SHUTDOWN, AD_HALT, NULL, zone_kcred()); @@ -510,7 +510,7 @@ proc_exit(int why, int what) /* * Stop and discard the process's lwps except for the current one, - * unless some other lwp beat us to it. If exitlwps() fails then + * unless some other lwp beat us to it. If exitlwps() fails then * return and the calling lwp will call (or continue in) lwp_exit(). */ proc_is_exiting(p); @@ -560,6 +560,19 @@ proc_exit(int why, int what) lwp_detach_brand_hdlrs(lwp); } + /* + * Don't let init exit unless zone_start_init() failed its exec, or + * we are shutting down the zone or the machine. + * + * Since we are single threaded, we don't need to lock the + * following accesses to zone_proc_initpid. + */ + if (p->p_pid == z->zone_proc_initpid) { + /* If zone's init restarts, we're done here. */ + if (zone_init_exit(z, why, what)) + return (0); + } + lwp_pcb_exit(); /* @@ -1005,7 +1018,7 @@ proc_exit(int why, int what) * curthread's proc pointer is changed to point to the 'sched' * process for the corresponding zone, except in the case when * the exiting process is in fact a zsched instance, in which - * case the proc pointer is set to p0. We do so, so that the + * case the proc pointer is set to p0. We do so, so that the * process still points at the right zone when we call the VN_RELE() * below. * @@ -1089,7 +1102,7 @@ proc_exit(int why, int what) /* * task_rele() may ultimately cause the zone to go away (or * may cause the last user process in a zone to go away, which - * signals zsched to go away). So prior to this call, we must + * signals zsched to go away). So prior to this call, we must * no longer point at zsched. */ t->t_procp = &p0; |
