From: Alberto Leiva Popper Date: Thu, 18 Jul 2024 00:13:49 +0000 (-0600) Subject: Wednesday X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5b5af723431196b05c9bc62d36050e174f061c60;p=thirdparty%2FFORT-validator.git Wednesday --- diff --git a/src/Makefile.am b/src/Makefile.am index 49644d31..051c779f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,3 @@ -# Comment these out during releases. -# Also increase optimization I guess (-O0 -> -On) -LDFLAGS_DEBUG = -rdynamic - bin_PROGRAMS = fort fort_SOURCES = alloc.c alloc.h @@ -15,8 +11,8 @@ fort_CFLAGS += -std=c99 -D_DEFAULT_SOURCE=1 -D_XOPEN_SOURCE=700 -D_BSD_SOURCE=1 fort_CFLAGS += -O2 -g $(FORT_FLAGS) ${XML2_CFLAGS} if BACKTRACE_ENABLED fort_CFLAGS += -DBACKTRACE_ENABLED +fort_LDFLAGS = -rdynamic endif -fort_LDFLAGS = $(LDFLAGS_DEBUG) fort_LDADD = ${JANSSON_LIBS} ${CURL_LIBS} ${XML2_LIBS} # I'm tired of scrolling up, but feel free to comment this out. diff --git a/src/cache/local_cache.c b/src/cache/local_cache.c index 2aa72671..d64ada59 100644 --- a/src/cache/local_cache.c +++ b/src/cache/local_cache.c @@ -716,6 +716,21 @@ cache_print(void) cachent_print(cache.https); } +static void +prune_rsync(void) +{ + struct cache_node *domain, *tmp1; + struct cache_node *module, *tmp2; + struct cache_node *child, *tmp3; + + HASH_ITER(hh, cache.rsync->children, domain, tmp1) + HASH_ITER(hh, domain->children, module, tmp2) + HASH_ITER(hh, module->children, child, tmp3) { + pr_op_debug("Removing leftover: %s", child->url); + cachent_delete(child); + } +} + /* * XXX this needs to be hit only by files now * XXX result is redundant @@ -723,18 +738,24 @@ cache_print(void) static bool commit_rpp_delta(struct cache_node *node, char const *path) { + struct cache_node *child, *tmp; int error; pr_op_debug("Commiting %s", node->url); if (node == cache.rsync || node == cache.https) { pr_op_debug("Root; nothing to commit."); - return true; + goto branch; } if (node->tmpdir == NULL) { - pr_op_debug("Not changed; nothing to commit."); - return true; + if (node->children) { + pr_op_debug("Branch."); + goto branch; + } else { + pr_op_debug("Not changed; nothing to commit."); + return true; + } } if (node->flags & CNF_VALID) { @@ -742,15 +763,25 @@ commit_rpp_delta(struct cache_node *node, char const *path) error = file_merge_into(node->tmpdir, path); if (error) printf("rename errno: %d\n", error); // XXX + /* XXX Think more about the implications of this. */ + HASH_ITER(hh, node->children, child, tmp) + cachent_delete(child); } else { pr_op_debug("Validation unsuccessful; rollbacking."); - /* XXX same; just do remove(). */ + /* XXX just do remove()? */ file_rm_f(node->tmpdir); } free(node->tmpdir); node->tmpdir = NULL; return true; + +branch: node->flags = 0; + if (node->tmpdir) { + free(node->tmpdir); + node->tmpdir = NULL; + } + return true; } //static bool @@ -992,21 +1023,6 @@ remove_abandoned(void) free(rootpath); } -static void -remove_leftover_nodes(void) -{ - struct cache_node *domain, *tmp1; - struct cache_node *module, *tmp2; - struct cache_node *child, *tmp3; - - HASH_ITER(hh, cache.rsync->children, domain, tmp1) - HASH_ITER(hh, domain->children, module, tmp2) - HASH_ITER(hh, module->children, child, tmp3) { - pr_op_debug("Removing leftover: %s", child->url); - cachent_delete(child); - } -} - static bool remove_orphaned(struct cache_node *node, char const *path) { @@ -1025,6 +1041,9 @@ remove_orphaned(struct cache_node *node, char const *path) static void cleanup_cache(void) { + pr_op_debug("Ditching redundant rsync nodes."); + prune_rsync(); + pr_op_debug("Committing successful RPPs."); cachent_traverse(cache.rsync, commit_rpp_delta); cachent_traverse(cache.https, commit_rpp_delta); @@ -1036,7 +1055,6 @@ cleanup_cache(void) remove_abandoned(); pr_op_debug("Cleaning up orphaned nodes."); - remove_leftover_nodes(); cachent_traverse(cache.rsync, remove_orphaned); cachent_traverse(cache.https, remove_orphaned); } diff --git a/src/file.c b/src/file.c index 909268c5..ba29b491 100644 --- a/src/file.c +++ b/src/file.c @@ -152,7 +152,7 @@ merge_into(const char *src, const struct stat *st, int typeflag, dst = join_paths(merge_dst, &src[src_offset]); if (S_ISDIR(st->st_mode)) { - PR_DEBUG_MSG("mkdir -p %s", dst); + pr_op_debug("mkdir -p %s", dst); if (mkdir_p(dst, true, st->st_mode)) { PR_DEBUG_MSG("Failed: %s", strerror(errno)); goto end; @@ -163,9 +163,16 @@ merge_into(const char *src, const struct stat *st, int typeflag, if (utimensat(AT_FDCWD, dst, times, AT_SYMLINK_NOFOLLOW)) PR_DEBUG_MSG("utimensat: %s", strerror(errno)); } else { - PR_DEBUG_MSG("rename: %s -> %s", src, dst); - if (rename(src, dst)) - PR_DEBUG_MSG("rename: %s", strerror(errno)); + pr_op_debug("rename: %s -> %s", src, dst); + if (rename(src, dst)) { + if (errno == EISDIR) { + /* XXX stacked nftw()s */ + if (file_rm_rf(dst) != 0) + PR_DEBUG_MSG("%s", "AAAAAAAAAAA"); + if (rename(src, dst)) + PR_DEBUG_MSG("rename: %s", strerror(errno)); + } + } } end: free(dst); diff --git a/test/cache/local_cache_test.c b/test/cache/local_cache_test.c index b224f532..be5371d0 100644 --- a/test/cache/local_cache_test.c +++ b/test/cache/local_cache_test.c @@ -308,7 +308,7 @@ cleanup_test(void) { dl_error = 0; cache_commit(); - ck_assert_int_eq(0, system("rm -rf tmp/")); +// ck_assert_int_eq(0, system("rm -rf tmp/")); } /* Tests */ @@ -700,7 +700,6 @@ START_TEST(test_cache_cleanup_https) /* Add a child to the same branch, do not update the old one */ new_iteration(true); - PR_DEBUG; run_dl_https("https://a.b.c/e/f/g", 0, 1); run_cleanup(); ck_cache_https( @@ -710,37 +709,95 @@ START_TEST(test_cache_cleanup_https) unode("https/a.b.c/e/f", ufnode("https/a.b.c/e/f/g", HFULL, NULL), NULL), NULL), NULL), NULL)); -// /* -// * Download parent, do not update child. -// * Children need to die, because parent is now a file. -// */ -// new_iteration(true); -// run_dl_https("https://a.b.c/e/f", 0, 1); -// run_cleanup(); -// ck_cache(NODE("https://a.b.c/e/f", 0, 1, 1), NULL); -// -// /* Do it again. */ -// new_iteration(true); -// run_dl_https("https://a.b.c/e", 0, 1); -// run_cleanup(); -// ck_cache(NODE("https://a.b.c/e", 0, 1, 1), NULL); -// -// /* Empty the tree */ -// new_iteration(true); -// run_cleanup(); -// ck_cache(NULL); -// -// /* Node exists, but file doesn't */ -// new_iteration(true); -// run_dl_https("https://a.b.c/e", 0, 1); -// run_dl_https("https://a.b.c/f/g/h", 0, 1); -// ck_cache( -// NODE("https://a.b.c/e", 0, 1, 1), -// NODE("https://a.b.c/f/g/h", 0, 1, 1), -// NULL); -// ck_assert_int_eq(0, file_rm_rf("tmp/https/a.b.c/f/g/h")); -// run_cleanup(); -// ck_cache(NODE("https://a.b.c/e", 0, 1, 1), NULL); + /* + * Download parent, do not update child. + * Children need to die, because parent is now a file. + */ + new_iteration(true); + run_dl_https("https://a.b.c/e/f", 0, 1); + run_cleanup(); + ck_cache_https( + unode("https", + unode("https/a.b.c", + unode("https/a.b.c/e", + ufnode("https/a.b.c/e/f", HFULL, NULL), NULL), NULL), NULL)); + + /* Do it again. */ + new_iteration(true); + run_dl_https("https://a.b.c/e", 0, 1); + run_cleanup(); + ck_cache_https( + unode("https", + unode("https/a.b.c", + ufnode("https/a.b.c/e", HFULL, NULL), NULL), NULL)); + + + /* Empty the tree */ + new_iteration(true); + run_cleanup(); + ck_cache_https(unode("https", NULL)); + + /* Node exists, but file doesn't */ + new_iteration(true); + run_dl_https("https://a.b.c/e", 0, 1); + run_dl_https("https://a.b.c/f/g/h", 0, 1); + ck_cache_https( + unode("https", + unode("https/a.b.c", + uftnode("https/a.b.c/e", HFULL, "tmp/tmp/7", NULL), + unode("https/a.b.c/f", + unode("https/a.b.c/f/g", + uftnode("https/a.b.c/f/g/h", HFULL, "tmp/tmp/8", NULL), NULL), NULL), NULL), NULL)); + run_cleanup(); /* Move from tmp/tmp to tmp/https */ + ck_cache_https( + unode("https", + unode("https/a.b.c", + ufnode("https/a.b.c/e", HFULL, NULL), + unode("https/a.b.c/f", + unode("https/a.b.c/f/g", + ufnode("https/a.b.c/f/g/h", HFULL, NULL), NULL), NULL), NULL), NULL)); + ck_assert_int_eq(0, file_rm_rf("tmp/https/a.b.c/f/g/h")); + run_cleanup(); /* Actual test */ + ck_cache_https( + unode("https", + unode("https/a.b.c", + ufnode("https/a.b.c/e", HFULL, NULL), NULL), NULL)); + + /* Temporal version disappears before we get a commit */ + new_iteration(true); + run_dl_https("https://a.b.c/e", 0, 1); + ck_cache_https( + unode("https", + unode("https/a.b.c", + uftnode("https/a.b.c/e", HFULL, "tmp/tmp/9", NULL), NULL), NULL)); + ck_assert_int_eq(0, file_rm_rf("tmp/tmp/9")); + run_cleanup(); + ck_cache_https(unode("https", NULL)); + + /* Temporal version disappears after we get a commit */ + new_iteration(true); + run_dl_https("https://a.b.c/e", 0, 1); + ck_cache_https( + unode("https", + unode("https/a.b.c", + uftnode("https/a.b.c/e", HFULL, "tmp/tmp/A", NULL), NULL), NULL)); + run_cleanup(); /* Commit */ + ck_cache_https( + unode("https", + unode("https/a.b.c", + ufnode("https/a.b.c/e", HFULL, NULL, NULL), NULL), NULL)); + new_iteration(false); + run_dl_https("https://a.b.c/e", 0, 1); + ck_cache_https( + unode("https", + unode("https/a.b.c", + uftnode("https/a.b.c/e", HFULL, "tmp/tmp/B", NULL), NULL), NULL)); + ck_assert_int_eq(0, file_rm_rf("tmp/tmp/B")); + run_cleanup(); + ck_cache_https( + unode("https", + unode("https/a.b.c", + ufnode("https/a.b.c/e", HFULL, NULL), NULL), NULL)); cleanup_test(); }