]> code.delx.au - pulseaudio/blobdiff - src/daemon/main.c
introduce default channel map in addition to the default sample spec
[pulseaudio] / src / daemon / main.c
index df8040b5cea6a40727821cf8a5f3d03f2f8cb7c1..d176f458af6917c2a2ec17a1e02ab65dd99035b9 100644 (file)
@@ -298,11 +298,15 @@ static void set_all_rlimits(const pa_daemon_conf *conf) {
 #ifdef RLIMIT_NPROC
     set_one_rlimit(&conf->rlimit_nproc, RLIMIT_NPROC, "RLIMIT_NPROC");
 #endif
+#ifdef RLIMIT_NOFILE
     set_one_rlimit(&conf->rlimit_nofile, RLIMIT_NOFILE, "RLIMIT_NOFILE");
+#endif
 #ifdef RLIMIT_MEMLOCK
     set_one_rlimit(&conf->rlimit_memlock, RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK");
 #endif
+#ifdef RLIMIT_AS
     set_one_rlimit(&conf->rlimit_as, RLIMIT_AS, "RLIMIT_AS");
+#endif
 #ifdef RLIMIT_LOCKS
     set_one_rlimit(&conf->rlimit_locks, RLIMIT_LOCKS, "RLIMIT_LOCKS");
 #endif
@@ -344,7 +348,6 @@ int main(int argc, char *argv[]) {
     pa_time_event *win32_timer;
     struct timeval win32_tv;
 #endif
-    char *lf = NULL;
     int autospawn_fd = -1;
     pa_bool_t autospawn_locked = FALSE;
 
@@ -365,8 +368,11 @@ int main(int argc, char *argv[]) {
          * value of $LD_BIND_NOW on initialization. */
 
         pa_set_env("LD_BIND_NOW", "1");
-        pa_assert_se(rp = pa_readlink("/proc/self/exe"));
-        pa_assert_se(execv(rp, argv) == 0);
+
+        if ((rp = pa_readlink("/proc/self/exe")))
+            pa_assert_se(execv(rp, argv) == 0);
+        else
+            pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");
     }
 #endif
 
@@ -435,6 +441,9 @@ int main(int argc, char *argv[]) {
     pa_log_debug("Started as real root: %s, suid root: %s", pa_yes_no(real_root), pa_yes_no(suid_root));
 
     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 */
@@ -477,12 +486,35 @@ int main(int argc, char *argv[]) {
              * let's give it up early */
 
             pa_drop_caps();
-
-            if (conf->high_priority || conf->realtime_scheduling)
-                pa_log_notice(_("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary privileges:\n"
-                                "We are not in group '"PA_REALTIME_GROUP"' and PolicyKit refuse to grant us privileges. Dropping SUID again.\n"
-                                "For enabling real-time scheduling please acquire the appropriate PolicyKit privileges, or become a member of '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."));
         }
+
+#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_notice(_("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 '"PA_REALTIME_GROUP"', 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 '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."));
+
+
+        if (!allow_realtime)
+            conf->realtime_scheduling = FALSE;
+
+        if (!allow_high_priority)
+            conf->high_priority = FALSE;
     }
 
 #ifdef HAVE_SYS_RESOURCE_H
@@ -496,12 +528,16 @@ int main(int argc, char *argv[]) {
     set_all_rlimits(conf);
 #endif
 
-    if (conf->high_priority && !pa_can_high_priority())
+    if (conf->high_priority && !pa_can_high_priority()) {
         pa_log_warn(_("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;
 
@@ -538,8 +574,10 @@ int main(int argc, char *argv[]) {
         }
     }
 
-    if (conf->realtime_scheduling && !pa_can_realtime())
+    if (conf->realtime_scheduling && !pa_can_realtime()) {
         pa_log_warn(_("Real-time scheduling enabled in configuration but not allowed by policy."));
+        conf->realtime_scheduling = FALSE;
+    }
 
     pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
 
@@ -789,6 +827,8 @@ int main(int argc, char *argv[]) {
     pa_log_debug(_("Running on host: %s"), s);
     pa_xfree(s);
 
+    pa_log_debug(_("Found %u CPUs."), pa_ncpus());
+
     pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
 
 #ifdef HAVE_VALGRIND_MEMCHECK_H
@@ -853,6 +893,8 @@ int main(int argc, char *argv[]) {
     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);
@@ -866,10 +908,10 @@ int main(int argc, char *argv[]) {
     }
 
     c->default_sample_spec = conf->default_sample_spec;
+    c->default_channel_map = conf->default_channel_map;
     c->default_n_fragments = conf->default_n_fragments;
     c->default_fragment_size_msec = conf->default_fragment_size_msec;
     c->exit_idle_time = conf->exit_idle_time;
-    c->module_idle_time = conf->module_idle_time;
     c->scache_idle_time = conf->scache_idle_time;
     c->resample_method = conf->resample_method;
     c->realtime_priority = conf->realtime_priority;
@@ -878,6 +920,7 @@ int main(int argc, char *argv[]) {
     c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
     c->running_as_daemon = !!conf->daemonize;
     c->disallow_exit = conf->disallow_exit;
+    c->flat_volumes = conf->flat_volumes;
 
     pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
     pa_signal_new(SIGINT, signal_callback, c);
@@ -931,11 +974,6 @@ int main(int argc, char *argv[]) {
         goto finish;
     }
 
-    if (c->default_sink_name && !pa_namereg_get(c, c->default_sink_name, PA_NAMEREG_SINK, TRUE) && conf->fail) {
-        pa_log_error(_("Default sink name (%s) does not exist in name register."), c->default_sink_name);
-        goto finish;
-    }
-
 #ifdef HAVE_FORK
     if (daemon_pipe[1] >= 0) {
         int ok = 0;
@@ -962,9 +1000,6 @@ finish:
         pa_autospawn_lock_done(FALSE);
     }
 
-    if (lf)
-        pa_xfree(lf);
-
 #ifdef OS_IS_WIN32
     if (win32_timer)
         pa_mainloop_get_api(mainloop)->time_free(win32_timer);