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;
};
#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_FIRST_CONFIGURED 1
@ -138,6 +142,7 @@ struct apk_database {
unsigned int repo_update_errors, repo_update_counter;
unsigned int pending_triggers;
unsigned int extract_flags;
unsigned int active_layers;
int performing_self_upgrade : 1;
int permanent : 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,
apk_blob_t dir, apk_blob_t name);
const char *apk_db_layer_name(int layer);
void apk_db_init(struct apk_database *db);
int apk_db_open(struct apk_database *db, struct apk_ctx *ctx);
void apk_db_close(struct apk_database *db);

View File

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

View File

@ -13,8 +13,6 @@
#include "apk_version.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)
{
struct apk_out *out = &db->ctx->out;
@ -44,8 +42,8 @@ zlib1g policy:
if (num++ == 0)
apk_out(out, "%s policy:", name->name);
apk_out(out, " " BLOB_FMT ":", BLOB_PRINTF(*p->version));
if (p->pkg->ipkg != NULL)
apk_out(out, " %s", apk_installed_file);
if (p->pkg->ipkg)
apk_out(out, " %s/installed", apk_db_layer_name(p->pkg->layer));
for (i = 0; i < db->num_repos; i++) {
repo = &db->repos[i];
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_arch_file = "etc/apk/arch";
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;
@ -759,7 +756,7 @@ err:
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_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 (pkg == NULL) {
pkg = apk_pkg_new();
pkg->layer = layer;
ipkg = NULL;
diri = NULL;
file_diri_node = NULL;
@ -911,6 +909,11 @@ err_fmt:
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)
{
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);
}
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;
int r, ret = 0;
int r, fd, ret = 0, flags = db->ctx->open_flags;
/* Read:
* 1. /etc/apk/world
* 1. world
* 2. installed packages db
* 3. triggers 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)) {
blob = world = apk_blob_from_file(db->root_fd, apk_world_file);
if (!APK_BLOB_IS_NULL(blob)) {
blob = apk_blob_trim(blob);
if (layer == APK_DB_LAYER_ROOT)
world = apk_blob_from_file(db->root_fd, apk_world_file);
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);
free(world.ptr);
} else {
@ -1194,18 +1205,19 @@ static int apk_db_read_state(struct apk_database *db, int flags)
}
if (!(flags & APK_OPENF_NO_INSTALLED)) {
r = apk_db_index_read(db, apk_istream_from_file(db->root_fd, apk_installed_file), -1);
if (r && r != -ENOENT) ret = r;
r = apk_db_triggers_read(db, apk_istream_from_file(db->root_fd, apk_triggers_file));
if (r && r != -ENOENT) ret = r;
r = apk_db_fdb_read(db, apk_istream_from_file(fd, "installed"), -1, layer);
if (!ret && r != -ENOENT) ret = r;
r = apk_db_triggers_read(db, apk_istream_from_file(fd, "triggers"));
if (!ret && r != -ENOENT) ret = r;
}
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);
if (r && r != -ENOENT) ret = r;
if (!ret && r != -ENOENT) ret = r;
}
close(fd);
return ret;
}
@ -1616,6 +1628,17 @@ static void unmount_proc(struct apk_database *db)
}
#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)
{
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;
const char *msg = NULL;
apk_blob_t blob;
int r;
int r, i;
apk_default_acl_dir = apk_db_acl_atomize(db, 0755, 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));
}
r = apk_db_read_state(db, ac->open_flags);
if (r != 0 && !(r == -ENOENT && (ac->open_flags & APK_OPENF_CREATE))) {
msg = "Unable to read database state";
goto ret_r;
for (i = 0; i < APK_DB_LAYER_NUM; i++) {
r = apk_db_read_layer(db, i);
if (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)) {