supervision - discussion about system services, daemon supervision, init, runlevel management, and tools such as s6 and runit
 help / color / mirror / Atom feed
* "run once" facility (patch for runit)
@ 2004-03-25 12:47 Wayne Marshall
  2004-03-25 13:45 ` Laurent Bercot
  2004-03-25 14:57 ` Charlie Brady
  0 siblings, 2 replies; 10+ messages in thread
From: Wayne Marshall @ 2004-03-25 12:47 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 2143 bytes --]

2004.03.25
Thu

Hi,

I have been influenced by Gerrit Pape's comments "why not think
about eth0 as a service" and performing one-time system
initializations with runit services, rather than various rc
scripts.

The attached patch to runit-1.0.1 recognizes the existence of a
file named "myservice/once" in a service directory, to run the
service one time.

The file "once"--like "down"--is intended to be a file created
by touch(1).

As noted in the patch:

# this patch modifies the "runsv" utility as follows:
#
#   If the file "myservice/once" exists--and the file
#   "myservice/down" does not exist--runsv runs the
#   service once.
#
#   The usual conventions for running the service once
#   are followed:
#
#   * if the service is not running, start "./run"
#
#   * if "./run" exits and "./finish" exists,
#     run "./finish"
#
#   * if "./finish" exits, do not restart "./run"
#
#   Note: no recognition is provided for the presence
#   of "myservice/log/once".
#
#
# this patch also modifies the "runsvstat" utility such
# that:
#
#   If the service is down and the file "myservice/once"
#   exists--and the file "myservice/down" does not exist--
#   then the output is:
#
#     myservice: down 310 seconds (run once)
#
#
# rationale:
#
#   to permit the installation of "one-time" services
#   --such as for the purposes of system initialization--
#   within the "runit" framework. 
#
#   see, for example, gerrit pape's "What is a service?"
#   musings in:
#
#     http://smarden.org/pape/djb/daemontools/noinit.html
#
#   similarly, felix von leitner's minit package recognizes
#   a "myservice/sync" file to provide one-time static
#   initialization services.
#   

This patch is just a suggestion for discussion and consideration.
I believe nothing has been done here to break existing
deployments.  In particular, no changes have been made in the
specification or contents of supervise/status.

If the facility were to be formally incorporated into the
release, however, I am sure it would be done much better.

Stay well!

Wayne

-- 
Wayne Marshall
guinix international
http://www.guinix.com/
"Computing Without Borders..."

[-- Attachment #2: runit-1.0.1.run_once.patch --]
[-- Type: application/octet-stream, Size: 4832 bytes --]

# runit-1.0.1.run_once.patch
#
# this patch modifies the "runsv" utility as follows:
#
#   If the file "myservice/once" exists--and the file
#   "myservice/down" does not exist--runsv runs the
#   service once.
#
#   The usual conventions for running the service once
#   are followed:
#
#   * if the service is not running, start "./run"
#
#   * if "./run" exits and "./finish" exists,
#     run "./finish"
#
#   * if "./finish" exits, do not restart "./run"
#
#   Note: no recognition is provided for the presence
#   of "myservice/log/once".
#
#
# this patch also modifies the "runsvstat" utility such
# that:
#
#   If the service is down and the file "myservice/once"
#   exists--and the file "myservice/down" does not exist--
#   then the output is:
#
#     myservice: down 310 seconds (run once)
#
#
# rationale:
#
#   to permit the installation of "one-time" services
#   --such as for the purposes of system initialization--
#   within the "runit" framework. 
#
#   see, for example, gerrit pape's "What is a service?"
#   musings in:
#
#     http://smarden.org/pape/djb/daemontools/noinit.html
#
#   similarly, felix von leitner's minit package recognizes
#   a "myservice/sync" file to provide one-time static
#   initialization services.
#   
#
# apply this patch:
#
#   # cd /package/admin/runit-1.0.1
#   # patch -p1 < /path/to/this/patch
#
#
# then (re)compile/(re)install runit:
#
#   # package/install
#
#
# notes:
#
#  * this patch does not update the documentation
#
#
# wcm, 2004.03.25 - 2004.03.25
# ===
diff -ur runit-1.0.1/src/runsv.c runit-1.0.1.run_once/src/runsv.c
--- runit-1.0.1/src/runsv.c	Sun Mar  7 13:41:09 2004
+++ runit-1.0.1.run_once/src/runsv.c	Thu Mar 25 12:37:28 2004
@@ -38,6 +38,7 @@
 #define W_UP 0
 #define W_DOWN 1
 #define W_EXIT 2
+#define W_ONCE 4
 
 struct svdir {
   int pid;
@@ -144,6 +145,9 @@
   case W_EXIT:
     buffer_puts(&b, ", want exit");
     break;
+  case W_ONCE:
+    buffer_puts(&b, ", want once");
+    break;
   }
   buffer_putsflush(&b, "\n");
   close(fd);
@@ -167,7 +171,7 @@
     status[16] =1;
   else
     status[16] =0;
-  if (s->want == W_UP)
+  if ((s->want == W_UP) || (s->want == W_ONCE))
     status[17] ='u';
   else
     status[17] ='d';
@@ -254,6 +258,7 @@
   }
   s->pid =p;
   pidchanged =1;
+  if(s->want == W_ONCE) s->want =W_DOWN;
   s->ctrl =C_NOOP;
   update_status(s);
   sleep(1);
@@ -295,7 +300,7 @@
     update_status(s);
     break;
   case 'o': /* once */
-    s->want =W_DOWN;
+    s->want =W_ONCE;
     if (! s->pid) startservice(s);
     else update_status(s);
     break;
@@ -349,6 +354,9 @@
   taia_now(&svd[0].start);
   if (stat("down", &s) != -1) svd[0].want =W_DOWN;
 
+  if ((svd[0].want != W_DOWN) && (stat("once", &s) != -1))
+    svd[0].want =W_ONCE;
+
   if (stat("log", &s) == -1) {
     if (errno != error_noent)
       warn("unable to stat() ./log: ");
@@ -365,6 +373,9 @@
       taia_now(&svd[1].start);
       if (stat("log/down", &s) != -1)
 	svd[1].want =W_DOWN;
+
+      /* note: W_ONCE not supported for log service */
+
       if (pipe(logpipe) == -1)
 	fatal("unable to create log pipe");
       coe(logpipe[0]);
@@ -452,7 +463,7 @@
     if (haslog)
       if (! svd[1].pid && (svd[1].want == W_UP)) startservice(&svd[1]);
     if (! svd[0].pid)
-      if ((svd[0].want == W_UP) || (svd[0].state == S_FINISH))
+      if ((svd[0].want == W_UP) || (svd[0].want == W_ONCE) || (svd[0].state == S_FINISH))
 	startservice(&svd[0]);
 
     x[0].fd =selfpipe[0];
diff -ur runit-1.0.1/src/runsvstat.c runit-1.0.1.run_once/src/runsvstat.c
--- runit-1.0.1/src/runsvstat.c	Sun Mar  7 13:41:09 2004
+++ runit-1.0.1.run_once/src/runsvstat.c	Thu Mar 25 14:25:29 2004
@@ -38,6 +38,7 @@
   int pid;
   int fd;
   int normallyup =0;
+  int runonce =0;
   char sulong[FMT_ULONG];
   struct tai when;
   struct tai now;
@@ -49,6 +50,17 @@
     }
     normallyup = 1;
   }
