From c8d851b4b756516973b5f4910c6d9204978a6dbb Mon Sep 17 00:00:00 2001 From: "Igor V. Kovalenko" Date: Sun, 29 Nov 2020 15:16:26 +0300 Subject: [PATCH] database: use existing database matching same architecture prefix State database binary file format may depend on system architecture, for instance gdbm binary format depends on architecture word size, making x86 and x64 gdbm files incompatible. If this is the case, it is handled by adding system architecture name to database file name using automatically configured CANONICAL_HOST string. Meson build define CANONICAL_HOST to be system architecture name, while autotools build extends this with vendor and and operating system components. Switch autotools build to use host_cpu for CANONICAL_HOST to match Meson configuration. For backwards compatibility always use existing database file matching CANONICAL_HOST prefix if it exists. Part-of: --- configure.ac | 2 +- src/pulsecore/database.c | 38 ++++++++++++++++++++++++++++++++++++++ src/pulsecore/database.h | 3 ++- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index a519e63d7..a95e4616e 100644 --- a/configure.ac +++ b/configure.ac @@ -57,7 +57,7 @@ AC_SUBST(LIBPULSE_SIMPLE_VERSION_INFO, [1:1:1]) AC_SUBST(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO, [0:6:0]) AC_CANONICAL_HOST -AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.]) +AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host_cpu", [Canonical host system architecture string.]) AC_CHECK_PROG([STOW], [stow], [yes], [no]) diff --git a/src/pulsecore/database.c b/src/pulsecore/database.c index 11f3d03c9..43af6fc76 100644 --- a/src/pulsecore/database.c +++ b/src/pulsecore/database.c @@ -22,6 +22,7 @@ #endif #include +#include #include #include @@ -37,6 +38,9 @@ pa_database* pa_database_open(const char *path, const char *fn, bool prependmid, char *machine_id = NULL, *filename_prefix, *full_path; + DIR *database_dir = NULL; + struct dirent *de; + pa_database *f; pa_assert(!arch_suffix || arch_suffix[0]); @@ -53,6 +57,40 @@ pa_database* pa_database_open(const char *path, const char *fn, bool prependmid, fn, arch_suffix?".":"", arch_suffix?:""); + /* Search for existing database directory entry name matching architecture suffix and filename suffix. */ + database_dir = opendir(path); + + if (database_dir) { + for (;;) { + errno = 0; + de = readdir(database_dir); + if (!de) { + if (errno) { + pa_log_warn("Unable to search for compatible database file, readdir() failed: %s", pa_cstrerror(errno)); + /* can continue as if there is no matching database file candidate */ + } + + break; + } + + if (pa_startswith(de->d_name, filename_prefix) && pa_endswith(de->d_name + strlen(filename_prefix), filename_suffix)) { + /* candidate filename found, replace filename_prefix with this one if match is not exact */ + + if (strlen(de->d_name) != strlen(filename_prefix) + strlen(filename_suffix)) { + pa_log_debug("Found compatible database file '%s/%s', using it", path, de->d_name); + pa_xfree(filename_prefix); + filename_prefix = pa_xstrndup(de->d_name, strlen(de->d_name) - strlen(filename_suffix)); + } + + break; + } + } + + closedir(database_dir); + } else { + pa_log_warn("Unable to search for compatible database file, failed to open directory %s: %s", path, pa_cstrerror(errno)); + } + full_path = pa_sprintf_malloc("%s" PA_PATH_SEP "%s%s", path, filename_prefix, filename_suffix); f = pa_database_open_internal(full_path, for_write); diff --git a/src/pulsecore/database.h b/src/pulsecore/database.h index fe2890577..cc16e535d 100644 --- a/src/pulsecore/database.h +++ b/src/pulsecore/database.h @@ -43,7 +43,8 @@ const char* pa_database_get_arch_suffix(void); /* Database implementation; returns non-empty database filename extension string */ const char* pa_database_get_filename_suffix(void); -/* This will attempt opening database file matching compiled CANONICAL_HOST identifier. +/* This will attempt opening database file matching compiled CANONICAL_HOST implementation architecture name prefix, + * or new database file will be created and opened with implementation architecture name suffix if required. * If prependmid is true, file name is augmented with machine id prefix. */ pa_database* pa_database_open(const char *path, const char *fn, bool prependmid, bool for_write);