[pulseaudio-commits] [Git][pulseaudio/pulseaudio][master] 5 commits: database: extract common method to handle machine id and architecture

PulseAudio Marge Bot gitlab at gitlab.freedesktop.org
Thu Jan 7 23:31:56 UTC 2021



PulseAudio Marge Bot pushed to branch master at PulseAudio / pulseaudio


Commits:
0ac6b167 by Igor V. Kovalenko at 2021-01-07T23:27:16+00:00
database: extract common method to handle machine id and architecture

Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/425>

- - - - -
ae9d0cf3 by Igor V. Kovalenko at 2021-01-07T23:27:16+00:00
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: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/425>

- - - - -
4ca8997a by Igor V. Kovalenko at 2021-01-07T23:27:16+00:00
database: drop arch from newly created database file name

Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/425>

- - - - -
7115023c by Igor V. Kovalenko at 2021-01-07T23:27:16+00:00
database: pick old database file from any arch

Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/425>

- - - - -
c2ae56a7 by Igor V. Kovalenko at 2021-01-07T23:27:16+00:00
database: clean up remaining references to CANONICAL_HOST

Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/425>

- - - - -


15 changed files:

- configure.ac
- meson.build
- src/Makefile.am
- src/daemon/main.c
- src/modules/module-card-restore.c
- src/modules/module-device-manager.c
- src/modules/module-device-restore.c
- src/modules/module-equalizer-sink.c
- src/modules/module-stream-restore.c
- src/pulsecore/database-gdbm.c
- src/pulsecore/database-simple.c
- src/pulsecore/database-tdb.c
- + src/pulsecore/database.c
- src/pulsecore/database.h
- src/pulsecore/meson.build


Changes:

=====================================
configure.ac
=====================================
@@ -56,9 +56,6 @@ AC_SUBST(LIBPULSE_SIMPLE_VERSION_INFO, [1:1:1])
 # info x:y:z always will hold x=z
 AC_SUBST(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO, [0:6:0])
 
-AC_CANONICAL_HOST
-AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.])
-
 AC_CHECK_PROG([STOW], [stow], [yes], [no])
 
 AS_IF([test "x$STOW" = "xyes" && test -d /usr/local/stow], [


=====================================
meson.build
=====================================
@@ -125,7 +125,6 @@ cdata = configuration_data()
 cdata.set_quoted('PACKAGE', 'pulseaudio')
 cdata.set_quoted('PACKAGE_NAME', 'pulseaudio')
 cdata.set_quoted('PACKAGE_VERSION', pa_version_str)
-cdata.set_quoted('CANONICAL_HOST', target_machine.cpu_family())
 cdata.set('PA_MAJOR', pa_version_major)
 cdata.set('PA_MINOR', pa_version_minor)
 cdata.set('PA_API_VERSION', pa_api_version)


=====================================
src/Makefile.am
=====================================
@@ -1042,7 +1042,7 @@ libpulsecore_ at PA_MAJORMINOR@_la_SOURCES = \
 		pulsecore/source.c pulsecore/source.h \
 		pulsecore/start-child.c pulsecore/start-child.h \
 		pulsecore/thread-mq.c pulsecore/thread-mq.h \
-		pulsecore/database.h
+		pulsecore/database.c pulsecore/database.h
 
 libpulsecore_ at PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS) $(LIBSNDFILE_CFLAGS) $(WINSOCK_CFLAGS)
 libpulsecore_ at PA_MAJORMINOR@_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) -avoid-version


=====================================
src/daemon/main.c
=====================================
@@ -922,7 +922,6 @@ int main(int argc, char *argv[]) {
     pa_set_env_and_record("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
 
     pa_log_info("This is PulseAudio %s", PACKAGE_VERSION);
-    pa_log_debug("Compilation host: %s", CANONICAL_HOST);
     pa_log_debug("Compilation CFLAGS: %s", PA_CFLAGS);
 
 #ifdef HAVE_LIBSAMPLERATE


=====================================
src/modules/module-card-restore.c
=====================================
@@ -618,7 +618,7 @@ static pa_hook_result_t card_preferred_port_changed_callback(pa_core *core, pa_c
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
-    char *fname;
+    char *state_path;
     bool restore_bluetooth_profile;
 
     pa_assert(m);
@@ -648,17 +648,15 @@ int pa__init(pa_module*m) {
     pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_CARD_PROFILE_ADDED], PA_HOOK_NORMAL, (pa_hook_cb_t) card_profile_added_callback, u);
     pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) port_offset_change_callback, u);
 
-    if (!(fname = pa_state_path("card-database", true)))
+    if (!(state_path = pa_state_path(NULL, true)))
         goto fail;
 
