mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-10 13:29:58 -05:00
Merge branch 'master' into dbus-work
Conflicts: src/daemon/daemon-conf.c src/daemon/daemon-conf.h src/daemon/main.c src/pulsecore/dbus-util.h
This commit is contained in:
commit
0bc538b08c
207 changed files with 33341 additions and 18718 deletions
|
|
@ -39,6 +39,7 @@
|
|||
#ifdef HAVE_SYS_CAPABILITY_H
|
||||
#include <sys/capability.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PRCTL_H
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
|
@ -51,12 +52,13 @@ int setresgid(gid_t r, gid_t e, gid_t s);
|
|||
int setresuid(uid_t r, uid_t e, uid_t s);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETUID
|
||||
|
||||
/* Drop root rights when called SUID root */
|
||||
void pa_drop_root(void) {
|
||||
uid_t uid = getuid();
|
||||
|
||||
#ifdef HAVE_GETUID
|
||||
uid_t uid;
|
||||
|
||||
uid = getuid();
|
||||
if (uid == 0 || geteuid() != 0)
|
||||
return;
|
||||
|
||||
|
|
@ -73,90 +75,19 @@ void pa_drop_root(void) {
|
|||
|
||||
pa_assert_se(getuid() == uid);
|
||||
pa_assert_se(geteuid() == uid);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void pa_drop_root(void) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_CAPABILITY_H) && defined(HAVE_SYS_PRCTL_H)
|
||||
|
||||
/* Limit permitted capabilities set to CAPSYS_NICE */
|
||||
void pa_limit_caps(void) {
|
||||
cap_t caps;
|
||||
cap_value_t nice_cap = CAP_SYS_NICE;
|
||||
|
||||
pa_assert_se(caps = cap_init());
|
||||
pa_assert_se(cap_clear(caps) == 0);
|
||||
pa_assert_se(cap_set_flag(caps, CAP_EFFECTIVE, 1, &nice_cap, CAP_SET) == 0);
|
||||
pa_assert_se(cap_set_flag(caps, CAP_PERMITTED, 1, &nice_cap, CAP_SET) == 0);
|
||||
|
||||
if (cap_set_proc(caps) < 0)
|
||||
/* Hmm, so we couldn't limit our caps, which probably means we
|
||||
* hadn't any in the first place, so let's just make sure of
|
||||
* that */
|
||||
pa_drop_caps();
|
||||
else
|
||||
pa_log_info(_("Limited capabilities successfully to CAP_SYS_NICE."));
|
||||
|
||||
pa_assert_se(cap_free(caps) == 0);
|
||||
|
||||
pa_assert_se(prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == 0);
|
||||
}
|
||||
|
||||
/* Drop all capabilities, effectively becoming a normal user */
|
||||
void pa_drop_caps(void) {
|
||||
cap_t caps;
|
||||
|
||||
#ifndef __OPTIMIZE__
|
||||
/* Valgrind doesn't not know set_caps, so we bypass it here -- but
|
||||
* only in development builds.*/
|
||||
|
||||
if (pa_in_valgrind() && !pa_have_caps())
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PRCTL_H
|
||||
pa_assert_se(prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) == 0);
|
||||
|
||||
pa_assert_se(caps = cap_init());
|
||||
pa_assert_se(cap_clear(caps) == 0);
|
||||
pa_assert_se(cap_set_proc(caps) == 0);
|
||||
pa_assert_se(cap_free(caps) == 0);
|
||||
|
||||
pa_assert_se(!pa_have_caps());
|
||||
}
|
||||
|
||||
pa_bool_t pa_have_caps(void) {
|
||||
cap_t caps;
|
||||
cap_flag_value_t flag = CAP_CLEAR;
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
pa_assert_se(caps = cap_get_proc());
|
||||
#else
|
||||
if (!(caps = cap_get_proc()))
|
||||
return FALSE;
|
||||
#endif
|
||||
pa_assert_se(cap_get_flag(caps, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0);
|
||||
pa_assert_se(cap_free(caps) == 0);
|
||||
|
||||
return flag == CAP_SET;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* NOOPs in case capabilities are not available. */
|
||||
void pa_limit_caps(void) {
|
||||
}
|
||||
|
||||
void pa_drop_caps(void) {
|
||||
pa_drop_root();
|
||||
}
|
||||
|
||||
pa_bool_t pa_have_caps(void) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_CAPABILITY_H
|
||||
{
|
||||
cap_t caps;
|
||||
pa_assert_se(caps = cap_init());
|
||||
pa_assert_se(cap_clear(caps) == 0);
|
||||
pa_assert_se(cap_set_proc(caps) == 0);
|
||||
pa_assert_se(cap_free(caps) == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,5 @@
|
|||
#include <pulsecore/macro.h>
|
||||
|
||||
void pa_drop_root(void);
|
||||
void pa_drop_caps(void);
|
||||
void pa_limit_caps(void);
|
||||
pa_bool_t pa_have_caps(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <pulse/xmalloc.h>
|
||||
#include <pulse/i18n.h>
|
||||
#include <pulse/util.h>
|
||||
|
||||
#include <pulsecore/core-util.h>
|
||||
#include <pulsecore/strbuf.h>
|
||||
|
|
@ -109,15 +110,8 @@ static const struct option long_options[] = {
|
|||
};
|
||||
|
||||
void pa_cmdline_help(const char *argv0) {
|
||||
const char *e;
|
||||
|
||||
pa_assert(argv0);
|
||||
|
||||
if ((e = strrchr(argv0, '/')))
|
||||
e++;
|
||||
else
|
||||
e = argv0;
|
||||
|
||||
printf(_("%s [options]\n\n"
|
||||
"COMMANDS:\n"
|
||||
" -h, --help Show this help\n"
|
||||
|
|
@ -172,7 +166,8 @@ void pa_cmdline_help(const char *argv0) {
|
|||
" -C Open a command line on the running TTY\n"
|
||||
" after startup\n\n"
|
||||
|
||||
" -n Don't load default script file\n"), e);
|
||||
" -n Don't load default script file\n"),
|
||||
pa_path_get_filename(argv0));
|
||||
}
|
||||
|
||||
int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d) {
|
||||
|
|
|
|||
|
|
@ -24,13 +24,14 @@
|
|||
#endif
|
||||
|
||||
#include <pulse/error.h>
|
||||
#include <pulse/rtclock.h>
|
||||
#include <pulse/timeval.h>
|
||||
|
||||
#include <pulsecore/core-rtclock.h>
|
||||
#include <pulsecore/core-util.h>
|
||||
#include <pulsecore/core-error.h>
|
||||
#include <pulsecore/log.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/rtclock.h>
|
||||
|
||||
#include "cpulimit.h"
|
||||
|
||||
|
|
@ -125,7 +126,7 @@ static void signal_handler(int sig) {
|
|||
char t[256];
|
||||
#endif
|
||||
|
||||
now = pa_rtclock_usec();
|
||||
now = pa_rtclock_now();
|
||||
elapsed = now - last_time;
|
||||
|
||||
#ifdef PRINT_CPU_LOAD
|
||||
|
|
@ -184,7 +185,7 @@ int pa_cpu_limit_init(pa_mainloop_api *m) {
|
|||
pa_assert(the_pipe[1] == -1);
|
||||
pa_assert(!installed);
|
||||
|
||||
last_time = pa_rtclock_usec();
|
||||
last_time = pa_rtclock_now();
|
||||
|
||||
/* Prepare the main loop pipe */
|
||||
if (pipe(the_pipe) < 0) {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ static const pa_daemon_conf default_conf = {
|
|||
.fail = TRUE,
|
||||
.high_priority = TRUE,
|
||||
.nice_level = -11,
|
||||
.realtime_scheduling = FALSE,
|
||||
.realtime_scheduling = TRUE,
|
||||
.realtime_priority = 5, /* Half of JACK's default rtprio */
|
||||
.disallow_module_loading = FALSE,
|
||||
.disallow_exit = FALSE,
|
||||
|
|
@ -88,6 +88,7 @@ static const pa_daemon_conf default_conf = {
|
|||
#endif
|
||||
.no_cpu_limit = FALSE,
|
||||
.disable_shm = FALSE,
|
||||
.lock_memory = FALSE,
|
||||
.default_n_fragments = 4,
|
||||
.default_fragment_size_msec = 25,
|
||||
.default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 },
|
||||
|
|
@ -484,6 +485,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
|
|||
{ "no-cpu-limit", pa_config_parse_bool, &c->no_cpu_limit, NULL },
|
||||
{ "disable-shm", pa_config_parse_bool, &c->disable_shm, NULL },
|
||||
{ "flat-volumes", pa_config_parse_bool, &c->flat_volumes, NULL },
|
||||
{ "lock-memory", pa_config_parse_bool, &c->lock_memory, NULL },
|
||||
{ "exit-idle-time", pa_config_parse_int, &c->exit_idle_time, NULL },
|
||||
{ "scache-idle-time", pa_config_parse_int, &c->scache_idle_time, NULL },
|
||||
{ "realtime-priority", parse_rtprio, c, NULL },
|
||||
|
|
@ -633,23 +635,22 @@ FILE *pa_daemon_conf_open_default_script_file(pa_daemon_conf *c) {
|
|||
return f;
|
||||
}
|
||||
|
||||
|
||||
static const char* const log_level_to_string[] = {
|
||||
[PA_LOG_DEBUG] = "debug",
|
||||
[PA_LOG_INFO] = "info",
|
||||
[PA_LOG_NOTICE] = "notice",
|
||||
[PA_LOG_WARN] = "warning",
|
||||
[PA_LOG_ERROR] = "error"
|
||||
};
|
||||
|
||||
static const char* const server_type_to_string[] = {
|
||||
[PA_SERVER_TYPE_UNSET] = "!!UNSET!!",
|
||||
[PA_SERVER_TYPE_USER] = "user",
|
||||
[PA_SERVER_TYPE_SYSTEM] = "system",
|
||||
[PA_SERVER_TYPE_NONE] = "none"
|
||||
};
|
||||
|
||||
char *pa_daemon_conf_dump(pa_daemon_conf *c) {
|
||||
static const char* const log_level_to_string[] = {
|
||||
[PA_LOG_DEBUG] = "debug",
|
||||
[PA_LOG_INFO] = "info",
|
||||
[PA_LOG_NOTICE] = "notice",
|
||||
[PA_LOG_WARN] = "warning",
|
||||
[PA_LOG_ERROR] = "error"
|
||||
};
|
||||
|
||||
static const char* const server_type_to_string[] = {
|
||||
[PA_SERVER_TYPE_UNSET] = "!!UNSET!!",
|
||||
[PA_SERVER_TYPE_USER] = "user",
|
||||
[PA_SERVER_TYPE_SYSTEM] = "system",
|
||||
[PA_SERVER_TYPE_NONE] = "none"
|
||||
};
|
||||
|
||||
pa_strbuf *s;
|
||||
char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
|
||||
|
||||
|
|
@ -678,6 +679,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
|
|||
pa_strbuf_printf(s, "no-cpu-limit = %s\n", pa_yes_no(c->no_cpu_limit));
|
||||
pa_strbuf_printf(s, "disable-shm = %s\n", pa_yes_no(c->disable_shm));
|
||||
pa_strbuf_printf(s, "flat-volumes = %s\n", pa_yes_no(c->flat_volumes));
|
||||
pa_strbuf_printf(s, "lock-memory = %s\n", pa_yes_no(c->lock_memory));
|
||||
pa_strbuf_printf(s, "exit-idle-time = %i\n", c->exit_idle_time);
|
||||
pa_strbuf_printf(s, "scache-idle-time = %i\n", c->scache_idle_time);
|
||||
pa_strbuf_printf(s, "dl-search-path = %s\n", pa_strempty(c->dl_search_path));
|
||||
|
|
|
|||
|
|
@ -74,7 +74,8 @@ typedef struct pa_daemon_conf {
|
|||
disallow_exit,
|
||||
log_meta,
|
||||
log_time,
|
||||
flat_volumes;
|
||||
flat_volumes,
|
||||
lock_memory;
|
||||
pa_server_type_t local_server_type;
|
||||
int exit_idle_time,
|
||||
scache_idle_time,
|
||||
|
|
|
|||
|
|
@ -28,15 +28,16 @@
|
|||
; local-server-type = user
|
||||
; disable-shm = no
|
||||
; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
|
||||
; lock-memory = no
|
||||
; no-cpu-limit = no
|
||||
|
||||
; high-priority = yes
|
||||
; nice-level = -11
|
||||
|
||||
; realtime-scheduling = no
|
||||
; realtime-scheduling = yes
|
||||
; realtime-priority = 5
|
||||
|
||||
; exit-idle-time = 20
|
||||
; module-idle-time = 20
|
||||
; scache-idle-time = 20
|
||||
|
||||
; dl-search-path = (depends on architecture)
|
||||
|
|
@ -56,8 +57,6 @@
|
|||
|
||||
; flat-volumes = yes
|
||||
|
||||
; no-cpu-limit = no
|
||||
|
||||
; rlimit-fsize = -1
|
||||
; rlimit-data = -1
|
||||
; rlimit-stack = -1
|
||||
|
|
|
|||
|
|
@ -49,11 +49,11 @@ load-module module-augment-properties
|
|||
#load-module module-pipe-sink
|
||||
|
||||
### Automatically load driver modules depending on the hardware available
|
||||
.ifexists module-hal-detect@PA_SOEXT@
|
||||
load-module module-hal-detect
|
||||
.ifexists module-udev-detect@PA_SOEXT@
|
||||
load-module module-udev-detect
|
||||
.else
|
||||
### Alternatively use the static hardware detection module (for systems that
|
||||
### lack HAL support)
|
||||
### lack udev support)
|
||||
load-module module-detect
|
||||
.endif
|
||||
|
||||
|
|
@ -103,6 +103,9 @@ load-module module-rescue-streams
|
|||
### Make sure we always have a sink around, even if it is a null sink.
|
||||
load-module module-always-sink
|
||||
|
||||
### Honour intended role device property
|
||||
load-module module-intended-roles
|
||||
|
||||
### Automatically suspend sinks/sources that become idle for too long
|
||||
load-module module-suspend-on-idle
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@
|
|||
|
||||
#include <liboil/liboil.h>
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
|
@ -69,6 +73,7 @@
|
|||
#include <pulsecore/lock-autospawn.h>
|
||||
#include <pulsecore/winsock.h>
|
||||
#include <pulsecore/core-error.h>
|
||||
#include <pulsecore/core-rtclock.h>
|
||||
#include <pulsecore/core.h>
|
||||
#include <pulsecore/memblock.h>
|
||||
#include <pulsecore/module.h>
|
||||
|
|
@ -80,8 +85,6 @@
|
|||
#include <pulsecore/pid.h>
|
||||
#include <pulsecore/namereg.h>
|
||||
#include <pulsecore/random.h>
|
||||
#include <pulsecore/rtsig.h>
|
||||
#include <pulsecore/rtclock.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/mutex.h>
|
||||
#include <pulsecore/thread.h>
|
||||
|
|
@ -98,7 +101,6 @@
|
|||
#include "dumpmodules.h"
|
||||
#include "caps.h"
|
||||
#include "ltdl-bind-now.h"
|
||||
#include "polkit.h"
|
||||
#include "server-lookup.h"
|
||||
|
||||
#ifdef HAVE_LIBWRAP
|
||||
|
|
@ -130,7 +132,7 @@ static void message_cb(pa_mainloop_api*a, pa_time_event*e, const struct timeval
|
|||
}
|
||||
|
||||
pa_timeval_add(pa_gettimeofday(&tvnext), 100000);
|
||||
a->time_restart(e, &tvnext);
|
||||
a->rtclock_time_restart(e, &tvnext);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -376,9 +378,7 @@ int main(int argc, char *argv[]) {
|
|||
pa_mainloop *mainloop = NULL;
|
||||
char *s;
|
||||
int r = 0, retval = 1, d = 0;
|
||||
pa_bool_t suid_root, real_root;
|
||||
pa_bool_t valid_pid_file = FALSE;
|
||||
gid_t gid = (gid_t) -1;
|
||||
pa_bool_t ltdl_init = FALSE;
|
||||
int passed_fd = -1;
|
||||
const char *e;
|
||||
|
|
@ -424,30 +424,6 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETUID
|
||||
real_root = getuid() == 0;
|
||||
suid_root = !real_root && geteuid() == 0;
|
||||
#else
|
||||
real_root = FALSE;
|
||||
suid_root = FALSE;
|
||||
#endif
|
||||
|
||||
if (!real_root) {
|
||||
/* Drop all capabilities except CAP_SYS_NICE */
|
||||
pa_limit_caps();
|
||||
|
||||
/* Drop privileges, but keep CAP_SYS_NICE */
|
||||
pa_drop_root();
|
||||
|
||||
/* After dropping root, the effective set is reset, hence,
|
||||
* let's raise it again */
|
||||
pa_limit_caps();
|
||||
|
||||
/* When capabilities are not supported we will not be able to
|
||||
* acquire RT sched anymore. But yes, that's the way it is. It
|
||||
* is just too risky tun let PA run as root all the time. */
|
||||
}
|
||||
|
||||
if ((e = getenv("PULSE_PASSED_FD"))) {
|
||||
passed_fd = atoi(e);
|
||||
|
||||
|
|
@ -455,15 +431,14 @@ int main(int argc, char *argv[]) {
|
|||
passed_fd = -1;
|
||||
}
|
||||
|
||||
/* We might be autospawned, in which case have no idea in which
|
||||
* context we have been started. Let's cleanup our execution
|
||||
* context as good as possible */
|
||||
pa_drop_root();
|
||||
pa_close_all(passed_fd, -1);
|
||||
|
||||
pa_reset_sigs(-1);
|
||||
pa_unblock_sigs(-1);
|
||||
|
||||
/* At this point, we are a normal user, possibly with CAP_NICE if
|
||||
* we were started SUID. If we are started as normal root, than we
|
||||
* still are normal root. */
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
pa_init_i18n();
|
||||
|
||||
|
|
@ -506,7 +481,7 @@ int main(int argc, char *argv[]) {
|
|||
pa_assert_not_reached();
|
||||
}
|
||||
|
||||
start_server = conf->local_server_type == PA_SERVER_TYPE_USER || (real_root && conf->local_server_type == PA_SERVER_TYPE_SYSTEM);
|
||||
start_server = conf->local_server_type == PA_SERVER_TYPE_USER || (getuid() == 0 && conf->local_server_type == PA_SERVER_TYPE_SYSTEM);
|
||||
|
||||
if (!start_server && conf->local_server_type == PA_SERVER_TYPE_SYSTEM) {
|
||||
pa_log_notice(_("System mode refused for non-root user. Only starting the D-Bus server lookup service."));
|
||||
|
|
@ -514,165 +489,6 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
#endif
|
||||
|
||||
pa_log_debug("Started as real root: %s, suid root: %s", pa_yes_no(real_root), pa_yes_no(suid_root));
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
/* XXX: Uhh, goto programming... as if this wasn't hard enough to follow
|
||||
* already. But if we won't start the full server, we want to just skip all
|
||||
* the capability stuff. */
|
||||
if (!start_server) {
|
||||
if (!real_root && pa_have_caps())
|
||||
pa_drop_caps();
|
||||
goto after_caps_setup;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!real_root && pa_have_caps()) {
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
struct rlimit rl;
|
||||
#endif
|
||||
pa_bool_t allow_high_priority = FALSE, allow_realtime = FALSE;
|
||||
|
||||
/* Let's better not enable high prio or RT by default */
|
||||
|
||||
if (conf->high_priority && !allow_high_priority) {
|
||||
if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
|
||||
pa_log_info(_("We're in the group '%s', allowing high-priority scheduling."), PA_REALTIME_GROUP);
|
||||
allow_high_priority = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->realtime_scheduling && !allow_realtime) {
|
||||
if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
|
||||
pa_log_info(_("We're in the group '%s', allowing real-time scheduling."), PA_REALTIME_GROUP);
|
||||
allow_realtime = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLKIT
|
||||
if (conf->high_priority && !allow_high_priority) {
|
||||
if (pa_polkit_check("org.pulseaudio.acquire-high-priority") > 0) {
|
||||
pa_log_info(_("PolicyKit grants us acquire-high-priority privilege."));
|
||||
allow_high_priority = TRUE;
|
||||
} else
|
||||
pa_log_info(_("PolicyKit refuses acquire-high-priority privilege."));
|
||||
}
|
||||
|
||||
if (conf->realtime_scheduling && !allow_realtime) {
|
||||
if (pa_polkit_check("org.pulseaudio.acquire-real-time") > 0) {
|
||||
pa_log_info(_("PolicyKit grants us acquire-real-time privilege."));
|
||||
allow_realtime = TRUE;
|
||||
} else
|
||||
pa_log_info(_("PolicyKit refuses acquire-real-time privilege."));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!allow_high_priority && !allow_realtime) {
|
||||
|
||||
/* OK, there's no further need to keep CAP_NICE. Hence
|
||||
* let's give it up early */
|
||||
|
||||
pa_drop_caps();
|
||||
}
|
||||
|
||||
#ifdef RLIMIT_RTPRIO
|
||||
if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0)
|
||||
if (rl.rlim_cur > 0) {
|
||||
pa_log_info("RLIMIT_RTPRIO is set to %u, allowing real-time scheduling.", (unsigned) rl.rlim_cur);
|
||||
allow_realtime = TRUE;
|
||||
}
|
||||
#endif
|
||||
#ifdef RLIMIT_NICE
|
||||
if (getrlimit(RLIMIT_NICE, &rl) >= 0)
|
||||
if (rl.rlim_cur > 20 ) {
|
||||
pa_log_info("RLIMIT_NICE is set to %u, allowing high-priority scheduling.", (unsigned) rl.rlim_cur);
|
||||
allow_high_priority = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((conf->high_priority && !allow_high_priority) ||
|
||||
(conf->realtime_scheduling && !allow_realtime))
|
||||
pa_log_info(_("Called SUID root and real-time and/or high-priority scheduling was requested in the configuration. However, we lack the necessary privileges:\n"
|
||||
"We are not in group '%s', PolicyKit refuse to grant us the requested privileges and we have no increase RLIMIT_NICE/RLIMIT_RTPRIO resource limits.\n"
|
||||
"For enabling real-time/high-priority scheduling please acquire the appropriate PolicyKit privileges, or become a member of '%s', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."),
|
||||
PA_REALTIME_GROUP, PA_REALTIME_GROUP);
|
||||
|
||||
|
||||
if (!allow_realtime)
|
||||
conf->realtime_scheduling = FALSE;
|
||||
|
||||
if (!allow_high_priority)
|
||||
conf->high_priority = FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
/* Reset resource limits. If we are run as root (for system mode)
|
||||
* this might end up increasing the limits, which is intended
|
||||
* behaviour. For all other cases, i.e. started as normal user, or
|
||||
* SUID root at this point we should have no CAP_SYS_RESOURCE and
|
||||
* increasing the limits thus should fail. Which is, too, intended
|
||||
* behaviour */
|
||||
|
||||
set_all_rlimits(conf);
|
||||
#endif
|
||||
|
||||
if (conf->high_priority && !pa_can_high_priority()) {
|
||||
pa_log_info(_("High-priority scheduling enabled in configuration but not allowed by policy."));
|
||||
conf->high_priority = FALSE;
|
||||
}
|
||||
|
||||
if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START))
|
||||
pa_raise_priority(conf->nice_level);
|
||||
|
||||
pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
|
||||
|
||||
if (!real_root && pa_have_caps()) {
|
||||
pa_bool_t drop;
|
||||
|
||||
drop = (conf->cmd != PA_CMD_DAEMON && conf->cmd != PA_CMD_START) || !conf->realtime_scheduling;
|
||||
|
||||
#ifdef RLIMIT_RTPRIO
|
||||
if (!drop) {
|
||||
struct rlimit rl;
|
||||
/* At this point we still have CAP_NICE if we were loaded
|
||||
* SUID root. If possible let's acquire RLIMIT_RTPRIO
|
||||
* instead and give CAP_NICE up. */
|
||||
|
||||
if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0) {
|
||||
|
||||
if (rl.rlim_cur >= 9)
|
||||
drop = TRUE;
|
||||
else {
|
||||
rl.rlim_max = rl.rlim_cur = 9;
|
||||
|
||||
if (setrlimit(RLIMIT_RTPRIO, &rl) >= 0) {
|
||||
pa_log_info(_("Successfully increased RLIMIT_RTPRIO"));
|
||||
drop = TRUE;
|
||||
} else
|
||||
pa_log_warn(_("RLIMIT_RTPRIO failed: %s"), pa_cstrerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (drop) {
|
||||
pa_log_info(_("Giving up CAP_NICE"));
|
||||
pa_drop_caps();
|
||||
suid_root = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->realtime_scheduling && !pa_can_realtime()) {
|
||||
pa_log_info(_("Real-time scheduling enabled in configuration but not allowed by policy."));
|
||||
conf->realtime_scheduling = FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
after_caps_setup:
|
||||
#endif
|
||||
|
||||
pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
|
||||
|
||||
LTDL_SET_PRELOADED_SYMBOLS();
|
||||
pa_ltdl_init();
|
||||
ltdl_init = TRUE;
|
||||
|
|
@ -757,10 +573,10 @@ after_caps_setup:
|
|||
pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
|
||||
}
|
||||
|
||||
if (real_root && !conf->system_instance)
|
||||
if (getuid() == 0 && !conf->system_instance)
|
||||
pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
|
||||
#ifndef HAVE_DBUS /* A similar, only a notice worthy check was done earlier, if D-Bus is enabled. */
|
||||
else if (!real_root && conf->system_instance) {
|
||||
else if (getuid() != 0 && conf->system_instance) {
|
||||
pa_log(_("Root privileges required."));
|
||||
goto finish;
|
||||
}
|
||||
|
|
@ -907,6 +723,13 @@ after_caps_setup:
|
|||
pa_assert_se(chdir("/") == 0);
|
||||
umask(0022);
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
set_all_rlimits(conf);
|
||||
#endif
|
||||
pa_rtclock_hrtimer_enable();
|
||||
|
||||
pa_raise_priority(conf->nice_level);
|
||||
|
||||
if (conf->system_instance)
|
||||
if (change_user() < 0)
|
||||
goto finish;
|
||||
|
|
@ -955,8 +778,8 @@ after_caps_setup:
|
|||
pa_xfree(s);
|
||||
|
||||
if ((s = pa_session_id())) {
|
||||
pa_log_info(_("Session ID is %s."), s);
|
||||
pa_xfree(s);
|
||||
pa_log_info(_("Session ID is %s."), s);
|
||||
pa_xfree(s);
|
||||
}
|
||||
|
||||
if (!(s = pa_get_runtime_dir()))
|
||||
|
|
@ -971,6 +794,11 @@ after_caps_setup:
|
|||
|
||||
pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
|
||||
|
||||
if (pa_in_system_mode())
|
||||
pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
|
||||
"If you do it nonetheless then it's your own fault if things don't work as expected.\n"
|
||||
"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."));
|
||||
|
||||
if (conf->use_pid_file) {
|
||||
int z;
|
||||
|
||||
|
|
@ -998,12 +826,16 @@ after_caps_setup:
|
|||
else
|
||||
pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
|
||||
|
||||
pa_rtclock_hrtimer_enable();
|
||||
|
||||
#ifdef SIGRTMIN
|
||||
/* Valgrind uses SIGRTMAX. To easy debugging we don't use it here */
|
||||
pa_rtsig_configure(SIGRTMIN, SIGRTMAX-1);
|
||||
if (conf->lock_memory) {
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
if (mlockall(MCL_FUTURE) < 0)
|
||||
pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno));
|
||||
else
|
||||
pa_log_info("Sucessfully locked process into memory.");
|
||||
#else
|
||||
pa_log_warn("Memory locking requested but not supported on platform.");
|
||||
#endif
|
||||
}
|
||||
|
||||
pa_memtrap_install();
|
||||
|
||||
|
|
@ -1028,7 +860,9 @@ after_caps_setup:
|
|||
c->running_as_daemon = !!conf->daemonize;
|
||||
c->disallow_exit = conf->disallow_exit;
|
||||
c->flat_volumes = conf->flat_volumes;
|
||||
#ifdef HAVE_DBUS
|
||||
c->server_type = conf->local_server_type;
|
||||
#endif
|
||||
|
||||
pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
|
||||
pa_signal_new(SIGINT, signal_callback, c);
|
||||
|
|
@ -1044,7 +878,7 @@ after_caps_setup:
|
|||
#endif
|
||||
|
||||
#ifdef OS_IS_WIN32
|
||||
win32_timer = pa_mainloop_get_api(mainloop)->time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
|
||||
win32_timer = pa_mainloop_get_api(mainloop)->rtclock_time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
|
||||
#endif
|
||||
|
||||
oil_init();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue