Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

maintenance: delete stale lock files, fix loose-objects task #468

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions builtin/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,8 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts)
char *lock_path = xstrfmt("%s/maintenance", r->objects->odb->path);

if (hold_lock_file_for_update(&lk, lock_path, LOCK_NO_DEREF) < 0) {
struct stat st;
struct strbuf lock_dot_lock = STRBUF_INIT;
/*
* Another maintenance command is running.
*
Expand All @@ -1284,6 +1286,25 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts)
if (!opts->auto_flag && !opts->quiet)
warning(_("lock file '%s' exists, skipping maintenance"),
lock_path);

/*
* Check timestamp on .lock file to see if we should
* delete it to recover from a fail state.
*/
strbuf_addstr(&lock_dot_lock, lock_path);
strbuf_addstr(&lock_dot_lock, ".lock");
if (lstat(lock_dot_lock.buf, &st))
warning_errno(_("unable to stat '%s'"), lock_dot_lock.buf);
else {
if (st.st_mtime < time(NULL) - (6 * 60 * 60)) {
if (unlink(lock_dot_lock.buf))
warning_errno(_("unable to delete stale lock file"));
else
warning(_("deleted stale lock file"));
}
}

strbuf_release(&lock_dot_lock);
free(lock_path);
return 0;
}
Expand Down Expand Up @@ -1412,6 +1433,7 @@ static int maintenance_run(int argc, const char **argv, const char *prefix)
{
int i;
struct maintenance_run_opts opts;
const char *tmp_obj_dir = NULL;
struct option builtin_maintenance_run_options[] = {
OPT_BOOL(0, "auto", &opts.auto_flag,
N_("run tasks based on the state of the repository")),
Expand Down Expand Up @@ -1451,9 +1473,11 @@ static int maintenance_run(int argc, const char **argv, const char *prefix)
* the gvfs.sharedcache config option to redirect the
* maintenance to that location.
*/
if (!git_config_get_value("gvfs.sharedcache", &object_dir) &&
object_dir)
if (!git_config_get_value("gvfs.sharedcache", &tmp_obj_dir) &&

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i the the problem here is that git_config_get_value is returning a pointer inside of the buffer used to parse/load the config data (such that the next call to this routine might overwrite the buffer) and we're holding it too long here.

tmp_obj_dir) {
object_dir = xstrdup(tmp_obj_dir);
setenv(DB_ENVIRONMENT, object_dir, 1);
}

return maintenance_run_tasks(&opts);
}
Expand Down
17 changes: 17 additions & 0 deletions t/t7900-maintenance.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,23 @@ test_expect_success 'run [--auto|--quiet]' '
test_subcommand git gc --no-quiet <run-no-quiet.txt
'

test_expect_success 'lock file behavior' '
test_when_finished git config --unset maintenance.commit-graph.schedule &&
git config maintenance.commit-graph.schedule hourly &&

touch .git/objects/maintenance.lock &&
git maintenance run --schedule=hourly --no-quiet 2>err &&
grep "lock file .* exists, skipping maintenance" err &&

test-tool chmtime =-22000 .git/objects/maintenance.lock &&
git maintenance run --schedule=hourly --no-quiet 2>err &&
grep "deleted stale lock file" err &&
test_path_is_missing .git/objects/maintenance.lock &&

git maintenance run --schedule=hourly 2>err &&
test_must_be_empty err
'

test_expect_success 'maintenance.auto config option' '
GIT_TRACE2_EVENT="$(pwd)/default" git commit --quiet --allow-empty -m 1 &&
test_subcommand git maintenance run --auto --quiet <default &&
Expand Down