]> git.alsa-project.org Git - alsa-utils.git/commitdiff
alsactl: clean the boot / hotplug card specific configuration directory
authorJaroslav Kysela <perex@perex.cz>
Tue, 13 Apr 2021 09:15:55 +0000 (11:15 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 13 Apr 2021 09:16:09 +0000 (11:16 +0200)
The /var/lib/alsa/card<NUMBER>.conf.d directories should be emptied
when the card is initialized. Implement this functionality directly
to alsactl.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
alsactl/alsactl.1
alsactl/alsactl.c
alsactl/alsactl.h
alsactl/init_parse.c
alsactl/state.c
alsactl/utils.c

index 0bd6c1bb95ab32910c212ddb36381b3fd973d53f..8296663a7c2dca62b86f335af1833d81ab3e6dd2 100644 (file)
@@ -98,6 +98,10 @@ Print alsactl version number.
 \fI\-f, \-\-file\fP
 Select the configuration file to use. The default is /var/lib/alsa/asound.state.
 
+.TP
+\fI\-a, \-\-config-dir\fP
+Select the boot / hotplug ALSA configuration directory to use. The default is /var/lib/alsa.
+
 .TP
 \fI\-l, \-\-lock\fP
 Use the file locking to serialize the concurrent access to the state file (this
index c8000877ea4be0bf486d373fdbbaf47403257d5d..a0112844c70a425160d3e321891436968807615d 100644 (file)
 #include <sched.h>
 #include "alsactl.h"
 
+#ifndef SYS_ASOUND_DIR
+#define SYS_ASOUND_DIR "/var/lib/alsa"
+#endif
 #ifndef SYS_ASOUNDRC
-#define SYS_ASOUNDRC "/var/lib/alsa/asound.state"
+#define SYS_ASOUNDRC SYS_ASOUND_DIR "/asound.state"
 #endif
 #ifndef SYS_PIDFILE
 #define SYS_PIDFILE "/var/run/alsactl.pid"
@@ -73,6 +76,7 @@ static struct arg args[] = {
 { 'v', "version", "print version of this program" },
 { HEADER, NULL, "Available state options:" },
 { FILEARG | 'f', "file", "configuration file (default " SYS_ASOUNDRC ")" },
+{ FILEARG | 'a', "config-dir", "boot / hotplug configuration directory (default " SYS_ASOUND_DIR ")" },
 { 'l', "lock", "use file locking to serialize concurrent access" },
 { 'L', "no-lock", "do not use file locking to serialize concurrent access" },
 { FILEARG | 'O', "lock-state-file", "state lock file path (default " SYS_LOCKFILE ")" },
@@ -227,6 +231,7 @@ int main(int argc, char *argv[])
                "/dev/snd/hwC",
                NULL
        };
+       char *cfgdir = SYS_ASOUND_DIR;
        char *cfgfile = SYS_ASOUNDRC;
        char *initfile = DATADIR "/init/00main";
        char *pidfile = SYS_PIDFILE;
@@ -286,6 +291,9 @@ int main(int argc, char *argv[])
                case 'f':
                        cfgfile = optarg;
                        break;
+               case 'a':
+                       cfgdir = optarg;
+                       break;
                case 'l':
                        do_lock = 1;
                        break;
@@ -420,7 +428,7 @@ int main(int argc, char *argv[])
        snd_lib_error_set_handler(error_handler);
 
        if (!strcmp(cmd, "init")) {
-               res = init(initfile, initflags | FLAG_UCM_FBOOT | FLAG_UCM_BOOT, cardname);
+               res = init(cfgdir, initfile, initflags | FLAG_UCM_FBOOT | FLAG_UCM_BOOT, cardname);
                snd_config_update_free_global();
        } else if (!strcmp(cmd, "store")) {
                res = save_state(cfgfile, cardname);
@@ -429,7 +437,7 @@ int main(int argc, char *argv[])
                   !strcmp(cmd, "nrestore")) {
                if (removestate)
                        remove(statefile);
-               res = load_state(cfgfile, initfile, initflags, cardname, init_fallback);
+               res = load_state(cfgdir, cfgfile, initfile, initflags, cardname, init_fallback);
                if (!strcmp(cmd, "rdaemon")) {
                        do_nice(use_nice, sched_idle);
                        res = state_daemon(cfgfile, cardname, period, pidfile);
index ca723e3191106f8a6dd77dbfa819c92468e8ae79..bbdf6c88baebe6efd1c60957245c2307c719dd7f 100644 (file)
@@ -46,12 +46,13 @@ const char *snd_card_iterator_next(struct snd_card_iterator *iter);
 int snd_card_iterator_error(struct snd_card_iterator *iter);
 
 int load_configuration(const char *file, snd_config_t **top, int *open_failed);
-int init(const char *file, int flags, const char *cardname);
+int init(const char *cfgdir, const char *file, int flags, const char *cardname);
 int init_ucm(int flags, int cardno);
 int state_lock(const char *file, int timeout);
 int state_unlock(int fd, const char *file);
 int save_state(const char *file, const char *cardname);
-int load_state(const char *file, const char *initfile, int initflags,
+int load_state(const char *cfgdir, const char *file,
+              const char *initfile, int initflags,
               const char *cardname, int do_init);
 int power(const char *argv[], int argc);
 int monitor(const char *name);
@@ -59,6 +60,7 @@ int state_daemon(const char *file, const char *cardname, int period,
                 const char *pidfile);
 int state_daemon_kill(const char *pidfile, const char *cmd);
 int clean(const char *cardname, char *const *extra_args);
+int snd_card_clean_cfgdir(const char *cfgdir, int cardno);
 
 /* utils */
 
index ab2c9065b23f5f6107dc9a3cf8beceea1cc81d89..9d0f473c1ada2aa7475d1d9f848a6a09c5178d08 100644 (file)
@@ -1743,7 +1743,7 @@ static int parse(struct space *space, const char *filename)
        return err ? err : -abs(space->exit_code);
 }
 
-int init(const char *filename, int flags, const char *cardname)
+int init(const char *cfgdir, const char *filename, int flags, const char *cardname)
 {
        struct space *space;
        struct snd_card_iterator iter;
@@ -1752,6 +1752,12 @@ int init(const char *filename, int flags, const char *cardname)
        sysfs_init();
        err = snd_card_iterator_sinit(&iter, cardname);
        while (snd_card_iterator_next(&iter)) {
+               err = snd_card_clean_cfgdir(cfgdir, iter.card);
+               if (err < 0) {
+                       if (lasterr == 0)
+                               lasterr = err;
+                       continue;
+               }
                err = init_ucm(flags, iter.card);
                if (err == 0)
                        continue;
index 0612970f5cad8aaf756c72fb7031e18fac9cd695..44fda3fe74d75138f66141cd6b7578ff47b77240 100644 (file)
@@ -1618,7 +1618,8 @@ out:
        return err;
 }
 
-int load_state(const char *file, const char *initfile, int initflags,
+int load_state(const char *cfgdir, const char *file,
+              const char *initfile, int initflags,
               const char *cardname, int do_init)
 {
        int err, finalerr = 0, open_failed;
@@ -1640,7 +1641,7 @@ int load_state(const char *file, const char *initfile, int initflags,
                while ((cardname1 = snd_card_iterator_next(&iter)) != NULL) {
                        if (!do_init)
                                break;
-                       err = init(initfile, initflags | FLAG_UCM_FBOOT | FLAG_UCM_BOOT, cardname1);
+                       err = init(cfgdir, initfile, initflags | FLAG_UCM_FBOOT | FLAG_UCM_BOOT, cardname1);
                        if (err < 0) {
                                finalerr = err;
                                initfailed(iter.card, "init", err);
@@ -1661,7 +1662,7 @@ int load_state(const char *file, const char *initfile, int initflags,
                init_ucm(initflags | FLAG_UCM_FBOOT, iter.card);
                /* do a check if controls matches state file */
                if (do_init && set_controls(iter.card, config, 0)) {
-                       err = init(initfile, initflags | FLAG_UCM_BOOT, cardname1);
+                       err = init(cfgdir, initfile, initflags | FLAG_UCM_BOOT, cardname1);
                        if (err < 0) {
                                initfailed(iter.card, "init", err);
                                finalerr = err;
index d0b1ac6705202bcb85a9d529c16b2b76f75b0ec7..c79fd951b8e00534e869538036562cf260edc64e 100644 (file)
@@ -284,3 +284,46 @@ int snd_card_iterator_error(struct snd_card_iterator *iter)
 {
        return iter->first ? (ignore_nocards ? 0 : -ENODEV) : 0;
 }
+
+static int cleanup_filename_filter(const struct dirent *dirent)
+{
+       size_t flen;
+
+       if (dirent == NULL)
+               return 0;
+       if (dirent->d_type == DT_DIR)
+               return 0;
+
+       flen = strlen(dirent->d_name);
+       if (flen <= 5)
+               return 0;
+
+       if (strncmp(&dirent->d_name[flen-5], ".conf", 5) == 0)
+               return 1;
+
+       return 0;
+}
+
+int snd_card_clean_cfgdir(const char *cfgdir, int cardno)
+{
+       char path[PATH_MAX];
+       struct dirent **list;
+       int lasterr = 0, n, j;
+
+       snprintf(path, sizeof(path), "%s/card%d.conf.d", cfgdir, cardno);
+       n = scandir(path, &list, cleanup_filename_filter, NULL);
+       if (n < 0) {
+               if (errno == ENOENT)
+                       return 0;
+               return -errno;
+       }
+       for (j = 0; j < n; j++) {
+               snprintf(path, sizeof(path), "%s/card%d.conf.d/%s", cfgdir, cardno, list[j]->d_name);
+               if (remove(path)) {
+                       error("Unable to remove file '%s'", path);
+                       lasterr = -errno;
+               }
+       }
+
+       return lasterr;
+}