From e5396fed3f33cb80699561b55090dc3ba7c95de8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 9 Oct 2011 16:36:45 +0200 Subject: test_virtualization: do not try to compare id in !virt context --- src/condition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/condition.c b/src/condition.c index e978656772..07624c841d 100644 --- a/src/condition.c +++ b/src/condition.c @@ -148,7 +148,7 @@ static bool test_virtualization(const char *parameter) { return true; /* Finally compare id */ - return streq(parameter, id); + return v > 0 && streq(parameter, id); } static bool test_security(const char *parameter) { -- cgit v1.2.3-54-g00ecf From 10d975f54c88223fb8762a226fd011ec3f30f2eb Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Wed, 5 Oct 2011 22:30:49 +0200 Subject: tmpfiles: fix file descriptor leak Detected by "cppcheck" --- src/tmpfiles.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/tmpfiles.c b/src/tmpfiles.c index a6b8f859aa..21bf44d3a4 100644 --- a/src/tmpfiles.c +++ b/src/tmpfiles.c @@ -157,6 +157,7 @@ static void load_unix_sockets(void) { } } + fclose(f); return; fail: -- cgit v1.2.3-54-g00ecf From 678abaf91e2308f02fb679c2dc2679a3b6a5b8be Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Wed, 5 Oct 2011 22:31:41 +0200 Subject: util: fix close() call on wrong variable Detected by "cppcheck" (actually it detected a file descriptor leak) --- src/util.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/util.c b/src/util.c index 7977ee46c5..e46606dabb 100644 --- a/src/util.c +++ b/src/util.c @@ -2307,8 +2307,10 @@ int chvt(int vt) { 0 }; - if (ioctl(fd, TIOCLINUX, tiocl) < 0) - return -errno; + if (ioctl(fd, TIOCLINUX, tiocl) < 0) { + r = -errno; + goto fail; + } vt = tiocl[0] <= 0 ? 1 : tiocl[0]; } @@ -2316,7 +2318,8 @@ int chvt(int vt) { if (ioctl(fd, VT_ACTIVATE, vt) < 0) r = -errno; - close_nointr_nofail(r); +fail: + close_nointr_nofail(fd); return r; } -- cgit v1.2.3-54-g00ecf From 53273a6aefeb27f62c439e25f28c26859023c7df Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 11 Oct 2011 01:43:58 +0200 Subject: readahead: lower max file size for readahead https://bugs.freedesktop.org/show_bug.cgi?id=41336 --- src/readahead-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/readahead-common.h b/src/readahead-common.h index 167df316d9..9547ad201c 100644 --- a/src/readahead-common.h +++ b/src/readahead-common.h @@ -27,7 +27,7 @@ #include "macro.h" -#define READAHEAD_FILE_SIZE_MAX (128*1024*1024) +#define READAHEAD_FILE_SIZE_MAX (10*1024*1024) int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st); -- cgit v1.2.3-54-g00ecf From b5dc29c079bd8dbeb5cb86e6b1a5906bfeb49e90 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 27 Sep 2011 20:45:51 +0200 Subject: hostname-setup: Frugalware switched to /etc/hostname --- src/hostname-setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/hostname-setup.c b/src/hostname-setup.c index 57db9fbf7c..7216b75c8a 100644 --- a/src/hostname-setup.c +++ b/src/hostname-setup.c @@ -32,7 +32,7 @@ #if defined(TARGET_FEDORA) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO) #define FILENAME "/etc/sysconfig/network" -#elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE) || defined(TARGET_FRUGALWARE) +#elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE) #define FILENAME "/etc/HOSTNAME" #elif defined(TARGET_ARCH) #define FILENAME "/etc/rc.conf" @@ -114,7 +114,7 @@ finish: fclose(f); return r; -#elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE) || defined(TARGET_FRUGALWARE) +#elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE) return read_and_strip_hostname(FILENAME, hn); #else return -ENOENT; -- cgit v1.2.3-54-g00ecf From e8fbe35df8e498ce4dc3d9f1010755538e041cf3 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Mon, 26 Sep 2011 09:25:27 -0400 Subject: sd-login.h: correct spelling mistakes in comments --- src/sd-login.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sd-login.h b/src/sd-login.h index 7102eb88e0..0cb0bf06bb 100644 --- a/src/sd-login.h +++ b/src/sd-login.h @@ -83,7 +83,7 @@ int sd_session_get_seat(const char *session, char **seat); int sd_seat_get_active(const char *seat, char **session, uid_t *uid); /* Return sessions and users on seat. Returns number of sessions as - * return value. If sessions is NULL returs only the number of + * return value. If sessions is NULL returns only the number of * sessions. */ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uid, unsigned *n_uids); @@ -94,7 +94,7 @@ int sd_seat_can_multi_session(const char *seat); * seats is NULL only returns number of seats. */ int sd_get_seats(char ***seats); -/* Get all sessions, store in *seessions. Returns the number of +/* Get all sessions, store in *sessions. Returns the number of * sessions. If sessions is NULL only returns number of sessions. */ int sd_get_sessions(char ***sessions); -- cgit v1.2.3-54-g00ecf From 21e557edcc1894ce4eeb70b71ca16e82e95bc0df Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Oct 2011 03:33:53 +0200 Subject: units: introduce local-fs-pre.target and remote-fs-pre.target This hook target enables services to order themselves between network.target and remote mounts, which is needed for GFS2 and similar systems. --- Makefile.am | 2 ++ man/systemd.special.xml.in | 26 ++++++++++++++++++++++++++ src/mount.c | 6 ++++-- src/special.h | 2 ++ 4 files changed, 34 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/Makefile.am b/Makefile.am index f4a17aa7f5..3a98c5b061 100644 --- a/Makefile.am +++ b/Makefile.am @@ -337,7 +337,9 @@ dist_systemunit_DATA = \ units/halt.target \ units/kexec.target \ units/local-fs.target \ + units/local-fs-pre.target \ units/remote-fs.target \ + units/remote-fs-pre.target \ units/cryptsetup.target \ units/network.target \ units/nss-lookup.target \ diff --git a/man/systemd.special.xml.in b/man/systemd.special.xml.in index 218754051e..116a43ccfb 100644 --- a/man/systemd.special.xml.in +++ b/man/systemd.special.xml.in @@ -59,6 +59,7 @@ halt.target, kbrequest.target, local-fs.target, + local-fs-pre.target, mail-transfer-agent.target, multi-user.target, network.target, @@ -66,6 +67,7 @@ poweroff.target, reboot.target, remote-fs.target, + remote-fs-pre.target, rescue.target, rpcbind.target, runlevel2.target, @@ -260,6 +262,18 @@ facility. + + local-fs-pre.target + + This target unit is + automatically ordered before + all local mount points marked + with + (see above). It can be used to + execute certain units before + all local mounts. + + mail-transfer-agent.target @@ -373,6 +387,18 @@ facility. + + remote-fs-pre.target + + This target unit is + automatically ordered before + all remote mount points marked + with + (see above). It can be used to + execute certain units before + all remote mounts. + + rescue.target diff --git a/src/mount.c b/src/mount.c index 2fc799a6ed..ef953f0d0a 100644 --- a/src/mount.c +++ b/src/mount.c @@ -357,9 +357,11 @@ static int mount_add_fstab_links(Mount *m) { if (mount_is_network(p)) { target = SPECIAL_REMOTE_FS_TARGET; - after = SPECIAL_NETWORK_TARGET; - } else + after = SPECIAL_REMOTE_FS_PRE_TARGET; + } else { target = SPECIAL_LOCAL_FS_TARGET; + after = SPECIAL_LOCAL_FS_PRE_TARGET; + } if (!path_equal(m->where, "/")) if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0) diff --git a/src/special.h b/src/special.h index 614e53ca1b..3fe34c955c 100644 --- a/src/special.h +++ b/src/special.h @@ -45,7 +45,9 @@ #define SPECIAL_SYSINIT_TARGET "sysinit.target" #define SPECIAL_SOCKETS_TARGET "sockets.target" #define SPECIAL_LOCAL_FS_TARGET "local-fs.target" /* LSB's $local_fs */ +#define SPECIAL_LOCAL_FS_PRE_TARGET "local-fs-pre.target" #define SPECIAL_REMOTE_FS_TARGET "remote-fs.target" /* LSB's $remote_fs */ +#define SPECIAL_REMOTE_FS_PRE_TARGET "remote-fs-pre.target" #define SPECIAL_SWAP_TARGET "swap.target" #define SPECIAL_BASIC_TARGET "basic.target" -- cgit v1.2.3-54-g00ecf From a724d2ed799a8985193ba70c5c3e76f621815e10 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Oct 2011 04:23:35 +0200 Subject: timedate: fall back to /etc/sysconfig/clock on Fedora, for compatibility with legacy --- TODO | 6 +----- src/timedated.c | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/TODO b/TODO index f662104b2c..aa51332c05 100644 --- a/TODO +++ b/TODO @@ -17,21 +17,17 @@ Bugfixes: * make polkit checks async -* logind is leaking fifos? +* fail gracefully if logind reaches it RLIMIT_NFILES for fifos Features: * ConditionCapability= -* order network mounts after network-fs-ready.target or so - * read fedora style timezone name config for compat * if we can not get user quota for tmpfs, mount a separate tmpfs instance for every user in /run/user/$USER with a configured maximum size -* bind mounts should be ordered after remount-root-fs.service - * default to actual 32bit PIDs, via /proc/sys/kernel/pid_max * increase RLIMIT_NOFILE for logind, logger by default diff --git a/src/timedated.c b/src/timedated.c index f6fe2d83b6..16f54b59d2 100644 --- a/src/timedated.c +++ b/src/timedated.c @@ -170,8 +170,24 @@ static int read_data(void) { free_data(); r = read_one_line_file("/etc/timezone", &zone); - if (r < 0 && r != -ENOENT) - return r; + if (r < 0) { + if (r != -ENOENT) + log_warning("Failed to read /etc/timezone: %s", strerror(-r)); + +#ifdef TARGET_FEDORA + r = parse_env_file("/etc/sysconfig/clock", NEWLINE, + "ZONE", &zone, + NULL); + + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/clock: %s", strerror(-r)); +#endif + } + + if (isempty(zone)) { + free(zone); + zone = NULL; + } verify_timezone(); -- cgit v1.2.3-54-g00ecf From 688c56ff7d124124007761f917a2950364509043 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Oct 2011 04:43:01 +0200 Subject: logind: fail gracefully if too many sessions are created https://bugzilla.redhat.com/show_bug.cgi?id=744726 --- TODO | 4 ---- src/logind-dbus.c | 7 +++++-- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/TODO b/TODO index aa51332c05..779d1a30dd 100644 --- a/TODO +++ b/TODO @@ -17,14 +17,10 @@ Bugfixes: * make polkit checks async -* fail gracefully if logind reaches it RLIMIT_NFILES for fifos - Features: * ConditionCapability= -* read fedora style timezone name config for compat - * if we can not get user quota for tmpfs, mount a separate tmpfs instance for every user in /run/user/$USER with a configured maximum size diff --git a/src/logind-dbus.c b/src/logind-dbus.c index bc1e49d18f..0550d1bd1c 100644 --- a/src/logind-dbus.c +++ b/src/logind-dbus.c @@ -973,8 +973,11 @@ static DBusHandlerResult manager_message_handler( } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CreateSession")) { r = bus_manager_create_session(m, message, &reply); - if (r == -ENOMEM) - goto oom; + + /* Don't delay the work on OOM here, since it might be + * triggered by a low RLIMIT_NOFILE here (since we + * send a dupped fd to the client), and we'd rather + * see this fail quickly then be retried later */ if (r < 0) return bus_send_error_reply(connection, message, &error, r); -- cgit v1.2.3-54-g00ecf From 62590f23c14d06e33bb1712a5e3cf04f12f189cb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Oct 2011 15:16:52 +0200 Subject: unit: introduce ConditionCapability --- TODO | 2 +- man/systemd.unit.xml | 24 +++++++++++++++++++----- src/condition.c | 34 ++++++++++++++++++++++++++++++++++ src/condition.h | 1 + src/load-fragment-gperf.gperf.m4 | 1 + 5 files changed, 56 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/TODO b/TODO index 99e026e3c1..9149018134 100644 --- a/TODO +++ b/TODO @@ -19,7 +19,7 @@ Bugfixes: Features: -* ConditionCapability= +* unset container= in PID1? * if we can not get user quota for tmpfs, mount a separate tmpfs instance for every user in /run/user/$USER with a configured maximum size diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index e47c14679e..897f99f24c 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -673,6 +673,7 @@ ConditionKernelCommandLine= ConditionVirtualization= ConditionSecurity= + ConditionCapability= ConditionNull= Before starting a unit @@ -749,9 +750,9 @@ value to check if being executed in any virtualized environment, or one of vm and - container to test against - a specific type of virtualization - solution, or one of + container to test + against a specific type of + virtualization solution, or one of qemu, kvm, vmware, @@ -775,7 +776,19 @@ system. Currently the only recognized value is selinux. The test may be negated by prepending - an exclamation mark. Finally, + an exclamation + mark. ConditionCapability= + may be used to check whether the given + capability exists in the capability + bounding set of the service manager + (i.e. this does not check whether + capability is actually available in + the permitted or effective sets, see + capabilities7 + for details). Pass a capability name + such as CAP_MKNOD, + possibly prefixed with an exclamation + mark to negate the check. Finally, ConditionNull= may be used to add a constant condition check value to the unit. It takes a @@ -932,7 +945,8 @@ systemd.target5, systemd.path5, systemd.timer5, - systemd.snapshot5 + systemd.snapshot5, + capabilities7 diff --git a/src/condition.c b/src/condition.c index 07624c841d..f18c45421a 100644 --- a/src/condition.c +++ b/src/condition.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef HAVE_SELINUX #include @@ -159,6 +160,36 @@ static bool test_security(const char *parameter) { return false; } +static bool test_capability(const char *parameter) { + cap_value_t value; + FILE *f; + char line[LINE_MAX]; + unsigned long long capabilities = (unsigned long long) -1; + + /* If it's an invalid capability, we don't have it */ + + if (cap_from_name(parameter, &value) < 0) + return false; + + /* If it's a valid capability we default to assume + * that we have it */ + + f = fopen("/proc/self/status", "re"); + if (!f) + return true; + + while (fgets(line, sizeof(line), f)) { + truncate_nl(line); + + if (startswith(line, "CapBnd:")) { + (void) sscanf(line+7, "%llx", &capabilities); + break; + } + } + + return !!(capabilities & (1ULL << value)); +} + bool condition_test(Condition *c) { assert(c); @@ -214,6 +245,9 @@ bool condition_test(Condition *c) { case CONDITION_SECURITY: return test_security(c->parameter) == !c->negate; + case CONDITION_CAPABILITY: + return test_capability(c->parameter) == !c->negate; + case CONDITION_NULL: return !c->negate; diff --git a/src/condition.h b/src/condition.h index dd65aa6054..71b1c6761e 100644 --- a/src/condition.h +++ b/src/condition.h @@ -37,6 +37,7 @@ typedef enum ConditionType { CONDITION_KERNEL_COMMAND_LINE, CONDITION_VIRTUALIZATION, CONDITION_SECURITY, + CONDITION_CAPABILITY, CONDITION_NULL, _CONDITION_TYPE_MAX, _CONDITION_TYPE_INVALID = -1 diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4 index 7749b88dfb..41797d20c0 100644 --- a/src/load-fragment-gperf.gperf.m4 +++ b/src/load-fragment-gperf.gperf.m4 @@ -119,6 +119,7 @@ Unit.ConditionFileIsExecutable, config_parse_unit_condition_path, CONDITION_F Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, 0 Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, 0 Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, 0 +Unit.ConditionCapability, config_parse_unit_condition_string, CONDITION_CAPABILITY, 0 Unit.ConditionNull, config_parse_unit_condition_null, 0, 0 m4_dnl Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file) -- cgit v1.2.3-54-g00ecf From adda7d8b9715a5090d9189144828ef4d3f51348c Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Tue, 11 Oct 2011 11:27:06 +0200 Subject: pager: add _noreturn_ to pager_fallback() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit src/pager.c: In function ‘pager_fallback’: src/pager.c:35:13: warning: function might be possible candidate for attribute ‘noreturn’ [-Wmissing-noreturn] --- src/pager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/pager.c b/src/pager.c index 6e2bb4901e..3fc81820e9 100644 --- a/src/pager.c +++ b/src/pager.c @@ -32,7 +32,7 @@ static pid_t pager_pid = 0; -static void pager_fallback(void) { +_noreturn_ static void pager_fallback(void) { ssize_t n; do { n = splice(STDIN_FILENO, NULL, STDOUT_FILENO, NULL, 64*1024, 0); -- cgit v1.2.3-54-g00ecf From 30fa6468353443318500c1783f5b1b164a32de0b Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Tue, 11 Oct 2011 12:34:14 +0200 Subject: localed: shorten generate-kbd-model-map Output is identical. --- src/generate-kbd-model-map | 42 +++++++++++++----------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/generate-kbd-model-map b/src/generate-kbd-model-map index 4fcf785e10..624c5179fa 100755 --- a/src/generate-kbd-model-map +++ b/src/generate-kbd-model-map @@ -1,49 +1,33 @@ #!/usr/bin/python -import system_config_keyboard.keyboard_models, sys +import sys +import system_config_keyboard.keyboard_models def strdash(s): - r = s.strip() - - if r == "": - return "-" - - return r - -def tab_extend(s, n = 1): + return s.strip() or '-' +def tab_extend(s, n=1): s = strdash(s) - k = len(s) / 8 + k = len(s) // 8 if k >= n: f = 1 else: f = n - k - for x in range(0, f): - s = s + "\t" - - return s - + return s + '\t'*f models = system_config_keyboard.keyboard_models.KeyboardModels().get_models() print "# Generated from system-config-keyboard's model list" - print "# consolelayout\t\txlayout\txmodel\t\txvariant\txoptions" -k = models.keys() - -k.reverse() - -for key in k: - value = models[key] - - options = value[4] - if len(options) > 0: - options = "terminate:ctrl_alt_bksp," + options - else: - options = "terminate:ctrl_alt_bksp" +for key, value in reversed(models.items()): + options = "terminate:ctrl_alt_bksp" + if value[4]: + options += ',' + value[4] - print "%s%s%s%s%s" % (tab_extend(key, 3), tab_extend(value[1]), tab_extend(value[2], 2), tab_extend(value[3], 2), options) + print ''.join((tab_extend(key, 3), tab_extend(value[1]), + tab_extend(value[2], 2), tab_extend(value[3], 2), + options)) -- cgit v1.2.3-54-g00ecf From c70ac211b486c70271e265d142f3b73e323faf6e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Oct 2011 20:20:01 +0200 Subject: localed: make sure s-s-k doesn't create any X11 config files anymore --- src/localed.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/localed.c b/src/localed.c index e627c3a716..c6b48de5f9 100644 --- a/src/localed.c +++ b/src/localed.c @@ -574,6 +574,10 @@ static int write_data_x11(void) { #ifdef TARGET_FEDORA unlink("/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf"); + + /* Symlink this to /dev/null, so that s-s-k (if it is + * still running) doesn't recreate this. */ + symlink("/dev/null", "/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf"); #endif if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) @@ -619,6 +623,10 @@ static int write_data_x11(void) { #ifdef TARGET_FEDORA unlink("/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf"); + + /* Symlink this to /dev/null, so that s-s-k (if it is + * still running) doesn't recreate this. */ + symlink("/dev/null", "/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf"); #endif r = 0; -- cgit v1.2.3-54-g00ecf From 1835f23c2a53e632959270e79dbf3143874e6111 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Oct 2011 20:21:06 +0200 Subject: service: don't try to guess PID for SysV services anymore As it turns out there are quite a number of SysV services too broken to make the guessing work: instead of returning in the parent only after the child is fully initialized they return immediately. The effect is that the guessing in systemd might happen too early, at a time where the final main process doesn't exist yet. By turning this off we won't try to detect the main pid anymore, with the effect that all processes of the service in question are considered equally likely to be the main process. --- src/service.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/service.c b/src/service.c index c2053ce3ac..e64d289fed 100644 --- a/src/service.c +++ b/src/service.c @@ -829,6 +829,7 @@ static int service_load_sysv_path(Service *s, const char *path) { /* Special setting for all SysV services */ s->type = SERVICE_FORKING; s->remain_after_exit = !s->pid_file; + s->guess_main_pid = false; s->restart = SERVICE_RESTART_NO; if (s->meta.manager->sysv_console) -- cgit v1.2.3-54-g00ecf From 64685e0cea62b4937f0804e47ce2cb7929f58223 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Oct 2011 22:30:31 +0200 Subject: util: properly detect what the last capability is --- src/execute.c | 7 ++----- src/nspawn.c | 8 +------- src/util.c | 33 +++++++++++++++++++++++++++++++++ src/util.h | 2 ++ 4 files changed, 38 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/execute.c b/src/execute.c index 53e7e77fde..866e8bf2f6 100644 --- a/src/execute.c +++ b/src/execute.c @@ -895,12 +895,9 @@ static int do_capability_bounding_set_drop(uint64_t drop) { } } - for (i = 0; i <= MAX(63LU, (unsigned long) CAP_LAST_CAP); i++) + for (i = 0; i <= cap_last_cap(); i++) if (drop & ((uint64_t) 1ULL << (uint64_t) i)) { if (prctl(PR_CAPBSET_DROP, i) < 0) { - if (errno == EINVAL) - break; - r = -errno; goto finish; } @@ -1720,7 +1717,7 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { unsigned long l; fprintf(f, "%sCapabilityBoundingSet:", prefix); - for (l = 0; l <= (unsigned long) CAP_LAST_CAP; l++) + for (l = 0; l <= cap_last_cap(); l++) if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) { char *t; diff --git a/src/nspawn.c b/src/nspawn.c index 8441c057b9..653d7db730 100644 --- a/src/nspawn.c +++ b/src/nspawn.c @@ -361,7 +361,7 @@ static int drop_capabilities(void) { unsigned long l; - for (l = 0; l <= MAX(63LU, (unsigned long) CAP_LAST_CAP); l++) { + for (l = 0; l <= cap_last_cap(); l++) { unsigned i; for (i = 0; i < ELEMENTSOF(retain); i++) @@ -372,12 +372,6 @@ static int drop_capabilities(void) { continue; if (prctl(PR_CAPBSET_DROP, l) < 0) { - - /* If this capability is not known, EINVAL - * will be returned, let's ignore this. */ - if (errno == EINVAL) - break; - log_error("PR_CAPBSET_DROP failed: %m"); return -errno; } diff --git a/src/util.c b/src/util.c index e46606dabb..e93e6f6cf5 100644 --- a/src/util.c +++ b/src/util.c @@ -5703,3 +5703,36 @@ int strdup_or_null(const char *a, char **b) { *b = c; return 0; } + +unsigned long cap_last_cap(void) { + static __thread unsigned long saved; + static __thread bool valid = false; + unsigned long p; + + if (valid) + return saved; + + p = (unsigned long) CAP_LAST_CAP; + + if (prctl(PR_CAPBSET_READ, p) < 0) { + + /* Hmm, look downwards, until we find one that + * works */ + for (p--; p > 0; p --) + if (prctl(PR_CAPBSET_READ, p) >= 0) + break; + + } else { + + /* Hmm, look upwards, until we find one that doesn't + * work */ + for (;; p++) + if (prctl(PR_CAPBSET_READ, p+1) < 0) + break; + } + + saved = p; + valid = true; + + return p; +} diff --git a/src/util.h b/src/util.h index ccbe8a3efa..a71a297eab 100644 --- a/src/util.h +++ b/src/util.h @@ -506,4 +506,6 @@ extern char **saved_argv; bool kexec_loaded(void); +unsigned long cap_last_cap(void); + #endif -- cgit v1.2.3-54-g00ecf