Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
repos: move lock and meta under "/var/db/repos/<name>"
Baptiste Daroussin committed 2 years ago
commit 76e201ac618cb63de43d6d659e2563b2e1e19247
parent 647e10a
5 files changed +83 -45
modified libpkg/pkg_config.c
@@ -73,6 +73,7 @@ struct pkg_ctx ctx = {
	.rootfd = -1,
	.cachedirfd = -1,
	.pkg_dbdirfd = -1,
+
	.pkg_reposdirfd = -1,
	.devnullfd = -1,
	.osversion = 0,
	.backup_libraries = false,
@@ -1452,6 +1453,7 @@ pkg_repo_new(const char *name, const char *url, const char *type)
	struct pkg_repo *r;

	r = xcalloc(1, sizeof(struct pkg_repo));
+
	r->dfd = -1;
	r->ops = pkg_repo_find_type(type);
	r->url = xstrdup(url);
	r->signature_type = SIG_NONE;
@@ -1713,8 +1715,9 @@ pkg_get_reposdirfd(void)
	if (ctx.pkg_reposdirfd == -1) {
		ctx.pkg_reposdirfd = openat(dbfd, "repos", O_DIRECTORY|O_CLOEXEC);
		if (ctx.pkg_reposdirfd == -1) {
-
			if (mkdirat(dbfd, "repos", 0755) == -1)
+
			if (mkdirat(dbfd, "repos", 0755) == -1) {
				return (-1);
+
			}
			ctx.pkg_reposdirfd = openat(dbfd, "repos", O_DIRECTORY|O_CLOEXEC);
		}
	}
modified libpkg/pkg_repo.c
@@ -844,6 +844,25 @@ pkg_repo_meta_extract_pubkey(int fd, void *ud)
}

int
+
pkg_repo_open(struct pkg_repo *repo)
+
{
+
	if (repo->dfd != -1)
+
		return (EPKG_OK);
+
	int reposfd = pkg_get_reposdirfd();
+
	if (reposfd == -1)
+
		return (EPKG_FATAL);
+
	repo->dfd = openat(reposfd, repo->name, O_DIRECTORY|O_CLOEXEC);
+
	if (repo->dfd == -1) {
+
		if (mkdirat(reposfd, repo->name, 0755) == -1)
+
			return (EPKG_FATAL);
+
		repo->dfd = openat(reposfd, repo->name, O_DIRECTORY|O_CLOEXEC);
+
	}
+
	if (repo->dfd == -1)
+
		return (EPKG_FATAL);
+
	return (EPKG_OK);
+
}
+

