summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-07-12 18:24:36 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-07-12 18:24:36 +0000
commitc2b02894be81650a85f940d82933a89cfb63bb09 (patch)
tree0feaea2cd17725ef910a696ff539ac9d93f5d6bf
parentc015784fa23921127487aa3668ea5240c6f179ff (diff)
downloads6-rc-c2b02894be81650a85f940d82933a89cfb63bb09.tar.xz
Fix a race condition in s6rc_servicedir_manage()
-rw-r--r--INSTALL2
-rw-r--r--NEWS6
-rw-r--r--doc/index.html4
-rw-r--r--doc/upgrade.html7
-rw-r--r--package/info2
-rw-r--r--src/libs6rc/s6rc_servicedir_manage.c35
6 files changed, 42 insertions, 14 deletions
diff --git a/INSTALL b/INSTALL
index ee9ea24..1718257 100644
--- a/INSTALL
+++ b/INSTALL
@@ -8,7 +8,7 @@ Build Instructions
- GNU make version 3.81 or later
- skalibs version 2.5.1.1 or later: http://skarnet.org/software/skalibs/
- execline version 2.3.0.1 or later: http://skarnet.org/software/execline/
- - s6 version 2.6.0.0 or later: http://skarnet.org/software/s6/
+ - s6 version 2.6.0.1 or later: http://skarnet.org/software/s6/
This software will run on any operating system that implements
POSIX.1-2008, available at:
diff --git a/NEWS b/NEWS
index f8a0d08..b7d19fc 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,11 @@
Changelog for s6-rc.
+In 0.2.1.2
+----------
+
+ - Bugfix release.
+
+
In 0.2.1.1
----------
diff --git a/doc/index.html b/doc/index.html
index 5fb12d1..52759fa 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -52,7 +52,7 @@ scripts are also run in a controlled environment.
<li> <a href="//skarnet.org/software/execline/">execline</a> version
2.3.0.1 or later </li>
<li> <a href="//skarnet.org/software/s6/">s6</a> version
-2.6.0.0 or later </li>
+2.6.0.1 or later </li>
</ul>
<h3> Licensing </h3>
@@ -66,7 +66,7 @@ scripts are also run in a controlled environment.
<ul>
<li> The current released version of s6-rc is
-<a href="s6-rc-0.2.1.1.tar.gz">0.2.1.1</a>. </li>
+<a href="s6-rc-0.2.1.2.tar.gz">0.2.1.2</a>. </li>
<li> Alternatively, you can checkout a copy of the
<a href="//git.skarnet.org/cgi-bin/cgit.cgi/s6-rc/">s6-rc
git repository</a>:
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 7ff579f..c5e944a 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -18,6 +18,13 @@
<h1> What has changed in s6-rc </h1>
+<h2> in 0.2.1.2 </h2>
+
+<ul>
+ <li> <a href="//skarnet.org/software/s6/">s6</a>
+dependency bumped to 2.6.0.1. </li>
+</ul>
+
<h2> in 0.2.1.1 </h2>
<ul>
diff --git a/package/info b/package/info
index 42b0037..be6dde5 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
package=s6-rc
-version=0.2.1.1
+version=0.2.1.2
category=admin
package_macro_name=S6RC
diff --git a/src/libs6rc/s6rc_servicedir_manage.c b/src/libs6rc/s6rc_servicedir_manage.c
index 529067b..218c0af 100644
--- a/src/libs6rc/s6rc_servicedir_manage.c
+++ b/src/libs6rc/s6rc_servicedir_manage.c
@@ -48,6 +48,7 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st
if (d->d_name[0] == '.') continue ;
{
size_t len = strlen(d->d_name) ;
+ int fdlock ;
int r ;
uint16_t id ;
char srcfn[livelen + 20 + len] ;
@@ -55,25 +56,29 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st
memcpy(srcfn, dirfn, livelen + 12) ;
srcfn[livelen + 12] = '/' ;
memcpy(srcfn + livelen + 13, d->d_name, len + 1) ;
+ fdlock = s6_svc_lock_take(srcfn) ;
+ if (fdlock < 0) goto err ;
r = s6_svc_ok(srcfn) ;
- if (r < 0) { e = errno ; goto err ; }
+ if (r < 0) goto errinloop ;
if (!r)
{
memcpy(srcfn + livelen + 13 + len, "/down", 6) ;
- if (!touch(srcfn)) { e = errno ; goto err ; }
+ if (!touch(srcfn)) goto errinloop ;
memcpy(srcfn + livelen + 14 + len, "event", 6) ;
- if (!ftrigw_fifodir_make(srcfn, gid, 0)) { e = errno ; goto err ; }
+ if (!ftrigw_fifodir_make(srcfn, gid, 0)) goto errinloop ;
id = ftrigr_subscribe(&a, srcfn, "s", 0, deadline, stamp) ;
- if (!id) { e = errno ; goto err ; }
- if (!genalloc_append(uint16_t, &ids, &id)) { e = errno ; goto err ; }
+ if (!id) goto errinloop ;
+ s6_svc_lock_release(fdlock) ;
+ if (!genalloc_append(uint16_t, &ids, &id)) goto err ;
srcfn[livelen + 13 + len] = 0 ;
}
+ else s6_svc_lock_release(fdlock) ;
memcpy(dstfn, live, livelen) ;
memcpy(dstfn + livelen, "/scandir/", 9) ;
memcpy(dstfn + livelen + 9, d->d_name, len + 1) ;
if (symlink(srcfn, dstfn) < 0)
{
- if (!r || errno != EEXIST) { e = errno ; goto err ; }
+ if (!r || errno != EEXIST) goto err ;
}
else if (!r)
{
@@ -81,12 +86,17 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st
{
e = errno ;
s6rc_servicedir_unsupervise(live, d->d_name, 0) ;
- goto err ;
+ goto errn ;
}
}
+ continue ;
+ errinloop:
+ e = errno ;
+ s6_svc_lock_release(fdlock) ;
+ goto errn ;
}
}
- if (errno) { e = errno ; goto err ; }
+ if (errno) goto err ;
dir_close(dir) ;
{
char scanfn[livelen + 9] ;
@@ -94,10 +104,10 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st
memcpy(scanfn, live, livelen) ;
memcpy(scanfn + livelen, "/scandir", 9) ;
r = s6_svc_writectl(scanfn, S6_SVSCAN_CTLDIR, "a", 1) ;
- if (r < 0) { e = errno ; goto closederr ; }
+ if (r < 0) goto closederr ;
if (!r) ok = 3 ;
else if (ftrigr_wait_and(&a, genalloc_s(uint16_t, &ids), genalloc_len(uint16_t, &ids), deadline, stamp) < 0)
- { e = errno ; goto closederr ; }
+ goto closederr ;
}
ftrigr_end(&a) ;
@@ -106,8 +116,13 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st
return ok ;
err:
+ e = errno ;
+ errn:
dir_close(dir) ;
+ goto closederrn ;
closederr:
+ e = errno ;
+ closederrn:
ftrigr_end(&a) ;
genalloc_free(uint16_t, &ids) ;
rollback(live, newnames.s, newnames.len) ;