]> git.alsa-project.org Git - alsa-utils.git/commitdiff
alsactl: fix sequence to clean card specific config files for UCM
authorJaroslav Kysela <perex@perex.cz>
Thu, 1 Jan 2026 17:39:38 +0000 (18:39 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 1 Jan 2026 17:41:22 +0000 (18:41 +0100)
For UCM, card-specific config files should be removed only when the fixed
boot flag is set or if the card is not the primary card in a given card
group.

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

index 2aefb899c30b0add76623d22edc392a73bf21142..9f1728458883f13883d32abecc96618484017e8c 100644 (file)
@@ -68,7 +68,7 @@ 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 *cfgdir, const char *file, int flags, const char *cardname);
-int init_ucm(int flags, int cardno);
+int init_ucm(const char *cfgdir, int flags, int cardno);
 bool validate_boot_time(long long boot_time, long long current_time, long long synctime);
 int read_boot_params(snd_ctl_t *handle, long long *boot_time, long long *sync_time, long long *restore_time, long long *primary_card);
 int write_boot_params(snd_ctl_t *handle, long long boot_time, long long sync_time, long long restore_time, long long primary_card);
index a34cb0e3f9c82874052704fb979dba340ff517e7..a437392b6061a1c7cc95d661578b21e70e19a58a 100644 (file)
@@ -1761,7 +1761,7 @@ int init(const char *cfgdir, const char *filename, int flags, const char *cardna
                                lasterr = err;
                        continue;
                }
-               err = init_ucm(flags, iter.card);
+               err = init_ucm(cfgdir, flags, iter.card);
                if (err == 0 || card_state_is_okay(err))
                        continue;
                err = init_space(&space, iter.card);
index 60967c407be17cce9e407ca0ecaa90dca4ae92d1..c16842739e17bc846f6fbdef8de95a80b4c68bbc 100644 (file)
@@ -137,11 +137,17 @@ static int reopen_ucm_manager(snd_use_case_mgr_t **uc_mgr, int cardno, int flags
  * Helper: Execute boot sequences
  * Returns: 0 on success, negative on error
  */
-static int execute_boot_sequences(snd_use_case_mgr_t *uc_mgr, int flags, bool fixed_boot)
+static int execute_boot_sequences(const char *cfgdir, snd_use_case_mgr_t *uc_mgr,
+                                 int cardno, int flags, bool fixed_boot)
 {
        int err = 0;
 
        if (fixed_boot) {
+               err = snd_card_clean_cfgdir(cfgdir, cardno);
+               if (err < 0) {
+                       dbg("ucm clean cfgdir: %d", err);
+                       return err;
+               }
                err = snd_use_case_set(uc_mgr, "_fboot", NULL);
                dbg("ucm _fboot: %d", err);
                if (err == -ENOENT && (flags & FLAG_UCM_BOOT) != 0) {
@@ -170,7 +176,7 @@ static int execute_boot_sequences(snd_use_case_mgr_t *uc_mgr, int flags, bool fi
  * Handle also card groups.
  * Returns: 0 = success, 1 = skip this card (e.g. linked or in-sync), negative on error
  */
-int init_ucm(int flags, int cardno)
+int init_ucm(const char *cfgdir, int flags, int cardno)
 {
        snd_use_case_mgr_t *uc_mgr;
        char id[64];
@@ -268,7 +274,7 @@ int init_ucm(int flags, int cardno)
        }
 
 _execute_boot:
-       if (flags & FLAG_UCM_FBOOT)
+       if (fixed_boot)
                restored = true;
 
        if (boot_card_group) {
@@ -277,7 +283,7 @@ _execute_boot:
                        goto _error;
        }
 
-       err = execute_boot_sequences(uc_mgr, flags, fixed_boot);
+       err = execute_boot_sequences(cfgdir, uc_mgr, cardno, flags, fixed_boot);
        if (err < 0)
                goto _error;
 
@@ -286,6 +292,15 @@ _execute_boot:
 _error:
        snd_use_case_mgr_close(uc_mgr);
 _fin:
+       if (fixed_boot && primary_card >= 0 && primary_card != cardno) {
+               /* remove card specific configuration files for other cards in group */
+               int clean_err = snd_card_clean_cfgdir(cfgdir, cardno);
+               if (clean_err < 0) {
+                       dbg("ucm clean cfgdir: %d", clean_err);
+                       if (err >= 0)
+                               err = clean_err;
+               }
+       }
        if (lock_fd >= 0)
                group_state_unlock(lock_fd, groupfile);
        if (ctl)
@@ -298,7 +313,7 @@ _fin:
 
 #else
 
-int init_ucm(int flags, int cardno)
+int init_ucm(const char *cfgdir, int flags, int cardno)
 {
        return -ENXIO;
 }
index 7c6e6d1facb9c02aaf2d43363fd1d4ed7eaa241f..79bd309987e70b3a682ce0d95f03e9760fa66e07 100644 (file)
@@ -1790,18 +1790,20 @@ int load_state(const char *cfgdir, const char *file,
                        finalerr = lock_fd;
                        continue;
                }
-               err = snd_card_clean_cfgdir(cfgdir, iter.card);
-               if (err < 0) {
-                       initfailed(iter.card, "cfgdir", err);
-                       finalerr = err;
-                       continue;
-               }
                /* error is ignored */
-               err = init_ucm(initflags | FLAG_UCM_FBOOT, iter.card);
+               err = init_ucm(cfgdir, initflags | FLAG_UCM_FBOOT, iter.card);
                /* return code 1 and 2 -> postpone initialization */
                if (card_state_is_okay(err)) {
                        export_card_state_set(iter.card, err);
                        goto unlock_card;
+               } else if (err < 0) {
+                       /* no UCM - remove card specific configuration */
+                       err = snd_card_clean_cfgdir(cfgdir, iter.card);
+                       if (err < 0) {
+                               initfailed(iter.card, "cfgdir", err);
+                               finalerr = err;
+                               continue;
+                       }
                }
                /* do a check if controls matches state file */
                if (do_init && set_controls(iter.card, config, 0)) {