+  if (normallyup) {
+    if (stat("once", &s) == 0) {
+      runonce = 1;
+    }
+    else {
+      if (errno != error_noent) {
+          warn(name, "unable to stat once");
+          return(-1);
+      }
+    }
+  }
   if ((fd =open_write("supervise/ok")) == -1) {
     if (errno == error_nodevice)
       warnx(name, "runsv not running.");
@@ -96,7 +108,12 @@
   buffer_put(buffer_1, sulong, fmt_ulong(sulong, tai_approx(&when)));
   buffer_puts(buffer_1, " seconds");
   if (pid && !normallyup) buffer_puts(buffer_1,", normally down");
-  if (!pid && normallyup) buffer_puts(buffer_1,", normally up");
+  if (!pid && normallyup) {
+    if (runonce)
+      buffer_puts(buffer_1,", (run once)");
+    else
+      buffer_puts(buffer_1,", normally up");
+  }
   if (pid && status[16]) buffer_puts(buffer_1,", paused");
   if (!pid && (status[17] == 'u')) buffer_puts(buffer_1,", want up");
   if (pid && (status[17] == 'd')) buffer_puts(buffer_1,", want down");

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "run once" facility (patch for runit)
  2004-03-25 12:47 "run once" facility (patch for runit) Wayne Marshall
@ 2004-03-25 13:45 ` Laurent Bercot
  2004-03-25 13:51   ` Wayne Marshall
  2004-03-25 14:57 ` Charlie Brady
  1 sibling, 1 reply; 10+ messages in thread
From: Laurent Bercot @ 2004-03-25 13:45 UTC (permalink / raw)


> I have been influenced by Gerrit Pape's comments "why not think
> about eth0 as a service" and performing one-time system
> initializations with runit services, rather than various rc
> scripts.

 It is indeed possible to think of network connections as services,
which can be stopped and restarted.
 However, one-time system initialization is a different thing.
A one-time process, by definition, is _not_ a service. It is a process.
When it dies, it must not be restarted. What good is supervision in that
case ?

 The concepts of service, and supervision, are excellent. But we must
pay attention not to make the same mistakes as many people, trying to
cram everything under the sun into a single mold, making it practically
meaningless.

-- 
 Ska


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "run once" facility (patch for runit)
  2004-03-25 13:45 ` Laurent Bercot
@ 2004-03-25 13:51   ` Wayne Marshall
  2004-03-25 14:46     ` Alex Efros
  2004-03-25 15:00     ` Laurent Bercot
  0 siblings, 2 replies; 10+ messages in thread
From: Wayne Marshall @ 2004-03-25 13:51 UTC (permalink / raw)


Hi,

The runit package--conceived as a subsitute for init--can provide
a framework for system initialization, for both one-time
initializations and long-running processes.

It is not necessary to use it in this way, merely possible.
If so, one may find benefits in the consistency of the
runit framework, including the service control interface,
dependency checking, "./finish" clean-up, logging, etc.

Wayne

-- 
Wayne Marshall
guinix international
http://www.guinix.com/
"Computing Without Borders..."



On Thu, 25 Mar 2004 14:45:38 +0100
Laurent Bercot <ska-supervision@skarnet.org> wrote:

> > I have been influenced by Gerrit Pape's comments "why not
> > think about eth0 as a service" and performing one-time system
> > initializations with runit services, rather than various rc
> > scripts.
> 
>  It is indeed possible to think of network connections as
>  services,
> which can be stopped and restarted.
>  However, one-time system initialization is a different thing.
> A one-time process, by definition, is _not_ a service. It is a
> process. When it dies, it must not be restarted. What good is
> supervision in that case ?
> 
>  The concepts of service, and supervision, are excellent. But
>  we must
> pay attention not to make the same mistakes as many people,
> trying to cram everything under the sun into a single mold,
> making it practically meaningless.
> 
> -- 
>  Ska
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "run once" facility (patch for runit)
  2004-03-25 13:51   ` Wayne Marshall
@ 2004-03-25 14:46     ` Alex Efros
  2004-03-25 14:59       ` Charlie Brady
  2004-03-25 15:00     ` Laurent Bercot
  1 sibling, 1 reply; 10+ messages in thread
From: Alex Efros @ 2004-03-25 14:46 UTC (permalink / raw)


Hi!

Hi!

On Thu, Mar 25, 2004 at 04:51:24PM +0300, Wayne Marshall wrote:
> The runit package--conceived as a subsitute for init--can provide
> a framework for system initialization, for both one-time
> initializations and long-running processes.
> 
> It is not necessary to use it in this way, merely possible.
> If so, one may find benefits in the consistency of the
> runit framework, including the service control interface,
> dependency checking, "./finish" clean-up, logging, etc.

Yes, while you speak about "runit package" - you right. But when you go
and patch "runsv" - you made mistake (Laurent Bercot already explained why)!

One-time system initialization tasks already supported by "runit package"
in file /etc/runit/1, and this is only right place for such tasks.

If you want to improve "runit package" in "one-time system initialization"
area - then you should patch runit-init, not runsv! :-)

-- 
			WBR, Alex.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "run once" facility (patch for runit)
  2004-03-25 12:47 "run once" facility (patch for runit) Wayne Marshall
  2004-03-25 13:45 ` Laurent Bercot
@ 2004-03-25 14:57 ` Charlie Brady
  2004-03-25 21:08   ` Gerrit Pape
  1 sibling, 1 reply; 10+ messages in thread
From: Charlie Brady @ 2004-03-25 14:57 UTC (permalink / raw)



On 25 Mar 2004, Wayne Marshall wrote:

> I have been influenced by Gerrit Pape's comments "why not think
> about eth0 as a service" and performing one-time system
> initializations with runit services, rather than various rc
> scripts.
> 
> The attached patch to runit-1.0.1 recognizes the existence of a
> file named "myservice/once" in a service directory, to run the
> service one time.

I don't see a need to modify runit to provide a run-once facility. Just 
compile:

main() { pause(); }

and have your run script do:

#! /bin/sh

thing_you_want_to_do_once && pause

So I wonder whether your patch is "creeping featuritis".

--
Charlie



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "run once" facility (patch for runit)
  2004-03-25 14:46     ` Alex Efros
@ 2004-03-25 14:59       ` Charlie Brady
  0 siblings, 0 replies; 10+ messages in thread
From: Charlie Brady @ 2004-03-25 14:59 UTC (permalink / raw)
  Cc: supervision


On Thu, 25 Mar 2004, Alex Efros wrote:

> One-time system initialization tasks already supported by "runit package"
> in file /etc/runit/1,

Only if you run runit-init as your init process.

> and this is only right place for such tasks.

Only if runit-init is The One True init.

> If you want to improve "runit package" in "one-time system initialization"
> area - then you should patch runit-init, not runsv! :-)

