tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: add a "notty" flag to ttys(5) for init(8)



In article <m1u5qrA-00Mo69C@more.local>,
Greg A. Woods <tech-userlevel%NetBSD.org@localhost> wrote:
>-=-=-=-=-=-
>
>The other day I was having problems with a syslogd dying during log
>rotation, at which point I was having to notice this happened (which I
>could tell from the emails from cron, once I checked email) and then of
>course I had to manually restart it.
>
>For a very long time now I've wanted a simple solution to deal with
>managing essential services in an rc.d world in such a way that I could
>automate such things.
>
>I finally remembered sysutils/monit and gave it a try.  It works
>amazingly well and while it is extremely minimal in requirements it
>provides an enormous amount of features and flexibility.  It was trivial
>to set up to monitor and restart syslogd and it works very very well.
>
>However that raised the question of how to reliably start it.
>
>I figured the best way would be to run it from init(8) so that it would
>be running at all times while logins are allowed, and so that init(8)
>could restart it should it ever die.
>
>The problem was that monit, like most programs, doesn't want arbitrary
>arguments on its command line, and the normal way init(8) starts a
>"getty" is to explicitly pass the terminal name as an additional
>argument.  I could have named the session "-I", but that's UGLY.
>
>In the end I was unable to make it work without writing a (trivial)
>wrapper script, but that also seemed like a crazy requirement when all I
>really wanted was for init(8) to not add an extra argument if it wasn't
>wanted/needed.
>
>So, I decided to add a "notty" flag to ttys(5) for init(8).
>
>(line numbers are not exact)
>
>Index: init.c
>===================================================================
>RCS file: /cvs/master/m-NetBSD/main/src/sbin/init/init.c,v
>retrieving revision 1.108
>diff -u -u -r1.108 init.c
>--- init.c	22 Jun 2020 07:50:53 -0000	1.108
>+++ init.c	17 Apr 2025 17:39:08 -0000
>@@ -1136,7 +1145,8 @@
> 		free(sp->se_getty);
> 		free(sp->se_getty_argv);
> 	}
>-	(void)asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name);
>+	(void)asprintf(&sp->se_getty, "%s %s", typ->ty_getty,
>+		       typ->ty_status & TTY_NOTTY ? "" : typ->ty_name);
> 	if (!sp->se_getty)
> 		return 0;
> 	sp->se_getty_argv = construct_argv(sp->se_getty);
>
>
>Of course there are other necessary (but simple and, I think, obvious)
>changes in lib/libc/gen/getttyent.c and the documentation.  Notably in
>ttys(5) I wrote:
>
>     notty    Do not add the tty name as an argument to the command.  This is
>              useful to allow init(8) to be used to run any command that must
>              be started when logins are allowed and which must always be
>              running.  The command will be restarted if it exits.
>
>I can now add a line like the following to /etc/ttys:
>
>	monitor "/usr/pkg/bin/monit -I"         -	on notty
>
>and, voila!
>
>	# kill -1 1
>	# who -a
>	                   ? system boot Apr 17 14:51   .            0  term=0
>exit=0 sess=0 type=boot time
>	                   ? system down Apr 17 14:52   .            0  term=0
>exit=0 sess=0 type=down time
>	                   ? run-level m Apr 18 11:20   .            0  new=m
>old=T sess=0 type=run level
>	/usr/libexec/getty - constty     Apr 17 14:52 20:28       3916  term=0
>exit=0 sess=1 type=login process
>	woods              - pts/0       Apr 17 14:52 00:19       3928  term=0
>exit=0 sess=0 type=user process  (10.0.2.146)
>	/usr/pkg/bin/monit ? monitor     Apr 18 11:20   .        20027  term=0
>exit=0 sess=18 type=login process
>
>
>So, to me this seems like a simple but highly effective feature, and it
>is arguably far more elegant and simple than writing wrapper scripts.
>
>What do you all think?
>
>For those who want to do some bikeshedding, we could discuss adding a
>full-fledged /etc/inittab to init(8)!  :-)  [But not seriously -- I'm
>quite happy with /etc/ttys just being able to start extra processes
>whenever logins are allowed and using /etc/rc (with all of /etc/rc.d,
>etc.) to do the rest.  No need to turn the world upside down just for
>this simple feature!]
>
>
>For the curious, this is the meat in my first /etc/monit/monitrc:
>
>set daemon  5               # check services at 5 second intervals
>set init                    # don't become a daemon (also called with -I)
>set log syslog
>set pidfile /var/run/monit.pid
>set idfile /var/run/monit.id
>set statefile /var/run/monit.state
>set mailserver localhost               # primary mailserver
>set mail-format { from: monit%more.weird.com@localhost }
>set alert root%more.weird.com@localhost          # receive all alerts
>set httpd port 2812 and
>    use address localhost  # only accept connection from localhost
>    allow localhost        # allow localhost to connect to the server and
>    allow admin:monit      # require user 'admin' with password 'monit'
>check process syslogd with pidfile /var/run/syslogd.pid
>    start program = "/etc/rc.d/syslogd start" with timeout 60 seconds
>    stop program  = "/etc/rc.d/syslogd stop"
>    group server
>

I think it sounds fine...

christos



Home | Main Index | Thread Index | Old Index