[pulseaudio-discuss] [RFC PATCH] inotify-wrapper: Quit daemon if pid file is removed

David Henningsson david.henningsson at canonical.com
Thu Apr 18 23:37:08 PDT 2013


On 04/17/2013 05:56 PM, David Henningsson wrote:
> XDG_RUNTIME_DIR is deleted on logout (according to xdg spec), and
> that's where we keep our pid file and native protocol socket.
>
> When these two files are deleted, it makes no sense to run anymore,
> so quit. Hanging around is not only sloppy, but can also be harmful:
> e g, if esd compat module is loaded, it will bind to the esd address.
> When a new pulseaudio process is created on next login of the same
> user, pulseaudio cannot start because the esd address is occupied.
>
> Buglink: https://bugs.launchpad.net/bugs/1167192
> Signed-off-by: David Henningsson <david.henningsson at canonical.com>
> ---
>
> This patch is probably unfinished, because I don't know how to deal with this
> on win32 systems etc. I had to come up with a quick fix for Ubuntu 13.04, and
> this is what I came up with.

I'm attaching second version of the patch. The below version could cause 
PA getting stuck in 100% CPU loop due to the event never being read out.


>
>   src/Makefile.am                 |    1 +
>   src/daemon/main.c               |   20 ++++++++-
>   src/pulsecore/inotify-wrapper.c |   93 +++++++++++++++++++++++++++++++++++++++
>   src/pulsecore/inotify-wrapper.h |   13 ++++++
>   src/pulsecore/pid.c             |    5 +++
>   src/pulsecore/pid.h             |    1 +
>   6 files changed, 131 insertions(+), 2 deletions(-)
>   create mode 100644 src/pulsecore/inotify-wrapper.c
>   create mode 100644 src/pulsecore/inotify-wrapper.h
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index a621a30..b8fb4b0 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -865,6 +865,7 @@ libpulsecore_ at PA_MAJORMINOR@_la_SOURCES = \
>   		pulsecore/core.c pulsecore/core.h \
>   		pulsecore/fdsem.c pulsecore/fdsem.h \
>   		pulsecore/hook-list.c pulsecore/hook-list.h \
> +		pulsecore/inotify-wrapper.c pulsecore/inotify-wrapper.h \
>   		pulsecore/ltdl-helper.c pulsecore/ltdl-helper.h \
>   		pulsecore/modargs.c pulsecore/modargs.h \
>   		pulsecore/modinfo.c pulsecore/modinfo.h \
> diff --git a/src/daemon/main.c b/src/daemon/main.c
> index c18524f..3016538 100644
> --- a/src/daemon/main.c
> +++ b/src/daemon/main.c
> @@ -74,6 +74,7 @@
>   #include <pulsecore/core-rtclock.h>
>   #include <pulsecore/core-scache.h>
>   #include <pulsecore/core.h>
> +#include <pulsecore/inotify-wrapper.h>
>   #include <pulsecore/module.h>
>   #include <pulsecore/cli-command.h>
>   #include <pulsecore/log.h>
> @@ -360,6 +361,15 @@ static char *check_configured_address(void) {
>       return default_server;
>   }
>
> +static bool valid_pid_file = false;
> +static void pid_file_deleted(void *userdata)
> +{
> +    pa_core *c = userdata;
> +    pa_log_info("Our pid file has been deleted (probably due to session logout), quitting...");
> +    valid_pid_file = false;
> +    pa_core_exit(c, true, 0);
> +}
> +
>   #ifdef HAVE_DBUS
>   static pa_dbus_connection *register_dbus_name(pa_core *c, DBusBusType bus, const char* name) {
>       DBusError error;
> @@ -402,7 +412,6 @@ int main(int argc, char *argv[]) {
>       char *s;
>       char *configured_address;
>       int r = 0, retval = 1, d = 0;
> -    pa_bool_t valid_pid_file = FALSE;
>       pa_bool_t ltdl_init = FALSE;
>       int passed_fd = -1;
>       const char *e;
> @@ -414,6 +423,7 @@ int main(int argc, char *argv[]) {
>       pa_time_event *win32_timer;
>       struct timeval win32_tv;
>   #endif
> +    pa_inotify *pid_monitor = NULL;
>       int autospawn_fd = -1;
>       pa_bool_t autospawn_locked = FALSE;
>   #ifdef HAVE_DBUS
> @@ -984,7 +994,7 @@ int main(int argc, char *argv[]) {
>               goto finish;
>           }
>
> -        valid_pid_file = TRUE;
> +        valid_pid_file = true;
>       }
>
>       pa_disable_sigpipe();
> @@ -1014,6 +1024,9 @@ int main(int argc, char *argv[]) {
>           goto finish;
>       }
>
> +    if (valid_pid_file)
> +        pid_monitor = pa_inotify_start(pa_pid_file_name(), c, pid_file_deleted, c);
> +
>       c->default_sample_spec = conf->default_sample_spec;
>       c->alternate_sample_rate = conf->alternate_sample_rate;
>       c->default_channel_map = conf->default_channel_map;
> @@ -1161,6 +1174,9 @@ finish:
>           pa_mainloop_get_api(mainloop)->time_free(win32_timer);
>   #endif
>
> +    if (pid_monitor)
> +        pa_inotify_stop(pid_monitor);
> +
>       if (c) {
>           /* Ensure all the modules/samples are unloaded when the core is still ref'ed,
>            * as unlink callback hooks in modules may need the core to be ref'ed */
> diff --git a/src/pulsecore/inotify-wrapper.c b/src/pulsecore/inotify-wrapper.c
> new file mode 100644
> index 0000000..00e36c6
> --- /dev/null
> +++ b/src/pulsecore/inotify-wrapper.c
> @@ -0,0 +1,93 @@
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <fcntl.h>
> +#include <sys/inotify.h>
> +#include <errno.h>
> +
> +#include "inotify-wrapper.h"
> +#include <pulse/mainloop.h>
> +#include <pulsecore/core-util.h>
> +#include <pulsecore/core-error.h>
> +
> +struct pa_inotify {
> +    char *filename;
> +    void *callback_data;
> +    pa_inotify_cb callback;
> +    int fd;
> +    pa_io_event *io_event;
> +    pa_core *core;
> +};
> +
> +
> +static void inotify_cb(
> +        pa_mainloop_api *a,
> +        pa_io_event *e,
> +        int fd,
> +        pa_io_event_flags_t events,
> +        void *userdata) {
> +
> +    pa_inotify *i = userdata;
> +    int pid_fd;
> +
> +    pa_assert(i);
> +
> +    pid_fd = pa_open_cloexec(i->filename, O_RDONLY
> +#ifdef O_NOFOLLOW
> +                       |O_NOFOLLOW
> +#endif
> +                       , S_IRUSR);
> +
> +    if (pid_fd < 0) {
> +        if (i->callback)
> +            i->callback(i->callback_data);
> +    } else
> +        pa_close(pid_fd);
> +}
> +
> +
> +pa_inotify *pa_inotify_start(const char *filename, void *userdata, pa_inotify_cb cb, pa_core *core) {
> +
> +    pa_inotify *i = pa_xnew0(pa_inotify, 1);
> +    pa_assert(i);
> +
> +    i->core = core;
> +    pa_core_ref(core);
> +
> +    i->filename = pa_xstrdup(filename);
> +    i->callback_data = userdata;
> +    i->callback = cb;
> +    i->fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
> +
> +    if (i->fd < 0) {
> +        pa_log("inotify_init1() failed: %s", pa_cstrerror(errno));
> +        pa_inotify_stop(i);
> +        return NULL;
> +    }
> +
> +    if (inotify_add_watch(i->fd, filename, IN_ATTRIB|IN_CLOSE_WRITE|IN_DELETE_SELF|IN_MOVE_SELF) < 0) {
> +        pa_log("inotify_add_watch() failed: %s", pa_cstrerror(errno));
> +        pa_inotify_stop(i);
> +        return NULL;
> +    }
> +
> +    pa_assert_se(i->io_event = core->mainloop->io_new(core->mainloop, i->fd, PA_IO_EVENT_INPUT, inotify_cb, i));
> +
> +    return i;
> +}
> +
> +
> +void pa_inotify_stop(pa_inotify *i) {
> +
> +    pa_assert(i);
> +
> +    if (i->io_event)
> +        i->core->mainloop->io_free(i->io_event);
> +    if (i->fd)
> +        pa_close(i->fd);
> +    pa_xfree(i->filename);
> +    if (i->core)
> +        pa_core_unref(i->core);
> +    pa_xfree(i);
> +}
> diff --git a/src/pulsecore/inotify-wrapper.h b/src/pulsecore/inotify-wrapper.h
> new file mode 100644
> index 0000000..e3b78d7
> --- /dev/null
> +++ b/src/pulsecore/inotify-wrapper.h
> @@ -0,0 +1,13 @@
> +#ifndef fooinotifywrapperhfoo
> +#define fooinotifywrapperhfoo
> +
> +#include <pulsecore/core.h>
> +
> +typedef struct pa_inotify pa_inotify;
> +
> +typedef void (*pa_inotify_cb)(void *userdata);
> +
> +pa_inotify *pa_inotify_start(const char *filename, void *userdata, pa_inotify_cb cb, pa_core *c);
> +void pa_inotify_stop(pa_inotify *i);
> +
> +#endif
> diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c
> index 588349b..3ef3981 100644
> --- a/src/pulsecore/pid.c
> +++ b/src/pulsecore/pid.c
> @@ -183,6 +183,11 @@ static int proc_name_ours(pid_t pid, const char *procname) {
>
>   }
>
> +char *pa_pid_file_name()
> +{
> +    return pa_runtime_path("pid");
> +}
> +
>   /* Create a new PID file for the current process. */
>   int pa_pid_file_create(const char *procname) {
>       int fd = -1;
> diff --git a/src/pulsecore/pid.h b/src/pulsecore/pid.h
> index d8458bf..507f75e 100644
> --- a/src/pulsecore/pid.h
> +++ b/src/pulsecore/pid.h
> @@ -22,6 +22,7 @@
>     USA.
>   ***/
>
> +char *pa_pid_file_name(void);
>   int pa_pid_file_create(const char *procname);
>   int pa_pid_file_remove(void);
>   int pa_pid_file_check_running(pid_t *pid, const char *procname);
>



-- 
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-inotify-wrapper-Quit-daemon-if-pid-file-is-removed.patch
Type: text/x-patch
Size: 8031 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/pulseaudio-discuss/attachments/20130419/3f72b562/attachment.bin>


More information about the pulseaudio-discuss mailing list