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
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) {
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
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)
{
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);
remove_abandoned();
pr_op_debug("Cleaning up orphaned nodes.");
- remove_leftover_nodes();
cachent_traverse(cache.rsync, remove_orphaned);
cachent_traverse(cache.https, remove_orphaned);
}
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;
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);
{
dl_error = 0;
cache_commit();
- ck_assert_int_eq(0, system("rm -rf tmp/"));
+// ck_assert_int_eq(0, system("rm -rf tmp/"));
}
/* Tests */
/* 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(
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();
}