~ubuntu-branches/ubuntu/oneiric/pulseaudio/oneiric

« back to all changes in this revision

Viewing changes to src/daemon/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2007-12-04 00:56:08 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20071204005608-y1xqvcu45g1yxtlu
Tags: 0.9.8-1ubuntu1
"Hail our new PulseAudio overlords (part two)."

* Merge from Debian unstable.
* Ubuntu-specific changes:
  - debian/control:
    + Don't build-depend on libjack0.100.0-dev or build jack module
      packages,
    + Update pulseaudio's Recommends and Suggests to accomodate
      existing promoted main packages,
    + Explicitly mention pasuspender in pulseaudio-utils's long
      description,
    + Add Vcs-Bzr URI,
    + Adhere to DebianMaintainerField;
  - debian/rules: Use multiuser for update-rc.d;
  - debian/patches/series: Retain the exclusion of
    0001-Set-ESD-socket-to-tmp-.esd-socket-to-match-up-with.patch.
* Dropped Ubuntu-specific change (absorbed into Debian source):
  debian/patches/0002-Double-esound-maximum-sample-size.patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: main.c 1976 2007-10-29 15:33:07Z lennart $ */
 
1
/* $Id: main.c 2067 2007-11-21 01:30:40Z lennart $ */
2
2
 
3
3
/***
4
4
  This file is part of PulseAudio.
94
94
#include "dumpmodules.h"
95
95
#include "caps.h"
96
96
#include "ltdl-bind-now.h"
 
97
#include "polkit.h"
97
98
 
98
99
#ifdef HAVE_LIBWRAP
99
100
/* Only one instance of these variables */
281
282
 
282
283
#ifdef HAVE_SYS_RESOURCE_H
283
284
 
284
 
static void set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
 
285
static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
285
286
    struct rlimit rl;
286
287
    pa_assert(r);
287
288
 
288
289
    if (!r->is_set)
289
 
        return;
 
290
        return 0;
290
291
 
291
292
    rl.rlim_cur = rl.rlim_max = r->value;
292
293
 
293
 
    if (setrlimit(resource, &rl) < 0)
 
294
    if (setrlimit(resource, &rl) < 0) {
294
295
        pa_log_warn("setrlimit(%s, (%u, %u)) failed: %s", name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno));
 
296
        return -1;
 
297
    }
 
298
 
 
299
    return 0;
295
300
}
296
301
 
297
302
static void set_all_rlimits(const pa_daemon_conf *conf) {
307
312
#ifdef RLIMIT_MEMLOCK
308
313
    set_one_rlimit(&conf->rlimit_memlock, RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK");
309
314
#endif
 
315
#ifdef RLIMIT_NICE
 
316
    set_one_rlimit(&conf->rlimit_nice, RLIMIT_NICE, "RLIMIT_NICE");
 
317
#endif
 
318
#ifdef RLIMIT_RTPRIO
 
319
    set_one_rlimit(&conf->rlimit_rtprio, RLIMIT_RTPRIO, "RLIMIT_RTPRIO");
 
320
#endif
310
321
}
311
322
#endif
312
323
 
318
329
    char *s;
319
330
    int r = 0, retval = 1, d = 0;
320
331
    int daemon_pipe[2] = { -1, -1 };
321
 
    int suid_root, real_root;
 
332
    pa_bool_t suid_root, real_root;
322
333
    int valid_pid_file = 0;
323
334
    gid_t gid = (gid_t) -1;
 
335
    pa_bool_t allow_realtime, allow_high_priority;
324
336
 
325
337
#ifdef OS_IS_WIN32
326
338
    pa_time_event *timer;
351
363
    real_root = getuid() == 0;
352
364
    suid_root = !real_root && geteuid() == 0;
353
365
#else
354
 
    real_root = 0;
355
 
    suid_root = 0;
 
366
    real_root = FALSE;
 
367
    suid_root = FALSE;
356
368
#endif
357
369
 
358
370
    if (suid_root) {
371
383
         * is just too risky tun let PA run as root all the time. */
372
384
    }
373
385
 
 
386
    /* At this point, we are a normal user, possibly with CAP_NICE if
 
387
     * we were started SUID. If we are started as normal root, than we
 
388
     * still are normal root. */
 
389
 
374
390
    setlocale(LC_ALL, "");
375
 
 
376
 
    if (suid_root && (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) <= 0)) {
377
 
        pa_log_info("Warning: Called SUID root, but not in group '"PA_REALTIME_GROUP"'. "
378
 
                    "For enabling real-time scheduling please become a member of '"PA_REALTIME_GROUP"' , or increase the RLIMIT_RTPRIO user limit.");
379
 
        pa_drop_caps();
380
 
        pa_drop_root();
381
 
        suid_root = real_root = 0;
382
 
    }
