mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-12 23:45:43 +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
|
\fI\-f, \-\-file\fP
|
||||||
Select the configuration file to use. The default is /var/lib/alsa/asound.state.
|
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
|
.TP
|
||||||
\fI\-l, \-\-lock\fP
|
\fI\-l, \-\-lock\fP
|
||||||
Use the file locking to serialize the concurrent access to the state file (this
|
Use the file locking to serialize the concurrent access to the state file (this
|
||||||
|
|
|
@ -31,8 +31,11 @@
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include "alsactl.h"
|
#include "alsactl.h"
|
||||||
|
|
||||||
|
#ifndef SYS_ASOUND_DIR
|
||||||
|
#define SYS_ASOUND_DIR "/var/lib/alsa"
|
||||||
|
#endif
|
||||||
#ifndef SYS_ASOUNDRC
|
#ifndef SYS_ASOUNDRC
|
||||||
#define SYS_ASOUNDRC "/var/lib/alsa/asound.state"
|
#define SYS_ASOUNDRC SYS_ASOUND_DIR "/asound.state"
|
||||||
#endif
|
#endif
|
||||||
#ifndef SYS_PIDFILE
|
#ifndef SYS_PIDFILE
|
||||||
#define SYS_PIDFILE "/var/run/alsactl.pid"
|
#define SYS_PIDFILE "/var/run/alsactl.pid"
|
||||||
|
@ -73,6 +76,7 @@ static struct arg args[] = {
|
||||||
{ 'v', "version", "print version of this program" },
|
{ 'v', "version", "print version of this program" },
|
||||||
{ HEADER, NULL, "Available state options:" },
|
{ HEADER, NULL, "Available state options:" },
|
||||||
{ FILEARG | 'f', "file", "configuration file (default " SYS_ASOUNDRC ")" },
|
{ 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', "lock", "use file locking to serialize concurrent access" },
|
||||||
{ 'L', "no-lock", "do not 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 ")" },
|
{ 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",
|
"/dev/snd/hwC",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
char *cfgdir = SYS_ASOUND_DIR;
|
||||||
char *cfgfile = SYS_ASOUNDRC;
|
char *cfgfile = SYS_ASOUNDRC;
|
||||||
char *initfile = DATADIR "/init/00main";
|
char *initfile = DATADIR "/init/00main";
|
||||||
char *pidfile = SYS_PIDFILE;
|
char *pidfile = SYS_PIDFILE;
|
||||||
|
@ -286,6 +291,9 @@ int main(int argc, char *argv[])
|
||||||
case 'f':
|
case 'f':
|
||||||
cfgfile = optarg;
|
cfgfile = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'a':
|
||||||
|
cfgdir = optarg;
|
||||||
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
do_lock = 1;
|
do_lock = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -420,7 +428,7 @@ int main(int argc, char *argv[])
|
||||||
snd_lib_error_set_handler(error_handler);
|
snd_lib_error_set_handler(error_handler);
|
||||||
|
|
||||||
if (!strcmp(cmd, "init")) {
|
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();
|
snd_config_update_free_global();
|
||||||
} else if (!strcmp(cmd, "store")) {
|
} else if (!strcmp(cmd, "store")) {
|
||||||
res = save_state(cfgfile, cardname);
|
res = save_state(cfgfile, cardname);
|
||||||
|
@ -429,7 +437,7 @@ int main(int argc, char *argv[])
|
||||||
!strcmp(cmd, "nrestore")) {
|
!strcmp(cmd, "nrestore")) {
|
||||||
if (removestate)
|
if (removestate)
|
||||||
remove(statefile);
|
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")) {
|
if (!strcmp(cmd, "rdaemon")) {
|
||||||
do_nice(use_nice, sched_idle);
|
do_nice(use_nice, sched_idle);
|
||||||
res = state_daemon(cfgfile, cardname, period, pidfile);
|
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 snd_card_iterator_error(struct snd_card_iterator *iter);
|
||||||
|
|
||||||
int load_configuration(const char *file, snd_config_t **top, int *open_failed);
|
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 init_ucm(int flags, int cardno);
|
||||||
int state_lock(const char *file, int timeout);
|
int state_lock(const char *file, int timeout);
|
||||||
int state_unlock(int fd, const char *file);
|
int state_unlock(int fd, const char *file);
|
||||||
int save_state(const char *file, const char *cardname);
|
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);
|
const char *cardname, int do_init);
|
||||||
int power(const char *argv[], int argc);
|
int power(const char *argv[], int argc);
|
||||||
int monitor(const char *name);
|
int monitor(const char *name);
|
||||||
|
@ -59,6 +60,7 @@ int state_daemon(const char *file, const char *cardname, int period,
|
||||||
const char *pidfile);
|
const char *pidfile);
|
||||||
int state_daemon_kill(const char *pidfile, const char *cmd);
|
int state_daemon_kill(const char *pidfile, const char *cmd);
|
||||||
int clean(const char *cardname, char *const *extra_args);
|
int clean(const char *cardname, char *const *extra_args);
|
||||||
|
int snd_card_clean_cfgdir(const char *cfgdir, int cardno);
|
||||||
|
|
||||||
/* utils */
|
/* utils */
|
||||||
|
|
||||||
|
|
|
@ -1743,7 +1743,7 @@ static int parse(struct space *space, const char *filename)
|
||||||
return err ? err : -abs(space->exit_code);
|
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 space *space;
|
||||||
struct snd_card_iterator iter;
|
struct snd_card_iterator iter;
|
||||||
|
@ -1752,6 +1752,12 @@ int init(const char *filename, int flags, const char *cardname)
|
||||||
sysfs_init();
|
sysfs_init();
|
||||||
err = snd_card_iterator_sinit(&iter, cardname);
|
err = snd_card_iterator_sinit(&iter, cardname);
|
||||||
while (snd_card_iterator_next(&iter)) {
|
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);
|
err = init_ucm(flags, iter.card);
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1618,7 +1618,8 @@ out:
|
||||||
return err;
|
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)
|
const char *cardname, int do_init)
|
||||||
{
|
{
|
||||||
int err, finalerr = 0, open_failed;
|
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) {
|
while ((cardname1 = snd_card_iterator_next(&iter)) != NULL) {
|
||||||
if (!do_init)
|
if (!do_init)
|
||||||
break;
|
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) {
|
if (err < 0) {
|
||||||
finalerr = err;
|
finalerr = err;
|
||||||
initfailed(iter.card, "init", 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);
|
init_ucm(initflags | FLAG_UCM_FBOOT, iter.card);
|
||||||
/* do a check if controls matches state file */
|
/* do a check if controls matches state file */
|
||||||
if (do_init && set_controls(iter.card, config, 0)) {
|
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) {
|
if (err < 0) {
|
||||||
initfailed(iter.card, "init", err);
|
initfailed(iter.card, "init", err);
|
||||||
finalerr = 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;
|
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