-    if (!(u->database = pa_database_open(fname, true))) {
-        pa_log("Failed to open volume database '%s': %s", fname, pa_cstrerror(errno));
-        pa_xfree(fname);
+    if (!(u->database = pa_database_open(state_path, "card-database", true, true))) {
+        pa_xfree(state_path);
         goto fail;
     }
 
-    pa_log_info("Successfully opened database file '%s'.", fname);
-    pa_xfree(fname);
+    pa_xfree(state_path);
 
     pa_modargs_free(ma);
     return 0;


=====================================
src/modules/module-device-manager.c
=====================================
@@ -1544,7 +1544,7 @@ struct prioritised_indexes {
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
-    char *fname;
+    char *state_path;
     pa_sink *sink;
     pa_source *source;
     uint32_t idx;
@@ -1601,17 +1601,15 @@ int pa__init(pa_module*m) {
         u->source_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE+5, (pa_hook_cb_t) source_unlink_hook_callback, u);
     }
 
-    if (!(fname = pa_state_path("device-manager", true)))
+    if (!(state_path = pa_state_path(NULL, true)))
         goto fail;
 
-    if (!(u->database = pa_database_open(fname, true))) {
-        pa_log("Failed to open volume database '%s': %s", fname, pa_cstrerror(errno));
-        pa_xfree(fname);
+    if (!(u->database = pa_database_open(state_path, "device-manager", true, true))) {
+        pa_xfree(state_path);
         goto fail;
     }
 
-    pa_log_info("Successfully opened database file '%s'.", fname);
-    pa_xfree(fname);
+    pa_xfree(state_path);
 
     /* Attempt to inject the devices into the list in priority order */
     total_devices = PA_MAX(pa_idxset_size(m->core->sinks), pa_idxset_size(m->core->sources));


=====================================
src/modules/module-device-restore.c
=====================================
@@ -1202,7 +1202,7 @@ static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_nati
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
-    char *fname;
+    char *state_path;
     pa_sink *sink;
     pa_source *source;
     uint32_t idx;
@@ -1259,17 +1259,15 @@ int pa__init(pa_module*m) {
     if (restore_formats)
         pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) sink_put_hook_callback, u);
 
-    if (!(fname = pa_state_path("device-volumes", true)))
+    if (!(state_path = pa_state_path(NULL, true)))
         goto fail;
 
-    if (!(u->database = pa_database_open(fname, true))) {
-        pa_log("Failed to open volume database '%s': %s", fname, pa_cstrerror(errno));
-        pa_xfree(fname);
+    if (!(u->database = pa_database_open(state_path, "device-volumes", true, true))) {
+        pa_xfree(state_path);
         goto fail;
     }
 
-    pa_log_info("Successfully opened database file '%s'.", fname);
-    pa_xfree(fname);
+    pa_xfree(state_path);
 
     PA_IDXSET_FOREACH(sink, m->core->sinks, idx)
         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW, sink->index, u);


=====================================
src/modules/module-equalizer-sink.c
=====================================
@@ -946,7 +946,7 @@ static void save_state(struct userdata *u) {
     float *H;
     pa_datum key, data;
     pa_database *database;
-    char *dbname;
+    char *state_path;
     char *packed;
     size_t packed_length;
 
@@ -969,9 +969,9 @@ static void save_state(struct userdata *u) {
     data.data = state;
     data.size = filter_state_size + packed_length;
     //thread safety for 0.9.17?
-    pa_assert_se(dbname = pa_state_path(EQ_STATE_DB, false));
-    pa_assert_se(database = pa_database_open(dbname, true));
-    pa_xfree(dbname);
+    pa_assert_se(state_path = pa_state_path(NULL, false));
+    pa_assert_se(database = pa_database_open(state_path, EQ_STATE_DB, false, true));
+    pa_xfree(state_path);
 
     pa_database_set(database, &key, &data, true);
     pa_database_sync(database);
@@ -1020,10 +1020,10 @@ static void load_state(struct userdata *u) {
     float *H;
     pa_datum key, value;
     pa_database *database;
-    char *dbname;
-    pa_assert_se(dbname = pa_state_path(EQ_STATE_DB, false));
-    database = pa_database_open(dbname, false);
-    pa_xfree(dbname);
+    char *state_path;
+    pa_assert_se(state_path = pa_state_path(NULL, false));
+    database = pa_database_open(state_path, EQ_STATE_DB, false, false);
+    pa_xfree(state_path);
     if (!database) {
         pa_log("No resume state");
         return;
@@ -1626,12 +1626,12 @@ void dbus_init(struct userdata *u) {
     sink_list = pa_shared_get(u->sink->core, SINKLIST);
     u->database = pa_shared_get(u->sink->core, EQDB);
     if (sink_list == NULL) {
-        char *dbname;
+        char *state_path;
         sink_list=pa_idxset_new(&pa_idxset_trivial_hash_func, &pa_idxset_trivial_compare_func);
         pa_shared_set(u->sink->core, SINKLIST, sink_list);
-        pa_assert_se(dbname = pa_state_path("equalizer-presets", false));
-        pa_assert_se(u->database = pa_database_open(dbname, true));
-        pa_xfree(dbname);
+        pa_assert_se(state_path = pa_state_path(NULL, false));
+        pa_assert_se(u->database = pa_database_open(state_path, "equalizer-presets", false, true));
+        pa_xfree(state_path);
         pa_shared_set(u->sink->core, EQDB, u->database);
         pa_dbus_protocol_add_interface(u->dbus_protocol, MANAGER_PATH, &manager_info, u->sink->core);
         pa_dbus_protocol_register_extension(u->dbus_protocol, EXTNAME);


=====================================
src/modules/module-stream-restore.c
=====================================
@@ -2266,7 +2266,7 @@ static void clean_up_db(struct userdata *u) {
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
-    char *fname;
+    char *state_path;
     pa_sink_input *si;
     pa_source_output *so;
     uint32_t idx;
@@ -2324,17 +2324,15 @@ int pa__init(pa_module*m) {
         pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_fixate_hook_callback, u);
     }
 
-    if (!(fname = pa_state_path("stream-volumes", true)))
+    if (!(state_path = pa_state_path(NULL, true)))
         goto fail;
 
-    if (!(u->database = pa_database_open(fname, true))) {
-        pa_log("Failed to open volume database '%s': %s", fname, pa_cstrerror(errno));
-        pa_xfree(fname);
+    if (!(u->database = pa_database_open(state_path, "stream-volumes", true, true))) {
+        pa_xfree(state_path);
         goto fail;
     }
 
-    pa_log_info("Successfully opened database file '%s'.", fname);
-    pa_xfree(fname);
+    pa_xfree(state_path);
 
     clean_up_db(u);
 


=====================================
src/pulsecore/database-gdbm.c
=====================================
@@ -59,17 +59,16 @@ void pa_datum_free(pa_datum *d) {
     pa_zero(d);
 }
 
-pa_database* pa_database_open(const char *fn, bool for_write) {
+const char* pa_database_get_filename_suffix(void) {
+    return ".gdbm";
+}
+
+pa_database* pa_database_open_internal(const char *path, bool for_write) {
     GDBM_FILE f;
     int gdbm_cache_size;
-    char *path;
 
-    pa_assert(fn);
+    pa_assert(path);
 
-    /* We include the host identifier in the file name because gdbm
-     * files are CPU dependent, and we don't want things to go wrong
-     * if we are on a multiarch system. */
-    path = pa_sprintf_malloc("%s."CANONICAL_HOST".gdbm", fn);
     errno = 0;
 
     /* We need to set the block size explicitly here, since otherwise
@@ -80,8 +79,6 @@ pa_database* pa_database_open(const char *fn, bool for_write) {
     if (f)
         pa_log_debug("Opened GDBM database '%s'", path);
 
-    pa_xfree(path);
-
     if (!f) {
         if (errno == 0)
             errno = EIO;


=====================================
src/pulsecore/database-simple.c
=====================================
@@ -222,14 +222,16 @@ static int fill_data(simple_data *db, FILE *f) {
     return pa_hashmap_size(db->map);
 }
 
-pa_database* pa_database_open(const char *fn, bool for_write) {
+const char* pa_database_get_filename_suffix(void) {
+    return ".simple";
+}
+
+pa_database* pa_database_open_internal(const char *path, bool for_write) {
     FILE *f;
-    char *path;
     simple_data *db;
 
-    pa_assert(fn);
+    pa_assert(path);
 
-    path = pa_sprintf_malloc("%s."CANONICAL_HOST".simple", fn);
     errno = 0;
 
     f = pa_fopen_cloexec(path, "r");
@@ -251,8 +253,6 @@ pa_database* pa_database_open(const char *fn, bool for_write) {
         db = NULL;
     }
 
-    pa_xfree(path);
-
     return (pa_database*) db;
 }
 


=====================================
src/pulsecore/database-tdb.c
=====================================
@@ -97,18 +97,18 @@ finish:
     return c;
 }
 
-pa_database* pa_database_open(const char *fn, bool for_write) {
+const char* pa_database_get_filename_suffix(void) {
+    return ".tdb";
+}
+
+pa_database* pa_database_open_internal(const char *path, bool for_write) {
     struct tdb_context *c;
-    char *path;
 
-    pa_assert(fn);
+    pa_assert(path);
 
-    path = pa_sprintf_malloc("%s.tdb", fn);
     if ((c = tdb_open_cloexec(path, 0, TDB_NOSYNC|TDB_NOLOCK, (for_write ? O_RDWR|O_CREAT : O_RDONLY), 0644)))
         pa_log_debug("Opened TDB database '%s'", path);
 
-    pa_xfree(path);
-
     if (!c) {
         if (errno == 0)
             errno = EIO;


=====================================
src/pulsecore/database.c
=====================================
@@ -0,0 +1,107 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2020 Igor V. Kovalenko <igor.v.kovalenko at gmail.com>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <dirent.h>
+
+#include <pulse/xmalloc.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/log.h>
+
+#include "database.h"
+#include "core-error.h"
+
+pa_database* pa_database_open(const char *path, const char *fn, bool prependmid, bool for_write) {
+
+    const char *filename_suffix = pa_database_get_filename_suffix();
+
+    char *machine_id = NULL, *filename_prefix, *full_path;
+
+    DIR *database_dir = NULL;
+    struct dirent *de;
+
+    pa_database *f;
+
+    pa_assert(filename_suffix && filename_suffix[0]);
+
+    if (prependmid && !(machine_id = pa_machine_id())) {
+        return NULL;
+    }
+
+    /* Database file name starts with ${machine_id}-${fn} */
+    if (machine_id)
+        filename_prefix = pa_sprintf_malloc("%s-%s", machine_id, fn);
+    else
+        filename_prefix = pa_xstrdup(fn);
+
+    /* 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 existing 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)
+                && de->d_name[strlen(filename_prefix)] == '.'
+                && pa_endswith(de->d_name + strlen(filename_prefix) + 1, filename_suffix)) {
+
+                /* candidate filename found, replace filename_prefix with this one */
+
+                pa_log_debug("Found existing 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 existing 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);
+
+    if (f)
+        pa_log_info("Successfully opened '%s' database file '%s'.", fn, full_path);
+    else
+        pa_log("Failed to open '%s' database file '%s': %s", fn, full_path, pa_cstrerror(errno));
+
+    pa_xfree(full_path);
+    pa_xfree(filename_prefix);
+
+    /* deallocate machine_id if it was used to construct file name */
+    pa_xfree(machine_id);
+
+    return f;
+}


=====================================
src/pulsecore/database.h
=====================================
@@ -38,8 +38,29 @@ typedef struct pa_datum {
 
 void pa_datum_free(pa_datum *d);
 
-/* This will append a suffix to the filename */
-pa_database* pa_database_open(const char *fn, bool for_write);
+/* Database implementation; returns non-empty database filename extension string */
+const char* pa_database_get_filename_suffix(void);
+
+/* Opens a database file. The file is loaded from the directory indicated by
+ * path. The file name is constructed by using fn as the base and then adding
+ * several parts:
+ *   1) If prependmid is true, the machine id is prepended to the file name.
+ *   2) The database implementation specific suffix is added.
+ *   3) Older versions of PulseAudio in some cases added the CPU architecture
+ *      to the file name, which was later deemed unnecessary, but for
+ *      compatibility reasons we still need to look for those files, so we scan
+ *      the directory for files that match the prefix (possible machine id plus
+ *      fn) and the suffix, and if any matches are found, we use the first one.
+ *
+ * When no existing file is found, we create a new file for the database
+ * (without the CPU architecture part in the name).
+ *
+ * For a read-only database, set for_write to false. */
+
+pa_database* pa_database_open(const char *path, const char *fn, bool prependmid, bool for_write);
+
+/* Database implementation; opens specified database file using provided path. */
+pa_database* pa_database_open_internal(const char *path, bool for_write);
 void pa_database_close(pa_database *db);
 
 pa_datum* pa_database_get(pa_database *db, const pa_datum *key, pa_datum* data);


=====================================
src/pulsecore/meson.build
=====================================
@@ -14,6 +14,7 @@ libpulsecore_sources = [
   'cpu-orc.c',
   'cpu-x86.c',
   'device-port.c',
+  'database.c',
   'ffmpeg/resample2.c',
   'filter/biquad.c',
   'filter/crossover.c',



View it on GitLab: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/compare/0efae0488ccd4536926f5fa2b4cf524e63da9095...c2ae56a73cac813c95973e534a011d38a6a9e891

-- 
View it on GitLab: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/compare/0efae0488ccd4536926f5fa2b4cf524e63da9095...c2ae56a73cac813c95973e534a011d38a6a9e891
You're receiving this email because of your account on gitlab.freedesktop.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/pulseaudio-commits/attachments/20210107/de7b3eca/attachment-0001.htm>


More information about the pulseaudio-commits mailing list