See my last post for another solution to the posed problem.

--
Charlie



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "run once" facility (patch for runit)
  2004-03-25 13:51   ` Wayne Marshall
  2004-03-25 14:46     ` Alex Efros
@ 2004-03-25 15:00     ` Laurent Bercot
  1 sibling, 0 replies; 10+ messages in thread
From: Laurent Bercot @ 2004-03-25 15:00 UTC (permalink / raw)


> The runit package--conceived as a subsitute for init--can provide
> a framework for system initialization, for both one-time
> initializations and long-running processes.

 Yes.
 And runit's 'stage 1' has been especially designed for one-time
initializations. Is there a reason to allow 'stage 2' to also
perform one-time tasks ? I'm afraid it would cause more confusion
than it would be helpful.


> It is not necessary to use it in this way, merely possible.
> If so, one may find benefits in the consistency of the
> runit framework, including the service control interface,
> dependency checking, "./finish" clean-up, logging, etc.

 Consistency also means treating related things the same way, and
unrelated things in different ways. :)

-- 
 Ska


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "run once" facility (patch for runit)
  2004-03-25 14:57 ` Charlie Brady
@ 2004-03-25 21:08   ` Gerrit Pape
  2004-03-26  6:49     ` Wayne Marshall
  0 siblings, 1 reply; 10+ messages in thread
From: Gerrit Pape @ 2004-03-25 21:08 UTC (permalink / raw)


On Thu, Mar 25, 2004 at 09:57:12AM -0500, Charlie Brady wrote:
> On 25 Mar 2004, Wayne Marshall wrote:
> > I have been influenced by Gerrit Pape's comments "why not think
> > about eth0 as a service" and performing one-time system
> > initializations with runit services, rather than various rc
> > scripts.

I was thinking about a service daemon that takes the job of ifconfig.
On startup it sets the state of the ethernet interface, and terminates
if the state changes.  It then would be restarted by the supervisor, and
resets the state.  The state of the interface could possibly include
route informations and packet filter configuration, and may be defined
through files in a configuration directory, e.g. eth0/ip, eth0/net,
eth0/netmask, ...  Change ip address by running
 # echo 10.0.0.14 >eth0/ip && runsvctrl term eth0
But I'm not that sure about the benefits.

> > The attached patch to runit-1.0.1 recognizes the existence of a
> > file named "myservice/once" in a service directory, to run the
> > service one time.

Basically I'm with Laurent, either it's a long running service, or it is
an one-time task.  The latter should go into stage 1.

> I don't see a need to modify runit to provide a run-once facility. Just 
> compile:
> main() { pause(); }
> and have your run script do:
> #! /bin/sh
> thing_you_want_to_do_once && pause

Another possibility is
./run:
 #!/bin/sh
 exec thing_you_want_to_do_once
./finish:
 #!/bin/sh
 runsvctrl down .

Or
./finish:
 #!/bin/sh
 touch down
 runsvctrl down .
and
 rm -f /var/service/myservice/down
in stage 1.

