Re: s6-svscan - controlling terminal semantics and stdin use
2018-01-02 0:53 GMT-03:00 Earl Chew: > > My first observation is that when killing the cron initiated s6-svscan > process with SIGINT or SIGTERM, I see the behaviour described in the > documentation. The child s6-supervise processes are correctly > terminated, and there are no orphans. > > If instead, I start s6-svcscan at the terminate and terminate it with ^C > (SIGINT), what I observe is that the child s6-supervise processes > terminate abruptly and their child service processes are orphaned. > [...] > > Has this scenario (ie starting s6-svscan from an interactive terminal) > been considered previously? > > My expectation was that the two scenarios would exhibit similar behaviours. Do you really need s6-svscan to run in the foreground, or do you just want to gracefully tear down the supervision tree in this case? What I do if I want to use s6-svscan from an interactive shell is: $ s6-svscan /path/to/scandir & (shell returns a job control job ID) $ (Do whatever I need to do with the supervision tree) $ s6-svscanctl -t /path/to/scandir With a suitable .s6-svscan/finish file, of course. This mostly works like when launching s6-svscan in any other way (except perhaps for the environment, as Casper pointed out). No special arrangement with nosetsid files needed. Using kill(1) with the job ID returned by the shell (i.e. kill %some_number) to send a SIGTERM signal instead of using s6-svscanctl works too, provided that s6-svscan was invoked without the 'divert signals' option, -s. G.
Re: s6-svscan - controlling terminal semantics and stdin use
Ok, I understand you're calling this out-of-bounds. I would suggest calling this out clearly in the documentation. Yes, I will update the documentation to clarify this, thanks for the suggestion. I do not think that my suggestion of placing the children of s6-svscan in a separate process group from s6-svscan itself changes any of these objectives. It doesn't indeed, but it's unnecessary. The supervision tree can be seen as one entity, despite it being multiple processes; having the s6-supervise processes in separate sessions or process groups does not bring any benefits - quite the contrary, if you lose the s6-svscan process and want to rebuild the supervision tree, you have to kill every s6-supervise process by hand, which is tedious. Really, since having a controlling terminal for the supervision tree is a very uncommon case that should stay uncommon, I want it to have the least possible amount of code dedicated to it, and to keep the default Unix behaviour wherever possible. The other thing I thought of is the asymmetry that although s6-svscan handles SIGINT, I notice that s6-supervise does not handle this signal. Perhaps this is a different point that could be considered. If s6-supervise receives SIGINT, it could send SIGINT to the process group it is supervising. See above - I don't particularly like s6-svscan handling SIGINT, and wish I could leave it out entirely. Unfortunately, it's a requirement for it to be able to run as process 1, since Ctrl-Alt-Del sends a SIGINT to process 1. -- Laurent
Re: s6-svscan - controlling terminal semantics and stdin use
On Tue, Jan 02, 2018 at 08:33:18AM -0800, Earl Chew via skaware wrote: > I do not think that my suggestion of placing the children of s6-svscan in a > separate process group from s6-svscan itself changes any of these > objectives. Each service would continue to apply its own session leader role > by default, and explicit requests to tear down the supervision tree and the > supervised processes should do just that. Perhaps this would achieve what you want: # mv /path/to/s6-supervise /path/to/s6-supervise.bin # > /path/to/s6-supervise printf \ '#!/bin/sh\nexec /path/to/setsid /path/to/s6-supervise.bin $@\n' (Similar tricks have been used to endow /path/to/s6-supervise with other "capabilities" without really modify the source code; also note that the shell would introduce additional variables into the environment, so you can also consider using execline.) -- My current OpenPGP key: RSA4096/0x227E8CAAB7AA186C (expires: 2020.10.19) 7077 7781 B859 5166 AE07 0286 227E 8CAA B7AA 186C
Re: s6-svscan - controlling terminal semantics and stdin use
[ Colin, Casper, thanks for your suggestions ] Laurent, we are not _certain_ there's no benefit from keeping stdin as is Yes, I think that is a reasonable argument to leave it as is. - The supervision tree isn't supposed to have a controlling terminal Ok, I understand you're calling this out-of-bounds. I would suggest calling this out clearly in the documentation. Perhaps something like: If you run s6-svscan from an interactive shell, be warned that typing ^C (ie sending SIGINT) from the controlling terminal will terminate the supervision tree and cause the supervised processes to become orphans. - It is more beneficial to run services as their own session leaders by default - The point of supervision is to increase reliability of services, not decrease it, so tearing down the supervision tree should generally not tear down services with it unless explicitly requested. I do not think that my suggestion of placing the children of s6-svscan in a separate process group from s6-svscan itself changes any of these objectives. Each service would continue to apply its own session leader role by default, and explicit requests to tear down the supervision tree and the supervised processes should do just that. The other thing I thought of is the asymmetry that although s6-svscan handles SIGINT, I notice that s6-supervise does not handle this signal. Perhaps this is a different point that could be considered. If s6-supervise receives SIGINT, it could send SIGINT to the process group it is supervising. Do you think that is a reasonable to do? -- Earl > mailto:earl_c...@yahoo.com
Re: s6-svscan - controlling terminal semantics and stdin use
Has this scenario (ie starting s6-svscan from an interactive terminal) been considered previously? Yes. The default behaviour was chosen considering this: - The supervision tree isn't supposed to have a controlling terminal - It is more beneficial to run services as their own session leaders by default - The point of supervision is to increase reliability of services, not decrease it, so tearing down the supervision tree should generally not tear down services with it unless explicitly requested. But you can tell s6-supervise to run its service in the same session as the supervision tree by touching the ./nosetsid file in the service directory. If all your service directories have a ./nosetsid file and s6-svscan has a controlling terminal, ^C on s6-svscan will kill everything as you expect. My second observation is that stdin of s6-svscan is inherited by all its s6-supervise children. I'm wondering if there is anything to be gained by that, and whether it would be less surprising to set stdin to /dev/null after fork() since having a herd of processes attempting to read from the same stdin does not seem to lead anywhere useful. You are wondering if there is anything to be gained by that. I am wondering, too; I suspect there's a case in s6-overlay where it's useful, because one early service actually uses data from this stdin (but I'd need to check the s6-overlay code to be sure). The point is, we are not _certain_ there's no benefit from keeping stdin as is. And redirecting stdin to /dev/null is very easy to do for a user, but impossible to reverse if it's hardcoded in a program: so enforcing the redirection would restrict what users can do without a significant usability improvement. So, the best choice is to do nothing. In the general case, users will run "s6-svscan < /dev/null", which is not difficult to remember (and this is also what s6-linux-init's stage 1 does). It is with redirections as it is with forks: users can easily do them, but cannot undo them. So it's best to leave the choice to the user. -- Laurent
Re: s6-svscan - controlling terminal semantics and stdin use
On Mon, Jan 01, 2018 at 07:53:39PM -0800, Earl Chew via skaware wrote: > If instead, I start s6-svcscan at the terminate and terminate it with ^C > (SIGINT), what I observe is that the child s6-supervise processes > terminate abruptly and their child service processes are orphaned. I > think the issue is that the child s6-supervise processes continue to be > part of the same process group as s6-svscan, which in turn is attached > to the controlling terminal of the session. The SIGINT is delivered to > all the processes in that group, which terminates the s6-supervise > processes immediately, thus causing their children to become orphaned. Perhaps you can try the `-s' option of s6-svscan? > I was thinking about how to go about making the two scenarios more > alike. Using s6-setsid as part of the */run supervision scripts seems > like a solution, but it will not have the right effect since what is > required is not to create a process group for the */run process, but to > dissociate the s6-supervise from process group of s6-svscan. This means > that any potential remedy would have to be placed around the fork() in > s6-svscan. (Actually s6-supervise does setsid() by default before exec()ing into its supervised process; there is an optional `setsid' control file to disable this behaviour.) > My second observation is that stdin of s6-svscan is inherited by all its > s6-supervise children. I'm wondering if there is anything to be gained > by that, and whether it would be less surprising to set stdin to > /dev/null after fork() since having a herd of processes attempting to > read from the same stdin does not seem to lead anywhere useful. I think `s6-svscan /path/to/sevices < /dev/null' should be enough? -- My current OpenPGP key: RSA4096/0x227E8CAAB7AA186C (expires: 2020.10.19) 7077 7781 B859 5166 AE07 0286 227E 8CAA B7AA 186C
Re: s6-svscan - controlling terminal semantics and stdin use
On Mon, Jan 01, 2018 at 07:53:39PM -0800, Earl Chew via skaware wrote: > Thanks for the s6-* family of programs. > > I've just started using s6-svscan for some deployments. > > In one of the scenarios, I was prototyping the behaviour of s6-svscan > over a supervision tree directly at the interactive terminal for use in > a cron-based scenario. > ... > Has this scenario (ie starting s6-svscan from an interactive terminal) > been considered previously? I believe this particular failure mode has been considered and decided an edge-enough case to not be worried about. Laurent will have to say for sure though. > > My second observation is that stdin of s6-svscan is inherited by all its > s6-supervise children. I'm wondering if there is anything to be gained > by that, and whether it would be less surprising to set stdin to > /dev/null after fork() since having a herd of processes attempting to > read from the same stdin does not seem to lead anywhere useful. stdin, stdout, and stderr are inherited when a process is forked, there's nothing special going on here. Since s6-svscan and s6-svscanctl ignore stdin, keeping it open shouldn't impact anything. If you want to close stdin, do it before execing into s6-svscan (or as part of the call if using shell). > > What do you think? > > Earl -- Colin Booth
s6-svscan - controlling terminal semantics and stdin use
Thanks for the s6-* family of programs. I've just started using s6-svscan for some deployments. In one of the scenarios, I was prototyping the behaviour of s6-svscan over a supervision tree directly at the interactive terminal for use in a cron-based scenario. My first observation is that when killing the cron initiated s6-svscan process with SIGINT or SIGTERM, I see the behaviour described in the documentation. The child s6-supervise processes are correctly terminated, and there are no orphans. If instead, I start s6-svcscan at the terminate and terminate it with ^C (SIGINT), what I observe is that the child s6-supervise processes terminate abruptly and their child service processes are orphaned. I think the issue is that the child s6-supervise processes continue to be part of the same process group as s6-svscan, which in turn is attached to the controlling terminal of the session. The SIGINT is delivered to all the processes in that group, which terminates the s6-supervise processes immediately, thus causing their children to become orphaned. Has this scenario (ie starting s6-svscan from an interactive terminal) been considered previously? My expectation was that the two scenarios would exhibit similar behaviours. I was thinking about how to go about making the two scenarios more alike. Using s6-setsid as part of the */run supervision scripts seems like a solution, but it will not have the right effect since what is required is not to create a process group for the */run process, but to dissociate the s6-supervise from process group of s6-svscan. This means that any potential remedy would have to be placed around the fork() in s6-svscan. AFAICT s6-svscan does not require that all its children reside in the same process group as s6-svscan. So an approach would be to either place each s6-supervise process in its own process group, or to create another process group for them all to reside in. My second observation is that stdin of s6-svscan is inherited by all its s6-supervise children. I'm wondering if there is anything to be gained by that, and whether it would be less surprising to set stdin to /dev/null after fork() since having a herd of processes attempting to read from the same stdin does not seem to lead anywhere useful. What do you think? Earl