diff options
author | Rob Austein <sra@hactrn.net> | 2011-06-27 22:16:30 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2011-06-27 22:16:30 +0000 |
commit | 590851d348e7cc15a30b84711a989717b4812e29 (patch) | |
tree | be199079406c0efc6e99e43d8d910a6faa0f72e1 | |
parent | 9b8e0ddbb27f711814d0f19fe6ae6f3e234785ec (diff) |
Checkpoint
svn path=/rcynic-ng/rcynic.c; revision=3905
-rw-r--r-- | rcynic-ng/rcynic.c | 120 |
1 files changed, 74 insertions, 46 deletions
diff --git a/rcynic-ng/rcynic.c b/rcynic-ng/rcynic.c index 48a37ee1..0f3053e5 100644 --- a/rcynic-ng/rcynic.c +++ b/rcynic-ng/rcynic.c @@ -1587,14 +1587,21 @@ static void rsync_mgr(const rcynic_ctx_t *rc) case -1: /* - * Not sure what to do here, for now just return. + * If we have no children, we're done here. + */ + if (errno == ECHILD) + return; + + /* + * Not a lot we can do for errors other than EINTR or ECHILD, + * other than whining. */ logmsg(rc, log_sys_err, "waitpid() returned error: %s", strerror(errno)); return; case 0: /* - * No children are ready to exit, continue to select() check. + * We have children, but none ready to exit, continue to select(). */ break; @@ -1656,7 +1663,7 @@ static void rsync_mgr(const rcynic_ctx_t *rc) (waitpid(ctx->pid, &pid_status, WNOHANG) == ctx->pid && WIFEXITED(pid_status))) continue; if (ctx->kill_count == 0) - logmsg(rc, log_debug, "Subprocess %u is taking too long", (unsigned) ctx->pid); + logmsg(rc, log_debug, "Subprocess %u is taking too long fetching %s", (unsigned) ctx->pid, ctx->uri.s); (void) kill(ctx->pid, ctx->kill_count++ < KILL_MAX ? SIGTERM : SIGKILL); ctx->deadline = now + 1; signaled++; @@ -1748,24 +1755,26 @@ static void rsync_mgr(const rcynic_ctx_t *rc) * Taken all together, this is pretty icky. Breaking it into separate * functions wouldn't help much. Don't read this on a full stomach. */ -static rsync_status_t rsync(const rcynic_ctx_t *rc, - const char * const *args, - const uri_t *uri, - STACK_OF(walk_ctx_t) *wsk, - void (*handler)(const rcynic_ctx_t *, const rsync_ctx_t *, const rsync_status_t)) +static rsync_status_t run_rsync(const rcynic_ctx_t *rc, + rsync_ctx_t *ctx) { static const char * const rsync_cmd[] = { "rsync", "--update", "--times", "--copy-links", "--itemize-changes", NULL }; - const char *argv[100]; + static const char * const rsync_tree_args[] = { + "--recursive", "--delete", NULL + }; + + const char *argv[10]; path_t path; - rsync_ctx_t *ctx = NULL; int i, argc = 0, flags, pipe_fds[2]; pipe_fds[0] = pipe_fds[1] = -1; - assert(rc && uri); + assert(rc && ctx); + + logmsg(rc, log_telemetry, "Fetching %s", ctx->uri.s); memset(argv, 0, sizeof(argv)); @@ -1773,53 +1782,35 @@ static rsync_status_t rsync(const rcynic_ctx_t *rc, assert(argc < sizeof(argv)/sizeof(*argv)); argv[argc++] = rsync_cmd[i]; } - if (args) { - for (i = 0; args[i]; i++) { + if (endswith(ctx->uri.s, "/")) { + for (i = 0; rsync_tree_args[i]; i++) { assert(argc < sizeof(argv)/sizeof(*argv)); - argv[argc++] = args[i]; + argv[argc++] = rsync_tree_args[i]; } } if (rc->rsync_program) argv[0] = rc->rsync_program; - if (!uri_to_filename(rc, uri, &path, &rc->unauthenticated)) { - logmsg(rc, log_data_err, "Couldn't extract filename from URI: %s", uri->s); - return rsync_status_failed; + if (!uri_to_filename(rc, &ctx->uri, &path, &rc->unauthenticated)) { + logmsg(rc, log_data_err, "Couldn't extract filename from URI: %s", ctx->uri.s); + goto lose; } assert(argc < sizeof(argv)/sizeof(*argv)); - argv[argc++] = uri->s; + argv[argc++] = ctx->uri.s; assert(argc < sizeof(argv)/sizeof(*argv)); argv[argc++] = path.s; - assert(strlen(uri->s) > SIZEOF_RSYNC); - if (rsync_cached_uri(rc, uri)) { - logmsg(rc, log_verbose, "rsync cache hit for %s", uri->s); - return rsync_status_done; - } - if (!mkdir_maybe(rc, &path)) { logmsg(rc, log_sys_err, "Couldn't make target directory: %s", path.s); - return rsync_status_failed; + goto lose; } - logmsg(rc, log_telemetry, "Fetching %s", uri->s); - for (i = 0; i < argc; i++) logmsg(rc, log_verbose, "rsync argv[%d]: %s", i, argv[i]); - if ((ctx = malloc(sizeof(*ctx))) == NULL) { - logmsg(rc, log_sys_err, "malloc(rsync_ctxt_t) failed"); - return rsync_status_failed; - } - memset(ctx, 0, sizeof(*ctx)); - memcpy(&ctx->uri, uri, sizeof(ctx->uri)); - ctx->handler = handler; - ctx->wsk = wsk; - ctx->fd = -1; - if (pipe(pipe_fds) < 0) { logmsg(rc, log_sys_err, "pipe() failed: %s", strerror(errno)); goto lose; @@ -1873,32 +1864,69 @@ static rsync_status_t rsync(const rcynic_ctx_t *rc, pipe_fds[1] = -1; if (rc->rsync_timeout) ctx->deadline = time(0) + rc->rsync_timeout; - if (!sk_rsync_ctx_t_push(rc->rsync_queue, ctx)) { - logmsg(rc, log_sys_err, "Couldn't push rsync state object onto queue, punting %s", uri->s); - goto lose; - } logmsg(rc, log_debug, "Subprocess %u started, current subprocess count %d", (unsigned) ctx->pid, sk_rsync_ctx_t_num(rc->rsync_queue)); return rsync_status_pending; } - lose: if (pipe_fds[0] != -1) (void) close(pipe_fds[0]); if (pipe_fds[1] != -1) (void) close(pipe_fds[1]); + if (rc->rsync_queue && ctx) + (void) sk_rsync_ctx_t_delete_ptr(rc->rsync_queue, ctx); if (ctx) free(ctx); return rsync_status_failed; } /** - * rsync a single file (CRL, manifest, ROA, whatever). + * Set up rsync context and attempt to start it. + */ +static rsync_status_t rsync(const rcynic_ctx_t *rc, + const uri_t *uri, + STACK_OF(walk_ctx_t) *wsk, + void (*handler)(const rcynic_ctx_t *, const rsync_ctx_t *, const rsync_status_t)) +{ + rsync_ctx_t *ctx = NULL; + + assert(rc && uri && strlen(uri->s) > SIZEOF_RSYNC); + + if (rsync_cached_uri(rc, uri)) { + logmsg(rc, log_verbose, "rsync cache hit for %s", uri->s); + return rsync_status_done; + } + + logmsg(rc, log_telemetry, "Fetching %s", uri->s); + + if ((ctx = malloc(sizeof(*ctx))) == NULL) { + logmsg(rc, log_sys_err, "malloc(rsync_ctxt_t) failed"); + return rsync_status_failed; + } + + memset(ctx, 0, sizeof(*ctx)); + ctx->uri = *uri; + ctx->handler = handler; + ctx->wsk = wsk; + ctx->fd = -1; + + if (!sk_rsync_ctx_t_push(rc->rsync_queue, ctx)) { + logmsg(rc, log_sys_err, "Couldn't push rsync state object onto queue, punting %s", ctx->uri.s); + free(ctx); + return rsync_status_failed; + } + + return run_rsync(rc, ctx); +} + +/** + * rsync a single file (trust anchor, CRL, manifest, ROA, whatever). */ static rsync_status_t rsync_file(const rcynic_ctx_t *rc, const uri_t *uri) { - return rsync(rc, NULL, uri, NULL, NULL); + assert(!endswith(uri->s, "/")); + return rsync(rc, uri, NULL, NULL); } /** @@ -1909,8 +1937,8 @@ static rsync_status_t rsync_tree(const rcynic_ctx_t *rc, STACK_OF(walk_ctx_t) *wsk, void (*handler)(const rcynic_ctx_t *, const rsync_ctx_t *, const rsync_status_t)) { - static const char * const rsync_args[] = { "--recursive", "--delete", NULL }; - return rsync(rc, rsync_args, uri, wsk, handler); + assert(endswith(uri->s, "/")); + return rsync(rc, uri, wsk, handler); } |