383
 
 
384
 
    LTDL_SET_PRELOADED_SYMBOLS();
385
 
 
386
 
    pa_ltdl_init();
387
 
 
388
 
#ifdef OS_IS_WIN32
389
 
    {
390
 
        WSADATA data;
391
 
        WSAStartup(MAKEWORD(2, 0), &data);
392
 
    }
393
 
#endif
394
 
 
395
 
    pa_random_seed();
396
 
 
 
391
    pa_log_set_maximal_level(PA_LOG_INFO);
397
392
    pa_log_set_ident("pulseaudio");
398
393
 
399
394
    conf = pa_daemon_conf_new();
405
400
        goto finish;
406
401
 
407
402
    if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
408
 
        pa_log("failed to parse command line.");
 
403
        pa_log("Failed to parse command line.");
409
404
        goto finish;
410
405
    }
411
406
 
412
407
    pa_log_set_maximal_level(conf->log_level);
413
408
    pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target, NULL);
414
409
 
 
410
    if (suid_root) {
 
411
        /* Ok, we're suid root, so let's better not enable high prio
 
412
         * or RT by default */
 
413
 
 
414
        allow_high_priority = allow_realtime = FALSE;
 
415
 
 
416
#ifdef HAVE_POLKIT
 
417
        if (conf->high_priority) {
 
418
            if (pa_polkit_check("org.pulseaudio.acquire-high-priority") > 0) {
 
419
                pa_log_info("PolicyKit grants us acquire-high-priority privilige.");
 
420
                allow_high_priority = TRUE;
 
421
            } else
 
422
                pa_log_info("PolicyKit refuses acquire-high-priority privilige.");
 
423
        }
 
424
 
 
425
        if (conf->realtime_scheduling) {
 
426
            if (pa_polkit_check("org.pulseaudio.acquire-real-time") > 0) {
 
427
                pa_log_info("PolicyKit grants us acquire-real-time privilige.");
 
428
                allow_realtime = TRUE;
 
429
            } else
 
430
                pa_log_info("PolicyKit refuses acquire-real-time privilige.");
 
431
        }
 
432
#endif
 
433
 
 
434
        if ((conf->high_priority || conf->realtime_scheduling) && pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
 
435
            pa_log_info("We're in the group '"PA_REALTIME_GROUP"', allowing real-time and high-priority scheduling.");
 
436
            allow_realtime = conf->realtime_scheduling;
 
437
            allow_high_priority = conf->high_priority;
 
438
        }
 
439
 
 
440
        if (!allow_high_priority && !allow_realtime) {
 
441
 
 
442
            /* OK, there's no further need to keep CAP_NICE. Hence
 
443
             * let's give it up early */
 
444
 
 
445
            pa_drop_caps();
 
446
            pa_drop_root();
 
447
            suid_root = real_root = FALSE;
 
448
 
 
449
            if (conf->high_priority || conf->realtime_scheduling)
 
450
                pa_log_notice("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n"
 
451
                              "We are not in group '"PA_REALTIME_GROUP"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
 
452
                              "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.");
 
453
        }
 
454
 
 
455
    } else {
 
456
 
 
457
        /* OK, we're a normal user, so let's allow the user evrything
 
458
         * he asks for, it's now the kernel's job to enforce limits,
 
459
         * not ours anymore */
 
460
        allow_high_priority = allow_realtime = TRUE;
 
461
    }
 
462
 
 
463
    if (conf->high_priority && !allow_high_priority) {
 
464
        pa_log_info("High-priority scheduling enabled in configuration but now allowed by policy. Disabling forcibly.");
 
465
        conf->high_priority = FALSE;
 
466
    }
 
467
 
 
468
    if (conf->realtime_scheduling && !allow_realtime) {
 
469
        pa_log_info("Real-time scheduling enabled in configuration but now allowed by policy. Disabling forcibly.");
 
470
        conf->realtime_scheduling = FALSE;
 
471
    }
 
472
 
415
473
    if (conf->high_priority && conf->cmd == PA_CMD_DAEMON)
416
 
        pa_raise_priority();
