180
178
if (!(pw = getpwnam(PA_SYSTEM_USER))) {
181
pa_log("Failed to find user '%s'.", PA_SYSTEM_USER);
179
pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER);
185
183
if (!(gr = getgrnam(PA_SYSTEM_GROUP))) {
186
pa_log("Failed to find group '%s'.", PA_SYSTEM_GROUP);
184
pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP);
190
pa_log_info("Found user '%s' (UID %lu) and group '%s' (GID %lu).",
188
pa_log_info(_("Found user '%s' (UID %lu) and group '%s' (GID %lu)."),
191
189
PA_SYSTEM_USER, (unsigned long) pw->pw_uid,
192
190
PA_SYSTEM_GROUP, (unsigned long) gr->gr_gid);
194
192
if (pw->pw_gid != gr->gr_gid) {
195
pa_log("GID of user '%s' and of group '%s' don't match.", PA_SYSTEM_USER, PA_SYSTEM_GROUP);
193
pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER, PA_SYSTEM_GROUP);
199
197
if (strcmp(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH) != 0)
200
pa_log_warn("Warning: home directory of user '%s' is not '%s', ignoring.", PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
198
pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
202
200
if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid) < 0) {
203
pa_log("Failed to create '%s': %s", PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
201
pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
205
if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) {
206
pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH, pa_cstrerror(errno));
210
/* We don't create the config dir here, because we don't need to write to it */
207
212
if (initgroups(PA_SYSTEM_USER, gr->gr_gid) != 0) {
208
pa_log("Failed to change group list: %s", pa_cstrerror(errno));
213
pa_log(_("Failed to change group list: %s"), pa_cstrerror(errno));
240
pa_log("Failed to change UID: %s", pa_cstrerror(errno));
245
pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno));
244
set_env("USER", PA_SYSTEM_USER);
245
set_env("USERNAME", PA_SYSTEM_USER);
246
set_env("LOGNAME", PA_SYSTEM_USER);
247
set_env("HOME", PA_SYSTEM_RUNTIME_PATH);
249
pa_set_env("USER", PA_SYSTEM_USER);
250
pa_set_env("USERNAME", PA_SYSTEM_USER);
251
pa_set_env("LOGNAME", PA_SYSTEM_USER);
252
pa_set_env("HOME", PA_SYSTEM_RUNTIME_PATH);
249
254
/* Relevant for pa_runtime_path() */
250
set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH);
251
set_env("PULSE_CONFIG_PATH", PA_SYSTEM_RUNTIME_PATH);
255
pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH);
256
pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH);
257
pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH);
253
pa_log_info("Successfully dropped root privileges.");
259
pa_log_info(_("Successfully dropped root privileges."));
303
292
static void set_all_rlimits(const pa_daemon_conf *conf) {
304
set_one_rlimit(&conf->rlimit_as, RLIMIT_AS, "RLIMIT_AS");
305
set_one_rlimit(&conf->rlimit_core, RLIMIT_CORE, "RLIMIT_CORE");
293
set_one_rlimit(&conf->rlimit_fsize, RLIMIT_FSIZE, "RLIMIT_FSIZE");
306
294
set_one_rlimit(&conf->rlimit_data, RLIMIT_DATA, "RLIMIT_DATA");
307
set_one_rlimit(&conf->rlimit_fsize, RLIMIT_FSIZE, "RLIMIT_FSIZE");
308
set_one_rlimit(&conf->rlimit_nofile, RLIMIT_NOFILE, "RLIMIT_NOFILE");
309
295
set_one_rlimit(&conf->rlimit_stack, RLIMIT_STACK, "RLIMIT_STACK");
296
set_one_rlimit(&conf->rlimit_core, RLIMIT_CORE, "RLIMIT_CORE");
297
set_one_rlimit(&conf->rlimit_rss, RLIMIT_RSS, "RLIMIT_RSS");
310
298
#ifdef RLIMIT_NPROC
311
299
set_one_rlimit(&conf->rlimit_nproc, RLIMIT_NPROC, "RLIMIT_NPROC");
301
set_one_rlimit(&conf->rlimit_nofile, RLIMIT_NOFILE, "RLIMIT_NOFILE");
313
302
#ifdef RLIMIT_MEMLOCK
314
303
set_one_rlimit(&conf->rlimit_memlock, RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK");
305
set_one_rlimit(&conf->rlimit_as, RLIMIT_AS, "RLIMIT_AS");
307
set_one_rlimit(&conf->rlimit_locks, RLIMIT_LOCKS, "RLIMIT_LOCKS");
309
#ifdef RLIMIT_SIGPENDING
310
set_one_rlimit(&conf->rlimit_sigpending, RLIMIT_SIGPENDING, "RLIMIT_SIGPENDING");
312
#ifdef RLIMIT_MSGQUEUE
313
set_one_rlimit(&conf->rlimit_msgqueue, RLIMIT_MSGQUEUE, "RLIMIT_MSGQUEUE");
316
315
#ifdef RLIMIT_NICE
317
316
set_one_rlimit(&conf->rlimit_nice, RLIMIT_NICE, "RLIMIT_NICE");
319
318
#ifdef RLIMIT_RTPRIO
320
319
set_one_rlimit(&conf->rlimit_rtprio, RLIMIT_RTPRIO, "RLIMIT_RTPRIO");
322
set_one_rlimit(&conf->rlimit_rttime, RLIMIT_RTTIME, "RLIMIT_RTTIME");
404
424
if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
405
pa_log("Failed to parse command line.");
425
pa_log(_("Failed to parse command line."));
409
429
pa_log_set_maximal_level(conf->log_level);
410
430
pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target, NULL);
413
/* Ok, we're suid root, so let's better not enable high prio
414
* or RT by default */
416
allow_high_priority = allow_realtime = FALSE;
432
pa_log_debug("Started as real root: %s, suid root: %s", pa_yes_no(real_root), pa_yes_no(suid_root));
434
if (!real_root && pa_have_caps()) {
435
pa_bool_t allow_high_priority = FALSE, allow_realtime = FALSE;
437
/* Let's better not enable high prio or RT by default */
439
if (conf->high_priority && !allow_high_priority) {
440
if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
441
pa_log_info(_("We're in the group '%s', allowing high-priority scheduling."), PA_REALTIME_GROUP);
442
allow_high_priority = TRUE;
446
if (conf->realtime_scheduling && !allow_realtime) {
447
if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
448
pa_log_info(_("We're in the group '%s', allowing real-time scheduling."), PA_REALTIME_GROUP);
449
allow_realtime = TRUE;
418
453
#ifdef HAVE_POLKIT
419
if (conf->high_priority) {
454
if (conf->high_priority && !allow_high_priority) {
420
455
if (pa_polkit_check("org.pulseaudio.acquire-high-priority") > 0) {
421
pa_log_info("PolicyKit grants us acquire-high-priority privilige.");
456
pa_log_info(_("PolicyKit grants us acquire-high-priority privilege."));
422
457
allow_high_priority = TRUE;
424
pa_log_info("PolicyKit refuses acquire-high-priority privilige.");
459
pa_log_info(_("PolicyKit refuses acquire-high-priority privilege."));
427
if (conf->realtime_scheduling) {
462
if (conf->realtime_scheduling && !allow_realtime) {
428
463
if (pa_polkit_check("org.pulseaudio.acquire-real-time") > 0) {
429
pa_log_info("PolicyKit grants us acquire-real-time privilige.");
464
pa_log_info(_("PolicyKit grants us acquire-real-time privilege."));
430
465
allow_realtime = TRUE;
432
pa_log_info("PolicyKit refuses acquire-real-time privilige.");
467
pa_log_info(_("PolicyKit refuses acquire-real-time privilege."));
436
if ((conf->high_priority || conf->realtime_scheduling) && pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
437
pa_log_info("We're in the group '"PA_REALTIME_GROUP"', allowing real-time and high-priority scheduling.");
438
allow_realtime = conf->realtime_scheduling;
439
allow_high_priority = conf->high_priority;
442
471
if (!allow_high_priority && !allow_realtime) {
444
473
/* OK, there's no further need to keep CAP_NICE. Hence
445
474
* let's give it up early */
449
suid_root = real_root = FALSE;
451
478
if (conf->high_priority || conf->realtime_scheduling)
452
pa_log_notice("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n"
453
"We are not in group '"PA_REALTIME_GROUP"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
454
"For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user.");
479
pa_log_notice(_("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n"
480
"We are not in group '"PA_REALTIME_GROUP"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
481
"For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."));
459
/* OK, we're a normal user, so let's allow the user evrything
460
* he asks for, it's now the kernel's job to enforce limits,
461
* not ours anymore */
462
allow_high_priority = allow_realtime = TRUE;
465
if (conf->high_priority && !allow_high_priority) {
466
pa_log_info("High-priority scheduling enabled in configuration but now allowed by policy. Disabling forcibly.");
467
conf->high_priority = FALSE;
470
if (conf->realtime_scheduling && !allow_realtime) {
471
pa_log_info("Real-time scheduling enabled in configuration but now allowed by policy. Disabling forcibly.");
472
conf->realtime_scheduling = FALSE;
475
if (conf->high_priority && conf->cmd == PA_CMD_DAEMON)
485
#ifdef HAVE_SYS_RESOURCE_H
486
/* Reset resource limits. If we are run as root (for system mode)
487
* this might end up increasing the limits, which is intended
488
* behaviour. For all other cases, i.e. started as normal user, or
489
* SUID root at this point we should have no CAP_SYS_RESOURCE and
490
* increasing the limits thus should fail. Which is, too, intended
493
set_all_rlimits(conf);
496
if (conf->high_priority && !pa_can_high_priority())
497
pa_log_warn(_("High-priority scheduling enabled in configuration but not allowed by policy."));
499
if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START))
476
500
pa_raise_priority(conf->nice_level);
502
if (!real_root && pa_have_caps()) {
481
drop = conf->cmd != PA_CMD_DAEMON || !conf->realtime_scheduling;
505
drop = (conf->cmd != PA_CMD_DAEMON && conf->cmd != PA_CMD_START) || !conf->realtime_scheduling;
483
507
#ifdef RLIMIT_RTPRIO
486
510
/* At this point we still have CAP_NICE if we were loaded
487
511
* SUID root. If possible let's acquire RLIMIT_RTPRIO
488
512
* instead and give CAP_NICE up. */
490
const pa_rlimit rl = { 9, TRUE };
492
if (set_one_rlimit(&rl, RLIMIT_RTPRIO, "RLIMIT_RTPRIO") >= 0) {
493
pa_log_info("Successfully increased RLIMIT_RTPRIO, giving up CAP_NICE.");
496
pa_log_warn("RLIMIT_RTPRIO failed: %s", pa_cstrerror(errno));
514
if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0) {
516
if (rl.rlim_cur >= 9)
519
rl.rlim_max = rl.rlim_cur = 9;
521
if (setrlimit(RLIMIT_RTPRIO, &rl) >= 0) {
522
pa_log_info(_("Successfully increased RLIMIT_RTPRIO"));
525
pa_log_warn(_("RLIMIT_RTPRIO failed: %s"), pa_cstrerror(errno));
532
pa_log_info(_("Giving up CAP_NICE"));
503
suid_root = real_root = FALSE;
538
if (conf->realtime_scheduling && !pa_can_realtime())
539
pa_log_warn(_("Real-time scheduling enabled in configuration but not allowed by policy."));
541
pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
507
543
LTDL_SET_PRELOADED_SYMBOLS();
509
545
ltdl_init = TRUE;
587
pa_assert(conf->cmd == PA_CMD_DAEMON);
623
pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
590
626
if (real_root && !conf->system_instance)
591
pa_log_warn("This program is not intended to be run as root (unless --system is specified).");
627
pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
592
628
else if (!real_root && conf->system_instance) {
593
pa_log("Root priviliges required.");
629
pa_log(_("Root priviliges required."));
633
if (conf->cmd == PA_CMD_START && conf->system_instance) {
634
pa_log(_("--start not supported for system instances."));
638
if (conf->system_instance && !conf->disallow_exit)
639
pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
641
if (conf->system_instance && !conf->disallow_module_loading)
642
pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
644
if (conf->system_instance && !conf->disable_shm) {
645
pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
646
conf->disable_shm = TRUE;
649
if (conf->system_instance && conf->exit_idle_time > 0) {
650
pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
651
conf->exit_idle_time = 0;
654
if (conf->cmd == PA_CMD_START) {
655
/* If we shall start PA only when it is not running yet, we
656
* first take the autospawn lock to make things
659
if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
660
pa_log("Failed to initialize autospawn lock");
664
if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
665
pa_log("Failed to acquire autospawn lock");
669
autospawn_locked = TRUE;
597
672
if (conf->daemonize) {
601
676
if (pa_stdio_acquire() < 0) {
602
pa_log("Failed to acquire stdio.");
677
pa_log(_("Failed to acquire stdio."));
607
682
if (pipe(daemon_pipe) < 0) {
608
pa_log("Failed to create pipe.");
683
pa_log(_("pipe failed: %s"), pa_cstrerror(errno));
612
687
if ((child = fork()) < 0) {
613
pa_log("fork() failed: %s", pa_cstrerror(errno));
688
pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
617
692
if (child != 0) {
620
696
pa_assert_se(pa_close(daemon_pipe[1]) == 0);
621
697
daemon_pipe[1] = -1;
623
if (pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL) != sizeof(retval)) {
624
pa_log("read() failed: %s", pa_cstrerror(errno));
699
if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
702
pa_log(_("read() failed: %s"), pa_cstrerror(errno));
629
pa_log("daemon startup failed.");
708
pa_log(_("Daemon startup failed."));
631
pa_log_info("daemon startup successful.");
710
pa_log_info(_("Daemon startup successful."));
715
if (autospawn_fd >= 0) {
716
/* The lock file is unlocked from the parent, so we need
717
* to close it in the child */
719
pa_autospawn_lock_release();
720
pa_autospawn_lock_done(TRUE);
722
autospawn_locked = FALSE;
636
726
pa_assert_se(pa_close(daemon_pipe[0]) == 0);
637
727
daemon_pipe[0] = -1;
770
pa_set_env("PULSE_INTERNAL", "1");
680
771
pa_assert_se(chdir("/") == 0);
683
if (conf->system_instance) {
774
if (conf->system_instance)
684
775
if (change_user() < 0)
686
} else if (create_runtime_dir() < 0)
778
pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
780
pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
781
pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
782
pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
784
s = pa_uname_string();
785
pa_log_debug(_("Running on host: %s"), s);
788
pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
790
#ifdef HAVE_VALGRIND_MEMCHECK_H
791
pa_log_debug(_("Compiled with Valgrind support: yes"));
793
pa_log_debug(_("Compiled with Valgrind support: no"));
796
pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
799
pa_log_debug(_("Optimized build: yes"));
801
pa_log_debug(_("Optimized build: no"));
804
if (!(s = pa_machine_id())) {
805
pa_log(_("Failed to get machine ID"));
808
pa_log_info(_("Machine ID is %s."), s);
811
if (!(s = pa_get_runtime_dir()))
813
pa_log_info(_("Using runtime directory %s."), s);
816
if (!(s = pa_get_state_dir()))
818
pa_log_info(_("Using state directory %s."), s);
821
pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
689
823
if (conf->use_pid_file) {
690
if (pa_pid_file_create() < 0) {
691
pa_log("pa_pid_file_create() failed.");
694
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
826
if ((z = pa_pid_file_create("pulseaudio")) != 0) {
828
if (conf->cmd == PA_CMD_START && z > 0) {
829
/* If we are already running and with are run in
830
* --start mode, then let's return this as success. */
836
pa_log(_("pa_pid_file_create() failed."));
840
valid_pid_file = TRUE;
702
#ifdef HAVE_SYS_RESOURCE_H
703
set_all_rlimits(conf);
707
844
signal(SIGPIPE, SIG_IGN);
710
pa_log_info("This is PulseAudio " PACKAGE_VERSION);
711
pa_log_info("Page size is %lu bytes", (unsigned long) PA_PAGE_SIZE);
713
847
if (pa_rtclock_hrtimer())
714
pa_log_info("Fresh high-resolution timers available! Bon appetit!");
848
pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
716
pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!");
850
pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
719
853
/* Valgrind uses SIGRTMAX. To easy debugging we don't use it here */
779
918
c->disallow_module_loading = !!conf->disallow_module_loading;
781
920
if (r < 0 && conf->fail) {
782
pa_log("Failed to initialize daemon.");
785
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
787
} else if (!c->modules || pa_idxset_size(c->modules) == 0) {
788
pa_log("daemon startup without any loaded modules, refusing to work.");
791
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
797
if (c->default_sink_name &&
798
pa_namereg_get(c, c->default_sink_name, PA_NAMEREG_SINK, 1) == NULL) {
799
pa_log_error("%s : Default sink name (%s) does not exist in name register.", __FILE__, c->default_sink_name);
800
retval = !!conf->fail;
805
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
809
pa_log_info("Daemon startup complete.");
810
if (pa_mainloop_run(mainloop, &retval) < 0)
812
pa_log_info("Daemon shutdown initiated.");
921
pa_log(_("Failed to initialize daemon."));
925
if (!c->modules || pa_idxset_size(c->modules) == 0) {
926
pa_log(_("Daemon startup without any loaded modules, refusing to work."));
930
if (c->default_sink_name && !pa_namereg_get(c, c->default_sink_name, PA_NAMEREG_SINK, TRUE) && conf->fail) {
931
pa_log_error(_("Default sink name (%s) does not exist in name register."), c->default_sink_name);
936
if (daemon_pipe[1] >= 0) {
938
pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
939
pa_close(daemon_pipe[1]);
944
pa_log_info(_("Daemon startup complete."));
947
if (pa_mainloop_run(mainloop, &retval) < 0)
950
pa_log_info(_("Daemon shutdown initiated."));
954
if (autospawn_fd >= 0) {
955
if (autospawn_locked)
956
pa_autospawn_lock_release();
958
pa_autospawn_lock_done(FALSE);
816
964
#ifdef OS_IS_WIN32
817
pa_mainloop_get_api(mainloop)->time_free(timer);
966
pa_mainloop_get_api(mainloop)->time_free(win32_timer);
971
pa_log_info(_("Daemon terminated."));
822
974
if (!conf->no_cpu_limit)
823
975
pa_cpu_limit_done();
825
977
pa_signal_done();
827
pa_log_info("Daemon terminated.");
980
if (daemon_pipe[1] >= 0)
981
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
983
pa_close_pipe(daemon_pipe);
832
987
pa_mainloop_free(mainloop);