db: prepare database reading for layers

cute-signatures
Timo Teräs 2022-02-01 19:44:36 +02:00
parent be4ce40797
commit 9e4dd29f54
4 changed files with 58 additions and 25 deletions

View File

@ -115,6 +115,10 @@ struct apk_repository {
apk_blob_t description; apk_blob_t description;
}; };
#define APK_DB_LAYER_ROOT 0
#define APK_DB_LAYER_UVOL 1
#define APK_DB_LAYER_NUM 2
#define APK_REPOSITORY_CACHED 0 #define APK_REPOSITORY_CACHED 0
#define APK_REPOSITORY_FIRST_CONFIGURED 1 #define APK_REPOSITORY_FIRST_CONFIGURED 1
@ -138,6 +142,7 @@ struct apk_database {
unsigned int repo_update_errors, repo_update_counter; unsigned int repo_update_errors, repo_update_counter;
unsigned int pending_triggers; unsigned int pending_triggers;
unsigned int extract_flags; unsigned int extract_flags;
unsigned int active_layers;
int performing_self_upgrade : 1; int performing_self_upgrade : 1;
int permanent : 1; int permanent : 1;
int autoupdate : 1; int autoupdate : 1;
@ -189,6 +194,7 @@ struct apk_db_dir *apk_db_dir_query(struct apk_database *db, apk_blob_t name);
struct apk_db_file *apk_db_file_query(struct apk_database *db, struct apk_db_file *apk_db_file_query(struct apk_database *db,
apk_blob_t dir, apk_blob_t name); apk_blob_t dir, apk_blob_t name);
const char *apk_db_layer_name(int layer);
void apk_db_init(struct apk_database *db); void apk_db_init(struct apk_database *db);
int apk_db_open(struct apk_database *db, struct apk_ctx *ctx); int apk_db_open(struct apk_database *db, struct apk_ctx *ctx);
void apk_db_close(struct apk_database *db); void apk_db_close(struct apk_database *db);

View File

@ -93,6 +93,7 @@ struct apk_package {
unsigned marked : 1; unsigned marked : 1;
unsigned uninstallable : 1; unsigned uninstallable : 1;
unsigned cached_non_repository : 1; unsigned cached_non_repository : 1;
unsigned layer : 4;
struct apk_checksum csum; struct apk_checksum csum;
}; };
APK_ARRAY(apk_package_array, struct apk_package *); APK_ARRAY(apk_package_array, struct apk_package *);

View File

