From: SURA <sura907@xxxxxxxxxxx> In Gitee.com, I often use scripts to start a time-limited "git fetch". When the execution time of'git fetch' is too long, send a signal (such as SIGINT) to the'git fetch' process But I found that after the process exits, there are some files in the format of 'objects/pack/tmp_pack_XXXXXX' on the disk. They are usually very large (some of them exceed 5G), and'git gc' has no effect on them. These fetch_tmp_pack files will gradually fill up the disk. For a long time, I set F_WRLCK to the file to confirm whether the file is opened by other processes, and delete the file if it is not opened Obviously this is only a temporary solution, I think it should be fixed from git I found fetch will start a 'index-pack' sub-process, this sub-process create the tmp_pack 1. make 'index-pack' unlink tmp_pack when get signal 2. make 'fetch' send signal to 'index-pack' when get signal Signed-off-by: SURA <sura907@xxxxxxxxxxx> --- builtin/fetch.c: clean tmp pack after receive signal Clean tmp-pack after 'git fetch' process get signal(SIGINT, SIGHUP, SIGTERM, SIGQUIT or SIGPIPE) Only for operations using ‘wire protocol version 2’ and ssh Signed-off-by: SURA sura907@xxxxxxxxxxx Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-890%2FSURA907%2Fgit-fetch-tmp-pack-v1 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-890/SURA907/git-fetch-tmp-pack-v1 Pull-Request: https://github.com/gitgitgadget/git/pull/890 builtin/fetch-pack.c | 3 ++- builtin/fetch.c | 10 ++++++++++ builtin/index-pack.c | 18 ++++++++++++++++++ fetch-pack.c | 7 +++++-- fetch-pack.h | 3 ++- transport.c | 3 ++- transport.h | 6 ++++++ 7 files changed, 45 insertions(+), 5 deletions(-) diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index c2d96f4c89ab..49a3e0bf2ae3 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -56,6 +56,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) struct string_list deepen_not = STRING_LIST_INIT_DUP; struct packet_reader reader; enum protocol_version version; + pid_t index_pack_pid = -1; fetch_if_missing = 0; @@ -232,7 +233,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) } ref = fetch_pack(&args, fd, ref, sought, nr_sought, - &shallow, pack_lockfiles_ptr, version); + &shallow, pack_lockfiles_ptr, version, &index_pack_pid); if (pack_lockfiles.nr) { int i; diff --git a/builtin/fetch.c b/builtin/fetch.c index 0b90de87c7a2..a87efa23ceb5 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -224,8 +224,18 @@ static void unlock_pack(void) transport_unlock_pack(gsecondary); } +static void send_signo_to_index_pack(int signo) +{ + if (gtransport && gtransport->index_pack_pid > 0) + kill(gtransport->index_pack_pid, signo); + + if (gsecondary && gsecondary->index_pack_pid > 0) + kill(gsecondary->index_pack_pid, signo); +} + static void unlock_pack_on_signal(int signo) { + send_signo_to_index_pack(signo); unlock_pack(); sigchain_pop(signo); raise(signo); diff --git a/builtin/index-pack.c b/builtin/index-pack.c index bad57488079c..27d1ebba746e 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -15,10 +15,13 @@ #include "packfile.h" #include "object-store.h" #include "promisor-remote.h" +#include "sigchain.h" static const char index_pack_usage[] = "git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--[no-]rev-index] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])"; +static const char *tmp_pack_name; + struct object_entry { struct pack_idx_entry idx; unsigned long size; @@ -336,6 +339,7 @@ static const char *open_pack_file(const char *pack_name) output_fd = odb_mkstemp(&tmp_file, "pack/tmp_pack_XXXXXX"); pack_name = strbuf_detach(&tmp_file, NULL); + tmp_pack_name = pack_name; } else { output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600); if (output_fd < 0) @@ -353,6 +357,19 @@ static const char *open_pack_file(const char *pack_name) return pack_name; } +static void remove_tmp_pack(void) +{ + if (tmp_pack_name) + unlink_or_warn(tmp_pack_name); +} + +static void remove_tmp_pack_on_signal(int signo) +{ + remove_tmp_pack(); + sigchain_pop(signo); + raise(signo); +} + static void parse_pack_header(void) { struct pack_header *hdr = fill(sizeof(struct pack_header)); @@ -1911,6 +1928,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) } curr_pack = open_pack_file(pack_name); + sigchain_push_common(remove_tmp_pack_on_signal); parse_pack_header(); objects = xcalloc(st_add(nr_objects, 1), sizeof(struct object_entry)); if (show_stat) diff --git a/fetch-pack.c b/fetch-pack.c index 6a61a464283e..bedbf69710f6 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -40,6 +40,7 @@ static struct shallow_lock shallow_lock; static const char *alternate_shallow_file; static struct strbuf fsck_msg_types = STRBUF_INIT; static struct string_list uri_protocols = STRING_LIST_INIT_DUP; +static pid_t *curr_index_pack_pid; /* Remember to update object flag allocation in object.h */ #define COMPLETE (1U << 0) @@ -944,6 +945,7 @@ static int get_pack(struct fetch_pack_args *args, cmd.git_cmd = 1; if (start_command(&cmd)) die(_("fetch-pack: unable to fork off %s"), cmd_name); + *curr_index_pack_pid = cmd.pid; if (do_keep && (pack_lockfiles || fsck_objects)) { int is_well_formed; char *pack_lockfile = index_pack_lockfile(cmd.out, &is_well_formed); @@ -1945,12 +1947,13 @@ struct ref *fetch_pack(struct fetch_pack_args *args, struct ref **sought, int nr_sought, struct oid_array *shallow, struct string_list *pack_lockfiles, - enum protocol_version version) + enum protocol_version version, + pid_t *index_pack_pid) { struct ref *ref_cpy; struct shallow_info si; struct oid_array shallows_scratch = OID_ARRAY_INIT; - + curr_index_pack_pid = index_pack_pid; fetch_pack_setup(); if (nr_sought) nr_sought = remove_duplicates_in_refs(sought, nr_sought); diff --git a/fetch-pack.h b/fetch-pack.h index 736a3dae467a..c05a2544bb06 100644 --- a/fetch-pack.h +++ b/fetch-pack.h @@ -78,7 +78,8 @@ struct ref *fetch_pack(struct fetch_pack_args *args, int nr_sought, struct oid_array *shallow, struct string_list *pack_lockfiles, - enum protocol_version version); + enum protocol_version version, + pid_t *index_pack_pid); /* * Print an appropriate error message for each sought ref that wasn't diff --git a/transport.c b/transport.c index b13fab5dc3b1..b18f62e6bd23 100644 --- a/transport.c +++ b/transport.c @@ -391,7 +391,7 @@ static int fetch_refs_via_pack(struct transport *transport, refs = fetch_pack(&args, data->fd, refs_tmp ? refs_tmp : transport->remote_refs, to_fetch, nr_heads, &data->shallow, - &transport->pack_lockfiles, data->version); + &transport->pack_lockfiles, data->version, &transport->index_pack_pid); close(data->fd[0]); close(data->fd[1]); @@ -1095,6 +1095,7 @@ struct transport *transport_get(struct remote *remote, const char *url) } ret->hash_algo = &hash_algos[GIT_HASH_SHA1]; + ret->index_pack_pid = -1; return ret; } diff --git a/transport.h b/transport.h index 24e15799e714..d25d76125784 100644 --- a/transport.h +++ b/transport.h @@ -118,6 +118,12 @@ struct transport { enum transport_family family; const struct git_hash_algo *hash_algo; + + /* + * Record the pid of the index_pack sub-process + * used to send the signal to this sub-process after the main fetch process receives the signal + */ + pid_t index_pack_pid; }; #define TRANSPORT_PUSH_ALL (1<<0) base-commit: 13d7ab6b5d7929825b626f050b62a11241ea4945 -- gitgitgadget