aboutsummaryrefslogtreecommitdiffstats
path: root/src/repo
diff options
context:
space:
mode:
Diffstat (limited to 'src/repo')
-rw-r--r--src/repo/deps-lib/s6rcrepo2
-rw-r--r--src/repo/s6-rc-set-copy.c67
-rw-r--r--src/repo/s6-rc-set-delete.c32
-rw-r--r--src/repo/s6rc_repo_compile.c23
-rw-r--r--src/repo/s6rc_repo_setcopy.c66
-rw-r--r--src/repo/s6rc_repo_setdelete.c30
6 files changed, 137 insertions, 83 deletions
diff --git a/src/repo/deps-lib/s6rcrepo b/src/repo/deps-lib/s6rcrepo
index 7d8b816..1935001 100644
--- a/src/repo/deps-lib/s6rcrepo
+++ b/src/repo/deps-lib/s6rcrepo
@@ -26,6 +26,8 @@ s6rc_repo_rxnames.o
s6rc_repo_sanitize_setname.o
s6rc_repo_sanitize_svname.o
s6rc_repo_setcompile.o
+s6rc_repo_setcopy.o
+s6rc_repo_setdelete.o
s6rc_repo_setuptodate.o
s6rc_repo_sv_bcmpr.o
s6rc_repo_sv_cmpr.o
diff --git a/src/repo/s6-rc-set-copy.c b/src/repo/s6-rc-set-copy.c
index 8cef993..13e14a5 100644
--- a/src/repo/s6-rc-set-copy.c
+++ b/src/repo/s6-rc-set-copy.c
@@ -2,14 +2,10 @@
#include <string.h>
#include <unistd.h>
-#include <errno.h>
#include <skalibs/uint64.h>
-#include <skalibs/posixplz.h>
#include <skalibs/envexec.h>
-#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
-#include <skalibs/unix-transactional.h>
#include <s6-rc/config.h>
#include <s6-rc/s6rc.h>
@@ -40,68 +36,23 @@ static gol_arg const rgola[] =
{ .so = 'r', .lo = "repodir", .i = GOLA_REPODIR }
} ;
-
-static uint64_t wgolb = 0 ;
-
-static void cleanup (char const *fn)
-{
- int e = errno ;
- rm_rf(fn) ;
- errno = e ;
-}
-
-static inline void docopy (char const *repo, char const *srcname, char const *dstname)
+static inline void docopy (char const *repo, char const *srcname, char const *dstname, uint64_t flags)
{
- size_t repolen = strlen(repo) ;
- size_t srclen = strlen(srcname) ;
- size_t dstlen = strlen(dstname) ;
- size_t r ;
- char src[repolen + srclen + 10] ;
- char dst[repolen + dstlen + 10] ;
- char realsrc[repolen + srclen + 18] ;
- char realdst[repolen + dstlen + 18] ;
- char olddst[repolen + dstlen + 18] ;
- memcpy(src, repo, repolen) ;
- memcpy(src + repolen, "/sources/", 9) ;
- memcpy(src + repolen + 9, srcname, srclen + 1) ;
- memcpy(dst, src, repolen + 9) ;
- memcpy(dst + repolen + 9, dstname, dstlen + 1) ;
- memcpy(olddst, dst, repolen + 9) ;
- olddst[repolen + 9] = 0 ;
- if (access(dst, F_OK) == -1)
- {
- if (errno != ENOENT) strerr_diefu2sys(111, "access ", dst) ;
- }
- else if (!(wgolb & GOLB_FORCE))
- strerr_dief4x(1, "set ", dstname, " already exists in repository ", repo) ;
-
- memcpy(realsrc, src, repolen + 9) ;
- r = readlink(src, realsrc + repolen + 9, srclen + 9) ;
- if (r == -1) strerr_diefu2sys(111, "readlink ", src) ;
- if (r != srclen + 8) strerr_dief3x(102, "symlink ", src, "doesn't point to a valid name") ;
- realsrc[repolen + srclen + 17] = 0 ;
- memcpy(realdst, dst, repolen + 9) ;
- realdst[repolen + 9] = '.' ;
- memcpy(realdst + repolen + 10, dstname, dstlen) ;
- memcpy(realdst + repolen + 10 + dstlen, ":XXXXXX", 8) ;
- if (mkntemp(realdst) == -1) strerr_diefu2sys(111, "mkntemp ", realdst) ;
- if (!hiercopy(realsrc, realdst))
- {
- cleanup(realdst) ;
- strerr_diefu4sys(111, "copy ", realsrc, " to ", realdst) ;
- }
- if (!atomic_symlink4(realdst + repolen + 9, dst, olddst + repolen + 9, dstlen + 9))
+ int e = s6rc_repo_setcopy(repo, srcname, dstname, !!(flags & GOLB_FORCE)) ;
+ switch (e)
{
- cleanup(realdst) ;
- strerr_diefu4sys(111, "symlink ", realdst + repolen + 9, " to ", dst) ;
+ case -2 : strerr_dief(102, "internal layout error: symlink inside ", srcname, " doesn't point to a valid name") ;
+ case -1 : strerr_dief(1, "set ", dstname, " already exists in repository ", repo) ;
+ case 0 : break ;
+ default : strerr_diefusys(111, "copy set ", srcname, " to set ", dstname) ;
}
- if (olddst[repolen + 9]) cleanup(olddst) ;
}
int main (int argc, char const *const *argv)
{
int fdlock ;
unsigned int verbosity = 1 ;
+ uint64_t wgolb = 0 ;
char const *wgola[GOLA_N] = { 0 } ;
unsigned int golc ;
@@ -121,6 +72,6 @@ int main (int argc, char const *const *argv)
tain_now_g() ;
fdlock = s6rc_repo_lock(wgola[GOLA_REPODIR], 1) ;
if (fdlock == -1) strerr_diefu2sys(111, "lock ", wgola[GOLA_REPODIR]) ;
- docopy(wgola[GOLA_REPODIR], argv[0], argv[1]) ;
+ docopy(wgola[GOLA_REPODIR], argv[0], argv[1], wgolb) ;
_exit(0) ;
}
diff --git a/src/repo/s6-rc-set-delete.c b/src/repo/s6-rc-set-delete.c
index 2987033..b32b253 100644
--- a/src/repo/s6-rc-set-delete.c
+++ b/src/repo/s6-rc-set-delete.c
@@ -18,38 +18,18 @@
#define USAGE "s6-rc-set-delete [ -v verbosity ] [ -r repo ] setname..."
#define dieusage() strerr_dieusage(100, USAGE)
-static inline void dodelete (char const *repo, char const *set)
+static void dodelete_compiled (char const *repo, char const *set)
{
size_t repolen = strlen(repo) ;
size_t setlen = strlen(set) ;
char fn[repolen + setlen + 11] ;
memcpy(fn, repo, repolen) ;
- memcpy(fn + repolen, "/sources/", 9) ;
- memcpy(fn + repolen + 9, set, setlen + 1) ;
- if (access(fn, W_OK) == -1)
- {
- if (errno != ENOENT) strerr_diefu2sys(111, "access ", fn) ;
- }
- else
- {
- ssize_t r ;
- char real[repolen + setlen + 18] ;
- memcpy(real, repo, repolen) ;
- memcpy(real + repolen, "/sources/", 9) ;
- r = readlink(fn, real + repolen + 9, setlen + 9) ;
- if (r == -1) strerr_diefu2sys(111, "readlink ", fn) ;
- else if (r != setlen + 8) strerr_dief3x(102, "symlink ", fn, " points to an invalid name") ;
- real[repolen + setlen + 17] = 0 ;
- unlink_void(fn) ;
- rm_rf(real) ;
- }
-
- memcpy(fn + repolen + 1, "compiled/", 9) ;
+ memcpy(fn + repolen, "/compiled/", 10) ;
memcpy(fn + repolen + 10, set, setlen + 1) ;
unlink_void(fn) ;
fn[repolen + 9] = 0 ;
DIR *dir = opendir(fn) ;
- if (!dir) strerr_diefu2sys(111, "opendir ", fn) ;
+ if (!dir) return ;
for (;;)
{
direntry *d ;
@@ -66,7 +46,6 @@ static inline void dodelete (char const *repo, char const *set)
rm_rf(tmp) ;
}
}
- if (errno) strerr_diefu2sys(111, "readdir ", fn) ;
dir_close(dir) ;
}
@@ -105,6 +84,9 @@ int main (int argc, char const *const *argv)
if (fdlock == -1) strerr_diefu2sys(111, "lock ", wgola[GOLA_REPODIR]) ;
for (unsigned int i = 0 ; i < argc ; i++)
- dodelete(wgola[GOLA_REPODIR], argv[i]) ;
+ {
+ s6rc_repo_setdelete(wgola[GOLA_REPODIR], argv[i]) ;
+ dodelete_compiled(wgola[GOLA_REPODIR], argv[i]) ;
+ }
_exit(0) ;
}
diff --git a/src/repo/s6rc_repo_compile.c b/src/repo/s6rc_repo_compile.c
index 64f8879..83fa744 100644
--- a/src/repo/s6rc_repo_compile.c
+++ b/src/repo/s6rc_repo_compile.c
@@ -22,6 +22,7 @@ int s6rc_repo_compile (char const *repo, char const *set, char const *const *rxs
size_t setlen = strlen(set) ;
size_t totrxlen = 0 ;
int needprefix = strcmp(set, ".ref") ;
+ char snap[repolen + setlen + 37] ;
char newc[repolen + setlen + 45] ;
memcpy(newc, repo, repolen) ;
memcpy(newc + repolen, "/compiled/.", 11) ;
@@ -89,6 +90,26 @@ int s6rc_repo_compile (char const *repo, char const *set, char const *const *rxs
return (WEXITSTATUS(wstat) == 1) - 1 ;
}
}
+
+ if (needprefix)
+ {
+ int e ;
+ memcpy(snap, ".snapshot:", 10) ;
+ memcpy(snap + 10, newc + repolen + 11, setlen + 26) ;
+ snap[repolen + setlen + 36] = 0 ;
+ e = s6rc_repo_setcopy(repo, set, snap, 1) ;
+ switch (e)
+ {
+ case -2 :
+ strerr_warnf("internal layout error while taking a snapshot of set ", set) ;
+ return (errno = EILSEQ, -1) ;
+ case 0 : break ;
+ default :
+ strerr_warnfusys("take a snapshot of set ", set) ;
+ return (errno = e, -1) ;
+ }
+ }
+
{
char fn[repolen + setlen + 11] ;
memcpy(fn, newc, repolen + 10) ;
@@ -97,10 +118,12 @@ int s6rc_repo_compile (char const *repo, char const *set, char const *const *rxs
{
int e = errno ;
rm_rf(newc) ;
+ s6rc_repo_setdelete(repo, snap) ;
errno = e ;
strerr_warnfu4sys("atomically symlink ", newc + repolen + 10, " to ", fn) ;
return -1 ;
}
}
+
return 1 + !!oldc[repolen + 10] ;
}
diff --git a/src/repo/s6rc_repo_setcopy.c b/src/repo/s6rc_repo_setcopy.c
new file mode 100644
index 0000000..30cb042
--- /dev/null
+++ b/src/repo/s6rc_repo_setcopy.c
@@ -0,0 +1,66 @@
+/* ISC license. */
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <skalibs/posixplz.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/unix-transactional.h>
+
+#include <s6-rc/repo.h>
+
+static void cleanup (char const *s)
+{
+ int e = errno ;
+ rm_rf(s) ;
+ errno = e ;
+}
+
+int s6rc_repo_setcopy (char const *repo, char const *srcname, char const *dstname, unsigned int flags)
+{
+ size_t repolen = strlen(repo) ;
+ size_t srclen = strlen(srcname) ;
+ size_t dstlen = strlen(dstname) ;
+ size_t r ;
+ char src[repolen + srclen + 10] ;
+ char dst[repolen + dstlen + 10] ;
+ char realsrc[repolen + srclen + 18] ;
+ char realdst[repolen + dstlen + 18] ;
+ char olddst[repolen + dstlen + 18] ;
+ memcpy(src, repo, repolen) ;
+ memcpy(src + repolen, "/sources/", 9) ;
+ memcpy(src + repolen + 9, srcname, srclen + 1) ;
+ memcpy(dst, src, repolen + 9) ;
+ memcpy(dst + repolen + 9, dstname, dstlen + 1) ;
+ memcpy(olddst, dst, repolen + 9) ;
+ olddst[repolen + 9] = 0 ;
+ if (access(dst, F_OK) == -1)
+ {
+ if (errno != ENOENT) return errno ;
+ }
+ else if (!(flags & 1)) return -1 ;
+
+ memcpy(realsrc, src, repolen + 9) ;
+ r = readlink(src, realsrc + repolen + 9, srclen + 9) ;
+ if (r == -1) return errno ;
+ if (r != srclen + 8) return -2 ;
+ realsrc[repolen + srclen + 17] = 0 ;
+ memcpy(realdst, dst, repolen + 9) ;
+ realdst[repolen + 9] = '.' ;
+ memcpy(realdst + repolen + 10, dstname, dstlen) ;
+ memcpy(realdst + repolen + 10 + dstlen, ":XXXXXX", 8) ;
+ if (mkntemp(realdst) == -1) return errno ;
+ if (!hiercopy(realsrc, realdst))
+ {
+ cleanup(realdst) ;
+ return errno ;
+ }
+ if (!atomic_symlink4(realdst + repolen + 9, dst, olddst + repolen + 9, dstlen + 9))
+ {
+ cleanup(realdst) ;
+ return errno ;
+ }
+ if (olddst[repolen + 9]) cleanup(olddst) ;
+ return 0 ;
+}
diff --git a/src/repo/s6rc_repo_setdelete.c b/src/repo/s6rc_repo_setdelete.c
new file mode 100644
index 0000000..a372d93
--- /dev/null
+++ b/src/repo/s6rc_repo_setdelete.c
@@ -0,0 +1,30 @@
+/* ISC license. */
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <skalibs/posixplz.h>
+#include <skalibs/djbunix.h>
+
+#include <s6-rc/repo.h>
+
+void s6rc_repo_setdelete (char const *repo, char const *set)
+{
+ size_t repolen = strlen(repo) ;
+ size_t setlen = strlen(set) ;
+ ssize_t r ;
+ char real[repolen + setlen + 18] ;
+ char fn[repolen + setlen + 11] ;
+ memcpy(fn, repo, repolen) ;
+ memcpy(fn + repolen, "/sources/", 9) ;
+ memcpy(fn + repolen + 9, set, setlen + 1) ;
+ if (access(fn, W_OK) == -1 && errno != ENOENT) return ;
+ memcpy(real, repo, repolen) ;
+ memcpy(real + repolen, "/sources/", 9) ;
+ r = readlink(fn, real + repolen + 9, setlen + 9) ;
+ if (r == -1 || r != setlen + 8) return ;
+ real[repolen + setlen + 17] = 0 ;
+ unlink_void(fn) ;
+ rm_rf(real) ;
+}