@ -13,8 +13,6 @@
#include "apk_version.h" #include "apk_version.h"
#include "apk_print.h" #include "apk_print.h"
extern const char * const apk_installed_file;
static void print_policy(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) static void print_policy(struct apk_database *db, const char *match, struct apk_name *name, void *ctx)
{ {
struct apk_out *out = &db->ctx->out; struct apk_out *out = &db->ctx->out;
@ -44,8 +42,8 @@ zlib1g policy:
if (num++ == 0) if (num++ == 0)
apk_out(out, "%s policy:", name->name); apk_out(out, "%s policy:", name->name);
apk_out(out, " " BLOB_FMT ":", BLOB_PRINTF(*p->version)); apk_out(out, " " BLOB_FMT ":", BLOB_PRINTF(*p->version));
if (p->pkg->ipkg != NULL) if (p->pkg->ipkg)
apk_out(out, " %s", apk_installed_file); apk_out(out, " %s/installed", apk_db_layer_name(p->pkg->layer));
for (i = 0; i < db->num_repos; i++) { for (i = 0; i < db->num_repos; i++) {
repo = &db->repos[i]; repo = &db->repos[i];
if (!(BIT(i) & p->pkg->repos)) if (!(BIT(i) & p->pkg->repos))

View File

@ -56,9 +56,6 @@ static const char * const apk_static_cache_dir = "var/cache/apk";
static const char * const apk_world_file = "etc/apk/world"; static const char * const apk_world_file = "etc/apk/world";
static const char * const apk_arch_file = "etc/apk/arch"; static const char * const apk_arch_file = "etc/apk/arch";
static const char * const apk_lock_file = "lib/apk/db/lock"; static const char * const apk_lock_file = "lib/apk/db/lock";
static const char * const apk_scripts_file = "lib/apk/db/scripts.tar";
static const char * const apk_triggers_file = "lib/apk/db/triggers";
const char * const apk_installed_file = "lib/apk/db/installed";
static struct apk_db_acl *apk_default_acl_dir, *apk_default_acl_file; static struct apk_db_acl *apk_default_acl_dir, *apk_default_acl_file;
@ -759,7 +756,7 @@ err:
return apk_istream_close(is); return apk_istream_close(is);
} }
int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo) static int apk_db_fdb_read(struct apk_database *db, struct apk_istream *is, int repo, unsigned layer)
{ {
struct apk_out *out = &db->ctx->out; struct apk_out *out = &db->ctx->out;
struct apk_package *pkg = NULL; struct apk_package *pkg = NULL;
@ -812,6 +809,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo)
/* If no package, create new */ /* If no package, create new */
if (pkg == NULL) { if (pkg == NULL) {
pkg = apk_pkg_new(); pkg = apk_pkg_new();
pkg->layer = layer;
ipkg = NULL; ipkg = NULL;
diri = NULL; diri = NULL;
file_diri_node = NULL; file_diri_node = NULL;
@ -911,6 +909,11 @@ err_fmt:
return apk_istream_close(is); return apk_istream_close(is);
} }
int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo)
{
return apk_db_fdb_read(db, is, repo, 0);
}
static void apk_blob_push_db_acl(apk_blob_t *b, char field, struct apk_db_acl *acl) static void apk_blob_push_db_acl(apk_blob_t *b, char field, struct apk_db_acl *acl)
{ {
char hdr[2] = { field, ':' }; char hdr[2] = { field, ':' };
@ -1171,21 +1174,29 @@ static int apk_db_triggers_read(struct apk_database *db, struct apk_istream *is)
return apk_istream_close(is); return apk_istream_close(is);
} }
static int apk_db_read_state(struct apk_database *db, int flags) static int apk_db_read_layer(struct apk_database *db, unsigned layer)
{ {
apk_blob_t blob, world; apk_blob_t blob, world;
int r, ret = 0; int r, fd, ret = 0, flags = db->ctx->open_flags;
/* Read: /* Read:
* 1. /etc/apk/world * 1. world
* 2. installed packages db * 2. installed packages db
* 3. triggers db * 3. triggers db
* 4. scripts db * 4. scripts db
*/ */
fd = openat(db->root_fd, apk_db_layer_name(layer), O_RDONLY | O_CLOEXEC);
if (fd < 0) return -errno;
if (!(flags & APK_OPENF_NO_WORLD)) { if (!(flags & APK_OPENF_NO_WORLD)) {
blob = world = apk_blob_from_file(db->root_fd, apk_world_file); if (layer == APK_DB_LAYER_ROOT)
if (!APK_BLOB_IS_NULL(blob)) { world = apk_blob_from_file(db->root_fd, apk_world_file);
blob = apk_blob_trim(blob); else
world = apk_blob_from_file(fd, "world");
if (!APK_BLOB_IS_NULL(world)) {
blob = apk_blob_trim(world);
apk_blob_pull_deps(&blob, db, &db->world); apk_blob_pull_deps(&blob, db, &db->world);
free(world.ptr); free(world.ptr);
} else { } else {
@ -1194,18 +1205,19 @@ static int apk_db_read_state(struct apk_database *db, int flags)
} }
if (!(flags & APK_OPENF_NO_INSTALLED)) { if (!(flags & APK_OPENF_NO_INSTALLED)) {
r = apk_db_index_read(db, apk_istream_from_file(db->root_fd, apk_installed_file), -1); r = apk_db_fdb_read(db, apk_istream_from_file(fd, "installed"), -1, layer);
if (r && r != -ENOENT) ret = r; if (!ret && r != -ENOENT) ret = r;
r = apk_db_triggers_read(db, apk_istream_from_file(db->root_fd, apk_triggers_file)); r = apk_db_triggers_read(db, apk_istream_from_file(fd, "triggers"));
if (r && r != -ENOENT) ret = r; if (!ret && r != -ENOENT) ret = r;
} }
if (!(flags & APK_OPENF_NO_SCRIPTS)) { if (!(flags & APK_OPENF_NO_SCRIPTS)) {
r = apk_tar_parse(apk_istream_from_file(db->root_fd, apk_scripts_file), r = apk_tar_parse(apk_istream_from_file(fd, "scripts.tar"),
apk_read_script_archive_entry, db, db->id_cache); apk_read_script_archive_entry, db, db->id_cache);
if (r && r != -ENOENT) ret = r; if (!ret && r != -ENOENT) ret = r;
} }
close(fd);
return ret; return ret;
} }
@ -1616,6 +1628,17 @@ static void unmount_proc(struct apk_database *db)
} }
#endif #endif
const char *apk_db_layer_name(int layer)
{
switch (layer) {
case APK_DB_LAYER_ROOT: return "lib/apk/db";
case APK_DB_LAYER_UVOL: return "lib/apk/db-uvol";
default:
assert("invalid layer");
return 0;
}
}
void apk_db_init(struct apk_database *db) void apk_db_init(struct apk_database *db)
{ {
memset(db, 0, sizeof(*db)); memset(db, 0, sizeof(*db));
@ -1637,7 +1660,7 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac)
struct apk_out *out = &ac->out; struct apk_out *out = &ac->out;
const char *msg = NULL; const char *msg = NULL;
apk_blob_t blob; apk_blob_t blob;
int r; int r, i;
apk_default_acl_dir = apk_db_acl_atomize(db, 0755, 0, 0); apk_default_acl_dir = apk_db_acl_atomize(db, 0755, 0, 0);
apk_default_acl_file = apk_db_acl_atomize(db, 0644, 0, 0); apk_default_acl_file = apk_db_acl_atomize(db, 0644, 0, 0);
@ -1721,10 +1744,15 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac)
apk_db_read_overlay(db, apk_istream_from_fd(STDIN_FILENO)); apk_db_read_overlay(db, apk_istream_from_fd(STDIN_FILENO));
} }
r = apk_db_read_state(db, ac->open_flags); for (i = 0; i < APK_DB_LAYER_NUM; i++) {
if (r != 0 && !(r == -ENOENT && (ac->open_flags & APK_OPENF_CREATE))) { r = apk_db_read_layer(db, i);
msg = "Unable to read database state"; if (r) {
goto ret_r; if (i != 0) continue;
if (r == -ENOENT && (ac->open_flags & APK_OPENF_CREATE)) continue;
msg = "Unable to read database";
goto ret_r;
}
db->active_layers |= BIT(i);
} }
if (!(ac->open_flags & APK_OPENF_NO_INSTALLED_REPO)) { if (!(ac->open_flags & APK_OPENF_NO_INSTALLED_REPO)) {