Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Allow to mmap packagesite.yaml
Baptiste Daroussin committed 12 years ago
commit 9071abf125bc5ef6d2f62a112bfa730472935087
parent 2de4c0a
3 files changed +46 -11
modified libpkg/pkg.h.in
@@ -801,6 +801,7 @@ int pkg_delannotation(struct pkg *pkg, const char *tag);
 * @return An error code.
 */
int pkg_parse_manifest(struct pkg *pkg, char *buf, struct pkg_manifest_key *key);
+
int pkg_parse_manifest_ev(struct pkg *pkg, char *buf, size_t len, struct pkg_manifest_parser *p);
int pkg_parse_manifest_file(struct pkg *pkg, FILE *f, struct pkg_manifest_key *key);
int pkg_parse_manifest_file_ev(struct pkg *pkg, FILE *f, struct pkg_manifest_parser *p);
int pkg_load_manifest_file(struct pkg *pkg, const char *fpath, struct pkg_manifest_key *key);
modified libpkg/pkg_manifest.c
@@ -207,7 +207,6 @@ pkg_manifest_parser_new(struct pkg_manifest_parser **p)

	if (*p != NULL) {
		yaml_parser_delete(&(*p)->parser);
-
		yaml_event_delete(&(*p)->event);
		yaml_parser_initialize(&(*p)->parser);
		return (EPKG_OK);
	}
@@ -1302,6 +1301,22 @@ pkg_parse_manifest_archive(struct pkg *pkg, struct archive *a, struct pkg_manife
}

int
+
pkg_parse_manifest_ev(struct pkg *pkg, char *buf, size_t len, struct pkg_manifest_parser *p)
+
{
+
	int rc;
+

+
	assert(pkg != NULL);
+
	assert(buf != NULL);
+
	assert(p != NULL);
+

+
	yaml_parser_set_input_string(&p->parser, buf, len);
+

+
	rc = scan_manifest(pkg, p);
+

+
	return (rc);
+
}
+

+
int
pkg_parse_manifest(struct pkg *pkg, char *buf, struct pkg_manifest_key *keys)
{
	yaml_parser_t parser;
modified libpkg/update.c
@@ -26,6 +26,7 @@

#include <sys/stat.h>
#include <sys/param.h>
+
#include <sys/mman.h>

#define _WITH_GETLINE
#include <stdio.h>
@@ -33,6 +34,7 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
+
#include <limits.h>

#include <archive.h>
#include <archive_entry.h>
@@ -365,7 +367,7 @@ pkg_update_full(const char *repofile, struct pkg_repo *repo, time_t *mtime)
}

static int
-
pkg_add_from_manifest(FILE *f, const char *origin, long offset,
+
pkg_add_from_manifest(FILE *f, char *buf, const char *origin, long offset,
		const char *manifest_digest, const char *local_arch, sqlite3 *sqlite,
		struct pkg_manifest_parser **parser, struct pkg **p)
{
@@ -373,7 +375,7 @@ pkg_add_from_manifest(FILE *f, const char *origin, long offset,
	struct pkg *pkg;
	const char *local_origin, *pkg_arch;

-
	if (fseek(f, offset, SEEK_SET) == -1) {
+
	if (buf == NULL && fseek(f, offset, SEEK_SET) == -1) {
		pkg_emit_errno("fseek", "invalid manifest offset");
		return (EPKG_FATAL);
	}
@@ -389,7 +391,11 @@ pkg_add_from_manifest(FILE *f, const char *origin, long offset,
	pkg = *p;

	pkg_manifest_parser_new(parser);
-
	rc = pkg_parse_manifest_file_ev(pkg, f, *parser);
+
	if (buf == NULL) {
+
		rc = pkg_parse_manifest_file_ev(pkg, f, *parser);
+
	} else {
+
		rc = pkg_parse_manifest_ev(pkg, buf, offset, *parser);
+
	}
	if (rc != EPKG_OK) {
		goto cleanup;
	}
@@ -458,10 +464,11 @@ pkg_update_incremental(const char *name, struct pkg_repo *repo, time_t *mtime)
	struct pkg_increment_task_item *ldel = NULL, *ladd = NULL,
			*item, *tmp_item;
	const char *myarch;
-
	struct pkg_manifest_key *keys = NULL;
	struct pkg_manifest_parser *parser = NULL;
	size_t linecap = 0;
	ssize_t linelen;
+
	char *map = MAP_FAILED;
+
	size_t len = 0;

	pkg_debug(1, "Pkgrepo, begin incremental update of '%s'", name);
	if ((rc = pkgdb_repo_open(name, false, &sqlite, false)) != EPKG_OK) {
@@ -497,8 +504,8 @@ pkg_update_incremental(const char *name, struct pkg_repo *repo, time_t *mtime)
	if (fmanifest == NULL)
		goto cleanup;
	*mtime = local_t;
-

-
	pkg_manifest_keys_new(&keys);
+
	fseek(fmanifest, 0, SEEK_END);
+
	len = ftell(fmanifest);

	pkg_debug(1, "Pkgrepo, reading new packagesite.yaml for '%s'", name);
	/* load the while digests */
@@ -554,10 +561,21 @@ pkg_update_incremental(const char *name, struct pkg_repo *repo, time_t *mtime)

	pkg_debug(1, "Pkgrepo, pushing new entries for '%s'", name);
	pkg = NULL;
+

+
	if (len > 0 && len < SSIZE_MAX) {
+
		map = mmap(NULL, len, PROT_READ, MAP_SHARED, fileno(fmanifest), 0);
+
		fclose(fmanifest);
+
	}
+

	HASH_ITER(hh, ladd, item, tmp_item) {
		if (rc == EPKG_OK) {
-
			rc = pkg_add_from_manifest(fmanifest, item->origin,
-
			        item->offset, item->digest, myarch, sqlite, &parser, &pkg);
+
			if (map != MAP_FAILED) {
+
				rc = pkg_add_from_manifest(NULL, map + item->offset, item->origin,
+
				    len - item->offset, item->digest, myarch, sqlite, &parser, &pkg);
+
			} else {
+
				rc = pkg_add_from_manifest(fmanifest, NULL, item->origin,
+
				    item->offset, item->digest, myarch, sqlite, &parser, &pkg);
+
			}
		}
		free(item->origin);
		free(item->digest);
@@ -574,11 +592,12 @@ cleanup:
		pkgdb_it_free(it);
	if (pkgdb_repo_close(sqlite, rc == EPKG_OK) != EPKG_OK)
		rc = EPKG_FATAL;
-
	if (fmanifest)
+
	if (map == MAP_FAILED && fmanifest)
		fclose(fmanifest);
	if (fdigests)
		fclose(fdigests);
-
	pkg_manifest_keys_free(keys);
+
	if (map != MAP_FAILED)
+
		munmap(map, len);

	return (rc);
}