db: prepare database writing for layers
parent
9e4dd29f54
commit
9089edcc44
125
src/database.c
125
src/database.c
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue