Compare commits

...

22 Commits
master ... f16

Author SHA1 Message Date
Michal Schmidt 57bf936f9b RequiredBy= in [Install], ignore Documentation= 2012-05-23 11:46:39 +02:00
Michal Schmidt a89d6fef4a Fix auto-restart handling (#817968, fdo#45511) 2012-05-22 09:18:55 +02:00
Michal Schmidt bd3438e3b8 Revert the ReleaseSession patch (#823485) 2012-05-22 01:24:57 +02:00
Michal Schmidt 022e766fad Fix another cause of "Failed to issue method call" (#814966) 2012-05-21 13:30:58 +02:00
Michal Schmidt bee9bcf23b bash-completion: Failed to issue method call (#814966) 2012-05-19 02:02:29 +02:00
Michal Schmidt 1a8e1d97ab Added many patches from current upstream
to fix mainly:
  - Loss of ordering with restart jobs and the behavior of try-restart while
    the service is inactive with a pending job (#753586).
  - Assertion in systemd-analyze while boot is still in progress (#701669).
  - systemd-tmpfiles preservation of atime on subdirectories (#810257).
  - Requires= dependencies were not started by systemctl restart (#802770).
- As a dependency for #753586, a refactoring of the transaction code is
  included. It also fixes several bugs.
- A few low-risk or cosmetic fixes are included too.

Notably skipped were the patches that improve systemd behavior in containers.
They were not considered important for F16.
2012-05-05 00:40:39 +02:00
Michal Schmidt a5a9a14d29 cryptsetup: emit a change uevent after mkswap
Workaround the lack of udev watches on dm devices in F16. (#711394)
2012-04-17 09:34:08 +02:00
Michal Schmidt 14c3102fc6 cherry-picks from v44 2012-03-20 00:34:19 +01:00
Michal Schmidt f3be5854ec CVE-2012-1174 (#804118) 2012-03-16 18:41:27 +01:00
Michal Schmidt a661dbaae2 socket tarpits and other fixes from upstream
- avoid socket tarpits when the service keeps failing
  - get rid of awk, sed, grep in bash completion
  - and minor fixes
2012-03-06 10:16:31 +01:00
Michal Schmidt 5bbea84736 logind: move X11 socket 2012-03-01 10:42:20 +01:00
Michal Schmidt b568ba0518 A few fixes from upstream
PrivateTmp permissions (#790522)
timedated without ntp installed (#790260)
logind: allow PowerOff and Reboot via polkit
loading empty files in read_one_line_file() (fdo#45362)
fix cgit URLs in manpages
2012-02-27 08:51:16 +01:00
Michal Schmidt 7a876fd5b6 Minor fixes and some manpage updates from upstream 2012-02-09 21:36:32 +01:00
Michal Schmidt e1f7878ec3 avoid glitch with plymouth, logind fixes 2012-01-29 22:03:20 +01:00
Michal Schmidt c0a5082a10 Fix automount regression 2012-01-26 09:45:03 +01:00
Michal Schmidt 5a09d6df41 Fix occasionally failing socket units with Accept=yes (#783344) 2012-01-21 00:12:17 +01:00
Michal Schmidt 567d93a9ca add Conflicts with known broken spamassassin 2012-01-20 02:08:19 +01:00
Michal Schmidt 83ed792467 Fix a crash related to pid file watch and daemon-reload (#783118) 2012-01-20 01:56:20 +01:00
Michal Schmidt bc0dd808db Shut up another logind message (#727315) 2012-01-17 13:20:18 +01:00
Michal Schmidt f1996ec017 Fix for quota and a couple of other issues 2012-01-14 21:43:54 +01:00
Michal Schmidt e43452dfe6 Fixes and low-risk enhancements (no journald) from upstream v38. 2012-01-11 12:22:35 +01:00
Karsten Hopp d2963bf492 add upstream patch for bugzilla 744415, encrypted filesystem passphrases
fail on runtime systems in hvc consoles
2011-12-02 18:26:31 +01:00
234 changed files with 34147 additions and 67 deletions

View File

@ -1,33 +0,0 @@
From a65cb51f29ee177f6f800c87232b68475216a418 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 23 Sep 2011 13:58:00 +0200
Subject: [PATCH] unit: fix complementing of requirement deps with After deps
for targets
'man systemd.target' says:
Unless DefaultDependencies= is set to false, target units will
implicitly complement all configured dependencies of type
Wants=, Requires=, RequiresOverridable= with dependencies of type
After= if the units in question also have DefaultDependencies=true.
It did not work because of a forgotten negation.
---
src/unit.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/unit.c b/src/unit.c
index 0b435cb..903a8e4 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -774,7 +774,7 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) {
/* If either side wants no automatic dependencies, then let's
* skip this */
if (!u->meta.default_dependencies ||
- target->meta.default_dependencies)
+ !target->meta.default_dependencies)
return 0;
/* Don't create loops */
--
1.7.4.4

View File

@ -0,0 +1,119 @@
From 3ad4e947bb0312940d56059328dd518d01718f6f Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 11 Oct 2011 22:30:31 +0200
Subject: [PATCH] util: properly detect what the last capability is (cherry
picked from commit
64685e0cea62b4937f0804e47ce2cb7929f58223)
---
src/execute.c | 7 ++-----
src/nspawn.c | 8 +-------
src/util.c | 33 +++++++++++++++++++++++++++++++++
src/util.h | 2 ++
4 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/src/execute.c b/src/execute.c
index 53e7e77..866e8bf 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 8441c05..653d7db 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 e46606d..e93e6f6 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 ccbe8a3..a71a297 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

View File

@ -1,7 +1,7 @@
From 563ba9ea6e60774086555998b957edf923e24b46 Mon Sep 17 00:00:00 2001
From b93ae6c00edfe8ef2f0fd70177dee1d111598fe0 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Mon, 17 Oct 2011 11:12:12 +0200
Subject: [PATCH 2/5] manager: fix a crash in isolating
Subject: [PATCH] manager: fix a crash in isolating
HASHMAP_FOREACH is safe against the removal of the current entry, but
not against the removal of other entries. job_finish_and_invalidate()
@ -17,6 +17,7 @@ possibility that the iterator could be invalid.
It is O(n^2) in the worst case, but that's better than a crash.
https://bugzilla.redhat.com/show_bug.cgi?id=717325
(cherry picked from commit 563ba9ea6e60774086555998b957edf923e24b46)
---
src/job.c | 19 ++++++++++++++-----
src/manager.c | 7 ++++++-
@ -112,6 +113,3 @@ index e626347..6d20258 100644
}
}
--
1.7.4.4

View File

@ -0,0 +1,53 @@
From 1d0ba48a582be7b9a539cbb5cbf6bbdf5f7b08e1 Mon Sep 17 00:00:00 2001
From: Jonathan Nieder <jrnieder@gmail.com>
Date: Mon, 17 Oct 2011 21:01:40 +0200
Subject: [PATCH] audit: do not complain if kernel lacks audit
When running on a kernel without audit support, systemd currently
writes a mysterious-sounding error to its log:
systemd[1]: Failed to connect to audit log: Protocol not supported
Better to suppress the audit_open() failure message when (and only
when) it is due to running on a kernel without audit support, since in
this case the admin probably does not mind systemd not writing to the
audit log. This way, more serious errors like ENOMEM and EACCES will
stand out more.
(cherry picked from commit 5a8d081c58f7b83172ad5031a8fdac0c33072b2a)
---
src/manager.c | 5 ++++-
src/update-utmp.c | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/manager.c b/src/manager.c
index 6d20258..111167a 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -286,7 +286,10 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) {
goto fail;
#ifdef HAVE_AUDIT
- if ((m->audit_fd = audit_open()) < 0)
+ if ((m->audit_fd = audit_open()) < 0 &&
+ /* If the kernel lacks netlink or audit support,
+ * don't worry about it. */
+ errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
log_error("Failed to connect to audit log: %m");
#endif
diff --git a/src/update-utmp.c b/src/update-utmp.c
index f81e7f4..12e4d11 100644
--- a/src/update-utmp.c
+++ b/src/update-utmp.c
@@ -376,7 +376,10 @@ int main(int argc, char *argv[]) {
umask(0022);
#ifdef HAVE_AUDIT
- if ((c.audit_fd = audit_open()) < 0)
+ if ((c.audit_fd = audit_open()) < 0 &&
+ /* If the kernel lacks netlink or audit support,
+ * don't worry about it. */
+ errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
log_error("Failed to connect to audit log: %m");
#endif

View File

@ -1,7 +1,7 @@
From 74eeab044e506a39786f484b160d9f64d48ad243 Mon Sep 17 00:00:00 2001
From fb4f5f218e83eb1496f2fdfa67b27e458b2bd6a4 Mon Sep 17 00:00:00 2001
From: Dave Reisner <d@falconindy.com>
Date: Tue, 11 Oct 2011 20:56:53 -0400
Subject: [PATCH 5/5] systemctl-completion: always invoke with --no-legend
Subject: [PATCH] systemctl-completion: always invoke with --no-legend
In the case of completion for the 'restart' verb, passing the invalid
unit name (the colums header) causes completion to cease functioning
@ -11,6 +11,7 @@ entirely, with the error:
This adds a small wrapper function for systemctl which can have common
options added to it.
(cherry picked from commit 74eeab044e506a39786f484b160d9f64d48ad243)
---
src/systemctl-bash-completion.sh | 20 ++++++++++++--------
1 files changed, 12 insertions(+), 8 deletions(-)
@ -71,6 +72,3 @@ index 6369a6c..6ebb792 100644
compopt -o nospace
fi
--
1.7.4.4

View File

@ -0,0 +1,76 @@
From 62403a219c01f907e69012e502a73cdb9aeeb251 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 24 Oct 2011 11:49:59 +0200
Subject: [PATCH] systemctl: make list-unit-files output more economical
The first column is given the width of the widest entry,
if possible, otherwise all entries are ellipsized to fit
in ($COLUMNS - (width of second column)).
[ Added a few fixes, calculate state_cols too, respect '--no-legend',
better handling of '--full' -- michich ]
(cherry picked from commit 1c0a113fd3fe3344b2c947ca9948760057052716)
---
src/systemctl.c | 35 +++++++++++++++++++++++++++--------
1 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/systemctl.c b/src/systemctl.c
index 0de2444..b0baf8d 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -551,11 +551,30 @@ static bool output_show_unit_file(const UnitFileList *u) {
}
static void output_unit_file_list(const UnitFileList *units, unsigned c) {
- unsigned n_shown = 0;
+ unsigned max_id_len, id_cols, state_cols, n_shown = 0;
const UnitFileList *u;
- if (on_tty())
- printf("%-25s %-6s\n", "UNIT FILE", "STATE");
+ max_id_len = sizeof("UNIT FILE")-1;
+ state_cols = sizeof("STATE")-1;
+ for (u = units; u < units + c; u++) {
+ if (!output_show_unit_file(u))
+ continue;
+
+ max_id_len = MAX(max_id_len, strlen(file_name_from_path(u->path)));
+ state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
+ }
+
+ if (!arg_full) {
+ unsigned basic_cols;
+ id_cols = MIN(max_id_len, 25);
+ basic_cols = 1 + id_cols + state_cols;
+ if (basic_cols < (unsigned) columns())
+ id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
+ } else
+ id_cols = max_id_len;
+
+ if (!arg_no_legend)
+ printf("%-*s %-*s\n", id_cols, "UNIT FILE", state_cols, "STATE");
for (u = units; u < units + c; u++) {
char *e;
@@ -580,16 +599,16 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
id = file_name_from_path(u->path);
- e = arg_full ? NULL : ellipsize(id, 25, 33);
+ e = arg_full ? NULL : ellipsize(id, id_cols, 33);
- printf("%-25s %s%-6s%s\n",
- e ? e : id,
- on, unit_file_state_to_string(u->state), off);
+ printf("%-*s %s%-*s%s\n",
+ id_cols, e ? e : id,
+ on, state_cols, unit_file_state_to_string(u->state), off);
free(e);
}
- if (on_tty())
+ if (!arg_no_legend)
printf("\n%u unit files listed.\n", n_shown);
}

View File

@ -0,0 +1,28 @@
From 4cff61c8150be456da22cc737696fad925c1393f Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 1 Nov 2011 14:20:31 +0100
Subject: [PATCH] plymouth: fix ply proto endianess issues
Plymouth enforces LE even for the local Ply proto, hence we should do
the conversion properly for BE arch compat.
Tracked down by Harald Hoyer.
https://bugzilla.redhat.com/show_bug.cgi?id=744415
(cherry picked from commit bb53abeb8c3407ea250be69bc43510b03c0df3da)
---
src/tty-ask-password-agent.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/tty-ask-password-agent.c b/src/tty-ask-password-agent.c
index 43d008f..13481b2 100644
--- a/src/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent.c
@@ -206,6 +206,7 @@ static int ask_password_plymouth(
continue;
memcpy(&size, buffer+1, sizeof(size));
+ size = le32toh(size);
if (size+5 > sizeof(buffer)) {
r = -EIO;
goto finish;

View File

@ -0,0 +1,34 @@
From fb47a8a6bc8903d8b4b7b71707baa2c7585a0407 Mon Sep 17 00:00:00 2001
From: Tom Gundersen <teg@jklm.no>
Date: Sat, 22 Oct 2011 18:47:08 +0200
Subject: [PATCH] random-seed: convert poolsize from bits to bytes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The problem was first noted in a bug report against Arch's initscripts.
Reported-by: Taylan Ulrich Bayırlı <taylanbayirli@gmail.com>
Reported-by: Gerardo Exequiel Pozzi <vmlinuz386@yahoo.com.ar>
(cherry picked from commit 7c2ec00930ce1f4aabfbb405d84b67eb9d065ef0)
---
src/random-seed.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/src/random-seed.c b/src/random-seed.c
index ee5cae3..0c63794 100644
--- a/src/random-seed.c
+++ b/src/random-seed.c
@@ -51,7 +51,11 @@ int main(int argc, char *argv[]) {
/* Read pool size, if possible */
if ((f = fopen("/proc/sys/kernel/random/poolsize", "re"))) {
- fscanf(f, "%zu", &buf_size);
+ if (fscanf(f, "%zu", &buf_size) > 0) {
+ /* poolsize is in bits on 2.6, but we want bytes */
+ buf_size /= 8;
+ }
+
fclose(f);
}

View File

@ -0,0 +1,24 @@
From 62f4ee1b584845c8a3d4caf41c572ec5e7d7af66 Mon Sep 17 00:00:00 2001
From: Thomas Jarosch <thomas.jarosch@intra2net.com>
Date: Wed, 26 Oct 2011 09:38:39 +0200
Subject: [PATCH] condition: Fix file descriptor leak in test_capability()
Detected by cppcheck.
(cherry picked from commit 7670e5a2aab543bc6b442ab0683411770e06fe26)
---
src/condition.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/src/condition.c b/src/condition.c
index f18c454..2b51a16 100644
--- a/src/condition.c
+++ b/src/condition.c
@@ -187,6 +187,8 @@ static bool test_capability(const char *parameter) {
}
}
+ fclose(f);
+
return !!(capabilities & (1ULL << value));
}

View File

@ -0,0 +1,51 @@
From 3e750716de6acad59112a34d3d79f50da680d023 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 1 Nov 2011 18:18:17 +0100
Subject: [PATCH] initctl: don't use dbus connection after PID 1 got respawned
After reexec PID 1 our bus connection is invalidated. Hence don't try to
reuse it, just terminate so that when we are spawned the next time we
just get a new one.
Spotted by Marti Raudsepp.
(cherry picked from commit f632a6634dd4eff041425aa9b3fb48ccfa98c014)
---
src/initctl.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/src/initctl.c b/src/initctl.c
index eaa717a..097c85f 100644
--- a/src/initctl.c
+++ b/src/initctl.c
@@ -56,6 +56,8 @@ typedef struct Server {
unsigned n_fifos;
DBusConnection *bus;
+
+ bool quit;
} Server;
struct Fifo {
@@ -174,6 +176,13 @@ static void request_process(Server *s, const struct init_request *req) {
case 'U':
if (kill(1, SIGTERM) < 0)
log_error("kill() failed: %m");
+
+ /* The bus connection will be
+ * terminated if PID 1 is reexecuted,
+ * hence let's just exit here, and
+ * rely on that we'll be restarted on
+ * the next request */
+ s->quit = true;
break;
case 'q':
@@ -404,7 +413,7 @@ int main(int argc, char *argv[]) {
"READY=1\n"
"STATUS=Processing requests...");
- for (;;) {
+ while (!server.quit) {
struct epoll_event event;
int k;

View File

@ -0,0 +1,30 @@
From b160c4add112ec90a811726ee3ac536f98cfd6cf Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 1 Nov 2011 22:02:36 +0100
Subject: [PATCH] cgroup: always recreate cgroup before we try to apply
attributes
We might have trimmed the cgroup tree previously, hence don't trust our
own "realized" flag, always recreate cgroup tree before applying our
attributes to make sure this actually works out.
https://bugzilla.redhat.com/show_bug.cgi?id=749687
(cherry picked from commit 6ddaf1ca4ab0e6a094f6d37fa1e0c604c6d867ba)
---
src/cgroup.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/src/cgroup.c b/src/cgroup.c
index dcf2c2f..be837c3 100644
--- a/src/cgroup.c
+++ b/src/cgroup.c
@@ -38,9 +38,6 @@ int cgroup_bonding_realize(CGroupBonding *b) {
assert(b->path);
assert(b->controller);
- if (b->realized)
- return 0;
-
r = cg_create(b->controller, b->path);
if (r < 0) {
log_warning("Failed to create cgroup %s:%s: %s", b->controller, b->path, strerror(-r));

View File

@ -1,4 +1,4 @@
From 7fc2a89a7387db1e5daa4892393c9e9536920c25 Mon Sep 17 00:00:00 2001
From 10e099981a14b6f435552854d4c9d5eaaa65c4da Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 1 Nov 2011 22:27:48 +0100
Subject: [PATCH] mount: order remote mounts after both network.target and
@ -9,6 +9,7 @@ remote mounts after network.target, so let's add that order explicitly
in addition to remote-fs-pre.target.
https://bugzilla.redhat.com/show_bug.cgi?id=749940
(cherry picked from commit 7fc2a89a7387db1e5daa4892393c9e9536920c25)
---
src/mount.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
@ -45,6 +46,3 @@ index ef953f0..f9cfe91 100644
if (automount) {
Unit *am;
--
1.7.7

View File

@ -1,4 +1,4 @@
From fc8f0b5c9cb8277950a2fefdb7f754c47b172dfd Mon Sep 17 00:00:00 2001
From 80c991c323a08ee03131d51c34b45286ae72001f Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 1 Nov 2011 22:29:48 +0100
Subject: [PATCH] units: drop [Install] section from remote-fs-pre.target
@ -6,6 +6,7 @@ Subject: [PATCH] units: drop [Install] section from remote-fs-pre.target
remote-fs-pre.target is not a unit a user should ever explicitly enable.
Instead services which need to hook before network mounts should pull it
in.
(cherry picked from commit fc8f0b5c9cb8277950a2fefdb7f754c47b172dfd)
---
units/remote-fs-pre.target | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
@ -21,6 +22,3 @@ index 5406aa2..8aceb08 100644
-
-[Install]
-WantedBy=multi-user.target
--
1.7.7

View File

@ -0,0 +1,37 @@
From 88230ce30fcd48f8f6fadcdf838e6f047a91acdf Mon Sep 17 00:00:00 2001
From: Tom Gundersen <teg@jklm.no>
Date: Mon, 17 Oct 2011 13:01:08 +0200
Subject: [PATCH] cryptsetup-generator: avoid ordering cycle on swap
Devices with random keys (swap), should not be ordered before local-fs.target,
as this creates a cycle with systemd-load-random-seed.service (and also it
does not make sense, a swap device is not a local-fs).
(cherry picked from commit 87e75fddbb3701fd5f4e0d62dc1d661e8d94b071)
---
src/cryptsetup-generator.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/cryptsetup-generator.c b/src/cryptsetup-generator.c
index 6f3aa78..a48b7a4 100644
--- a/src/cryptsetup-generator.c
+++ b/src/cryptsetup-generator.c
@@ -112,8 +112,7 @@ static int create_disk(
"DefaultDependencies=no\n"
"BindTo=%s dev-mapper-%%i.device\n"
"After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n"
- "Before=umount.target\n"
- "Before=local-fs.target\n",
+ "Before=umount.target\n",
d, d);
if (!nofail)
@@ -125,6 +124,9 @@ static int create_disk(
streq(password, "/dev/hw_random")))
fprintf(f,
"After=systemd-random-seed-load.service\n");
+ else
+ fprintf(f,
+ "Before=local-fs.target\n");
fprintf(f,
"\n[Service]\n"

View File

@ -0,0 +1,150 @@
From f116811feefbde2af0138ab73a2bfab38639f315 Mon Sep 17 00:00:00 2001
From: Ran Benita <ran234@gmail.com>
Date: Wed, 2 Nov 2011 10:48:49 +0200
Subject: [PATCH] bash-completion: update with new verbs and arguments
Adds arguments --root= --runtime --no-legend.
Adds verbs link mask unmask reenable list-unit-files.
Also uses list-unit-files to make nicer enable and disable completions.
Rebased due to changes in systemctl.
(cherry picked from commit 8aea83c718af18e6436e6bdce9437238de052dbb)
---
src/systemctl-bash-completion.sh | 61 +++++++++++++++++++++++++++----------
1 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh
index 6ebb792..0aa87af 100644
--- a/src/systemctl-bash-completion.sh
+++ b/src/systemctl-bash-completion.sh
@@ -16,7 +16,7 @@
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
__systemctl() {
- systemctl --no-legend "$@"
+ systemctl --full --no-legend "$@"
}
__contains_word () {
@@ -36,10 +36,13 @@ __filter_units_by_property () {
done
}
-__get_all_units () { __systemctl list-units --full --all | awk ' {print $1}' ; }
-__get_active_units () { __systemctl list-units --full | awk ' {print $1}' ; }
-__get_inactive_units () { __systemctl list-units --full --all | awk '$3 == "inactive" {print $1}' ; }
-__get_failed_units () { __systemctl list-units --full | awk '$3 == "failed" {print $1}' ; }
+__get_all_units () { __systemctl list-units --all | awk ' {print $1}' ; }
+__get_active_units () { __systemctl list-units | awk ' {print $1}' ; }
+__get_inactive_units () { __systemctl list-units --all | awk '$3 == "inactive" {print $1}' ; }
+__get_failed_units () { __systemctl list-units | awk '$3 == "failed" {print $1}' ; }
+__get_enabled_units () { __systemctl list-unit-files | awk '$2 == "enabled" {print $1}' ; }
+__get_disabled_units () { __systemctl list-unit-files | awk '$2 == "disabled" {print $1}' ; }
+__get_masked_units () { __systemctl list-unit-files | awk '$2 == "masked" {print $1}' ; }
_systemctl () {
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
@@ -47,15 +50,15 @@ _systemctl () {
local -A OPTS=(
[STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global
- --help -h --no-ask-password --no-block --no-pager --no-reload --no-wall
- --order --require --quiet -q --privileged -P --system --user --version'
- [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t'
+ --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
+ --order --require --quiet -q --privileged -P --system --user --version --runtime'
+ [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root'
)
if __contains_word "$prev" ${OPTS[ARG]}; then
case $prev in
--signal|-s)
- comps=$(compgen -A signal | grep '^SIG' | grep -Ev 'RTMIN|RTMAX|JUNK')
+ comps=$(compgen -A signal)
;;
--type|-t)
comps='automount device mount path service snapshot socket swap target timer'
@@ -66,7 +69,14 @@ _systemctl () {
--kill-mode)
comps='control-group process'
;;
- --property|-p|--host|-H)
+ --root)
+ comps=$(compgen -A directory -- "$cur" )
+ compopt -o filenames
+ ;;
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --property|-p)
comps=''
;;
esac
@@ -81,22 +91,26 @@ _systemctl () {
fi
local -A VERBS=(
- [ALL_UNITS]='enable disable is-active is-enabled status show'
+ [ALL_UNITS]='is-active is-enabled status show mask preset'
+ [ENABLED_UNITS]='disable reenable'
+ [DISABLED_UNITS]='enable'
[FAILED_UNITS]='reset-failed'
[STARTABLE_UNITS]='start'
- [STOPPABLE_UNITS]='stop kill try-restart condrestart'
+ [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
[ISOLATABLE_UNITS]='isolate'
- [RELOADABLE_UNITS]='reload reload-or-try-restart force-reload'
- [RESTARTABLE_UNITS]='restart reload-or-restart'
+ [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload'
+ [RESTARTABLE_UNITS]='restart reload-or-restart'
+ [MASKED_UNITS]='unmask'
[JOBS]='cancel'
[SNAPSHOTS]='delete'
[ENVS]='set-environment unset-environment'
- [STANDALONE]='daemon-reexec daemon-reload default dot dump emergency exit halt kexec
- list-jobs list-units poweroff reboot rescue show-environment'
+ [STANDALONE]='daemon-reexec daemon-reload default dot dump
+ emergency exit halt kexec list-jobs list-units
+ list-unit-files poweroff reboot rescue show-environment'
[NAME]='snapshot load'
+ [FILE]='link'
)
- local verb
for ((i=0; $i <= $COMP_CWORD; i++)); do
if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
@@ -111,6 +125,12 @@ _systemctl () {
elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
comps=$( __get_all_units )
+ elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
+ comps=$( __get_enabled_units )
+
+ elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
+ comps=$( __get_disabled_units )
+
elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
comps=$( __filter_units_by_property CanStart yes \
$( __get_inactive_units | grep -Ev '\.(device|snapshot)$' ))
@@ -134,6 +154,9 @@ _systemctl () {
elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
comps=$( __get_failed_units )
+ elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
+ comps=$( __get_masked_units )
+
elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
comps=''
@@ -146,6 +169,10 @@ _systemctl () {
elif __contains_word "$verb" ${VERBS[ENVS]}; then
comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' )
compopt -o nospace
+
+ elif __contains_word "$verb" ${VERBS[FILE]}; then
+ comps=$( compgen -A file -- "$cur" )
+ compopt -o filenames
fi
COMPREPLY=( $(compgen -W "$comps" -- "$cur") )

View File

@ -0,0 +1,103 @@
From cb1d467a016e97e74222fc775fefe4ee3790f8fb Mon Sep 17 00:00:00 2001
From: Ran Benita <ran234@gmail.com>
Date: Wed, 2 Nov 2011 10:48:50 +0200
Subject: [PATCH] bash-completion: add completions for systemd-loginctl
This script is straightforward and should give proper completions for
all of systemd-loginctl's verbs.
(cherry picked from commit 3cdbf916d3629733fa9998d5802bf4c20d98c50e)
---
src/systemctl-bash-completion.sh | 83 ++++++++++++++++++++++++++++++++++++++
1 files changed, 83 insertions(+), 0 deletions(-)
diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh
index 0aa87af..176591f 100644
--- a/src/systemctl-bash-completion.sh
+++ b/src/systemctl-bash-completion.sh
@@ -179,3 +179,86 @@ _systemctl () {
return 0
}
complete -F _systemctl systemctl
+
+__get_all_sessions () { systemd-loginctl list-sessions | awk '{print $1}' ; }
+__get_all_users () { systemd-loginctl list-users | awk '{print $2}' ; }
+__get_all_seats () { systemd-loginctl list-seats | awk '{print $1}' ; }
+
+_systemd_loginctl () {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local verb comps
+
+ local -A OPTS=(
+ [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version'
+ [ARG]='--host -H --kill-who --property -p --signal -s'
+ )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --signal|-s)
+ comps=$(compgen -A signal)
+ ;;
+ --kill-who)
+ comps='all leader'
+ ;;
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --property|-p)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+ return 0
+ fi
+
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") )
+ return 0
+ fi
+
+ local -A VERBS=(
+ [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session'
+ [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user'
+ [SEATS]='seat-status show-seat terminate-seat'
+ [STANDALONE]='list-sessions list-users list-seats flush-devices'
+ [ATTACH]='attach'
+ )
+
+ for ((i=0; $i <= $COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z $verb ]]; then
+ comps="${VERBS[*]}"
+
+ elif __contains_word "$verb" ${VERBS[SESSIONS]}; then
+ comps=$( __get_all_sessions )
+
+ elif __contains_word "$verb" ${VERBS[USERS]}; then
+ comps=$( __get_all_users )
+
+ elif __contains_word "$verb" ${VERBS[SEATS]}; then
+ comps=$( __get_all_seats )
+
+ elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+ comps=''
+
+ elif __contains_word "$verb" ${VERBS[ATTACH]}; then
+ if [[ $prev = $verb ]]; then
+ comps=$( __get_all_seats )
+ else
+ comps=$(compgen -A file -- "$cur" )
+ compopt -o filenames
+ fi
+ fi
+
+ COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+ return 0
+}
+complete -F _systemd_loginctl systemd-loginctl

View File

@ -0,0 +1,568 @@
From b7ff1f56d52becdc0820d54a26b2fbec7fbd698c Mon Sep 17 00:00:00 2001
From: Ran Benita <ran234@gmail.com>
Date: Wed, 2 Nov 2011 10:48:51 +0200
Subject: [PATCH] bash-completion: rename file since it is no longer for
systemctl only (cherry picked from commit
f5a613c03c54cc82e92c38af0b3e1c130003a68b)
---
Makefile.am | 2 +-
src/systemctl-bash-completion.sh | 264 --------------------------------------
src/systemd-bash-completion.sh | 264 ++++++++++++++++++++++++++++++++++++++
3 files changed, 265 insertions(+), 265 deletions(-)
delete mode 100644 src/systemctl-bash-completion.sh
create mode 100644 src/systemd-bash-completion.sh
diff --git a/Makefile.am b/Makefile.am
index dabe32a..8f1ffdc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -314,7 +314,7 @@ dbusinterface_DATA += \
endif
dist_bashcompletion_DATA = \
- src/systemctl-bash-completion.sh
+ src/systemd-bash-completion.sh
dist_tmpfiles_DATA = \
tmpfiles.d/systemd.conf \
diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh
deleted file mode 100644
index 176591f..0000000
--- a/src/systemctl-bash-completion.sh
+++ /dev/null
@@ -1,264 +0,0 @@
-# This file is part of systemd.
-#
-# Copyright 2010 Ran Benita
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# systemd is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with systemd; If not, see <http://www.gnu.org/licenses/>.
-
-__systemctl() {
- systemctl --full --no-legend "$@"
-}
-
-__contains_word () {
- local word=$1; shift
- for w in $*; do [[ $w = $word ]] && return 0; done
- return 1
-}
-
-__filter_units_by_property () {
- local property=$1 value=$2 ; shift ; shift
- local -a units=( $* )
- local -a props=( $(__systemctl show --property "$property" -- ${units[*]} | grep -v ^$) )
- for ((i=0; $i < ${#units[*]}; i++)); do
- if [[ "${props[i]}" = "$property=$value" ]]; then
- echo "${units[i]}"
- fi
- done
-}
-
-__get_all_units () { __systemctl list-units --all | awk ' {print $1}' ; }
-__get_active_units () { __systemctl list-units | awk ' {print $1}' ; }
-__get_inactive_units () { __systemctl list-units --all | awk '$3 == "inactive" {print $1}' ; }
-__get_failed_units () { __systemctl list-units | awk '$3 == "failed" {print $1}' ; }
-__get_enabled_units () { __systemctl list-unit-files | awk '$2 == "enabled" {print $1}' ; }
-__get_disabled_units () { __systemctl list-unit-files | awk '$2 == "disabled" {print $1}' ; }
-__get_masked_units () { __systemctl list-unit-files | awk '$2 == "masked" {print $1}' ; }
-
-_systemctl () {
- local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
- local verb comps
-
- local -A OPTS=(
- [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global
- --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
- --order --require --quiet -q --privileged -P --system --user --version --runtime'
- [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root'
- )
-
- if __contains_word "$prev" ${OPTS[ARG]}; then
- case $prev in
- --signal|-s)
- comps=$(compgen -A signal)
- ;;
- --type|-t)
- comps='automount device mount path service snapshot socket swap target timer'
- ;;
- --kill-who)
- comps='all control main'
- ;;
- --kill-mode)
- comps='control-group process'
- ;;
- --root)
- comps=$(compgen -A directory -- "$cur" )
- compopt -o filenames
- ;;
- --host|-H)
- comps=$(compgen -A hostname)
- ;;
- --property|-p)
- comps=''
- ;;
- esac
- COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
- return 0
- fi
-
-
- if [[ "$cur" = -* ]]; then
- COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") )
- return 0
- fi
-
- local -A VERBS=(
- [ALL_UNITS]='is-active is-enabled status show mask preset'
- [ENABLED_UNITS]='disable reenable'
- [DISABLED_UNITS]='enable'
- [FAILED_UNITS]='reset-failed'
- [STARTABLE_UNITS]='start'
- [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
- [ISOLATABLE_UNITS]='isolate'
- [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload'
- [RESTARTABLE_UNITS]='restart reload-or-restart'
- [MASKED_UNITS]='unmask'
- [JOBS]='cancel'
- [SNAPSHOTS]='delete'
- [ENVS]='set-environment unset-environment'
- [STANDALONE]='daemon-reexec daemon-reload default dot dump
- emergency exit halt kexec list-jobs list-units
- list-unit-files poweroff reboot rescue show-environment'
- [NAME]='snapshot load'
- [FILE]='link'
- )
-
- for ((i=0; $i <= $COMP_CWORD; i++)); do
- if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
- ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
- verb=${COMP_WORDS[i]}
- break
- fi
- done
-
- if [[ -z $verb ]]; then
- comps="${VERBS[*]}"
-
- elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
- comps=$( __get_all_units )
-
- elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
- comps=$( __get_enabled_units )
-
- elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
- comps=$( __get_disabled_units )
-
- elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
- comps=$( __filter_units_by_property CanStart yes \
- $( __get_inactive_units | grep -Ev '\.(device|snapshot)$' ))
-
- elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
- comps=$( __filter_units_by_property CanStart yes \
- $( __get_all_units | grep -Ev '\.(device|snapshot|socket|timer)$' ))
-
- elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
- comps=$( __filter_units_by_property CanStop yes \
- $( __get_active_units ) )
-
- elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
- comps=$( __filter_units_by_property CanReload yes \
- $( __get_active_units ) )
-
- elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
- comps=$( __filter_units_by_property AllowIsolate yes \
- $( __get_all_units ) )
-
- elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
- comps=$( __get_failed_units )
-
- elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
- comps=$( __get_masked_units )
-
- elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
- comps=''
-
- elif __contains_word "$verb" ${VERBS[JOBS]}; then
- comps=$( __systemctl list-jobs | awk '{print $1}' )
-
- elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then
- comps=$( __systemctl list-units --type snapshot --full --all | awk '{print $1}' )
-
- elif __contains_word "$verb" ${VERBS[ENVS]}; then
- comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' )
- compopt -o nospace
-
- elif __contains_word "$verb" ${VERBS[FILE]}; then
- comps=$( compgen -A file -- "$cur" )
- compopt -o filenames
- fi
-
- COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
- return 0
-}
-complete -F _systemctl systemctl
-
-__get_all_sessions () { systemd-loginctl list-sessions | awk '{print $1}' ; }
-__get_all_users () { systemd-loginctl list-users | awk '{print $2}' ; }
-__get_all_seats () { systemd-loginctl list-seats | awk '{print $1}' ; }
-
-_systemd_loginctl () {
- local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
- local verb comps
-
- local -A OPTS=(
- [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version'
- [ARG]='--host -H --kill-who --property -p --signal -s'
- )
-
- if __contains_word "$prev" ${OPTS[ARG]}; then
- case $prev in
- --signal|-s)
- comps=$(compgen -A signal)
- ;;
- --kill-who)
- comps='all leader'
- ;;
- --host|-H)
- comps=$(compgen -A hostname)
- ;;
- --property|-p)
- comps=''
- ;;
- esac
- COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
- return 0
- fi
-
-
- if [[ "$cur" = -* ]]; then
- COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") )
- return 0
- fi
-
- local -A VERBS=(
- [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session'
- [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user'
- [SEATS]='seat-status show-seat terminate-seat'
- [STANDALONE]='list-sessions list-users list-seats flush-devices'
- [ATTACH]='attach'
- )
-
- for ((i=0; $i <= $COMP_CWORD; i++)); do
- if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
- ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
- verb=${COMP_WORDS[i]}
- break
- fi
- done
-
- if [[ -z $verb ]]; then
- comps="${VERBS[*]}"
-
- elif __contains_word "$verb" ${VERBS[SESSIONS]}; then
- comps=$( __get_all_sessions )
-
- elif __contains_word "$verb" ${VERBS[USERS]}; then
- comps=$( __get_all_users )
-
- elif __contains_word "$verb" ${VERBS[SEATS]}; then
- comps=$( __get_all_seats )
-
- elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
- comps=''
-
- elif __contains_word "$verb" ${VERBS[ATTACH]}; then
- if [[ $prev = $verb ]]; then
- comps=$( __get_all_seats )
- else
- comps=$(compgen -A file -- "$cur" )
- compopt -o filenames
- fi
- fi
-
- COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
- return 0
-}
-complete -F _systemd_loginctl systemd-loginctl
diff --git a/src/systemd-bash-completion.sh b/src/systemd-bash-completion.sh
new file mode 100644
index 0000000..176591f
--- /dev/null
+++ b/src/systemd-bash-completion.sh
@@ -0,0 +1,264 @@
+# This file is part of systemd.
+#
+# Copyright 2010 Ran Benita
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__systemctl() {
+ systemctl --full --no-legend "$@"
+}
+
+__contains_word () {
+ local word=$1; shift
+ for w in $*; do [[ $w = $word ]] && return 0; done
+ return 1
+}
+
+__filter_units_by_property () {
+ local property=$1 value=$2 ; shift ; shift
+ local -a units=( $* )
+ local -a props=( $(__systemctl show --property "$property" -- ${units[*]} | grep -v ^$) )
+ for ((i=0; $i < ${#units[*]}; i++)); do
+ if [[ "${props[i]}" = "$property=$value" ]]; then
+ echo "${units[i]}"
+ fi
+ done
+}
+
+__get_all_units () { __systemctl list-units --all | awk ' {print $1}' ; }
+__get_active_units () { __systemctl list-units | awk ' {print $1}' ; }
+__get_inactive_units () { __systemctl list-units --all | awk '$3 == "inactive" {print $1}' ; }
+__get_failed_units () { __systemctl list-units | awk '$3 == "failed" {print $1}' ; }
+__get_enabled_units () { __systemctl list-unit-files | awk '$2 == "enabled" {print $1}' ; }
+__get_disabled_units () { __systemctl list-unit-files | awk '$2 == "disabled" {print $1}' ; }
+__get_masked_units () { __systemctl list-unit-files | awk '$2 == "masked" {print $1}' ; }
+
+_systemctl () {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local verb comps
+
+ local -A OPTS=(
+ [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global
+ --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
+ --order --require --quiet -q --privileged -P --system --user --version --runtime'
+ [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root'
+ )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --signal|-s)
+ comps=$(compgen -A signal)
+ ;;
+ --type|-t)
+ comps='automount device mount path service snapshot socket swap target timer'
+ ;;
+ --kill-who)
+ comps='all control main'
+ ;;
+ --kill-mode)
+ comps='control-group process'
+ ;;
+ --root)
+ comps=$(compgen -A directory -- "$cur" )
+ compopt -o filenames
+ ;;
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --property|-p)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+ return 0
+ fi
+
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") )
+ return 0
+ fi
+
+ local -A VERBS=(
+ [ALL_UNITS]='is-active is-enabled status show mask preset'
+ [ENABLED_UNITS]='disable reenable'
+ [DISABLED_UNITS]='enable'
+ [FAILED_UNITS]='reset-failed'
+ [STARTABLE_UNITS]='start'
+ [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
+ [ISOLATABLE_UNITS]='isolate'
+ [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload'
+ [RESTARTABLE_UNITS]='restart reload-or-restart'
+ [MASKED_UNITS]='unmask'
+ [JOBS]='cancel'
+ [SNAPSHOTS]='delete'
+ [ENVS]='set-environment unset-environment'
+ [STANDALONE]='daemon-reexec daemon-reload default dot dump
+ emergency exit halt kexec list-jobs list-units
+ list-unit-files poweroff reboot rescue show-environment'
+ [NAME]='snapshot load'
+ [FILE]='link'
+ )
+
+ for ((i=0; $i <= $COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z $verb ]]; then
+ comps="${VERBS[*]}"
+
+ elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
+ comps=$( __get_all_units )
+
+ elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
+ comps=$( __get_enabled_units )
+
+ elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
+ comps=$( __get_disabled_units )
+
+ elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
+ comps=$( __filter_units_by_property CanStart yes \
+ $( __get_inactive_units | grep -Ev '\.(device|snapshot)$' ))
+
+ elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
+ comps=$( __filter_units_by_property CanStart yes \
+ $( __get_all_units | grep -Ev '\.(device|snapshot|socket|timer)$' ))
+
+ elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
+ comps=$( __filter_units_by_property CanStop yes \
+ $( __get_active_units ) )
+
+ elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
+ comps=$( __filter_units_by_property CanReload yes \
+ $( __get_active_units ) )
+
+ elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
+ comps=$( __filter_units_by_property AllowIsolate yes \
+ $( __get_all_units ) )
+
+ elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
+ comps=$( __get_failed_units )
+
+ elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
+ comps=$( __get_masked_units )
+
+ elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
+ comps=''
+
+ elif __contains_word "$verb" ${VERBS[JOBS]}; then
+ comps=$( __systemctl list-jobs | awk '{print $1}' )
+
+ elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then
+ comps=$( __systemctl list-units --type snapshot --full --all | awk '{print $1}' )
+
+ elif __contains_word "$verb" ${VERBS[ENVS]}; then
+ comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' )
+ compopt -o nospace
+
+ elif __contains_word "$verb" ${VERBS[FILE]}; then
+ comps=$( compgen -A file -- "$cur" )
+ compopt -o filenames
+ fi
+
+ COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+ return 0
+}
+complete -F _systemctl systemctl
+
+__get_all_sessions () { systemd-loginctl list-sessions | awk '{print $1}' ; }
+__get_all_users () { systemd-loginctl list-users | awk '{print $2}' ; }
+__get_all_seats () { systemd-loginctl list-seats | awk '{print $1}' ; }
+
+_systemd_loginctl () {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local verb comps
+
+ local -A OPTS=(
+ [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version'
+ [ARG]='--host -H --kill-who --property -p --signal -s'
+ )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --signal|-s)
+ comps=$(compgen -A signal)
+ ;;
+ --kill-who)
+ comps='all leader'
+ ;;
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --property|-p)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+ return 0
+ fi
+
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") )
+ return 0
+ fi
+
+ local -A VERBS=(
+ [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session'
+ [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user'
+ [SEATS]='seat-status show-seat terminate-seat'
+ [STANDALONE]='list-sessions list-users list-seats flush-devices'
+ [ATTACH]='attach'
+ )
+
+ for ((i=0; $i <= $COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z $verb ]]; then
+ comps="${VERBS[*]}"
+
+ elif __contains_word "$verb" ${VERBS[SESSIONS]}; then
+ comps=$( __get_all_sessions )
+
+ elif __contains_word "$verb" ${VERBS[USERS]}; then
+ comps=$( __get_all_users )
+
+ elif __contains_word "$verb" ${VERBS[SEATS]}; then
+ comps=$( __get_all_seats )
+
+ elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+ comps=''
+
+ elif __contains_word "$verb" ${VERBS[ATTACH]}; then
+ if [[ $prev = $verb ]]; then
+ comps=$( __get_all_seats )
+ else
+ comps=$(compgen -A file -- "$cur" )
+ compopt -o filenames
+ fi
+ fi
+
+ COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+ return 0
+}
+complete -F _systemd_loginctl systemd-loginctl

View File

@ -0,0 +1,57 @@
From 59c42570c4191f833c06561ea5c6df134946e1f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 23 Feb 2011 14:03:59 +0100
Subject: [PATCH] systemadm: break timestamp formatting out into a seperate
function
Since the timezone is always local, it doesn't make much sense to
display it. The timestamp is now formatted without the timezone.
I guess it can be further improved, which should be easier now
that it is tucked-away in a separate function.
(cherry picked from commit 8401f1533d6936add337a621c5e58e3bbe9f346a)
---
src/systemadm.vala | 24 +++++++++++-------------
1 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index d45ec64..988e9f1 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -23,6 +23,13 @@ using Pango;
static bool user = false;
+public string format_time(uint64 time_ns) {
+ if (time_ns <= 0)
+ return "";
+ Time timestamp = Time.local((time_t) (time_ns / 1000000));
+ return timestamp.format("%a, %d %b %Y %H:%M:%S");
+}
+
public class LeftLabel : Label {
public LeftLabel(string? text = null) {
if (text != null)
@@ -515,19 +522,10 @@ public class MainWindow : Window {
else
unit_fragment_path_label.set_text_or_na();
- uint64 t = unit.active_enter_timestamp;
- if (t > 0) {
- Time timestamp = Time.local((time_t) (t / 1000000));
- unit_active_enter_timestamp_label.set_text_or_na(timestamp.format("%a, %d %b %Y %H:%M:%S %z"));
- } else
- unit_active_enter_timestamp_label.set_text_or_na();
-
- t = unit.active_exit_timestamp;
- if (t > 0) {
- Time timestamp = Time.local((time_t) (t / 1000000));
- unit_active_exit_timestamp_label.set_text_or_na(timestamp.format("%a, %d %b %Y %H:%M:%S %z"));
- } else
- unit_active_exit_timestamp_label.set_text_or_na();
+
+ unit_active_enter_timestamp_label.set_text_or_na(format_time(unit.active_enter_timestamp));
+
+ unit_active_exit_timestamp_label.set_text_or_na(format_time(unit.active_exit_timestamp));
bool b = unit.can_start;
start_button.set_sensitive(b);

View File

@ -0,0 +1,72 @@
From 5a7251ffb8ea53dd6c0e0b78e78af704bbb1cbb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 24 Feb 2011 16:29:24 +0100
Subject: [PATCH] systemadm: allow sorting of jobs and units (cherry picked
from commit 661ece1029ea454ff76093a5f1b40e9209cac86d)
---
src/systemadm.vala | 31 ++++++++++++++++++++-----------
1 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index 988e9f1..21177bf 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -30,6 +30,13 @@ public string format_time(uint64 time_ns) {
return timestamp.format("%a, %d %b %Y %H:%M:%S");
}
+public void new_column(TreeView view, int column_id, string title) {
+ TreeViewColumn col;
+ col = new TreeViewColumn.with_attributes(title, new CellRendererText(), "text", column_id);
+ col.set_sort_column_id(column_id);
+ view.insert_column(col, -1);
+}
+
public class LeftLabel : Label {
public LeftLabel(string? text = null) {
if (text != null)
@@ -171,22 +178,24 @@ public class MainWindow : Window {
unit_model_filter = new TreeModelFilter(unit_model, null);
unit_model_filter.set_visible_func(unit_filter);
- unit_view = new TreeView.with_model(unit_model_filter);
+ TreeModelSort unit_model_sort = new TreeModelSort.with_model(unit_model_filter);
+
+ unit_view = new TreeView.with_model(unit_model_sort);
job_view = new TreeView.with_model(job_model);
unit_view.cursor_changed.connect(unit_changed);
job_view.cursor_changed.connect(job_changed);
- unit_view.insert_column_with_attributes(-1, "Load State", new CellRendererText(), "text", 2);
- unit_view.insert_column_with_attributes(-1, "Active State", new CellRendererText(), "text", 3);
- unit_view.insert_column_with_attributes(-1, "Unit State", new CellRendererText(), "text", 4);
- unit_view.insert_column_with_attributes(-1, "Unit", new CellRendererText(), "text", 0);
- unit_view.insert_column_with_attributes(-1, "Job", new CellRendererText(), "text", 5);
+ new_column(unit_view, 2, "Load State");
+ new_column(unit_view, 3, "Active State");
+ new_column(unit_view, 4, "Unit State");
+ new_column(unit_view, 0, "Unit");
+ new_column(unit_view, 5, "Job");
- job_view.insert_column_with_attributes(-1, "Job", new CellRendererText(), "text", 0);
- job_view.insert_column_with_attributes(-1, "Unit", new CellRendererText(), "text", 1);
- job_view.insert_column_with_attributes(-1, "Type", new CellRendererText(), "text", 2);
- job_view.insert_column_with_attributes(-1, "State", new CellRendererText(), "text", 3);
+ new_column(job_view, 0, "Job");
+ new_column(job_view, 1, "Unit");
+ new_column(job_view, 2, "Type");
+ new_column(job_view, 3, "State");
ScrolledWindow scroll = new ScrolledWindow(null, null);
scroll.set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
@@ -897,7 +906,7 @@ public class MainWindow : Window {
}
public void unit_type_changed() {
- TreeModelFilter model = (TreeModelFilter) unit_view.get_model();
+ TreeModelFilter model = (TreeModelFilter) ((TreeModelSort) unit_view.get_model()).get_model();
model.refilter();
}

View File

@ -0,0 +1,109 @@
From 24924bc68792f49d73cfaf0ff4dd2975d1c3c765 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 25 Feb 2011 18:20:16 +0100
Subject: [PATCH] systemadm: split the type+status combo box into type combo &
status checkbox (cherry picked from commit
a3c159a23c7cae889f89ed69bbe82c272bf163ca)
---
src/systemadm.vala | 62 +++++++++++++++++++++++++--------------------------
1 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index 21177bf..e78fd7c 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -113,6 +113,7 @@ public class MainWindow : Window {
private RightLabel job_type_label;
private ComboBox unit_type_combo_box;
+ private CheckButton inactive_checkbox;
public MainWindow() throws IOError {
title = user ? "systemd User Service Manager" : "systemd System Manager";
@@ -137,8 +138,7 @@ public class MainWindow : Window {
type_hbox.pack_start(unit_type_combo_box, false, false, 0);
unit_vbox.pack_start(type_hbox, false, false, 0);
- unit_type_combo_box.append_text("Show All Units");
- unit_type_combo_box.append_text("Show Only Live Units");
+ unit_type_combo_box.append_text("Show All");
unit_type_combo_box.append_text("Services");
unit_type_combo_box.append_text("Sockets");
unit_type_combo_box.append_text("Devices");
@@ -146,9 +146,13 @@ public class MainWindow : Window {
unit_type_combo_box.append_text("Automounts");
unit_type_combo_box.append_text("Targets");
unit_type_combo_box.append_text("Snapshots");
- unit_type_combo_box.set_active(1);
+ unit_type_combo_box.set_active(0); // Show All
unit_type_combo_box.changed.connect(unit_type_changed);
+ inactive_checkbox = new CheckButton.with_label("inactive too");
+ inactive_checkbox.toggled.connect(unit_type_changed);
+ type_hbox.pack_start(inactive_checkbox, false, false, 0);
+
unit_load_entry = new Entry();
unit_load_button = new Button.with_mnemonic("_Load");
unit_load_button.set_sensitive(false);
@@ -872,37 +876,31 @@ public class MainWindow : Window {
if (id == null)
return false;
- switch (unit_type_combo_box.get_active()) {
-
- case 0:
- return true;
-
- case 1:
- return active_state != "inactive" || job != "";
-
- case 2:
- return id.has_suffix(".service");
-
- case 3:
- return id.has_suffix(".socket");
-
- case 4:
- return id.has_suffix(".device");
-
- case 5:
- return id.has_suffix(".mount");
-
- case 6:
- return id.has_suffix(".automount");
-
- case 7:
- return id.has_suffix(".target");
+ if (!inactive_checkbox.get_active()
+ && active_state == "inactive" && job == "")
+ return false;
- case 8:
- return id.has_suffix(".snapshot");
+ switch (unit_type_combo_box.get_active()) {
+ case 0:
+ return true;
+ case 1:
+ return id.has_suffix(".service");
+ case 2:
+ return id.has_suffix(".socket");
+ case 3:
+ return id.has_suffix(".device");
+ case 4:
+ return id.has_suffix(".mount");
+ case 5:
+ return id.has_suffix(".automount");
+ case 6:
+ return id.has_suffix(".target");
+ case 7:
+ return id.has_suffix(".snapshot");
+ default:
+ assert(false);
+ return false;
}
-
- return false;
}
public void unit_type_changed() {

View File

@ -0,0 +1,63 @@
From ad2d88f188922c5267f15e25446e7ece114b5ac0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 28 Feb 2011 10:35:23 +0100
Subject: [PATCH] systemadm: filter on swaps, paths, and timers too. (cherry
picked from commit
e377ad0d11e1bd9954c6084956494ebbf41b4486)
---
src/systemadm.vala | 21 +++++++++++++++------
1 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index e78fd7c..6126eca 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -138,13 +138,16 @@ public class MainWindow : Window {
type_hbox.pack_start(unit_type_combo_box, false, false, 0);
unit_vbox.pack_start(type_hbox, false, false, 0);
- unit_type_combo_box.append_text("Show All");
+ unit_type_combo_box.append_text("All unit types");
+ unit_type_combo_box.append_text("Targets");
unit_type_combo_box.append_text("Services");
- unit_type_combo_box.append_text("Sockets");
unit_type_combo_box.append_text("Devices");
unit_type_combo_box.append_text("Mounts");
unit_type_combo_box.append_text("Automounts");
- unit_type_combo_box.append_text("Targets");
+ unit_type_combo_box.append_text("Swaps");
+ unit_type_combo_box.append_text("Sockets");
+ unit_type_combo_box.append_text("Paths");
+ unit_type_combo_box.append_text("Timers");
unit_type_combo_box.append_text("Snapshots");
unit_type_combo_box.set_active(0); // Show All
unit_type_combo_box.changed.connect(unit_type_changed);
@@ -884,9 +887,9 @@ public class MainWindow : Window {
case 0:
return true;
case 1:
- return id.has_suffix(".service");
+ return id.has_suffix(".target");
case 2:
- return id.has_suffix(".socket");
+ return id.has_suffix(".service");
case 3:
return id.has_suffix(".device");
case 4:
@@ -894,8 +897,14 @@ public class MainWindow : Window {
case 5:
return id.has_suffix(".automount");
case 6:
- return id.has_suffix(".target");
+ return id.has_suffix(".swap");
case 7:
+ return id.has_suffix(".socket");
+ case 8:
+ return id.has_suffix(".path");
+ case 9:
+ return id.has_suffix(".timer");
+ case 10:
return id.has_suffix(".snapshot");
default:
assert(false);

View File

@ -0,0 +1,129 @@
From fb6ffd0ed76b175b4eeb1c73b9fd7a3cbcf6ecbb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Tue, 1 Mar 2011 11:18:13 +0100
Subject: [PATCH] systemadm: add a wrappable label and use it for status lines
The new WrapLabel is there to work around a deficiency in GTK,
namely the fact that it is hard to make labels which are both
resizable and wrappable. The code is a port from libview.
(cherry picked from commit 0dd27daff4ba4bdad99b12b85b630ab21c84fa9e)
---
Makefile.am | 3 +-
src/systemadm.vala | 7 ++---
src/wraplabel.vala | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 78 insertions(+), 5 deletions(-)
create mode 100644 src/wraplabel.vala
diff --git a/Makefile.am b/Makefile.am
index 8f1ffdc..54bccb5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1426,7 +1426,8 @@ systemd_stdio_bridge_LDADD = \
systemadm_SOURCES = \
src/systemadm.vala \
- src/systemd-interfaces.vala
+ src/systemd-interfaces.vala \
+ src/wraplabel.vala
systemadm_CFLAGS = \
$(AM_CFLAGS) \
diff --git a/src/systemadm.vala b/src/systemadm.vala
index 6126eca..68652d0 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -46,12 +46,11 @@ public class LeftLabel : Label {
}
}
-public class RightLabel : Label {
+public class RightLabel : WrapLabel {
+
public RightLabel(string? text = null) {
- set_text_or_na(text);
- set_alignment(0, 0);
- set_ellipsize(EllipsizeMode.START);
set_selectable(true);
+ set_text_or_na(text);
}
public void set_text_or_na(string? text = null) {
diff --git a/src/wraplabel.vala b/src/wraplabel.vala
new file mode 100644
index 0000000..49858c3
--- /dev/null
+++ b/src/wraplabel.vala
@@ -0,0 +1,73 @@
+// Copyright (c) 2005 VMware, Inc.
+
+// This is a translation of http://git.gnome.org/browse/meld/tree/meld/ui/wraplabel.py,
+// which in turn is a translation of WrapLabel from libview.
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+// Python translation from wrapLabel.{cc|h} by Gian Mario Tagliaretti
+// Vala translation from wraplabel.py by Zbigniew Jędrzejewski-Szmek
+
+public class WrapLabel : Gtk.Label {
+ private int _wrap_width;
+
+ public WrapLabel(string? text = null) {
+ this._wrap_width = 0;
+ var layout = get_layout();
+ layout.set_wrap(Pango.WrapMode.WORD_CHAR);
+ if (text != null)
+ this.set_text(text);
+ this.set_alignment(0, 0);
+ }
+
+ public override void size_request(out Gtk.Requisition requisition) {
+ int width, height;
+ var layout = get_layout();
+ layout.get_pixel_size(out width, out height);
+ requisition.width = 0;
+ requisition.height = height;
+ }
+
+ public override void size_allocate(Gdk.Rectangle allocation) {
+ base.size_allocate (allocation);
+ this._set_wrap_width(allocation.width);
+ }
+
+ public new void set_text(string str) {
+ base.set_text(str);
+ this._set_wrap_width(this._wrap_width);
+ }
+
+ public new void set_markup(string str) {
+ base.set_markup(str);
+ this._set_wrap_width(this._wrap_width);
+ }
+
+ private void _set_wrap_width(int width) {
+ if (width == 0)
+ return;
+
+ var layout = get_layout();
+ layout.set_width(width * Pango.SCALE);
+ if (_wrap_width != width) {
+ this._wrap_width = width;
+ this.queue_resize();
+ }
+ }
+}

View File

@ -0,0 +1,98 @@
From 6c8061acd30f7cb604953dd75f00bb8f8cc7323b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 3 Mar 2011 20:54:01 +0100
Subject: [PATCH] systemadm: add libgee as dependency and use it for a unit
map (cherry picked from commit
11216eb0bd5aab6b14af004fd2f24d423e3d356d)
---
Makefile.am | 1 +
configure.ac | 2 +-
src/systemadm.vala | 14 ++++++++++++++
3 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 54bccb5..4416ab7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1440,6 +1440,7 @@ systemadm_CFLAGS = \
systemadm_VALAFLAGS = \
--pkg=posix \
--pkg=gtk+-2.0 \
+ --pkg=gee-1.0 \
-g
systemadm_LDADD = \
diff --git a/configure.ac b/configure.ac
index 0ec6f69..56b7d7a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -327,7 +327,7 @@ AM_CONDITIONAL(ENABLE_LOCALED, [test "$have_localed" = "yes"])
have_gtk=no
AC_ARG_ENABLE(gtk, AS_HELP_STRING([--disable-gtk], [disable GTK tools]))
if test "x$enable_gtk" != "xno"; then
- PKG_CHECK_MODULES(GTK, [ gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 ],
+ PKG_CHECK_MODULES(GTK, [ gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0],
[AC_DEFINE(HAVE_GTK, 1, [Define if GTK is available]) have_gtk=yes], have_gtk=no)
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index 68652d0..c893da0 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -79,6 +79,8 @@ public class MainWindow : Window {
private ListStore unit_model;
private ListStore job_model;
+ private Gee.HashMap<string, Unit> unit_map;
+
private Button start_button;
private Button stop_button;
private Button restart_button;
@@ -180,6 +182,8 @@ public class MainWindow : Window {
unit_model = new ListStore(7, typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(Unit));
job_model = new ListStore(6, typeof(string), typeof(string), typeof(string), typeof(string), typeof(Job), typeof(uint32));
+ unit_map = new Gee.HashMap<string, Unit>();
+
TreeModelFilter unit_model_filter;
unit_model_filter = new TreeModelFilter(unit_model, null);
unit_model_filter.set_visible_func(unit_filter);
@@ -355,6 +359,8 @@ public class MainWindow : Window {
"org.freedesktop.systemd1",
i.unit_path);
+ unit_map[i.id] = u;
+
unit_model.append(out iter);
unit_model.set(iter,
0, i.id,
@@ -415,6 +421,10 @@ public class MainWindow : Window {
return u;
}
+ public Unit? get_unit(string id) {
+ return this.unit_map[id];
+ }
+
public void unit_changed() {
Unit u = get_current_unit();
@@ -712,6 +722,8 @@ public class MainWindow : Window {
"org.freedesktop.systemd1",
path);
+ unit_map[id] = u;
+
update_unit_iter(iter, id, u);
} catch (IOError e) {
show_error(e.message);
@@ -773,6 +785,8 @@ public class MainWindow : Window {
}
} while (unit_model.iter_next(ref iter));
+
+ unit_map.unset(id);
}
public void on_job_removed(uint32 id, ObjectPath path, string res) {

View File

@ -0,0 +1,34 @@
From 9a11d4dc5b77fc3b9b33f96888f1a46f5a013786 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 3 Mar 2011 01:30:08 +0100
Subject: [PATCH] systemadm: display dependencies sorted (cherry picked from
commit 8278f06953f5339646e5ff98900321f1525c0a21)
---
src/systemadm.vala | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index c893da0..088ba26 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -458,6 +458,10 @@ public class MainWindow : Window {
}
public string make_dependency_string(string? prefix, string word, string[] dependencies) {
+ Gee.Collection<unowned string> sorted = new Gee.TreeSet<string>();
+ foreach (string i in dependencies)
+ sorted.add(i);
+
bool first = true;
string r;
@@ -466,7 +470,7 @@ public class MainWindow : Window {
else
r = prefix;
- foreach (string i in dependencies) {
+ foreach (string i in sorted) {
if (r != "")
r += first ? "\n" : ",";

View File

@ -0,0 +1,49 @@
From c9e50116433d60c2f296f7f542e43e13a872cc75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 3 Mar 2011 22:20:19 +0100
Subject: [PATCH] systemadm: use color for dependency links (cherry picked
from commit 23b51f17b1cf473bff3ae5332477e2028a5c5f53)
---
src/systemadm.vala | 21 ++++++++++++++++++++-
1 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index 088ba26..eed46b5 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -457,6 +457,25 @@ public class MainWindow : Window {
unit_cgroup_label.set_text_or_na();
}
+ public string format_unit_link(string i) {
+ Unit? u = get_unit(i);
+ if(u == null)
+ return "<span color='grey'>" + i + "</span";
+
+ string color;
+ switch (u.sub_state) {
+ case "active": color = "blue"; break;
+ case "dead": color = "red"; break;
+ case "running": color = "green"; break;
+ default: color = "black"; break;
+ }
+ string span = "<span underline='none' color='" + color + "'>"
+ + i + "(" +
+ u.sub_state + ")" + "</span>";
+ return " <a href='" + i + "'>" + span + "</a>";
+ }
+
+
public string make_dependency_string(string? prefix, string word, string[] dependencies) {
Gee.Collection<unowned string> sorted = new Gee.TreeSet<string>();
foreach (string i in dependencies)
@@ -479,7 +498,7 @@ public class MainWindow : Window {
first = false;
}
- r += " <a href=\"" + i + "\">" + i + "</a>";
+ r += format_unit_link(i);
}
return r;

View File

@ -0,0 +1,23 @@
From 4640202a44277e573dda7125d87e43025436fc4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sat, 17 Sep 2011 14:57:19 +0100
Subject: [PATCH] systemadm: use bold for "requires", etc. (cherry picked from
commit 8b1451ade7794c21d29141dc363d0f626e2070ee)
---
src/systemadm.vala | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index eed46b5..a3068f1 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -494,7 +494,7 @@ public class MainWindow : Window {
r += first ? "\n" : ",";
if (first) {
- r += word;
+ r += "<b>" + word + ":</b>";
first = false;
}

View File

@ -0,0 +1,24 @@
From edafba60cbcaab71266f53f3359126c69106b21c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sun, 18 Sep 2011 11:06:07 +0200
Subject: [PATCH] systemadm: make the dependency listing selectable
There's no reason to forbid selecting the text.
(cherry picked from commit 37d3b881f1cc7c18d23013ff29429ab67ab5b61d)
---
src/systemadm.vala | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index a3068f1..e7fa354 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -238,7 +238,7 @@ public class MainWindow : Window {
job_type_label = new RightLabel();
unit_dependency_label.set_track_visited_links(false);
- unit_dependency_label.set_selectable(false);
+ unit_dependency_label.set_selectable(true);
unit_dependency_label.activate_link.connect(on_activate_link);
unit_fragment_path_label.set_track_visited_links(false);

View File

@ -0,0 +1,143 @@
From 328238ca7c52a658089aa5c8ba0d63dfeaf3c2bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 24 Feb 2011 16:30:55 +0100
Subject: [PATCH] systemadm: catch exceptions generated by dbus
Otherwise, access-denied dbus errors were not caught, and only
caused a message to be printed out on the console. After this
change a proper popup window pops up :).
(cherry picked from commit 734b60d7961a28adab45ef141807a0f3e0ba11e5)
---
src/systemadm.vala | 28 ++++++++++++++--------------
1 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index e7fa354..d420800 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -642,7 +642,7 @@ public class MainWindow : Window {
try {
u.start("replace");
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -655,7 +655,7 @@ public class MainWindow : Window {
try {
u.stop("replace");
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -668,7 +668,7 @@ public class MainWindow : Window {
try {
u.reload("replace");
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -681,7 +681,7 @@ public class MainWindow : Window {
try {
u.restart("replace");
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -694,7 +694,7 @@ public class MainWindow : Window {
try {
j.cancel();
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -722,7 +722,7 @@ public class MainWindow : Window {
4, u.sub_state,
5, t != "" ? "→ %s".printf(t) : "",
6, u);
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -748,7 +748,7 @@ public class MainWindow : Window {
unit_map[id] = u;
update_unit_iter(iter, id, u);
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -784,7 +784,7 @@ public class MainWindow : Window {
update_job_iter(iter, id, j);
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -866,7 +866,7 @@ public class MainWindow : Window {
} while (unit_model.iter_next(ref iter));
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -902,7 +902,7 @@ public class MainWindow : Window {
} while (job_model.iter_next(ref iter));
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -957,7 +957,7 @@ public class MainWindow : Window {
public void on_server_reload() {
try {
manager.reload();
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -969,7 +969,7 @@ public class MainWindow : Window {
if (unit_type_combo_box.get_active() != 0)
unit_type_combo_box.set_active(8);
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -998,7 +998,7 @@ public class MainWindow : Window {
m.destroy();
show_unit(u);
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}
}
@@ -1018,7 +1018,7 @@ public class MainWindow : Window {
path);
show_unit(u);
- } catch (IOError e) {
+ } catch (Error e) {
show_error(e.message);
}

View File

@ -0,0 +1,80 @@
From 5581802cca0ebea3b8a3193f94c80cfc4d0a3111 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sun, 18 Sep 2011 17:00:12 +0200
Subject: [PATCH] systemadm: coalesce id and decription fields
This is just in interest of saving space (e.g. 5 lines for multi-user.target).
(cherry picked from commit 8f38d5a4c6e627180809db739b2bdaa5ca0c645a)
---
src/systemadm.vala | 24 +++++++++++-------------
1 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index d420800..4cb5c55 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -96,7 +96,6 @@ public class MainWindow : Window {
private Manager manager;
private RightLabel unit_id_label;
- private RightLabel unit_aliases_label;
private RightLabel unit_dependency_label;
private RightLabel unit_description_label;
private RightLabel unit_load_state_label;
@@ -220,7 +219,6 @@ public class MainWindow : Window {
job_vbox.pack_start(scroll, true, true, 0);
unit_id_label = new RightLabel();
- unit_aliases_label = new RightLabel();
unit_dependency_label = new RightLabel();
unit_description_label = new RightLabel();
unit_load_state_label = new RightLabel();
@@ -255,8 +253,6 @@ public class MainWindow : Window {
unit_table.attach(new LeftLabel("Id:"), 0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
unit_table.attach(unit_id_label, 1, 6, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(new LeftLabel("Aliases:"), 0, 1, 1, 2, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_aliases_label, 1, 6, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
unit_table.attach(new LeftLabel("Description:"), 0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
unit_table.attach(unit_description_label, 1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
unit_table.attach(new LeftLabel("Dependencies:"), 0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
@@ -443,7 +439,6 @@ public class MainWindow : Window {
restart_button.set_sensitive(false);
unit_id_label.set_text_or_na();
- unit_aliases_label.set_text_or_na();
unit_description_label.set_text_or_na();
unit_description_label.set_text_or_na();
unit_load_state_label.set_text_or_na();
@@ -507,20 +502,23 @@ public class MainWindow : Window {
public void show_unit(Unit unit) {
current_unit_id = unit.id;
- unit_id_label.set_text_or_na(current_unit_id);
-
- string a = "";
+ string id_display = current_unit_id;
+ bool has_alias = false;
foreach (string i in unit.names) {
if (i == current_unit_id)
continue;
- if (a == "")
- a = i;
- else
- a += "\n" + i;
+ if (!has_alias) {
+ id_display += " (aliases:";
+ has_alias = true;
+ }
+
+ id_display += " " + i;
}
+ if(has_alias)
+ id_display += ")";
- unit_aliases_label.set_text_or_na(a);
+ unit_id_label.set_text_or_na(id_display);
string[]
requires = unit.requires,

View File

@ -0,0 +1,72 @@
From e3eece11dcdef669d90fef5f42428a921cad33b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 19 Sep 2011 08:14:02 +0200
Subject: [PATCH] systemadm: adjust row numbers after removing 'aliases'
(cherry picked from commit
fe7e28146f30ec442c0dd7f71002a1b482d910a9)
---
src/systemadm.vala | 50 +++++++++++++++++++++++++-------------------------
1 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index 4cb5c55..1118999 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -253,31 +253,31 @@ public class MainWindow : Window {
unit_table.attach(new LeftLabel("Id:"), 0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
unit_table.attach(unit_id_label, 1, 6, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(new LeftLabel("Description:"), 0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_description_label, 1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(new LeftLabel("Dependencies:"), 0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_dependency_label, 1, 6, 3, 4, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(new LeftLabel("Fragment Path:"), 0, 1, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_fragment_path_label, 1, 6, 4, 5, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(new LeftLabel("Control Group:"), 0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_cgroup_label, 1, 6, 5, 6, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-
- unit_table.attach(new LeftLabel("Load State:"), 0, 1, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_load_state_label, 1, 2, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(new LeftLabel("Active State:"), 0, 1, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_active_state_label, 1, 2, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(new LeftLabel("Unit State:"), 0, 1, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_sub_state_label, 1, 2, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-
- unit_table.attach(new LeftLabel("Active Enter Timestamp:"), 2, 3, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_active_enter_timestamp_label, 3, 4, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(new LeftLabel("Active Exit Timestamp:"), 2, 3, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_active_exit_timestamp_label, 3, 4, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-
- unit_table.attach(new LeftLabel("Can Start/Stop:"), 4, 5, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_can_start_label, 5, 6, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(new LeftLabel("Can Reload:"), 4, 5, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
- unit_table.attach(unit_can_reload_label, 5, 6, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(new LeftLabel("Description:"), 0, 1, 1, 2, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_description_label, 1, 6, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(new LeftLabel("Dependencies:"), 0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_dependency_label, 1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(new LeftLabel("Fragment Path:"), 0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_fragment_path_label, 1, 6, 3, 4, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(new LeftLabel("Control Group:"), 0, 1, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_cgroup_label, 1, 6, 4, 5, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+
+ unit_table.attach(new LeftLabel("Load State:"), 0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_load_state_label, 1, 2, 5, 6, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(new LeftLabel("Active State:"), 0, 1, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_active_state_label, 1, 2, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(new LeftLabel("Unit State:"), 0, 1, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_sub_state_label, 1, 2, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+
+ unit_table.attach(new LeftLabel("Activated:"), 2, 3, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_active_enter_timestamp_label, 3, 4, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(new LeftLabel("Deactivated:"), 2, 3, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_active_exit_timestamp_label, 3, 4, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+
+ unit_table.attach(new LeftLabel("Can Start/Stop:"), 4, 5, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_can_start_label, 5, 6, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(new LeftLabel("Can Reload:"), 4, 5, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ unit_table.attach(unit_can_reload_label, 5, 6, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
job_table.attach(new LeftLabel("Id:"), 0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
job_table.attach(job_id_label, 1, 2, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);

View File

@ -0,0 +1,74 @@
From d21907af22f1c14445521cb6ae5cabccbe186bcc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 19 Sep 2011 08:20:17 +0200
Subject: [PATCH] systemadm: use colors for id too, remove color from fragment
link (cherry picked from commit
79b1e6cb8080e5c88754484f5af591ce74714ff0)
---
src/systemadm.vala | 17 +++++++++++------
1 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index 1118999..5971ac0 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -452,7 +452,7 @@ public class MainWindow : Window {
unit_cgroup_label.set_text_or_na();
}
- public string format_unit_link(string i) {
+ public string format_unit_link(string i, bool link) {
Unit? u = get_unit(i);
if(u == null)
return "<span color='grey'>" + i + "</span";
@@ -467,7 +467,10 @@ public class MainWindow : Window {
string span = "<span underline='none' color='" + color + "'>"
+ i + "(" +
u.sub_state + ")" + "</span>";
- return " <a href='" + i + "'>" + span + "</a>";
+ if(link)
+ return " <a href='" + i + "'>" + span + "</a>";
+ else
+ return span;
}
@@ -493,7 +496,7 @@ public class MainWindow : Window {
first = false;
}
- r += format_unit_link(i);
+ r += format_unit_link(i, true);
}
return r;
@@ -502,7 +505,7 @@ public class MainWindow : Window {
public void show_unit(Unit unit) {
current_unit_id = unit.id;
- string id_display = current_unit_id;
+ string id_display = format_unit_link(current_unit_id, false);
bool has_alias = false;
foreach (string i in unit.names) {
if (i == current_unit_id)
@@ -518,7 +521,7 @@ public class MainWindow : Window {
if(has_alias)
id_display += ")";
- unit_id_label.set_text_or_na(id_display);
+ unit_id_label.set_markup_or_na(id_display);
string[]
requires = unit.requires,
@@ -564,7 +567,9 @@ public class MainWindow : Window {
string fp = unit.fragment_path;
if (fp != "")
- unit_fragment_path_label.set_markup_or_na("<a href=\"file://" + fp +"\">" + fp + "</a>" );
+ unit_fragment_path_label.set_markup_or_na(
+ "<a href=\"file://" + fp +"\">" +
+ "<span underline='none' color='black'>" + fp + "</span></a>");
else
unit_fragment_path_label.set_text_or_na();

View File

@ -0,0 +1,52 @@
From 54a91c5eae72181cc7aadf618c152e18ac336b5e Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Thu, 3 Nov 2011 19:42:53 +0100
Subject: [PATCH] cgroup: immediately remove all cgroups which run empty
Some controllers have scaling problems when many empty cgroups exist.
Hence, as soon as we get a notification that a cgroup is empty, delete
it. This is also nice to keep the systemd-cgls output short.
(cherry picked from commit 353fa6a21aab96b0b82ab40cc22b08b1fb0bf652)
---
src/cgroup.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/cgroup.c b/src/cgroup.c
index be837c3..4bbb54f 100644
--- a/src/cgroup.c
+++ b/src/cgroup.c
@@ -363,7 +363,8 @@ int cgroup_notify_empty(Manager *m, const char *group) {
assert(m);
assert(group);
- if (!(l = hashmap_get(m->cgroup_bondings, group)))
+ l = hashmap_get(m->cgroup_bondings, group);
+ if (!l)
return 0;
LIST_FOREACH(by_path, b, l) {
@@ -372,7 +373,8 @@ int cgroup_notify_empty(Manager *m, const char *group) {
if (!b->unit)
continue;
- if ((t = cgroup_bonding_is_empty_list(b)) < 0) {
+ t = cgroup_bonding_is_empty_list(b);
+ if (t < 0) {
/* If we don't know, we don't know */
if (t != -EAGAIN)
@@ -381,9 +383,13 @@ int cgroup_notify_empty(Manager *m, const char *group) {
continue;
}
- if (t > 0)
+ if (t > 0) {
+ /* If it is empty, let's delete it */
+ cgroup_bonding_trim_list(b->unit->meta.cgroup_bondings, true);
+
if (UNIT_VTABLE(b->unit)->cgroup_notify_empty)
UNIT_VTABLE(b->unit)->cgroup_notify_empty(b->unit);
+ }
}
return 0;

View File

@ -0,0 +1,134 @@
From 9052b8afdf507b674b2e3abfb803d96c19c0a307 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sun, 6 Nov 2011 23:06:38 +0100
Subject: [PATCH] utmp: remove unneded parameters
With these functions no caller ever passes anything else than 0
for 't' (meaning the current time will be used).
(cherry picked from commit 0ad26e09de813857382ec3a787fc6df5e52cf98b)
---
src/execute.c | 2 +-
src/systemctl.c | 2 +-
src/update-utmp.c | 4 ++--
src/utmp-wtmp.c | 12 ++++++------
src/utmp-wtmp.h | 6 +++---
5 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/execute.c b/src/execute.c
index 866e8bf..250d53a 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1170,7 +1170,7 @@ int exec_spawn(ExecCommand *command,
}
if (context->utmp_id)
- utmp_put_init_process(0, context->utmp_id, getpid(), getsid(0), context->tty_path);
+ utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path);
if (context->user) {
username = context->user;
diff --git a/src/systemctl.c b/src/systemctl.c
index b0baf8d..4426f70 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -5156,7 +5156,7 @@ static int halt_main(DBusConnection *bus) {
if (!arg_no_wtmp) {
if (sd_booted() > 0)
log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
- else if ((r = utmp_put_shutdown(0)) < 0)
+ else if ((r = utmp_put_shutdown()) < 0)
log_warning("Failed to write utmp record: %s", strerror(-r));
}
diff --git a/src/update-utmp.c b/src/update-utmp.c
index 12e4d11..073f28e 100644
--- a/src/update-utmp.c
+++ b/src/update-utmp.c
@@ -284,7 +284,7 @@ static int on_shutdown(Context *c) {
}
#endif
- if ((q = utmp_put_shutdown(0)) < 0) {
+ if ((q = utmp_put_shutdown()) < 0) {
log_error("Failed to write utmp record: %s", strerror(-q));
r = q;
}
@@ -339,7 +339,7 @@ static int on_runlevel(Context *c) {
}
#endif
- if ((q = utmp_put_runlevel(0, runlevel, previous)) < 0) {
+ if ((q = utmp_put_runlevel(runlevel, previous)) < 0) {
log_error("Failed to write utmp record: %s", strerror(-q));
r = q;
}
diff --git a/src/utmp-wtmp.c b/src/utmp-wtmp.c
index b03a3e7..e7b2e3c 100644
--- a/src/utmp-wtmp.c
+++ b/src/utmp-wtmp.c
@@ -172,10 +172,10 @@ static int write_entry_both(const struct utmpx *store) {
return r;
}
-int utmp_put_shutdown(usec_t t) {
+int utmp_put_shutdown(void) {
struct utmpx store;
- init_entry(&store, t);
+ init_entry(&store, 0);
store.ut_type = RUN_LVL;
strncpy(store.ut_user, "shutdown", sizeof(store.ut_user));
@@ -206,12 +206,12 @@ static const char *sanitize_id(const char *id) {
return id + l - sizeof(((struct utmpx*) NULL)->ut_id);
}
-int utmp_put_init_process(usec_t t, const char *id, pid_t pid, pid_t sid, const char *line) {
+int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line) {
struct utmpx store;
assert(id);
- init_timestamp(&store, t);
+ init_timestamp(&store, 0);
store.ut_type = INIT_PROCESS;
store.ut_pid = pid;
@@ -257,7 +257,7 @@ int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
}
-int utmp_put_runlevel(usec_t t, int runlevel, int previous) {
+int utmp_put_runlevel(int runlevel, int previous) {
struct utmpx store;
int r;
@@ -277,7 +277,7 @@ int utmp_put_runlevel(usec_t t, int runlevel, int previous) {
if (previous == runlevel)
return 0;
- init_entry(&store, t);
+ init_entry(&store, 0);
store.ut_type = RUN_LVL;
store.ut_pid = (runlevel & 0xFF) | ((previous & 0xFF) << 8);
diff --git a/src/utmp-wtmp.h b/src/utmp-wtmp.h
index 4054aff..a5998eb 100644
--- a/src/utmp-wtmp.h
+++ b/src/utmp-wtmp.h
@@ -26,12 +26,12 @@
int utmp_get_runlevel(int *runlevel, int *previous);
-int utmp_put_shutdown(usec_t timestamp);
+int utmp_put_shutdown(void);
int utmp_put_reboot(usec_t timestamp);
-int utmp_put_runlevel(usec_t timestamp, int runlevel, int previous);
+int utmp_put_runlevel(int runlevel, int previous);
int utmp_put_dead_process(const char *id, pid_t pid, int code, int status);
-int utmp_put_init_process(usec_t timestamp, const char *id, pid_t pid, pid_t sid, const char *line);
+int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line);
int utmp_wall(const char *message, bool (*match_tty)(const char *tty));

View File

@ -0,0 +1,24 @@
From ddd712b60245be98042ad5212597ef9ec9833ccf Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sun, 6 Nov 2011 23:07:54 +0100
Subject: [PATCH] utmp: no need to zero a struct before overwriting it with
memcpy (cherry picked from commit
b8e47420b32b52619c6c49c98a663bee7929ccbe)
---
src/utmp-wtmp.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/src/utmp-wtmp.c b/src/utmp-wtmp.c
index e7b2e3c..98c1a25 100644
--- a/src/utmp-wtmp.c
+++ b/src/utmp-wtmp.c
@@ -242,8 +242,6 @@ int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
if (found->ut_pid != pid)
return 0;
- zero(store);
-
memcpy(&store, &lookup, sizeof(store));
store.ut_type = DEAD_PROCESS;
store.ut_exit.e_termination = code;

View File

@ -0,0 +1,24 @@
From b2072011a7998e22f6d8a4f2a815ed3dbab819cc Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sun, 6 Nov 2011 23:31:46 +0100
Subject: [PATCH] utmp: initialize store with the found entry, not with the
lookup key (cherry picked from commit
fa4ad7ceca6c96d9f0b7022819acf8954cba35ea)
---
src/utmp-wtmp.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/utmp-wtmp.c b/src/utmp-wtmp.c
index 98c1a25..00e19a3 100644
--- a/src/utmp-wtmp.c
+++ b/src/utmp-wtmp.c
@@ -242,7 +242,7 @@ int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
if (found->ut_pid != pid)
return 0;
- memcpy(&store, &lookup, sizeof(store));
+ memcpy(&store, found, sizeof(store));
store.ut_type = DEAD_PROCESS;
store.ut_exit.e_termination = code;
store.ut_exit.e_exit = status;

View File

@ -0,0 +1,68 @@
From 404b71bb18c983f62897ed40d9a4b310ddcca86a Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sun, 6 Nov 2011 23:55:06 +0100
Subject: [PATCH] utmp: for DEAD_PROCESS write the current time to wtmp
Zeroed .ut_tv values in wtmp confuse chkrootkit.
Reported and debugged by Norman Smith. This is based on his patch,
but modified to behave more like upstart did in F14 and cleaned up.
https://bugzilla.redhat.com/show_bug.cgi?id=743696
(cherry picked from commit 4743137a4b7ce6214a06d02872bdfac080b6f131)
---
src/utmp-wtmp.c | 18 +++++++++++++-----
1 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/src/utmp-wtmp.c b/src/utmp-wtmp.c
index 00e19a3..217ae1e 100644
--- a/src/utmp-wtmp.c
+++ b/src/utmp-wtmp.c
@@ -155,11 +155,11 @@ static int write_entry_wtmp(const struct utmpx *store) {
return -errno;
}
-static int write_entry_both(const struct utmpx *store) {
+static int write_utmp_wtmp(const struct utmpx *store_utmp, const struct utmpx *store_wtmp) {
int r, s;
- r = write_entry_utmp(store);
- s = write_entry_wtmp(store);
+ r = write_entry_utmp(store_utmp);
+ s = write_entry_wtmp(store_wtmp);
if (r >= 0)
r = s;
@@ -172,6 +172,10 @@ static int write_entry_both(const struct utmpx *store) {
return r;
}
+static int write_entry_both(const struct utmpx *store) {
+ return write_utmp_wtmp(store, store);
+}
+
int utmp_put_shutdown(void) {
struct utmpx store;
@@ -226,7 +230,7 @@ int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line
}
int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
- struct utmpx lookup, store, *found;
+ struct utmpx lookup, store, store_wtmp, *found;
assert(id);
@@ -251,7 +255,11 @@ int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
zero(store.ut_host);
zero(store.ut_tv);
- return write_entry_both(&store);
+ memcpy(&store_wtmp, &store, sizeof(store_wtmp));
+ /* wtmp wants the current time */
+ init_timestamp(&store_wtmp, 0);
+
+ return write_utmp_wtmp(&store, &store_wtmp);
}

View File

@ -0,0 +1,23 @@
From abd72ba81496bd84a970faa7daec3bacd6a81356 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Mon, 7 Nov 2011 01:08:21 +0100
Subject: [PATCH] man: fix a typo in signal number (cherry picked from commit
75c982a79f68a9209f0bcaf422d50414167bc5d1)
---
man/systemd.xml | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/man/systemd.xml b/man/systemd.xml
index a8a6967..c1766e2 100644
--- a/man/systemd.xml
+++ b/man/systemd.xml
@@ -813,7 +813,7 @@
<listitem><para>Sets the log level to
<literal>debug</literal>
(resp. <literal>info</literal> on
- <literal>SIGRTMIN+32</literal>), as
+ <literal>SIGRTMIN+23</literal>), as
controlled via
<varname>systemd.log_level=debug</varname>
(resp. <varname>systemd.log_level=info</varname>

View File

@ -0,0 +1,76 @@
From 27b67ec67a39321dd52828002a50868071cb5bbf Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Wed, 9 Nov 2011 08:42:03 +0100
Subject: [PATCH] units: drop unnecessary 'StandardOutput=syslog'
DefaultStandardOutput is syslog anyway. There's no reason to assume that
the administrator would want these units to be excluded when he configures
a different DefaultStandardOutput.
(cherry picked from commit c99e42c1db91eb1982b90a1aa631f4c4a765f95e)
---
units/quotacheck.service.in | 1 -
units/quotaon.service | 1 -
units/remount-rootfs.service | 1 -
units/systemd-logind.service.in | 1 -
units/systemd-remount-api-vfs.service.in | 1 -
units/systemd-vconsole-setup.service.in | 1 -
6 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/units/quotacheck.service.in b/units/quotacheck.service.in
index 27dcb1e..c97b7a4 100644
--- a/units/quotacheck.service.in
+++ b/units/quotacheck.service.in
@@ -16,5 +16,4 @@ ConditionPathExists=/sbin/quotacheck
Type=oneshot
RemainAfterExit=yes
ExecStart=@rootlibexecdir@/systemd-quotacheck
-StandardOutput=syslog
TimeoutSec=0
diff --git a/units/quotaon.service b/units/quotaon.service
index 2c7b36b..ef2fc8c 100644
--- a/units/quotaon.service
+++ b/units/quotaon.service
@@ -16,4 +16,3 @@ ConditionPathExists=/sbin/quotaon
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/quotaon -aug
-StandardOutput=syslog
diff --git a/units/remount-rootfs.service b/units/remount-rootfs.service
index 89a16c8..7b63752 100644
--- a/units/remount-rootfs.service
+++ b/units/remount-rootfs.service
@@ -17,4 +17,3 @@ Wants=local-fs-pre.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/mount / -o remount
-StandardOutput=syslog
diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
index 4241b8b..c332039 100644
--- a/units/systemd-logind.service.in
+++ b/units/systemd-logind.service.in
@@ -15,7 +15,6 @@ ExecStart=@rootlibexecdir@/systemd-logind
Type=dbus
BusName=org.freedesktop.login1
CapabilityBoundingSet=CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER
-StandardOutput=syslog
# Increase the default a bit in order to allow many simultaneous
# logins since we keep one fd open per session.
diff --git a/units/systemd-remount-api-vfs.service.in b/units/systemd-remount-api-vfs.service.in
index 6339ee6..f4df0ca 100644
--- a/units/systemd-remount-api-vfs.service.in
+++ b/units/systemd-remount-api-vfs.service.in
@@ -17,4 +17,3 @@ Wants=local-fs-pre.target
Type=oneshot
RemainAfterExit=yes
ExecStart=@rootlibexecdir@/systemd-remount-api-vfs
-StandardOutput=syslog
diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in
index 91d95d6..673fb6c 100644
--- a/units/systemd-vconsole-setup.service.in
+++ b/units/systemd-vconsole-setup.service.in
@@ -16,4 +16,3 @@ Before=sysinit.target shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=@rootlibexecdir@/systemd-vconsole-setup
-StandardOutput=syslog

View File

@ -0,0 +1,25 @@
From a8fda0ca8760ccad7630b9dd4b544577ce97d232 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Wed, 9 Nov 2011 08:58:36 +0100
Subject: [PATCH] units/fedora: let rc-local.service log to syslog
rc-local.service should not be excluded from the default stdout logging.
Missing logs were noticed by Andrew McNabb in
https://bugzilla.redhat.com/show_bug.cgi?id=750032#c3
(cherry picked from commit 9d7286112d8b54da0294ca0d6bbd7314d890b7e2)
---
units/fedora/rc-local.service | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service
index f5f940f..106b12c 100644
--- a/units/fedora/rc-local.service
+++ b/units/fedora/rc-local.service
@@ -13,6 +13,5 @@ ConditionFileIsExecutable=/etc/rc.d/rc.local
Type=forking
ExecStart=/etc/rc.d/rc.local start
TimeoutSec=0
-StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99

View File

@ -0,0 +1,58 @@
From 3fdac700a322217421675774e25cfd5cb09c2dd2 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 10 Nov 2011 09:55:47 +0100
Subject: [PATCH] service: don't warn if the pidfile still exists after
SIGCHLD
A service that drops its privileges may not be able to remove it when it
exits. The stale pidfile is not a problem as long as the service
carefully recognizes it on its next start.
systemd would produce a warning after the service exits:
PID ... read from file ... does not exist. Your service or init
script might be broken.
Silence the warning in this case. Still warn if this error is detected
when loading the pidfile after service start.
Noticed by Miroslav Lichvar in
https://bugzilla.redhat.com/show_bug.cgi?id=752396
(cherry picked from commit c5419d4239ceb4c3bd0263a0a810cf24a072b3c0)
---
src/service.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/service.c b/src/service.c
index e64d289..d51445e 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1282,7 +1282,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
free(p2);
}
-static int service_load_pid_file(Service *s, bool warn_if_missing) {
+static int service_load_pid_file(Service *s, bool may_warn) {
char *k;
int r;
pid_t pid;
@@ -1293,7 +1293,7 @@ static int service_load_pid_file(Service *s, bool warn_if_missing) {
return -ENOENT;
if ((r = read_one_line_file(s->pid_file, &k)) < 0) {
- if (warn_if_missing)
+ if (may_warn)
log_warning("Failed to read PID file %s after %s. The service might be broken.",
s->pid_file, service_state_to_string(s->state));
return r;
@@ -1306,8 +1306,9 @@ static int service_load_pid_file(Service *s, bool warn_if_missing) {
return r;
if (kill(pid, 0) < 0 && errno != EPERM) {
- log_warning("PID %lu read from file %s does not exist. Your service or init script might be broken.",
- (unsigned long) pid, s->pid_file);
+ if (may_warn)
+ log_warning("PID %lu read from file %s does not exist. Your service or init script might be broken.",
+ (unsigned long) pid, s->pid_file);
return -ESRCH;
}

View File

@ -0,0 +1,129 @@
From dd36a516b3945e64578ab4190499266ae44b1155 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 10 Nov 2011 12:53:39 +0100
Subject: [PATCH] job: colored status messages on boot
The lack or green/red status marks on boot has been described by some
users as "critical", "dramatic", "dealbreaker", "showstopper". Seriously.
(cherry picked from commit 5831e9b726ab6e76b28a94861a014d3bc2aa3015)
---
src/job.c | 13 +++++++------
src/unit.c | 24 ++++++++++++++++++++----
src/unit.h | 2 +-
3 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/src/job.c b/src/job.c
index 20971da..1520d81 100644
--- a/src/job.c
+++ b/src/job.c
@@ -484,19 +484,20 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
switch (result) {
case JOB_DONE:
- unit_status_printf(u, "Started %s.\n", unit_description(u));
+ unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Started %s", unit_description(u));
break;
case JOB_FAILED:
- unit_status_printf(u, "Starting %s " ANSI_HIGHLIGHT_ON "failed" ANSI_HIGHLIGHT_OFF ", see 'systemctl status %s' for details.\n", unit_description(u), u->meta.id);
+ unit_status_printf(u, ANSI_HIGHLIGHT_ON "FAILED" ANSI_HIGHLIGHT_OFF, "Failed to start %s", unit_description(u));
+ unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->meta.id);
break;
case JOB_DEPENDENCY:
- unit_status_printf(u, "Starting %s " ANSI_HIGHLIGHT_ON "aborted" ANSI_HIGHLIGHT_OFF " because a dependency failed.\n", unit_description(u));
+ unit_status_printf(u, ANSI_HIGHLIGHT_ON " ABORT" ANSI_HIGHLIGHT_OFF, "Dependency failed. Aborted start of %s", unit_description(u));
break;
case JOB_TIMEOUT:
- unit_status_printf(u, "Starting %s " ANSI_HIGHLIGHT_ON "timed out" ANSI_HIGHLIGHT_OFF ".\n", unit_description(u), u->meta.id);
+ unit_status_printf(u, ANSI_HIGHLIGHT_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out starting %s", unit_description(u));
break;
default:
@@ -508,12 +509,12 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
switch (result) {
case JOB_TIMEOUT:
- unit_status_printf(u, "Stopping %s " ANSI_HIGHLIGHT_ON "timed out" ANSI_HIGHLIGHT_OFF ".\n", unit_description(u), u->meta.id);
+ unit_status_printf(u, ANSI_HIGHLIGHT_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out stopping %s", unit_description(u));
break;
case JOB_DONE:
case JOB_FAILED:
- unit_status_printf(u, "Stopped %s.\n", unit_description(u));
+ unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Stopped %s", unit_description(u));
break;
default:
diff --git a/src/unit.c b/src/unit.c
index 903a8e4..ad4063b 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -924,7 +924,7 @@ int unit_start(Unit *u) {
unit_add_to_dbus_queue(u);
- unit_status_printf(u, "Starting %s...\n", unit_description(u));
+ unit_status_printf(u, NULL, "Starting %s...", unit_description(u));
return UNIT_VTABLE(u)->start(u);
}
@@ -966,7 +966,7 @@ int unit_stop(Unit *u) {
unit_add_to_dbus_queue(u);
- unit_status_printf(u, "Stopping %s...\n", unit_description(u));
+ unit_status_printf(u, NULL, "Stopping %s...", unit_description(u));
return UNIT_VTABLE(u)->stop(u);
}
@@ -2426,8 +2426,11 @@ int unit_coldplug(Unit *u) {
return 0;
}
-void unit_status_printf(Unit *u, const char *format, ...) {
+void unit_status_printf(Unit *u, const char *status, const char *format, ...) {
va_list ap;
+ char *s, *e;
+ int err;
+ const unsigned emax = status ? 80 - (sizeof("[ OK ]")-1) : 80;
assert(u);
assert(format);
@@ -2442,8 +2445,21 @@ void unit_status_printf(Unit *u, const char *format, ...) {
return;
va_start(ap, format);
- status_vprintf(format, ap);
+ err = vasprintf(&s, format, ap);
va_end(ap);
+ if (err < 0)
+ return;
+
+ e = ellipsize(s, emax, 100);
+ free(s);
+ if (!e)
+ return;
+
+ if (status)
+ status_printf("%s%*s[%s]\n", e, emax - strlen(e), "", status);
+ else
+ status_printf("%s\n", e);
+ free(e);
}
bool unit_need_daemon_reload(Unit *u) {
diff --git a/src/unit.h b/src/unit.h
index 7da5723..b32c1a7 100644
--- a/src/unit.h
+++ b/src/unit.h
@@ -512,7 +512,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants);
int unit_coldplug(Unit *u);
-void unit_status_printf(Unit *u, const char *format, ...);
+void unit_status_printf(Unit *u, const char *status, const char *format, ...);
bool unit_need_daemon_reload(Unit *u);

View File

@ -0,0 +1,24 @@
From acd5d830990975310998d28800cad086357a80c0 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 11 Nov 2011 10:48:17 +0100
Subject: [PATCH] man: fix typo in sd_notify
Noticed by guzu.
(cherry picked from commit 9f84624270432cdff35c4f499fbdb9e0f94fe705)
---
man/sd_notify.xml | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/man/sd_notify.xml b/man/sd_notify.xml
index dd0ba93..62347f8 100644
--- a/man/sd_notify.xml
+++ b/man/sd_notify.xml
@@ -166,7 +166,7 @@
for details.</para>
<para><function>sd_notifyf()</function> is similar to
- <function>sd_notifyf()</function> but takes a
+ <function>sd_notify()</function> but takes a
<function>printf()</function>-like format string plus
arguments.</para>
</refsect1>

View File

@ -0,0 +1,29 @@
From b3070998c22feaa3b85337c56fb437527aec962e Mon Sep 17 00:00:00 2001
From: Thomas Jarosch <thomas.jarosch@intra2net.com>
Date: Wed, 9 Nov 2011 20:48:31 +0100
Subject: [PATCH] Fix same expression on both sides of '&&'
The code should probably look like the statements above it.
Please verify, I just detected it using cppcheck.
Signed-off-by: Thomas Jarosch <thomas.jarosch@intra2net.com>
(cherry picked from commit 085c98af4eb17858b4687068f12eccc51a032732)
---
src/unit.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/unit.c b/src/unit.c
index ad4063b..2a549e2 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -564,8 +564,8 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
c->std_error != EXEC_OUTPUT_KMSG &&
- c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
- c->std_error != EXEC_OUTPUT_KMSG &&
+ c->std_error != EXEC_OUTPUT_SYSLOG &&
+ c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
return 0;

View File

@ -0,0 +1,58 @@
From 838ad64f4f4502f370dcbf5faaed94b618bdac08 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Wed, 16 Nov 2011 23:45:01 +0100
Subject: [PATCH] execute: avoid logging to closed fds
Several functions called from the "sd(EXEC)" process try to log messages
when all the file descriptors are already closed, including the logging
ones. The logging functions do not expect their fds to be closed and
they hit an assertion failure. The failure wants to be logged too,
so there is an infinite recursion, ended by a SIGSEGV.
When we close all fds, we must let log.c know about it.
(cherry picked from commit 4d8a7798e7f12c6400495cbc4d0ad57ed20ce90a)
---
src/execute.c | 1 +
src/log.c | 4 ++++
src/log.h | 1 +
3 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/src/execute.c b/src/execute.c
index 250d53a..0651014 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1016,6 +1016,7 @@ int exec_spawn(ExecCommand *command,
/* Close sockets very early to make sure we don't
* block init reexecution because it cannot bind its
* sockets */
+ log_forget_fds();
if (close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
socket_fd >= 0 ? 1 : n_fds) < 0) {
r = EXIT_FDS;
diff --git a/src/log.c b/src/log.c
index b8ce122..5c5b734 100644
--- a/src/log.c
+++ b/src/log.c
@@ -237,6 +237,10 @@ void log_close(void) {
log_close_syslog();
}
+void log_forget_fds(void) {
+ console_fd = kmsg_fd = syslog_fd = -1;
+}
+
void log_set_max_level(int level) {
assert((level & LOG_PRIMASK) == level);
diff --git a/src/log.h b/src/log.h
index c402afb..9942e3e 100644
--- a/src/log.h
+++ b/src/log.h
@@ -57,6 +57,7 @@ int log_get_max_level(void);
int log_open(void);
void log_close(void);
+void log_forget_fds(void);
void log_close_syslog(void);
void log_close_kmsg(void);

View File

@ -0,0 +1,45 @@
From 859dc200c20c5dd7e49e443bd29ab6c31dfb0b69 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 17 Nov 2011 00:16:22 +0100
Subject: [PATCH] execute: make setup_pam() return -errno when possible
The only caller currently checks if the result is non-zero,
so nothing changes there.
(cherry picked from commit 9ba353983adc026b75a503c1381f6e5c8062f3e0)
---
src/execute.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/src/execute.c b/src/execute.c
index 0651014..2039861 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -716,6 +716,7 @@ static int setup_pam(
pam_handle_t *handle = NULL;
sigset_t ss, old_ss;
int pam_code = PAM_SUCCESS;
+ int err;
char **e = NULL;
bool close_session = false;
pid_t pam_pid = 0, parent_pid;
@@ -835,6 +836,11 @@ static int setup_pam(
return 0;
fail:
+ if (pam_code != PAM_SUCCESS)
+ err = -EPERM; /* PAM errors do not map to errno */
+ else
+ err = -errno;
+
if (handle) {
if (close_session)
pam_code = pam_close_session(handle, PAM_DATA_SILENT);
@@ -851,7 +857,7 @@ fail:
kill(pam_pid, SIGCONT);
}
- return EXIT_PAM;
+ return err;
}
#endif

View File

@ -0,0 +1,475 @@
From 43516d8c437d0afd7f4a70592487291e45675101 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 17 Nov 2011 00:21:16 +0100
Subject: [PATCH] execute: log errors from "sd(EXEC)"
To give the administrator more hints about failures occuring in spawning
of commands than just the exit code, log the strerror.
All fds are closed, so reopen the log.
Related-to: https://bugzilla.redhat.com/show_bug.cgi?id=752901
(cherry picked from commit 4c2630ebf23b6348174f0bdf1110e90efe45259c)
---
src/execute.c | 138 +++++++++++++++++++++++++++++++++++++++--------------
src/exit-status.c | 3 +
src/exit-status.h | 3 +-
3 files changed, 107 insertions(+), 37 deletions(-)
diff --git a/src/execute.c b/src/execute.c
index 2039861..481725d 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -989,7 +989,7 @@ int exec_spawn(ExecCommand *command,
}
if (pid == 0) {
- int i;
+ int i, err;
sigset_t ss;
const char *username = NULL, *home = NULL;
uid_t uid = (uid_t) -1;
@@ -1015,6 +1015,7 @@ int exec_spawn(ExecCommand *command,
if (sigemptyset(&ss) < 0 ||
sigprocmask(SIG_SETMASK, &ss, NULL) < 0) {
+ err = -errno;
r = EXIT_SIGNAL_MASK;
goto fail_child;
}
@@ -1023,14 +1024,16 @@ int exec_spawn(ExecCommand *command,
* block init reexecution because it cannot bind its
* sockets */
log_forget_fds();
- if (close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
- socket_fd >= 0 ? 1 : n_fds) < 0) {
+ err = close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
+ socket_fd >= 0 ? 1 : n_fds);
+ if (err < 0) {
r = EXIT_FDS;
goto fail_child;
}
if (!context->same_pgrp)
if (setsid() < 0) {
+ err = -errno;
r = EXIT_SETSID;
goto fail_child;
}
@@ -1038,12 +1041,14 @@ int exec_spawn(ExecCommand *command,
if (context->tcpwrap_name) {
if (socket_fd >= 0)
if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) {
+ err = -EACCES;
r = EXIT_TCPWRAP;
goto fail_child;
}
for (i = 0; i < (int) n_fds; i++) {
if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) {
+ err = -EACCES;
r = EXIT_TCPWRAP;
goto fail_child;
}
@@ -1059,11 +1064,14 @@ int exec_spawn(ExecCommand *command,
/* Set up terminal for the question */
if ((r = setup_confirm_stdio(context,
- &saved_stdin, &saved_stdout)))
+ &saved_stdin, &saved_stdout))) {
+ err = -errno;
goto fail_child;
+ }
/* Now ask the question. */
if (!(line = exec_command_line(argv))) {
+ err = -ENOMEM;
r = EXIT_MEMORY;
goto fail_child;
}
@@ -1072,18 +1080,21 @@ int exec_spawn(ExecCommand *command,
free(line);
if (r < 0 || response == 'n') {
+ err = -ECANCELED;
r = EXIT_CONFIRM;
goto fail_child;
} else if (response == 's') {
- r = 0;
+ err = r = 0;
goto fail_child;
}
/* Release terminal for the question */
if ((r = restore_confirm_stdio(context,
&saved_stdin, &saved_stdout,
- &keep_stdin, &keep_stdout)))
+ &keep_stdin, &keep_stdout))) {
+ err = -errno;
goto fail_child;
+ }
}
/* If a socket is connected to STDIN/STDOUT/STDERR, we
@@ -1091,28 +1102,35 @@ int exec_spawn(ExecCommand *command,
if (socket_fd >= 0)
fd_nonblock(socket_fd, false);
- if (!keep_stdin)
- if (setup_input(context, socket_fd, apply_tty_stdin) < 0) {
+ if (!keep_stdin) {
+ err = setup_input(context, socket_fd, apply_tty_stdin);
+ if (err < 0) {
r = EXIT_STDIN;
goto fail_child;
}
+ }
- if (!keep_stdout)
- if (setup_output(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin) < 0) {
+ if (!keep_stdout) {
+ err = setup_output(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin);
+ if (err < 0) {
r = EXIT_STDOUT;
goto fail_child;
}
+ }
- if (setup_error(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin) < 0) {
+ err = setup_error(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin);
+ if (err < 0) {
r = EXIT_STDERR;
goto fail_child;
}
- if (cgroup_bondings)
- if (cgroup_bonding_install_list(cgroup_bondings, 0) < 0) {
+ if (cgroup_bondings) {
+ err = cgroup_bonding_install_list(cgroup_bondings, 0);
+ if (err < 0) {
r = EXIT_CGROUP;
goto fail_child;
}
+ }
if (context->oom_score_adjust_set) {
char t[16];
@@ -1133,6 +1151,7 @@ int exec_spawn(ExecCommand *command,
if (write_one_line_file("/proc/self/oom_adj", t) < 0
&& errno != EACCES) {
+ err = -errno;
r = EXIT_OOM_ADJUST;
goto fail_child;
}
@@ -1141,6 +1160,7 @@ int exec_spawn(ExecCommand *command,
if (context->nice_set)
if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
+ err = -errno;
r = EXIT_NICE;
goto fail_child;
}
@@ -1153,6 +1173,7 @@ int exec_spawn(ExecCommand *command,
if (sched_setscheduler(0, context->cpu_sched_policy |
(context->cpu_sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0), &param) < 0) {
+ err = -errno;
r = EXIT_SETSCHEDULER;
goto fail_child;
}
@@ -1160,18 +1181,21 @@ int exec_spawn(ExecCommand *command,
if (context->cpuset)
if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
+ err = -errno;
r = EXIT_CPUAFFINITY;
goto fail_child;
}
if (context->ioprio_set)
if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
+ err = -errno;
r = EXIT_IOPRIO;
goto fail_child;
}
if (context->timer_slack_nsec_set)
if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
+ err = -errno;
r = EXIT_TIMERSLACK;
goto fail_child;
}
@@ -1181,36 +1205,45 @@ int exec_spawn(ExecCommand *command,
if (context->user) {
username = context->user;
- if (get_user_creds(&username, &uid, &gid, &home) < 0) {
+ err = get_user_creds(&username, &uid, &gid, &home);
+ if (err < 0) {
r = EXIT_USER;
goto fail_child;
}
- if (is_terminal_input(context->std_input))
- if (chown_terminal(STDIN_FILENO, uid) < 0) {
+ if (is_terminal_input(context->std_input)) {
+ err = chown_terminal(STDIN_FILENO, uid);
+ if (err < 0) {
r = EXIT_STDIN;
goto fail_child;
}
+ }
- if (cgroup_bondings && context->control_group_modify)
- if (cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid) < 0 ||
- cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid) < 0) {
+ if (cgroup_bondings && context->control_group_modify) {
+ err = cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid);
+ if (err >= 0)
+ err = cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid);
+ if (err < 0) {
r = EXIT_CGROUP;
goto fail_child;
}
+ }
}
- if (apply_permissions)
- if (enforce_groups(context, username, gid) < 0) {
+ if (apply_permissions) {
+ err = enforce_groups(context, username, gid);
+ if (err < 0) {
r = EXIT_GROUP;
goto fail_child;
}
+ }
umask(context->umask);
#ifdef HAVE_PAM
if (context->pam_name && username) {
- if (setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds) != 0) {
+ err = setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds);
+ if (err < 0) {
r = EXIT_PAM;
goto fail_child;
}
@@ -1218,6 +1251,7 @@ int exec_spawn(ExecCommand *command,
#endif
if (context->private_network) {
if (unshare(CLONE_NEWNET) < 0) {
+ err = -errno;
r = EXIT_NETWORK;
goto fail_child;
}
@@ -1229,23 +1263,28 @@ int exec_spawn(ExecCommand *command,
strv_length(context->read_only_dirs) > 0 ||
strv_length(context->inaccessible_dirs) > 0 ||
context->mount_flags != MS_SHARED ||
- context->private_tmp)
- if ((r = setup_namespace(
- context->read_write_dirs,
- context->read_only_dirs,
- context->inaccessible_dirs,
- context->private_tmp,
- context->mount_flags)) < 0)
+ context->private_tmp) {
+ err = setup_namespace(context->read_write_dirs,
+ context->read_only_dirs,
+ context->inaccessible_dirs,
+ context->private_tmp,
+ context->mount_flags);
+ if (err < 0) {
+ r = EXIT_NAMESPACE;
goto fail_child;
+ }
+ }
if (apply_chroot) {
if (context->root_directory)
if (chroot(context->root_directory) < 0) {
+ err = -errno;
r = EXIT_CHROOT;
goto fail_child;
}
if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
+ err = -errno;
r = EXIT_CHDIR;
goto fail_child;
}
@@ -1256,11 +1295,13 @@ int exec_spawn(ExecCommand *command,
if (asprintf(&d, "%s/%s",
context->root_directory ? context->root_directory : "",
context->working_directory ? context->working_directory : "") < 0) {
+ err = -ENOMEM;
r = EXIT_MEMORY;
goto fail_child;
}
if (chdir(d) < 0) {
+ err = -errno;
free(d);
r = EXIT_CHDIR;
goto fail_child;
@@ -1271,9 +1312,12 @@ int exec_spawn(ExecCommand *command,
/* We repeat the fd closing here, to make sure that
* nothing is leaked from the PAM modules */
- if (close_all_fds(fds, n_fds) < 0 ||
- shift_fds(fds, n_fds) < 0 ||
- flags_fds(fds, n_fds, context->non_blocking) < 0) {
+ err = close_all_fds(fds, n_fds);
+ if (err >= 0)
+ err = shift_fds(fds, n_fds);
+ if (err >= 0)
+ err = flags_fds(fds, n_fds, context->non_blocking);
+ if (err < 0) {
r = EXIT_FDS;
goto fail_child;
}
@@ -1285,22 +1329,27 @@ int exec_spawn(ExecCommand *command,
continue;
if (setrlimit(i, context->rlimit[i]) < 0) {
+ err = -errno;
r = EXIT_LIMITS;
goto fail_child;
}
}
- if (context->capability_bounding_set_drop)
- if (do_capability_bounding_set_drop(context->capability_bounding_set_drop) < 0) {
+ if (context->capability_bounding_set_drop) {
+ err = do_capability_bounding_set_drop(context->capability_bounding_set_drop);
+ if (err < 0) {
r = EXIT_CAPABILITIES;
goto fail_child;
}
+ }
- if (context->user)
- if (enforce_user(context, uid) < 0) {
+ if (context->user) {
+ err = enforce_user(context, uid);
+ if (err < 0) {
r = EXIT_USER;
goto fail_child;
}
+ }
/* PR_GET_SECUREBITS is not privileged, while
* PR_SET_SECUREBITS is. So to suppress
@@ -1308,18 +1357,21 @@ int exec_spawn(ExecCommand *command,
* PR_SET_SECUREBITS unless necessary. */
if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
+ err = -errno;
r = EXIT_SECUREBITS;
goto fail_child;
}
if (context->capabilities)
if (cap_set_proc(context->capabilities) < 0) {
+ err = -errno;
r = EXIT_CAPABILITIES;
goto fail_child;
}
}
if (!(our_env = new0(char*, 7))) {
+ err = -ENOMEM;
r = EXIT_MEMORY;
goto fail_child;
}
@@ -1327,12 +1379,14 @@ int exec_spawn(ExecCommand *command,
if (n_fds > 0)
if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 ||
asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) {
+ err = -ENOMEM;
r = EXIT_MEMORY;
goto fail_child;
}
if (home)
if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) {
+ err = -ENOMEM;
r = EXIT_MEMORY;
goto fail_child;
}
@@ -1340,6 +1394,7 @@ int exec_spawn(ExecCommand *command,
if (username)
if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 ||
asprintf(our_env + n_env++, "USER=%s", username) < 0) {
+ err = -ENOMEM;
r = EXIT_MEMORY;
goto fail_child;
}
@@ -1348,6 +1403,7 @@ int exec_spawn(ExecCommand *command,
context->std_output == EXEC_OUTPUT_TTY ||
context->std_error == EXEC_OUTPUT_TTY)
if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) {
+ err = -ENOMEM;
r = EXIT_MEMORY;
goto fail_child;
}
@@ -1362,11 +1418,13 @@ int exec_spawn(ExecCommand *command,
files_env,
pam_env,
NULL))) {
+ err = -ENOMEM;
r = EXIT_MEMORY;
goto fail_child;
}
if (!(final_argv = replace_env_argv(argv, final_env))) {
+ err = -ENOMEM;
r = EXIT_MEMORY;
goto fail_child;
}
@@ -1374,9 +1432,17 @@ int exec_spawn(ExecCommand *command,
final_env = strv_env_clean(final_env);
execve(command->path, final_argv, final_env);
+ err = -errno;
r = EXIT_EXEC;
fail_child:
+ if (r != 0) {
+ log_open();
+ log_warning("Failed at step %s spawning %s: %s",
+ exit_status_to_string(r, EXIT_STATUS_SYSTEMD),
+ command->path, strerror(-err));
+ }
+
strv_free(our_env);
strv_free(final_env);
strv_free(pam_env);
diff --git a/src/exit-status.c b/src/exit-status.c
index 8ed1a0e..ab8907d 100644
--- a/src/exit-status.c
+++ b/src/exit-status.c
@@ -119,6 +119,9 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
case EXIT_NETWORK:
return "NETWORK";
+
+ case EXIT_NAMESPACE:
+ return "NAMESPACE";
}
}
diff --git a/src/exit-status.h b/src/exit-status.h
index 3e977b1..44ef879 100644
--- a/src/exit-status.h
+++ b/src/exit-status.h
@@ -65,7 +65,8 @@ typedef enum ExitStatus {
EXIT_STDERR,
EXIT_TCPWRAP,
EXIT_PAM,
- EXIT_NETWORK
+ EXIT_NETWORK,
+ EXIT_NAMESPACE
} ExitStatus;

View File

@ -0,0 +1,24 @@
From d9e63f3d535758350a83b9b39050e98e01d8d638 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 19 Nov 2011 01:14:11 +0100
Subject: [PATCH] pam-module: use the correct session type "unspecified"
logind does not understand "other".
(cherry picked from commit 1dc995370987660ff045ff4d7cf512da0390cf96)
---
src/pam-module.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/pam-module.c b/src/pam-module.c
index dd05f93..e650886 100644
--- a/src/pam-module.c
+++ b/src/pam-module.c
@@ -472,7 +472,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
get_seat_from_display(display, &seat, &vtnr);
type = !isempty(display) ? "x11" :
- !isempty(tty) ? "tty" : "other";
+ !isempty(tty) ? "tty" : "unspecified";
remote = !isempty(remote_host) && !streq(remote_host, "localhost") && !streq(remote_host, "localhost.localdomain");

View File

@ -0,0 +1,52 @@
From ecac03685b4679d53c0ec86db257e061bec2d2c9 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 19 Nov 2011 01:17:46 +0100
Subject: [PATCH] pam-module: treat "cron" in PAM_TTY as empty tty
cron sets PAM_TTY to "cron" and it has been doing it for a long time.
It cannot be changed because user configurations may depend on it.
https://bugzilla.redhat.com/show_bug.cgi?id=727315
(cherry picked from commit 1a4459d63323cdfdb8751077e555ddbbf80564b1)
---
src/logind-session.c | 4 ++--
src/pam-module.c | 4 ++++
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/logind-session.c b/src/logind-session.c
index b0a09e3..63ee758 100644
--- a/src/logind-session.c
+++ b/src/logind-session.c
@@ -536,7 +536,7 @@ int session_start(Session *s) {
if (r < 0)
return r;
- log_full(s->display || s->tty ? LOG_INFO : LOG_DEBUG,
+ log_full(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG,
"New session %s of user %s.", s->id, s->user->name);
/* Create cgroup */
@@ -659,7 +659,7 @@ int session_stop(Session *s) {
assert(s);
if (s->started)
- log_full(s->display || s->tty ? LOG_INFO : LOG_DEBUG,
+ log_full(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG,
"Removed session %s.", s->id);
/* Kill cgroup */
diff --git a/src/pam-module.c b/src/pam-module.c
index e650886..46b7bec 100644
--- a/src/pam-module.c
+++ b/src/pam-module.c
@@ -463,6 +463,10 @@ _public_ PAM_EXTERN int pam_sm_open_session(
if (isempty(display))
display = tty;
tty = "";
+ } else if (streq(tty, "cron")) {
+ /* cron has been setting PAM_TTY to "cron" for a very long time
+ * and it cannot stop doing that for compatibility reasons. */
+ tty = "";
}
if (!isempty(cvtnr))

View File

@ -0,0 +1,52 @@
From 003cb5ce02b9660a790ab330796e92b5d79806b6 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 19 Nov 2011 02:47:09 +0100
Subject: [PATCH] let mount and swap units log to the configured defaults
Related-to: https://bugzilla.redhat.com/show_bug.cgi?id=750032
(cherry picked from commit f6cebb3bd5a00d79c8131637c0f6796a75e6af99)
---
src/mount.c | 6 ++++--
src/swap.c | 5 +++--
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/mount.c b/src/mount.c
index f9cfe91..47422cc 100644
--- a/src/mount.c
+++ b/src/mount.c
@@ -68,8 +68,10 @@ static void mount_init(Unit *u) {
/* The stdio/kmsg bridge socket is on /, in order to avoid a
* dep loop, don't use kmsg logging for -.mount */
- if (!unit_has_name(u, "-.mount"))
- m->exec_context.std_output = EXEC_OUTPUT_KMSG;
+ if (!unit_has_name(u, "-.mount")) {
+ m->exec_context.std_output = u->meta.manager->default_std_output;
+ m->exec_context.std_error = u->meta.manager->default_std_error;
+ }
/* We need to make sure that /bin/mount is always called in
* the same process group as us, so that the autofs kernel
diff --git a/src/swap.c b/src/swap.c
index 54a8640..4fa30a3 100644
--- a/src/swap.c
+++ b/src/swap.c
@@ -74,7 +74,7 @@ static void swap_unset_proc_swaps(Swap *s) {
s->parameters_proc_swaps.what = NULL;
}
- static void swap_init(Unit *u) {
+static void swap_init(Unit *u) {
Swap *s = SWAP(u);
assert(s);
@@ -83,7 +83,8 @@ static void swap_unset_proc_swaps(Swap *s) {
s->timeout_usec = DEFAULT_TIMEOUT_USEC;
exec_context_init(&s->exec_context);
- s->exec_context.std_output = EXEC_OUTPUT_KMSG;
+ s->exec_context.std_output = u->meta.manager->default_std_output;
+ s->exec_context.std_error = u->meta.manager->default_std_error;
s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;

View File

@ -0,0 +1,91 @@
From 1a542f80955b0d425412f5c3dd604483747db133 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Tue, 29 Nov 2011 22:15:41 +0100
Subject: [PATCH] socket: add option for SO_PASSCRED
Add an option to enable SO_PASSCRED for unix sockets.
(cherry picked from commit d68af58657ce0e99594dff199fbb9b319cf6af96)
---
src/dbus-socket.c | 2 ++
src/load-fragment-gperf.gperf.m4 | 1 +
src/socket.c | 8 ++++++++
src/socket.h | 1 +
4 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/src/dbus-socket.c b/src/dbus-socket.c
index 2a1a17d..37ab7eb 100644
--- a/src/dbus-socket.c
+++ b/src/dbus-socket.c
@@ -51,6 +51,7 @@
" <property name=\"FreeBind\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"Transparent\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"Broadcast\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"PassCred\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"Mark\" type=\"i\" access=\"read\"/>\n" \
" <property name=\"MaxConnections\" type=\"u\" access=\"read\"/>\n" \
" <property name=\"NAccepted\" type=\"u\" access=\"read\"/>\n" \
@@ -113,6 +114,7 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMes
{ "org.freedesktop.systemd1.Socket", "FreeBind", bus_property_append_bool, "b", &u->socket.free_bind },
{ "org.freedesktop.systemd1.Socket", "Transparent", bus_property_append_bool, "b", &u->socket.transparent },
{ "org.freedesktop.systemd1.Socket", "Broadcast", bus_property_append_bool, "b", &u->socket.broadcast },
+ { "org.freedesktop.systemd1.Socket", "PassCred", bus_property_append_bool, "b", &u->socket.pass_cred },
{ "org.freedesktop.systemd1.Socket", "Mark", bus_property_append_int, "i", &u->socket.mark },
{ "org.freedesktop.systemd1.Socket", "MaxConnections", bus_property_append_unsigned, "u", &u->socket.max_connections },
{ "org.freedesktop.systemd1.Socket", "NConnections", bus_property_append_unsigned, "u", &u->socket.n_connections },
diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4
index 41797d2..84ae28c 100644
--- a/src/load-fragment-gperf.gperf.m4
+++ b/src/load-fragment-gperf.gperf.m4
@@ -177,6 +177,7 @@ Socket.PipeSize, config_parse_size, 0,
Socket.FreeBind, config_parse_bool, 0, offsetof(Socket, free_bind)
Socket.Transparent, config_parse_bool, 0, offsetof(Socket, transparent)
Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast)
+Socket.PassCred, config_parse_bool, 0, offsetof(Socket, pass_cred)
Socket.TCPCongestion, config_parse_string, 0, offsetof(Socket, tcp_congestion)
Socket.MessageQueueMaxMessages, config_parse_long, 0, offsetof(Socket, mq_maxmsg)
Socket.MessageQueueMessageSize, config_parse_long, 0, offsetof(Socket, mq_msgsize)
diff --git a/src/socket.c b/src/socket.c
index 7ddf326..0864cce 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -406,6 +406,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
"%sFreeBind: %s\n"
"%sTransparent: %s\n"
"%sBroadcast: %s\n"
+ "%sPassCred: %s\n"
"%sTCPCongestion: %s\n",
prefix, socket_state_to_string(s->state),
prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
@@ -416,6 +417,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
prefix, yes_no(s->free_bind),
prefix, yes_no(s->transparent),
prefix, yes_no(s->broadcast),
+ prefix, yes_no(s->pass_cred),
prefix, strna(s->tcp_congestion));
if (s->control_pid > 0)
@@ -657,6 +659,12 @@ static void socket_apply_socket_options(Socket *s, int fd) {
log_warning("SO_BROADCAST failed: %m");
}
+ if (s->pass_cred) {
+ int one = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
+ log_warning("SO_PASSCRED failed: %m");
+ }
+
if (s->priority >= 0)
if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0)
log_warning("SO_PRIORITY failed: %m");
diff --git a/src/socket.h b/src/socket.h
index fd13ac4..fbd29da 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -118,6 +118,7 @@ struct Socket {
bool free_bind;
bool transparent;
bool broadcast;
+ bool pass_cred;
int priority;
int mark;
size_t receive_buffer;

View File

@ -0,0 +1,55 @@
From 6811dc0646d92f0c668cbf3ce5a6426e273c4abf Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Tue, 29 Nov 2011 23:14:36 +0100
Subject: [PATCH] shutdownd: use PassCred=yes in the socket unit
Since Linux 3.2 in order to receive SCM_CREDENTIALS it is not sufficient
to set SO_PASSCRED just before recvmsg(). The option has to be already
set when the sender sends the message.
With socket activation it is too late to set the option in the service.
It must be set on the socket right from the start.
See the kernel commit:
16e57262 af_unix: dont send SCM_CREDENTIALS by default
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=757628
(cherry picked from commit 75d3fc60f88e08bf953063819a8a04b881d6db23)
---
src/shutdownd.c | 6 ------
units/systemd-shutdownd.socket | 1 +
2 files changed, 1 insertions(+), 6 deletions(-)
diff --git a/src/shutdownd.c b/src/shutdownd.c
index 0ffa8b2..46856b0 100644
--- a/src/shutdownd.c
+++ b/src/shutdownd.c
@@ -173,7 +173,6 @@ int main(int argc, char *argv[]) {
};
int r = EXIT_FAILURE, n_fds;
- int one = 1;
struct shutdownd_command c;
struct pollfd pollfd[_FD_MAX];
bool exec_shutdown = false, unlink_nologin = false, failed = false;
@@ -205,11 +204,6 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
- if (setsockopt(SD_LISTEN_FDS_START, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) {
- log_error("SO_PASSCRED failed: %m");
- return EXIT_FAILURE;
- }
-
zero(c);
zero(pollfd);
diff --git a/units/systemd-shutdownd.socket b/units/systemd-shutdownd.socket
index bc0358a..13b6c7a 100644
--- a/units/systemd-shutdownd.socket
+++ b/units/systemd-shutdownd.socket
@@ -15,3 +15,4 @@ Before=sockets.target
[Socket]
ListenDatagram=/run/systemd/shutdownd
SocketMode=0600
+PassCred=yes

View File

@ -0,0 +1,49 @@
From 20f36bebf9cb9655cb8ac606b70461e4db7ecbde Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Wed, 30 Nov 2011 09:37:13 +0100
Subject: [PATCH] syslog: use PassCred=yes for the /dev/log socket
Both kmsg-syslogd and the real syslog service want to receive
SCM_CREDENTIALS. With socket activation it is too late to set
SO_PASSCRED in the services.
(cherry picked from commit 1a2801529e916ec31d2a8cc66cd5c3b8d9ad9caa)
---
src/kmsg-syslogd.c | 5 +----
units/syslog.socket | 1 +
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/kmsg-syslogd.c b/src/kmsg-syslogd.c
index 0901a0e..7fd69f8 100644
--- a/src/kmsg-syslogd.c
+++ b/src/kmsg-syslogd.c
@@ -91,7 +91,7 @@ static int server_init(Server *s, unsigned n_sockets) {
}
for (i = 0; i < n_sockets; i++) {
- int fd, one = 1;
+ int fd;
fd = SD_LISTEN_FDS_START+i;
@@ -106,9 +106,6 @@ static int server_init(Server *s, unsigned n_sockets) {
goto fail;
}
- if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
- log_error("SO_PASSCRED failed: %m");
-
zero(ev);
ev.events = EPOLLIN;
ev.data.fd = fd;
diff --git a/units/syslog.socket b/units/syslog.socket
index 500bb7c..e74b559 100644
--- a/units/syslog.socket
+++ b/units/syslog.socket
@@ -18,6 +18,7 @@ Wants=syslog.target
[Socket]
ListenDatagram=/dev/log
SocketMode=0666
+PassCred=yes
# The service we activate on incoming traffic is
# systemd-kmsg-syslogd.service. That doesn't mean however, that this

View File

@ -0,0 +1,32 @@
From b1d7dbb539fcbd671ec4ddce1d162fe3543440ea Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Wed, 30 Nov 2011 11:06:35 +0100
Subject: [PATCH] man: document the PassCred option (cherry picked from commit
42e87475cfe20a5e79da882012629f9d3ae63648)
---
man/systemd.socket.xml | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 28c8dc4..2f31242 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -525,6 +525,17 @@
</varlistentry>
<varlistentry>
+ <term><varname>PassCred=</varname></term>
+ <listitem><para>Takes a boolean
+ value. This controls the SO_PASSCRED
+ option, which allows UNIX sockets to
+ receive the credentials of the sending
+ process in an ancillary message.
+ Defaults to
+ <option>false</option>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>TCPCongestion=</varname></term>
<listitem><para>Takes a string
value. Controls the TCP congestion

View File

@ -0,0 +1,247 @@
From a40cb5c2aaa67a66c20b17f18cb30fd7b65154d4 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 2 Dec 2011 10:18:46 +0100
Subject: [PATCH] add a generator to pull rc-local.service in
rc-local.service acts as an ordering barrier even if its condition is
false, because conditions are evaluated when the service is about to be
started.
To avoid the ordering barrier in a legacy-free system, add a generator
to pull rc-local.service into the transaction only if the script is
executable.
If/when we rewrite SysV compatibility into a generator, this one can become
a part of it.
(cherry picked from commit 156730831730701cada2750e826abbf7b113861f)
Conflicts:
Makefile.am
---
Makefile.am | 24 ++++++----
src/rc-local-generator.c | 107 +++++++++++++++++++++++++++++++++++++++++
units/fedora/rc-local.service | 4 +-
units/suse/rc-local.service | 2 +
4 files changed, 127 insertions(+), 10 deletions(-)
create mode 100644 src/rc-local-generator.c
diff --git a/Makefile.am b/Makefile.am
index 4416ab7..4d04db3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -522,6 +522,8 @@ dist_systemunit_DATA += \
units/fedora/prefdm.service \
units/fedora/rc-local.service \
units/fedora/halt-local.service
+systemgenerator_PROGRAMS += \
+ systemd-rc-local-generator
endif
if TARGET_MANDRIVA
@@ -529,6 +531,8 @@ dist_systemunit_DATA += \
units/mandriva/prefdm.service \
units/fedora/rc-local.service \
units/fedora/halt-local.service
+systemgenerator_PROGRAMS += \
+ systemd-rc-local-generator
endif
if TARGET_FRUGALWARE
@@ -540,6 +544,8 @@ if TARGET_SUSE
dist_systemunit_DATA += \
units/suse/rc-local.service \
units/suse/halt-local.service
+systemgenerator_PROGRAMS += \
+ systemd-rc-local-generator
endif
if HAVE_PLYMOUTH
@@ -1256,6 +1262,15 @@ systemd_getty_generator_CFLAGS = \
systemd_getty_generator_LDADD = \
libsystemd-basic.la
+systemd_rc_local_generator_SOURCES = \
+ src/rc-local-generator.c
+
+systemd_rc_local_generator_CFLAGS = \
+ $(AM_CFLAGS)
+
+systemd_rc_local_generator_LDADD = \
+ libsystemd-basic.la
+
systemd_user_sessions_SOURCES = \
src/user-sessions.c \
src/cgroup-util.c
@@ -1949,9 +1964,6 @@ endif
if TARGET_FEDORA
$(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants
- ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \
- rm -f rc-local.service && \
- $(LN_S) $(systemunitdir)/rc-local.service rc-local.service )
( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \
rm -f halt-local.service && \
$(LN_S) $(systemunitdir)/halt-local.service halt-local.service )
@@ -1966,9 +1978,6 @@ endif
if TARGET_MANDRIVA
$(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants
- ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \
- rm -f rc-local.service && \
- $(LN_S) $(systemunitdir)/rc-local.service rc-local.service )
( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \
rm -f halt-local.service && \
$(LN_S) $(systemunitdir)/halt-local.service halt-local.service )
@@ -1990,9 +1999,6 @@ endif
if TARGET_SUSE
$(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants
- ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \
- rm -f rc-local.service && \
- $(LN_S) $(systemunitdir)/rc-local.service rc-local.service )
( cd $(DESTDIR)$(systemunitdir) && \
rm -f local.service && \
$(LN_S) rc-local.service local.service )
diff --git a/src/rc-local-generator.c b/src/rc-local-generator.c
new file mode 100644
index 0000000..ac6424a
--- /dev/null
+++ b/src/rc-local-generator.c
@@ -0,0 +1,107 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+ Copyright 2011 Michal Schmidt
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "util.h"
+
+#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+#define SCRIPT_PATH "/etc/rc.d/rc.local"
+#elif defined(TARGET_SUSE)
+#define SCRIPT_PATH "/etc/init.d/boot.local"
+#endif
+
+const char *arg_dest = "/tmp";
+
+static int add_symlink(const char *service) {
+ char *from = NULL, *to = NULL;
+ int r;
+
+ assert(service);
+
+ asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", service);
+ asprintf(&to, "%s/multi-user.target.wants/%s", arg_dest, service);
+
+ if (!from || !to) {
+ log_error("Out of memory");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ mkdir_parents(to, 0755);
+
+ r = symlink(from, to);
+ if (r < 0) {
+ if (errno == EEXIST)
+ r = 0;
+ else {
+ log_error("Failed to create symlink from %s to %s: %m", from, to);
+ r = -errno;
+ }
+ }
+
+finish:
+
+ free(from);
+ free(to);
+
+ return r;
+}
+
+static bool file_is_executable(const char *f) {
+ struct stat st;
+
+ if (stat(f, &st) < 0)
+ return false;
+
+ return S_ISREG(st.st_mode) && (st.st_mode & 0111);
+}
+
+int main(int argc, char *argv[]) {
+
+ int r = EXIT_SUCCESS;
+
+ if (argc > 2) {
+ log_error("This program takes one or no arguments.");
+ return EXIT_FAILURE;
+ }
+
+ log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
+ log_parse_environment();
+ log_open();
+
+ if (argc > 1)
+ arg_dest = argv[1];
+
+ if (file_is_executable(SCRIPT_PATH)) {
+ log_debug("Automatically adding rc-local.service.");
+
+ if (add_symlink("rc-local.service") < 0)
+ r = EXIT_FAILURE;
+
+ }
+
+ return r;
+}
diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service
index 106b12c..fade90c 100644
--- a/units/fedora/rc-local.service
+++ b/units/fedora/rc-local.service
@@ -5,8 +5,10 @@
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
+# This unit gets pulled automatically into multi-user.target by
+# systemd-rc-local-generator if /etc/rc.d/rc.local is executable.
[Unit]
-Description=/etc/rc.local Compatibility
+Description=/etc/rc.d/rc.local Compatibility
ConditionFileIsExecutable=/etc/rc.d/rc.local
[Service]
diff --git a/units/suse/rc-local.service b/units/suse/rc-local.service
index fe4c007..df9a09b 100644
--- a/units/suse/rc-local.service
+++ b/units/suse/rc-local.service
@@ -5,6 +5,8 @@
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
+# This unit gets pulled automatically into multi-user.target by
+# systemd-rc-local-generator if /etc/init.d/boot.local is executable.
[Unit]
Description=/etc/init.d/boot.local Compatibility
ConditionFileIsExecutable=/etc/init.d/boot.local

View File

@ -0,0 +1,37 @@
From 6d3970658de8f270b651e8b4cffbc464e3774428 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 2 Dec 2011 11:32:04 +0100
Subject: [PATCH] rc-local: no need to check if the script is executable
rc-local.service is pulled in by a generator only if the script is
executable. No need to check again.
(cherry picked from commit e951701a4d90152447e195e926e0e12c7dcc0051)
---
units/fedora/rc-local.service | 1 -
units/suse/rc-local.service | 1 -
2 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service
index fade90c..36100df 100644
--- a/units/fedora/rc-local.service
+++ b/units/fedora/rc-local.service
@@ -9,7 +9,6 @@
# systemd-rc-local-generator if /etc/rc.d/rc.local is executable.
[Unit]
Description=/etc/rc.d/rc.local Compatibility
-ConditionFileIsExecutable=/etc/rc.d/rc.local
[Service]
Type=forking
diff --git a/units/suse/rc-local.service b/units/suse/rc-local.service
index df9a09b..11dc581 100644
--- a/units/suse/rc-local.service
+++ b/units/suse/rc-local.service
@@ -9,7 +9,6 @@
# systemd-rc-local-generator if /etc/init.d/boot.local is executable.
[Unit]
Description=/etc/init.d/boot.local Compatibility
-ConditionFileIsExecutable=/etc/init.d/boot.local
[Service]
Type=oneshot

View File

@ -0,0 +1,39 @@
From 7f0aa58747b7335c7856fb7153be6cd1e22b74b6 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 2 Dec 2011 11:32:52 +0100
Subject: [PATCH] rc-local: order after network.target
As suggested by Bill Nottingham: rc.local is often used for frobbing the
network.
https://bugzilla.redhat.com/show_bug.cgi?id=754789
(cherry picked from commit 91b684c7300879a8d2006038f7d9185d92c3c3bf)
---
units/fedora/rc-local.service | 1 +
units/suse/rc-local.service | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service
index 36100df..0bef5c7 100644
--- a/units/fedora/rc-local.service
+++ b/units/fedora/rc-local.service
@@ -9,6 +9,7 @@
# systemd-rc-local-generator if /etc/rc.d/rc.local is executable.
[Unit]
Description=/etc/rc.d/rc.local Compatibility
+After=network.target
[Service]
Type=forking
diff --git a/units/suse/rc-local.service b/units/suse/rc-local.service
index 11dc581..454095c 100644
--- a/units/suse/rc-local.service
+++ b/units/suse/rc-local.service
@@ -9,6 +9,7 @@
# systemd-rc-local-generator if /etc/init.d/boot.local is executable.
[Unit]
Description=/etc/init.d/boot.local Compatibility
+After=network.target
[Service]
Type=oneshot

View File

@ -0,0 +1,51 @@
From 360ab562c360ec375f76fb88318546323a835459 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 3 Dec 2011 00:41:34 +0100
Subject: [PATCH] util: fix error checking after fgets()
fgets() does not set errno on EOF.
(cherry picked from commit 35d50f55f346c71fd5e957d35ebcae1c50b1f9ce)
---
src/util.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/util.c b/src/util.c
index e93e6f6..da71e4d 100644
--- a/src/util.c
+++ b/src/util.c
@@ -516,7 +516,7 @@ int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
return -errno;
if (!(fgets(line, sizeof(line), f))) {
- r = -errno;
+ r = feof(f) ? -EIO : -errno;
fclose(f);
return r;
}
@@ -561,7 +561,7 @@ int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
return -errno;
if (!(fgets(line, sizeof(line), f))) {
- r = -errno;
+ r = feof(f) ? -EIO : -errno;
fclose(f);
return r;
}
@@ -708,7 +708,7 @@ int read_one_line_file(const char *fn, char **line) {
return -errno;
if (!(fgets(t, sizeof(t), f))) {
- r = -errno;
+ r = feof(f) ? -EIO : -errno;
goto finish;
}
@@ -3266,7 +3266,7 @@ int get_ctty_devnr(pid_t pid, dev_t *d) {
return -errno;
if (!fgets(line, sizeof(line), f)) {
- k = -errno;
+ k = feof(f) ? -EIO : -errno;
fclose(f);
return k;
}

View File

@ -0,0 +1,33 @@
From 5971b6afa801868d4bf790727dec254588832d70 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 3 Dec 2011 01:36:05 +0100
Subject: [PATCH] path: use %m instead of strerror(errno)
and strerror(-errno) was just wrong.
(cherry picked from commit 768147d13d0877a4c3e5f6f986c3064de62ff4f1)
---
src/path.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/path.c b/src/path.c
index f15c921..142fd2d 100644
--- a/src/path.c
+++ b/src/path.c
@@ -556,7 +556,7 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
}
if (ioctl(fd, FIONREAD, &l) < 0) {
- log_error("FIONREAD failed: %s", strerror(errno));
+ log_error("FIONREAD failed: %m");
goto fail;
}
@@ -568,7 +568,7 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
}
if ((k = read(fd, buf, l)) < 0) {
- log_error("Failed to read inotify event: %s", strerror(-errno));
+ log_error("Failed to read inotify event: %m");
goto fail;
}

View File

@ -0,0 +1,504 @@
From 69086d0499fb8ae161ab9bd83da19f098317f6bc Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 3 Dec 2011 01:38:30 +0100
Subject: [PATCH] path: refactor PathSpec usage
path_*() functions operate on "Path *p" and they do not touch PathSpec
internals directly.
pathspec_*() functions operate on "PathSpec *s". The PathSpec class will
be useful outside of path.c.
(cherry picked from commit 4b562198c79e4ebfc3d84b69a1dae374bc6cf9f5)
---
src/path.c | 356 +++++++++++++++++++++++++++++++++---------------------------
src/path.h | 8 ++
2 files changed, 203 insertions(+), 161 deletions(-)
diff --git a/src/path.c b/src/path.c
index 142fd2d..db6f873 100644
--- a/src/path.c
+++ b/src/path.c
@@ -39,26 +39,202 @@ static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = {
[PATH_FAILED] = UNIT_FAILED
};
-static void path_init(Unit *u) {
- Path *p = PATH(u);
+int pathspec_watch(PathSpec *s, Unit *u) {
+ static const int flags_table[_PATH_TYPE_MAX] = {
+ [PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+ [PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+ [PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
+ [PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO
+ };
+
+ bool exists = false;
+ char *k, *slash;
+ int r;
assert(u);
- assert(u->meta.load_state == UNIT_STUB);
+ assert(s);
- p->directory_mode = 0755;
+ pathspec_unwatch(s, u);
+
+ if (!(k = strdup(s->path)))
+ return -ENOMEM;
+
+ if ((s->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC)) < 0) {
+ r = -errno;
+ goto fail;
+ }
+
+ if (unit_watch_fd(u, s->inotify_fd, EPOLLIN, &s->watch) < 0) {
+ r = -errno;
+ goto fail;
+ }
+
+ if ((s->primary_wd = inotify_add_watch(s->inotify_fd, k, flags_table[s->type])) >= 0)
+ exists = true;
+
+ do {
+ int flags;
+
+ /* This assumes the path was passed through path_kill_slashes()! */
+ if (!(slash = strrchr(k, '/')))
+ break;
+
+ /* Trim the path at the last slash. Keep the slash if it's the root dir. */
+ slash[slash == k] = 0;
+
+ flags = IN_MOVE_SELF;
+ if (!exists)
+ flags |= IN_DELETE_SELF | IN_ATTRIB | IN_CREATE | IN_MOVED_TO;
+
+ if (inotify_add_watch(s->inotify_fd, k, flags) >= 0)
+ exists = true;
+ } while (slash != k);
+
+ return 0;
+
+fail:
+ free(k);
+
+ pathspec_unwatch(s, u);
+ return r;
}
-static void path_unwatch_one(Path *p, PathSpec *s) {
+void pathspec_unwatch(PathSpec *s, Unit *u) {
if (s->inotify_fd < 0)
return;
- unit_unwatch_fd(UNIT(p), &s->watch);
+ unit_unwatch_fd(u, &s->watch);
close_nointr_nofail(s->inotify_fd);
s->inotify_fd = -1;
}
+int pathspec_fd_event(PathSpec *s, uint32_t events) {
+ uint8_t *buf = NULL;
+ struct inotify_event *e;
+ ssize_t k;
+ int l;
+ int r = 0;
+
+ if (events != EPOLLIN) {
+ log_error("Got Invalid poll event on inotify.");
+ r = -EINVAL;
+ goto out;
+ }
+
+ if (ioctl(s->inotify_fd, FIONREAD, &l) < 0) {
+ log_error("FIONREAD failed: %m");
+ r = -errno;
+ goto out;
+ }
+
+ assert(l > 0);
+
+ if (!(buf = malloc(l))) {
+ log_error("Failed to allocate buffer: %m");
+ r = -errno;
+ goto out;
+ }
+
+ if ((k = read(s->inotify_fd, buf, l)) < 0) {
+ log_error("Failed to read inotify event: %m");
+ r = -errno;
+ goto out;
+ }
+
+ e = (struct inotify_event*) buf;
+
+ while (k > 0) {
+ size_t step;
+
+ if (s->type == PATH_CHANGED && s->primary_wd == e->wd)
+ r = 1;
+
+ step = sizeof(struct inotify_event) + e->len;
+ assert(step <= (size_t) k);
+
+ e = (struct inotify_event*) ((uint8_t*) e + step);
+ k -= step;
+ }
+out:
+ free(buf);
+ return r;
+}
+
+static bool pathspec_check_good(PathSpec *s, bool initial) {
+ bool good = false;
+
+ switch (s->type) {
+
+ case PATH_EXISTS:
+ good = access(s->path, F_OK) >= 0;
+ break;
+
+ case PATH_EXISTS_GLOB:
+ good = glob_exists(s->path) > 0;
+ break;
+
+ case PATH_DIRECTORY_NOT_EMPTY: {
+ int k;
+
+ k = dir_is_empty(s->path);
+ good = !(k == -ENOENT || k > 0);
+ break;
+ }
+
+ case PATH_CHANGED: {
+ bool b;
+
+ b = access(s->path, F_OK) >= 0;
+ good = !initial && b != s->previous_exists;
+ s->previous_exists = b;
+ break;
+ }
+
+ default:
+ ;
+ }
+
+ return good;
+}
+
+static bool pathspec_startswith(PathSpec *s, const char *what) {
+ return path_startswith(s->path, what);
+}
+
+static void pathspec_mkdir(PathSpec *s, mode_t mode) {
+ int r;
+
+ if (s->type == PATH_EXISTS || s->type == PATH_EXISTS_GLOB)
+ return;
+
+ if ((r = mkdir_p(s->path, mode)) < 0)
+ log_warning("mkdir(%s) failed: %s", s->path, strerror(-r));
+}
+
+static void pathspec_dump(PathSpec *s, FILE *f, const char *prefix) {
+ fprintf(f,
+ "%s%s: %s\n",
+ prefix,
+ path_type_to_string(s->type),
+ s->path);
+}
+
+void pathspec_done(PathSpec *s) {
+ assert(s->inotify_fd == -1);
+ free(s->path);
+}
+
+static void path_init(Unit *u) {
+ Path *p = PATH(u);
+
+ assert(u);
+ assert(u->meta.load_state == UNIT_STUB);
+
+ p->directory_mode = 0755;
+}
+
static void path_done(Unit *u) {
Path *p = PATH(u);
PathSpec *s;
@@ -66,9 +242,9 @@ static void path_done(Unit *u) {
assert(p);
while ((s = p->specs)) {
- path_unwatch_one(p, s);
+ pathspec_unwatch(s, u);
LIST_REMOVE(PathSpec, spec, p->specs, s);
- free(s->path);
+ pathspec_done(s);
free(s);
}
}
@@ -86,7 +262,7 @@ int path_add_one_mount_link(Path *p, Mount *m) {
LIST_FOREACH(spec, s, p->specs) {
- if (!path_startswith(s->path, m->where))
+ if (!pathspec_startswith(s, m->where))
continue;
if ((r = unit_add_two_dependencies(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0)
@@ -187,71 +363,7 @@ static void path_dump(Unit *u, FILE *f, const char *prefix) {
prefix, p->directory_mode);
LIST_FOREACH(spec, s, p->specs)
- fprintf(f,
- "%s%s: %s\n",
- prefix,
- path_type_to_string(s->type),
- s->path);
-}
-
-static int path_watch_one(Path *p, PathSpec *s) {
- static const int flags_table[_PATH_TYPE_MAX] = {
- [PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
- [PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
- [PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
- [PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO
- };
-
- bool exists = false;
- char *k, *slash;
- int r;
-
- assert(p);
- assert(s);
-
- path_unwatch_one(p, s);
-
- if (!(k = strdup(s->path)))
- return -ENOMEM;
-
- if ((s->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC)) < 0) {
- r = -errno;
- goto fail;
- }
-
- if (unit_watch_fd(UNIT(p), s->inotify_fd, EPOLLIN, &s->watch) < 0) {
- r = -errno;
- goto fail;
- }
-
- if ((s->primary_wd = inotify_add_watch(s->inotify_fd, k, flags_table[s->type])) >= 0)
- exists = true;
-
- do {
- int flags;
-
- /* This assumes the path was passed through path_kill_slashes()! */
- if (!(slash = strrchr(k, '/')))
- break;
-
- /* Trim the path at the last slash. Keep the slash if it's the root dir. */
- slash[slash == k] = 0;
-
- flags = IN_MOVE_SELF;
- if (!exists)
- flags |= IN_DELETE_SELF | IN_ATTRIB | IN_CREATE | IN_MOVED_TO;
-
- if (inotify_add_watch(s->inotify_fd, k, flags) >= 0)
- exists = true;
- } while (slash != k);
-
- return 0;
-
-fail:
- free(k);
-
- path_unwatch_one(p, s);
- return r;
+ pathspec_dump(s, f, prefix);
}
static void path_unwatch(Path *p) {
@@ -260,7 +372,7 @@ static void path_unwatch(Path *p) {
assert(p);
LIST_FOREACH(spec, s, p->specs)
- path_unwatch_one(p, s);
+ pathspec_unwatch(s, UNIT(p));
}
static int path_watch(Path *p) {
@@ -270,7 +382,7 @@ static int path_watch(Path *p) {
assert(p);
LIST_FOREACH(spec, s, p->specs)
- if ((r = path_watch_one(p, s)) < 0)
+ if ((r = pathspec_watch(s, UNIT(p))) < 0)
return r;
return 0;
@@ -361,37 +473,7 @@ static bool path_check_good(Path *p, bool initial) {
assert(p);
LIST_FOREACH(spec, s, p->specs) {
-
- switch (s->type) {
-
- case PATH_EXISTS:
- good = access(s->path, F_OK) >= 0;
- break;
-
- case PATH_EXISTS_GLOB:
- good = glob_exists(s->path) > 0;
- break;
-
- case PATH_DIRECTORY_NOT_EMPTY: {
- int k;
-
- k = dir_is_empty(s->path);
- good = !(k == -ENOENT || k > 0);
- break;
- }
-
- case PATH_CHANGED: {
- bool b;
-
- b = access(s->path, F_OK) >= 0;
- good = !initial && b != s->previous_exists;
- s->previous_exists = b;
- break;
- }
-
- default:
- ;
- }
+ good = pathspec_check_good(s, initial);
if (good)
break;
@@ -440,15 +522,8 @@ static void path_mkdir(Path *p) {
if (!p->make_directory)
return;
- LIST_FOREACH(spec, s, p->specs) {
- int r;
-
- if (s->type == PATH_EXISTS || s->type == PATH_EXISTS_GLOB)
- continue;
-
- if ((r = mkdir_p(s->path, p->directory_mode)) < 0)
- log_warning("mkdir(%s) failed: %s", s->path, strerror(-r));
- }
+ LIST_FOREACH(spec, s, p->specs)
+ pathspec_mkdir(s, p->directory_mode);
}
static int path_start(Unit *u) {
@@ -525,12 +600,8 @@ static const char *path_sub_state_to_string(Unit *u) {
static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
Path *p = PATH(u);
- int l;
- ssize_t k;
- uint8_t *buf = NULL;
- struct inotify_event *e;
PathSpec *s;
- bool changed;
+ int changed;
assert(p);
assert(fd >= 0);
@@ -541,13 +612,8 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
/* log_debug("inotify wakeup on %s.", u->meta.id); */
- if (events != EPOLLIN) {
- log_error("Got Invalid poll event on inotify.");
- goto fail;
- }
-
LIST_FOREACH(spec, s, p->specs)
- if (s->inotify_fd == fd)
+ if (pathspec_owns_inotify_fd(s, fd))
break;
if (!s) {
@@ -555,55 +621,23 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
goto fail;
}
- if (ioctl(fd, FIONREAD, &l) < 0) {
- log_error("FIONREAD failed: %m");
- goto fail;
- }
-
- assert(l > 0);
-
- if (!(buf = malloc(l))) {
- log_error("Failed to allocate buffer: %s", strerror(ENOMEM));
- goto fail;
- }
-
- if ((k = read(fd, buf, l)) < 0) {
- log_error("Failed to read inotify event: %m");
+ changed = pathspec_fd_event(s, events);
+ if (changed < 0)
goto fail;
- }
/* If we are already running, then remember that one event was
* dispatched so that we restart the service only if something
* actually changed on disk */
p->inotify_triggered = true;
- e = (struct inotify_event*) buf;
-
- changed = false;
- while (k > 0) {
- size_t step;
-
- if (s->type == PATH_CHANGED && s->primary_wd == e->wd)
- changed = true;
-
- step = sizeof(struct inotify_event) + e->len;
- assert(step <= (size_t) k);
-
- e = (struct inotify_event*) ((uint8_t*) e + step);
- k -= step;
- }
-
if (changed)
path_enter_running(p);
else
path_enter_waiting(p, false, true);
- free(buf);
-
return;
fail:
- free(buf);
path_enter_dead(p, false);
}
diff --git a/src/path.h b/src/path.h
index 116fc63..4e6ccf5 100644
--- a/src/path.h
+++ b/src/path.h
@@ -60,6 +60,14 @@ typedef struct PathSpec {
} PathSpec;
+int pathspec_watch(PathSpec *s, Unit *u);
+void pathspec_unwatch(PathSpec *s, Unit *u);
+int pathspec_fd_event(PathSpec *s, uint32_t events);
+void pathspec_done(PathSpec *s);
+static inline bool pathspec_owns_inotify_fd(PathSpec *s, int fd) {
+ return s->inotify_fd == fd;
+}
+
struct Path {
Meta meta;

View File

@ -0,0 +1,87 @@
From 30fb4092d987ff81f39177461f6472e2fff225a1 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 3 Dec 2011 10:22:26 +0100
Subject: [PATCH] path: add PathModified (= PathChanged + IN_MODIFY) (cherry
picked from commit
e92238567b9fc83ef77e359588d7b005ecae3d70)
---
man/systemd.path.xml | 17 ++++++++++-------
src/path.c | 2 ++
src/path.h | 1 +
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/man/systemd.path.xml b/man/systemd.path.xml
index 10d8f73..5b1ff75 100644
--- a/man/systemd.path.xml
+++ b/man/systemd.path.xml
@@ -113,6 +113,7 @@
<term><varname>PathExists=</varname></term>
<term><varname>PathExistsGlob=</varname></term>
<term><varname>PathChanged=</varname></term>
+ <term><varname>PathModified=</varname></term>
<term><varname>DirectoryNotEmpty=</varname></term>
<listitem><para>Defines paths to
@@ -129,8 +130,14 @@
specified. <varname>PathChanged=</varname>
may be used to watch a file or
directory and activate the configured
- unit whenever it changes or is
- modified. <varname>DirectoryNotEmpty=</varname>
+ unit whenever it changes. It is not activated
+ on every write to the watched file but it is
+ activated if the file which was open for writing
+ gets closed. <varname>PathModified=</varname>
+ is similar, but additionally it is activated
+ also on simple writes to the watched file.
+
+ <varname>DirectoryNotEmpty=</varname>
may be used to watch a directory and
activate the configured unit whenever
it contains at least one file.</para>
@@ -154,11 +161,7 @@
activated, then the configured unit is
immediately activated as
well. Something similar does not apply
- to
- <varname>PathChanged=</varname>. The
- latter is not activated on simple
- writes but only if files with were
- opened for writing are closed.
+ to <varname>PathChanged=</varname>.
</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/path.c b/src/path.c
index db6f873..1e5d825 100644
--- a/src/path.c
+++ b/src/path.c
@@ -44,6 +44,7 @@ int pathspec_watch(PathSpec *s, Unit *u) {
[PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
[PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
[PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
+ [PATH_MODIFIED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO|IN_MODIFY,
[PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO
};
@@ -713,6 +714,7 @@ static const char* const path_type_table[_PATH_TYPE_MAX] = {
[PATH_EXISTS] = "PathExists",
[PATH_EXISTS_GLOB] = "PathExistsGlob",
[PATH_CHANGED] = "PathChanged",
+ [PATH_MODIFIED] = "PathModified",
[PATH_DIRECTORY_NOT_EMPTY] = "DirectoryNotEmpty"
};
diff --git a/src/path.h b/src/path.h
index 4e6ccf5..1d78fe4 100644
--- a/src/path.h
+++ b/src/path.h
@@ -41,6 +41,7 @@ typedef enum PathType {
PATH_EXISTS_GLOB,
PATH_DIRECTORY_NOT_EMPTY,
PATH_CHANGED,
+ PATH_MODIFIED,
_PATH_TYPE_MAX,
_PATH_TYPE_INVALID = -1
} PathType;

View File

@ -0,0 +1,326 @@
From 1b2395f867d283bb08862e1ce421ab3ac1b02968 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 3 Dec 2011 02:13:30 +0100
Subject: [PATCH] service: handle services with racy daemonization gracefully
There are a lot of forking daemons that do not exactly follow the
initialization steps as described in daemon(7). It is common that they
do not bother waiting in the parent process for the child to write the
PID file before exiting. The daemons' developers often do not perceive
this as a bug and they're unwilling to change.
Currently systemd warns about the missing PID file and falls back to
guessing the main PID. Being not quite deterministic, the guess can be
wrong with bad consequences. If the guessing is disabled, determinism is
achieved at the cost of losing the ability of noticing when the main
process of the service dies.
As long as it does not negatively affect properly written services,
systemd should strive for compatibility even with services with racy
daemonization. It is possible to provide determinism _and_ main process
supervision to them.
If the PID file is not there, rather than guessing and considering the
service running immediately after getting the SIGCHLD from the ExecStart
(or ExecStartPost) process, we can keep the service in the activating
state for a bit longer. We can use inotify to wait for the PID file to
appear. Only when it finally does appear and we read a valid PID from
it, we'll move the service to the running state. If the PID file never
appears, the usual timeout kicks in and the service fails.
(cherry picked from commit 3a11183858af30bc9b4e9dac430dd7541deec19b)
---
src/service.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
src/service.h | 3 +
2 files changed, 157 insertions(+), 21 deletions(-)
diff --git a/src/service.c b/src/service.c
index d51445e..0b03a8d 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1294,8 +1294,8 @@ static int service_load_pid_file(Service *s, bool may_warn) {
if ((r = read_one_line_file(s->pid_file, &k)) < 0) {
if (may_warn)
- log_warning("Failed to read PID file %s after %s. The service might be broken.",
- s->pid_file, service_state_to_string(s->state));
+ log_info("PID file %s not readable (yet?) after %s.",
+ s->pid_file, service_state_to_string(s->state));
return r;
}
@@ -1307,8 +1307,8 @@ static int service_load_pid_file(Service *s, bool may_warn) {
if (kill(pid, 0) < 0 && errno != EPERM) {
if (may_warn)
- log_warning("PID %lu read from file %s does not exist. Your service or init script might be broken.",
- (unsigned long) pid, s->pid_file);
+ log_info("PID %lu read from file %s does not exist.",
+ (unsigned long) pid, s->pid_file);
return -ESRCH;
}
@@ -1320,7 +1320,8 @@ static int service_load_pid_file(Service *s, bool may_warn) {
(unsigned long) s->main_pid, (unsigned long) pid);
service_unwatch_main_pid(s);
s->main_pid_known = false;
- }
+ } else
+ log_debug("Main PID loaded: %lu", (unsigned long) pid);
if ((r = service_set_main_pid(s, pid)) < 0)
return r;
@@ -1351,6 +1352,7 @@ static int service_search_main_pid(Service *s) {
if ((pid = cgroup_bonding_search_main_pid_list(s->meta.cgroup_bondings)) <= 0)
return -ENOENT;
+ log_debug("Main PID guessed: %lu", (unsigned long) pid);
if ((r = service_set_main_pid(s, pid)) < 0)
return r;
@@ -1443,6 +1445,17 @@ static int service_notify_sockets_dead(Service *s) {
return 0;
}
+static void service_unwatch_pid_file(Service *s) {
+ if (!s->pid_file_pathspec)
+ return;
+
+ log_debug("Stopping watch for %s's PID file %s", s->meta.id, s->pid_file_pathspec->path);
+ pathspec_unwatch(s->pid_file_pathspec, UNIT(s));
+ pathspec_done(s->pid_file_pathspec);
+ free(s->pid_file_pathspec);
+ s->pid_file_pathspec = NULL;
+}
+
static void service_set_state(Service *s, ServiceState state) {
ServiceState old_state;
assert(s);
@@ -1450,6 +1463,8 @@ static void service_set_state(Service *s, ServiceState state) {
old_state = s->state;
s->state = state;
+ service_unwatch_pid_file(s);
+
if (state != SERVICE_START_PRE &&
state != SERVICE_START &&
state != SERVICE_START_POST &&
@@ -2594,6 +2609,95 @@ static bool service_check_snapshot(Unit *u) {
return !s->got_socket_fd;
}
+static int service_retry_pid_file(Service *s) {
+ int r;
+
+ assert(s->pid_file);
+ assert(s->state == SERVICE_START || s->state == SERVICE_START_POST);
+
+ r = service_load_pid_file(s, false);
+ if (r < 0)
+ return r;
+
+ service_unwatch_pid_file(s);
+
+ service_enter_running(s, true);
+ return 0;
+}
+
+static int service_watch_pid_file(Service *s) {
+ int r;
+
+ log_debug("Setting watch for %s's PID file %s", s->meta.id, s->pid_file_pathspec->path);
+ r = pathspec_watch(s->pid_file_pathspec, UNIT(s));
+ if (r < 0)
+ goto fail;
+
+ /* the pidfile might have appeared just before we set the watch */
+ service_retry_pid_file(s);
+
+ return 0;
+fail:
+ log_error("Failed to set a watch for %s's PID file %s: %s",
+ s->meta.id, s->pid_file_pathspec->path, strerror(-r));
+ service_unwatch_pid_file(s);
+ return r;
+}
+
+static int service_demand_pid_file(Service *s) {
+ PathSpec *ps;
+
+ assert(s->pid_file);
+ assert(!s->pid_file_pathspec);
+
+ ps = new0(PathSpec, 1);
+ if (!ps)
+ return -ENOMEM;
+
+ ps->path = strdup(s->pid_file);
+ if (!ps->path) {
+ free(ps);
+ return -ENOMEM;
+ }
+
+ path_kill_slashes(ps->path);
+
+ /* PATH_CHANGED would not be enough. There are daemons (sendmail) that
+ * keep their PID file open all the time. */
+ ps->type = PATH_MODIFIED;
+ ps->inotify_fd = -1;
+
+ s->pid_file_pathspec = ps;
+
+ return service_watch_pid_file(s);
+}
+
+static void service_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+ Service *s = SERVICE(u);
+
+ assert(s);
+ assert(fd >= 0);
+ assert(s->state == SERVICE_START || s->state == SERVICE_START_POST);
+ assert(s->pid_file_pathspec);
+ assert(pathspec_owns_inotify_fd(s->pid_file_pathspec, fd));
+
+ log_debug("inotify event for %s", u->meta.id);
+
+ if (pathspec_fd_event(s->pid_file_pathspec, events) < 0)
+ goto fail;
+
+ if (service_retry_pid_file(s) == 0)
+ return;
+
+ if (service_watch_pid_file(s) < 0)
+ goto fail;
+
+ return;
+fail:
+ service_unwatch_pid_file(s);
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, false);
+}
+
static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
Service *s = SERVICE(u);
bool success;
@@ -2699,7 +2803,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
success = true;
}
- log_full(success ? LOG_DEBUG : LOG_NOTICE,
+ log_full(success ? LOG_DEBUG : LOG_NOTICE,
"%s: control process exited, code=%s status=%i", u->meta.id, sigchld_code_to_string(code), status);
s->failure = s->failure || !success;
@@ -2734,27 +2838,41 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
case SERVICE_START:
assert(s->type == SERVICE_FORKING);
- /* Let's try to load the pid
- * file here if we can. We
- * ignore the return value,
- * since the PID file might
- * actually be created by a
- * START_POST script */
-
- if (success) {
- service_load_pid_file(s, !s->exec_command[SERVICE_EXEC_START_POST]);
- service_search_main_pid(s);
+ if (!success) {
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
+ break;
+ }
- service_enter_start_post(s);
+ if (s->pid_file) {
+ /* Let's try to load the pid file here if we can.
+ * The PID file might actually be created by a START_POST
+ * script. In that case don't worry if the loading fails. */
+ bool has_start_post = !!s->exec_command[SERVICE_EXEC_START_POST];
+ int r = service_load_pid_file(s, !has_start_post);
+ if (!has_start_post && r < 0) {
+ r = service_demand_pid_file(s);
+ if (r < 0 || !cgroup_good(s))
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
+ break;
+ }
} else
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
+ service_search_main_pid(s);
+ service_enter_start_post(s);
break;
case SERVICE_START_POST:
if (success) {
- service_load_pid_file(s, true);
- service_search_main_pid(s);
+ if (s->pid_file) {
+ int r = service_load_pid_file(s, true);
+ if (r < 0) {
+ r = service_demand_pid_file(s);
+ if (r < 0 || !cgroup_good(s))
+ service_enter_stop(s, false);
+ break;
+ }
+ } else
+ service_search_main_pid(s);
}
s->reload_failure = !success;
@@ -2899,6 +3017,20 @@ static void service_cgroup_notify_event(Unit *u) {
* except when we don't know pid which to expect the
* SIGCHLD for. */
+ case SERVICE_START:
+ case SERVICE_START_POST:
+ /* If we were hoping for the daemon to write its PID file,
+ * we can give up now. */
+ if (s->pid_file_pathspec) {
+ log_warning("%s never wrote its PID file. Failing.", s->meta.id);
+ service_unwatch_pid_file(s);
+ if (s->state == SERVICE_START)
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
+ else
+ service_enter_stop(s, false);
+ }
+ break;
+
case SERVICE_RUNNING:
service_enter_running(s, true);
break;
@@ -3208,7 +3340,7 @@ static int service_enumerate(Manager *m) {
r = 0;
#ifdef TARGET_SUSE
- sysv_facility_in_insserv_conf (m);
+ sysv_facility_in_insserv_conf (m);
#endif
finish:
@@ -3503,6 +3635,7 @@ const UnitVTable service_vtable = {
.sigchld_event = service_sigchld_event,
.timer_event = service_timer_event,
+ .fd_event = service_fd_event,
.reset_failed = service_reset_failed,
diff --git a/src/service.h b/src/service.h
index e28f74b..15d58cc 100644
--- a/src/service.h
+++ b/src/service.h
@@ -86,6 +86,8 @@ typedef enum NotifyAccess {
_NOTIFY_ACCESS_INVALID = -1
} NotifyAccess;
+typedef struct PathSpec PathSpec;
+
struct Service {
Meta meta;
@@ -157,6 +159,7 @@ struct Service {
Set *configured_sockets;
Watch timer_watch;
+ PathSpec *pid_file_pathspec;
NotifyAccess notify_access;
};

View File

@ -0,0 +1,57 @@
From 4035af799be35919232a68dfb0786af4f54257a1 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 3 Dec 2011 21:34:34 +0100
Subject: [PATCH] service: stop the service if ExecStartPost ends with a
failure
The handling of failures in ExecStartPost is inconsistent. If the
command times out, the service is stopped. But if the command exits
with a failure, the service keeps running.
It makes more sense to stop the service when ExecStartPost fails.
If this behaviour is not desired, the ExecStartPost command can be
prefixed with "-".
(cherry picked from commit 2096e009a790073a934f5cd07d17024d3b199d0b)
---
src/service.c | 26 ++++++++++++++------------
1 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/src/service.c b/src/service.c
index 0b03a8d..175a729 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2862,20 +2862,22 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
break;
case SERVICE_START_POST:
- if (success) {
- if (s->pid_file) {
- int r = service_load_pid_file(s, true);
- if (r < 0) {
- r = service_demand_pid_file(s);
- if (r < 0 || !cgroup_good(s))
- service_enter_stop(s, false);
- break;
- }
- } else
- service_search_main_pid(s);
+ if (!success) {
+ service_enter_stop(s, false);
+ break;
}
- s->reload_failure = !success;
+ if (s->pid_file) {
+ int r = service_load_pid_file(s, true);
+ if (r < 0) {
+ r = service_demand_pid_file(s);
+ if (r < 0 || !cgroup_good(s))
+ service_enter_stop(s, false);
+ break;
+ }
+ } else
+ service_search_main_pid(s);
+
service_enter_running(s, true);
break;

View File

@ -0,0 +1,60 @@
From 7c3d4fb80496c466d6523b88d5720a7f4ff7939d Mon Sep 17 00:00:00 2001
From: Bill Nottingham <notting@redhat.com>
Date: Tue, 22 Nov 2011 15:45:34 -0500
Subject: [PATCH] Allow 'list-unit-files' to run with --root.
To do so, move the check for the bus to the bus-using portion of
list_unit_files(), and ensure that get_config_path doesn't abort when
checking the runtime path with --root.
(cherry picked from commit d380a3bcd14376ed72286e78dbcc871b7d6d2151)
---
src/install.c | 5 ++---
src/systemctl.c | 5 +++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/install.c b/src/install.c
index cfbd50e..1fb1f9d 100644
--- a/src/install.c
+++ b/src/install.c
@@ -72,9 +72,8 @@ static int get_config_path(UnitFileScope scope, bool runtime, const char *root_d
case UNIT_FILE_SYSTEM:
if (root_dir && runtime)
- return -EINVAL;
-
- if (runtime)
+ asprintf(&p, "%s/run/systemd/system", root_dir);
+ else if (runtime)
p = strdup("/run/systemd/system");
else if (root_dir)
asprintf(&p, "%s/%s", root_dir, SYSTEM_CONFIG_UNIT_PATH);
diff --git a/src/systemctl.c b/src/systemctl.c
index 4426f70..668641d 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -622,8 +622,6 @@ static int list_unit_files(DBusConnection *bus, char **args) {
dbus_error_init(&error);
- assert(bus);
-
pager_open_if_enabled();
if (avoid_bus()) {
@@ -659,6 +657,8 @@ static int list_unit_files(DBusConnection *bus, char **args) {
hashmap_free(h);
} else {
+ assert(bus);
+
m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
@@ -5001,6 +5001,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
if (!streq(verbs[i].verb, "enable") &&
!streq(verbs[i].verb, "disable") &&
!streq(verbs[i].verb, "is-enable") &&
+ !streq(verbs[i].verb, "list-unit-files") &&
!streq(verbs[i].verb, "reenable") &&
!streq(verbs[i].verb, "preset") &&
!streq(verbs[i].verb, "mask") &&

View File

@ -0,0 +1,27 @@
From 069a85095fb07d894ae1825db5f7300c5b5f092b Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Tue, 6 Dec 2011 00:47:28 +0100
Subject: [PATCH] unit: garbage collect units with load error
Units that failed to load were never cleaned up. It was possible to
reach the 128K limit of units by attempting to load a bunch of nonsense.
Bug observed by Reartes Guillermo in
https://bugzilla.redhat.com/show_bug.cgi?id=680122
(cherry picked from commit 9a46fc3b9014de1bf0ed1f3004a536b08a19ebb3)
---
src/unit.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/unit.c b/src/unit.c
index 2a549e2..018e986 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -858,6 +858,7 @@ fail:
u->meta.load_state = UNIT_ERROR;
u->meta.load_error = r;
unit_add_to_dbus_queue(u);
+ unit_add_to_gc_queue(u);
log_debug("Failed to load configuration for %s: %s", u->meta.id, strerror(-r));

View File

@ -0,0 +1,38 @@
From 3fc55e7a9f4dc14ca74ed6b293e1fac03e1fec74 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Tue, 6 Dec 2011 01:14:36 +0100
Subject: [PATCH] systemctl: print 'error' load state in red
Be consistent in coloring of load states in list-units and status.
Print only 'error' in red.
There are no 'banned' or 'failed' states. Do not color 'masked', it's
not an error.
(cherry picked from commit f7b9e331ed71fb2f832ac5587fb5119dd2bfc32f)
---
src/systemctl.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/systemctl.c b/src/systemctl.c
index 668641d..960d3c0 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -377,8 +377,7 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
n_shown++;
- if (!streq(u->load_state, "loaded") &&
- !streq(u->load_state, "banned")) {
+ if (streq(u->load_state, "error")) {
on_loaded = ansi_highlight(true);
off_loaded = ansi_highlight(false);
} else
@@ -2063,8 +2062,7 @@ static void print_status_info(UnitStatusInfo *i) {
if (i->following)
printf("\t Follow: unit currently follows state of %s\n", i->following);
- if (streq_ptr(i->load_state, "failed") ||
- streq_ptr(i->load_state, "banned")) {
+ if (streq_ptr(i->load_state, "error")) {
on = ansi_highlight(true);
off = ansi_highlight(false);
} else

View File

@ -0,0 +1,24 @@
From 0773caae1b4eae198f8e41fb8a1d46c24c99543e Mon Sep 17 00:00:00 2001
From: Tim Waugh <twaugh@redhat.com>
Date: Thu, 8 Dec 2011 17:32:09 +0100
Subject: [PATCH] '@' is an 'ampersat' not an 'ampersand'; let's call it 'at
symbol' (cherry picked from commit
7e115808a990199fe00de4cc2ef48fe96de3d3d0)
---
man/systemd.socket.xml | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 2f31242..f883543 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -156,7 +156,7 @@
family.</para>
<para>If the address starts with an
- ampersand (@) it is read as abstract
+ at symbol (@) it is read as abstract
namespace socket in the AF_UNIX
family. The @ is replaced with a NUL
character before binding. For details

View File

@ -0,0 +1,49 @@
From 7cae93f652dff82e998a3d1f99f1a18a3f908c30 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 8 Dec 2011 12:09:10 +0100
Subject: [PATCH] path: add missing pieces for PathModified
PATH_MODIFIED worked internally for PID files detection, but was unusable
in units.
(cherry picked from commit 714d943f72417f53bcb98ed45d002aa270e793c4)
---
src/load-fragment-gperf.gperf.m4 | 1 +
src/path.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4
index 84ae28c..35ec005 100644
--- a/src/load-fragment-gperf.gperf.m4
+++ b/src/load-fragment-gperf.gperf.m4
@@ -210,6 +210,7 @@ m4_dnl
Path.PathExists, config_parse_path_spec, 0, 0
Path.PathExistsGlob, config_parse_path_spec, 0, 0
Path.PathChanged, config_parse_path_spec, 0, 0
+Path.PathModified, config_parse_path_spec, 0, 0
Path.DirectoryNotEmpty, config_parse_path_spec, 0, 0
Path.Unit, config_parse_path_unit, 0, 0
Path.MakeDirectory, config_parse_bool, 0, offsetof(Path, make_directory)
diff --git a/src/path.c b/src/path.c
index 1e5d825..3fee247 100644
--- a/src/path.c
+++ b/src/path.c
@@ -149,7 +149,8 @@ int pathspec_fd_event(PathSpec *s, uint32_t events) {
while (k > 0) {
size_t step;
- if (s->type == PATH_CHANGED && s->primary_wd == e->wd)
+ if ((s->type == PATH_CHANGED || s->type == PATH_MODIFIED) &&
+ s->primary_wd == e->wd)
r = 1;
step = sizeof(struct inotify_event) + e->len;
@@ -184,7 +185,8 @@ static bool pathspec_check_good(PathSpec *s, bool initial) {
break;
}
- case PATH_CHANGED: {
+ case PATH_CHANGED:
+ case PATH_MODIFIED: {
bool b;
b = access(s->path, F_OK) >= 0;

View File

@ -0,0 +1,52 @@
From 43664cdd8565ae24b27c3f91be1de64ae9021608 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 9 Dec 2011 15:24:04 +0100
Subject: [PATCH] unit: fix false positive in check for unneeded unit
A freshly started unit A was immediately considered unneeded just because
unit B, which Requires A, was starting later in the transaction.
Fix it by looking not only at the state of B, but also at its pending job.
Also fix a copied&pasted comment.
(cherry picked from commit f60c2665f9ba1dd4a6b4a36b2e8195482ada9957)
---
src/unit.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/unit.c b/src/unit.c
index 018e986..56137d7 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -1032,19 +1032,19 @@ static void unit_check_unneeded(Unit *u) {
return;
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i)
- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+ if (unit_pending_active(other))
return;
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+ if (unit_pending_active(other))
return;
SET_FOREACH(other, u->meta.dependencies[UNIT_WANTED_BY], i)
- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+ if (unit_pending_active(other))
return;
SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i)
- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+ if (unit_pending_active(other))
return;
log_info("Service %s is not needed anymore. Stopping.", u->meta.id);
@@ -2518,7 +2518,7 @@ bool unit_pending_inactive(Unit *u) {
bool unit_pending_active(Unit *u) {
assert(u);
- /* Returns true if the unit is inactive or going down */
+ /* Returns true if the unit is active or going up */
if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
return true;

View File

@ -0,0 +1,45 @@
From c075b337c3ebfd4665f3745a66984bf2d2793a97 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 9 Dec 2011 15:25:29 +0100
Subject: [PATCH] unit: check for unneeded dependencies even when unit stop
was expected
systemd did not stop units marked as "StopWhenUnneeded=yes" when the requiring
unit was stopped on user's request.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=704197
(cherry picked from commit cd0504d0a13d8297b97c9238fd1b94b4141c5aa8)
---
src/unit.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/src/unit.c b/src/unit.c
index 56137d7..03c90f5 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -1105,6 +1105,14 @@ static void retroactively_stop_dependencies(Unit *u) {
SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i)
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
+}
+
+static void check_unneeded_dependencies(Unit *u) {
+ Iterator i;
+ Unit *other;
+
+ assert(u);
+ assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
/* Garbage collect services that might not be needed anymore, if enabled */
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i)
@@ -1263,6 +1271,10 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
retroactively_stop_dependencies(u);
}
+ /* stop unneeded units regardless if going down was expected or not */
+ if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
+ check_unneeded_dependencies(u);
+
if (ns != os && ns == UNIT_FAILED) {
log_notice("Unit %s entered failed state.", u->meta.id);
unit_trigger_on_failure(u);

View File

@ -0,0 +1,38 @@
From 2f9743bff6e9bfe4365c24becea68b27d06d1c0d Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Wed, 14 Dec 2011 01:25:47 +0100
Subject: [PATCH] pam-module: add a couple of debugging prints (cherry picked
from commit ce9593140b127ce782e2fa2f47fc55558b331126)
---
src/pam-module.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/src/pam-module.c b/src/pam-module.c
index 46b7bec..9002f4e 100644
--- a/src/pam-module.c
+++ b/src/pam-module.c
@@ -521,6 +521,11 @@ _public_ PAM_EXTERN int pam_sm_open_session(
goto finish;
}
+ if (debug)
+ pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: "
+ "uid=%u pid=%u service=%s type=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s",
+ uid, pid, service, type, seat, vtnr, tty, display, yes_no(remote), remote_user, remote_host);
+
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
if (!reply) {
pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error));
@@ -541,6 +546,11 @@ _public_ PAM_EXTERN int pam_sm_open_session(
goto finish;
}
+ if (debug)
+ pam_syslog(handle, LOG_DEBUG, "Reply from logind: "
+ "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u",
+ id, object_path, runtime_path, session_fd, seat, vtnr);
+
r = pam_misc_setenv(handle, "XDG_SESSION_ID", id, 0);
if (r != PAM_SUCCESS) {
pam_syslog(handle, LOG_ERR, "Failed to set session id.");

View File

@ -0,0 +1,23 @@
From 0d380f2f2d27eabcab8167a52e2d7196720f3d6a Mon Sep 17 00:00:00 2001
From: Gregs Gregs <gregpuppy01@yahoo.gr>
Date: Mon, 14 Nov 2011 19:58:03 +0200
Subject: [PATCH] fsck: Fix typo in comment (cherry picked from commit
b911442003350c56673e5689328f173ed03bbabd)
---
src/fsck.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/fsck.c b/src/fsck.c
index c5088ad..3e66535 100644
--- a/src/fsck.c
+++ b/src/fsck.c
@@ -80,7 +80,7 @@ static void start_target(const char *target, bool isolate) {
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- /* Don't print a waring if we aren't called during
+ /* Don't print a warning if we aren't called during
* startup */
if (!dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_JOB))
log_error("Failed to start unit: %s", bus_error_message(&error));

View File

@ -0,0 +1,24 @@
From b63edf0ecaab0cb26bba99b139511ac22d3bf785 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Wed, 14 Dec 2011 22:23:56 +0100
Subject: [PATCH] systemctl: fix typo in 'is-enabled'
It prevented the action from working without dbus.
(cherry picked from commit c971700e41e0ac9883ab0744921b79dd396170dc)
---
src/systemctl.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/systemctl.c b/src/systemctl.c
index 960d3c0..c86ec80 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -4998,7 +4998,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
* enable/disable */
if (!streq(verbs[i].verb, "enable") &&
!streq(verbs[i].verb, "disable") &&
- !streq(verbs[i].verb, "is-enable") &&
+ !streq(verbs[i].verb, "is-enabled") &&
!streq(verbs[i].verb, "list-unit-files") &&
!streq(verbs[i].verb, "reenable") &&
!streq(verbs[i].verb, "preset") &&

View File

@ -0,0 +1,71 @@
From c8be37cab131ec8a1aa54e5878483a18fc0bde6e Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 15 Dec 2011 21:31:14 +0100
Subject: [PATCH] tmpfiles: use an enum instead of plain char for item type
For better safety. gcc can warn about missing values in switch statements.
(cherry picked from commit 66ccd0387e528567dff92239e85c962d2f140ef1)
---
src/tmpfiles.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/tmpfiles.c b/src/tmpfiles.c
index 21bf44d..6171140 100644
--- a/src/tmpfiles.c
+++ b/src/tmpfiles.c
@@ -50,7 +50,7 @@
* properly owned directories beneath /tmp, /var/tmp, /run, which are
* volatile and hence need to be recreated on bootup. */
-enum {
+typedef enum ItemType {
/* These ones take file names */
CREATE_FILE = 'f',
TRUNCATE_FILE = 'F',
@@ -62,10 +62,10 @@ enum {
IGNORE_PATH = 'x',
REMOVE_PATH = 'r',
RECURSIVE_REMOVE_PATH = 'R'
-};
+} ItemType;
typedef struct Item {
- char type;
+ ItemType type;
char *path;
uid_t uid;
@@ -90,7 +90,7 @@ static const char *arg_prefix = NULL;
#define MAX_DEPTH 256
-static bool needs_glob(int t) {
+static bool needs_glob(ItemType t) {
return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH;
}
@@ -701,6 +701,7 @@ static bool item_equal(Item *a, Item *b) {
static int parse_line(const char *fname, unsigned line, const char *buffer) {
Item *i, *existing;
char *mode = NULL, *user = NULL, *group = NULL, *age = NULL;
+ char type;
Hashmap *h;
int r;
@@ -720,7 +721,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
"%ms "
"%ms "
"%ms",
- &i->type,
+ &type,
&i->path,
&mode,
&user,
@@ -730,6 +731,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
r = -EIO;
goto finish;
}
+ i->type = type;
if (i->type != CREATE_FILE &&
i->type != TRUNCATE_FILE &&

View File

@ -0,0 +1,52 @@
From bdd9b9807a89eb8e4789a3279253f6f845f90e9b Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 15 Dec 2011 21:32:50 +0100
Subject: [PATCH] tmpfiles: rename a couple of functions
remove_item -> remove_item_instance
remove_item_glob -> remove_item
(cherry picked from commit a08961233bea3bfad7776e04482d07012216b134)
---
src/tmpfiles.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/tmpfiles.c b/src/tmpfiles.c
index 6171140..4308f7f 100644
--- a/src/tmpfiles.c
+++ b/src/tmpfiles.c
@@ -563,7 +563,7 @@ finish:
return r;
}
-static int remove_item(Item *i, const char *instance) {
+static int remove_item_instance(Item *i, const char *instance) {
int r;
assert(i);
@@ -599,7 +599,7 @@ static int remove_item(Item *i, const char *instance) {
return 0;
}
-static int remove_item_glob(Item *i) {
+static int remove_item(Item *i) {
assert(i);
switch (i->type) {
@@ -633,7 +633,7 @@ static int remove_item_glob(Item *i) {
}
STRV_FOREACH(fn, g.gl_pathv)
- if ((k = remove_item(i, *fn)) < 0)
+ if ((k = remove_item_instance(i, *fn)) < 0)
r = k;
globfree(&g);
@@ -650,7 +650,7 @@ static int process_item(Item *i) {
assert(i);
r = arg_create ? create_item(i) : 0;
- q = arg_remove ? remove_item_glob(i) : 0;
+ q = arg_remove ? remove_item(i) : 0;
p = arg_clean ? clean_item(i) : 0;
if (r < 0)

View File

@ -0,0 +1,208 @@
From 35bb56b851308370435c0ff28c2d73a790043fbb Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 15 Dec 2011 23:44:23 +0100
Subject: [PATCH] tmpfiles: use a common function to set
owner/group/mode/label (cherry picked from commit
f05bc3f7f1d85ce4d31fa9c9b2780797ef3953cd)
---
src/tmpfiles.c | 120 +++++++++++++++++++++-----------------------------------
1 files changed, 45 insertions(+), 75 deletions(-)
diff --git a/src/tmpfiles.c b/src/tmpfiles.c
index 4308f7f..9d07a2a 100644
--- a/src/tmpfiles.c
+++ b/src/tmpfiles.c
@@ -405,8 +405,27 @@ finish:
return r;
}
+static int item_set_perms(Item *i) {
+ if (i->mode_set)
+ if (chmod(i->path, i->mode) < 0) {
+ log_error("chmod(%s) failed: %m", i->path);
+ return -errno;
+ }
+
+ if (i->uid_set || i->gid_set)
+ if (chown(i->path,
+ i->uid_set ? i->uid : (uid_t) -1,
+ i->gid_set ? i->gid : (gid_t) -1) < 0) {
+
+ log_error("chown(%s) failed: %m", i->path);
+ return -errno;
+ }
+
+ return label_fix(i->path, false);
+}
+
static int create_item(Item *i) {
- int fd = -1, r;
+ int r;
mode_t u;
struct stat st;
@@ -420,7 +439,8 @@ static int create_item(Item *i) {
return 0;
case CREATE_FILE:
- case TRUNCATE_FILE:
+ case TRUNCATE_FILE: {
+ int fd;
u = umask(0);
fd = open(i->path, O_CREAT|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW|
@@ -429,39 +449,27 @@ static int create_item(Item *i) {
if (fd < 0) {
log_error("Failed to create file %s: %m", i->path);
- r = -errno;
- goto finish;
+ return -errno;
}
- if (fstat(fd, &st) < 0) {
+ close_nointr_nofail(fd);
+
+ if (stat(i->path, &st) < 0) {
log_error("stat(%s) failed: %m", i->path);
- r = -errno;
- goto finish;
+ return -errno;
}
if (!S_ISREG(st.st_mode)) {
log_error("%s is not a file.", i->path);
- r = -EEXIST;
- goto finish;
+ return -EEXIST;
}
- if (i->mode_set)
- if (fchmod(fd, i->mode) < 0) {
- log_error("chmod(%s) failed: %m", i->path);
- r = -errno;
- goto finish;
- }
-
- if (i->uid_set || i->gid_set)
- if (fchown(fd,
- i->uid_set ? i->uid : (uid_t) -1,
- i->gid_set ? i->gid : (gid_t) -1) < 0) {
- log_error("chown(%s) failed: %m", i->path);
- r = -errno;
- goto finish;
- }
+ r = item_set_perms(i);
+ if (r < 0)
+ return r;
break;
+ }
case TRUNCATE_DIRECTORY:
case CREATE_DIRECTORY:
@@ -473,38 +481,22 @@ static int create_item(Item *i) {
if (r < 0 && errno != EEXIST) {
log_error("Failed to create directory %s: %m", i->path);
- r = -errno;
- goto finish;
+ return -errno;
}
if (stat(i->path, &st) < 0) {
log_error("stat(%s) failed: %m", i->path);
- r = -errno;
- goto finish;
+ return -errno;
}
if (!S_ISDIR(st.st_mode)) {
log_error("%s is not a directory.", i->path);
- r = -EEXIST;
- goto finish;
+ return -EEXIST;
}
- if (i->mode_set)
- if (chmod(i->path, i->mode) < 0) {
- log_error("chmod(%s) failed: %m", i->path);
- r = -errno;
- goto finish;
- }
-
- if (i->uid_set || i->gid_set)
- if (chown(i->path,
- i->uid_set ? i->uid : (uid_t) -1,
- i->gid_set ? i->gid : (gid_t) -1) < 0) {
-
- log_error("chown(%s) failed: %m", i->path);
- r = -errno;
- goto finish;
- }
+ r = item_set_perms(i);
+ if (r < 0)
+ return r;
break;
@@ -516,51 +508,29 @@ static int create_item(Item *i) {
if (r < 0 && errno != EEXIST) {
log_error("Failed to create fifo %s: %m", i->path);
- r = -errno;
- goto finish;
+ return -errno;
}
if (stat(i->path, &st) < 0) {
log_error("stat(%s) failed: %m", i->path);
- r = -errno;
- goto finish;
+ return -errno;
}
if (!S_ISFIFO(st.st_mode)) {
log_error("%s is not a fifo.", i->path);
- r = -EEXIST;
- goto finish;
+ return -EEXIST;
}
- if (i->mode_set)
- if (chmod(i->path, i->mode) < 0) {
- log_error("chmod(%s) failed: %m", i->path);
- r = -errno;
- goto finish;
- }
-
- if (i->uid_set || i->gid_set)
- if (chown(i->path,
- i->uid_set ? i->uid : (uid_t) -1,
- i->gid_set ? i->gid : (gid_t) -1) < 0) {
- log_error("chown(%s) failed: %m", i->path);
- r = -errno;
- goto finish;
- }
+ r = item_set_perms(i);
+ if (r < 0)
+ return r;
break;
}
- if ((r = label_fix(i->path, false)) < 0)
- goto finish;
-
log_debug("%s created successfully.", i->path);
-finish:
- if (fd >= 0)
- close_nointr_nofail(fd);
-
- return r;
+ return 0;
}
static int remove_item_instance(Item *i, const char *instance) {

View File

@ -0,0 +1,98 @@
From ef754c81da83d1a1d9b2a3eb41b545196800f59f Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 15 Dec 2011 23:45:26 +0100
Subject: [PATCH] tmpfiles: separate a generic item glob processing function
Item glob processing will be useful for more than just removing.
(cherry picked from commit 99e68c0b2d6ca9d491036920fcbca4c8d54404a8)
---
src/tmpfiles.c | 60 ++++++++++++++++++++++++++++++-------------------------
1 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/src/tmpfiles.c b/src/tmpfiles.c
index 9d07a2a..d655bc3 100644
--- a/src/tmpfiles.c
+++ b/src/tmpfiles.c
@@ -405,6 +405,33 @@ finish:
return r;
}
+static int glob_item(Item *i, int (*action)(Item *, const char *)) {
+ int r = 0, k;
+ glob_t g;
+ char **fn;
+
+ zero(g);
+
+ errno = 0;
+ if ((k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g)) != 0) {
+
+ if (k != GLOB_NOMATCH) {
+ if (errno != 0)
+ errno = EIO;
+
+ log_error("glob(%s) failed: %m", i->path);
+ return -errno;
+ }
+ }
+
+ STRV_FOREACH(fn, g.gl_pathv)
+ if ((k = action(i, *fn)) < 0)
+ r = k;
+
+ globfree(&g);
+ return r;
+}
+
static int item_set_perms(Item *i) {
if (i->mode_set)
if (chmod(i->path, i->mode) < 0) {
@@ -570,6 +597,8 @@ static int remove_item_instance(Item *i, const char *instance) {
}
static int remove_item(Item *i) {
+ int r = 0;
+
assert(i);
switch (i->type) {
@@ -583,35 +612,12 @@ static int remove_item(Item *i) {
case REMOVE_PATH:
case TRUNCATE_DIRECTORY:
- case RECURSIVE_REMOVE_PATH: {
- int r = 0, k;
- glob_t g;
- char **fn;
-
- zero(g);
-
- errno = 0;
- if ((k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g)) != 0) {
-
- if (k != GLOB_NOMATCH) {
- if (errno != 0)
- errno = EIO;
-
- log_error("glob(%s) failed: %m", i->path);
- return -errno;
- }
- }
-
- STRV_FOREACH(fn, g.gl_pathv)
- if ((k = remove_item_instance(i, *fn)) < 0)
- r = k;
-
- globfree(&g);
- return r;
- }
+ case RECURSIVE_REMOVE_PATH:
+ r = glob_item(i, remove_item_instance);
+ break;
}
- return 0;
+ return r;
}
static int process_item(Item *i) {

View File

@ -0,0 +1,192 @@
From 265c05c53ac71337feb5db53eb8c7acf13901a31 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 15 Dec 2011 23:11:07 +0100
Subject: [PATCH] tmpfiles: add RECURSIVE_RELABEL_PATH ('Z')
Feature requested by Dan Walsh.
(cherry picked from commit a8d8878329893d19106053e5008f0075f149aa16)
---
src/tmpfiles.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 112 insertions(+), 12 deletions(-)
diff --git a/src/tmpfiles.c b/src/tmpfiles.c
index d655bc3..18067c4 100644
--- a/src/tmpfiles.c
+++ b/src/tmpfiles.c
@@ -61,7 +61,8 @@ typedef enum ItemType {
/* These ones take globs */
IGNORE_PATH = 'x',
REMOVE_PATH = 'r',
- RECURSIVE_REMOVE_PATH = 'R'
+ RECURSIVE_REMOVE_PATH = 'R',
+ RECURSIVE_RELABEL_PATH = 'Z'
} ItemType;
typedef struct Item {
@@ -91,7 +92,7 @@ static const char *arg_prefix = NULL;
#define MAX_DEPTH 256
static bool needs_glob(ItemType t) {
- return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH;
+ return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RECURSIVE_RELABEL_PATH;
}
static struct Item* find_glob(Hashmap *h, const char *match) {
@@ -405,6 +406,96 @@ finish:
return r;
}
+static int recursive_relabel_children(const char *path) {
+ DIR *d;
+ int ret = 0;
+
+ /* This returns the first error we run into, but nevertheless
+ * tries to go on */
+
+ d = opendir(path);
+ if (!d)
+ return errno == ENOENT ? 0 : -errno;
+
+ for (;;) {
+ struct dirent buf, *de;
+ bool is_dir;
+ int r;
+ char *entry_path;
+
+ r = readdir_r(d, &buf, &de);
+ if (r != 0) {
+ if (ret == 0)
+ ret = -r;
+ break;
+ }
+
+ if (!de)
+ break;
+
+ if (streq(de->d_name, ".") || streq(de->d_name, ".."))
+ continue;
+
+ if (asprintf(&entry_path, "%s/%s", path, de->d_name) < 0) {
+ if (ret == 0)
+ ret = -ENOMEM;
+ continue;
+ }
+
+ if (de->d_type == DT_UNKNOWN) {
+ struct stat st;
+
+ if (lstat(entry_path, &st) < 0) {
+ if (ret == 0 && errno != ENOENT)
+ ret = -errno;
+ free(entry_path);
+ continue;
+ }
+
+ is_dir = S_ISDIR(st.st_mode);
+
+ } else
+ is_dir = de->d_type == DT_DIR;
+
+ r = label_fix(entry_path, false);
+ if (r < 0) {
+ if (ret == 0 && r != -ENOENT)
+ ret = r;
+ free(entry_path);
+ continue;
+ }
+
+ if (is_dir) {
+ r = recursive_relabel_children(entry_path);
+ if (r < 0 && ret == 0)
+ ret = r;
+ }
+
+ free(entry_path);
+ }
+
+ closedir(d);
+
+ return ret;
+}
+
+static int recursive_relabel(Item *i, const char *path) {
+ int r;
+ struct stat st;
+
+ r = label_fix(path, false);
+ if (r < 0)
+ return r;
+
+ if (lstat(path, &st) < 0)
+ return -errno;
+
+ if (S_ISDIR(st.st_mode))
+ r = recursive_relabel_children(path);
+
+ return r;
+}
+
static int glob_item(Item *i, int (*action)(Item *, const char *)) {
int r = 0, k;
glob_t g;
@@ -553,6 +644,12 @@ static int create_item(Item *i) {
return r;
break;
+
+ case RECURSIVE_RELABEL_PATH:
+
+ r = glob_item(i, recursive_relabel);
+ if (r < 0)
+ return r;
}
log_debug("%s created successfully.", i->path);
@@ -572,6 +669,7 @@ static int remove_item_instance(Item *i, const char *instance) {
case CREATE_DIRECTORY:
case CREATE_FIFO:
case IGNORE_PATH:
+ case RECURSIVE_RELABEL_PATH:
break;
case REMOVE_PATH:
@@ -608,6 +706,7 @@ static int remove_item(Item *i) {
case CREATE_DIRECTORY:
case CREATE_FIFO:
case IGNORE_PATH:
+ case RECURSIVE_RELABEL_PATH:
break;
case REMOVE_PATH:
@@ -707,20 +806,21 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
r = -EIO;
goto finish;
}
- i->type = type;
- if (i->type != CREATE_FILE &&
- i->type != TRUNCATE_FILE &&
- i->type != CREATE_DIRECTORY &&
- i->type != TRUNCATE_DIRECTORY &&
- i->type != CREATE_FIFO &&
- i->type != IGNORE_PATH &&
- i->type != REMOVE_PATH &&
- i->type != RECURSIVE_REMOVE_PATH) {
- log_error("[%s:%u] Unknown file type '%c'.", fname, line, i->type);
+ if (type != CREATE_FILE &&
+ type != TRUNCATE_FILE &&
+ type != CREATE_DIRECTORY &&
+ type != TRUNCATE_DIRECTORY &&
+ type != CREATE_FIFO &&
+ type != IGNORE_PATH &&
+ type != REMOVE_PATH &&
+ type != RECURSIVE_REMOVE_PATH &&
+ type != RECURSIVE_RELABEL_PATH) {
+ log_error("[%s:%u] Unknown file type '%c'.", fname, line, type);
r = -EBADMSG;
goto finish;
}
+ i->type = type;
if (!path_is_absolute(i->path)) {
log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);

View File

@ -0,0 +1,46 @@
From e5c58e069271013582b9de91859aaa5fef70f079 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 15 Dec 2011 23:04:37 +0100
Subject: [PATCH] man: document 'Z' in tmpfiles (cherry picked from commit
462d63db0680c2b69d5426ded197342372ebe309)
---
man/systemd-tmpfiles.xml | 3 ++-
man/tmpfiles.d.xml | 10 ++++++++++
2 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
index 08d5c73..20e399b 100644
--- a/man/systemd-tmpfiles.xml
+++ b/man/systemd-tmpfiles.xml
@@ -84,7 +84,8 @@
<listitem><para>If this option is passed all
files and directories marked with f,
F, d, D in the configuration files are
- created.</para></listitem>
+ created. Files and directories marked with Z
+ are relabeled.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index 7f4c45c..580d99c 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -155,6 +155,16 @@ d /run/user 0755 root root 10d</programlisting>
place of normal path
names.</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>Z</varname></term>
+ <listitem><para>Recursively
+ relabel security context of a path and
+ all its subdirectories (if it is a
+ directory). Lines of this type accept
+ shell-style globs in place of normal
+ path names.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect2>

View File

@ -0,0 +1,32 @@
From a783d0af2d7a5a40942c8c2355a9119e3344dcc2 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 16 Dec 2011 00:38:22 +0100
Subject: [PATCH] man: mention that 'Z' ignores uid/gid/mode (cherry picked
from commit a37b560a63f9b48980b94fc1cf9cd4fe25e3b904)
---
man/tmpfiles.d.xml | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index 580d99c..6a2a377 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -175,7 +175,7 @@ d /run/user 0755 root root 10d</programlisting>
creating this file or directory. If omitted or
when set to - the default is used: 0755 for
directories, 0644 for files. This parameter is
- ignored for x, r, R lines.</para>
+ ignored for x, r, R, Z lines.</para>
</refsect2>
<refsect2>
@@ -186,7 +186,7 @@ d /run/user 0755 root root 10d</programlisting>
user/group ID or a user or group name. If
omitted or when set to - the default 0 (root)
is used. . These parameters are ignored for x,
- r, R lines.</para>
+ r, R, Z lines.</para>
</refsect2>
<refsect2>

View File

@ -0,0 +1,25 @@
From d18d8b40a2c65a551d2954cea701631a5db323e7 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 16 Dec 2011 17:38:01 +0100
Subject: [PATCH] service: use 'syslog+console' for sysv_console
The default output to 'tty' for SysV service was making it hard to debug
problems because error messages were missing from syslog.
(cherry picked from commit 18d01523c88d59293d5bd1c199d41ce587e4856e)
---
src/service.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/service.c b/src/service.c
index 175a729..d229301 100644
--- a/src/service.c
+++ b/src/service.c
@@ -833,7 +833,7 @@ static int service_load_sysv_path(Service *s, const char *path) {
s->restart = SERVICE_RESTART_NO;
if (s->meta.manager->sysv_console)
- s->exec_context.std_output = EXEC_OUTPUT_TTY;
+ s->exec_context.std_output = EXEC_OUTPUT_SYSLOG_AND_CONSOLE;
s->exec_context.kill_mode = KILL_PROCESS;

View File

@ -0,0 +1,191 @@
From 2c023ff55f1449a841aa8449f03792a8436c2481 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 16 Dec 2011 18:00:11 +0100
Subject: [PATCH] tmpfiles: apply chown, chmod for 'Z' entries too
If changing ownership or permissions is not desired, they can be
configured to '-' or omitted entirely.
(cherry picked from commit 062e01bbdbc3201e4c99bc0b702cb04a0ae2190c)
---
man/systemd-tmpfiles.xml | 3 +-
man/tmpfiles.d.xml | 16 ++++++++-----
src/tmpfiles.c | 55 +++++++++++++++++++++++----------------------
3 files changed, 40 insertions(+), 34 deletions(-)
diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
index 20e399b..74dfd5a 100644
--- a/man/systemd-tmpfiles.xml
+++ b/man/systemd-tmpfiles.xml
@@ -85,7 +85,8 @@
files and directories marked with f,
F, d, D in the configuration files are
created. Files and directories marked with Z
- are relabeled.</para></listitem>
+ have their ownership, access mode and security
+ labels set.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index 6a2a377..e137967 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -158,8 +158,9 @@ d /run/user 0755 root root 10d</programlisting>
<varlistentry>
<term><varname>Z</varname></term>
- <listitem><para>Recursively
- relabel security context of a path and
+ <listitem><para>Recursively set
+ ownership, access mode and relabel
+ security context of a path and
all its subdirectories (if it is a
directory). Lines of this type accept
shell-style globs in place of normal
@@ -174,8 +175,10 @@ d /run/user 0755 root root 10d</programlisting>
<para>The file access mode to use when
creating this file or directory. If omitted or
when set to - the default is used: 0755 for
- directories, 0644 for files. This parameter is
- ignored for x, r, R, Z lines.</para>
+ directories, 0644 for files. For Z lines
+ if omitted or when set to - the file access mode will
+ not be modified. This parameter is ignored for x, r, R
+ lines.</para>
</refsect2>
<refsect2>
@@ -185,8 +188,9 @@ d /run/user 0755 root root 10d</programlisting>
or directory. This may either be a numeric
user/group ID or a user or group name. If
omitted or when set to - the default 0 (root)
- is used. . These parameters are ignored for x,
- r, R, Z lines.</para>
+ is used. For Z lines when omitted or when set to -
+ the file ownership will not be modified.
+ These parameters are ignored for x, r, R lines.</para>
</refsect2>
<refsect2>
diff --git a/src/tmpfiles.c b/src/tmpfiles.c
index 18067c4..1395082 100644
--- a/src/tmpfiles.c
+++ b/src/tmpfiles.c
@@ -406,7 +406,27 @@ finish:
return r;
}
-static int recursive_relabel_children(const char *path) {
+static int item_set_perms(Item *i, const char *path) {
+ /* not using i->path directly because it may be a glob */
+ if (i->mode_set)
+ if (chmod(path, i->mode) < 0) {
+ log_error("chmod(%s) failed: %m", path);
+ return -errno;
+ }
+
+ if (i->uid_set || i->gid_set)
+ if (chown(path,
+ i->uid_set ? i->uid : (uid_t) -1,
+ i->gid_set ? i->gid : (gid_t) -1) < 0) {
+
+ log_error("chown(%s) failed: %m", path);
+ return -errno;
+ }
+
+ return label_fix(path, false);
+}
+
+static int recursive_relabel_children(Item *i, const char *path) {
DIR *d;
int ret = 0;
@@ -457,7 +477,7 @@ static int recursive_relabel_children(const char *path) {
} else
is_dir = de->d_type == DT_DIR;
- r = label_fix(entry_path, false);
+ r = item_set_perms(i, entry_path);
if (r < 0) {
if (ret == 0 && r != -ENOENT)
ret = r;
@@ -466,7 +486,7 @@ static int recursive_relabel_children(const char *path) {
}
if (is_dir) {
- r = recursive_relabel_children(entry_path);
+ r = recursive_relabel_children(i, entry_path);
if (r < 0 && ret == 0)
ret = r;
}
@@ -483,7 +503,7 @@ static int recursive_relabel(Item *i, const char *path) {
int r;
struct stat st;
- r = label_fix(path, false);
+ r = item_set_perms(i, path);
if (r < 0)
return r;
@@ -491,7 +511,7 @@ static int recursive_relabel(Item *i, const char *path) {
return -errno;
if (S_ISDIR(st.st_mode))
- r = recursive_relabel_children(path);
+ r = recursive_relabel_children(i, path);
return r;
}
@@ -523,25 +543,6 @@ static int glob_item(Item *i, int (*action)(Item *, const char *)) {
return r;
}
-static int item_set_perms(Item *i) {
- if (i->mode_set)
- if (chmod(i->path, i->mode) < 0) {
- log_error("chmod(%s) failed: %m", i->path);
- return -errno;
- }
-
- if (i->uid_set || i->gid_set)
- if (chown(i->path,
- i->uid_set ? i->uid : (uid_t) -1,
- i->gid_set ? i->gid : (gid_t) -1) < 0) {
-
- log_error("chown(%s) failed: %m", i->path);
- return -errno;
- }
-
- return label_fix(i->path, false);
-}
-
static int create_item(Item *i) {
int r;
mode_t u;
@@ -582,7 +583,7 @@ static int create_item(Item *i) {
return -EEXIST;
}
- r = item_set_perms(i);
+ r = item_set_perms(i, i->path);
if (r < 0)
return r;
@@ -612,7 +613,7 @@ static int create_item(Item *i) {
return -EEXIST;
}
- r = item_set_perms(i);
+ r = item_set_perms(i, i->path);
if (r < 0)
return r;
@@ -639,7 +640,7 @@ static int create_item(Item *i) {
return -EEXIST;
}
- r = item_set_perms(i);
+ r = item_set_perms(i, i->path);
if (r < 0)
return r;

View File

@ -0,0 +1,146 @@
From 4f0399974eb67bc9420c3bd700465190e38d92d6 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 16 Dec 2011 18:27:35 +0100
Subject: [PATCH] tmpfiles: add 'z', like 'Z' but not recursive (cherry picked
from commit 777b87e702197ad1f2d0f2a3aea5271d18062c5c)
---
man/systemd-tmpfiles.xml | 4 ++--
man/tmpfiles.d.xml | 14 ++++++++++++--
src/tmpfiles.c | 34 ++++++++++++++++++++++++----------
3 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
index 74dfd5a..bbb80b2 100644
--- a/man/systemd-tmpfiles.xml
+++ b/man/systemd-tmpfiles.xml
@@ -84,8 +84,8 @@
<listitem><para>If this option is passed all
files and directories marked with f,
F, d, D in the configuration files are
- created. Files and directories marked with Z
- have their ownership, access mode and security
+ created. Files and directories marked with z,
+ Z have their ownership, access mode and security
labels set.</para></listitem>
</varlistentry>
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index e137967..4a8e831 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -157,6 +157,16 @@ d /run/user 0755 root root 10d</programlisting>
</varlistentry>
<varlistentry>
+ <term><varname>z</varname></term>
+ <listitem><para>Set ownership, access
+ mode and relabel security context of
+ a file or directory if it exists.
+ Lines of this type accept shell-style
+ globs in place of normal path names.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>Z</varname></term>
<listitem><para>Recursively set
ownership, access mode and relabel
@@ -175,7 +185,7 @@ d /run/user 0755 root root 10d</programlisting>
<para>The file access mode to use when
creating this file or directory. If omitted or
when set to - the default is used: 0755 for
- directories, 0644 for files. For Z lines
+ directories, 0644 for files. For z, Z lines
if omitted or when set to - the file access mode will
not be modified. This parameter is ignored for x, r, R
lines.</para>
@@ -188,7 +198,7 @@ d /run/user 0755 root root 10d</programlisting>
or directory. This may either be a numeric
user/group ID or a user or group name. If
omitted or when set to - the default 0 (root)
- is used. For Z lines when omitted or when set to -
+ is used. For z, Z lines when omitted or when set to -
the file ownership will not be modified.
These parameters are ignored for x, r, R lines.</para>
</refsect2>
diff --git a/src/tmpfiles.c b/src/tmpfiles.c
index 1395082..19a7c08 100644
--- a/src/tmpfiles.c
+++ b/src/tmpfiles.c
@@ -62,6 +62,7 @@ typedef enum ItemType {
IGNORE_PATH = 'x',
REMOVE_PATH = 'r',
RECURSIVE_REMOVE_PATH = 'R',
+ RELABEL_PATH = 'z',
RECURSIVE_RELABEL_PATH = 'Z'
} ItemType;
@@ -92,7 +93,7 @@ static const char *arg_prefix = NULL;
#define MAX_DEPTH 256
static bool needs_glob(ItemType t) {
- return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RECURSIVE_RELABEL_PATH;
+ return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RELABEL_PATH || t == RECURSIVE_RELABEL_PATH;
}
static struct Item* find_glob(Hashmap *h, const char *match) {
@@ -646,6 +647,13 @@ static int create_item(Item *i) {
break;
+ case RELABEL_PATH:
+
+ r = glob_item(i, item_set_perms);
+ if (r < 0)
+ return 0;
+ break;
+
case RECURSIVE_RELABEL_PATH:
r = glob_item(i, recursive_relabel);
@@ -670,6 +678,7 @@ static int remove_item_instance(Item *i, const char *instance) {
case CREATE_DIRECTORY:
case CREATE_FIFO:
case IGNORE_PATH:
+ case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
break;
@@ -707,6 +716,7 @@ static int remove_item(Item *i) {
case CREATE_DIRECTORY:
case CREATE_FIFO:
case IGNORE_PATH:
+ case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
break;
@@ -808,15 +818,19 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
goto finish;
}
- if (type != CREATE_FILE &&
- type != TRUNCATE_FILE &&
- type != CREATE_DIRECTORY &&
- type != TRUNCATE_DIRECTORY &&
- type != CREATE_FIFO &&
- type != IGNORE_PATH &&
- type != REMOVE_PATH &&
- type != RECURSIVE_REMOVE_PATH &&
- type != RECURSIVE_RELABEL_PATH) {
+ switch(type) {
+ case CREATE_FILE:
+ case TRUNCATE_FILE:
+ case CREATE_DIRECTORY:
+ case TRUNCATE_DIRECTORY:
+ case CREATE_FIFO:
+ case IGNORE_PATH:
+ case REMOVE_PATH:
+ case RECURSIVE_REMOVE_PATH:
+ case RELABEL_PATH:
+ case RECURSIVE_RELABEL_PATH:
+ break;
+ default:
log_error("[%s:%u] Unknown file type '%c'.", fname, line, type);
r = -EBADMSG;
goto finish;

View File

@ -0,0 +1,29 @@
From f2a7f81850607590c5d64efe5beedadc85be9909 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 17 Dec 2011 00:39:19 +0100
Subject: [PATCH] man: fix misplaced remark in description of Sockets= (cherry
picked from commit
4f025f4c4f9e043a06a05bcd4fc9fa65ee232ecc)
---
man/systemd.service.xml | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 7b6f12d..0baddd1 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -671,11 +671,11 @@
<listitem><para>Specifies the name of
the socket units this service shall
inherit the sockets from when the
- service (ignoring the different suffix
- of course) is started. Normally it
+ service is started. Normally it
should not be necessary to use this
setting as all sockets whose unit
shares the same name as the service
+ (ignoring the different suffix of course)
are passed to the spawned
process.</para>

View File

@ -0,0 +1,26 @@
From ef50636c71f16165e58b38c25890213e2a6b073b Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sat, 17 Dec 2011 01:33:40 +0100
Subject: [PATCH] execute: fix losing of start timestamps
Start timestamps were always cleared before saving exit timestamps.
Fix it by removing a condition that makes no sense any way I look at it.
(cherry picked from commit 0b1f4ae63548c627decd80e3e2fd030c2d4f3af6)
---
src/execute.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/src/execute.c b/src/execute.c
index 481725d..abbbfdd 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1860,8 +1860,7 @@ void exec_status_start(ExecStatus *s, pid_t pid) {
void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
assert(s);
- if ((s->pid && s->pid != pid) ||
- !s->start_timestamp.realtime <= 0)
+ if (s->pid && s->pid != pid)
zero(*s);
s->pid = pid;

View File

@ -0,0 +1,23 @@
From afa63b4de8367c2c48c639471e18962c1e1b5ad5 Mon Sep 17 00:00:00 2001
From: Dan Walsh <dwalsh@redhat.com>
Date: Mon, 19 Dec 2011 23:55:29 +0100
Subject: [PATCH] label: fix labeling of symbolic links (cherry picked from
commit 81c3f1f6aba52ac5e95241b51083b61c7401be44)
---
src/label.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/label.c b/src/label.c
index d9d195b..2c887a0 100644
--- a/src/label.c
+++ b/src/label.c
@@ -109,7 +109,7 @@ int label_fix(const char *path, bool ignore_enoent) {
return 0;
if (r == 0) {
- r = setfilecon(path, fcon);
+ r = lsetfilecon(path, fcon);
freecon(fcon);
/* If the FS doesn't support labels, then exit without warning */

View File

@ -0,0 +1,560 @@
From 6e1da63130bb563b5cce89c2a7d66e98e79c5ec4 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sun, 18 Dec 2011 14:58:10 +0100
Subject: [PATCH] dbus: register to DBus asynchronously
Chen Jie observed and analyzed a deadlock. Assuming systemd-kmsg-syslogd
is already stopped, but rsyslogd is not started yet:
1. systemd makes a synchronous call to dbus-daemon.
2. dbus-daemon wants to write something to syslog.
3. syslog needs to be started by systemd.
... but cannot be, because systemd is waiting in 1.
Solve this by avoiding synchronous D-Bus calls. I had to write an async
bus registration call. Interestingly, D-Bus authors anticipated this, in
documentation to dbus_bus_set_unique_name():
> The only reason to use this function is to re-implement the equivalent
> of dbus_bus_register() yourself. One (probably unusual) reason to do
> that might be to do the bus registration call asynchronously instead
> of synchronously.
Lennart's comments from IRC:
> though I think this doesn't fix the problem in its entirety
> simply because dbus_connection_open_private() itself is still synchronous
> i.e. the connect() call behind it is not async
> I think I listed that issue actually on some D-Bus todo list
> i.e. to make dbus_connection_get() fully async
> but that's going to be hard
> so your patch looks good
So it may not be perfect, but it's clearly an improvement.
I did not manage to reproduce the original deadlock with the patch.
(cherry picked from commit cbd37330bcd039587121a767280fc9fee597af6e)
---
src/dbus.c | 378 +++++++++++++++++++++++++++++++++++++++------------------
src/manager.c | 2 +-
src/manager.h | 1 +
3 files changed, 262 insertions(+), 119 deletions(-)
diff --git a/src/dbus.c b/src/dbus.c
index daa2c84..81b4f53 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -48,6 +48,11 @@
#define CONNECTIONS_MAX 52
+/* Well-known address (http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-types) */
+#define DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
+/* Only used as a fallback */
+#define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:"
+
static const char bus_properties_interface[] = BUS_PROPERTIES_INTERFACE;
static const char bus_introspectable_interface[] = BUS_INTROSPECTABLE_INTERFACE;
@@ -767,37 +772,19 @@ static void bus_new_connection(
dbus_connection_ref(new_connection);
}
-static int bus_init_system(Manager *m) {
- DBusError error;
- int r;
-
- assert(m);
-
- dbus_error_init(&error);
-
- if (m->system_bus)
- return 0;
-
- if (m->running_as == MANAGER_SYSTEM && m->api_bus)
- m->system_bus = m->api_bus;
- else {
- if (!(m->system_bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error))) {
- log_debug("Failed to get system D-Bus connection, retrying later: %s", bus_error_message(&error));
- r = 0;
- goto fail;
- }
-
- if ((r = bus_setup_loop(m, m->system_bus)) < 0)
- goto fail;
- }
+static int init_registered_system_bus(Manager *m) {
+ char *id;
if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL)) {
log_error("Not enough memory");
- r = -ENOMEM;
- goto fail;
+ return -ENOMEM;
}
if (m->running_as != MANAGER_SYSTEM) {
+ DBusError error;
+
+ dbus_error_init(&error);
+
dbus_bus_add_match(m->system_bus,
"type='signal',"
"interface='org.freedesktop.systemd1.Agent',"
@@ -807,59 +794,28 @@ static int bus_init_system(Manager *m) {
if (dbus_error_is_set(&error)) {
log_error("Failed to register match: %s", bus_error_message(&error));
- r = -EIO;
- goto fail;
+ dbus_error_free(&error);
+ return -1;
}
}
- if (m->api_bus != m->system_bus) {
- char *id;
- log_debug("Successfully connected to system D-Bus bus %s as %s",
- strnull((id = dbus_connection_get_server_id(m->system_bus))),
- strnull(dbus_bus_get_unique_name(m->system_bus)));
- dbus_free(id);
- }
+ log_debug("Successfully connected to system D-Bus bus %s as %s",
+ strnull((id = dbus_connection_get_server_id(m->system_bus))),
+ strnull(dbus_bus_get_unique_name(m->system_bus)));
+ dbus_free(id);
return 0;
-
-fail:
- bus_done_system(m);
- dbus_error_free(&error);
-
- return r;
}
-static int bus_init_api(Manager *m) {
- DBusError error;
+static int init_registered_api_bus(Manager *m) {
int r;
- assert(m);
-
- dbus_error_init(&error);
-
- if (m->api_bus)
- return 0;
-
- if (m->running_as == MANAGER_SYSTEM && m->system_bus)
- m->api_bus = m->system_bus;
- else {
- if (!(m->api_bus = dbus_bus_get_private(m->running_as == MANAGER_USER ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &error))) {
- log_debug("Failed to get API D-Bus connection, retrying later: %s", bus_error_message(&error));
- r = 0;
- goto fail;
- }
-
- if ((r = bus_setup_loop(m, m->api_bus)) < 0)
- goto fail;
- }
-
if (!dbus_connection_register_object_path(m->api_bus, "/org/freedesktop/systemd1", &bus_manager_vtable, m) ||
!dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) ||
!dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) ||
!dbus_connection_add_filter(m->api_bus, api_bus_message_filter, m, NULL)) {
log_error("Not enough memory");
- r = -ENOMEM;
- goto fail;
+ return -ENOMEM;
}
/* Get NameOwnerChange messages */
@@ -869,13 +825,7 @@ static int bus_init_api(Manager *m) {
"interface='"DBUS_INTERFACE_DBUS"',"
"member='NameOwnerChanged',"
"path='"DBUS_PATH_DBUS"'",
- &error);
-
- if (dbus_error_is_set(&error)) {
- log_error("Failed to register match: %s", bus_error_message(&error));
- r = -EIO;
- goto fail;
- }
+ NULL);
/* Get activation requests */
dbus_bus_add_match(m->api_bus,
@@ -884,33 +834,225 @@ static int bus_init_api(Manager *m) {
"interface='org.freedesktop.systemd1.Activator',"
"member='ActivationRequest',"
"path='"DBUS_PATH_DBUS"'",
- &error);
-
- if (dbus_error_is_set(&error)) {
- log_error("Failed to register match: %s", bus_error_message(&error));
- r = -EIO;
- goto fail;
- }
+ NULL);
- if ((r = request_name(m)) < 0)
- goto fail;
+ r = request_name(m);
+ if (r < 0)
+ return r;
- if ((r = query_name_list(m)) < 0)
- goto fail;
+ r = query_name_list(m);
+ if (r < 0)
+ return r;
- if (m->api_bus != m->system_bus) {
+ if (m->running_as == MANAGER_USER) {
char *id;
log_debug("Successfully connected to API D-Bus bus %s as %s",
strnull((id = dbus_connection_get_server_id(m->api_bus))),
strnull(dbus_bus_get_unique_name(m->api_bus)));
dbus_free(id);
+ } else
+ log_debug("Successfully initialized API on the system bus");
+
+ return 0;
+}
+
+static void bus_register_cb(DBusPendingCall *pending, void *userdata) {
+ Manager *m = userdata;
+ DBusConnection **conn;
+ DBusMessage *reply;
+ DBusError error;
+ const char *name;
+ int r = 0;
+
+ dbus_error_init(&error);
+
+ conn = dbus_pending_call_get_data(pending, m->conn_data_slot);
+ assert(conn == &m->system_bus || conn == &m->api_bus);
+
+ reply = dbus_pending_call_steal_reply(pending);
+
+ switch (dbus_message_get_type(reply)) {
+ case DBUS_MESSAGE_TYPE_ERROR:
+ assert_se(dbus_set_error_from_message(&error, reply));
+ log_warning("Failed to register to bus: %s", bus_error_message(&error));
+ r = -1;
+ break;
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ if (!dbus_message_get_args(reply, &error,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID)) {
+ log_error("Failed to parse Hello reply: %s", bus_error_message(&error));
+ r = -1;
+ break;
+ }
+
+ log_debug("Received name %s in reply to Hello", name);
+ if (!dbus_bus_set_unique_name(*conn, name)) {
+ log_error("Failed to set unique name");
+ r = -1;
+ break;
+ }
+
+ if (conn == &m->system_bus) {
+ r = init_registered_system_bus(m);
+ if (r == 0 && m->running_as == MANAGER_SYSTEM)
+ r = init_registered_api_bus(m);
+ } else
+ r = init_registered_api_bus(m);
+
+ break;
+ default:
+ assert_not_reached("Invalid reply message");
+ }
+
+ dbus_message_unref(reply);
+ dbus_error_free(&error);
+
+ if (r < 0) {
+ if (conn == &m->system_bus) {
+ log_debug("Failed setting up the system bus");
+ bus_done_system(m);
+ } else {
+ log_debug("Failed setting up the API bus");
+ bus_done_api(m);
+ }
+ }
+}
+
+static int manager_bus_async_register(Manager *m, DBusConnection **conn) {
+ DBusMessage *message = NULL;
+ DBusPendingCall *pending = NULL;
+
+ message = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "Hello");
+ if (!message)
+ goto oom;
+
+ if (!dbus_connection_send_with_reply(*conn, message, &pending, -1))
+ goto oom;
+
+ if (!dbus_pending_call_set_data(pending, m->conn_data_slot, conn, NULL))
+ goto oom;
+
+ if (!dbus_pending_call_set_notify(pending, bus_register_cb, m, NULL))
+ goto oom;
+
+ dbus_message_unref(message);
+ dbus_pending_call_unref(pending);
+
+ return 0;
+oom:
+ if (pending) {
+ dbus_pending_call_cancel(pending);
+ dbus_pending_call_unref(pending);
+ }
+
+ if (message)
+ dbus_message_unref(message);
+
+ return -ENOMEM;
+}
+
+static DBusConnection* manager_bus_connect_private(Manager *m, DBusBusType type) {
+ const char *address;
+ DBusConnection *connection;
+ DBusError error;
+
+ switch (type) {
+ case DBUS_BUS_SYSTEM:
+ address = getenv("DBUS_SYSTEM_BUS_ADDRESS");
+ if (!address || !address[0])
+ address = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS;
+ break;
+ case DBUS_BUS_SESSION:
+ address = getenv("DBUS_SESSION_BUS_ADDRESS");
+ if (!address || !address[0])
+ address = DBUS_SESSION_BUS_DEFAULT_ADDRESS;
+ break;
+ default:
+ assert_not_reached("Invalid bus type");
+ }
+
+ dbus_error_init(&error);
+
+ connection = dbus_connection_open_private(address, &error);
+ if (!connection) {
+ log_warning("Failed to open private bus connection: %s", bus_error_message(&error));
+ goto fail;
+ }
+
+ return connection;
+fail:
+ if (connection)
+ dbus_connection_close(connection);
+ dbus_error_free(&error);
+ return NULL;
+}
+
+static int bus_init_system(Manager *m) {
+ int r;
+
+ if (m->system_bus)
+ return 0;
+
+ m->system_bus = manager_bus_connect_private(m, DBUS_BUS_SYSTEM);
+ if (!m->system_bus) {
+ log_debug("Failed to connect to system D-Bus, retrying later");
+ r = 0;
+ goto fail;
}
+ r = bus_setup_loop(m, m->system_bus);
+ if (r < 0)
+ goto fail;
+
+ r = manager_bus_async_register(m, &m->system_bus);
+ if (r < 0)
+ goto fail;
+
return 0;
+fail:
+ bus_done_system(m);
+
+ return r;
+}
+
+static int bus_init_api(Manager *m) {
+ int r;
+
+ if (m->api_bus)
+ return 0;
+
+ if (m->running_as == MANAGER_SYSTEM) {
+ m->api_bus = m->system_bus;
+ /* In this mode there is no distinct connection to the API bus,
+ * the API is published on the system bus.
+ * bus_register_cb() is aware of that and will init the API
+ * when the system bus gets registered.
+ * No need to setup anything here. */
+ return 0;
+ }
+
+ m->api_bus = manager_bus_connect_private(m, DBUS_BUS_SESSION);
+ if (!m->api_bus) {
+ log_debug("Failed to connect to API D-Bus, retrying later");
+ r = 0;
+ goto fail;
+ }
+
+ r = bus_setup_loop(m, m->api_bus);
+ if (r < 0)
+ goto fail;
+ r = manager_bus_async_register(m, &m->api_bus);
+ if (r < 0)
+ goto fail;
+
+ return 0;
fail:
bus_done_api(m);
- dbus_error_free(&error);
return r;
}
@@ -989,22 +1131,20 @@ int bus_init(Manager *m, bool try_bus_connect) {
int r;
if (set_ensure_allocated(&m->bus_connections, trivial_hash_func, trivial_compare_func) < 0 ||
- set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0) {
- log_error("Not enough memory");
- return -ENOMEM;
- }
+ set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0)
+ goto oom;
if (m->name_data_slot < 0)
- if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot)) {
- log_error("Not enough memory");
- return -ENOMEM;
- }
+ if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot))
+ goto oom;
+
+ if (m->conn_data_slot < 0)
+ if (!dbus_pending_call_allocate_data_slot(&m->conn_data_slot))
+ goto oom;
if (m->subscribed_data_slot < 0)
- if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot)) {
- log_error("Not enough memory");
- return -ENOMEM;
- }
+ if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot))
+ goto oom;
if (try_bus_connect) {
if ((r = bus_init_system(m)) < 0 ||
@@ -1016,6 +1156,9 @@ int bus_init(Manager *m, bool try_bus_connect) {
return r;
return 0;
+oom:
+ log_error("Not enough memory");
+ return -ENOMEM;
}
static void shutdown_connection(Manager *m, DBusConnection *c) {
@@ -1059,42 +1202,38 @@ static void shutdown_connection(Manager *m, DBusConnection *c) {
}
static void bus_done_api(Manager *m) {
- assert(m);
-
- if (m->api_bus) {
- if (m->system_bus == m->api_bus)
- m->system_bus = NULL;
+ if (!m->api_bus)
+ return;
+ if (m->running_as == MANAGER_USER)
shutdown_connection(m, m->api_bus);
- m->api_bus = NULL;
- }
+ m->api_bus = NULL;
- if (m->queued_message) {
- dbus_message_unref(m->queued_message);
- m->queued_message = NULL;
- }
+ if (m->queued_message) {
+ dbus_message_unref(m->queued_message);
+ m->queued_message = NULL;
+ }
}
static void bus_done_system(Manager *m) {
- assert(m);
+ if (!m->system_bus)
+ return;
- if (m->system_bus == m->api_bus)
+ if (m->running_as == MANAGER_SYSTEM)
bus_done_api(m);
- if (m->system_bus) {
- shutdown_connection(m, m->system_bus);
- m->system_bus = NULL;
- }
+ shutdown_connection(m, m->system_bus);
+ m->system_bus = NULL;
}
static void bus_done_private(Manager *m) {
+ if (!m->private_bus)
+ return;
- if (m->private_bus) {
- dbus_server_disconnect(m->private_bus);
- dbus_server_unref(m->private_bus);
- m->private_bus = NULL;
- }
+ dbus_server_disconnect(m->private_bus);
+ dbus_server_unref(m->private_bus);
+ m->private_bus = NULL;
}
void bus_done(Manager *m) {
@@ -1116,6 +1255,9 @@ void bus_done(Manager *m) {
if (m->name_data_slot >= 0)
dbus_pending_call_free_data_slot(&m->name_data_slot);
+ if (m->conn_data_slot >= 0)
+ dbus_pending_call_free_data_slot(&m->conn_data_slot);
+
if (m->subscribed_data_slot >= 0)
dbus_connection_free_data_slot(&m->subscribed_data_slot);
}
diff --git a/src/manager.c b/src/manager.c
index 111167a..6acc821 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -231,7 +231,7 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) {
dual_timestamp_get(&m->startup_timestamp);
m->running_as = running_as;
- m->name_data_slot = m->subscribed_data_slot = -1;
+ m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1;
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
m->pin_cgroupfs_fd = -1;
diff --git a/src/manager.h b/src/manager.h
index 5deb569..6e7558e 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -179,6 +179,7 @@ struct Manager {
Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */
int32_t name_data_slot;
+ int32_t conn_data_slot;
int32_t subscribed_data_slot;
uint32_t current_job_id;

View File

@ -0,0 +1,26 @@
From 8787a5577aef2703a1484a57db4fe3afb196fc73 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Mon, 19 Dec 2011 18:32:10 +0100
Subject: [PATCH] dbus: no sync D-Bus connection flushing
Blocking on D-Bus in a system manager could lead to deadlock.
(cherry picked from commit 9721b19968dd80ad187d03da214a2a8d28ead3ad)
---
src/dbus.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/src/dbus.c b/src/dbus.c
index 81b4f53..f9250f1 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -1196,7 +1196,9 @@ static void shutdown_connection(Manager *m, DBusConnection *c) {
}
dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL);
- dbus_connection_flush(c);
+ /* system manager cannot afford to block on DBus */
+ if (m->running_as != MANAGER_SYSTEM)
+ dbus_connection_flush(c);
dbus_connection_close(c);
dbus_connection_unref(c);
}

View File

@ -0,0 +1,74 @@
From 58a06a6dfb11121bc1220c1c21fdf11ae65ac895 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Sun, 18 Dec 2011 14:57:54 +0100
Subject: [PATCH] log: never block on syslog in PID 1
Use a non-blocking syslog socket if logging from PID 1.
If sendmsg fails with EAGAIN, fall back to kmsg or console only for the
current message. Next message will try syslog again.
(cherry picked from commit 8f7f7a1bd3a26f501b2d6546cce1c669b59dcc87)
---
src/log.c | 23 ++++++++++++++++-------
1 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/src/log.c b/src/log.c
index 5c5b734..4f57821 100644
--- a/src/log.c
+++ b/src/log.c
@@ -118,6 +118,9 @@ static int create_log_socket(int type) {
struct timeval tv;
int fd;
+ if (getpid() == 1)
+ /* systemd should not block on syslog */
+ type |= SOCK_NONBLOCK;
if ((fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0)) < 0)
return -errno;
@@ -330,7 +333,8 @@ static int write_to_syslog(
for (;;) {
ssize_t n;
- if ((n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL)) < 0)
+ n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
+ if (n < 0)
return -errno;
if (!syslog_is_stream ||
@@ -407,8 +411,10 @@ static int log_dispatch(
log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
log_target == LOG_TARGET_SYSLOG) {
- if ((k = write_to_syslog(level, file, line, func, buffer)) < 0) {
- log_close_syslog();
+ k = write_to_syslog(level, file, line, func, buffer);
+ if (k < 0) {
+ if (k != -EAGAIN)
+ log_close_syslog();
log_open_kmsg();
} else if (k > 0)
r++;
@@ -419,16 +425,19 @@ static int log_dispatch(
log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
log_target == LOG_TARGET_KMSG)) {
- if ((k = write_to_kmsg(level, file, line, func, buffer)) < 0) {
+ k = write_to_kmsg(level, file, line, func, buffer);
+ if (k < 0) {
log_close_kmsg();
log_open_console();
} else if (k > 0)
r++;
}
- if (k <= 0 &&
- (k = write_to_console(level, file, line, func, buffer)) < 0)
- return k;
+ if (k <= 0) {
+ k = write_to_console(level, file, line, func, buffer);
+ if (k < 0)
+ return k;
+ }
buffer = e;
} while (buffer);

View File

@ -0,0 +1,23 @@
From 410c7e298a2937bd3c69e70b31d6ee0c4754c566 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 8 Nov 2011 18:18:48 +0100
Subject: [PATCH] macro: fix ALIGN_TO macro definition (cherry picked from
commit 9b3c575ed90bb1165a192dfae2fb2330baab583c)
---
src/macro.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/macro.h b/src/macro.h
index e7a4d2c..3f30aa7 100644
--- a/src/macro.h
+++ b/src/macro.h
@@ -149,7 +149,7 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
char *_s = (char *)(s); \
_i->iov_base = _s; \
_i->iov_len = strlen(_s); \
- } while(false);
+ } while(false)
static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
unsigned j;

View File

@ -0,0 +1,956 @@
From caaed693b9e8b16102c794fa52850bbcb7cc6fd9 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2011 03:02:17 +0100
Subject: [PATCH] man: document the sd-login interfaces (cherry picked from
commit 0b3b020a178cf3b957fed627de13c895773995ec)
---
man/sd_get_seats.xml | 125 +++++++++++++++++++++++++++++
man/sd_login_monitor_new.xml | 172 +++++++++++++++++++++++++++++++++++++++
man/sd_pid_get_session.xml | 136 +++++++++++++++++++++++++++++++
man/sd_seat_get_active.xml | 150 ++++++++++++++++++++++++++++++++++
man/sd_session_is_active.xml | 134 +++++++++++++++++++++++++++++++
man/sd_uid_get_state.xml | 182 ++++++++++++++++++++++++++++++++++++++++++
6 files changed, 899 insertions(+), 0 deletions(-)
create mode 100644 man/sd_get_seats.xml
create mode 100644 man/sd_login_monitor_new.xml
create mode 100644 man/sd_pid_get_session.xml
create mode 100644 man/sd_seat_get_active.xml
create mode 100644 man/sd_session_is_active.xml
create mode 100644 man/sd_uid_get_state.xml
diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml
new file mode 100644
index 0000000..bbc396a
--- /dev/null
+++ b/man/sd_get_seats.xml
@@ -0,0 +1,125 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_get_seats">
+
+ <refentryinfo>
+ <title>sd_get_seats</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_get_seats</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_get_seats</refname>
+ <refname>sd_get_sessions</refname>
+ <refname>sd_get_uids</refname>
+ <refpurpose>Determine available seats, sessions and logged in users</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>sd_get_seats</function></funcdef>
+ <paramdef>char*** <parameter>seats</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_get_sessions</function></funcdef>
+ <paramdef>char*** <parameter>sessions</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_get_uids</function></funcdef>
+ <paramdef>char*** <parameter>sessions</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>sd_get_seats()</function> may be used
+ to determine all currently available local
+ seats. Returns an array of seat identifiers. The
+ returned array and all strings it references need to
+ be freed with the libc
+ <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call after use.</para>
+
+ <para>Similar, <function>sd_get_sessions()</function> may
+ be used to determine all current login sessions.</para>
+
+ <para>Similar, <function>sd_get_uids()</function> may
+ be used to determine all Unix users who currently have login sessions.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success <function>sd_get_seats()</function>,
+ <function>sd_get_sessions()</function> and
+ <function>sd_get_uids()</function> return the number
+ of entries in the arrays. On failure, these calls
+ return a negative errno-style error code.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>The <function>sd_get_seats()</function>,
+ <function>sd_get_sessions()</function> and
+ <function>sd_get_uids()</function> interfaces
+ are available as shared library, which can be compiled
+ and linked to with the
+ <literal>libsystemd-login</literal>
+ <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ file.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml
new file mode 100644
index 0000000..2b37f00
--- /dev/null
+++ b/man/sd_login_monitor_new.xml
@@ -0,0 +1,172 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_login_monitor_new">
+
+ <refentryinfo>
+ <title>sd_login_monitor_new</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_login_monitor_new</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_login_monitor_new</refname>
+ <refname>sd_login_monitor_unref</refname>
+ <refname>sd_login_monitor_flush</refname>
+ <refname>sd_login_monitor_get_fd</refname>
+ <refpurpose>Monitor login sessions, seats and users</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>sd_login_monitor_new</function></funcdef>
+ <paramdef>const char* <parameter>category</parameter></paramdef>
+ <paramdef>sd_login_monitor** <parameter>ret</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>sd_login_monitor* <function>sd_login_monitor_unref</function></funcdef>
+ <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_login_monitor_flush</function></funcdef>
+ <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_login_monitor_get_fd</function></funcdef>
+ <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>sd_login_monitor_new()</function> may
+ be used to monitor login session, users and seats. Via
+ a monitor object a file descriptor can be integrated
+ into an application defined event loop which is woken
+ up each time a user logs in, logs out or a seat is
+ added or removed, or a session, user, or seat changes
+ state otherwise. The first parameter takes a string
+ which can be either <literal>seat</literal> (to get
+ only notifications about seats being added, removed or
+ changed), <literal>session</literal> (to get only
+ notifications about sessions being created or removed
+ or changed) or <literal>uid</literal> (to get only
+ notifications when a user changes state in respect to
+ logins). If notifications shall be generated in all
+ these conditions, NULL may be passed. Note that in
+ future additional categories may be defined. The
+ second parameter returns a monitor object and needs to
+ be freed with the
+ <function>sd_login_monitor_unref()</function> call
+ after use.</para>
+
+ <para><function>sd_login_monitor_unref()</function>
+ may be used to destroy a monitor object. Note that
+ this will invalidate any file descriptor returned by
+ <function>sd_login_monitor_get_fd()</function>.</para>
+
+ <para><function>sd_login_monitor_flush()</function>
+ may be used to reset the wakeup state of the monitor
+ object. Whenever an event causes the monitor to wake
+ up the event loop via the file descriptor this
+ function needs to be called to reset the wake-up
+ state. If this call is not invoked the file descriptor
+ will immediately wake up the event loop again.</para>
+
+ <para><function>sd_login_monitor_get_fd()</function>
+ may be used to retrieve the file descriptor of the
+ monitor object that may be integrated in an
+ application defined event loop, based around
+ <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ or a similar interface. The application should include
+ the returned file descriptor as wake up source for
+ POLLIN events. Whenever a wake-up is triggered the
+ file descriptor needs to be reset via
+ <function>sd_login_monitor_flush()</function>. An
+ application needs to reread the login state with a
+ function like
+ <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ or similar to determine what changed.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success
+ <function>sd_login_monitor_new()</function> and
+ <function>sd_login_monitor_flush()</function> return 0
+ or a positive integer. On success
+ <function>sd_login_monitor_get_fd()</function> returns
+ a Unix file descriptor. On failure, these calls return
+ a negative errno-style error code.</para>
+
+ <para><function>sd_login_monitor_unref()</function>
+ always returns NULL.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>The <function>sd_login_monitor_new()</function>,
+ <function>sd_login_monitor_unref()</function>, <function>sd_login_monitor_flush()</function> and
+ <function>sd_login_monitor_get_fd()</function> interfaces
+ are available as shared library, which can be compiled
+ and linked to with the
+ <literal>libsystemd-login</literal>
+ <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ file.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml
new file mode 100644
index 0000000..9176433
--- /dev/null
+++ b/man/sd_pid_get_session.xml
@@ -0,0 +1,136 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_pid_get_session">
+
+ <refentryinfo>
+ <title>sd_pid_get_session</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_pid_get_session</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_pid_get_session</refname>
+ <refname>sd_pid_get_owner_uid</refname>
+ <refpurpose>Determine session or owner of a session of a specific PID</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>sd_pid_get_session</function></funcdef>
+ <paramdef>pid_t <parameter>pid</parameter></paramdef>
+ <paramdef>char** <parameter>session</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
+ <paramdef>pid_t <parameter>pid</parameter></paramdef>
+ <paramdef>uid_t* <parameter>uid</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>sd_pid_get_session()</function> may be
+ used to determine the login session identifier of a
+ process identified by the specified process identifier. The session
+ identifier is a short string (up to 64 characters),
+ consisting only of the characters a-zA-Z0-9 as well as
+ '-' and '_'. It is suitable for usage in file system
+ paths. Note that not all processes are part of a login
+ session (e.g. system service processes and user
+ processes that are shared between multiple sessions of
+ the same user). For processes not being part of a
+ login session this function will fail. The returned
+ string needs to be freed with the libc
+ <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call after use.</para>
+
+ <para><function>sd_pid_get_owner_uid()</function> may
+ be used to determine the Unix user identifier of the
+ owner of the session of a process identified the
+ specified PID. Note that this function will succeed
+ for user processes which are shared between multiple
+ login sessions of the same user, where
+ <function>sd_pid_get_session()</function> will
+ fail. For processes not being part of a login session
+ and not being a shared process of a user this function
+ will fail.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success these calls return 0 or a positive
+ integer. On failure, these calls return a negative
+ errno-style error code.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>The <function>sd_pid_get_session()</function>
+ and <function>sd_pid_get_owner_uid()</function>
+ interfaces are available as shared library, which can
+ be compiled and linked to with the
+ <literal>libsystemd-login</literal>
+ <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ file.</para>
+
+ <para>Note that the login session identifier as
+ returned by <function>sd_pid_get_session()</function>
+ is completely unrelated to the process session
+ identifier as returned by
+ <citerefentry><refentrytitle>getsid</refentrytitle><manvolnum>2</manvolnum></citerefentry>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>getsid</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml
new file mode 100644
index 0000000..e729a65
--- /dev/null
+++ b/man/sd_seat_get_active.xml
@@ -0,0 +1,150 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_seat_get_active">
+
+ <refentryinfo>
+ <title>sd_seat_get_active</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_seat_get_active</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_seat_get_active</refname>
+ <refname>sd_seat_get_sessions</refname>
+ <refname>sd_seat_can_multi_session</refname>
+ <refpurpose>Determine state of a specific seat</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>sd_seat_get_active</function></funcdef>
+ <paramdef>const char* <parameter>seat</parameter></paramdef>
+ <paramdef>char** <parameter>session</parameter></paramdef>
+ <paramdef>uid_t* <parameter>uid</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_seat_get_sessions</function></funcdef>
+ <paramdef>const char* <parameter>seat</parameter></paramdef>
+ <paramdef>char*** <parameter>sessions</parameter></paramdef>
+ <paramdef>uid_t** <parameter>uid</parameter></paramdef>
+ <paramdef>unsigned* <parameter>n_uids</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_seat_can_multi_session</function></funcdef>
+ <paramdef>const char* <parameter>session</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>sd_seat_get_active()</function> may be
+ used to determine which session is currently active on
+ a seat, if there is any. Returns the session
+ identifier and the user identifier of the Unix user
+ the session is belonging to. Either the session or the
+ user identifier parameter can be be passed NULL, in
+ case only one of the parameters shall be queried. The
+ returned string needs to be freed with the libc
+ <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call after use.</para>
+
+ <para><function>sd_seat_get_sessions()</function> may
+ be used to determine all sessions on the specified
+ seat. Returns two arrays, one (NULL terminated) with
+ the session identifiers of the sessions and one with
+ the user identifiers of the Unix users the sessions
+ belong to. An additional parameter may be used to
+ return the number of entries in the latter array. The
+ two arrays and the latter parameter may be passed as
+ NULL in case these values need not to be
+ determined. The arrays and the strings referenced by
+ them need to be freed with the libc
+ <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call after use.</para>
+
+ <para><function>sd_seat_can_multi_session()</function>
+ may be used to determine whether a specific seat is
+ capable of multi-session, i.e. allows multiple login
+ sessions in parallel (whith only one being active at a
+ time).</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para> On success
+ <function>sd_seat_get_active()</function> return
+ return 0 or a positive integer. On success
+ <function>sd_seat_get_sessions()</function> returns
+ the number of entries in the session identifier
+ array. If the test succeeds
+ <function>sd_seat_can_multi_session</function> returns
+ a positive integer, if it fails 0. On failure, these
+ calls return a negative errno-style error code.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>The <function>sd_seat_get_active()</function>,
+ <function>sd_seat_get_sessions()</function>, and
+ <function>sd_seat_can_multi_session()</function> interfaces
+ are available as shared library, which can be compiled
+ and linked to with the
+ <literal>libsystemd-login</literal>
+ <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ file.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
new file mode 100644
index 0000000..82919f8
--- /dev/null
+++ b/man/sd_session_is_active.xml
@@ -0,0 +1,134 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_session_is_active">
+
+ <refentryinfo>
+ <title>sd_session_is_active</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_session_is_active</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_session_is_active</refname>
+ <refname>sd_session_get_uid</refname>
+ <refname>sd_session_get_seat</refname>
+ <refpurpose>Determine state of a specific session</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>sd_session_is_active</function></funcdef>
+ <paramdef>const char* <parameter>session</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_session_get_uid</function></funcdef>
+ <paramdef>const char* <parameter>session</parameter></paramdef>
+ <paramdef>uid_t* <parameter>uid</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_session_get_seat</function></funcdef>
+ <paramdef>const char* <parameter>session</parameter></paramdef>
+ <paramdef>char** <parameter>seat</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>sd_session_is_active()</function> may
+ be used to determine whether the session identified by
+ the specified session identifier is currently active
+ (i.e. currently in the foreground and available for
+ user input) or not.</para>
+
+ <para><function>sd_session_get_uid()</function> may be
+ used to determine the user identifier of the Unix user the session
+ identified by the specified session identifier belongs
+ to.</para>
+
+ <para><function>sd_session_get_seat()</function> may
+ be used to determine the seat identifier of the seat
+ the session identified by the specified session
+ identifier belongs to. Note that not all sessions are
+ attached to a seat, this call will fail for them. The
+ returned string needs to be freed with the libc
+ <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call after use.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>If the test succeeds
+ <function>sd_session_is_active()</function> returns a
+ positive integer, if it fails 0. On success
+ <function>sd_session_get_uid()</function> and
+ <function>sd_session_get_seat()</function> return 0 or
+ a positive integer. On failure, these calls return a
+ negative errno-style error code.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>The <function>sd_session_is_active()</function>,
+ <function>sd_session_get_uid()</function>, and
+ <function>sd_session_get_seat()</function> interfaces
+ are available as shared library, which can be compiled
+ and linked to with the
+ <literal>libsystemd-login</literal>
+ <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ file.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml
new file mode 100644
index 0000000..a4e9e73
--- /dev/null
+++ b/man/sd_uid_get_state.xml
@@ -0,0 +1,182 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_uid_get_state">
+
+ <refentryinfo>
+ <title>sd_uid_get_state</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_uid_get_state</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_uid_get_state</refname>
+ <refname>sd_uid_is_on_seat</refname>
+ <refname>sd_uid_get_sessions</refname>
+ <refname>sd_uid_get_seats</refname>
+ <refpurpose>Determine login state of a specific Unix user ID</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>sd_uid_get_state</function></funcdef>
+ <paramdef>uid_t <parameter>pid</parameter></paramdef>
+ <paramdef>char** <parameter>state</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_uid_is_on_seat</function></funcdef>
+ <paramdef>uid_t <parameter>pid</parameter></paramdef>
+ <paramdef>int <parameter>require_active</parameter></paramdef>
+ <paramdef>const char* <parameter>seat</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_uid_get_sessions</function></funcdef>
+ <paramdef>uid_t <parameter>pid</parameter></paramdef>
+ <paramdef>int <parameter>require_active</parameter></paramdef>
+ <paramdef>char*** <parameter>sessions</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_uid_get_seats</function></funcdef>
+ <paramdef>uid_t <parameter>pid</parameter></paramdef>
+ <paramdef>int <parameter>require_active</parameter></paramdef>
+ <paramdef>char*** <parameter>seats</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>sd_uid_get_state()</function> may be
+ used to determine the login state of a specific Unix
+ user identifier. The following states are currently
+ known: <literal>offline</literal> (user not logged in
+ at all), <literal>lingering</literal> (user not logged
+ in, but some user services running),
+ <literal>online</literal> (user logged in, but not
+ active), <literal>active</literal> (user logged in on
+ an active seat). In the future additional states might
+ be defined, client code should be written to be robust
+ in regards to additional state strings being
+ returned. The returned string needs to be freed with
+ the libc
+ <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call after use.</para>
+
+ <para><function>sd_uid_is_on_seat()</function> may be
+ used to determine whether a specific user is logged in
+ or active on a specific seat. Accepts a Unix user
+ identifier and a seat identifier string as
+ parameters. The <parameter>require_active</parameter>
+ parameter is a boolean. If non-zero (true) this
+ function will test if the user is active (i.e. has a
+ session that is in the foreground and accepting user
+ input) on the specified seat, otherwise (false) only
+ if the user is logged in (and possibly inactive) on
+ the specified seat.</para>
+
+ <para><function>sd_uid_get_sessions()</function> may
+ be used to determine the current sessions of the
+ specified user. Acceptes a Unix user identifier as
+ parameter. The <parameter>require_active</parameter>
+ boolean parameter controls whether the returned list
+ shall consist of only those sessions where the user is
+ currently active (true) or where the user is currently
+ logged in at all, possibly inactive (false). The call
+ returns a NULL terminated string array of session
+ identifiers in <parameter>sessions</parameter> which
+ needs to be freed by the caller with the libc
+ <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call after use, including all the strings referenced. If
+ the string array parameter is passed as NULL the array
+ will not be filled in, but the return code still
+ indicates the number of current sessions.</para>
+
+ <para>Similar, <function>sd_uid_get_seats()</function>
+ may be used to determine the list of seats on which
+ the user currently has sessions. Similar semantics
+ apply, however note that the user may have
+ multiple sessions on the same seat as well as sessions
+ with no attached seat and hence the number of entries
+ in the returned array may differ from the one returned
+ by <function>sd_uid_get_sessions()</function>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success
+ <function>sd_uid_get_state()</function> returns 0 or a
+ positive integer. If the test succeeds
+ <function>sd_uid_is_on_seat()</function> returns a
+ positive integer, if it fails
+ 0. <function>sd_uid_get_sessions()</function> and
+ <function>sd_uid_get_seats()</function> return the
+ number of entries in the returned arrays. On failure,
+ these calls return a negative errno-style error
+ code.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>The <function>sd_uid_get_state()</function>,
+ <function>sd_uid_is_on_seat()</function>,
+ <function>sd_uid_get_sessions()</function>, and
+ <function>sd_uid_get_seats()</function> interfaces are
+ available as shared library, which can be compiled and
+ linked to with the <literal>libsystemd-login</literal>
+ <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ file.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ </para>
+ </refsect1>
+
+</refentry>

View File

@ -0,0 +1,80 @@
From 76c801950d0f596ba7804088a838ecc8d8dc9d5e Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2011 13:11:42 +0100
Subject: [PATCH] sd-daemon: fix #include lines since we now ship a shared
library (cherry picked from commit
a822cbfa2e42d60c3cafe724a8571329ab6c632e)
---
man/sd-daemon.xml | 2 +-
man/sd_booted.xml | 2 +-
man/sd_is_fifo.xml | 2 +-
man/sd_listen_fds.xml | 2 +-
man/sd_notify.xml | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml
index cd67d99..383d77f 100644
--- a/man/sd-daemon.xml
+++ b/man/sd-daemon.xml
@@ -50,7 +50,7 @@
<refsynopsisdiv>
<funcsynopsis>
- <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
+ <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
</funcsynopsis>
<cmdsynopsis>
diff --git a/man/sd_booted.xml b/man/sd_booted.xml
index ebcde36..c9f538a 100644
--- a/man/sd_booted.xml
+++ b/man/sd_booted.xml
@@ -49,7 +49,7 @@
<refsynopsisdiv>
<funcsynopsis>
- <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
+ <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>sd_booted</function></funcdef>
diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml
index f6fafab..82b89bb 100644
--- a/man/sd_is_fifo.xml
+++ b/man/sd_is_fifo.xml
@@ -53,7 +53,7 @@
<refsynopsisdiv>
<funcsynopsis>
- <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
+ <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>sd_is_fifo</function></funcdef>
diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml
index 3276aff..68a45cd 100644
--- a/man/sd_listen_fds.xml
+++ b/man/sd_listen_fds.xml
@@ -49,7 +49,7 @@
<refsynopsisdiv>
<funcsynopsis>
- <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
+ <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
<funcsynopsisinfo>#define SD_LISTEN_FDS_START 3</funcsynopsisinfo>
diff --git a/man/sd_notify.xml b/man/sd_notify.xml
index 62347f8..c3791ce 100644
--- a/man/sd_notify.xml
+++ b/man/sd_notify.xml
@@ -50,7 +50,7 @@
<refsynopsisdiv>
<funcsynopsis>
- <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
+ <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>sd_notify</function></funcdef>

View File

@ -0,0 +1,27 @@
From 271f93368eee2784ad360fe6cfed0b684f4a1032 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2011 13:12:36 +0100
Subject: [PATCH] man: build new man pages (cherry picked from commit
f0d2e205a28e37528ef791cc2913e6664d0dde7f)
---
Makefile.am | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 4d04db3..3b2cbc2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -818,6 +818,12 @@ MANPAGES_ALIAS = \
man/sd_is_socket_unix.3 \
man/sd_is_socket_inet.3 \
man/sd_notifyf.3 \
+ man/sd_pid_get_session.3 \
+ man/sd_uid_get_state.3 \
+ man/sd_session_is_active.3 \
+ man/sd_seat_get_active.3 \
+ man/sd_get_seats.3 \
+ man/sd_login_monitor_new.3 \
man/init.1
man/reboot.8: man/halt.8

View File

@ -0,0 +1,58 @@
From d5956203ad4ed4f8183685c65cc323ae8f927820 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2011 13:19:01 +0100
Subject: [PATCH] man: sd_readahead is not actually available in
libsystemd-daemon (cherry picked from commit
559de1289000f874e23ad01edfa1b37c102a793a)
---
man/sd_readahead.xml | 28 +++++++++++-----------------
1 files changed, 11 insertions(+), 17 deletions(-)
diff --git a/man/sd_readahead.xml b/man/sd_readahead.xml
index 88b135b..25fe5b2 100644
--- a/man/sd_readahead.xml
+++ b/man/sd_readahead.xml
@@ -49,7 +49,7 @@
<refsynopsisdiv>
<funcsynopsis>
- <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
+ <funcsynopsisinfo>#include "sd-readahead.h"</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>sd_readahead</function></funcdef>
@@ -134,23 +134,17 @@
url="http://cgit.freedesktop.org/systemd/tree/src/sd-readahead.h"/></para>
<para><function>sd_readahead()</function> is
- implemented in the reference implementation's
+ implemented in the reference implementation's drop-in
<filename>sd-readahead.c</filename> and
- <filename>sd-readahead.h</filename> files. These
- interfaces are available as shared library, which can
- be compiled and linked to with the
- <literal>libsystemd-daemon</literal>
- <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- file. Alternatively, applications consuming this API
- may copy the implementation into their source
- tree. For more details about the reference
- implementation see
- <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
-
- <para>If the reference implementation is used as
- drop-in files and -DDISABLE_SYSTEMD is set during
- compilation this function will always return 0 and
- otherwise become a NOP.</para>
+ <filename>sd-readahead.h</filename> files. It is
+ recommended that applications consuming this API copy
+ the implementation into their source tree. For more
+ details about the reference implementation see
+ <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>7</manvolnum></citerefentry></para>
+
+ <para>If -DDISABLE_SYSTEMD is set during compilation
+ this function will always return 0 and otherwise
+ become a NOP.</para>
</refsect1>
<refsect1>

View File

@ -0,0 +1,37 @@
From 741e7c477da184725f18f928fed7174d97732419 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2011 13:25:00 +0100
Subject: [PATCH] build-sys: add rules for man page aliases (cherry picked
from commit c10eb7b02eb048eb23f0c9f239bfe1f9e7bc8e4a)
---
Makefile.am | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 3b2cbc2..c04125e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -831,8 +831,22 @@ man/poweroff.8: man/halt.8
man/sd_is_socket.3: man/sd_is_fifo.3
man/sd_is_socket_unix.3: man/sd_is_fifo.3
man/sd_is_socket_inet.3: man/sd_is_fifo.3
+man/sd_is_mq.3: man/sd_is_fifo.3
man/sd_notifyf.3: man/sd_notify.3
man/init.1: man/systemd.1
+man/sd_session_get_uid.3: man/sd_session_is_active.3
+man/sd_session_get_seat.3: man/sd_session_is_active.3
+man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3
+man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3
+man/sd_uid_get_sessions.3: man/sd_uid_get_state.3
+man/sd_uid_get_seats.3: man/sd_uid_get_state.3
+man/sd_seat_get_sessions.3: man/sd_seat_get_active.3
+man/sd_seat_can_multi_session.3: man/sd_seat_get_active.3
+man/sd_get_sessions.3: man/sd_get_seats.3
+man/sd_get_uids.3: man/sd_get_seats.3
+man/sd_login_monitor_unref.3: man/sd_login_monitor_new.3
+man/sd_login_monitor_flush.3: man/sd_login_monitor_new.3
+man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3
dist_man_MANS = \
$(MANPAGES) \

View File

@ -0,0 +1,223 @@
From 362fa48aecfac175e3601d4075bbc1eb18684625 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2011 13:57:07 +0100
Subject: [PATCH] man: add sd-login(7) page (cherry picked from commit
01448ff92d9549785242ffab453bf5bcde348c61)
---
Makefile.am | 31 +++++++++---
man/sd-login.xml | 117 ++++++++++++++++++++++++++++++++++++++++++++
man/sd_pid_get_session.xml | 19 +++----
3 files changed, 149 insertions(+), 18 deletions(-)
create mode 100644 man/sd-login.xml
diff --git a/Makefile.am b/Makefile.am
index c04125e..a5d9c77 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -786,6 +786,7 @@ MANPAGES = \
man/daemon.7 \
man/sd-daemon.7 \
man/sd-readahead.7 \
+ man/sd-login.7 \
man/runlevel.8 \
man/telinit.8 \
man/halt.8 \
@@ -804,7 +805,13 @@ MANPAGES = \
man/modules-load.d.5 \
man/sysctl.d.5 \
man/systemd-ask-password.1 \
- man/systemd-loginctl.1
+ man/systemd-loginctl.1 \
+ man/sd_pid_get_session.3 \
+ man/sd_uid_get_state.3 \
+ man/sd_session_is_active.3 \
+ man/sd_seat_get_active.3 \
+ man/sd_get_seats.3 \
+ man/sd_login_monitor_new.3
if ENABLE_BINFMT
MANPAGES += \
@@ -817,14 +824,22 @@ MANPAGES_ALIAS = \
man/sd_is_socket.3 \
man/sd_is_socket_unix.3 \
man/sd_is_socket_inet.3 \
+ man/sd_is_mq.3 \
man/sd_notifyf.3 \
- man/sd_pid_get_session.3 \
- man/sd_uid_get_state.3 \
- man/sd_session_is_active.3 \
- man/sd_seat_get_active.3 \
- man/sd_get_seats.3 \
- man/sd_login_monitor_new.3 \
- man/init.1
+ man/init.1 \
+ man/sd_session_get_uid.3 \
+ man/sd_session_get_seat.3 \
+ man/sd_pid_get_owner_uid.3 \
+ man/sd_uid_is_on_seat.3 \
+ man/sd_uid_get_sessions.3 \
+ man/sd_uid_get_seats.3 \
+ man/sd_seat_get_sessions.3 \
+ man/sd_seat_can_multi_session.3 \
+ man/sd_get_sessions.3 \
+ man/sd_get_uids.3 \
+ man/sd_login_monitor_unref.3 \
+ man/sd_login_monitor_flush.3 \
+ man/sd_login_monitor_get_fd.3
man/reboot.8: man/halt.8
man/poweroff.8: man/halt.8
diff --git a/man/sd-login.xml b/man/sd-login.xml
new file mode 100644
index 0000000..62ec6ff
--- /dev/null
+++ b/man/sd-login.xml
@@ -0,0 +1,117 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd-login">
+
+ <refentryinfo>
+ <title>sd-login</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd-login</refentrytitle>
+ <manvolnum>7</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd-login</refname>
+ <refpurpose>APIs for
+ tracking logins</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
+ </funcsynopsis>
+
+ <cmdsynopsis>
+ <command>pkg-config --cflags --libs libsystemd-login</command>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><filename>sd-login.h</filename> provides APIs to
+ introspect and monitor seat, login session and user
+ status information on the local system. </para>
+
+ <para>See <ulink
+ url="http://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
+ on Linux</ulink> for an introduction into multi-seat
+ support on Linux, the background for this set of APIs.</para>
+
+ <para>Note that these APIs only allow purely passive access
+ and monitoring of seats, sessions and users. To
+ actively make changes to the seat configuration,
+ terminate login sessions, or switch session on a seat
+ you need to utilize the D-Bus API of
+ systemd-logind.</para>
+
+ <para>See
+ <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_uid_get_state</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_seat_get_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_login_monitor_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ for more information about the functions
+ implemented.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>These APIs are implemented as shared library,
+ which can be compiled and linked to with the
+ <literal>libsystemd-login</literal>
+ <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ file.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_uid_get_state</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_seat_get_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_login_monitor_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml
index 9176433..24e4680 100644
--- a/man/sd_pid_get_session.xml
+++ b/man/sd_pid_get_session.xml
@@ -71,16 +71,15 @@
<para><function>sd_pid_get_session()</function> may be
used to determine the login session identifier of a
- process identified by the specified process identifier. The session
- identifier is a short string (up to 64 characters),
- consisting only of the characters a-zA-Z0-9 as well as
- '-' and '_'. It is suitable for usage in file system
- paths. Note that not all processes are part of a login
- session (e.g. system service processes and user
- processes that are shared between multiple sessions of
- the same user). For processes not being part of a
- login session this function will fail. The returned
- string needs to be freed with the libc
+ process identified by the specified process
+ identifier. The session identifier is a short string,
+ suitable for usage in file system paths. Note that not
+ all processes are part of a login session (e.g. system
+ service processes and user processes that are shared
+ between multiple sessions of the same user). For
+ processes not being part of a login session this
+ function will fail. The returned string needs to be
+ freed with the libc
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
call after use.</para>

View File

@ -0,0 +1,159 @@
From 550fab31953acced44a6e7b2acc050b8270dd558 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2011 14:42:59 +0100
Subject: [PATCH] man: various updates (cherry picked from commit
595aae376fae21f885ec9af2cac1aaf3ff3e9bee)
---
man/sd-login.xml | 21 ++++++++++++++++++++-
man/sd_get_seats.xml | 12 +++++++-----
man/sd_login_monitor_new.xml | 2 +-
man/sd_seat_get_active.xml | 6 ++++--
man/sd_session_is_active.xml | 2 +-
man/sd_uid_get_state.xml | 13 ++++++++-----
6 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/man/sd-login.xml b/man/sd-login.xml
index 62ec6ff..9926d2b 100644
--- a/man/sd-login.xml
+++ b/man/sd-login.xml
@@ -75,7 +75,26 @@
actively make changes to the seat configuration,
terminate login sessions, or switch session on a seat
you need to utilize the D-Bus API of
- systemd-logind.</para>
+ systemd-logind, instead.</para>
+
+ <para>These functions access data in
+ <filename>/proc</filename>,
+ <filename>/sys/fs/cgroup</filename> and
+ <filename>/run</filename>. All of these are virtual
+ file systems, hence the runtime cost of the accesses
+ is relatively cheap.</para>
+
+ <para>If the functions return string arrays, these are
+ generally NULL terminated and need to be freed by the
+ caller with the libc
+ <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call after use, including the strings referenced
+ therein. Similar, individual strings returned need to
+ be freed, as well.</para>
+
+ <para>As a special exception, instead of an empty
+ string array NULL may be returned, which should be
+ treated equivalent to an empty string array.</para>
<para>See
<citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml
index bbc396a..2ac7650 100644
--- a/man/sd_get_seats.xml
+++ b/man/sd_get_seats.xml
@@ -76,11 +76,13 @@
<para><function>sd_get_seats()</function> may be used
to determine all currently available local
- seats. Returns an array of seat identifiers. The
- returned array and all strings it references need to
- be freed with the libc
+ seats. Returns a NULL terminated array of seat
+ identifiers. The returned array and all strings it
+ references need to be freed with the libc
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- call after use.</para>
+ call after use. Note that instead of an empty array
+ NULL may be returned and should be considered
+ equivalent to an empty array.</para>
<para>Similar, <function>sd_get_sessions()</function> may
be used to determine all current login sessions.</para>
@@ -118,7 +120,7 @@
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml
index 2b37f00..de48432 100644
--- a/man/sd_login_monitor_new.xml
+++ b/man/sd_login_monitor_new.xml
@@ -165,7 +165,7 @@
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml
index e729a65..14cda60 100644
--- a/man/sd_seat_get_active.xml
+++ b/man/sd_seat_get_active.xml
@@ -101,7 +101,9 @@
determined. The arrays and the strings referenced by
them need to be freed with the libc
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- call after use.</para>
+ call after use. Note that instead of an empty array
+ NULL may be returned and should be considered
+ equivalent to an empty array.</para>
<para><function>sd_seat_can_multi_session()</function>
may be used to determine whether a specific seat is
@@ -143,7 +145,7 @@
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
index 82919f8..88b22fd 100644
--- a/man/sd_session_is_active.xml
+++ b/man/sd_session_is_active.xml
@@ -127,7 +127,7 @@
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml
index a4e9e73..6777625 100644
--- a/man/sd_uid_get_state.xml
+++ b/man/sd_uid_get_state.xml
@@ -126,10 +126,13 @@
identifiers in <parameter>sessions</parameter> which
needs to be freed by the caller with the libc
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- call after use, including all the strings referenced. If
- the string array parameter is passed as NULL the array
- will not be filled in, but the return code still
- indicates the number of current sessions.</para>
+ call after use, including all the strings
+ referenced. If the string array parameter is passed as
+ NULL the array will not be filled in, but the return
+ code still indicates the number of current
+ sessions. Note that instead of an empty array NULL may
+ be returned and should be considered equivalent to an
+ empty array.</para>
<para>Similar, <function>sd_uid_get_seats()</function>
may be used to determine the list of seats on which
@@ -175,7 +178,7 @@
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>

View File

@ -0,0 +1,40 @@
From d54ac9394336db0564b3bca712d43042486dacc1 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2011 17:40:31 +0100
Subject: [PATCH] man: extend sd-login(7) in regards to mixing D-Bus and
synchronous library calls a bit (cherry picked from commit
5079a105e701f17439635e76d8cb3052badbb34c)
---
man/sd-login.xml | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/man/sd-login.xml b/man/sd-login.xml
index 9926d2b..3fc0e16 100644
--- a/man/sd-login.xml
+++ b/man/sd-login.xml
@@ -77,13 +77,23 @@
you need to utilize the D-Bus API of
systemd-logind, instead.</para>
- <para>These functions access data in
+ <para>These functions synchronously access data in
<filename>/proc</filename>,
<filename>/sys/fs/cgroup</filename> and
<filename>/run</filename>. All of these are virtual
file systems, hence the runtime cost of the accesses
is relatively cheap.</para>
+ <para>It is possible (and often a very good choice) to
+ mix calls to the synchronous interface of
+ <filename>sd-login.h</filename> with the asynchronous
+ D-Bus interface of systemd-logind. However, if this is
+ done you need to think a bit about possible races
+ since the stream of events from D-Bus and from
+ <filename>sd-login.h</filename> interfaces such as the
+ login monitor are asynchronous and not ordered against
+ each other.</para>
+
<para>If the functions return string arrays, these are
generally NULL terminated and need to be freed by the
caller with the libc

View File

@ -0,0 +1,29 @@
From d522760b761ddb9e92eb068c656c68ed60bdb50e Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2011 19:55:54 +0100
Subject: [PATCH] man: generate HTML instead of XHTML with XSL docbook to work
around 'fsfunc' noise (cherry picked from commit
38c67e2a442d875c1de6f5aae46647a195230b05)
---
Makefile.am | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index a5d9c77..9ee2c7f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1709,11 +1709,11 @@ XSLTPROC_PROCESS_MAN_IN = \
XSLTPROC_PROCESS_HTML = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
- $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/xhtml-1_1/docbook.xsl $<
+ $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $<
XSLTPROC_PROCESS_HTML_IN = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
- $(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/xhtml-1_1/docbook.xsl $< && \
+ $(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< && \
mv ${@:.in=} $@
man/%.1: man/%.xml

View File

@ -0,0 +1,85 @@
From 1b6836c15717a62ef81cef8e9617fc7df6c7e605 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2011 20:25:52 +0100
Subject: [PATCH] man: switch to UTF-8 output, to work around charset issues
(cherry picked from commit
76318284fc970b30e9dc4c079960807345331dad)
---
Makefile.am | 9 +++++----
man/custom-html.xsl | 29 +++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 4 deletions(-)
create mode 100644 man/custom-html.xsl
diff --git a/Makefile.am b/Makefile.am
index 9ee2c7f..295944d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -495,7 +495,8 @@ EXTRA_DIST = \
src/libsystemd-login.sym \
introspect.awk \
src/73-seat-late.rules.in \
- src/99-systemd.rules.in
+ src/99-systemd.rules.in \
+ man/custom-html.xsl
if ENABLE_BINFMT
EXTRA_DIST += \
@@ -1696,7 +1697,7 @@ endif
if HAVE_XSLTPROC
XSLTPROC_FLAGS = \
--nonet \
- --param funcsynopsis.style "'ansi'"
+ --stringparam funcsynopsis.style ansi
XSLTPROC_PROCESS_MAN = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
@@ -1709,11 +1710,11 @@ XSLTPROC_PROCESS_MAN_IN = \
XSLTPROC_PROCESS_HTML = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
- $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $<
+ $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) man/custom-html.xsl $<
XSLTPROC_PROCESS_HTML_IN = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
- $(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< && \
+ $(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) man/custom-html.xsl $< && \
mv ${@:.in=} $@
man/%.1: man/%.xml
diff --git a/man/custom-html.xsl b/man/custom-html.xsl
new file mode 100644
index 0000000..2d2f458
--- /dev/null
+++ b/man/custom-html.xsl
@@ -0,0 +1,29 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2011 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
+
+<!-- Switch things to UTF-8, ISO-8859-1 is soo yesteryear -->
+<xsl:output method="html" encoding="UTF-8" indent="no"/>
+
+</xsl:stylesheet>

View File

@ -0,0 +1,25 @@
From 988a59b65bcf86ed1cdf9fefb5a2ac7c16536c1b Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 27 Dec 2011 22:52:15 +0100
Subject: [PATCH] udev: exclude loopback device from udev rule based sysctl
application, since we can just apply that directly at boot
(cherry picked from commit
330672957438243c8003d3a90f0e59dedbd845e9)
---
src/99-systemd.rules.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/99-systemd.rules.in b/src/99-systemd.rules.in
index b2481ae..d306f71 100644
--- a/src/99-systemd.rules.in
+++ b/src/99-systemd.rules.in
@@ -44,7 +44,7 @@ SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:
# Apply sysctl variables to network devices (and only to those) as they appear.
-SUBSYSTEM=="net", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name"
+SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name"
# Asynchronously mount file systems implemented by these modules as
# soon as they are loaded.

Some files were not shown because too many files have changed in this diff Show More