summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2015-07-14 20:11:53 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2015-07-14 20:11:53 +0000
commit9fdde3fe9f514f021728db63f387593c273f028e (patch)
treedd2eb58f790451318916ce66c1cfc701b69ff821
parent08662f8255b6f168b75abc997769b41b69559082 (diff)
downloads6-rc-9fdde3fe9f514f021728db63f387593c273f028e.tar.xz
Various bugfixes, thanks Colin Booth
(haven't touched the timeouts yet)
-rw-r--r--doc/index.html7
-rw-r--r--doc/s6-rc-init.html4
-rw-r--r--doc/s6-rc.html11
-rw-r--r--src/include/s6-rc/s6rc-db.h1
-rw-r--r--src/libs6rc/s6rc_db_read.c19
-rw-r--r--src/s6-rc/s6-rc-compile.c29
-rw-r--r--src/s6-rc/s6-rc-db.c39
-rw-r--r--src/s6-rc/s6-rc.c25
8 files changed, 65 insertions, 70 deletions
diff --git a/doc/index.html b/doc/index.html
index 4f717be..e9a70b4 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -131,12 +131,5 @@ for s6, with a similar design (but no compilation phase). </li>
is a complete init system and service manager for Unix. </li>
</ul>
-<h3> Discussion </h3>
-
-<ul>
- <li> <tt>s6-rc</tt> is discussed on the
-<a href="http://skarnet.org/lists.html#skaware">skaware</a> mailing-list. </li>
-</ul>
-
</body>
</html>
diff --git a/doc/s6-rc-init.html b/doc/s6-rc-init.html
index f2bd8e1..39d11a7 100644
--- a/doc/s6-rc-init.html
+++ b/doc/s6-rc-init.html
@@ -77,7 +77,9 @@ filesystem. Default is
<p>
Administrators should invoke <tt>s6-rc-init</tt> once, in their
-early boot scripts, after s6-svscan is functional but before any
+early boot scripts, after s6-svscan is functional and ready to
+supervise longrun services (and after its catch-all logger, if
+any, has started), but before any
other initialization. (The rest of the initialization can be
written as a set of s6-rc services, and performed by just one
invocation of the <a href="s6-rc.html">s6-rc change</a> command.)
diff --git a/doc/s6-rc.html b/doc/s6-rc.html
index 8d976d6..ae3e469 100644
--- a/doc/s6-rc.html
+++ b/doc/s6-rc.html
@@ -217,7 +217,16 @@ readiness notification, the
<a href="http://skarnet.org/software/s6/s6-svc.html">s6-svc</a>
command that is invoked by s6-rc will print a warning message, and
the transition will be considered successful as soon as the daemon
-is up.
+is up, i.e. as soon as the <tt>run</tt> script is executed by
+<a href="http://skarnet.org/software/s6/s6-supervise.html">s6-supervise</a>.
+</p>
+
+<p>
+ When a longrun service supports readiness notification, unless
+a nonzero timeout has been declared in the <tt>timeout-up</tt> file
+in the service definition directory,
+s6-rc will wait forever on an "up" transition for the notification
+to arrive. The transition will fail if a timeout occurs.
</p>
<p>
diff --git a/src/include/s6-rc/s6rc-db.h b/src/include/s6-rc/s6rc-db.h
index cc2bb9f..bc516b2 100644
--- a/src/include/s6-rc/s6rc-db.h
+++ b/src/include/s6-rc/s6rc-db.h
@@ -41,7 +41,6 @@ struct s6rc_service_s
uint32 ndeps[2] ;
uint32 timeout[2] ;
s6rc_longshot_t x ;
- unsigned char type : 1 ;
} ;
typedef struct s6rc_db_s s6rc_db_t, *s6rc_db_t_ref ;
diff --git a/src/libs6rc/s6rc_db_read.c b/src/libs6rc/s6rc_db_read.c
index f10462c..7a38797 100644
--- a/src/libs6rc/s6rc_db_read.c
+++ b/src/libs6rc/s6rc_db_read.c
@@ -53,13 +53,10 @@ static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db)
s6rc_service_t *sv = db->services ;
unsigned int nargvs = db->nargvs ;
unsigned int argvpos = 0 ;
- char type ;
-#ifdef DEBUG
register unsigned int i = 0 ;
-#endif
- while (n--)
+ for (; i < n ; i++)
{
- DBG("iteration %u - %u remaining", i++, n) ;
+ DBG("iteration %u/%u remaining", i+1, n) ;
if (!s6rc_db_read_uint32(b, &sv->name)) return -1 ;
DBG(" name is %u: %s", sv->name, db->string + sv->name) ;
if (sv->name >= db->stringlen) return 0 ;
@@ -91,10 +88,8 @@ static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db)
DBG(" dep on %u", db->deps[db->ndeps + sv->deps[1] + k]) ;
}
#endif
- if (buffer_get(b, &type, 1) < 1) return -1 ;
- if (type)
+ if (i < db->nlong)
{
- sv->type = 1 ;
if (!s6rc_db_read_uint32(b, &sv->x.longrun.servicedir)) return -1 ;
DBG(" longrun - servicedir is %u: %s", sv->x.longrun.servicedir, db->string + sv->x.longrun.servicedir) ;
if (!s6rc_db_check_valid_string(db->string, db->stringlen, sv->x.longrun.servicedir)) return 0 ;
@@ -103,7 +98,6 @@ static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db)
{
unsigned int i = 0 ;
DBG(" oneshot") ;
- sv->type = 0 ;
for (; i < 2 ; i++)
{
uint32 pos, argc ;
@@ -121,8 +115,11 @@ static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db)
if (!nargvs--) return 0 ; db->argvs[argvpos++] = 0 ;
}
}
- if (buffer_get(b, &type, 1) < 1) return -1 ;
- if (type != '\376') return 0 ;
+ {
+ char c ;
+ if (buffer_get(b, &c, 1) < 1) return -1 ;
+ if (c != '\376') return 0 ;
+ }
sv++ ;
}
if (nargvs) return 0 ;
diff --git a/src/s6-rc/s6-rc-compile.c b/src/s6-rc/s6-rc-compile.c
index 97990a1..7e4e515 100644
--- a/src/s6-rc/s6-rc-compile.c
+++ b/src/s6-rc/s6-rc-compile.c
@@ -694,7 +694,6 @@ static inline unsigned int resolve_services (s6rc_db_t *db, before_t const *be,
byte_zero(sarray, nbits * n) ;
for (; i < db->nlong ; i++)
{
- db->services[i].type = 1 ;
db->services[i].name = longruns[i].common.kname ;
db->services[i].flags = longruns[i].common.annotation_flags ;
db->services[i].timeout[0] = longruns[i].common.timeout[0] ;
@@ -706,7 +705,6 @@ static inline unsigned int resolve_services (s6rc_db_t *db, before_t const *be,
}
for (i = 0 ; i < db->nshort ; i++)
{
- db->services[db->nlong + i].type = 0 ;
db->services[db->nlong + i].name = oneshots[i].common.kname ;
db->services[db->nlong + i].flags = oneshots[i].common.annotation_flags ;
db->services[db->nlong + i].timeout[0] = oneshots[i].common.timeout[0] ;
@@ -1037,9 +1035,9 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db,
}
}
-static inline int write_service (buffer *b, s6rc_service_t const *sv)
+static inline int write_service (buffer *b, s6rc_service_t const *sv, int type)
{
- char pack[50] ;
+ char pack[49] ;
unsigned int m ;
uint32_pack_big(pack, sv->name) ;
uint32_pack_big(pack + 4, sv->flags) ;
@@ -1049,19 +1047,18 @@ static inline int write_service (buffer *b, s6rc_service_t const *sv)
uint32_pack_big(pack + 20, sv->ndeps[1]) ;
uint32_pack_big(pack + 24, sv->deps[0]) ;
uint32_pack_big(pack + 28, sv->deps[1]) ;
- pack[32] = sv->type ;
- if (sv->type)
+ if (type)
{
- uint32_pack_big(pack + 33, sv->x.longrun.servicedir) ;
- m = 37 ;
+ uint32_pack_big(pack + 32, sv->x.longrun.servicedir) ;
+ m = 36 ;
}
else
{
- uint32_pack_big(pack + 33, sv->x.oneshot.argc[0]) ;
- uint32_pack_big(pack + 37, sv->x.oneshot.argv[0]) ;
- uint32_pack_big(pack + 41, sv->x.oneshot.argc[1]) ;
- uint32_pack_big(pack + 45, sv->x.oneshot.argv[1]) ;
- m = 49 ;
+ uint32_pack_big(pack + 32, sv->x.oneshot.argc[0]) ;
+ uint32_pack_big(pack + 36, sv->x.oneshot.argv[0]) ;
+ uint32_pack_big(pack + 40, sv->x.oneshot.argc[1]) ;
+ uint32_pack_big(pack + 44, sv->x.oneshot.argv[1]) ;
+ m = 48 ;
}
pack[m++] = '\376' ;
return (buffer_put(b, pack, m) == m) ;
@@ -1107,9 +1104,11 @@ static inline void write_db (char const *compiled, s6rc_db_t const *db)
}
{
- unsigned int i = db->nshort + db->nlong ;
+ unsigned int i = db->nlong ;
s6rc_service_t const *sv = db->services ;
- while (i--) if (!write_service(&b, sv++)) goto err ;
+ while (i--) if (!write_service(&b, sv++, 1)) goto err ;
+ i = db->nshort ;
+ while (i--) if (!write_service(&b, sv++, 0)) goto err ;
}
if (buffer_putflush(&b, S6RC_DB_BANNER_END, S6RC_DB_BANNER_END_LEN) < 0)
diff --git a/src/s6-rc/s6-rc-db.c b/src/s6-rc/s6-rc-db.c
index 8cfe5b9..5d0493c 100644
--- a/src/s6-rc/s6-rc-db.c
+++ b/src/s6-rc/s6-rc-db.c
@@ -138,7 +138,6 @@ static unsigned int resolve_service (char const *name)
int fd = open_readatb(fdcompiled, "resolve.cdb") ;
uint32 x ;
char pack[4] ;
- unsigned int len ;
register int r ;
if (fd < 0) strerr_diefu3sys(111, "open ", compiled, "/resolve.cdb") ;
if (!cdb_init_map(&c, fd, 1))
@@ -146,7 +145,6 @@ static unsigned int resolve_service (char const *name)
r = cdb_find(&c, name, str_len(name)) ;
if (r < 0) strerr_diefu3sys(111, "read ", compiled, "/resolve.cdb") ;
if (!r) strerr_dief3x(1, name, " is not a valid identifier in ", compiled) ;
- len = cdb_datalen(&c) >> 2 ;
if (cdb_datalen(&c) != 4) return db->nshort + db->nlong ;
if (cdb_read(&c, pack, 4, cdb_datapos(&c)) < 0)
strerr_diefu3sys(111, "cdb_read ", compiled, "/resolve.cdb") ;
@@ -163,7 +161,7 @@ static unsigned int resolve_service (char const *name)
static void print_type (char const *name)
{
unsigned int n = resolve_service(name) ;
- char const *s = n >= db->nshort + db->nlong ? "bundle" : db->services[n].type ? "longrun" : "oneshot" ;
+ char const *s = n >= db->nshort + db->nlong ? "bundle" : n < db->nlong ? "longrun" : "oneshot" ;
if (buffer_puts(buffer_1, s) < 0
|| buffer_putflush(buffer_1, "\n", 1) < 0)
strerr_diefu1sys(111, "write to stdout") ;
@@ -192,23 +190,6 @@ static void print_servicedir (char const *name)
strerr_diefu1sys(111, "write to stdout") ;
}
-static void print_deps (char const *name, int h)
-{
- uint32 const *p ;
- unsigned int ndeps ;
- unsigned int n = resolve_service(name) ;
- if (n >= db->nshort + db->nlong)
- strerr_dief5x(1, "in database ", compiled, ": identifier ", name, " represents a bundle") ;
- p = db->deps + h * db->ndeps + db->services[n].deps[h] ;
- ndeps = db->services[n].ndeps[h] ;
- while (ndeps--)
- if (buffer_puts(buffer_1, db->string + db->services[*p++].name) < 0
- || buffer_put(buffer_1, "\n", 1) < 0)
- strerr_diefu1sys(111, "write to stdout") ;
- if (!buffer_flush(buffer_1))
- strerr_diefu1sys(111, "write to stdout") ;
-}
-
static void print_script (char const *name, int h)
{
unsigned int argc ;
@@ -239,7 +220,7 @@ static inline void print_flags (char const *name)
strerr_diefu1sys(111, "write to stdout") ;
}
-static void print_atomics (char const *const *argv, int h, int doclosure)
+static void print_union (char const *const *argv, int h, int isdeps, int doclosure)
{
unsigned int n = db->nshort + db->nlong ;
cdb_t c = CDB_ZERO ;
@@ -266,7 +247,13 @@ static void print_atomics (char const *const *argv, int h, int doclosure)
uint32_unpack_big(p, &x) ; p += 4 ;
if (x >= db->nshort + db->nlong)
strerr_dief2x(4, "invalid database in ", compiled) ;
- state[x] |= 1 ;
+ if (isdeps)
+ {
+ register uint32 ndeps = db->services[x].ndeps[h] ;
+ register uint32 const *deps = db->deps + h * db->ndeps + db->services[x].deps[h] ;
+ while (ndeps--) state[*deps++] |= 1 ;
+ }
+ else state[x] |= 1 ;
}
}
}
@@ -290,7 +277,7 @@ static inline void print_help (void)
"s6-rc-db type servicename\n"
"s6-rc-db [ -u | -d ] timeout atomicname\n"
"s6-rc-db contents bundlename\n"
-"s6-rc-db [ -u | -d ] dependencies servicename\n"
+"s6-rc-db [ -u | -d ] dependencies servicename...\n"
"s6-rc-db servicedir longrunname\n"
"s6-rc-db [ -u | -d ] script oneshotname\n"
"s6-rc-db flags atomicname\n"
@@ -461,7 +448,7 @@ int main (int argc, char const *const *argv)
print_bundle_contents(argv[1]) ;
break ;
case 6 : /* dependencies */
- print_deps(argv[1], up) ;
+ print_union(argv + 1, up, 1, 0) ;
break ;
case 7 : /* servicedir */
print_servicedir(argv[1]) ;
@@ -473,10 +460,10 @@ int main (int argc, char const *const *argv)
print_flags(argv[1]) ;
break ;
case 10 : /* atomics */
- print_atomics(argv + 1, 1, 0) ;
+ print_union(argv + 1, 1, 0, 0) ;
break ;
case 11 : /* all-dependencies */
- print_atomics(argv + 1, up, 1) ;
+ print_union(argv + 1, up, 0, 1) ;
break ;
}
}
diff --git a/src/s6-rc/s6-rc.c b/src/s6-rc/s6-rc.c
index 4cb68b6..381b910 100644
--- a/src/s6-rc/s6-rc.c
+++ b/src/s6-rc/s6-rc.c
@@ -127,7 +127,7 @@ static pid_t start_longrun (unsigned int i, int h)
strerr_warnwu2sys("access ", servicefn) ;
}
}
- byte_copy(servicefn + livelen + 13 + svdlen, 6, "/down") ;
+ servicefn[livelen + 13 + svdlen] = 0 ;
fmt[uint32_fmt(fmt, db->services[i].timeout[h])] = 0 ;
vfmt[uint_fmt(vfmt, verbosity)] = 0 ;
if (dryrun[0])
@@ -146,27 +146,35 @@ static pid_t start_longrun (unsigned int i, int h)
newargv[m++] = "--" ;
newargv[m++] = servicefn ;
newargv[m++] = 0 ;
+ return child_spawn0(newargv[0], newargv, (char const *const *)environ) ;
+}
+static void success_longrun (unsigned int i, int h)
+{
if (!dryrun[0])
{
+ unsigned int svdlen = str_len(db->string + db->services[i].x.longrun.servicedir) ;
+ char fn[livelen + svdlen + 19] ;
+ byte_copy(fn, livelen, live) ;
+ byte_copy(fn + livelen, 13, "/servicedirs/") ;
+ byte_copy(fn + livelen + 13, svdlen, db->string + db->services[i].x.longrun.servicedir) ;
+ byte_copy(fn + livelen + 13 + svdlen, 6, "/down") ;
if (h)
{
- if (unlink(servicefn) < 0 && verbosity)
- strerr_warnwu2sys("unlink ", servicefn) ;
+ if (unlink(fn) < 0 && verbosity)
+ strerr_warnwu2sys("unlink ", fn) ;
}
else
{
- int fd = open_trunc(servicefn) ;
+ int fd = open_trunc(fn) ;
if (fd < 0)
{
if (verbosity)
- strerr_warnwu2sys("touch ", servicefn) ;
+ strerr_warnwu2sys("touch ", fn) ;
}
else fd_close(fd) ;
}
}
- servicefn[livelen + 13 + svdlen] = 0 ;
- return child_spawn0(newargv[0], newargv, (char const *const *)environ) ;
}
static void broadcast_success (unsigned int, int) ;
@@ -185,7 +193,7 @@ static void examine (unsigned int i, int h)
}
else
{
- pidindex[npids].pid = db->services[i].type ? start_longrun(i, h) : start_oneshot(i, h) ;
+ pidindex[npids].pid = i < db->nlong ? start_longrun(i, h) : start_oneshot(i, h) ;
if (pidindex[npids].pid)
{
pidindex[npids++].i = i ;
@@ -218,6 +226,7 @@ static void broadcast_success (unsigned int i, int h)
static void on_success (unsigned int i, int h)
{
+ if (i < db->nlong) success_longrun(i, h) ;
if (h) state[i] |= 1 ; else state[i] &= 254 ;
announce() ;
if (verbosity >= 2)