+
int
pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
{
	char filepath[MAXPATHLEN];
@@ -859,12 +878,15 @@ pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
	pkghash_it it;

	dbdirfd = pkg_get_dbdirfd();
-
	snprintf(filepath, sizeof(filepath), "%s.meta", pkg_repo_name(repo));
+
	if (repo->dfd == -1) {
+
		if (pkg_repo_open(repo) == EPKG_FATAL)
+
			return (EPKG_FATAL);
+
	}
	fd = pkg_repo_fetch_remote_tmp(repo, "meta", "conf", t, &rc, true);
	if (fd != -1) {
		newscheme = true;
		metafd = fd;
-
		fd = openat(dbdirfd, filepath, O_RDWR|O_CREAT|O_TRUNC, 0644);
+
		fd = openat(repo->dfd, "meta", O_RDWR|O_CREAT|O_TRUNC, 0644);
		if (fd == -1) {
			close(metafd);
			return (EPKG_FATAL);
@@ -879,7 +901,7 @@ pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
	if (fd == -1)
		return (rc);

-
	metafd = openat(dbdirfd, filepath, O_RDWR|O_CREAT|O_TRUNC, 0644);
+
	metafd = openat(repo->dfd, "meta", O_RDWR|O_CREAT|O_TRUNC, 0644);
	if (metafd == -1) {
		close(fd);
		return (EPKG_FATAL);
@@ -915,7 +937,7 @@ pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
	}

	/* Map meta file for extracting pubkeys from it */
-
	if ((metafd = openat(dbdirfd, filepath, O_RDONLY)) == -1) {
+
	if ((metafd = openat(repo->dfd, "meta", O_RDONLY)) == -1) {
		pkg_emit_errno("pkg_repo_fetch_meta", "cannot open meta fetched");
		rc = EPKG_FATAL;
		goto cleanup;
modified libpkg/private/pkg.h
@@ -556,6 +556,7 @@ struct pkg_repo {

	ip_version_t ip;
	kvlist_t env;
+
	int dfd;

	/* Opaque repository data */
	void *priv;
@@ -645,6 +646,7 @@ int pkg_delete(struct pkg *pkg, struct pkg *rpkg, struct pkgdb *db, int flags,

int pkg_fetch_file_to_fd(struct pkg_repo *repo, int dest, struct fetch_item *,
    bool silent);
+
int pkg_repo_open(struct pkg_repo *repo);
int pkg_repo_fetch_package(struct pkg *pkg);
int pkg_repo_mirror_package(struct pkg *pkg, const char *destdir);
int pkg_repo_fetch_remote_extract_fd(struct pkg_repo *repo, struct pkg_repo_content *);
modified libpkg/repo/binary/init.c
@@ -1,13 +1,14 @@
-
/* Copyright (c) 2014, Vsevolod Stakhov
-
 * All rights reserved.
+
/* 
+
 * Copyright (c) 2014, Vsevolod Stakhov
+
 * Copyright (c) 2024, Baptiste Daroussin
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
-
 *       * Redistributions of source code must retain the above copyright
-
 *         notice, this list of conditions and the following disclaimer.
-
 *       * Redistributions in binary form must reproduce the above copyright
-
 *         notice, this list of conditions and the following disclaimer in the
-
 *         documentation and/or other materials provided with the distribution.
+
 *  * Redistributions of source code must retain the above copyright
+
 *    notice, this list of conditions and the following disclaimer.
+
 *  * Redistributions in binary form must reproduce the above copyright
+
 *    notice, this list of conditions and the following disclaimer in the
+
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -301,7 +302,7 @@ pkg_repo_binary_open(struct pkg_repo *repo, unsigned mode)
{
	char filepath[MAXPATHLEN];
	sqlite3 *sqlite = NULL;
-
	int flags, dbdirfd, fd;
+
	int flags, dbdirfd, fd, reposfd, thisrepofd;
	int64_t res;
	struct pkg_repo_it *it;
	struct pkg *pkg = NULL;
@@ -311,13 +312,19 @@ pkg_repo_binary_open(struct pkg_repo *repo, unsigned mode)
	pkgdb_syscall_overload();

	dbdirfd = pkg_get_dbdirfd();
-
	snprintf(filepath, sizeof(filepath), "%s.meta", pkg_repo_name(repo));
+
	reposfd = pkg_get_reposdirfd();
+
	thisrepofd = openat(reposfd, repo->name, O_DIRECTORY|O_CLOEXEC);
+
	if (thisrepofd == -1) {
+
		if (mkdirat(reposfd, repo->name, 0755) == -1)
+
			return( EPKG_FATAL);
+
		thisrepofd = openat(reposfd, repo->name, O_DIRECTORY|O_CLOEXEC);
+
	}

	/* Open metafile */
-
	if ((fd = openat(dbdirfd, filepath, O_RDONLY)) != -1) {
+
	if ((fd = openat(thisrepofd, "meta", O_RDONLY)) != -1) {
		if (pkg_repo_meta_load(fd, &repo->meta) != EPKG_OK) {
			pkg_emit_error("Repository %s load error: "
-
			    "meta file cannot be loaded", pkg_repo_name(repo));
+
			    "meta file cannot be loaded", repo->name);
			close(fd);
			return (EPKG_FATAL);
		}
modified libpkg/repo/binary/update.c
@@ -1,6 +1,6 @@
/*
 * Copyright (c) 2014, Vsevolod Stakhov
-
 * Copyright (c) 2012-2014 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2012-2024 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * All rights reserved.
 *
@@ -497,6 +497,22 @@ rollback_repo(void *data)
	unlink(path);
}

+
static void
+
save_groups(struct pkg_repo *repo, ucl_object_t *groups)
+
{
+
	if (groups == NULL)
+
		return;
+
	if (repo->dfd == -1 && pkg_repo_open(repo) == EPKG_FATAL)
+
		return;
+
	int fd = openat(repo->dfd, "groups.ucl", O_CREAT|O_TRUNC|O_RDWR, 0644);
+
	if (fd == -1) {
+
		pkg_emit_errno("openat", "repo groups");
+
		return;
+
	}
+
	ucl_object_emit_fd(groups, UCL_EMIT_JSON_COMPACT, fd);
+
	close(fd);
+
}
+

static int
pkg_repo_binary_update_proceed(const char *name, struct pkg_repo *repo,
	time_t *mtime, bool force)
@@ -619,20 +635,8 @@ pkg_repo_binary_update_proceed(const char *name, struct pkg_repo *repo,
				break;
		}
		pkg_emit_progress_tick(nbel, cnt);
-
		ucl_object_t *groups = ucl_object_ref(ucl_object_find_key(data, "groups"));
-
		if (groups != NULL) {
-
			int fd = openat(pkg_get_dbdirfd(),
-
			    pkg_repo_binary_get_groups_filename(repo->name),
-
			    O_CREAT|O_TRUNC|O_RDWR, 0644);
-
			if (fd != -1) {
-
				ucl_object_emit_fd(groups, UCL_EMIT_JSON_COMPACT, fd);
-
				close(fd);
-
			} else {
-
				pkg_emit_errno("openat",
-
				    pkg_repo_binary_get_groups_filename(repo->name));
-
			}
-

-
		}
+
		save_groups(repo,
+
		    ucl_object_ref(ucl_object_find_key(data, "groups")));
	}

	if (rc == EPKG_OK)
@@ -686,7 +690,7 @@ pkg_repo_binary_update(struct pkg_repo *repo, bool force)

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

	bool got_meta = false;

@@ -700,6 +704,9 @@ pkg_repo_binary_update(struct pkg_repo *repo, bool force)
	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->dfd == -1 && pkg_repo_open(repo) == EPKG_FATAL)
+
		return (EPKG_FATAL);
+

	if (repo->ops->open(repo, R_OK|W_OK) != EPKG_OK) {
		pkg_debug(1, "PkgRepo: need forced update of %s", repo->name);
		t = 0;
@@ -709,8 +716,7 @@ pkg_repo_binary_update(struct pkg_repo *repo, bool force)
	}
	else {
		repo->ops->close(repo, false);
-
		snprintf(filepath, sizeof(filepath), "%s/%s.meta", ctx.dbdir, repo->name);
-
		if (stat(filepath, &st) != -1) {
+
		if (fstatat(repo->dfd, "meta", &st, 0) != -1) {
			t = force ? 0 : st.st_mtime;
			got_meta = true;
		}
@@ -723,9 +729,11 @@ pkg_repo_binary_update(struct pkg_repo *repo, bool force)
		}
	}

-
	xasprintf(&lockpath, "%s-lock", filename);
-
	dfd = pkg_get_dbdirfd();
-
	ld = openat(dfd, lockpath, O_CREAT|O_TRUNC|O_WRONLY, 00644);
+
	ld = openat(repo->dfd, "lock", O_CREAT|O_TRUNC|O_WRONLY, 00644);
+
	if (ld == -1) {
+
		pkg_emit_errno("plop", "plop");
+
		pkg_emit_error("plop, %d\n", repo->dfd);
+
	}
	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 "
@@ -754,10 +762,8 @@ cleanup:
		close(ld);
	}

-
	if (lockpath != NULL) {
-
		unlinkat(dfd, lockpath, 0);
-
		free(lockpath);
-
	}
+
	if (lockpath != NULL)
+
		unlinkat(repo->dfd, "lock", 0);

	/* Set mtime from http request if possible */
	if (t != 0 && res == EPKG_OK) {
@@ -773,10 +779,8 @@ cleanup:
		};

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

	if (repo->priv != NULL)