summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2021-11-15 15:31:56 +0200
committerTimo Teräs <timo.teras@iki.fi>2021-11-15 15:56:48 +0200
commit83b71f0bafeac4b2e7d48cba408014d13a89d614 (patch)
tree6f833347321bf6dce16b0f288cd4fde7a2b23daf /src
parent061bd69b8040d978f22212db5f615f9ce608b678 (diff)
downloadapk-tools-83b71f0bafeac4b2e7d48cba408014d13a89d614.tar.gz
apk-tools-83b71f0bafeac4b2e7d48cba408014d13a89d614.tar.bz2
apk-tools-83b71f0bafeac4b2e7d48cba408014d13a89d614.tar.xz
apk-tools-83b71f0bafeac4b2e7d48cba408014d13a89d614.zip
db: lazy create directories with --initdb
fixes #10778
Diffstat (limited to 'src')
-rw-r--r--src/apk_database.h2
-rw-r--r--src/database.c138
-rw-r--r--src/package.c21
3 files changed, 73 insertions, 88 deletions
diff --git a/src/apk_database.h b/src/apk_database.h
index 587aefb..ff94762 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -141,6 +141,8 @@ struct apk_database {
int performing_self_upgrade : 1;
int permanent : 1;
int autoupdate : 1;
+ int write_arch : 1;
+ int script_dirs_checked : 1;
int open_complete : 1;
int compat_newfeatures : 1;
int compat_notinstallable : 1;
diff --git a/src/database.c b/src/database.c
index 535df5e..4bb23dd 100644
--- a/src/database.c
+++ b/src/database.c
@@ -25,7 +25,6 @@
#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/statvfs.h>
-#include <sys/sysmacros.h>
#include <linux/magic.h>
#include "apk_defines.h"
@@ -1161,7 +1160,7 @@ static int apk_db_triggers_read(struct apk_database *db, struct apk_istream *is)
static int apk_db_read_state(struct apk_database *db, int flags)
{
apk_blob_t blob, world;
- int r;
+ int r, ret = 0;
/* Read:
* 1. /etc/apk/world
@@ -1171,26 +1170,29 @@ static int apk_db_read_state(struct apk_database *db, int flags)
*/
if (!(flags & APK_OPENF_NO_WORLD)) {
blob = world = apk_blob_from_file(db->root_fd, apk_world_file);
- if (APK_BLOB_IS_NULL(blob)) return -ENOENT;
- blob = apk_blob_trim(blob);
- apk_blob_pull_deps(&blob, db, &db->world);
- free(world.ptr);
+ if (!APK_BLOB_IS_NULL(blob)) {
+ blob = apk_blob_trim(blob);
+ apk_blob_pull_deps(&blob, db, &db->world);
+ free(world.ptr);
+ } else {
+ ret = -ENOENT;
+ }
}
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) return r;
+ 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) return r;
+ if (r && r != -ENOENT) ret = r;
}
if (!(flags & APK_OPENF_NO_SCRIPTS)) {
r = apk_tar_parse(apk_istream_from_file(db->root_fd, apk_scripts_file),
apk_read_script_archive_entry, db, db->id_cache);
- if (r && r != -ENOENT) return r;
+ if (r && r != -ENOENT) ret = r;
}
- return 0;
+ return ret;
}
struct index_write_ctx {
@@ -1330,39 +1332,6 @@ static int add_protected_paths_from_file(void *ctx, int dirfd, const char *file)
return 0;
}
-static int apk_db_create(struct apk_database *db)
-{
- int fd;
-
- mkdirat(db->root_fd, "tmp", 01777);
- mkdirat(db->root_fd, "dev", 0755);
- mknodat(db->root_fd, "dev/null", S_IFCHR | 0666, makedev(1, 3));
- mknodat(db->root_fd, "dev/zero", S_IFCHR | 0666, makedev(1, 5));
- mknodat(db->root_fd, "dev/random", S_IFCHR | 0666, makedev(1, 8));
- mknodat(db->root_fd, "dev/urandom", S_IFCHR | 0666, makedev(1, 9));
- mknodat(db->root_fd, "dev/console", S_IFCHR | 0600, makedev(5, 1));
- mkdirat(db->root_fd, "etc", 0755);
- mkdirat(db->root_fd, "etc/apk", 0755);
- mkdirat(db->root_fd, "lib", 0755);
- mkdirat(db->root_fd, "lib/apk", 0755);
- mkdirat(db->root_fd, "lib/apk/db", 0755);
- mkdirat(db->root_fd, "var", 0755);
- mkdirat(db->root_fd, "var/cache", 0755);
- mkdirat(db->root_fd, "var/cache/apk", 0755);
- mkdirat(db->root_fd, "var/cache/misc", 0755);
-
- fd = openat(db->root_fd, apk_world_file, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0644);
- if (fd < 0)
- return -errno;
- close(fd);
- fd = openat(db->root_fd, apk_installed_file, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0644);
- if (fd < 0)
- return -errno;
- close(fd);
-
- return 0;
-}
-
static void handle_alarm(int sig)
{
}
@@ -1531,7 +1500,7 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac)
const char *msg = NULL;
struct statfs stfs;
apk_blob_t blob;
- int r, fd, write_arch = FALSE;
+ int r, fd;
apk_default_acl_dir = apk_db_acl_atomize(db, 0755, 0, 0);
apk_default_acl_file = apk_db_acl_atomize(db, 0644, 0, 0);
@@ -1556,7 +1525,7 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac)
if (ac->root && ac->arch) {
db->arch = apk_atomize(&db->atoms, APK_BLOB_STR(ac->arch));
- write_arch = TRUE;
+ db->write_arch = 1;
} else {
apk_blob_t arch;
arch = apk_blob_from_file(db->root_fd, apk_arch_file);
@@ -1565,48 +1534,37 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac)
free(arch.ptr);
} else {
db->arch = apk_atomize(&db->atoms, APK_BLOB_STR(APK_DEFAULT_ARCH));
- write_arch = TRUE;
+ db->write_arch = 1;
}
}
db->id_cache = apk_ctx_get_id_cache(ac);
if (ac->open_flags & APK_OPENF_WRITE) {
+ msg = "Unable to lock database";
db->lock_fd = openat(db->root_fd, apk_lock_file,
O_CREAT | O_RDWR | O_CLOEXEC, 0600);
- if (db->lock_fd < 0 && errno == ENOENT &&
- (ac->open_flags & APK_OPENF_CREATE)) {
- r = apk_db_create(db);
- if (r != 0) {
- msg = "Unable to create database";
- goto ret_r;
- }
- db->lock_fd = openat(db->root_fd, apk_lock_file,
- O_CREAT | O_RDWR | O_CLOEXEC, 0600);
- }
- if (db->lock_fd < 0 ||
- flock(db->lock_fd, LOCK_EX | LOCK_NB) < 0) {
- msg = "Unable to lock database";
- if (ac->lock_wait) {
- struct sigaction sa, old_sa;
-
- apk_msg(out, "Waiting for repository lock");
- memset(&sa, 0, sizeof sa);
- sa.sa_handler = handle_alarm;
- sa.sa_flags = SA_ONESHOT;
- sigaction(SIGALRM, &sa, &old_sa);
-
- alarm(ac->lock_wait);
- if (flock(db->lock_fd, LOCK_EX) < 0)
- goto ret_errno;
-
- alarm(0);
- sigaction(SIGALRM, &old_sa, NULL);
- } else
+ if (db->lock_fd < 0) {
+ if (!(ac->open_flags & APK_OPENF_CREATE))
goto ret_errno;
+ } else if (flock(db->lock_fd, LOCK_EX | LOCK_NB) < 0) {
+ struct sigaction sa, old_sa;
+
+ if (!ac->lock_wait) goto ret_errno;
+
+ apk_msg(out, "Waiting for repository lock");
+ memset(&sa, 0, sizeof sa);
+ sa.sa_handler = handle_alarm;
+ sa.sa_flags = SA_ONESHOT;
+ sigaction(SIGALRM, &sa, &old_sa);
+
+ alarm(ac->lock_wait);
+ if (flock(db->lock_fd, LOCK_EX) < 0)
+ goto ret_errno;
+
+ alarm(0);
+ sigaction(SIGALRM, &old_sa, NULL);
}
- if (write_arch)
- apk_blob_to_file(db->root_fd, apk_arch_file, *db->arch, APK_BTF_ADD_EOL);
/* mount /proc */
if (asprintf(&db->root_proc_dir, "%s/proc", db->ctx->root) == -1)
@@ -1655,6 +1613,7 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac)
db->cache_dir = apk_static_cache_dir;
db->cache_fd = openat(db->root_fd, db->cache_dir, O_RDONLY | O_CLOEXEC);
if (db->cache_fd < 0) {
+ mkdirat(db->root_fd, "var", 0755);
mkdirat(db->root_fd, "var/cache", 0755);
mkdirat(db->root_fd, "var/cache/apk", 0755);
db->cache_fd = openat(db->root_fd, db->cache_dir, O_RDONLY | O_CLOEXEC);
@@ -1671,15 +1630,7 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac)
}
r = apk_db_read_state(db, ac->open_flags);
- if (r == -ENOENT && (ac->open_flags & APK_OPENF_CREATE)) {
- r = apk_db_create(db);
- if (r != 0) {
- msg = "Unable to create database";
- goto ret_r;
- }
- r = apk_db_read_state(db, ac->open_flags);
- }
- if (r != 0) {
+ if (r != 0 && !(r == -ENOENT && (ac->open_flags & APK_OPENF_CREATE))) {
msg = "Unable to read database state";
goto ret_r;
}
@@ -1748,11 +1699,24 @@ int apk_db_write_config(struct apk_database *db)
if ((db->ctx->flags & APK_SIMULATE) || db->ctx->root == NULL)
return 0;
- if (db->lock_fd == 0) {
+ if (db->ctx->open_flags & APK_OPENF_CREATE) {
+ if (faccessat(db->root_fd, "lib/apk/db", F_OK, 0) != 0) {
+ mkdirat(db->root_fd, "lib", 0755);
+ mkdirat(db->root_fd, "lib/apk", 0755);
+ mkdirat(db->root_fd, "lib/apk/db", 0755);
+ }
+ if (faccessat(db->root_fd, "etc/apk", F_OK, 0) != 0) {
+ mkdirat(db->root_fd, "etc", 0755);
+ mkdirat(db->root_fd, "etc/apk", 0755);
+ }
+ } else if (db->lock_fd == 0) {
apk_err(out, "Refusing to write db without write lock!");
return -1;
}
+ 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));
diff --git a/src/package.c b/src/package.c
index 0b80b06..0ad0156 100644
--- a/src/package.c
+++ b/src/package.c
@@ -18,6 +18,7 @@
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
+#include <sys/sysmacros.h>
#include "apk_openssl.h"
#include <openssl/pem.h>
@@ -773,10 +774,28 @@ void apk_ipkg_run_script(struct apk_installed_package *ipkg,
if ((db->ctx->flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0)
return;
+ if (!db->script_dirs_checked) {
+ db->script_dirs_checked = 1;
+ if (faccessat(db->root_fd, "tmp", F_OK, 0) != 0)
+ mkdirat(db->root_fd, "tmp", 01777);
+ if (faccessat(db->root_fd, "dev", F_OK, 0) != 0) {
+ mkdirat(db->root_fd, "dev", 0755);
+ mknodat(db->root_fd, "dev/null", S_IFCHR | 0666, makedev(1, 3));
+ mknodat(db->root_fd, "dev/zero", S_IFCHR | 0666, makedev(1, 5));
+ mknodat(db->root_fd, "dev/random", S_IFCHR | 0666, makedev(1, 8));
+ mknodat(db->root_fd, "dev/urandom", S_IFCHR | 0666, makedev(1, 9));
+ mknodat(db->root_fd, "dev/console", S_IFCHR | 0600, makedev(5, 1));
+ }
+ if (faccessat(db->root_fd, "var/cache/misc", F_OK, 0) != 0) {
+ mkdirat(root_fd, "var", 0755);
+ mkdirat(root_fd, "var/cache", 0755);
+ mkdirat(root_fd, "var/cache/misc", 0755);
+ }
+ }
+
apk_msg(out, "Executing %s", &fn[15]);
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0755);
if (fd < 0) {
- mkdirat(root_fd, "var/cache/misc", 0755);
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0755);
if (fd < 0) goto err_log;
}