mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-09 17:45:41 +01:00
alsactl: clean the boot / hotplug card specific configuration directory
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>
This commit is contained in:
parent
0a6b63a2c4
commit
a589d88862
6 changed files with 73 additions and 9 deletions
|
@ -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
|
||||
|
|
|
@ -31,8 +31,11 @@
|
|||
#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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue