db: prepare database writing for layers

cute-signatures
Timo Teräs 2022-02-01 17:44:49 +02:00
parent 9e4dd29f54
commit 9089edcc44
1 changed files with 169 additions and 132 deletions

View File

@ -931,10 +931,9 @@ static void apk_blob_push_db_acl(apk_blob_t *b, char field, struct apk_db_acl *a
apk_blob_push_blob(b, APK_BLOB_STR("\n"));
}
static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
static int apk_db_fdb_write(struct apk_database *db, struct apk_installed_package *ipkg, struct apk_ostream *os)
{
struct apk_installed_package *ipkg;
struct apk_package *pkg;
struct apk_package *pkg = ipkg->pkg;
struct apk_db_dir_instance *diri;
struct apk_db_file *file;
struct hlist_node *c1, *c2;
@ -944,8 +943,6 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
if (IS_ERR(os)) return PTR_ERR(os);
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
pkg = ipkg->pkg;
r = apk_pkg_write_index_entry(pkg, os);
if (r < 0) goto err;
@ -1018,17 +1015,14 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
}
}
r = apk_ostream_write(os, "\n", 1);
if (r < 0) goto err;
}
err:
if (r < 0) apk_ostream_cancel(os, r);
return apk_ostream_close(os);
return r;
}
static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os)
static int apk_db_scriptdb_write(struct apk_database *db, struct apk_installed_package *ipkg, struct apk_ostream *os)
{
struct apk_installed_package *ipkg;
struct apk_package *pkg;
struct apk_package *pkg = ipkg->pkg;
struct apk_file_info fi;
char filename[256];
apk_blob_t bfn;
@ -1036,12 +1030,8 @@ static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os
if (IS_ERR(os)) return PTR_ERR(os);
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
pkg = ipkg->pkg;
for (i = 0; i < APK_SCRIPT_MAX; i++) {
if (ipkg->script[i].ptr == NULL)
continue;
if (!ipkg->script[i].ptr) continue;
fi = (struct apk_file_info) {
.name = filename,
@ -1066,10 +1056,8 @@ static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os
break;
}
}
}
apk_tar_write_entry(os, NULL, NULL);
return apk_ostream_close(os);
return r;
}
static int apk_read_script_archive_entry(void *ctx,
@ -1123,16 +1111,15 @@ static int parse_triggers(void *ctx, apk_blob_t blob)
return 0;
}
static int apk_db_triggers_write(struct apk_database *db, struct apk_ostream *os)
static int apk_db_triggers_write(struct apk_database *db, struct apk_installed_package *ipkg, struct apk_ostream *os)
{
struct apk_installed_package *ipkg;
char buf[APK_BLOB_CHECKSUM_BUF];
apk_blob_t bfn;
char **trigger;
if (IS_ERR(os)) return PTR_ERR(os);
if (!ipkg->triggers || ipkg->triggers->num == 0) return 0;
list_for_each_entry(ipkg, &db->installed.triggers, trigger_pkgs_list) {
bfn = APK_BLOB_BUF(buf);
apk_blob_push_csum(&bfn, &ipkg->pkg->csum);
bfn = apk_blob_pushed(APK_BLOB_BUF(buf), bfn);
@ -1143,8 +1130,7 @@ static int apk_db_triggers_write(struct apk_database *db, struct apk_ostream *os
apk_ostream_write_string(os, *trigger);
}
apk_ostream_write(os, "\n", 1);
}
return apk_ostream_close(os);
return 0;
}
static int apk_db_triggers_read(struct apk_database *db, struct apk_istream *is)
@ -1199,7 +1185,7 @@ static int apk_db_read_layer(struct apk_database *db, unsigned layer)
blob = apk_blob_trim(world);
apk_blob_pull_deps(&blob, db, &db->world);
free(world.ptr);
} else {
} else if (layer == APK_DB_LAYER_ROOT) {
ret = -ENOENT;
}
}
@ -1747,11 +1733,12 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac)
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;
if (i != APK_DB_LAYER_ROOT) continue;
if (!(r == -ENOENT && (ac->open_flags & APK_OPENF_CREATE))) {
msg = "Unable to read database";
goto ret_r;
}
}
db->active_layers |= BIT(i);
}
@ -1810,10 +1797,74 @@ struct write_ctx {
int fd;
};
static int apk_db_write_layers(struct apk_database *db)
{
struct layer_data {
int fd;
struct apk_ostream *installed, *scripts, *triggers;
} layers[APK_DB_LAYER_NUM] = {0};
struct apk_installed_package *ipkg;
struct apk_ostream *os;
int i, r, rr = 0;
for (i = 0; i < APK_DB_LAYER_NUM; i++) {
struct layer_data *ld = &layers[i];
if (!(db->active_layers & BIT(i))) continue;
ld->fd = openat(db->root_fd, apk_db_layer_name(i), O_RDONLY | O_CLOEXEC);
if (ld->fd < 0) {
if (i == 0) return -errno;
continue;
}
ld->installed = apk_ostream_to_file(ld->fd, "installed", 0644);
ld->scripts = apk_ostream_to_file(ld->fd, "scripts.tar", 0644);
ld->triggers = apk_ostream_to_file(ld->fd, "triggers", 0644);
}
os = apk_ostream_to_file(db->root_fd, apk_world_file, 0644);
if (!IS_ERR(os)) {
apk_deps_write(db, db->world, os, APK_BLOB_PTR_LEN("\n", 1));
apk_ostream_write(os, "\n", 1);
r = apk_ostream_close(os);
if (!rr) rr = r;
}
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
struct layer_data *ld = &layers[ipkg->pkg->layer];
if (!ld->fd) continue;
apk_db_fdb_write(db, ipkg, ld->installed);
apk_db_scriptdb_write(db, ipkg, ld->scripts);
apk_db_triggers_write(db, ipkg, ld->triggers);
}
for (i = 0; i < APK_DB_LAYER_NUM; i++) {
struct layer_data *ld = &layers[i];
if (!(db->active_layers & BIT(i))) continue;
if (!IS_ERR(ld->installed))
r = apk_ostream_close(ld->installed);
else r = PTR_ERR(ld->installed);
if (!rr) rr = r;
if (!IS_ERR(ld->scripts)) {
apk_tar_write_entry(ld->scripts, NULL, NULL);
r = apk_ostream_close(ld->scripts);
} else r = PTR_ERR(ld->scripts);
if (!rr) rr = r;
if (!IS_ERR(ld->triggers))
r = apk_ostream_close(ld->triggers);
else r = PTR_ERR(ld->triggers);
if (!rr) rr = r;
close(ld->fd);
}
return rr;
}
int apk_db_write_config(struct apk_database *db)
{
struct apk_out *out = &db->ctx->out;
struct apk_ostream *os;
int r, rr = 0;
if ((db->ctx->flags & APK_SIMULATE) || db->ctx->root == NULL)
@ -1837,26 +1888,12 @@ int apk_db_write_config(struct apk_database *db)
if (db->write_arch)
apk_blob_to_file(db->root_fd, apk_arch_file, *db->arch, APK_BTF_ADD_EOL);
os = apk_ostream_to_file(db->root_fd, apk_world_file, 0644);
if (!IS_ERR(os)) {
apk_deps_write(db, db->world, os, APK_BLOB_PTR_LEN("\n", 1));
apk_ostream_write(os, "\n", 1);
r = apk_ostream_close(os);
if (r && !rr) rr = r;
}
r = apk_db_write_fdb(db, apk_ostream_to_file(db->root_fd, apk_installed_file, 0644));
if (r < 0 && !rr) rr = r;
r = apk_db_scriptdb_write(db, apk_ostream_to_file(db->root_fd, apk_scripts_file, 0644));
if (r < 0 && !rr) rr = r;
r = apk_db_write_layers(db);
if (!rr ) rr = r;
r = apk_db_index_write_nr_cache(db);
if (r < 0 && !rr) rr = r;
r = apk_db_triggers_write(db, apk_ostream_to_file(db->root_fd, apk_triggers_file, 0644));
if (r < 0 && !rr) rr = r;
if (rr) {
apk_err(out, "System state may be inconsistent: failed to write database: %s",
apk_error_str(rr));