Skip to content

Commit

Permalink
update: lock globally and sync return of concurrent process
Browse files Browse the repository at this point in the history
PR: #2200
  • Loading branch information
fichtner authored and bapt committed Nov 29, 2023
1 parent fc09e75 commit 69e28e7
Showing 1 changed file with 35 additions and 7 deletions.
42 changes: 35 additions & 7 deletions libpkg/repo/binary/update.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <sys/stat.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/time.h>

#include <stdio.h>
Expand Down Expand Up @@ -584,13 +585,15 @@ int
pkg_repo_binary_update(struct pkg_repo *repo, bool force)
{
char filepath[MAXPATHLEN];
char *lockpath = NULL;
const char update_finish_sql[] = ""
"DROP TABLE repo_update;";
const char *filename;
sqlite3 *sqlite;

struct stat st;
time_t t = 0;
int res = EPKG_FATAL;
int dfd, ld, res = EPKG_FATAL;

bool got_meta = false;

Expand All @@ -599,32 +602,47 @@ pkg_repo_binary_update(struct pkg_repo *repo, bool force)
if (!pkg_repo_enabled(repo))
return (EPKG_OK);

pkg_debug(1, "PkgRepo: verifying update for %s", pkg_repo_name(repo));
pkg_debug(1, "PkgRepo: verifying update for %s", repo->name);

filename = pkg_repo_binary_get_filename(repo->name);

/* First of all, try to open and init repo and check whether it is fine */
if (repo->ops->open(repo, R_OK|W_OK) != EPKG_OK) {
pkg_debug(1, "PkgRepo: need forced update of %s", pkg_repo_name(repo));
pkg_debug(1, "PkgRepo: need forced update of %s", repo->name);
t = 0;
force = true;
snprintf(filepath, sizeof(filepath), "%s/%s", ctx.dbdir,
pkg_repo_binary_get_filename(pkg_repo_name(repo)));
filename);
}
else {
repo->ops->close(repo, false);
snprintf(filepath, sizeof(filepath), "%s/%s.meta", ctx.dbdir, pkg_repo_name(repo));
snprintf(filepath, sizeof(filepath), "%s/%s.meta", ctx.dbdir, repo->name);
if (stat(filepath, &st) != -1) {
t = force ? 0 : st.st_mtime;
got_meta = true;
}

snprintf(filepath, sizeof(filepath), "%s/%s", ctx.dbdir,
pkg_repo_binary_get_filename(pkg_repo_name(repo)));
filename);
if (got_meta && stat(filepath, &st) != -1) {
if (!force)
t = st.st_mtime;
}
}

xasprintf(&lockpath, "%s-lock", filename);
dfd = pkg_get_dbdirfd();
ld = openat(dfd, lockpath, O_CREAT|O_TRUNC|O_WRONLY, 00644);
if (flock(ld, LOCK_EX|LOCK_NB) == -1) {
/* lock blocking anyway to let the other end finish */
pkg_emit_notice("Waiting for another process to "
"update repository %s", repo->name);
flock(ld, LOCK_EX);
res = EPKG_OK;
t = 0;
goto cleanup;
}

res = pkg_repo_binary_update_proceed(filepath, repo, &t, force);
if (res != EPKG_OK && res != EPKG_UPTODATE) {
pkg_emit_notice("Unable to update repository %s", repo->name);
Expand All @@ -638,6 +656,16 @@ pkg_repo_binary_update(struct pkg_repo *repo, bool force)
}

cleanup:
if (ld != -1) {
flock(ld, LOCK_UN);
close(ld);
}

if (lockpath != NULL) {
unlinkat(dfd, lockpath, 0);
free(lockpath);
}

/* Set mtime from http request if possible */
if (t != 0 && res == EPKG_OK) {
struct timeval ftimes[2] = {
Expand All @@ -653,7 +681,7 @@ pkg_repo_binary_update(struct pkg_repo *repo, bool force)

utimes(filepath, ftimes);
if (got_meta) {
snprintf(filepath, sizeof(filepath), "%s/%s.meta", ctx.dbdir, pkg_repo_name(repo));
snprintf(filepath, sizeof(filepath), "%s/%s.meta", ctx.dbdir, repo->name);
utimes(filepath, ftimes);
}
}
Expand Down

0 comments on commit 69e28e7

Please sign in to comment.