417
 
 
418
 
    if (suid_root && (conf->cmd != PA_CMD_DAEMON || !conf->high_priority)) {
419
 
        pa_drop_caps();
420
 
        pa_drop_root();
 
474
        pa_raise_priority(conf->nice_level);
 
475
 
 
476
    if (suid_root) {
 
477
        pa_bool_t drop;
 
478
 
 
479
        drop = conf->cmd != PA_CMD_DAEMON || !conf->realtime_scheduling;
 
480
 
 
481
#ifdef RLIMIT_RTPRIO
 
482
        if (!drop) {
 
483
 
 
484
            /* At this point we still have CAP_NICE if we were loaded
 
485
             * SUID root. If possible let's acquire RLIMIT_RTPRIO
 
486
             * instead and give CAP_NICE up. */
 
487
 
 
488
            const pa_rlimit rl = { 9, TRUE };
 
489
 
 
490
            if (set_one_rlimit(&rl, RLIMIT_RTPRIO, "RLIMIT_RTPRIO") >= 0) {
 
491
                pa_log_info("Successfully increased RLIMIT_RTPRIO, giving up CAP_NICE.");
 
492
                drop = TRUE;
 
493
            } else
 
494
                pa_log_warn("RLIMIT_RTPRIO failed: %s", pa_cstrerror(errno));
 
495
        }
 
496
#endif
 
497
 
 
498
        if (drop)  {
 
499
            pa_drop_caps();
 
500
            pa_drop_root();
 
501
            suid_root = real_root = FALSE;
 
502
        }
421
503
    }
422
504
 
 
505
    LTDL_SET_PRELOADED_SYMBOLS();
 
506
    pa_ltdl_init();
 
507
 
423
508
    if (conf->dl_search_path)
424
509
        lt_dlsetsearchpath(conf->dl_search_path);
425
510
 
 
511
#ifdef OS_IS_WIN32
 
512
    {
 
513
        WSADATA data;
 
514
        WSAStartup(MAKEWORD(2, 0), &data);
 
515
    }
 
516
#endif
 
517
 
 
518
    pa_random_seed();
 
519
 
426
520
    switch (conf->cmd) {
427
521
        case PA_CMD_DUMP_MODULES:
428
522
            pa_dump_modules(conf, argc-d, argv+d);
460
554
        case PA_CMD_CHECK: {
461
555
            pid_t pid;
462
556
 
463
 
            if (pa_pid_file_check_running(&pid) < 0) {
464
 
                pa_log_info("daemon not running");
465
 
            } else {
466
 
                pa_log_info("daemon running as PID %u", pid);
 
557
            if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
 
558
                pa_log_info("Daemon not running");
 
559
            else {
 
560
                pa_log_info("Daemon running as PID %u", pid);
467
561
                retval = 0;
468
562
            }
469
563
 
472
566
        }
473
567
        case PA_CMD_KILL:
474
568
 
475
 
            if (pa_pid_file_kill(SIGINT, NULL) < 0)
476
 
                pa_log("failed to kill daemon.");
 
569
            if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
 
570
                pa_log("Failed to kill daemon.");
477
571
            else
478
572
                retval = 0;
479
573
 
490
584
            pa_assert(conf->cmd == PA_CMD_DAEMON);
491
585
    }
492
586
 
493
 
    if (real_root && !conf->system_instance) {
 
587
    if (real_root && !conf->system_instance)
494
588
        pa_log_warn("This program is not intended to be run as root (unless --system is specified).");
495
 
    } else if (!real_root && conf->system_instance) {
 
589
    else if (!real_root && conf->system_instance) {
496
590
        pa_log("Root priviliges required.");
497
591
        goto finish;
498
592
    }
630
724
    }
631
725
 
632
726
    c->is_system_instance = !!conf->system_instance;
633
 
    c->high_priority = !!conf->high_priority;
634
727
    c->default_sample_spec = conf->default_sample_spec;
635
728
    c->default_n_fragments = conf->default_n_fragments;
636
729
    c->default_fragment_size_msec = conf->default_fragment_size_msec;
637
 
    c->disallow_module_loading = conf->disallow_module_loading;
638
730
    c->exit_idle_time = conf->exit_idle_time;
639
731
    c->module_idle_time = conf->module_idle_time;
640
732
    c->scache_idle_time = conf->scache_idle_time;
641
733
    c->resample_method = conf->resample_method;
 
734
    c->realtime_priority = conf->realtime_priority;
 
735
    c->realtime_scheduling = !!conf->realtime_scheduling;
 
736
    c->disable_remixing = !!conf->disable_remixing;
642
737
 
643
738
    pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
644
739
    pa_signal_new(SIGINT, signal_callback, c);
659
754
#endif
660
755
 
661
756
    if (conf->daemonize)
662
 
        c->running_as_daemon = 1;
 
757
        c->running_as_daemon = TRUE;
663
758
 
664
759
    oil_init();
665
760
 
675
770
    pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
676
771
    pa_xfree(s);
677
772
 
 
773
    /* We completed the initial module loading, so let's disable it
 
774
     * from now on, if requested */
 
775
    c->disallow_module_loading = !!conf->disallow_module_loading;
 
776
 
678
777
    if (r < 0 && conf->fail) {
679
778
        pa_log("failed to initialize daemon.");
680
779
#ifdef HAVE_FORK