diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2017-07-12 18:24:36 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2017-07-12 18:24:36 +0000 |
commit | c2b02894be81650a85f940d82933a89cfb63bb09 (patch) | |
tree | 0feaea2cd17725ef910a696ff539ac9d93f5d6bf | |
parent | c015784fa23921127487aa3668ea5240c6f179ff (diff) | |
download | s6-rc-c2b02894be81650a85f940d82933a89cfb63bb09.tar.xz |
Fix a race condition in s6rc_servicedir_manage()
-rw-r--r-- | INSTALL | 2 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | doc/index.html | 4 | ||||
-rw-r--r-- | doc/upgrade.html | 7 | ||||
-rw-r--r-- | package/info | 2 | ||||
-rw-r--r-- | src/libs6rc/s6rc_servicedir_manage.c | 35 |
6 files changed, 42 insertions, 14 deletions
@@ -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: @@ -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) ; |