Regards, Gerrit.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "run once" facility (patch for runit)
  2004-03-25 21:08   ` Gerrit Pape
@ 2004-03-26  6:49     ` Wayne Marshall
  2004-03-26  8:47       ` Gerrit Pape
  0 siblings, 1 reply; 10+ messages in thread
From: Wayne Marshall @ 2004-03-26  6:49 UTC (permalink / raw)


Organization: guinix international
X-Mailer: Sylpheed version 0.9.8claws (GTK+ 1.2.10; i386-unknown-openbsd3.4)
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

On Thu, 25 Mar 2004 21:08:01 +0000
Gerrit Pape <pape@smarden.org> wrote:

> > > The attached patch to runit-1.0.1 recognizes the existence
> > > of a file named "myservice/once" in a service directory, to
> > > run the service one time.
> 
> Basically I'm with Laurent, either it's a long running service,
> or it is an one-time task.  The latter should go into stage 1.
>

Many of our supervision vendors allow us to run a service once:

  # svc -o my_daemontools_service
  # msvc -o my_minit_service
  # runsvctrl o my_runit_service

Now I suppose we should request that this capability be removed,
so that we aren't tempted to actually use it...  ;-)

The touch(1) "once" suggested here is simply orthongonal to the
touch(1) "down" facility already available.  Each permits a
simple way to control the behavior of a service at start-up
--behaviors already available through the control interface--
avoiding the awkward constructs in run scripts:

> Another possibility is
> ./run:
>  #!/bin/sh
>  exec thing_you_want_to_do_once
> ./finish:
>  #!/bin/sh
>  runsvctrl down .
> 
> Or
> ./finish:
>  #!/bin/sh
>  touch down
>  runsvctrl down .
> and
>  rm -f /var/service/myservice/down
> in stage 1.
>

Following this line of thinking, one could suggest we don't
really need our supervisors to recognize "down" either:

#!/bin/sh
if [ -f ./down ] ; then
  runsvctrl d .
else
  exec myservice
fi


Oh well, stay well...

Wayne


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: "run once" facility (patch for runit)
  2004-03-26  6:49     ` Wayne Marshall
@ 2004-03-26  8:47       ` Gerrit Pape
  0 siblings, 0 replies; 10+ messages in thread
From: Gerrit Pape @ 2004-03-26  8:47 UTC (permalink / raw)


On Fri, Mar 26, 2004 at 09:48:48AM +0259, Wayne Marshall wrote:
> On Thu, 25 Mar 2004 21:08:01 +0000
> Gerrit Pape <pape@smarden.org> wrote:
> > > > The attached patch to runit-1.0.1 recognizes the existence
> > > > of a file named "myservice/once" in a service directory, to
> > > > run the service one time.
> > Basically I'm with Laurent, either it's a long running service,
> > or it is an one-time task.  The latter should go into stage 1.

> Many of our supervision vendors allow us to run a service once:
>   # svc -o my_daemontools_service
>   # msvc -o my_minit_service
>   # runsvctrl o my_runit_service
> Now I suppose we should request that this capability be removed,
> so that we aren't tempted to actually use it...  ;-)

Sorry, I cannot follow your reasoning here.

> The touch(1) "once" suggested here is simply orthongonal to the
> touch(1) "down" facility already available.  Each permits a
> simple way to control the behavior of a service at start-up
> --behaviors already available through the control interface--
> avoiding the awkward constructs in run scripts:

I don't consider it awkward, I rather think it's elegant.  And it does
exactly what you want to achieve.  Maybe you like this more:
./run:
 #!/bin/sh
 runsvctrl once .
 exec whatever

Frankly, I think the longer you work with daemontools or runit, you'll
most probably see that you finally don't need this feature.  And if not,
it's really easy to do it without changing runsv.

> Following this line of thinking, one could suggest we don't
> really need our supervisors to recognize "down" either:
> 
> #!/bin/sh
> if [ -f ./down ] ; then
>   runsvctrl d .
> else
>   exec myservice
> fi

This changes semantics.  How do you tell the supervisor to bring the
service, that's normally down, up?  How do you tell it to run the
service, that's normally down, once?

Regards, Gerrit.


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2004-03-26  8:47 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-25 12:47 "run once" facility (patch for runit) Wayne Marshall
2004-03-25 13:45 ` Laurent Bercot
2004-03-25 13:51   ` Wayne Marshall
2004-03-25 14:46     ` Alex Efros
2004-03-25 14:59       ` Charlie Brady
2004-03-25 15:00     ` Laurent Bercot
2004-03-25 14:57 ` Charlie Brady
2004-03-25 21:08   ` Gerrit Pape
2004-03-26  6:49     ` Wayne Marshall
2004-03-26  8:47       ` Gerrit Pape

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).