From: Derrick Stolee <dstolee@xxxxxxxxxxxxx> Git has the ability to fork the process and launch a "daemonized" copy of the current process. This is used to launch a background 'git gc' command in some cases or to launch the 'git daemon' server process. Update the 'git job-runner' command with a --daemonize option that launches this background process. The implementation of daemonize() in setup.c is very clear that this may no-op and return an error if NO_POSIX_GOODIES is not defined. Include an error message to point out that this mechanism may not be available on a platform-by-platform basis. Include a clear error message that daemonize() might fail due to platform incompatibilities. I have been running the current version of this series on my Linux VM using --daemonize to keep my copies of torvalds/linux and git/git maintained. Using GIT_TRACE2_PERF set to a path, I can see that the 'git run-job' processes are being created on the correct schedule according to my config for each. RFC QUESTION: I notice that 'git gc' does not document --daemonize. Is that intentional? Or is it an oversight? Signed-off-by: Derrick Stolee <dstolee@xxxxxxxxxxxxx> --- Documentation/git-job-runner.txt | 5 +++++ builtin/job-runner.c | 12 ++++++++++-- cache.h | 4 +--- daemon.h | 7 +++++++ 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 daemon.h diff --git a/Documentation/git-job-runner.txt b/Documentation/git-job-runner.txt index 0719113a008..f48d6bcd10b 100644 --- a/Documentation/git-job-runner.txt +++ b/Documentation/git-job-runner.txt @@ -39,6 +39,11 @@ OPTIONS If this is not specified, then the default will be found from `jobs.loopInterval` or the default value of 30 minutes. +--daemonize:: + If supported by your platform, launch an identical + `git job-runner` process in the background and close the + foreground process immediately. + CONFIGURATION ------------- diff --git a/builtin/job-runner.c b/builtin/job-runner.c index 45f82a50d49..3b629428ef1 100644 --- a/builtin/job-runner.c +++ b/builtin/job-runner.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "config.h" +#include "daemon.h" #include "parse-options.h" #include "run-command.h" #include "string-list.h" @@ -78,7 +79,8 @@ static int try_get_config(const char *job, fclose(proc_out); - result = finish_command(config_proc); + /* ignore result as 'git config' fails on non-existent value */ + finish_command(config_proc); cleanup: free(config_proc); @@ -93,7 +95,7 @@ static int try_get_timestamp(const char *job, char *value; int result = try_get_config(job, repo, postfix, &value); - if (!result) { + if (!result && value) { *t = atol(value); free(value); } @@ -304,6 +306,7 @@ static int initialize_jobs(struct string_list *list) return 0; } +static int arg_daemonize = 0; int cmd_job_runner(int argc, const char **argv, const char *prefix) { int result; @@ -316,6 +319,8 @@ int cmd_job_runner(int argc, const char **argv, const char *prefix) PARSE_OPT_NONEG, arg_repos_append), OPT_INTEGER(0, "interval", &arg_interval, N_("seconds to pause between running any jobs")), + OPT_BOOL(0, "daemonize", &arg_daemonize, + N_("request to spawn a background process")), OPT_END(), }; @@ -328,6 +333,9 @@ int cmd_job_runner(int argc, const char **argv, const char *prefix) builtin_job_runner_usage, 0); + if (arg_daemonize && daemonize()) + die(_("failed to daemonize; this may not be available on your platform.")); + result = initialize_jobs(&job_list); while (!(result = run_job_loop_step(&job_list))) { diff --git a/cache.h b/cache.h index c77b95870a5..34ef690faf6 100644 --- a/cache.h +++ b/cache.h @@ -17,6 +17,7 @@ #include "sha1-array.h" #include "repository.h" #include "mem-pool.h" +#include "daemon.h" #include <zlib.h> typedef struct git_zstream { @@ -631,9 +632,6 @@ int init_db(const char *git_dir, const char *real_git_dir, unsigned int flags); void initialize_repository_version(int hash_algo); -void sanitize_stdfds(void); -int daemonize(void); - #define alloc_nr(x) (((x)+16)*3/2) /** diff --git a/daemon.h b/daemon.h new file mode 100644 index 00000000000..c1e50a20354 --- /dev/null +++ b/daemon.h @@ -0,0 +1,7 @@ +#ifndef DAEMON_H__ +#define DAEMON_H__ + +void sanitize_stdfds(void); +int daemonize(void); + +#endif -- gitgitgadget