From e43452dfe678264ac81c087d2a8735c973f99686 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Jan 11 2012 11:22:35 +0000 Subject: Fixes and low-risk enhancements (no journald) from upstream v38. --- diff --git a/0001-mount-order-remote-mounts-after-both-network.target-.patch b/0001-mount-order-remote-mounts-after-both-network.target-.patch deleted file mode 100644 index c845c8d..0000000 --- a/0001-mount-order-remote-mounts-after-both-network.target-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 7fc2a89a7387db1e5daa4892393c9e9536920c25 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 1 Nov 2011 22:27:48 +0100 -Subject: [PATCH] mount: order remote mounts after both network.target and - remote-fs-pre.target - -Since remote-fs-pre.target is optional we cannot count on it to order -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 ---- - src/mount.c | 7 ++++++- - 1 files changed, 6 insertions(+), 1 deletions(-) - -diff --git a/src/mount.c b/src/mount.c -index ef953f0..f9cfe91 100644 ---- a/src/mount.c -+++ b/src/mount.c -@@ -327,7 +327,7 @@ static bool needs_quota(MountParameters *p) { - } - - static int mount_add_fstab_links(Mount *m) { -- const char *target, *after = NULL; -+ const char *target, *after = NULL, *after2 = NULL; - MountParameters *p; - Unit *tu; - int r; -@@ -358,6 +358,7 @@ static int mount_add_fstab_links(Mount *m) { - if (mount_is_network(p)) { - target = SPECIAL_REMOTE_FS_TARGET; - after = SPECIAL_REMOTE_FS_PRE_TARGET; -+ after2 = SPECIAL_NETWORK_TARGET; - } else { - target = SPECIAL_LOCAL_FS_TARGET; - after = SPECIAL_LOCAL_FS_PRE_TARGET; -@@ -374,6 +375,10 @@ static int mount_add_fstab_links(Mount *m) { - if ((r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true)) < 0) - return r; - -+ if (after2) -+ if ((r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true)) < 0) -+ return r; -+ - if (automount) { - Unit *am; - --- -1.7.7 - diff --git a/0001-unit-fix-complementing-of-requirement-deps-with-Afte.patch b/0001-unit-fix-complementing-of-requirement-deps-with-Afte.patch deleted file mode 100644 index 7e6b8c4..0000000 --- a/0001-unit-fix-complementing-of-requirement-deps-with-Afte.patch +++ /dev/null @@ -1,33 +0,0 @@ -From a65cb51f29ee177f6f800c87232b68475216a418 Mon Sep 17 00:00:00 2001 -From: Michal Schmidt -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 - diff --git a/0001-units-drop-Install-section-from-remote-fs-pre.target.patch b/0001-units-drop-Install-section-from-remote-fs-pre.target.patch deleted file mode 100644 index bbad2fd..0000000 --- a/0001-units-drop-Install-section-from-remote-fs-pre.target.patch +++ /dev/null @@ -1,26 +0,0 @@ -From fc8f0b5c9cb8277950a2fefdb7f754c47b172dfd Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 1 Nov 2011 22:29:48 +0100 -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. ---- - units/remote-fs-pre.target | 3 --- - 1 files changed, 0 insertions(+), 3 deletions(-) - -diff --git a/units/remote-fs-pre.target b/units/remote-fs-pre.target -index 5406aa2..8aceb08 100644 ---- a/units/remote-fs-pre.target -+++ b/units/remote-fs-pre.target -@@ -10,6 +10,3 @@ - [Unit] - Description=Remote File Systems (Pre) - After=network.target -- --[Install] --WantedBy=multi-user.target --- -1.7.7 - diff --git a/0001-util-properly-detect-what-the-last-capability-is.patch b/0001-util-properly-detect-what-the-last-capability-is.patch new file mode 100644 index 0000000..12108c1 --- /dev/null +++ b/0001-util-properly-detect-what-the-last-capability-is.patch @@ -0,0 +1,122 @@ +From 3ad4e947bb0312940d56059328dd518d01718f6f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 11 Oct 2011 22:30:31 +0200 +Subject: [PATCH 001/126] 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 +-- +1.7.7.5 + diff --git a/0002-manager-fix-a-crash-in-isolating.patch b/0002-manager-fix-a-crash-in-isolating.patch index b9697c7..eb76574 100644 --- a/0002-manager-fix-a-crash-in-isolating.patch +++ b/0002-manager-fix-a-crash-in-isolating.patch @@ -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 Date: Mon, 17 Oct 2011 11:12:12 +0200 -Subject: [PATCH 2/5] manager: fix a crash in isolating +Subject: [PATCH 002/126] 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 ++++++- @@ -113,5 +114,5 @@ index e626347..6d20258 100644 } -- -1.7.4.4 +1.7.7.5 diff --git a/0003-audit-do-not-complain-if-kernel-lacks-audit.patch b/0003-audit-do-not-complain-if-kernel-lacks-audit.patch new file mode 100644 index 0000000..74ae8c7 --- /dev/null +++ b/0003-audit-do-not-complain-if-kernel-lacks-audit.patch @@ -0,0 +1,56 @@ +From 1d0ba48a582be7b9a539cbb5cbf6bbdf5f7b08e1 Mon Sep 17 00:00:00 2001 +From: Jonathan Nieder +Date: Mon, 17 Oct 2011 21:01:40 +0200 +Subject: [PATCH 003/126] 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 + +-- +1.7.7.5 + diff --git a/0004-systemctl-completion-always-invoke-with-no-legend.patch b/0004-systemctl-completion-always-invoke-with-no-legend.patch new file mode 100644 index 0000000..7b82fe4 --- /dev/null +++ b/0004-systemctl-completion-always-invoke-with-no-legend.patch @@ -0,0 +1,77 @@ +From fb4f5f218e83eb1496f2fdfa67b27e458b2bd6a4 Mon Sep 17 00:00:00 2001 +From: Dave Reisner +Date: Tue, 11 Oct 2011 20:56:53 -0400 +Subject: [PATCH 004/126] 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 +entirely, with the error: + + Failed to issue method call: Unit name UNIT is not valid. + +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(-) + +diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh +index 6369a6c..6ebb792 100644 +--- a/src/systemctl-bash-completion.sh ++++ b/src/systemctl-bash-completion.sh +@@ -15,6 +15,10 @@ + # You should have received a copy of the GNU General Public License + # along with systemd; If not, see . + ++__systemctl() { ++ systemctl --no-legend "$@" ++} ++ + __contains_word () { + local word=$1; shift + for w in $*; do [[ $w = $word ]] && return 0; done +@@ -24,7 +28,7 @@ __contains_word () { + __filter_units_by_property () { + local property=$1 value=$2 ; shift ; shift + local -a units=( $* ) +- local -a props=( $(systemctl show --property "$property" -- ${units[*]} | grep -v ^$) ) ++ 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]}" +@@ -32,10 +36,10 @@ __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 --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}' ; } + + _systemctl () { + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} +@@ -134,13 +138,13 @@ _systemctl () { + comps='' + + elif __contains_word "$verb" ${VERBS[JOBS]}; then +- comps=$( systemctl list-jobs | awk '{print $1}' ) ++ 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}' ) ++ 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_' ) ++ comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' ) + compopt -o nospace + fi + +-- +1.7.7.5 + diff --git a/0005-systemctl-completion-always-invoke-with-no-legend.patch b/0005-systemctl-completion-always-invoke-with-no-legend.patch deleted file mode 100644 index a085836..0000000 --- a/0005-systemctl-completion-always-invoke-with-no-legend.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 74eeab044e506a39786f484b160d9f64d48ad243 Mon Sep 17 00:00:00 2001 -From: Dave Reisner -Date: Tue, 11 Oct 2011 20:56:53 -0400 -Subject: [PATCH 5/5] 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 -entirely, with the error: - - Failed to issue method call: Unit name UNIT is not valid. - -This adds a small wrapper function for systemctl which can have common -options added to it. ---- - src/systemctl-bash-completion.sh | 20 ++++++++++++-------- - 1 files changed, 12 insertions(+), 8 deletions(-) - -diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh -index 6369a6c..6ebb792 100644 ---- a/src/systemctl-bash-completion.sh -+++ b/src/systemctl-bash-completion.sh -@@ -15,6 +15,10 @@ - # You should have received a copy of the GNU General Public License - # along with systemd; If not, see . - -+__systemctl() { -+ systemctl --no-legend "$@" -+} -+ - __contains_word () { - local word=$1; shift - for w in $*; do [[ $w = $word ]] && return 0; done -@@ -24,7 +28,7 @@ __contains_word () { - __filter_units_by_property () { - local property=$1 value=$2 ; shift ; shift - local -a units=( $* ) -- local -a props=( $(systemctl show --property "$property" -- ${units[*]} | grep -v ^$) ) -+ 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]}" -@@ -32,10 +36,10 @@ __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 --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}' ; } - - _systemctl () { - local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} -@@ -134,13 +138,13 @@ _systemctl () { - comps='' - - elif __contains_word "$verb" ${VERBS[JOBS]}; then -- comps=$( systemctl list-jobs | awk '{print $1}' ) -+ 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}' ) -+ 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_' ) -+ comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' ) - compopt -o nospace - fi - --- -1.7.4.4 - diff --git a/0005-systemctl-make-list-unit-files-output-more-economica.patch b/0005-systemctl-make-list-unit-files-output-more-economica.patch new file mode 100644 index 0000000..d8b83a3 --- /dev/null +++ b/0005-systemctl-make-list-unit-files-output-more-economica.patch @@ -0,0 +1,80 @@ +From 62403a219c01f907e69012e502a73cdb9aeeb251 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 24 Oct 2011 11:49:59 +0200 +Subject: [PATCH 005/126] 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); + } + +-- +1.7.7.5 + diff --git a/0006-plymouth-fix-ply-proto-endianess-issues.patch b/0006-plymouth-fix-ply-proto-endianess-issues.patch new file mode 100644 index 0000000..32348b0 --- /dev/null +++ b/0006-plymouth-fix-ply-proto-endianess-issues.patch @@ -0,0 +1,31 @@ +From 4cff61c8150be456da22cc737696fad925c1393f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 1 Nov 2011 14:20:31 +0100 +Subject: [PATCH 006/126] 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; +-- +1.7.7.5 + diff --git a/0007-random-seed-convert-poolsize-from-bits-to-bytes.patch b/0007-random-seed-convert-poolsize-from-bits-to-bytes.patch new file mode 100644 index 0000000..4212e93 --- /dev/null +++ b/0007-random-seed-convert-poolsize-from-bits-to-bytes.patch @@ -0,0 +1,37 @@ +From fb47a8a6bc8903d8b4b7b71707baa2c7585a0407 Mon Sep 17 00:00:00 2001 +From: Tom Gundersen +Date: Sat, 22 Oct 2011 18:47:08 +0200 +Subject: [PATCH 007/126] 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ı +Reported-by: Gerardo Exequiel Pozzi +(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); + } + +-- +1.7.7.5 + diff --git a/0008-condition-Fix-file-descriptor-leak-in-test_capabilit.patch b/0008-condition-Fix-file-descriptor-leak-in-test_capabilit.patch new file mode 100644 index 0000000..b158ab1 --- /dev/null +++ b/0008-condition-Fix-file-descriptor-leak-in-test_capabilit.patch @@ -0,0 +1,28 @@ +From 62f4ee1b584845c8a3d4caf41c572ec5e7d7af66 Mon Sep 17 00:00:00 2001 +From: Thomas Jarosch +Date: Wed, 26 Oct 2011 09:38:39 +0200 +Subject: [PATCH 008/126] 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)); + } + +-- +1.7.7.5 + diff --git a/0009-initctl-don-t-use-dbus-connection-after-PID-1-got-re.patch b/0009-initctl-don-t-use-dbus-connection-after-PID-1-got-re.patch new file mode 100644 index 0000000..08da8c6 --- /dev/null +++ b/0009-initctl-don-t-use-dbus-connection-after-PID-1-got-re.patch @@ -0,0 +1,55 @@ +From 3e750716de6acad59112a34d3d79f50da680d023 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 1 Nov 2011 18:18:17 +0100 +Subject: [PATCH 009/126] 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; + +-- +1.7.7.5 + diff --git a/0010-cgroup-always-recreate-cgroup-before-we-try-to-apply.patch b/0010-cgroup-always-recreate-cgroup-before-we-try-to-apply.patch new file mode 100644 index 0000000..2aa6a45 --- /dev/null +++ b/0010-cgroup-always-recreate-cgroup-before-we-try-to-apply.patch @@ -0,0 +1,33 @@ +From b160c4add112ec90a811726ee3ac536f98cfd6cf Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 1 Nov 2011 22:02:36 +0100 +Subject: [PATCH 010/126] 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)); +-- +1.7.7.5 + diff --git a/0011-mount-order-remote-mounts-after-both-network.target-.patch b/0011-mount-order-remote-mounts-after-both-network.target-.patch new file mode 100644 index 0000000..69f7415 --- /dev/null +++ b/0011-mount-order-remote-mounts-after-both-network.target-.patch @@ -0,0 +1,51 @@ +From 10e099981a14b6f435552854d4c9d5eaaa65c4da Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 1 Nov 2011 22:27:48 +0100 +Subject: [PATCH 011/126] mount: order remote mounts after both network.target + and remote-fs-pre.target + +Since remote-fs-pre.target is optional we cannot count on it to order +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(-) + +diff --git a/src/mount.c b/src/mount.c +index ef953f0..f9cfe91 100644 +--- a/src/mount.c ++++ b/src/mount.c +@@ -327,7 +327,7 @@ static bool needs_quota(MountParameters *p) { + } + + static int mount_add_fstab_links(Mount *m) { +- const char *target, *after = NULL; ++ const char *target, *after = NULL, *after2 = NULL; + MountParameters *p; + Unit *tu; + int r; +@@ -358,6 +358,7 @@ static int mount_add_fstab_links(Mount *m) { + if (mount_is_network(p)) { + target = SPECIAL_REMOTE_FS_TARGET; + after = SPECIAL_REMOTE_FS_PRE_TARGET; ++ after2 = SPECIAL_NETWORK_TARGET; + } else { + target = SPECIAL_LOCAL_FS_TARGET; + after = SPECIAL_LOCAL_FS_PRE_TARGET; +@@ -374,6 +375,10 @@ static int mount_add_fstab_links(Mount *m) { + if ((r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true)) < 0) + return r; + ++ if (after2) ++ if ((r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true)) < 0) ++ return r; ++ + if (automount) { + Unit *am; + +-- +1.7.7.5 + diff --git a/0012-units-drop-Install-section-from-remote-fs-pre.target.patch b/0012-units-drop-Install-section-from-remote-fs-pre.target.patch new file mode 100644 index 0000000..047833e --- /dev/null +++ b/0012-units-drop-Install-section-from-remote-fs-pre.target.patch @@ -0,0 +1,28 @@ +From 80c991c323a08ee03131d51c34b45286ae72001f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 1 Nov 2011 22:29:48 +0100 +Subject: [PATCH 012/126] 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(-) + +diff --git a/units/remote-fs-pre.target b/units/remote-fs-pre.target +index 5406aa2..8aceb08 100644 +--- a/units/remote-fs-pre.target ++++ b/units/remote-fs-pre.target +@@ -10,6 +10,3 @@ + [Unit] + Description=Remote File Systems (Pre) + After=network.target +- +-[Install] +-WantedBy=multi-user.target +-- +1.7.7.5 + diff --git a/0013-cryptsetup-generator-avoid-ordering-cycle-on-swap.patch b/0013-cryptsetup-generator-avoid-ordering-cycle-on-swap.patch new file mode 100644 index 0000000..6933026 --- /dev/null +++ b/0013-cryptsetup-generator-avoid-ordering-cycle-on-swap.patch @@ -0,0 +1,40 @@ +From 88230ce30fcd48f8f6fadcdf838e6f047a91acdf Mon Sep 17 00:00:00 2001 +From: Tom Gundersen +Date: Mon, 17 Oct 2011 13:01:08 +0200 +Subject: [PATCH 013/126] 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" +-- +1.7.7.5 + diff --git a/0014-bash-completion-update-with-new-verbs-and-arguments.patch b/0014-bash-completion-update-with-new-verbs-and-arguments.patch new file mode 100644 index 0000000..9d26b47 --- /dev/null +++ b/0014-bash-completion-update-with-new-verbs-and-arguments.patch @@ -0,0 +1,153 @@ +From f116811feefbde2af0138ab73a2bfab38639f315 Mon Sep 17 00:00:00 2001 +From: Ran Benita +Date: Wed, 2 Nov 2011 10:48:49 +0200 +Subject: [PATCH 014/126] 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 . + + __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") ) +-- +1.7.7.5 + diff --git a/0015-bash-completion-add-completions-for-systemd-loginctl.patch b/0015-bash-completion-add-completions-for-systemd-loginctl.patch new file mode 100644 index 0000000..b8beb1a --- /dev/null +++ b/0015-bash-completion-add-completions-for-systemd-loginctl.patch @@ -0,0 +1,107 @@ +From cb1d467a016e97e74222fc775fefe4ee3790f8fb Mon Sep 17 00:00:00 2001 +From: Ran Benita +Date: Wed, 2 Nov 2011 10:48:50 +0200 +Subject: [PATCH 015/126] 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 +-- +1.7.7.5 + diff --git a/0016-bash-completion-rename-file-since-it-is-no-longer-fo.patch b/0016-bash-completion-rename-file-since-it-is-no-longer-fo.patch new file mode 100644 index 0000000..dd3024a --- /dev/null +++ b/0016-bash-completion-rename-file-since-it-is-no-longer-fo.patch @@ -0,0 +1,571 @@ +From b7ff1f56d52becdc0820d54a26b2fbec7fbd698c Mon Sep 17 00:00:00 2001 +From: Ran Benita +Date: Wed, 2 Nov 2011 10:48:51 +0200 +Subject: [PATCH 016/126] 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 . +- +-__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 . ++ ++__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 +-- +1.7.7.5 + diff --git a/0017-systemadm-break-timestamp-formatting-out-into-a-sepe.patch b/0017-systemadm-break-timestamp-formatting-out-into-a-sepe.patch new file mode 100644 index 0000000..9bf17d6 --- /dev/null +++ b/0017-systemadm-break-timestamp-formatting-out-into-a-sepe.patch @@ -0,0 +1,60 @@ +From 59c42570c4191f833c06561ea5c6df134946e1f8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 23 Feb 2011 14:03:59 +0100 +Subject: [PATCH 017/126] 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); +-- +1.7.7.5 + diff --git a/0018-systemadm-allow-sorting-of-jobs-and-units.patch b/0018-systemadm-allow-sorting-of-jobs-and-units.patch new file mode 100644 index 0000000..ad9fe69 --- /dev/null +++ b/0018-systemadm-allow-sorting-of-jobs-and-units.patch @@ -0,0 +1,76 @@ +From 5a7251ffb8ea53dd6c0e0b78e78af704bbb1cbb2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 24 Feb 2011 16:29:24 +0100 +Subject: [PATCH 018/126] 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(); + } +-- +1.7.7.5 + diff --git a/0019-systemadm-split-the-type-status-combo-box-into-type-.patch b/0019-systemadm-split-the-type-status-combo-box-into-type-.patch new file mode 100644 index 0000000..7920cc7 --- /dev/null +++ b/0019-systemadm-split-the-type-status-combo-box-into-type-.patch @@ -0,0 +1,112 @@ +From 24924bc68792f49d73cfaf0ff4dd2975d1c3c765 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 25 Feb 2011 18:20:16 +0100 +Subject: [PATCH 019/126] 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() { +-- +1.7.7.5 + diff --git a/0020-systemadm-filter-on-swaps-paths-and-timers-too.patch b/0020-systemadm-filter-on-swaps-paths-and-timers-too.patch new file mode 100644 index 0000000..a5ea1e3 --- /dev/null +++ b/0020-systemadm-filter-on-swaps-paths-and-timers-too.patch @@ -0,0 +1,66 @@ +From ad2d88f188922c5267f15e25446e7ece114b5ac0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 28 Feb 2011 10:35:23 +0100 +Subject: [PATCH 020/126] 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); +-- +1.7.7.5 + diff --git a/0021-systemadm-add-a-wrappable-label-and-use-it-for-statu.patch b/0021-systemadm-add-a-wrappable-label-and-use-it-for-statu.patch new file mode 100644 index 0000000..500c847 --- /dev/null +++ b/0021-systemadm-add-a-wrappable-label-and-use-it-for-statu.patch @@ -0,0 +1,133 @@ +From fb6ffd0ed76b175b4eeb1c73b9fd7a3cbcf6ecbb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 1 Mar 2011 11:18:13 +0100 +Subject: [PATCH 021/126] 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(); ++ } ++ } ++} +-- +1.7.7.5 + diff --git a/0022-systemadm-add-libgee-as-dependency-and-use-it-for-a-.patch b/0022-systemadm-add-libgee-as-dependency-and-use-it-for-a-.patch new file mode 100644 index 0000000..cd401b8 --- /dev/null +++ b/0022-systemadm-add-libgee-as-dependency-and-use-it-for-a-.patch @@ -0,0 +1,101 @@ +From 6c8061acd30f7cb604953dd75f00bb8f8cc7323b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 3 Mar 2011 20:54:01 +0100 +Subject: [PATCH 022/126] 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 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(); ++ + 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) { +-- +1.7.7.5 + diff --git a/0023-systemadm-display-dependencies-sorted.patch b/0023-systemadm-display-dependencies-sorted.patch new file mode 100644 index 0000000..adb2df2 --- /dev/null +++ b/0023-systemadm-display-dependencies-sorted.patch @@ -0,0 +1,38 @@ +From 9a11d4dc5b77fc3b9b33f96888f1a46f5a013786 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 3 Mar 2011 01:30:08 +0100 +Subject: [PATCH 023/126] 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 sorted = new Gee.TreeSet(); ++ 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" : ","; + +-- +1.7.7.5 + diff --git a/0024-systemadm-use-color-for-dependency-links.patch b/0024-systemadm-use-color-for-dependency-links.patch new file mode 100644 index 0000000..22d7410 --- /dev/null +++ b/0024-systemadm-use-color-for-dependency-links.patch @@ -0,0 +1,53 @@ +From c9e50116433d60c2f296f7f542e43e13a872cc75 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 3 Mar 2011 22:20:19 +0100 +Subject: [PATCH 024/126] 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 "" + i + "" ++ + i + "(" + ++ u.sub_state + ")" + ""; ++ return " " + span + ""; ++ } ++ ++ + public string make_dependency_string(string? prefix, string word, string[] dependencies) { + Gee.Collection sorted = new Gee.TreeSet(); + foreach (string i in dependencies) +@@ -479,7 +498,7 @@ public class MainWindow : Window { + first = false; + } + +- r += " " + i + ""; ++ r += format_unit_link(i); + } + + return r; +-- +1.7.7.5 + diff --git a/0025-systemadm-use-bold-for-requires-etc.patch b/0025-systemadm-use-bold-for-requires-etc.patch new file mode 100644 index 0000000..596ac0d --- /dev/null +++ b/0025-systemadm-use-bold-for-requires-etc.patch @@ -0,0 +1,27 @@ +From 4640202a44277e573dda7125d87e43025436fc4a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 17 Sep 2011 14:57:19 +0100 +Subject: [PATCH 025/126] 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 += "" + word + ":"; + first = false; + } + +-- +1.7.7.5 + diff --git a/0026-systemadm-make-the-dependency-listing-selectable.patch b/0026-systemadm-make-the-dependency-listing-selectable.patch new file mode 100644 index 0000000..a232841 --- /dev/null +++ b/0026-systemadm-make-the-dependency-listing-selectable.patch @@ -0,0 +1,27 @@ +From edafba60cbcaab71266f53f3359126c69106b21c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 18 Sep 2011 11:06:07 +0200 +Subject: [PATCH 026/126] 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); +-- +1.7.7.5 + diff --git a/0027-systemadm-catch-exceptions-generated-by-dbus.patch b/0027-systemadm-catch-exceptions-generated-by-dbus.patch new file mode 100644 index 0000000..74b63e9 --- /dev/null +++ b/0027-systemadm-catch-exceptions-generated-by-dbus.patch @@ -0,0 +1,146 @@ +From 328238ca7c52a658089aa5c8ba0d63dfeaf3c2bd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 24 Feb 2011 16:30:55 +0100 +Subject: [PATCH 027/126] 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); + } + +-- +1.7.7.5 + diff --git a/0028-systemadm-coalesce-id-and-decription-fields.patch b/0028-systemadm-coalesce-id-and-decription-fields.patch new file mode 100644 index 0000000..6e2e5dc --- /dev/null +++ b/0028-systemadm-coalesce-id-and-decription-fields.patch @@ -0,0 +1,83 @@ +From 5581802cca0ebea3b8a3193f94c80cfc4d0a3111 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 18 Sep 2011 17:00:12 +0200 +Subject: [PATCH 028/126] 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, +-- +1.7.7.5 + diff --git a/0029-systemadm-adjust-row-numbers-after-removing-aliases.patch b/0029-systemadm-adjust-row-numbers-after-removing-aliases.patch new file mode 100644 index 0000000..67619db --- /dev/null +++ b/0029-systemadm-adjust-row-numbers-after-removing-aliases.patch @@ -0,0 +1,75 @@ +From e3eece11dcdef669d90fef5f42428a921cad33b1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 19 Sep 2011 08:14:02 +0200 +Subject: [PATCH 029/126] 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); +-- +1.7.7.5 + diff --git a/0030-systemadm-use-colors-for-id-too-remove-color-from-fr.patch b/0030-systemadm-use-colors-for-id-too-remove-color-from-fr.patch new file mode 100644 index 0000000..5dc7013 --- /dev/null +++ b/0030-systemadm-use-colors-for-id-too-remove-color-from-fr.patch @@ -0,0 +1,77 @@ +From d21907af22f1c14445521cb6ae5cabccbe186bcc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 19 Sep 2011 08:20:17 +0200 +Subject: [PATCH 030/126] 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 "" + i + "" + + i + "(" + + u.sub_state + ")" + ""; +- return " " + span + ""; ++ if(link) ++ return " " + span + ""; ++ 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("" + fp + "" ); ++ unit_fragment_path_label.set_markup_or_na( ++ "" + ++ "" + fp + ""); + else + unit_fragment_path_label.set_text_or_na(); + +-- +1.7.7.5 + diff --git a/0031-cgroup-immediately-remove-all-cgroups-which-run-empt.patch b/0031-cgroup-immediately-remove-all-cgroups-which-run-empt.patch new file mode 100644 index 0000000..907b81d --- /dev/null +++ b/0031-cgroup-immediately-remove-all-cgroups-which-run-empt.patch @@ -0,0 +1,56 @@ +From 54a91c5eae72181cc7aadf618c152e18ac336b5e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 3 Nov 2011 19:42:53 +0100 +Subject: [PATCH 031/126] 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; +-- +1.7.7.5 + diff --git a/0032-utmp-remove-unneded-parameters.patch b/0032-utmp-remove-unneded-parameters.patch new file mode 100644 index 0000000..1dd926f --- /dev/null +++ b/0032-utmp-remove-unneded-parameters.patch @@ -0,0 +1,137 @@ +From 9052b8afdf507b674b2e3abfb803d96c19c0a307 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sun, 6 Nov 2011 23:06:38 +0100 +Subject: [PATCH 032/126] 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)); + +-- +1.7.7.5 + diff --git a/0033-utmp-no-need-to-zero-a-struct-before-overwriting-it-.patch b/0033-utmp-no-need-to-zero-a-struct-before-overwriting-it-.patch new file mode 100644 index 0000000..ff18fcc --- /dev/null +++ b/0033-utmp-no-need-to-zero-a-struct-before-overwriting-it-.patch @@ -0,0 +1,27 @@ +From ddd712b60245be98042ad5212597ef9ec9833ccf Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sun, 6 Nov 2011 23:07:54 +0100 +Subject: [PATCH 033/126] 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; +-- +1.7.7.5 + diff --git a/0034-utmp-initialize-store-with-the-found-entry-not-with-.patch b/0034-utmp-initialize-store-with-the-found-entry-not-with-.patch new file mode 100644 index 0000000..1bd62cf --- /dev/null +++ b/0034-utmp-initialize-store-with-the-found-entry-not-with-.patch @@ -0,0 +1,27 @@ +From b2072011a7998e22f6d8a4f2a815ed3dbab819cc Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sun, 6 Nov 2011 23:31:46 +0100 +Subject: [PATCH 034/126] 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; +-- +1.7.7.5 + diff --git a/0035-utmp-for-DEAD_PROCESS-write-the-current-time-to-wtmp.patch b/0035-utmp-for-DEAD_PROCESS-write-the-current-time-to-wtmp.patch new file mode 100644 index 0000000..806f9ae --- /dev/null +++ b/0035-utmp-for-DEAD_PROCESS-write-the-current-time-to-wtmp.patch @@ -0,0 +1,72 @@ +From 404b71bb18c983f62897ed40d9a4b310ddcca86a Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sun, 6 Nov 2011 23:55:06 +0100 +Subject: [PATCH 035/126] 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); + } + + +-- +1.7.7.5 + diff --git a/0036-man-fix-a-typo-in-signal-number.patch b/0036-man-fix-a-typo-in-signal-number.patch new file mode 100644 index 0000000..f4fd2fe --- /dev/null +++ b/0036-man-fix-a-typo-in-signal-number.patch @@ -0,0 +1,26 @@ +From abd72ba81496bd84a970faa7daec3bacd6a81356 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 7 Nov 2011 01:08:21 +0100 +Subject: [PATCH 036/126] 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 @@ + Sets the log level to + debug + (resp. info on +- SIGRTMIN+32), as ++ SIGRTMIN+23), as + controlled via + systemd.log_level=debug + (resp. systemd.log_level=info +-- +1.7.7.5 + diff --git a/0037-units-drop-unnecessary-StandardOutput-syslog.patch b/0037-units-drop-unnecessary-StandardOutput-syslog.patch new file mode 100644 index 0000000..e77d19d --- /dev/null +++ b/0037-units-drop-unnecessary-StandardOutput-syslog.patch @@ -0,0 +1,79 @@ +From 27b67ec67a39321dd52828002a50868071cb5bbf Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Wed, 9 Nov 2011 08:42:03 +0100 +Subject: [PATCH 037/126] 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 +-- +1.7.7.5 + diff --git a/0038-units-fedora-let-rc-local.service-log-to-syslog.patch b/0038-units-fedora-let-rc-local.service-log-to-syslog.patch new file mode 100644 index 0000000..00bc3ec --- /dev/null +++ b/0038-units-fedora-let-rc-local.service-log-to-syslog.patch @@ -0,0 +1,28 @@ +From a8fda0ca8760ccad7630b9dd4b544577ce97d232 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Wed, 9 Nov 2011 08:58:36 +0100 +Subject: [PATCH 038/126] 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 +-- +1.7.7.5 + diff --git a/0039-service-don-t-warn-if-the-pidfile-still-exists-after.patch b/0039-service-don-t-warn-if-the-pidfile-still-exists-after.patch new file mode 100644 index 0000000..54fe142 --- /dev/null +++ b/0039-service-don-t-warn-if-the-pidfile-still-exists-after.patch @@ -0,0 +1,61 @@ +From 3fdac700a322217421675774e25cfd5cb09c2dd2 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 10 Nov 2011 09:55:47 +0100 +Subject: [PATCH 039/126] 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; + } + +-- +1.7.7.5 + diff --git a/0040-job-colored-status-messages-on-boot.patch b/0040-job-colored-status-messages-on-boot.patch new file mode 100644 index 0000000..356bb3f --- /dev/null +++ b/0040-job-colored-status-messages-on-boot.patch @@ -0,0 +1,132 @@ +From dd36a516b3945e64578ab4190499266ae44b1155 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 10 Nov 2011 12:53:39 +0100 +Subject: [PATCH 040/126] 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); + +-- +1.7.7.5 + diff --git a/0041-man-fix-typo-in-sd_notify.patch b/0041-man-fix-typo-in-sd_notify.patch new file mode 100644 index 0000000..ae48ece --- /dev/null +++ b/0041-man-fix-typo-in-sd_notify.patch @@ -0,0 +1,27 @@ +From acd5d830990975310998d28800cad086357a80c0 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 11 Nov 2011 10:48:17 +0100 +Subject: [PATCH 041/126] 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. + + sd_notifyf() is similar to +- sd_notifyf() but takes a ++ sd_notify() but takes a + printf()-like format string plus + arguments. + +-- +1.7.7.5 + diff --git a/0042-Fix-same-expression-on-both-sides-of.patch b/0042-Fix-same-expression-on-both-sides-of.patch new file mode 100644 index 0000000..7ff7a88 --- /dev/null +++ b/0042-Fix-same-expression-on-both-sides-of.patch @@ -0,0 +1,32 @@ +From b3070998c22feaa3b85337c56fb437527aec962e Mon Sep 17 00:00:00 2001 +From: Thomas Jarosch +Date: Wed, 9 Nov 2011 20:48:31 +0100 +Subject: [PATCH 042/126] 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 +(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; + +-- +1.7.7.5 + diff --git a/0043-execute-avoid-logging-to-closed-fds.patch b/0043-execute-avoid-logging-to-closed-fds.patch new file mode 100644 index 0000000..1898c0c --- /dev/null +++ b/0043-execute-avoid-logging-to-closed-fds.patch @@ -0,0 +1,61 @@ +From 838ad64f4f4502f370dcbf5faaed94b618bdac08 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Wed, 16 Nov 2011 23:45:01 +0100 +Subject: [PATCH 043/126] 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); +-- +1.7.7.5 + diff --git a/0044-execute-make-setup_pam-return-errno-when-possible.patch b/0044-execute-make-setup_pam-return-errno-when-possible.patch new file mode 100644 index 0000000..17f8b96 --- /dev/null +++ b/0044-execute-make-setup_pam-return-errno-when-possible.patch @@ -0,0 +1,49 @@ +From 859dc200c20c5dd7e49e443bd29ab6c31dfb0b69 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 17 Nov 2011 00:16:22 +0100 +Subject: [PATCH 044/126] 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 + +-- +1.7.7.5 + diff --git a/0045-execute-log-errors-from-sd-EXEC.patch b/0045-execute-log-errors-from-sd-EXEC.patch new file mode 100644 index 0000000..dcfdc14 --- /dev/null +++ b/0045-execute-log-errors-from-sd-EXEC.patch @@ -0,0 +1,478 @@ +From 43516d8c437d0afd7f4a70592487291e45675101 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 17 Nov 2011 00:21:16 +0100 +Subject: [PATCH 045/126] 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), ¶m) < 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; + +-- +1.7.7.5 + diff --git a/0046-pam-module-use-the-correct-session-type-unspecified.patch b/0046-pam-module-use-the-correct-session-type-unspecified.patch new file mode 100644 index 0000000..e394873 --- /dev/null +++ b/0046-pam-module-use-the-correct-session-type-unspecified.patch @@ -0,0 +1,28 @@ +From d9e63f3d535758350a83b9b39050e98e01d8d638 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 19 Nov 2011 01:14:11 +0100 +Subject: [PATCH 046/126] 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"); + +-- +1.7.7.5 + diff --git a/0047-pam-module-treat-cron-in-PAM_TTY-as-empty-tty.patch b/0047-pam-module-treat-cron-in-PAM_TTY-as-empty-tty.patch new file mode 100644 index 0000000..9e99b0e --- /dev/null +++ b/0047-pam-module-treat-cron-in-PAM_TTY-as-empty-tty.patch @@ -0,0 +1,55 @@ +From ecac03685b4679d53c0ec86db257e061bec2d2c9 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 19 Nov 2011 01:17:46 +0100 +Subject: [PATCH 047/126] 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)) +-- +1.7.7.5 + diff --git a/0048-let-mount-and-swap-units-log-to-the-configured-defau.patch b/0048-let-mount-and-swap-units-log-to-the-configured-defau.patch new file mode 100644 index 0000000..968e536 --- /dev/null +++ b/0048-let-mount-and-swap-units-log-to-the-configured-defau.patch @@ -0,0 +1,56 @@ +From 003cb5ce02b9660a790ab330796e92b5d79806b6 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 19 Nov 2011 02:47:09 +0100 +Subject: [PATCH 048/126] 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; + +-- +1.7.7.5 + diff --git a/0049-socket-add-option-for-SO_PASSCRED.patch b/0049-socket-add-option-for-SO_PASSCRED.patch new file mode 100644 index 0000000..45b0769 --- /dev/null +++ b/0049-socket-add-option-for-SO_PASSCRED.patch @@ -0,0 +1,94 @@ +From 1a542f80955b0d425412f5c3dd604483747db133 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Tue, 29 Nov 2011 22:15:41 +0100 +Subject: [PATCH 049/126] 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 @@ + " \n" \ + " \n" \ + " \n" \ ++ " \n" \ + " \n" \ + " \n" \ + " \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; +-- +1.7.7.5 + diff --git a/0050-shutdownd-use-PassCred-yes-in-the-socket-unit.patch b/0050-shutdownd-use-PassCred-yes-in-the-socket-unit.patch new file mode 100644 index 0000000..b232173 --- /dev/null +++ b/0050-shutdownd-use-PassCred-yes-in-the-socket-unit.patch @@ -0,0 +1,58 @@ +From 6811dc0646d92f0c668cbf3ce5a6426e273c4abf Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Tue, 29 Nov 2011 23:14:36 +0100 +Subject: [PATCH 050/126] 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 +-- +1.7.7.5 + diff --git a/0051-syslog-use-PassCred-yes-for-the-dev-log-socket.patch b/0051-syslog-use-PassCred-yes-for-the-dev-log-socket.patch new file mode 100644 index 0000000..e2aeb25 --- /dev/null +++ b/0051-syslog-use-PassCred-yes-for-the-dev-log-socket.patch @@ -0,0 +1,52 @@ +From 20f36bebf9cb9655cb8ac606b70461e4db7ecbde Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Wed, 30 Nov 2011 09:37:13 +0100 +Subject: [PATCH 051/126] 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 +-- +1.7.7.5 + diff --git a/0052-man-document-the-PassCred-option.patch b/0052-man-document-the-PassCred-option.patch new file mode 100644 index 0000000..56303d7 --- /dev/null +++ b/0052-man-document-the-PassCred-option.patch @@ -0,0 +1,36 @@ +From b1d7dbb539fcbd671ec4ddce1d162fe3543440ea Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Wed, 30 Nov 2011 11:06:35 +0100 +Subject: [PATCH 052/126] 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 @@ + + + ++ PassCred= ++ 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 ++ . ++ ++ ++ + TCPCongestion= + Takes a string + value. Controls the TCP congestion +-- +1.7.7.5 + diff --git a/0053-add-a-generator-to-pull-rc-local.service-in.patch b/0053-add-a-generator-to-pull-rc-local.service-in.patch new file mode 100644 index 0000000..8a5f2a7 --- /dev/null +++ b/0053-add-a-generator-to-pull-rc-local.service-in.patch @@ -0,0 +1,250 @@ +From a40cb5c2aaa67a66c20b17f18cb30fd7b65154d4 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 2 Dec 2011 10:18:46 +0100 +Subject: [PATCH 053/126] 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 . ++***/ ++ ++#include ++#include ++#include ++ ++#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 +-- +1.7.7.5 + diff --git a/0054-rc-local-no-need-to-check-if-the-script-is-executabl.patch b/0054-rc-local-no-need-to-check-if-the-script-is-executabl.patch new file mode 100644 index 0000000..d99b790 --- /dev/null +++ b/0054-rc-local-no-need-to-check-if-the-script-is-executabl.patch @@ -0,0 +1,41 @@ +From 6d3970658de8f270b651e8b4cffbc464e3774428 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 2 Dec 2011 11:32:04 +0100 +Subject: [PATCH 054/126] 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 +-- +1.7.7.5 + diff --git a/0055-rc-local-order-after-network.target.patch b/0055-rc-local-order-after-network.target.patch new file mode 100644 index 0000000..46d104c --- /dev/null +++ b/0055-rc-local-order-after-network.target.patch @@ -0,0 +1,42 @@ +From 7f0aa58747b7335c7856fb7153be6cd1e22b74b6 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 2 Dec 2011 11:32:52 +0100 +Subject: [PATCH 055/126] 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 +-- +1.7.7.5 + diff --git a/0056-util-fix-error-checking-after-fgets.patch b/0056-util-fix-error-checking-after-fgets.patch new file mode 100644 index 0000000..9b7965c --- /dev/null +++ b/0056-util-fix-error-checking-after-fgets.patch @@ -0,0 +1,54 @@ +From 360ab562c360ec375f76fb88318546323a835459 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 3 Dec 2011 00:41:34 +0100 +Subject: [PATCH 056/126] 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; + } +-- +1.7.7.5 + diff --git a/0057-path-use-m-instead-of-strerror-errno.patch b/0057-path-use-m-instead-of-strerror-errno.patch new file mode 100644 index 0000000..1fa8d40 --- /dev/null +++ b/0057-path-use-m-instead-of-strerror-errno.patch @@ -0,0 +1,36 @@ +From 5971b6afa801868d4bf790727dec254588832d70 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 3 Dec 2011 01:36:05 +0100 +Subject: [PATCH 057/126] 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; + } + +-- +1.7.7.5 + diff --git a/0058-path-refactor-PathSpec-usage.patch b/0058-path-refactor-PathSpec-usage.patch new file mode 100644 index 0000000..88c9c72 --- /dev/null +++ b/0058-path-refactor-PathSpec-usage.patch @@ -0,0 +1,507 @@ +From 69086d0499fb8ae161ab9bd83da19f098317f6bc Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 3 Dec 2011 01:38:30 +0100 +Subject: [PATCH 058/126] 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; + +-- +1.7.7.5 + diff --git a/0059-path-add-PathModified-PathChanged-IN_MODIFY.patch b/0059-path-add-PathModified-PathChanged-IN_MODIFY.patch new file mode 100644 index 0000000..c1ca096 --- /dev/null +++ b/0059-path-add-PathModified-PathChanged-IN_MODIFY.patch @@ -0,0 +1,90 @@ +From 30fb4092d987ff81f39177461f6472e2fff225a1 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 3 Dec 2011 10:22:26 +0100 +Subject: [PATCH 059/126] 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 @@ + PathExists= + PathExistsGlob= + PathChanged= ++ PathModified= + DirectoryNotEmpty= + + Defines paths to +@@ -129,8 +130,14 @@ + specified. PathChanged= + may be used to watch a file or + directory and activate the configured +- unit whenever it changes or is +- modified. DirectoryNotEmpty= ++ 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. PathModified= ++ is similar, but additionally it is activated ++ also on simple writes to the watched file. ++ ++ DirectoryNotEmpty= + may be used to watch a directory and + activate the configured unit whenever + it contains at least one file. +@@ -154,11 +161,7 @@ + activated, then the configured unit is + immediately activated as + well. Something similar does not apply +- to +- PathChanged=. The +- latter is not activated on simple +- writes but only if files with were +- opened for writing are closed. ++ to PathChanged=. + + + +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; +-- +1.7.7.5 + diff --git a/0060-service-handle-services-with-racy-daemonization-grac.patch b/0060-service-handle-services-with-racy-daemonization-grac.patch new file mode 100644 index 0000000..5239f62 --- /dev/null +++ b/0060-service-handle-services-with-racy-daemonization-grac.patch @@ -0,0 +1,330 @@ +From 1b2395f867d283bb08862e1ce421ab3ac1b02968 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 3 Dec 2011 02:13:30 +0100 +Subject: [PATCH 060/126] 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; + }; +-- +1.7.7.5 + diff --git a/0061-service-stop-the-service-if-ExecStartPost-ends-with-.patch b/0061-service-stop-the-service-if-ExecStartPost-ends-with-.patch new file mode 100644 index 0000000..4fdd039 --- /dev/null +++ b/0061-service-stop-the-service-if-ExecStartPost-ends-with-.patch @@ -0,0 +1,60 @@ +From 4035af799be35919232a68dfb0786af4f54257a1 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 3 Dec 2011 21:34:34 +0100 +Subject: [PATCH 061/126] 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; + +-- +1.7.7.5 + diff --git a/0062-Allow-list-unit-files-to-run-with-root.patch b/0062-Allow-list-unit-files-to-run-with-root.patch new file mode 100644 index 0000000..190b956 --- /dev/null +++ b/0062-Allow-list-unit-files-to-run-with-root.patch @@ -0,0 +1,63 @@ +From 7c3d4fb80496c466d6523b88d5720a7f4ff7939d Mon Sep 17 00:00:00 2001 +From: Bill Nottingham +Date: Tue, 22 Nov 2011 15:45:34 -0500 +Subject: [PATCH 062/126] 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") && +-- +1.7.7.5 + diff --git a/0063-unit-garbage-collect-units-with-load-error.patch b/0063-unit-garbage-collect-units-with-load-error.patch new file mode 100644 index 0000000..5054e39 --- /dev/null +++ b/0063-unit-garbage-collect-units-with-load-error.patch @@ -0,0 +1,30 @@ +From 069a85095fb07d894ae1825db5f7300c5b5f092b Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Tue, 6 Dec 2011 00:47:28 +0100 +Subject: [PATCH 063/126] 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)); + +-- +1.7.7.5 + diff --git a/0064-systemctl-print-error-load-state-in-red.patch b/0064-systemctl-print-error-load-state-in-red.patch new file mode 100644 index 0000000..c559d58 --- /dev/null +++ b/0064-systemctl-print-error-load-state-in-red.patch @@ -0,0 +1,41 @@ +From 3fc55e7a9f4dc14ca74ed6b293e1fac03e1fec74 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Tue, 6 Dec 2011 01:14:36 +0100 +Subject: [PATCH 064/126] 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 +-- +1.7.7.5 + diff --git a/0065-is-an-ampersat-not-an-ampersand-let-s-call-it-at-sym.patch b/0065-is-an-ampersat-not-an-ampersand-let-s-call-it-at-sym.patch new file mode 100644 index 0000000..dc012ee --- /dev/null +++ b/0065-is-an-ampersat-not-an-ampersand-let-s-call-it-at-sym.patch @@ -0,0 +1,27 @@ +From 0773caae1b4eae198f8e41fb8a1d46c24c99543e Mon Sep 17 00:00:00 2001 +From: Tim Waugh +Date: Thu, 8 Dec 2011 17:32:09 +0100 +Subject: [PATCH 065/126] '@' 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. + + 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 +-- +1.7.7.5 + diff --git a/0066-path-add-missing-pieces-for-PathModified.patch b/0066-path-add-missing-pieces-for-PathModified.patch new file mode 100644 index 0000000..8d68968 --- /dev/null +++ b/0066-path-add-missing-pieces-for-PathModified.patch @@ -0,0 +1,52 @@ +From 7cae93f652dff82e998a3d1f99f1a18a3f908c30 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 8 Dec 2011 12:09:10 +0100 +Subject: [PATCH 066/126] 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; +-- +1.7.7.5 + diff --git a/0067-unit-fix-false-positive-in-check-for-unneeded-unit.patch b/0067-unit-fix-false-positive-in-check-for-unneeded-unit.patch new file mode 100644 index 0000000..a2715ff --- /dev/null +++ b/0067-unit-fix-false-positive-in-check-for-unneeded-unit.patch @@ -0,0 +1,55 @@ +From 43664cdd8565ae24b27c3f91be1de64ae9021608 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 9 Dec 2011 15:24:04 +0100 +Subject: [PATCH 067/126] 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; +-- +1.7.7.5 + diff --git a/0068-unit-check-for-unneeded-dependencies-even-when-unit-.patch b/0068-unit-check-for-unneeded-dependencies-even-when-unit-.patch new file mode 100644 index 0000000..58f27db --- /dev/null +++ b/0068-unit-check-for-unneeded-dependencies-even-when-unit-.patch @@ -0,0 +1,48 @@ +From c075b337c3ebfd4665f3745a66984bf2d2793a97 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 9 Dec 2011 15:25:29 +0100 +Subject: [PATCH 068/126] 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); +-- +1.7.7.5 + diff --git a/0069-pam-module-add-a-couple-of-debugging-prints.patch b/0069-pam-module-add-a-couple-of-debugging-prints.patch new file mode 100644 index 0000000..a642c0c --- /dev/null +++ b/0069-pam-module-add-a-couple-of-debugging-prints.patch @@ -0,0 +1,42 @@ +From 2f9743bff6e9bfe4365c24becea68b27d06d1c0d Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Wed, 14 Dec 2011 01:25:47 +0100 +Subject: [PATCH 069/126] 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."); +-- +1.7.7.5 + diff --git a/0070-fsck-Fix-typo-in-comment.patch b/0070-fsck-Fix-typo-in-comment.patch new file mode 100644 index 0000000..a335d73 --- /dev/null +++ b/0070-fsck-Fix-typo-in-comment.patch @@ -0,0 +1,26 @@ +From 0d380f2f2d27eabcab8167a52e2d7196720f3d6a Mon Sep 17 00:00:00 2001 +From: Gregs Gregs +Date: Mon, 14 Nov 2011 19:58:03 +0200 +Subject: [PATCH 070/126] 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)); +-- +1.7.7.5 + diff --git a/0071-systemctl-fix-typo-in-is-enabled.patch b/0071-systemctl-fix-typo-in-is-enabled.patch new file mode 100644 index 0000000..bec6221 --- /dev/null +++ b/0071-systemctl-fix-typo-in-is-enabled.patch @@ -0,0 +1,27 @@ +From b63edf0ecaab0cb26bba99b139511ac22d3bf785 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Wed, 14 Dec 2011 22:23:56 +0100 +Subject: [PATCH 071/126] 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") && +-- +1.7.7.5 + diff --git a/0072-tmpfiles-use-an-enum-instead-of-plain-char-for-item-.patch b/0072-tmpfiles-use-an-enum-instead-of-plain-char-for-item-.patch new file mode 100644 index 0000000..5328119 --- /dev/null +++ b/0072-tmpfiles-use-an-enum-instead-of-plain-char-for-item-.patch @@ -0,0 +1,75 @@ +From c8be37cab131ec8a1aa54e5878483a18fc0bde6e Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 15 Dec 2011 21:31:14 +0100 +Subject: [PATCH 072/126] 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 && +-- +1.7.7.5 + diff --git a/0073-tmpfiles-rename-a-couple-of-functions.patch b/0073-tmpfiles-rename-a-couple-of-functions.patch new file mode 100644 index 0000000..f1cec53 --- /dev/null +++ b/0073-tmpfiles-rename-a-couple-of-functions.patch @@ -0,0 +1,55 @@ +From bdd9b9807a89eb8e4789a3279253f6f845f90e9b Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 15 Dec 2011 21:32:50 +0100 +Subject: [PATCH 073/126] 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) +-- +1.7.7.5 + diff --git a/0074-tmpfiles-use-a-common-function-to-set-owner-group-mo.patch b/0074-tmpfiles-use-a-common-function-to-set-owner-group-mo.patch new file mode 100644 index 0000000..573fb9e --- /dev/null +++ b/0074-tmpfiles-use-a-common-function-to-set-owner-group-mo.patch @@ -0,0 +1,211 @@ +From 35bb56b851308370435c0ff28c2d73a790043fbb Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 15 Dec 2011 23:44:23 +0100 +Subject: [PATCH 074/126] 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) { +-- +1.7.7.5 + diff --git a/0075-tmpfiles-separate-a-generic-item-glob-processing-fun.patch b/0075-tmpfiles-separate-a-generic-item-glob-processing-fun.patch new file mode 100644 index 0000000..d19e058 --- /dev/null +++ b/0075-tmpfiles-separate-a-generic-item-glob-processing-fun.patch @@ -0,0 +1,102 @@ +From ef754c81da83d1a1d9b2a3eb41b545196800f59f Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 15 Dec 2011 23:45:26 +0100 +Subject: [PATCH 075/126] 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) { +-- +1.7.7.5 + diff --git a/0076-tmpfiles-add-RECURSIVE_RELABEL_PATH-Z.patch b/0076-tmpfiles-add-RECURSIVE_RELABEL_PATH-Z.patch new file mode 100644 index 0000000..a50fcc3 --- /dev/null +++ b/0076-tmpfiles-add-RECURSIVE_RELABEL_PATH-Z.patch @@ -0,0 +1,195 @@ +From 265c05c53ac71337feb5db53eb8c7acf13901a31 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 15 Dec 2011 23:11:07 +0100 +Subject: [PATCH 076/126] 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); +-- +1.7.7.5 + diff --git a/0077-man-document-Z-in-tmpfiles.patch b/0077-man-document-Z-in-tmpfiles.patch new file mode 100644 index 0000000..8dc8ffc --- /dev/null +++ b/0077-man-document-Z-in-tmpfiles.patch @@ -0,0 +1,49 @@ +From e5c58e069271013582b9de91859aaa5fef70f079 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Thu, 15 Dec 2011 23:04:37 +0100 +Subject: [PATCH 077/126] 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 @@ + If this option is passed all + files and directories marked with f, + F, d, D in the configuration files are +- created. ++ created. Files and directories marked with Z ++ are relabeled. + + + +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 + place of normal path + names. + ++ ++ ++ Z ++ 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. ++ + + + +-- +1.7.7.5 + diff --git a/0078-man-mention-that-Z-ignores-uid-gid-mode.patch b/0078-man-mention-that-Z-ignores-uid-gid-mode.patch new file mode 100644 index 0000000..de444b5 --- /dev/null +++ b/0078-man-mention-that-Z-ignores-uid-gid-mode.patch @@ -0,0 +1,36 @@ +From a783d0af2d7a5a40942c8c2355a9119e3344dcc2 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 16 Dec 2011 00:38:22 +0100 +Subject: [PATCH 078/126] 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 + 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. ++ ignored for x, r, R, Z lines. + + + +@@ -186,7 +186,7 @@ d /run/user 0755 root root 10d + 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. ++ r, R, Z lines. + + + +-- +1.7.7.5 + diff --git a/0079-service-use-syslog-console-for-sysv_console.patch b/0079-service-use-syslog-console-for-sysv_console.patch new file mode 100644 index 0000000..1266bba --- /dev/null +++ b/0079-service-use-syslog-console-for-sysv_console.patch @@ -0,0 +1,28 @@ +From d18d8b40a2c65a551d2954cea701631a5db323e7 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 16 Dec 2011 17:38:01 +0100 +Subject: [PATCH 079/126] 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; + +-- +1.7.7.5 + diff --git a/0080-tmpfiles-apply-chown-chmod-for-Z-entries-too.patch b/0080-tmpfiles-apply-chown-chmod-for-Z-entries-too.patch new file mode 100644 index 0000000..1811f01 --- /dev/null +++ b/0080-tmpfiles-apply-chown-chmod-for-Z-entries-too.patch @@ -0,0 +1,194 @@ +From 2c023ff55f1449a841aa8449f03792a8436c2481 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 16 Dec 2011 18:00:11 +0100 +Subject: [PATCH 080/126] 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. ++ have their ownership, access mode and security ++ labels set. + + + +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 + + + Z +- Recursively +- relabel security context of a path and ++ 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 + 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. ++ 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. + + + +@@ -185,8 +188,9 @@ d /run/user 0755 root root 10d + 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. ++ 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. + + + +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; + +-- +1.7.7.5 + diff --git a/0081-tmpfiles-add-z-like-Z-but-not-recursive.patch b/0081-tmpfiles-add-z-like-Z-but-not-recursive.patch new file mode 100644 index 0000000..c312015 --- /dev/null +++ b/0081-tmpfiles-add-z-like-Z-but-not-recursive.patch @@ -0,0 +1,150 @@ +From 4f0399974eb67bc9420c3bd700465190e38d92d6 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 16 Dec 2011 18:27:35 +0100 +Subject: [PATCH 081/126] 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 @@ + 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. + + +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 + + + ++ z ++ 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. ++ ++ ++ ++ + Z + Recursively set + ownership, access mode and relabel +@@ -175,7 +185,7 @@ d /run/user 0755 root root 10d + 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. +@@ -188,7 +198,7 @@ d /run/user 0755 root root 10d + 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. + +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; +-- +1.7.7.5 + diff --git a/0082-man-fix-misplaced-remark-in-description-of-Sockets.patch b/0082-man-fix-misplaced-remark-in-description-of-Sockets.patch new file mode 100644 index 0000000..388b42b --- /dev/null +++ b/0082-man-fix-misplaced-remark-in-description-of-Sockets.patch @@ -0,0 +1,32 @@ +From f2a7f81850607590c5d64efe5beedadc85be9909 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 17 Dec 2011 00:39:19 +0100 +Subject: [PATCH 082/126] 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 @@ + 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. + +-- +1.7.7.5 + diff --git a/0083-execute-fix-losing-of-start-timestamps.patch b/0083-execute-fix-losing-of-start-timestamps.patch new file mode 100644 index 0000000..3809c06 --- /dev/null +++ b/0083-execute-fix-losing-of-start-timestamps.patch @@ -0,0 +1,29 @@ +From ef50636c71f16165e58b38c25890213e2a6b073b Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sat, 17 Dec 2011 01:33:40 +0100 +Subject: [PATCH 083/126] 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; +-- +1.7.7.5 + diff --git a/0084-label-fix-labeling-of-symbolic-links.patch b/0084-label-fix-labeling-of-symbolic-links.patch new file mode 100644 index 0000000..f7f8528 --- /dev/null +++ b/0084-label-fix-labeling-of-symbolic-links.patch @@ -0,0 +1,27 @@ +From afa63b4de8367c2c48c639471e18962c1e1b5ad5 Mon Sep 17 00:00:00 2001 +From: Dan Walsh +Date: Mon, 19 Dec 2011 23:55:29 +0100 +Subject: [PATCH 084/126] 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 */ +-- +1.7.7.5 + diff --git a/0085-dbus-register-to-DBus-asynchronously.patch b/0085-dbus-register-to-DBus-asynchronously.patch new file mode 100644 index 0000000..d127dc1 --- /dev/null +++ b/0085-dbus-register-to-DBus-asynchronously.patch @@ -0,0 +1,563 @@ +From 6e1da63130bb563b5cce89c2a7d66e98e79c5ec4 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sun, 18 Dec 2011 14:58:10 +0100 +Subject: [PATCH 085/126] 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; +-- +1.7.7.5 + diff --git a/0086-dbus-no-sync-D-Bus-connection-flushing.patch b/0086-dbus-no-sync-D-Bus-connection-flushing.patch new file mode 100644 index 0000000..a79400e --- /dev/null +++ b/0086-dbus-no-sync-D-Bus-connection-flushing.patch @@ -0,0 +1,29 @@ +From 8787a5577aef2703a1484a57db4fe3afb196fc73 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 19 Dec 2011 18:32:10 +0100 +Subject: [PATCH 086/126] 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); + } +-- +1.7.7.5 + diff --git a/0087-log-never-block-on-syslog-in-PID-1.patch b/0087-log-never-block-on-syslog-in-PID-1.patch new file mode 100644 index 0000000..f0c3939 --- /dev/null +++ b/0087-log-never-block-on-syslog-in-PID-1.patch @@ -0,0 +1,77 @@ +From 58a06a6dfb11121bc1220c1c21fdf11ae65ac895 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Sun, 18 Dec 2011 14:57:54 +0100 +Subject: [PATCH 087/126] 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); +-- +1.7.7.5 + diff --git a/0088-macro-fix-ALIGN_TO-macro-definition.patch b/0088-macro-fix-ALIGN_TO-macro-definition.patch new file mode 100644 index 0000000..13a4f3f --- /dev/null +++ b/0088-macro-fix-ALIGN_TO-macro-definition.patch @@ -0,0 +1,27 @@ +From 410c7e298a2937bd3c69e70b31d6ee0c4754c566 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 8 Nov 2011 18:18:48 +0100 +Subject: [PATCH 088/126] 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; +-- +1.7.7.5 + diff --git a/0089-man-document-the-sd-login-interfaces.patch b/0089-man-document-the-sd-login-interfaces.patch new file mode 100644 index 0000000..be97580 --- /dev/null +++ b/0089-man-document-the-sd-login-interfaces.patch @@ -0,0 +1,960 @@ +From caaed693b9e8b16102c794fa52850bbcb7cc6fd9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Dec 2011 03:02:17 +0100 +Subject: [PATCH 089/126] 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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ sd_get_seats ++ systemd ++ ++ ++ ++ Developer ++ Lennart ++ Poettering ++ lennart@poettering.net ++ ++ ++ ++ ++ ++ sd_get_seats ++ 3 ++ ++ ++ ++ sd_get_seats ++ sd_get_sessions ++ sd_get_uids ++ Determine available seats, sessions and logged in users ++ ++ ++ ++ ++ #include <systemd/sd-login.h> ++ ++ ++ int sd_get_seats ++ char*** seats ++ ++ ++ ++ int sd_get_sessions ++ char*** sessions ++ ++ ++ ++ int sd_get_uids ++ char*** sessions ++ ++ ++ ++ ++ ++ ++ Description ++ ++ sd_get_seats() 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 ++ free3 ++ call after use. ++ ++ Similar, sd_get_sessions() may ++ be used to determine all current login sessions. ++ ++ Similar, sd_get_uids() may ++ be used to determine all Unix users who currently have login sessions. ++ ++ ++ ++ Return Value ++ ++ On success sd_get_seats(), ++ sd_get_sessions() and ++ sd_get_uids() return the number ++ of entries in the arrays. On failure, these calls ++ return a negative errno-style error code. ++ ++ ++ ++ Notes ++ ++ The sd_get_seats(), ++ sd_get_sessions() and ++ sd_get_uids() interfaces ++ are available as shared library, which can be compiled ++ and linked to with the ++ libsystemd-login ++ pkg-config1 ++ file. ++ ++ ++ ++ See Also ++ ++ ++ systemd1, ++ sd-login7, ++ sd_session_get_seat3, ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ sd_login_monitor_new ++ systemd ++ ++ ++ ++ Developer ++ Lennart ++ Poettering ++ lennart@poettering.net ++ ++ ++ ++ ++ ++ sd_login_monitor_new ++ 3 ++ ++ ++ ++ sd_login_monitor_new ++ sd_login_monitor_unref ++ sd_login_monitor_flush ++ sd_login_monitor_get_fd ++ Monitor login sessions, seats and users ++ ++ ++ ++ ++ #include <systemd/sd-login.h> ++ ++ ++ int sd_login_monitor_new ++ const char* category ++ sd_login_monitor** ret ++ ++ ++ ++ sd_login_monitor* sd_login_monitor_unref ++ sd_login_monitor* m ++ ++ ++ ++ int sd_login_monitor_flush ++ sd_login_monitor* m ++ ++ ++ ++ int sd_login_monitor_get_fd ++ sd_login_monitor* m ++ ++ ++ ++ ++ ++ ++ Description ++ ++ sd_login_monitor_new() 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 seat (to get ++ only notifications about seats being added, removed or ++ changed), session (to get only ++ notifications about sessions being created or removed ++ or changed) or uid (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 ++ sd_login_monitor_unref() call ++ after use. ++ ++ sd_login_monitor_unref() ++ may be used to destroy a monitor object. Note that ++ this will invalidate any file descriptor returned by ++ sd_login_monitor_get_fd(). ++ ++ sd_login_monitor_flush() ++ 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. ++ ++ sd_login_monitor_get_fd() ++ may be used to retrieve the file descriptor of the ++ monitor object that may be integrated in an ++ application defined event loop, based around ++ poll2 ++ 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 ++ sd_login_monitor_flush(). An ++ application needs to reread the login state with a ++ function like ++ sd_get_seats3 ++ or similar to determine what changed. ++ ++ ++ ++ Return Value ++ ++ On success ++ sd_login_monitor_new() and ++ sd_login_monitor_flush() return 0 ++ or a positive integer. On success ++ sd_login_monitor_get_fd() returns ++ a Unix file descriptor. On failure, these calls return ++ a negative errno-style error code. ++ ++ sd_login_monitor_unref() ++ always returns NULL. ++ ++ ++ ++ Notes ++ ++ The sd_login_monitor_new(), ++ sd_login_monitor_unref(), sd_login_monitor_flush() and ++ sd_login_monitor_get_fd() interfaces ++ are available as shared library, which can be compiled ++ and linked to with the ++ libsystemd-login ++ pkg-config1 ++ file. ++ ++ ++ ++ See Also ++ ++ ++ systemd1, ++ sd-login7, ++ sd_get_seats3, ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ sd_pid_get_session ++ systemd ++ ++ ++ ++ Developer ++ Lennart ++ Poettering ++ lennart@poettering.net ++ ++ ++ ++ ++ ++ sd_pid_get_session ++ 3 ++ ++ ++ ++ sd_pid_get_session ++ sd_pid_get_owner_uid ++ Determine session or owner of a session of a specific PID ++ ++ ++ ++ ++ #include <systemd/sd-login.h> ++ ++ ++ int sd_pid_get_session ++ pid_t pid ++ char** session ++ ++ ++ ++ int sd_pid_get_owner_uid ++ pid_t pid ++ uid_t* uid ++ ++ ++ ++ ++ ++ Description ++ ++ sd_pid_get_session() 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 ++ free3 ++ call after use. ++ ++ sd_pid_get_owner_uid() 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 ++ sd_pid_get_session() will ++ fail. For processes not being part of a login session ++ and not being a shared process of a user this function ++ will fail. ++ ++ ++ ++ Return Value ++ ++ On success these calls return 0 or a positive ++ integer. On failure, these calls return a negative ++ errno-style error code. ++ ++ ++ ++ Notes ++ ++ The sd_pid_get_session() ++ and sd_pid_get_owner_uid() ++ interfaces are available as shared library, which can ++ be compiled and linked to with the ++ libsystemd-login ++ pkg-config1 ++ file. ++ ++ Note that the login session identifier as ++ returned by sd_pid_get_session() ++ is completely unrelated to the process session ++ identifier as returned by ++ getsid2. ++ ++ ++ ++ See Also ++ ++ ++ systemd1, ++ sd-login7, ++ sd_session_is_active3, ++ getsid2 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ sd_seat_get_active ++ systemd ++ ++ ++ ++ Developer ++ Lennart ++ Poettering ++ lennart@poettering.net ++ ++ ++ ++ ++ ++ sd_seat_get_active ++ 3 ++ ++ ++ ++ sd_seat_get_active ++ sd_seat_get_sessions ++ sd_seat_can_multi_session ++ Determine state of a specific seat ++ ++ ++ ++ ++ #include <systemd/sd-login.h> ++ ++ ++ int sd_seat_get_active ++ const char* seat ++ char** session ++ uid_t* uid ++ ++ ++ ++ int sd_seat_get_sessions ++ const char* seat ++ char*** sessions ++ uid_t** uid ++ unsigned* n_uids ++ ++ ++ ++ int sd_seat_can_multi_session ++ const char* session ++ ++ ++ ++ ++ ++ Description ++ ++ sd_seat_get_active() 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 ++ free3 ++ call after use. ++ ++ sd_seat_get_sessions() 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 ++ free3 ++ call after use. ++ ++ sd_seat_can_multi_session() ++ 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). ++ ++ ++ ++ Return Value ++ ++ On success ++ sd_seat_get_active() return ++ return 0 or a positive integer. On success ++ sd_seat_get_sessions() returns ++ the number of entries in the session identifier ++ array. If the test succeeds ++ sd_seat_can_multi_session returns ++ a positive integer, if it fails 0. On failure, these ++ calls return a negative errno-style error code. ++ ++ ++ ++ Notes ++ ++ The sd_seat_get_active(), ++ sd_seat_get_sessions(), and ++ sd_seat_can_multi_session() interfaces ++ are available as shared library, which can be compiled ++ and linked to with the ++ libsystemd-login ++ pkg-config1 ++ file. ++ ++ ++ ++ See Also ++ ++ ++ systemd1, ++ sd-login7, ++ sd_session_get_seat3, ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ sd_session_is_active ++ systemd ++ ++ ++ ++ Developer ++ Lennart ++ Poettering ++ lennart@poettering.net ++ ++ ++ ++ ++ ++ sd_session_is_active ++ 3 ++ ++ ++ ++ sd_session_is_active ++ sd_session_get_uid ++ sd_session_get_seat ++ Determine state of a specific session ++ ++ ++ ++ ++ #include <systemd/sd-login.h> ++ ++ ++ int sd_session_is_active ++ const char* session ++ ++ ++ ++ int sd_session_get_uid ++ const char* session ++ uid_t* uid ++ ++ ++ ++ int sd_session_get_seat ++ const char* session ++ char** seat ++ ++ ++ ++ ++ ++ Description ++ ++ sd_session_is_active() 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. ++ ++ sd_session_get_uid() may be ++ used to determine the user identifier of the Unix user the session ++ identified by the specified session identifier belongs ++ to. ++ ++ sd_session_get_seat() 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 ++ free3 ++ call after use. ++ ++ ++ ++ Return Value ++ ++ If the test succeeds ++ sd_session_is_active() returns a ++ positive integer, if it fails 0. On success ++ sd_session_get_uid() and ++ sd_session_get_seat() return 0 or ++ a positive integer. On failure, these calls return a ++ negative errno-style error code. ++ ++ ++ ++ Notes ++ ++ The sd_session_is_active(), ++ sd_session_get_uid(), and ++ sd_session_get_seat() interfaces ++ are available as shared library, which can be compiled ++ and linked to with the ++ libsystemd-login ++ pkg-config1 ++ file. ++ ++ ++ ++ See Also ++ ++ ++ systemd1, ++ sd-login7, ++ sd_pid_get_session3, ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ sd_uid_get_state ++ systemd ++ ++ ++ ++ Developer ++ Lennart ++ Poettering ++ lennart@poettering.net ++ ++ ++ ++ ++ ++ sd_uid_get_state ++ 3 ++ ++ ++ ++ sd_uid_get_state ++ sd_uid_is_on_seat ++ sd_uid_get_sessions ++ sd_uid_get_seats ++ Determine login state of a specific Unix user ID ++ ++ ++ ++ ++ #include <systemd/sd-login.h> ++ ++ ++ int sd_uid_get_state ++ uid_t pid ++ char** state ++ ++ ++ ++ int sd_uid_is_on_seat ++ uid_t pid ++ int require_active ++ const char* seat ++ ++ ++ ++ int sd_uid_get_sessions ++ uid_t pid ++ int require_active ++ char*** sessions ++ ++ ++ ++ int sd_uid_get_seats ++ uid_t pid ++ int require_active ++ char*** seats ++ ++ ++ ++ ++ ++ Description ++ ++ sd_uid_get_state() may be ++ used to determine the login state of a specific Unix ++ user identifier. The following states are currently ++ known: offline (user not logged in ++ at all), lingering (user not logged ++ in, but some user services running), ++ online (user logged in, but not ++ active), active (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 ++ free3 ++ call after use. ++ ++ sd_uid_is_on_seat() 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 require_active ++ 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. ++ ++ sd_uid_get_sessions() may ++ be used to determine the current sessions of the ++ specified user. Acceptes a Unix user identifier as ++ parameter. The require_active ++ 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 sessions which ++ needs to be freed by the caller with the libc ++ free3 ++ 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. ++ ++ Similar, sd_uid_get_seats() ++ 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 sd_uid_get_sessions(). ++ ++ ++ ++ Return Value ++ ++ On success ++ sd_uid_get_state() returns 0 or a ++ positive integer. If the test succeeds ++ sd_uid_is_on_seat() returns a ++ positive integer, if it fails ++ 0. sd_uid_get_sessions() and ++ sd_uid_get_seats() return the ++ number of entries in the returned arrays. On failure, ++ these calls return a negative errno-style error ++ code. ++ ++ ++ ++ Notes ++ ++ The sd_uid_get_state(), ++ sd_uid_is_on_seat(), ++ sd_uid_get_sessions(), and ++ sd_uid_get_seats() interfaces are ++ available as shared library, which can be compiled and ++ linked to with the libsystemd-login ++ pkg-config1 ++ file. ++ ++ ++ ++ See Also ++ ++ ++ systemd1, ++ sd-login7, ++ sd_pid_get_owner_uid3, ++ ++ ++ ++ +-- +1.7.7.5 + diff --git a/0090-sd-daemon-fix-include-lines-since-we-now-ship-a-shar.patch b/0090-sd-daemon-fix-include-lines-since-we-now-ship-a-shar.patch new file mode 100644 index 0000000..70016f5 --- /dev/null +++ b/0090-sd-daemon-fix-include-lines-since-we-now-ship-a-shar.patch @@ -0,0 +1,83 @@ +From 76c801950d0f596ba7804088a838ecc8d8dc9d5e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Dec 2011 13:11:42 +0100 +Subject: [PATCH 090/126] 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 @@ + + + +- #include "sd-daemon.h" ++ #include <systemd/sd-daemon.h> + + + +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 @@ + + + +- #include "sd-daemon.h" ++ #include <systemd/sd-daemon.h> + + + int sd_booted +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 @@ + + + +- #include "sd-daemon.h" ++ #include <systemd/sd-daemon.h> + + + int sd_is_fifo +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 @@ + + + +- #include "sd-daemon.h" ++ #include <systemd/sd-daemon.h> + + #define SD_LISTEN_FDS_START 3 + +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 @@ + + + +- #include "sd-daemon.h" ++ #include <systemd/sd-daemon.h> + + + int sd_notify +-- +1.7.7.5 + diff --git a/0091-man-build-new-man-pages.patch b/0091-man-build-new-man-pages.patch new file mode 100644 index 0000000..9b34473 --- /dev/null +++ b/0091-man-build-new-man-pages.patch @@ -0,0 +1,30 @@ +From 271f93368eee2784ad360fe6cfed0b684f4a1032 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Dec 2011 13:12:36 +0100 +Subject: [PATCH 091/126] 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 +-- +1.7.7.5 + diff --git a/0092-man-sd_readahead-is-not-actually-available-in-libsys.patch b/0092-man-sd_readahead-is-not-actually-available-in-libsys.patch new file mode 100644 index 0000000..7b9b21e --- /dev/null +++ b/0092-man-sd_readahead-is-not-actually-available-in-libsys.patch @@ -0,0 +1,61 @@ +From d5956203ad4ed4f8183685c65cc323ae8f927820 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Dec 2011 13:19:01 +0100 +Subject: [PATCH 092/126] 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 @@ + + + +- #include "sd-daemon.h" ++ #include "sd-readahead.h" + + + int sd_readahead +@@ -134,23 +134,17 @@ + url="http://cgit.freedesktop.org/systemd/tree/src/sd-readahead.h"/> + + sd_readahead() is +- implemented in the reference implementation's ++ implemented in the reference implementation's drop-in + sd-readahead.c and +- sd-readahead.h files. These +- interfaces are available as shared library, which can +- be compiled and linked to with the +- libsystemd-daemon +- pkg-config1 +- file. Alternatively, applications consuming this API +- may copy the implementation into their source +- tree. For more details about the reference +- implementation see +- sd-readahead7. +- +- 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. ++ sd-readahead.h files. It is ++ recommended that applications consuming this API copy ++ the implementation into their source tree. For more ++ details about the reference implementation see ++ sd-readahead7 ++ ++ If -DDISABLE_SYSTEMD is set during compilation ++ this function will always return 0 and otherwise ++ become a NOP. + + + +-- +1.7.7.5 + diff --git a/0093-build-sys-add-rules-for-man-page-aliases.patch b/0093-build-sys-add-rules-for-man-page-aliases.patch new file mode 100644 index 0000000..419b1e8 --- /dev/null +++ b/0093-build-sys-add-rules-for-man-page-aliases.patch @@ -0,0 +1,41 @@ +From 741e7c477da184725f18f928fed7174d97732419 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Dec 2011 13:25:00 +0100 +Subject: [PATCH 093/126] 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) \ +-- +1.7.7.5 + diff --git a/0094-man-add-sd-login-7-page.patch b/0094-man-add-sd-login-7-page.patch new file mode 100644 index 0000000..cceb45b --- /dev/null +++ b/0094-man-add-sd-login-7-page.patch @@ -0,0 +1,226 @@ +From 362fa48aecfac175e3601d4075bbc1eb18684625 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Dec 2011 13:57:07 +0100 +Subject: [PATCH 094/126] 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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ sd-login ++ systemd ++ ++ ++ ++ Developer ++ Lennart ++ Poettering ++ lennart@poettering.net ++ ++ ++ ++ ++ ++ sd-login ++ 7 ++ ++ ++ ++ sd-login ++ APIs for ++ tracking logins ++ ++ ++ ++ ++ #include <systemd/sd-login.h> ++ ++ ++ ++ pkg-config --cflags --libs libsystemd-login ++ ++ ++ ++ ++ Description ++ ++ sd-login.h provides APIs to ++ introspect and monitor seat, login session and user ++ status information on the local system. ++ ++ See Multi-Seat ++ on Linux for an introduction into multi-seat ++ support on Linux, the background for this set of APIs. ++ ++ 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. ++ ++ See ++ sd_pid_get_session3, ++ sd_uid_get_state3, ++ sd_session_is_active3, ++ sd_seat_get_active3, ++ sd_get_seats3, ++ sd_login_monitor_new3 ++ for more information about the functions ++ implemented. ++ ++ ++ ++ Notes ++ ++ These APIs are implemented as shared library, ++ which can be compiled and linked to with the ++ libsystemd-login ++ pkg-config1 ++ file. ++ ++ ++ ++ See Also ++ ++ systemd1, ++ sd_pid_get_session3, ++ sd_uid_get_state3, ++ sd_session_is_active3, ++ sd_seat_get_active3, ++ sd_get_seats3, ++ sd_login_monitor_new3, ++ sd-daemon7, ++ sd-readahead7, ++ pkg-config1 ++ ++ ++ ++ +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 @@ + + sd_pid_get_session() 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 + free3 + call after use. + +-- +1.7.7.5 + diff --git a/0095-man-various-updates.patch b/0095-man-various-updates.patch new file mode 100644 index 0000000..df85563 --- /dev/null +++ b/0095-man-various-updates.patch @@ -0,0 +1,162 @@ +From 550fab31953acced44a6e7b2acc050b8270dd558 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Dec 2011 14:42:59 +0100 +Subject: [PATCH 095/126] 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. ++ systemd-logind, instead. ++ ++ These functions access data in ++ /proc, ++ /sys/fs/cgroup and ++ /run. All of these are virtual ++ file systems, hence the runtime cost of the accesses ++ is relatively cheap. ++ ++ If the functions return string arrays, these are ++ generally NULL terminated and need to be freed by the ++ caller with the libc ++ free3 ++ call after use, including the strings referenced ++ therein. Similar, individual strings returned need to ++ be freed, as well. ++ ++ As a special exception, instead of an empty ++ string array NULL may be returned, which should be ++ treated equivalent to an empty string array. + + See + sd_pid_get_session3, +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 @@ + + sd_get_seats() 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 + free3 +- call after use. ++ call after use. Note that instead of an empty array ++ NULL may be returned and should be considered ++ equivalent to an empty array. + + Similar, sd_get_sessions() may + be used to determine all current login sessions. +@@ -118,7 +120,7 @@ + + systemd1, + sd-login7, +- sd_session_get_seat3, ++ sd_session_get_seat3 + + + +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 @@ + + systemd1, + sd-login7, +- sd_get_seats3, ++ sd_get_seats3 + + + +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 + free3 +- call after use. ++ call after use. Note that instead of an empty array ++ NULL may be returned and should be considered ++ equivalent to an empty array. + + sd_seat_can_multi_session() + may be used to determine whether a specific seat is +@@ -143,7 +145,7 @@ + + systemd1, + sd-login7, +- sd_session_get_seat3, ++ sd_session_get_seat3 + + + +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 @@ + + systemd1, + sd-login7, +- sd_pid_get_session3, ++ sd_pid_get_session3 + + + +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 sessions which + needs to be freed by the caller with the libc + free3 +- 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. ++ 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. + + Similar, sd_uid_get_seats() + may be used to determine the list of seats on which +@@ -175,7 +178,7 @@ + + systemd1, + sd-login7, +- sd_pid_get_owner_uid3, ++ sd_pid_get_owner_uid3 + + + +-- +1.7.7.5 + diff --git a/0096-man-extend-sd-login-7-in-regards-to-mixing-D-Bus-and.patch b/0096-man-extend-sd-login-7-in-regards-to-mixing-D-Bus-and.patch new file mode 100644 index 0000000..93b724b --- /dev/null +++ b/0096-man-extend-sd-login-7-in-regards-to-mixing-D-Bus-and.patch @@ -0,0 +1,44 @@ +From d54ac9394336db0564b3bca712d43042486dacc1 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Dec 2011 17:40:31 +0100 +Subject: [PATCH 096/126] 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. + +- These functions access data in ++ These functions synchronously access data in + /proc, + /sys/fs/cgroup and + /run. All of these are virtual + file systems, hence the runtime cost of the accesses + is relatively cheap. + ++ It is possible (and often a very good choice) to ++ mix calls to the synchronous interface of ++ sd-login.h 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 ++ sd-login.h interfaces such as the ++ login monitor are asynchronous and not ordered against ++ each other. ++ + If the functions return string arrays, these are + generally NULL terminated and need to be freed by the + caller with the libc +-- +1.7.7.5 + diff --git a/0097-man-generate-HTML-instead-of-XHTML-with-XSL-docbook-.patch b/0097-man-generate-HTML-instead-of-XHTML-with-XSL-docbook-.patch new file mode 100644 index 0000000..affe3b4 --- /dev/null +++ b/0097-man-generate-HTML-instead-of-XHTML-with-XSL-docbook-.patch @@ -0,0 +1,32 @@ +From d522760b761ddb9e92eb068c656c68ed60bdb50e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Dec 2011 19:55:54 +0100 +Subject: [PATCH 097/126] 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 +-- +1.7.7.5 + diff --git a/0098-man-switch-to-UTF-8-output-to-work-around-charset-is.patch b/0098-man-switch-to-UTF-8-output-to-work-around-charset-is.patch new file mode 100644 index 0000000..86ff000 --- /dev/null +++ b/0098-man-switch-to-UTF-8-output-to-work-around-charset-is.patch @@ -0,0 +1,88 @@ +From 1b6836c15717a62ef81cef8e9617fc7df6c7e605 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Dec 2011 20:25:52 +0100 +Subject: [PATCH 098/126] 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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.7.7.5 + diff --git a/0099-udev-exclude-loopback-device-from-udev-rule-based-sy.patch b/0099-udev-exclude-loopback-device-from-udev-rule-based-sy.patch new file mode 100644 index 0000000..5667b45 --- /dev/null +++ b/0099-udev-exclude-loopback-device-from-udev-rule-based-sy.patch @@ -0,0 +1,28 @@ +From 988a59b65bcf86ed1cdf9fefb5a2ac7c16536c1b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 27 Dec 2011 22:52:15 +0100 +Subject: [PATCH 099/126] 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. +-- +1.7.7.5 + diff --git a/0100-remount-api-vfs-handle-another-OOM-condition.patch b/0100-remount-api-vfs-handle-another-OOM-condition.patch new file mode 100644 index 0000000..033692b --- /dev/null +++ b/0100-remount-api-vfs-handle-another-OOM-condition.patch @@ -0,0 +1,75 @@ +From ae1e1f08b63b11eee857598076dbc5aaa9020032 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 30 Dec 2011 15:34:21 +0100 +Subject: [PATCH 100/126] remount-api-vfs: handle another OOM condition + (cherry picked from commit + adb2ce5f694cb528f9294219941b1e37dc6a9530) + +--- + src/remount-api-vfs.c | 23 +++++++++++++++++------ + 1 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/src/remount-api-vfs.c b/src/remount-api-vfs.c +index 8bbc021..7b14655 100644 +--- a/src/remount-api-vfs.c ++++ b/src/remount-api-vfs.c +@@ -54,12 +54,14 @@ int main(int argc, char *argv[]) { + + umask(0022); + +- if (!(f = setmntent("/etc/fstab", "r"))) { ++ f = setmntent("/etc/fstab", "r"); ++ if (!f) { + log_error("Failed to open /etc/fstab: %m"); + goto finish; + } + +- if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) { ++ pids = hashmap_new(trivial_hash_func, trivial_compare_func); ++ if (!pids) { + log_error("Failed to allocate set"); + goto finish; + } +@@ -76,9 +78,10 @@ int main(int argc, char *argv[]) { + + log_debug("Remounting %s", me->mnt_dir); + +- if ((pid = fork()) < 0) { ++ pid = fork(); ++ if (pid < 0) { + log_error("Failed to fork: %m"); +- ret = 1; ++ ret = EXIT_FAILURE; + continue; + } + +@@ -101,8 +104,15 @@ int main(int argc, char *argv[]) { + /* Parent */ + + s = strdup(me->mnt_dir); ++ if (!s) { ++ log_error("Out of memory."); ++ ret = EXIT_FAILURE; ++ continue; ++ } ++ + +- if ((k = hashmap_put(pids, UINT_TO_PTR(pid), s)) < 0) { ++ k = hashmap_put(pids, UINT_TO_PTR(pid), s); ++ if (k < 0) { + log_error("Failed to add PID to set: %s", strerror(-k)); + ret = EXIT_FAILURE; + continue; +@@ -124,7 +134,8 @@ int main(int argc, char *argv[]) { + break; + } + +- if ((s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) { ++ s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)); ++ if (s) { + if (!is_clean_exit(si.si_code, si.si_status)) { + if (si.si_code == CLD_EXITED) + log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status); +-- +1.7.7.5 + diff --git a/0101-socket-rename-the-PassCred-option-to-PassCredentials.patch b/0101-socket-rename-the-PassCred-option-to-PassCredentials.patch new file mode 100644 index 0000000..2e8cfce --- /dev/null +++ b/0101-socket-rename-the-PassCred-option-to-PassCredentials.patch @@ -0,0 +1,129 @@ +From 0e984106a89ac1732a5200f7b3180454a6c3ad15 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sat, 31 Dec 2011 01:07:49 +0100 +Subject: [PATCH 101/126] socket: rename the PassCred= option to + PassCredentials=, since we don't want to needlessly + abbreviate options unless they are very well + established (cherry picked from commit + 271b032a053f9d4a1be271bb052276ae27fe36c6) + +Conflicts: + + units/systemd-journald.socket +--- + man/systemd.socket.xml | 8 ++++---- + src/dbus-socket.c | 4 ++-- + src/load-fragment-gperf.gperf.m4 | 2 +- + src/socket.c | 2 +- + units/syslog.socket | 2 +- + units/systemd-shutdownd.socket | 2 +- + 6 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml +index f883543..ef5b28c 100644 +--- a/man/systemd.socket.xml ++++ b/man/systemd.socket.xml +@@ -510,7 +510,7 @@ + Transparent= + Takes a boolean + value. Controls the IP_TRANSPARENT +- option. Defaults to ++ socket option. Defaults to + . + + +@@ -518,17 +518,17 @@ + Broadcast= + Takes a boolean + value. This controls the SO_BROADCAST +- option, which allows broadcast ++ socket option, which allows broadcast + datagrams to be sent from this + socket. Defaults to + . + + + +- PassCred= ++ PassCredentials= + Takes a boolean + value. This controls the SO_PASSCRED +- option, which allows UNIX sockets to ++ socket option, which allows UNIX sockets to + receive the credentials of the sending + process in an ancillary message. + Defaults to +diff --git a/src/dbus-socket.c b/src/dbus-socket.c +index 37ab7eb..c428189 100644 +--- a/src/dbus-socket.c ++++ b/src/dbus-socket.c +@@ -51,7 +51,7 @@ + " \n" \ + " \n" \ + " \n" \ +- " \n" \ ++ " \n" \ + " \n" \ + " \n" \ + " \n" \ +@@ -114,7 +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", "PassCredentials",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 35ec005..81e186c 100644 +--- a/src/load-fragment-gperf.gperf.m4 ++++ b/src/load-fragment-gperf.gperf.m4 +@@ -177,7 +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.PassCredentials, 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 0864cce..bbfc842 100644 +--- a/src/socket.c ++++ b/src/socket.c +@@ -406,7 +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" ++ "%sPassCrededentials: %s\n" + "%sTCPCongestion: %s\n", + prefix, socket_state_to_string(s->state), + prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only), +diff --git a/units/syslog.socket b/units/syslog.socket +index e74b559..ccf79fe 100644 +--- a/units/syslog.socket ++++ b/units/syslog.socket +@@ -18,7 +18,7 @@ Wants=syslog.target + [Socket] + ListenDatagram=/dev/log + SocketMode=0666 +-PassCred=yes ++PassCredentials=yes + + # The service we activate on incoming traffic is + # systemd-kmsg-syslogd.service. That doesn't mean however, that this +diff --git a/units/systemd-shutdownd.socket b/units/systemd-shutdownd.socket +index 13b6c7a..532a6f0 100644 +--- a/units/systemd-shutdownd.socket ++++ b/units/systemd-shutdownd.socket +@@ -15,4 +15,4 @@ Before=sockets.target + [Socket] + ListenDatagram=/run/systemd/shutdownd + SocketMode=0600 +-PassCred=yes ++PassCredentials=yes +-- +1.7.7.5 + diff --git a/0102-socket-only-add-dependency-on-kmsg-socket-to-socket-.patch b/0102-socket-only-add-dependency-on-kmsg-socket-to-socket-.patch new file mode 100644 index 0000000..0364d00 --- /dev/null +++ b/0102-socket-only-add-dependency-on-kmsg-socket-to-socket-.patch @@ -0,0 +1,49 @@ +From faa9db1ad2fe229ba90b7d75e104ead6614ea813 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 3 Jan 2012 20:33:28 +0100 +Subject: [PATCH 102/126] socket: only add dependency on kmsg socket to socket + units which have any kind of exec program specified + (cherry picked from commit + 4cfc6dbe52e4ff867750ce0d64f09d42c0ea6c27) + +--- + src/socket.c | 16 ++++++++++++++-- + 1 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/src/socket.c b/src/socket.c +index bbfc842..1f5e067 100644 +--- a/src/socket.c ++++ b/src/socket.c +@@ -323,6 +323,17 @@ static int socket_add_default_dependencies(Socket *s) { + return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); + } + ++static bool socket_has_exec(Socket *s) { ++ unsigned i; ++ assert(s); ++ ++ for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++) ++ if (s->exec_command[i]) ++ return true; ++ ++ return false; ++} ++ + static int socket_load(Unit *u) { + Socket *s = SOCKET(u); + int r; +@@ -352,8 +363,9 @@ static int socket_load(Unit *u) { + if ((r = socket_add_device_link(s)) < 0) + return r; + +- if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0) +- return r; ++ if (socket_has_exec(s)) ++ if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0) ++ return r; + + if ((r = unit_add_default_cgroups(u)) < 0) + return r; +-- +1.7.7.5 + diff --git a/0103-readahead-bring-export-definition-of-sd-readahead-in.patch b/0103-readahead-bring-export-definition-of-sd-readahead-in.patch new file mode 100644 index 0000000..afa8eea --- /dev/null +++ b/0103-readahead-bring-export-definition-of-sd-readahead-in.patch @@ -0,0 +1,75 @@ +From 24954dcfd60261600c04ffdfc9cd0b1980a4b7d3 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 3 Jan 2012 20:34:09 +0100 +Subject: [PATCH 103/126] readahead: bring export definition of sd-readahead + in line with sd-daemon (cherry picked from commit + 4f3656e1cec7fe3d7d3537e23a406cb88d734502) + +--- + src/sd-readahead.c | 14 +++++++++++++- + src/sd-readahead.h | 10 +--------- + 2 files changed, 14 insertions(+), 10 deletions(-) + +diff --git a/src/sd-readahead.c b/src/sd-readahead.c +index c5cfe67..a334066 100644 +--- a/src/sd-readahead.c ++++ b/src/sd-readahead.c +@@ -37,6 +37,18 @@ + + #include "sd-readahead.h" + ++#if (__GNUC__ >= 4) ++#ifdef SD_EXPORT_SYMBOLS ++/* Export symbols */ ++#define _sd_export_ __attribute__ ((visibility("default"))) ++#else ++/* Don't export the symbols */ ++#define _sd_export_ __attribute__ ((visibility("hidden"))) ++#endif ++#else ++#define _sd_export_ ++#endif ++ + static int touch(const char *path) { + + #if !defined(DISABLE_SYSTEMD) && defined(__linux__) +@@ -60,7 +72,7 @@ static int touch(const char *path) { + return 0; + } + +-int sd_readahead(const char *action) { ++_sd_export_ int sd_readahead(const char *action) { + + if (!action) + return -EINVAL; +diff --git a/src/sd-readahead.h b/src/sd-readahead.h +index 5bf975a..ee7e306 100644 +--- a/src/sd-readahead.h ++++ b/src/sd-readahead.h +@@ -56,14 +56,6 @@ extern "C" { + See sd-readahead(7) for more information. + */ + +-#ifndef _sd_hidden_ +-#if (__GNUC__ >= 4) && !defined(SD_EXPORT_SYMBOLS) +-#define _sd_hidden_ __attribute__ ((visibility("hidden"))) +-#else +-#define _sd_hidden_ +-#endif +-#endif +- + /* + Controls ongoing disk read-ahead operations during boot-up. The argument + must be a string, and either "cancel", "done" or "noreplay". +@@ -72,7 +64,7 @@ extern "C" { + done = terminate read-ahead data collection, keep collected information + noreplay = terminate read-ahead replay + */ +-int sd_readahead(const char *action) _sd_hidden_; ++int sd_readahead(const char *action); + + #ifdef __cplusplus + } +-- +1.7.7.5 + diff --git a/0104-nspawn-get-rid-of-BUFFER_SIZE-use-LINE_MAX-instead.patch b/0104-nspawn-get-rid-of-BUFFER_SIZE-use-LINE_MAX-instead.patch new file mode 100644 index 0000000..743a613 --- /dev/null +++ b/0104-nspawn-get-rid-of-BUFFER_SIZE-use-LINE_MAX-instead.patch @@ -0,0 +1,55 @@ +From 79dbd0ccda06dc6b9d1a6a8a04a214895b0d91e8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 3 Jan 2012 20:41:20 +0100 +Subject: [PATCH 104/126] nspawn: get rid of BUFFER_SIZE, use LINE_MAX instead + (cherry picked from commit + b72491a2fd8c237299055c636d4f748bca2b4b1f) + +--- + src/nspawn.c | 12 +++++------- + 1 files changed, 5 insertions(+), 7 deletions(-) + +diff --git a/src/nspawn.c b/src/nspawn.c +index 653d7db..3ea603f 100644 +--- a/src/nspawn.c ++++ b/src/nspawn.c +@@ -394,11 +394,9 @@ static int is_os_tree(const char *path) { + return r < 0 ? 0 : 1; + } + +-#define BUFFER_SIZE 1024 +- + static int process_pty(int master, sigset_t *mask) { + +- char in_buffer[BUFFER_SIZE], out_buffer[BUFFER_SIZE]; ++ char in_buffer[LINE_MAX], out_buffer[LINE_MAX]; + size_t in_buffer_full = 0, out_buffer_full = 0; + struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev; + bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false; +@@ -519,9 +517,9 @@ static int process_pty(int master, sigset_t *mask) { + (master_readable && out_buffer_full <= 0) || + (stdout_writable && out_buffer_full > 0)) { + +- if (stdin_readable && in_buffer_full < BUFFER_SIZE) { ++ if (stdin_readable && in_buffer_full < LINE_MAX) { + +- if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, BUFFER_SIZE - in_buffer_full)) < 0) { ++ if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, LINE_MAX - in_buffer_full)) < 0) { + + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) + stdin_readable = false; +@@ -553,9 +551,9 @@ static int process_pty(int master, sigset_t *mask) { + } + } + +- if (master_readable && out_buffer_full < BUFFER_SIZE) { ++ if (master_readable && out_buffer_full < LINE_MAX) { + +- if ((k = read(master, out_buffer + out_buffer_full, BUFFER_SIZE - out_buffer_full)) < 0) { ++ if ((k = read(master, out_buffer + out_buffer_full, LINE_MAX - out_buffer_full)) < 0) { + + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) + master_readable = false; +-- +1.7.7.5 + diff --git a/0105-namespace-remount-namespace-root-dir-for-SLAVE-to-av.patch b/0105-namespace-remount-namespace-root-dir-for-SLAVE-to-av.patch new file mode 100644 index 0000000..6200515 --- /dev/null +++ b/0105-namespace-remount-namespace-root-dir-for-SLAVE-to-av.patch @@ -0,0 +1,35 @@ +From 4cecfa6c03410e72e42b520575613c4f30253bef Mon Sep 17 00:00:00 2001 +From: Daniel Walsh +Date: Tue, 3 Jan 2012 21:12:10 +0100 +Subject: [PATCH 105/126] namespace: remount namespace root dir for SLAVE to + avoid propagation of mounts from the namespace to + the host + +https://bugzilla.redhat.com/show_bug.cgi?id=752540 +(cherry picked from commit dc4b02006455a4dddeb6ccc1f6656c89d3ebd27c) +--- + src/namespace.c | 8 ++++++-- + 1 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/namespace.c b/src/namespace.c +index 54b22f4..a06cac1 100644 +--- a/src/namespace.c ++++ b/src/namespace.c +@@ -266,8 +266,12 @@ int setup_namespace( + goto fail; + } + +- /* We assume that by default mount events from us won't be +- * propagated to the root namespace. */ ++ /* Remount / as SLAVE so that nothing mounted in the namespace ++ shows up in the parent */ ++ if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) { ++ r = -errno; ++ goto fail; ++ } + + for (p = paths; p < paths + n; p++) + if ((r = apply_mount(p, root_dir, inaccessible_dir, private_dir, flags)) < 0) +-- +1.7.7.5 + diff --git a/0106-logind-if-we-can-t-open-dev-tty0-assume-there-is-no-.patch b/0106-logind-if-we-can-t-open-dev-tty0-assume-there-is-no-.patch new file mode 100644 index 0000000..477f467 --- /dev/null +++ b/0106-logind-if-we-can-t-open-dev-tty0-assume-there-is-no-.patch @@ -0,0 +1,200 @@ +From c190c0e59e4dfa52a523a220a82b94b3bbfd3ad9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 3 Jan 2012 21:47:54 +0100 +Subject: [PATCH 106/126] logind: if we can't open /dev/tty0, assume there is + no VT subsystem and don't pretend we could do VT + switching (cherry picked from commit + addedec48ba0ffc4472ef6d3b5a45c9d4239f1cd) + +--- + src/logind-dbus.c | 2 +- + src/logind-seat-dbus.c | 2 +- + src/logind-seat.c | 28 +++++++++++++++++++++------- + src/logind-seat.h | 1 + + src/logind-session.c | 4 ++-- + src/logind.c | 7 ++++++- + src/sd-login.c | 2 +- + 7 files changed, 33 insertions(+), 13 deletions(-) + +diff --git a/src/logind-dbus.c b/src/logind-dbus.c +index 0550d1b..efbc040 100644 +--- a/src/logind-dbus.c ++++ b/src/logind-dbus.c +@@ -301,7 +301,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess + return -EINVAL; + + if (s) { +- if (seat_is_vtconsole(s)) { ++ if (seat_can_multi_session(s)) { + if (vtnr <= 0 || vtnr > 63) + return -EINVAL; + } else { +diff --git a/src/logind-seat-dbus.c b/src/logind-seat-dbus.c +index 3a916ee..a15689b 100644 +--- a/src/logind-seat-dbus.c ++++ b/src/logind-seat-dbus.c +@@ -141,7 +141,7 @@ static int bus_seat_append_multi_session(DBusMessageIter *i, const char *propert + assert(property); + assert(s); + +- b = seat_is_vtconsole(s); ++ b = seat_can_multi_session(s); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; +diff --git a/src/logind-seat.c b/src/logind-seat.c +index 3cf3958..8c83a2c 100644 +--- a/src/logind-seat.c ++++ b/src/logind-seat.c +@@ -101,8 +101,10 @@ int seat_save(Seat *s) { + + fprintf(f, + "# This is private data. Do not parse.\n" +- "IS_VTCONSOLE=%i\n", +- seat_is_vtconsole(s)); ++ "IS_VTCONSOLE=%i\n" ++ "CAN_MULTI_SESSION=%i\n", ++ seat_is_vtconsole(s), ++ seat_can_multi_session(s)); + + if (s->active) { + assert(s->active->user); +@@ -191,7 +193,7 @@ int seat_preallocate_vts(Seat *s) { + if (s->manager->n_autovts <= 0) + return 0; + +- if (!seat_is_vtconsole(s)) ++ if (!seat_can_multi_session(s)) + return 0; + + for (i = 1; i <= s->manager->n_autovts; i++) { +@@ -266,7 +268,7 @@ int seat_active_vt_changed(Seat *s, int vtnr) { + assert(s); + assert(vtnr >= 1); + +- if (!seat_is_vtconsole(s)) ++ if (!seat_can_multi_session(s)) + return -EINVAL; + + log_debug("VT changed to %i", vtnr); +@@ -290,7 +292,7 @@ int seat_read_active_vt(Seat *s) { + + assert(s); + +- if (!seat_is_vtconsole(s)) ++ if (!seat_can_multi_session(s)) + return 0; + + lseek(s->manager->console_active_fd, SEEK_SET, 0); +@@ -388,7 +390,7 @@ int seat_attach_session(Seat *s, Session *session) { + assert(session); + assert(!session->seat); + +- if (!seat_is_vtconsole(s) && s->sessions) ++ if (!seat_can_multi_session(s) && s->sessions) + return -EEXIST; + + session->seat = s; +@@ -396,7 +398,7 @@ int seat_attach_session(Seat *s, Session *session) { + + seat_send_changed(s, "Sessions\0"); + +- if (!seat_is_vtconsole(s)) { ++ if (!seat_can_multi_session(s)) { + assert(!s->active); + seat_set_active(s, session); + } +@@ -410,6 +412,18 @@ bool seat_is_vtconsole(Seat *s) { + return s->manager->vtconsole == s; + } + ++bool seat_can_multi_session(Seat *s) { ++ assert(s); ++ ++ if (!seat_is_vtconsole(s)) ++ return false; ++ ++ /* If we can't watch which VT is in the foreground, we don't ++ * support VT switching */ ++ ++ return s->manager->console_active_fd >= 0; ++} ++ + int seat_get_idle_hint(Seat *s, dual_timestamp *t) { + Session *session; + bool idle_hint = true; +diff --git a/src/logind-seat.h b/src/logind-seat.h +index 5bce143..3b2c7f0 100644 +--- a/src/logind-seat.h ++++ b/src/logind-seat.h +@@ -62,6 +62,7 @@ int seat_preallocate_vts(Seat *s); + int seat_attach_session(Seat *s, Session *session); + + bool seat_is_vtconsole(Seat *s); ++bool seat_can_multi_session(Seat *s); + int seat_get_idle_hint(Seat *s, dual_timestamp *t); + + int seat_start(Seat *s); +diff --git a/src/logind-session.c b/src/logind-session.c +index 63ee758..58c70c3 100644 +--- a/src/logind-session.c ++++ b/src/logind-session.c +@@ -185,7 +185,7 @@ int session_save(Session *s) { + "SERVICE=%s\n", + s->service); + +- if (s->seat && seat_is_vtconsole(s->seat)) ++ if (s->seat && seat_can_multi_session(s->seat)) + fprintf(f, + "VTNR=%i\n", + s->vtnr); +@@ -270,7 +270,7 @@ int session_load(Session *s) { + seat_attach_session(o, s); + } + +- if (vtnr && s->seat && seat_is_vtconsole(s->seat)) { ++ if (vtnr && s->seat && seat_can_multi_session(s->seat)) { + int v; + + k = safe_atoi(vtnr, &v); +diff --git a/src/logind.c b/src/logind.c +index 4633a5e..3a1903c 100644 +--- a/src/logind.c ++++ b/src/logind.c +@@ -655,7 +655,6 @@ int manager_dispatch_seat_udev(Manager *m) { + return r; + } + +- + int manager_dispatch_vcsa_udev(Manager *m) { + struct udev_device *d; + int r = 0; +@@ -906,6 +905,12 @@ static int manager_connect_console(Manager *m) { + + m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (m->console_active_fd < 0) { ++ ++ /* On certain architectures (S390 and Xen), /dev/tty0 ++ does not exist, so don't fail if we can't open it.*/ ++ if (errno == ENOENT) ++ return 0; ++ + log_error("Failed to open /sys/class/tty/tty0/active: %m"); + return -errno; + } +diff --git a/src/sd-login.c b/src/sd-login.c +index a0a56c4..38a2ff7 100644 +--- a/src/sd-login.c ++++ b/src/sd-login.c +@@ -547,7 +547,7 @@ _public_ int sd_seat_can_multi_session(const char *seat) { + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, +- "IS_VTCONSOLE", &s, ++ "CAN_MULTI_SESSION", &s, + NULL); + free(p); + +-- +1.7.7.5 + diff --git a/0107-logind-don-t-watch-vcsa-if-nobody-cares.patch b/0107-logind-don-t-watch-vcsa-if-nobody-cares.patch new file mode 100644 index 0000000..b4cad32 --- /dev/null +++ b/0107-logind-don-t-watch-vcsa-if-nobody-cares.patch @@ -0,0 +1,46 @@ +From a00aab29d1970ef575ee395b016363cf48d39a7d Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 3 Jan 2012 21:50:02 +0100 +Subject: [PATCH 107/126] logind: don't watch vcsa if nobody cares (cherry + picked from commit + 976c088a0242a1a91b8f00899a4c2ae0e621a185) + +--- + src/logind.c | 11 ++++++----- + 1 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/src/logind.c b/src/logind.c +index 3a1903c..333d5f8 100644 +--- a/src/logind.c ++++ b/src/logind.c +@@ -955,7 +955,8 @@ static int manager_connect_udev(Manager *m) { + ev.events = EPOLLIN; + ev.data.u32 = FD_SEAT_UDEV; + +- if (m->n_autovts <= 0) ++ /* Don't bother watching VCSA devices, if nobody cares */ ++ if (m->n_autovts <= 0 || m->console_active_fd < 0) + return 0; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0) +@@ -1074,13 +1075,13 @@ int manager_startup(Manager *m) { + if (m->epoll_fd < 0) + return -errno; + +- /* Connect to udev */ +- r = manager_connect_udev(m); ++ /* Connect to console */ ++ r = manager_connect_console(m); + if (r < 0) + return r; + +- /* Connect to console */ +- r = manager_connect_console(m); ++ /* Connect to udev */ ++ r = manager_connect_udev(m); + if (r < 0) + return r; + +-- +1.7.7.5 + diff --git a/0108-man-fix-SEE-ALSO-in-hostname-5.patch b/0108-man-fix-SEE-ALSO-in-hostname-5.patch new file mode 100644 index 0000000..153c390 --- /dev/null +++ b/0108-man-fix-SEE-ALSO-in-hostname-5.patch @@ -0,0 +1,27 @@ +From b07ccd2e4d5fd58f9ead2e597a69711d50f7d744 Mon Sep 17 00:00:00 2001 +From: Tom Gundersen +Date: Sat, 31 Dec 2011 01:15:04 +0100 +Subject: [PATCH 108/126] man: fix SEE ALSO in hostname(5) + +Rather than referencing itself (hostname(5)), point to hostname(7). +(cherry picked from commit 63c52e45de6b6071d64cc4d3bb0d47357a1f5ead) +--- + man/hostname.xml | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/man/hostname.xml b/man/hostname.xml +index b8b05c8..1acda1a 100644 +--- a/man/hostname.xml ++++ b/man/hostname.xml +@@ -86,7 +86,7 @@ + systemd1, + sethostname2, + hostname1, +- hostname5, ++ hostname7, + machine-id5, + machine-info5 + +-- +1.7.7.5 + diff --git a/0109-logind-send-out-Lock-signal-when-locking.patch b/0109-logind-send-out-Lock-signal-when-locking.patch new file mode 100644 index 0000000..6929641 --- /dev/null +++ b/0109-logind-send-out-Lock-signal-when-locking.patch @@ -0,0 +1,30 @@ +From 02ed8bfecd03c02b39c0d9d04c846e7deb905381 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 3 Jan 2012 23:08:15 +0100 +Subject: [PATCH 109/126] logind: send out Lock signal when locking (cherry + picked from commit + bda061759c3baef4383a2ec0bf1b538905cb30b0) + +Conflicts: + + TODO +--- + src/logind-session-dbus.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/src/logind-session-dbus.c b/src/logind-session-dbus.c +index dc0ef5b..cbd6d7f 100644 +--- a/src/logind-session-dbus.c ++++ b/src/logind-session-dbus.c +@@ -288,7 +288,7 @@ static DBusHandlerResult session_message_dispatch( + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Lock") || + dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Unlock")) { + +- if (session_send_signal(s, streq(dbus_message_get_member(message), "Lock")) < 0) ++ if (session_send_lock(s, streq(dbus_message_get_member(message), "Lock")) < 0) + goto oom; + + reply = dbus_message_new_method_return(message); +-- +1.7.7.5 + diff --git a/0110-logind-add-needed-include-for-sd_notify.patch b/0110-logind-add-needed-include-for-sd_notify.patch new file mode 100644 index 0000000..9503b23 --- /dev/null +++ b/0110-logind-add-needed-include-for-sd_notify.patch @@ -0,0 +1,26 @@ +From 427275bed23af1079fc9140459fea61e5d06e7fc Mon Sep 17 00:00:00 2001 +From: Kay Sievers +Date: Thu, 5 Jan 2012 00:52:56 +0100 +Subject: [PATCH 110/126] logind: add needed include for sd_notify() (cherry + picked from commit + 4726299357861c0ced3a53a4214e1c3809968e5e) + +--- + src/logind.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/src/logind.c b/src/logind.c +index 333d5f8..5cff2db 100644 +--- a/src/logind.c ++++ b/src/logind.c +@@ -30,6 +30,7 @@ + #include + + #include "logind.h" ++#include "sd-daemon.h" + #include "dbus-common.h" + #include "dbus-loop.h" + #include "strv.h" +-- +1.7.7.5 + diff --git a/0111-fix-compilation-error-with-PathSpec-redefined.patch b/0111-fix-compilation-error-with-PathSpec-redefined.patch new file mode 100644 index 0000000..d4070b2 --- /dev/null +++ b/0111-fix-compilation-error-with-PathSpec-redefined.patch @@ -0,0 +1,35 @@ +From 6cddfe340771dd1c120e13379646e0cc9d012b11 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 5 Jan 2012 00:56:21 +0100 +Subject: [PATCH 111/126] fix compilation error with 'PathSpec redefined' + (cherry picked from commit + 9cf3ab0e16af7db666ca3cf7d73dc4d616deb8fa) + +--- + src/service.h | 3 +-- + 1 files changed, 1 insertions(+), 2 deletions(-) + +diff --git a/src/service.h b/src/service.h +index 15d58cc..2102826 100644 +--- a/src/service.h ++++ b/src/service.h +@@ -25,6 +25,7 @@ + typedef struct Service Service; + + #include "unit.h" ++#include "path.h" + #include "ratelimit.h" + + typedef enum ServiceState { +@@ -86,8 +87,6 @@ typedef enum NotifyAccess { + _NOTIFY_ACCESS_INVALID = -1 + } NotifyAccess; + +-typedef struct PathSpec PathSpec; +- + struct Service { + Meta meta; + +-- +1.7.7.5 + diff --git a/0112-util-when-printing-status-updates-during-boot-take-t.patch b/0112-util-when-printing-status-updates-during-boot-take-t.patch new file mode 100644 index 0000000..9a095ed --- /dev/null +++ b/0112-util-when-printing-status-updates-during-boot-take-t.patch @@ -0,0 +1,219 @@ +From 36318b0838442ef35fff111910d5657c20f1a71c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 5 Jan 2012 03:24:39 +0100 +Subject: [PATCH 112/126] util: when printing status updates during boot, take + terminal width into account (cherry picked from + commit 81beb7508e72b29ae7cec60b50231cbe0c1d582e) + +Conflicts: + + src/util.c + src/util.h +--- + src/unit.c | 18 +----------- + src/util.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++----------- + src/util.h | 7 +++-- + 3 files changed, 75 insertions(+), 37 deletions(-) + +diff --git a/src/unit.c b/src/unit.c +index 03c90f5..dea8f4a 100644 +--- a/src/unit.c ++++ b/src/unit.c +@@ -2441,9 +2441,6 @@ int unit_coldplug(Unit *u) { + + 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); +@@ -2458,21 +2455,8 @@ void unit_status_printf(Unit *u, const char *status, const char *format, ...) { + return; + + va_start(ap, format); +- err = vasprintf(&s, format, ap); ++ status_vprintf(status, 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/util.c b/src/util.c +index da71e4d..9ed7d13 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -3531,9 +3531,12 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) { + } + } + +-void status_vprintf(const char *format, va_list ap) { +- char *s = NULL; +- int fd = -1; ++void status_vprintf(const char *status, const char *format, va_list ap) { ++ char *s = NULL, *spaces = NULL, *e; ++ int fd = -1, c; ++ size_t emax, sl, left; ++ struct iovec iovec[5]; ++ int n = 0; + + assert(format); + +@@ -3543,25 +3546,65 @@ void status_vprintf(const char *format, va_list ap) { + if (vasprintf(&s, format, ap) < 0) + goto finish; + +- if ((fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) ++ fd = open_terminal("/dev/tty", O_WRONLY|O_NOCTTY|O_CLOEXEC); ++ if (fd < 0) + goto finish; + +- write(fd, s, strlen(s)); ++ c = fd_columns(fd); ++ if (c <= 0) ++ c = 80; ++ ++ if (status) { ++ sl = 2 + 6 + 1; /* " [" status "]" */ ++ emax = (size_t) c > sl ? c - sl - 1 : 0; ++ } else ++ emax = c - 1; ++ ++ e = ellipsize(s, emax, 75); ++ if (e) { ++ free(s); ++ s = e; ++ } ++ ++ zero(iovec); ++ IOVEC_SET_STRING(iovec[n++], s); ++ ++ sl = strlen(s); ++ left = emax > sl ? emax - sl : 0; ++ if (left > 0) { ++ spaces = malloc(left); ++ if (spaces) { ++ memset(spaces, ' ', left); ++ iovec[n].iov_base = spaces; ++ iovec[n].iov_len = left; ++ n++; ++ } ++ } ++ ++ if (status) { ++ IOVEC_SET_STRING(iovec[n++], " ["); ++ IOVEC_SET_STRING(iovec[n++], status); ++ IOVEC_SET_STRING(iovec[n++], "]\n"); ++ } else ++ IOVEC_SET_STRING(iovec[n++], "\n"); ++ ++ writev(fd, iovec, n); + + finish: + free(s); ++ free(spaces); + + if (fd >= 0) + close_nointr_nofail(fd); + } + +-void status_printf(const char *format, ...) { ++void status_printf(const char *status, const char *format, ...) { + va_list ap; + + assert(format); + + va_start(ap, format); +- status_vprintf(format, ap); ++ status_vprintf(status, format, ap); + va_end(ap); + } + +@@ -3718,7 +3761,8 @@ void status_welcome(void) { + if (!ansi_color && !const_color) + const_color = "1"; + +- status_printf("\nWelcome to \x1B[%sm%s\x1B[0m!\n\n", ++ status_printf(NULL, ++ "\nWelcome to \x1B[%sm%s\x1B[0m!\n", + const_color ? const_color : ansi_color, + const_pretty ? const_pretty : pretty_name); + +@@ -3860,23 +3904,32 @@ char **replace_env_argv(char **argv, char **env) { + return r; + } + +-int columns(void) { ++int fd_columns(int fd) { ++ struct winsize ws; ++ zero(ws); ++ ++ if (ioctl(fd, TIOCGWINSZ, &ws) < 0) ++ return -errno; ++ ++ if (ws.ws_col <= 0) ++ return -EIO; ++ ++ return ws.ws_col; ++} ++ ++unsigned columns(void) { + static __thread int parsed_columns = 0; + const char *e; + + if (_likely_(parsed_columns > 0)) + return parsed_columns; + +- if ((e = getenv("COLUMNS"))) ++ e = getenv("COLUMNS"); ++ if (e) + parsed_columns = atoi(e); + +- if (parsed_columns <= 0) { +- struct winsize ws; +- zero(ws); +- +- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0) +- parsed_columns = ws.ws_col; +- } ++ if (parsed_columns <= 0) ++ parsed_columns = fd_columns(STDOUT_FILENO); + + if (parsed_columns <= 0) + parsed_columns = 80; +diff --git a/src/util.h b/src/util.h +index a71a297..e4a554a 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -370,11 +370,12 @@ int pipe_eof(int fd); + + cpu_set_t* cpu_set_malloc(unsigned *ncpus); + +-void status_vprintf(const char *format, va_list ap); +-void status_printf(const char *format, ...); ++void status_vprintf(const char *status, const char *format, va_list ap); ++void status_printf(const char *status, const char *format, ...); + void status_welcome(void); + +-int columns(void); ++int fd_columns(int fd); ++unsigned columns(void); + + int running_in_chroot(void); + +-- +1.7.7.5 + diff --git a/0113-log-minor-optimization.patch b/0113-log-minor-optimization.patch new file mode 100644 index 0000000..8b2d3d0 --- /dev/null +++ b/0113-log-minor-optimization.patch @@ -0,0 +1,48 @@ +From 3e1a7de638aec192ae7ac25baea7e8c343ab414b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 5 Jan 2012 03:25:10 +0100 +Subject: [PATCH 113/126] log: minor optimization (cherry picked from commit + 674f8283698517047a7c0e78cff1e18932a97b05) + +--- + src/log.c | 13 ++++++++----- + 1 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/src/log.c b/src/log.c +index 4f57821..3dfe654 100644 +--- a/src/log.c ++++ b/src/log.c +@@ -95,7 +95,8 @@ static int log_open_kmsg(void) { + if (kmsg_fd >= 0) + return 0; + +- if ((kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) { ++ kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC); ++ if (kmsg_fd < 0) { + log_error("Failed to open /dev/kmsg for logging: %s", strerror(errno)); + return -errno; + } +@@ -265,14 +266,16 @@ static int write_to_console( + if (console_fd < 0) + return 0; + +- snprintf(location, sizeof(location), "(%s:%u) ", file, line); +- char_array_0(location); +- + highlight = LOG_PRI(level) <= LOG_ERR && show_color; + + zero(iovec); +- if (show_location) ++ ++ if (show_location) { ++ snprintf(location, sizeof(location), "(%s:%u) ", file, line); ++ char_array_0(location); + IOVEC_SET_STRING(iovec[n++], location); ++ } ++ + if (highlight) + IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_ON); + IOVEC_SET_STRING(iovec[n++], buffer); +-- +1.7.7.5 + diff --git a/0114-util-never-ellipsize-welcome-message.patch b/0114-util-never-ellipsize-welcome-message.patch new file mode 100644 index 0000000..358f19f --- /dev/null +++ b/0114-util-never-ellipsize-welcome-message.patch @@ -0,0 +1,146 @@ +From a8bd50e0b09cb537bb3019845560e645899960ed Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 5 Jan 2012 15:35:16 +0100 +Subject: [PATCH 114/126] util: never ellipsize welcome message (cherry picked + from commit + 67e5cc4f3ed41feaed399cfed77c6fbb41e14a8c) + +--- + src/unit.c | 2 +- + src/util.c | 55 ++++++++++++++++++++++++++++++------------------------- + src/util.h | 4 ++-- + 3 files changed, 33 insertions(+), 28 deletions(-) + +diff --git a/src/unit.c b/src/unit.c +index dea8f4a..3191071 100644 +--- a/src/unit.c ++++ b/src/unit.c +@@ -2455,7 +2455,7 @@ void unit_status_printf(Unit *u, const char *status, const char *format, ...) { + return; + + va_start(ap, format); +- status_vprintf(status, format, ap); ++ status_vprintf(status, true, format, ap); + va_end(ap); + } + +diff --git a/src/util.c b/src/util.c +index 9ed7d13..fce0a0c 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -3531,7 +3531,7 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) { + } + } + +-void status_vprintf(const char *status, const char *format, va_list ap) { ++void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) { + char *s = NULL, *spaces = NULL, *e; + int fd = -1, c; + size_t emax, sl, left; +@@ -3546,38 +3546,42 @@ void status_vprintf(const char *status, const char *format, va_list ap) { + if (vasprintf(&s, format, ap) < 0) + goto finish; + +- fd = open_terminal("/dev/tty", O_WRONLY|O_NOCTTY|O_CLOEXEC); ++ fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + goto finish; + +- c = fd_columns(fd); +- if (c <= 0) +- c = 80; ++ if (ellipse) { ++ c = fd_columns(fd); ++ if (c <= 0) ++ c = 80; + +- if (status) { +- sl = 2 + 6 + 1; /* " [" status "]" */ +- emax = (size_t) c > sl ? c - sl - 1 : 0; +- } else +- emax = c - 1; ++ if (status) { ++ sl = 2 + 6 + 1; /* " [" status "]" */ ++ emax = (size_t) c > sl ? c - sl - 1 : 0; ++ } else ++ emax = c - 1; + +- e = ellipsize(s, emax, 75); +- if (e) { +- free(s); +- s = e; ++ e = ellipsize(s, emax, 75); ++ if (e) { ++ free(s); ++ s = e; ++ } + } + + zero(iovec); + IOVEC_SET_STRING(iovec[n++], s); + +- sl = strlen(s); +- left = emax > sl ? emax - sl : 0; +- if (left > 0) { +- spaces = malloc(left); +- if (spaces) { +- memset(spaces, ' ', left); +- iovec[n].iov_base = spaces; +- iovec[n].iov_len = left; +- n++; ++ if (ellipse) { ++ sl = strlen(s); ++ left = emax > sl ? emax - sl : 0; ++ if (left > 0) { ++ spaces = malloc(left); ++ if (spaces) { ++ memset(spaces, ' ', left); ++ iovec[n].iov_base = spaces; ++ iovec[n].iov_len = left; ++ n++; ++ } + } + } + +@@ -3598,13 +3602,13 @@ finish: + close_nointr_nofail(fd); + } + +-void status_printf(const char *status, const char *format, ...) { ++void status_printf(const char *status, bool ellipse, const char *format, ...) { + va_list ap; + + assert(format); + + va_start(ap, format); +- status_vprintf(status, format, ap); ++ status_vprintf(status, ellipse, format, ap); + va_end(ap); + } + +@@ -3762,6 +3766,7 @@ void status_welcome(void) { + const_color = "1"; + + status_printf(NULL, ++ false, + "\nWelcome to \x1B[%sm%s\x1B[0m!\n", + const_color ? const_color : ansi_color, + const_pretty ? const_pretty : pretty_name); +diff --git a/src/util.h b/src/util.h +index e4a554a..40a2a39 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -370,8 +370,8 @@ int pipe_eof(int fd); + + cpu_set_t* cpu_set_malloc(unsigned *ncpus); + +-void status_vprintf(const char *status, const char *format, va_list ap); +-void status_printf(const char *status, const char *format, ...); ++void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap); ++void status_printf(const char *status, bool ellipse, const char *format, ...); + void status_welcome(void); + + int fd_columns(int fd); +-- +1.7.7.5 + diff --git a/0115-headers-fix-git-URLs-for-source-files.patch b/0115-headers-fix-git-URLs-for-source-files.patch new file mode 100644 index 0000000..51ceb12 --- /dev/null +++ b/0115-headers-fix-git-URLs-for-source-files.patch @@ -0,0 +1,160 @@ +From e304704addaa0ab824060b2c9612ffeee64cb5bf Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 5 Jan 2012 18:21:26 +0100 +Subject: [PATCH 115/126] headers: fix git URLs for source files (cherry + picked from commit + 8ab49c12dcab02d9d83e63a93676d4fc8f709516) + +--- + man/sd-daemon.xml | 4 ++-- + man/sd-readahead.xml | 4 ++-- + man/sd_booted.xml | 4 ++-- + man/sd_is_fifo.xml | 4 ++-- + man/sd_listen_fds.xml | 4 ++-- + man/sd_notify.xml | 4 ++-- + man/sd_readahead.xml | 4 ++-- + src/sd-daemon.h | 2 +- + src/sd-readahead.h | 4 ++-- + 9 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml +index 383d77f..3f3a723 100644 +--- a/man/sd-daemon.xml ++++ b/man/sd-daemon.xml +@@ -130,8 +130,8 @@ + In addition, for details about the algorithms + check the liberally licensed reference implementation + sources: +- +- resp. ++ ++ resp. + + These APIs are implemented in the reference + implementation's sd-daemon.c and +diff --git a/man/sd-readahead.xml b/man/sd-readahead.xml +index 819691e..7c21656 100644 +--- a/man/sd-readahead.xml ++++ b/man/sd-readahead.xml +@@ -86,8 +86,8 @@ + In addition, for details about the algorithms + check the liberally licensed reference implementation + sources: +- +- resp. ++ ++ resp. + + These APIs are implemented in the reference + implementation's drop-in +diff --git a/man/sd_booted.xml b/man/sd_booted.xml +index c9f538a..c876874 100644 +--- a/man/sd_booted.xml ++++ b/man/sd_booted.xml +@@ -93,9 +93,9 @@ + + For details about the algorithm check the + liberally licensed reference implementation sources: +- ++ + resp. ++ url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h"/> + + sd_booted() is implemented + in the reference implementation's +diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml +index 82b89bb..6055893 100644 +--- a/man/sd_is_fifo.xml ++++ b/man/sd_is_fifo.xml +@@ -180,9 +180,9 @@ + + For details about the algorithms check the + liberally licensed reference implementation sources: +- ++ + resp. ++ url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h"/> + + sd_is_fifo() and the + related functions are implemented in the reference +diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml +index 68a45cd..09d0503 100644 +--- a/man/sd_listen_fds.xml ++++ b/man/sd_listen_fds.xml +@@ -140,9 +140,9 @@ + + For details about the algorithm check the + liberally licensed reference implementation sources: +- ++ + resp. ++ url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h"/> + + sd_listen_fds() is + implemented in the reference implementation's +diff --git a/man/sd_notify.xml b/man/sd_notify.xml +index c3791ce..0209146 100644 +--- a/man/sd_notify.xml ++++ b/man/sd_notify.xml +@@ -208,9 +208,9 @@ + + For details about the algorithms check the + liberally licensed reference implementation sources: +- ++ + resp. ++ url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h"/> + + sd_notify() and + sd_notifyf() are implemented in +diff --git a/man/sd_readahead.xml b/man/sd_readahead.xml +index 25fe5b2..4b8c957 100644 +--- a/man/sd_readahead.xml ++++ b/man/sd_readahead.xml +@@ -129,9 +129,9 @@ + + For details about the algorithm check the + liberally licensed reference implementation sources: +- ++ + resp. ++ url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-readahead.h"/> + + sd_readahead() is + implemented in the reference implementation's drop-in +diff --git a/src/sd-daemon.h b/src/sd-daemon.h +index 46dc7fd..eb2a606 100644 +--- a/src/sd-daemon.h ++++ b/src/sd-daemon.h +@@ -58,7 +58,7 @@ extern "C" { + + You may find an up-to-date version of these source files online: + +- http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h ++ http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h + http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c + + This should compile on non-Linux systems, too, but with the +diff --git a/src/sd-readahead.h b/src/sd-readahead.h +index ee7e306..afe6768 100644 +--- a/src/sd-readahead.h ++++ b/src/sd-readahead.h +@@ -47,8 +47,8 @@ extern "C" { + + You may find an up-to-date version of these source files online: + +- http://cgit.freedesktop.org/systemd/plain/src/sd-readahead.h +- http://cgit.freedesktop.org/systemd/plain/src/sd-readahead.c ++ http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-readahead.h ++ http://cgit.freedesktop.org/systemd/plain/src/readahead/sd-readahead.c + + This should compile on non-Linux systems, too, but all functions + will become NOPs. +-- +1.7.7.5 + diff --git a/0116-README-correct-license-claims.patch b/0116-README-correct-license-claims.patch new file mode 100644 index 0000000..64ef3c5 --- /dev/null +++ b/0116-README-correct-license-claims.patch @@ -0,0 +1,27 @@ +From 7ac8afd6e39c4f485d3b066f61d755d0f678f4f8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 5 Jan 2012 18:24:18 +0100 +Subject: [PATCH 116/126] README: correct license claims (cherry picked from + commit 0df4f9d669bec2d34777735f8cdd40797b1fd753) + +--- + README | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/README b/README +index 15afb2c..17b3f49 100644 +--- a/README ++++ b/README +@@ -27,7 +27,8 @@ AUTHOR: + Lennart Poettering with major support from Kay Sievers + + LICENSE: +- GPLv2+ for all code, except sd-daemon.[ch] which is MIT ++ GPLv2+ for all code, except sd-daemon.[ch] and ++ sd-readahead.[ch] which are MIT + + REQUIREMENTS: + Linux kernel >= 2.6.39 (with devtmpfs, cgroups; optional but strongly recommended: autofs4, ipv6) +-- +1.7.7.5 + diff --git a/0117-util-fix-switching-to-console-unicode-mode.patch b/0117-util-fix-switching-to-console-unicode-mode.patch new file mode 100644 index 0000000..b6fe22a --- /dev/null +++ b/0117-util-fix-switching-to-console-unicode-mode.patch @@ -0,0 +1,36 @@ +From 6fca919fd967a6a16405f96872228c93eb8217c3 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 6 Jan 2012 01:28:30 +0100 +Subject: [PATCH 117/126] util: fix switching to console unicode mode + +The KDSKBMODE ioctl wants a value directly, not its address. +(cherry picked from commit df465b3f4419b6ba2e12bf9a5f7d7bde5a0c3531) +--- + src/util.c | 4 +--- + 1 files changed, 1 insertions(+), 3 deletions(-) + +diff --git a/src/util.c b/src/util.c +index fce0a0c..a9d0821 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -2424,7 +2424,6 @@ int ask(char *ret, const char *replies, const char *text, ...) { + int reset_terminal_fd(int fd) { + struct termios termios; + int r = 0; +- long arg; + + /* Set terminal to some sane defaults */ + +@@ -2438,8 +2437,7 @@ int reset_terminal_fd(int fd) { + ioctl(fd, TIOCNXCL); + + /* Enable console unicode mode */ +- arg = K_UNICODE; +- ioctl(fd, KDSKBMODE, &arg); ++ ioctl(fd, KDSKBMODE, K_UNICODE); + + if (tcgetattr(fd, &termios) < 0) { + r = -errno; +-- +1.7.7.5 + diff --git a/0118-util-switch-the-console-to-text-mode-on-reset.patch b/0118-util-switch-the-console-to-text-mode-on-reset.patch new file mode 100644 index 0000000..aea727d --- /dev/null +++ b/0118-util-switch-the-console-to-text-mode-on-reset.patch @@ -0,0 +1,30 @@ +From 21ee8544227b293260e864c2a6bcf47a1e0d7a4c Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 6 Jan 2012 01:32:34 +0100 +Subject: [PATCH 118/126] util: switch the console to text mode on reset + +In case we're taking over the console after a killed X server. + +https://bugzilla.redhat.com/show_bug.cgi?id=771563 +(cherry picked from commit 5c0100a53772eb7f4b11db7b071fc63e82e5a1a7) +--- + src/util.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/src/util.c b/src/util.c +index a9d0821..5bac05f 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -2436,6 +2436,9 @@ int reset_terminal_fd(int fd) { + /* Disable exclusive mode, just in case */ + ioctl(fd, TIOCNXCL); + ++ /* Switch to text mode */ ++ ioctl(fd, KDSETMODE, KD_TEXT); ++ + /* Enable console unicode mode */ + ioctl(fd, KDSKBMODE, K_UNICODE); + +-- +1.7.7.5 + diff --git a/0119-service-add-dependencies-on-configured-sockets.patch b/0119-service-add-dependencies-on-configured-sockets.patch new file mode 100644 index 0000000..dd344aa --- /dev/null +++ b/0119-service-add-dependencies-on-configured-sockets.patch @@ -0,0 +1,54 @@ +From 423d96b0e5e351ae6489370ebc4af1bd18008b5d Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 6 Jan 2012 19:23:03 +0100 +Subject: [PATCH 119/126] service: add dependencies on configured sockets + (cherry picked from commit + 73aa0c00df8b101bad4c3a038148a633df88610c) + +--- + src/service.c | 22 ++++++++++++++++++++++ + 1 files changed, 22 insertions(+), 0 deletions(-) + +diff --git a/src/service.c b/src/service.c +index d229301..65a45e1 100644 +--- a/src/service.c ++++ b/src/service.c +@@ -1100,6 +1100,22 @@ static int service_add_default_dependencies(Service *s) { + return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); + } + ++static int service_add_socket_dependencies(Service *s) { ++ Iterator i; ++ Unit *u; ++ int r; ++ ++ /* Make sure we pull in all explicitly configured sockets */ ++ ++ SET_FOREACH(u, s->configured_sockets, i) { ++ r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, u, true); ++ if (r < 0) ++ return r; ++ } ++ ++ return 0; ++} ++ + static void service_fix_output(Service *s) { + assert(s); + +@@ -1173,6 +1189,12 @@ static int service_load(Unit *u) { + if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true)) < 0) + return r; + ++ if (!set_isempty(s->configured_sockets)) { ++ r = service_add_socket_dependencies(s); ++ if (r < 0) ++ return r; ++ } ++ + if (s->meta.default_dependencies) + if ((r = service_add_default_dependencies(s)) < 0) + return r; +-- +1.7.7.5 + diff --git a/0120-unit-properly-update-references-to-units-which-are-m.patch b/0120-unit-properly-update-references-to-units-which-are-m.patch new file mode 100644 index 0000000..496a2f4 --- /dev/null +++ b/0120-unit-properly-update-references-to-units-which-are-m.patch @@ -0,0 +1,1515 @@ +From a1f378075e7ff6f07031ab1d2f653110f7d0e1f2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 6 Jan 2012 23:08:54 +0100 +Subject: [PATCH 120/126] unit: properly update references to units which are + merged + +When we merge units that some kind of object points to, those pointers +might become invalidated, and needs to be updated. Introduce a UnitRef +struct which links up all the unit references, to ensure corrected +references. + +At the same time, drop configured_sockets in the Service object, and +replace it by proper UNIT_TRIGGERS resp. UNIT_TRIGGERED_BY dependencies, +which allow us to simplify a lot of code. +(cherry picked from commit 57020a3abff20f176e9f0cbb982d7977119d6f08) +--- + src/automount.c | 21 +++++--- + src/automount.h | 3 +- + src/dbus-path.c | 2 +- + src/dbus-service.c | 2 - + src/dbus-timer.c | 2 +- + src/dbus-unit.h | 2 + + src/load-fragment.c | 58 ++++++++++---------- + src/mount.c | 20 +++---- + src/path.c | 93 +++++++++++++++----------------- + src/path.h | 14 +++--- + src/service.c | 147 ++++++++++----------------------------------------- + src/service.h | 6 ++- + src/socket.c | 88 +++++++++++++++---------------- + src/socket.h | 9 ++-- + src/timer.c | 57 ++++++++----------- + src/timer.h | 2 +- + src/unit.c | 39 ++++++++++++- + src/unit.h | 22 ++++++++ + 18 files changed, 268 insertions(+), 319 deletions(-) + +diff --git a/src/automount.c b/src/automount.c +index 29b807d..85558e5 100644 +--- a/src/automount.c ++++ b/src/automount.c +@@ -105,7 +105,7 @@ static void automount_done(Unit *u) { + assert(a); + + unmount_autofs(a); +- a->mount = NULL; ++ unit_ref_unset(&a->mount); + + free(a->where); + a->where = NULL; +@@ -205,6 +205,7 @@ static int automount_load(Unit *u) { + return r; + + if (u->meta.load_state == UNIT_LOADED) { ++ Unit *x; + + if (!a->where) + if (!(a->where = unit_name_to_path(u->meta.id))) +@@ -215,10 +216,14 @@ static int automount_load(Unit *u) { + if ((r = automount_add_mount_links(a)) < 0) + return r; + +- if ((r = unit_load_related_unit(u, ".mount", (Unit**) &a->mount)) < 0) ++ r = unit_load_related_unit(u, ".mount", &x); ++ if (r < 0) + return r; + +- if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(a->mount), true)) < 0) ++ unit_ref_set(&a->mount, x); ++ ++ r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(a->mount), true); ++ if (r < 0) + return r; + + if (a->meta.default_dependencies) +@@ -569,7 +574,7 @@ static void automount_enter_runnning(Automount *a) { + DBusError error; + + assert(a); +- assert(a->mount); ++ assert(UNIT_DEREF(a->mount)); + + dbus_error_init(&error); + +@@ -591,7 +596,7 @@ static void automount_enter_runnning(Automount *a) { + + if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id) + log_info("%s's automount point already active?", a->meta.id); +- else if ((r = manager_add_job(a->meta.manager, JOB_START, UNIT(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) { ++ else if ((r = manager_add_job(a->meta.manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) { + log_warning("%s failed to queue mount startup job: %s", a->meta.id, bus_error(&error, r)); + goto fail; + } +@@ -616,7 +621,7 @@ static int automount_start(Unit *u) { + return -EEXIST; + } + +- if (a->mount->meta.load_state != UNIT_LOADED) ++ if (UNIT_DEREF(a->mount)->meta.load_state != UNIT_LOADED) + return -ENOENT; + + a->failure = false; +@@ -738,10 +743,10 @@ static bool automount_check_gc(Unit *u) { + + assert(a); + +- if (!a->mount) ++ if (!UNIT_DEREF(a->mount)) + return false; + +- return UNIT_VTABLE(UNIT(a->mount))->check_gc(UNIT(a->mount)); ++ return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount)); + } + + static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { +diff --git a/src/automount.h b/src/automount.h +index 1a6cc98..c6326ed 100644 +--- a/src/automount.h ++++ b/src/automount.h +@@ -42,14 +42,13 @@ struct Automount { + + char *where; + +- Mount *mount; ++ UnitRef mount; + + int pipe_fd; + mode_t directory_mode; + Watch pipe_watch; + dev_t dev_id; + +- + Set *tokens; + + bool failure:1; +diff --git a/src/dbus-path.c b/src/dbus-path.c +index 1523879..f67b5a2 100644 +--- a/src/dbus-path.c ++++ b/src/dbus-path.c +@@ -86,7 +86,7 @@ static int bus_path_append_unit(DBusMessageIter *i, const char *property, void * + assert(property); + assert(u); + +- t = u->path.unit ? u->path.unit->meta.id : ""; ++ t = UNIT_DEREF(u->path.unit) ? UNIT_DEREF(u->path.unit)->meta.id : ""; + + return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM; + } +diff --git a/src/dbus-service.c b/src/dbus-service.c +index 3486623..373e3f5 100644 +--- a/src/dbus-service.c ++++ b/src/dbus-service.c +@@ -59,7 +59,6 @@ + " \n" \ + " \n" \ + " \n" \ +- " \n" \ + BUS_SERVICE_SYSV_INTERFACE_FRAGMENT \ + " \n" + +@@ -120,7 +119,6 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio + { "org.freedesktop.systemd1.Service", "ControlPID", bus_property_append_pid, "u", &u->service.control_pid }, + { "org.freedesktop.systemd1.Service", "BusName", bus_property_append_string, "s", u->service.bus_name }, + { "org.freedesktop.systemd1.Service", "StatusText", bus_property_append_string, "s", u->service.status_text }, +- { "org.freedesktop.systemd1.Service", "Sockets", bus_unit_append_dependencies, "as", u->service.configured_sockets }, + #ifdef HAVE_SYSV_COMPAT + { "org.freedesktop.systemd1.Service", "SysVRunLevels", bus_property_append_string, "s", u->service.sysv_runlevels }, + { "org.freedesktop.systemd1.Service", "SysVStartPriority", bus_property_append_int, "i", &u->service.sysv_start_priority }, +diff --git a/src/dbus-timer.c b/src/dbus-timer.c +index abcbe6f..07d425e 100644 +--- a/src/dbus-timer.c ++++ b/src/dbus-timer.c +@@ -107,7 +107,7 @@ static int bus_timer_append_unit(DBusMessageIter *i, const char *property, void + assert(property); + assert(u); + +- t = u->timer.unit ? u->timer.unit->meta.id : ""; ++ t = UNIT_DEREF(u->timer.unit) ? UNIT_DEREF(u->timer.unit)->meta.id : ""; + + return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM; + } +diff --git a/src/dbus-unit.h b/src/dbus-unit.h +index 9fed6d7..20d5506 100644 +--- a/src/dbus-unit.h ++++ b/src/dbus-unit.h +@@ -141,6 +141,8 @@ + { "org.freedesktop.systemd1.Unit", "Before", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_BEFORE] }, \ + { "org.freedesktop.systemd1.Unit", "After", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_AFTER] }, \ + { "org.freedesktop.systemd1.Unit", "OnFailure", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_ON_FAILURE] }, \ ++ { "org.freedesktop.systemd1.Unit", "Triggers", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_TRIGGERS] }, \ ++ { "org.freedesktop.systemd1.Unit", "TriggeredBy", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_TRIGGERED_BY] }, \ + { "org.freedesktop.systemd1.Unit", "Description", bus_unit_append_description, "s", u }, \ + { "org.freedesktop.systemd1.Unit", "LoadState", bus_unit_append_load_state, "s", &u->meta.load_state }, \ + { "org.freedesktop.systemd1.Unit", "ActiveState", bus_unit_append_active_state, "s", u }, \ +diff --git a/src/load-fragment.c b/src/load-fragment.c +index 12079c6..1903190 100644 +--- a/src/load-fragment.c ++++ b/src/load-fragment.c +@@ -84,7 +84,8 @@ int config_parse_unit_deps( + char *t, *k; + int r; + +- if (!(t = strndup(w, l))) ++ t = strndup(w, l); ++ if (!t) + return -ENOMEM; + + k = unit_name_printf(u, t); +@@ -94,12 +95,8 @@ int config_parse_unit_deps( + return -ENOMEM; + + r = unit_add_dependency_by_name(u, d, k, NULL, true); +- +- if (r < 0) { +- log_error("Failed to add dependency on %s, ignoring: %s", k, strerror(-r)); +- free(k); +- return 0; +- } ++ if (r < 0) ++ log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", filename, line, k, strerror(-r)); + + free(k); + } +@@ -1265,6 +1262,7 @@ int config_parse_timer_unit( + Timer *t = data; + int r; + DBusError error; ++ Unit *u; + + assert(filename); + assert(lvalue); +@@ -1278,12 +1276,15 @@ int config_parse_timer_unit( + return 0; + } + +- if ((r = manager_load_unit(t->meta.manager, rvalue, NULL, NULL, &t->unit)) < 0) { ++ r = manager_load_unit(t->meta.manager, rvalue, NULL, NULL, &u); ++ if (r < 0) { + log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r)); + dbus_error_free(&error); + return 0; + } + ++ unit_ref_set(&t->unit, u); ++ + return 0; + } + +@@ -1347,6 +1348,7 @@ int config_parse_path_unit( + Path *t = data; + int r; + DBusError error; ++ Unit *u; + + assert(filename); + assert(lvalue); +@@ -1360,12 +1362,14 @@ int config_parse_path_unit( + return 0; + } + +- if ((r = manager_load_unit(t->meta.manager, rvalue, NULL, &error, &t->unit)) < 0) { ++ if ((r = manager_load_unit(t->meta.manager, rvalue, NULL, &error, &u)) < 0) { + log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r)); + dbus_error_free(&error); + return 0; + } + ++ unit_ref_set(&t->unit, u); ++ + return 0; + } + +@@ -1416,7 +1420,6 @@ int config_parse_service_sockets( + + Service *s = data; + int r; +- DBusError error; + char *state, *w; + size_t l; + +@@ -1425,35 +1428,34 @@ int config_parse_service_sockets( + assert(rvalue); + assert(data); + +- dbus_error_init(&error); +- + FOREACH_WORD_QUOTED(w, l, rvalue, state) { +- char *t; +- Unit *sock; ++ char *t, *k; + +- if (!(t = strndup(w, l))) ++ t = strndup(w, l); ++ if (!t) + return -ENOMEM; + +- if (!endswith(t, ".socket")) { +- log_error("[%s:%u] Unit must be of type socket, ignoring: %s", filename, line, rvalue); +- free(t); +- continue; +- } +- +- r = manager_load_unit(s->meta.manager, t, NULL, &error, &sock); ++ k = unit_name_printf(UNIT(s), t); + free(t); + +- if (r < 0) { +- log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r)); +- dbus_error_free(&error); ++ if (!k) ++ return -ENOMEM; ++ ++ if (!endswith(k, ".socket")) { ++ log_error("[%s:%u] Unit must be of type socket, ignoring: %s", filename, line, rvalue); ++ free(k); + continue; + } + +- if ((r = set_ensure_allocated(&s->configured_sockets, trivial_hash_func, trivial_compare_func)) < 0) +- return r; ++ r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true); ++ if (r < 0) ++ log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", filename, line, k, strerror(-r)); + +- if ((r = set_put(s->configured_sockets, sock)) < 0) ++ r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true); ++ if (r < 0) + return r; ++ ++ free(k); + } + + return 0; +diff --git a/src/mount.c b/src/mount.c +index 47422cc..f72c50a 100644 +--- a/src/mount.c ++++ b/src/mount.c +@@ -108,21 +108,12 @@ static void mount_parameters_done(MountParameters *p) { + + static void mount_done(Unit *u) { + Mount *m = MOUNT(u); +- Meta *other; + + assert(m); + + free(m->where); + m->where = NULL; + +- /* Try to detach us from the automount unit if there is any */ +- LIST_FOREACH(units_by_type, other, m->meta.manager->units_by_type[UNIT_AUTOMOUNT]) { +- Automount *a = (Automount*) other; +- +- if (a->mount == m) +- a->mount = NULL; +- } +- + mount_parameters_done(&m->parameters_etc_fstab); + mount_parameters_done(&m->parameters_proc_self_mountinfo); + mount_parameters_done(&m->parameters_fragment); +@@ -647,13 +638,18 @@ static int mount_load(Unit *u) { + static int mount_notify_automount(Mount *m, int status) { + Unit *p; + int r; ++ Iterator i; + + assert(m); + +- if ((r = unit_get_related_unit(UNIT(m), ".automount", &p)) < 0) +- return r == -ENOENT ? 0 : r; ++ SET_FOREACH(p, m->meta.dependencies[UNIT_TRIGGERED_BY], i) ++ if (p->meta.type == UNIT_AUTOMOUNT) { ++ r = automount_send_ready(AUTOMOUNT(p), status); ++ if (r < 0) ++ return r; ++ } + +- return automount_send_ready(AUTOMOUNT(p), status); ++ return 0; + } + + static void mount_set_state(Mount *m, MountState state) { +diff --git a/src/path.c b/src/path.c +index 3fee247..957af05 100644 +--- a/src/path.c ++++ b/src/path.c +@@ -39,7 +39,8 @@ static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = { + [PATH_FAILED] = UNIT_FAILED + }; + +-int pathspec_watch(PathSpec *s, Unit *u) { ++int path_spec_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, +@@ -55,7 +56,7 @@ int pathspec_watch(PathSpec *s, Unit *u) { + assert(u); + assert(s); + +- pathspec_unwatch(s, u); ++ path_spec_unwatch(s, u); + + if (!(k = strdup(s->path))) + return -ENOMEM; +@@ -96,11 +97,11 @@ int pathspec_watch(PathSpec *s, Unit *u) { + fail: + free(k); + +- pathspec_unwatch(s, u); ++ path_spec_unwatch(s, u); + return r; + } + +-void pathspec_unwatch(PathSpec *s, Unit *u) { ++void path_spec_unwatch(PathSpec *s, Unit *u) { + + if (s->inotify_fd < 0) + return; +@@ -111,7 +112,7 @@ void pathspec_unwatch(PathSpec *s, Unit *u) { + s->inotify_fd = -1; + } + +-int pathspec_fd_event(PathSpec *s, uint32_t events) { ++int path_spec_fd_event(PathSpec *s, uint32_t events) { + uint8_t *buf = NULL; + struct inotify_event *e; + ssize_t k; +@@ -164,7 +165,7 @@ out: + return r; + } + +-static bool pathspec_check_good(PathSpec *s, bool initial) { ++static bool path_spec_check_good(PathSpec *s, bool initial) { + bool good = false; + + switch (s->type) { +@@ -202,11 +203,11 @@ static bool pathspec_check_good(PathSpec *s, bool initial) { + return good; + } + +-static bool pathspec_startswith(PathSpec *s, const char *what) { ++static bool path_spec_startswith(PathSpec *s, const char *what) { + return path_startswith(s->path, what); + } + +-static void pathspec_mkdir(PathSpec *s, mode_t mode) { ++static void path_spec_mkdir(PathSpec *s, mode_t mode) { + int r; + + if (s->type == PATH_EXISTS || s->type == PATH_EXISTS_GLOB) +@@ -216,7 +217,7 @@ static void pathspec_mkdir(PathSpec *s, mode_t mode) { + log_warning("mkdir(%s) failed: %s", s->path, strerror(-r)); + } + +-static void pathspec_dump(PathSpec *s, FILE *f, const char *prefix) { ++static void path_spec_dump(PathSpec *s, FILE *f, const char *prefix) { + fprintf(f, + "%s%s: %s\n", + prefix, +@@ -224,8 +225,10 @@ static void pathspec_dump(PathSpec *s, FILE *f, const char *prefix) { + s->path); + } + +-void pathspec_done(PathSpec *s) { ++void path_spec_done(PathSpec *s) { ++ assert(s); + assert(s->inotify_fd == -1); ++ + free(s->path); + } + +@@ -244,10 +247,12 @@ static void path_done(Unit *u) { + + assert(p); + ++ unit_ref_unset(&p->unit); ++ + while ((s = p->specs)) { +- pathspec_unwatch(s, u); ++ path_spec_unwatch(s, u); + LIST_REMOVE(PathSpec, spec, p->specs, s); +- pathspec_done(s); ++ path_spec_done(s); + free(s); + } + } +@@ -265,7 +270,7 @@ int path_add_one_mount_link(Path *p, Mount *m) { + + LIST_FOREACH(spec, s, p->specs) { + +- if (!pathspec_startswith(s, m->where)) ++ if (!path_spec_startswith(s, m->where)) + continue; + + if ((r = unit_add_two_dependencies(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0) +@@ -330,11 +335,18 @@ static int path_load(Unit *u) { + + if (u->meta.load_state == UNIT_LOADED) { + +- if (!p->unit) +- if ((r = unit_load_related_unit(u, ".service", &p->unit))) ++ if (!UNIT_DEREF(p->unit)) { ++ Unit *x; ++ ++ r = unit_load_related_unit(u, ".service", &x); ++ if (r < 0) + return r; + +- if ((r = unit_add_dependency(u, UNIT_BEFORE, p->unit, true)) < 0) ++ unit_ref_set(&p->unit, x); ++ } ++ ++ r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(p->unit), true); ++ if (r < 0) + return r; + + if ((r = path_add_mount_links(p)) < 0) +@@ -361,12 +373,12 @@ static void path_dump(Unit *u, FILE *f, const char *prefix) { + "%sMakeDirectory: %s\n" + "%sDirectoryMode: %04o\n", + prefix, path_state_to_string(p->state), +- prefix, p->unit->meta.id, ++ prefix, UNIT_DEREF(p->unit)->meta.id, + prefix, yes_no(p->make_directory), + prefix, p->directory_mode); + + LIST_FOREACH(spec, s, p->specs) +- pathspec_dump(s, f, prefix); ++ path_spec_dump(s, f, prefix); + } + + static void path_unwatch(Path *p) { +@@ -375,7 +387,7 @@ static void path_unwatch(Path *p) { + assert(p); + + LIST_FOREACH(spec, s, p->specs) +- pathspec_unwatch(s, UNIT(p)); ++ path_spec_unwatch(s, UNIT(p)); + } + + static int path_watch(Path *p) { +@@ -385,7 +397,7 @@ static int path_watch(Path *p) { + assert(p); + + LIST_FOREACH(spec, s, p->specs) +- if ((r = pathspec_watch(s, UNIT(p))) < 0) ++ if ((r = path_spec_watch(s, UNIT(p))) < 0) + return r; + + return 0; +@@ -451,7 +463,7 @@ static void path_enter_running(Path *p) { + if (p->meta.job && p->meta.job->type == JOB_STOP) + return; + +- if ((r = manager_add_job(p->meta.manager, JOB_START, p->unit, JOB_REPLACE, true, &error, NULL)) < 0) ++ if ((r = manager_add_job(p->meta.manager, JOB_START, UNIT_DEREF(p->unit), JOB_REPLACE, true, &error, NULL)) < 0) + goto fail; + + p->inotify_triggered = false; +@@ -476,7 +488,7 @@ static bool path_check_good(Path *p, bool initial) { + assert(p); + + LIST_FOREACH(spec, s, p->specs) { +- good = pathspec_check_good(s, initial); ++ good = path_spec_check_good(s, initial); + + if (good) + break; +@@ -526,7 +538,7 @@ static void path_mkdir(Path *p) { + return; + + LIST_FOREACH(spec, s, p->specs) +- pathspec_mkdir(s, p->directory_mode); ++ path_spec_mkdir(s, p->directory_mode); + } + + static int path_start(Unit *u) { +@@ -535,7 +547,7 @@ static int path_start(Unit *u) { + assert(p); + assert(p->state == PATH_DEAD || p->state == PATH_FAILED); + +- if (p->unit->meta.load_state != UNIT_LOADED) ++ if (UNIT_DEREF(p->unit)->meta.load_state != UNIT_LOADED) + return -ENOENT; + + path_mkdir(p); +@@ -616,7 +628,7 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + /* log_debug("inotify wakeup on %s.", u->meta.id); */ + + LIST_FOREACH(spec, s, p->specs) +- if (pathspec_owns_inotify_fd(s, fd)) ++ if (path_spec_owns_inotify_fd(s, fd)) + break; + + if (!s) { +@@ -624,7 +636,7 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + goto fail; + } + +- changed = pathspec_fd_event(s, events); ++ changed = path_spec_fd_event(s, events); + if (changed < 0) + goto fail; + +@@ -645,36 +657,22 @@ fail: + } + + void path_unit_notify(Unit *u, UnitActiveState new_state) { +- char *n; +- int r; + Iterator i; ++ Unit *k; + + if (u->meta.type == UNIT_PATH) + return; + +- SET_FOREACH(n, u->meta.names, i) { +- char *k; +- Unit *t; ++ SET_FOREACH(k, u->meta.dependencies[UNIT_TRIGGERED_BY], i) { + Path *p; + +- if (!(k = unit_name_change_suffix(n, ".path"))) { +- r = -ENOMEM; +- goto fail; +- } +- +- t = manager_get_unit(u->meta.manager, k); +- free(k); +- +- if (!t) ++ if (k->meta.type != UNIT_PATH) + continue; + +- if (t->meta.load_state != UNIT_LOADED) ++ if (k->meta.load_state != UNIT_LOADED) + continue; + +- p = PATH(t); +- +- if (p->unit != u) +- continue; ++ p = PATH(k); + + if (p->state == PATH_RUNNING && new_state == UNIT_INACTIVE) { + log_debug("%s got notified about unit deactivation.", p->meta.id); +@@ -685,11 +683,6 @@ void path_unit_notify(Unit *u, UnitActiveState new_state) { + path_enter_waiting(p, false, p->inotify_triggered); + } + } +- +- return; +- +-fail: +- log_error("Failed find path unit: %s", strerror(-r)); + } + + static void path_reset_failed(Unit *u) { +diff --git a/src/path.h b/src/path.h +index 1d78fe4..8b3c0bc 100644 +--- a/src/path.h ++++ b/src/path.h +@@ -58,14 +58,14 @@ typedef struct PathSpec { + int primary_wd; + + bool previous_exists; +- + } 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) { ++int path_spec_watch(PathSpec *s, Unit *u); ++void path_spec_unwatch(PathSpec *s, Unit *u); ++int path_spec_fd_event(PathSpec *s, uint32_t events); ++void path_spec_done(PathSpec *s); ++ ++static inline bool path_spec_owns_inotify_fd(PathSpec *s, int fd) { + return s->inotify_fd == fd; + } + +@@ -74,7 +74,7 @@ struct Path { + + LIST_HEAD(PathSpec, specs); + +- Unit *unit; ++ UnitRef unit; + + PathState state, deserialized_state; + +diff --git a/src/service.c b/src/service.c +index 65a45e1..81a2954 100644 +--- a/src/service.c ++++ b/src/service.c +@@ -187,11 +187,11 @@ static void service_close_socket_fd(Service *s) { + static void service_connection_unref(Service *s) { + assert(s); + +- if (!s->accept_socket) ++ if (!UNIT_DEREF(s->accept_socket)) + return; + +- socket_connection_unref(s->accept_socket); +- s->accept_socket = NULL; ++ socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket))); ++ unit_ref_unset(&s->accept_socket); + } + + static void service_done(Unit *u) { +@@ -232,7 +232,7 @@ static void service_done(Unit *u) { + service_close_socket_fd(s); + service_connection_unref(s); + +- set_free(s->configured_sockets); ++ unit_ref_unset(&s->accept_socket); + + unit_unwatch_timer(u, &s->timer_watch); + } +@@ -1100,22 +1100,6 @@ static int service_add_default_dependencies(Service *s) { + return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); + } + +-static int service_add_socket_dependencies(Service *s) { +- Iterator i; +- Unit *u; +- int r; +- +- /* Make sure we pull in all explicitly configured sockets */ +- +- SET_FOREACH(u, s->configured_sockets, i) { +- r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, u, true); +- if (r < 0) +- return r; +- } +- +- return 0; +-} +- + static void service_fix_output(Service *s) { + assert(s); + +@@ -1189,12 +1173,6 @@ static int service_load(Unit *u) { + if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true)) < 0) + return r; + +- if (!set_isempty(s->configured_sockets)) { +- r = service_add_socket_dependencies(s); +- if (r < 0) +- return r; +- } +- + if (s->meta.default_dependencies) + if ((r = service_add_default_dependencies(s)) < 0) + return r; +@@ -1385,86 +1363,22 @@ static int service_search_main_pid(Service *s) { + return 0; + } + +-static int service_get_sockets(Service *s, Set **_set) { +- Set *set; ++static void service_notify_sockets_dead(Service *s) { + Iterator i; +- char *t; +- int r; +- +- assert(s); +- assert(_set); +- +- if (s->socket_fd >= 0) +- return 0; +- +- if (!set_isempty(s->configured_sockets)) +- return 0; +- +- /* Collects all Socket objects that belong to this +- * service. Note that a service might have multiple sockets +- * via multiple names. */ +- +- if (!(set = set_new(NULL, NULL))) +- return -ENOMEM; +- +- SET_FOREACH(t, s->meta.names, i) { +- char *k; +- Unit *p; +- +- /* Look for all socket objects that go by any of our +- * units and collect their fds */ +- +- if (!(k = unit_name_change_suffix(t, ".socket"))) { +- r = -ENOMEM; +- goto fail; +- } +- +- p = manager_get_unit(s->meta.manager, k); +- free(k); +- +- if (!p) +- continue; +- +- if ((r = set_put(set, p)) < 0) +- goto fail; +- } +- +- *_set = set; +- return 0; +- +-fail: +- set_free(set); +- return r; +-} +- +-static int service_notify_sockets_dead(Service *s) { +- Iterator i; +- Set *set, *free_set = NULL; +- Socket *sock; +- int r; ++ Unit *u; + + assert(s); + + /* Notifies all our sockets when we die */ + + if (s->socket_fd >= 0) +- return 0; +- +- if (!set_isempty(s->configured_sockets)) +- set = s->configured_sockets; +- else { +- if ((r = service_get_sockets(s, &free_set)) < 0) +- return r; +- +- set = free_set; +- } +- +- SET_FOREACH(sock, set, i) +- socket_notify_service_dead(sock); ++ return; + +- set_free(free_set); ++ SET_FOREACH(u, s->meta.dependencies[UNIT_TRIGGERED_BY], i) ++ if (u->meta.type == UNIT_SOCKET) ++ socket_notify_service_dead(SOCKET(u)); + +- return 0; ++ return; + } + + static void service_unwatch_pid_file(Service *s) { +@@ -1472,8 +1386,8 @@ static void service_unwatch_pid_file(Service *s) { + 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); ++ path_spec_unwatch(s->pid_file_pathspec, UNIT(s)); ++ path_spec_done(s->pid_file_pathspec); + free(s->pid_file_pathspec); + s->pid_file_pathspec = NULL; + } +@@ -1636,8 +1550,7 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) { + int r; + int *rfds = NULL; + unsigned rn_fds = 0; +- Set *set, *free_set = NULL; +- Socket *sock; ++ Unit *u; + + assert(s); + assert(fds); +@@ -1646,18 +1559,15 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) { + if (s->socket_fd >= 0) + return 0; + +- if (!set_isempty(s->configured_sockets)) +- set = s->configured_sockets; +- else { +- if ((r = service_get_sockets(s, &free_set)) < 0) +- return r; +- +- set = free_set; +- } +- +- SET_FOREACH(sock, set, i) { ++ SET_FOREACH(u, s->meta.dependencies[UNIT_TRIGGERED_BY], i) { + int *cfds; + unsigned cn_fds; ++ Socket *sock; ++ ++ if (u->meta.type != UNIT_SOCKET) ++ continue; ++ ++ sock = SOCKET(u); + + if ((r = socket_collect_fds(sock, &cfds, &cn_fds)) < 0) + goto fail; +@@ -1690,12 +1600,9 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) { + *fds = rfds; + *n_fds = rn_fds; + +- set_free(free_set); +- + return 0; + + fail: +- set_free(set); + free(rfds); + + return r; +@@ -2651,7 +2558,7 @@ 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)); ++ r = path_spec_watch(s->pid_file_pathspec, UNIT(s)); + if (r < 0) + goto fail; + +@@ -2701,11 +2608,11 @@ static void service_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + 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)); ++ assert(path_spec_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) ++ if (path_spec_fd_event(s->pid_file_pathspec, events) < 0) + goto fail; + + if (service_retry_pid_file(s) == 0) +@@ -3450,6 +3357,7 @@ static void service_bus_query_pid_done( + } + + int service_set_socket_fd(Service *s, int fd, Socket *sock) { ++ + assert(s); + assert(fd >= 0); + +@@ -3468,9 +3376,10 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock) { + + s->socket_fd = fd; + s->got_socket_fd = true; +- s->accept_socket = sock; + +- return 0; ++ unit_ref_set(&s->accept_socket, UNIT(sock)); ++ ++ return unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false); + } + + static void service_reset_failed(Unit *u) { +diff --git a/src/service.h b/src/service.h +index 2102826..8f67ad5 100644 +--- a/src/service.h ++++ b/src/service.h +@@ -27,6 +27,7 @@ typedef struct Service Service; + #include "unit.h" + #include "path.h" + #include "ratelimit.h" ++#include "service.h" + + typedef enum ServiceState { + SERVICE_DEAD, +@@ -154,8 +155,7 @@ struct Service { + + RateLimit ratelimit; + +- struct Socket *accept_socket; +- Set *configured_sockets; ++ UnitRef accept_socket; + + Watch timer_watch; + PathSpec *pid_file_pathspec; +@@ -165,6 +165,8 @@ struct Service { + + extern const UnitVTable service_vtable; + ++struct Socket; ++ + int service_set_socket_fd(Service *s, int fd, struct Socket *socket); + + const char* service_state_to_string(ServiceState i); +diff --git a/src/socket.c b/src/socket.c +index 1f5e067..7034436 100644 +--- a/src/socket.c ++++ b/src/socket.c +@@ -98,7 +98,6 @@ static void socket_unwatch_control_pid(Socket *s) { + static void socket_done(Unit *u) { + Socket *s = SOCKET(u); + SocketPort *p; +- Meta *i; + + assert(s); + +@@ -120,7 +119,7 @@ static void socket_done(Unit *u) { + + socket_unwatch_control_pid(s); + +- s->service = NULL; ++ unit_ref_unset(&s->service); + + free(s->tcp_congestion); + s->tcp_congestion = NULL; +@@ -129,16 +128,6 @@ static void socket_done(Unit *u) { + s->bind_to_device = NULL; + + unit_unwatch_timer(u, &s->timer_watch); +- +- /* Make sure no service instance refers to us anymore. */ +- LIST_FOREACH(units_by_type, i, u->meta.manager->units_by_type[UNIT_SERVICE]) { +- Service *service = (Service *) i; +- +- if (service->accept_socket == s) +- service->accept_socket = NULL; +- +- set_remove(service->configured_sockets, s); +- } + } + + static int socket_instantiate_service(Socket *s) { +@@ -153,7 +142,7 @@ static int socket_instantiate_service(Socket *s) { + * here. For Accept=no this is mostly a NOP since the service + * is figured out at load time anyway. */ + +- if (s->service) ++ if (UNIT_DEREF(s->service)) + return 0; + + assert(s->accept); +@@ -181,8 +170,9 @@ static int socket_instantiate_service(Socket *s) { + #endif + + u->meta.no_gc = true; +- s->service = SERVICE(u); +- return 0; ++ unit_ref_set(&s->service, u); ++ ++ return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false); + } + + static bool have_non_accept_socket(Socket *s) { +@@ -226,7 +216,7 @@ static int socket_verify(Socket *s) { + return -EINVAL; + } + +- if (s->accept && s->service) { ++ if (s->accept && UNIT_DEREF(s->service)) { + log_error("Explicit service configuration for accepting sockets not supported on %s. Refusing.", s->meta.id); + return -EINVAL; + } +@@ -349,11 +339,18 @@ static int socket_load(Unit *u) { + + if (have_non_accept_socket(s)) { + +- if (!s->service) +- if ((r = unit_load_related_unit(u, ".service", (Unit**) &s->service)) < 0) ++ if (!UNIT_DEREF(s->service)) { ++ Unit *x; ++ ++ r = unit_load_related_unit(u, ".service", &x); ++ if (r < 0) + return r; + +- if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service), true)) < 0) ++ unit_ref_set(&s->service, x); ++ } ++ ++ r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true); ++ if (r < 0) + return r; + } + +@@ -912,8 +909,9 @@ static int socket_open_fds(Socket *s) { + if ((r = socket_instantiate_service(s)) < 0) + return r; + +- if (s->service && s->service->exec_command[SERVICE_EXEC_START]) { +- r = label_get_create_label_from_exe(s->service->exec_command[SERVICE_EXEC_START]->path, &label); ++ if (UNIT_DEREF(s->service) && ++ SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) { ++ r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label); + + if (r < 0) { + if (r != -EPERM) +@@ -1380,26 +1378,20 @@ static void socket_enter_running(Socket *s, int cfd) { + } + + if (cfd < 0) { ++ Iterator i; ++ Unit *u; + bool pending = false; +- Meta *i; + + /* If there's already a start pending don't bother to + * do anything */ +- LIST_FOREACH(units_by_type, i, s->meta.manager->units_by_type[UNIT_SERVICE]) { +- Service *service = (Service *) i; +- +- if (!set_get(service->configured_sockets, s)) +- continue; +- +- if (!unit_pending_active(UNIT(service))) +- continue; +- +- pending = true; +- break; +- } ++ SET_FOREACH(u, s->meta.dependencies[UNIT_TRIGGERS], i) ++ if (unit_pending_active(u)) { ++ pending = true; ++ break; ++ } + + if (!pending) +- if ((r = manager_add_job(s->meta.manager, JOB_START, UNIT(s->service), JOB_REPLACE, true, &error, NULL)) < 0) ++ if ((r = manager_add_job(s->meta.manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL)) < 0) + goto fail; + + socket_set_state(s, SOCKET_RUNNING); +@@ -1434,13 +1426,13 @@ static void socket_enter_running(Socket *s, int cfd) { + goto fail; + } + +- if ((r = unit_add_name(UNIT(s->service), name)) < 0) { ++ if ((r = unit_add_name(UNIT_DEREF(s->service), name)) < 0) { + free(name); + goto fail; + } + +- service = s->service; +- s->service = NULL; ++ service = SERVICE(UNIT_DEREF(s->service)); ++ unit_ref_unset(&s->service); + s->n_accepted ++; + + service->meta.no_gc = false; +@@ -1523,23 +1515,27 @@ static int socket_start(Unit *u) { + return 0; + + /* Cannot run this without the service being around */ +- if (s->service) { +- if (s->service->meta.load_state != UNIT_LOADED) { +- log_error("Socket service %s not loaded, refusing.", s->service->meta.id); ++ if (UNIT_DEREF(s->service)) { ++ Service *service; ++ ++ service = SERVICE(UNIT_DEREF(s->service)); ++ ++ if (service->meta.load_state != UNIT_LOADED) { ++ log_error("Socket service %s not loaded, refusing.", service->meta.id); + return -ENOENT; + } + + /* If the service is already active we cannot start the + * socket */ +- if (s->service->state != SERVICE_DEAD && +- s->service->state != SERVICE_FAILED && +- s->service->state != SERVICE_AUTO_RESTART) { +- log_error("Socket service %s already active, refusing.", s->service->meta.id); ++ if (service->state != SERVICE_DEAD && ++ service->state != SERVICE_FAILED && ++ service->state != SERVICE_AUTO_RESTART) { ++ log_error("Socket service %s already active, refusing.", service->meta.id); + return -EBUSY; + } + + #ifdef HAVE_SYSV_COMPAT +- if (s->service->sysv_path) { ++ if (service->sysv_path) { + log_error("Using SysV services for socket activation is not supported. Refusing."); + return -ENOENT; + } +diff --git a/src/socket.h b/src/socket.h +index fbd29da..4fc2cbe 100644 +--- a/src/socket.h ++++ b/src/socket.h +@@ -28,6 +28,7 @@ typedef struct Socket Socket; + #include "unit.h" + #include "socket-util.h" + #include "mount.h" ++#include "service.h" + + typedef enum SocketState { + SOCKET_DEAD, +@@ -93,7 +94,7 @@ struct Socket { + /* For Accept=no sockets refers to the one service we'll + activate. For Accept=yes sockets is either NULL, or filled + when the next service we spawn. */ +- Service *service; ++ UnitRef service; + + SocketState state, deserialized_state; + +@@ -103,9 +104,6 @@ struct Socket { + SocketExecCommand control_command_id; + pid_t control_pid; + +- /* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */ +- SocketAddressBindIPv6Only bind_ipv6_only; +- + mode_t directory_mode; + mode_t socket_mode; + +@@ -130,6 +128,9 @@ struct Socket { + char *tcp_congestion; + long mq_maxmsg; + long mq_msgsize; ++ ++ /* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */ ++ SocketAddressBindIPv6Only bind_ipv6_only; + }; + + /* Called from the service code when collecting fds */ +diff --git a/src/timer.c b/src/timer.c +index e6f207f..c732076 100644 +--- a/src/timer.c ++++ b/src/timer.c +@@ -57,6 +57,8 @@ static void timer_done(Unit *u) { + } + + unit_unwatch_timer(u, &t->timer_watch); ++ ++ unit_ref_unset(&t->unit); + } + + static int timer_verify(Timer *t) { +@@ -101,11 +103,18 @@ static int timer_load(Unit *u) { + + if (u->meta.load_state == UNIT_LOADED) { + +- if (!t->unit) +- if ((r = unit_load_related_unit(u, ".service", &t->unit))) ++ if (!UNIT_DEREF(t->unit)) { ++ Unit *x; ++ ++ r = unit_load_related_unit(u, ".service", &x); ++ if (r < 0) + return r; + +- if ((r = unit_add_dependency(u, UNIT_BEFORE, t->unit, true)) < 0) ++ unit_ref_set(&t->unit, x); ++ } ++ ++ r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(t->unit), true); ++ if (r < 0) + return r; + + if (t->meta.default_dependencies) +@@ -126,7 +135,7 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) { + "%sTimer State: %s\n" + "%sUnit: %s\n", + prefix, timer_state_to_string(t->state), +- prefix, t->unit->meta.id); ++ prefix, UNIT_DEREF(t->unit)->meta.id); + + LIST_FOREACH(value, v, t->values) + fprintf(f, +@@ -216,18 +225,18 @@ static void timer_enter_waiting(Timer *t, bool initial) { + + case TIMER_UNIT_ACTIVE: + +- if (t->unit->meta.inactive_exit_timestamp.monotonic <= 0) ++ if (UNIT_DEREF(t->unit)->meta.inactive_exit_timestamp.monotonic <= 0) + continue; + +- base = t->unit->meta.inactive_exit_timestamp.monotonic; ++ base = UNIT_DEREF(t->unit)->meta.inactive_exit_timestamp.monotonic; + break; + + case TIMER_UNIT_INACTIVE: + +- if (t->unit->meta.inactive_enter_timestamp.monotonic <= 0) ++ if (UNIT_DEREF(t->unit)->meta.inactive_enter_timestamp.monotonic <= 0) + continue; + +- base = t->unit->meta.inactive_enter_timestamp.monotonic; ++ base = UNIT_DEREF(t->unit)->meta.inactive_enter_timestamp.monotonic; + break; + + default: +@@ -278,7 +287,7 @@ static void timer_enter_running(Timer *t) { + if (t->meta.job && t->meta.job->type == JOB_STOP) + return; + +- if ((r = manager_add_job(t->meta.manager, JOB_START, t->unit, JOB_REPLACE, true, &error, NULL)) < 0) ++ if ((r = manager_add_job(t->meta.manager, JOB_START, UNIT_DEREF(t->unit), JOB_REPLACE, true, &error, NULL)) < 0) + goto fail; + + timer_set_state(t, TIMER_RUNNING); +@@ -297,7 +306,7 @@ static int timer_start(Unit *u) { + assert(t); + assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED); + +- if (t->unit->meta.load_state != UNIT_LOADED) ++ if (UNIT_DEREF(t->unit)->meta.load_state != UNIT_LOADED) + return -ENOENT; + + t->failure = false; +@@ -374,37 +383,24 @@ static void timer_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + } + + void timer_unit_notify(Unit *u, UnitActiveState new_state) { +- char *n; + int r; + Iterator i; ++ Unit *k; + + if (u->meta.type == UNIT_TIMER) + return; + +- SET_FOREACH(n, u->meta.names, i) { +- char *k; +- Unit *p; ++ SET_FOREACH(k, u->meta.dependencies[UNIT_TRIGGERED_BY], i) { + Timer *t; + TimerValue *v; + +- if (!(k = unit_name_change_suffix(n, ".timer"))) { +- r = -ENOMEM; +- goto fail; +- } +- +- p = manager_get_unit(u->meta.manager, k); +- free(k); +- +- if (!p) ++ if (k->meta.type != UNIT_TIMER) + continue; + +- if (p->meta.load_state != UNIT_LOADED) ++ if (k->meta.load_state != UNIT_LOADED) + continue; + +- t = TIMER(p); +- +- if (t->unit != u) +- continue; ++ t = TIMER(k); + + /* Reenable all timers that depend on unit state */ + LIST_FOREACH(value, v, t->values) +@@ -438,11 +434,6 @@ void timer_unit_notify(Unit *u, UnitActiveState new_state) { + assert_not_reached("Unknown timer state"); + } + } +- +- return; +- +-fail: +- log_error("Failed find timer unit: %s", strerror(-r)); + } + + static void timer_reset_failed(Unit *u) { +diff --git a/src/timer.h b/src/timer.h +index 6295605..ad55cf7 100644 +--- a/src/timer.h ++++ b/src/timer.h +@@ -63,7 +63,7 @@ struct Timer { + usec_t next_elapse; + + TimerState state, deserialized_state; +- Unit *unit; ++ UnitRef unit; + + Watch timer_watch; + +diff --git a/src/unit.c b/src/unit.c +index 3191071..7ce783e 100644 +--- a/src/unit.c ++++ b/src/unit.c +@@ -377,12 +377,15 @@ void unit_free(Unit *u) { + + free(u->meta.description); + free(u->meta.fragment_path); ++ free(u->meta.instance); + + set_free_free(u->meta.names); + + condition_free_list(u->meta.conditions); + +- free(u->meta.instance); ++ while (u->meta.refs) ++ unit_ref_unset(u->meta.refs); ++ + free(u); + } + +@@ -498,6 +501,10 @@ int unit_merge(Unit *u, Unit *other) { + /* Merge names */ + merge_names(u, other); + ++ /* Redirect all references */ ++ while (other->meta.refs) ++ unit_ref_set(other->meta.refs, u); ++ + /* Merge dependencies */ + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) + merge_dependencies(u, other, d); +@@ -1526,7 +1533,9 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen + [UNIT_AFTER] = UNIT_BEFORE, + [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID, + [UNIT_REFERENCES] = UNIT_REFERENCED_BY, +- [UNIT_REFERENCED_BY] = UNIT_REFERENCES ++ [UNIT_REFERENCED_BY] = UNIT_REFERENCES, ++ [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY, ++ [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS + }; + int r, q = 0, v = 0, w = 0; + +@@ -2588,6 +2597,28 @@ UnitFileState unit_get_unit_file_state(Unit *u) { + return u->meta.unit_file_state; + } + ++Unit* unit_ref_set(UnitRef *ref, Unit *u) { ++ assert(ref); ++ assert(u); ++ ++ if (ref->unit) ++ unit_ref_unset(ref); ++ ++ ref->unit = u; ++ LIST_PREPEND(UnitRef, refs, u->meta.refs, ref); ++ return u; ++} ++ ++void unit_ref_unset(UnitRef *ref) { ++ assert(ref); ++ ++ if (!ref->unit) ++ return; ++ ++ LIST_REMOVE(UnitRef, refs, ref->unit->meta.refs, ref); ++ ref->unit = NULL; ++} ++ + static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = { + [UNIT_STUB] = "stub", + [UNIT_LOADED] = "loaded", +@@ -2626,7 +2657,9 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { + [UNIT_AFTER] = "After", + [UNIT_REFERENCES] = "References", + [UNIT_REFERENCED_BY] = "ReferencedBy", +- [UNIT_ON_FAILURE] = "OnFailure" ++ [UNIT_ON_FAILURE] = "OnFailure", ++ [UNIT_TRIGGERS] = "Triggers", ++ [UNIT_TRIGGERED_BY] = "TriggeredBy" + }; + + DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency); +diff --git a/src/unit.h b/src/unit.h +index b32c1a7..4d83309 100644 +--- a/src/unit.h ++++ b/src/unit.h +@@ -32,6 +32,7 @@ typedef enum UnitType UnitType; + typedef enum UnitLoadState UnitLoadState; + typedef enum UnitActiveState UnitActiveState; + typedef enum UnitDependency UnitDependency; ++typedef struct UnitRef UnitRef; + + #include "set.h" + #include "util.h" +@@ -119,6 +120,10 @@ enum UnitDependency { + /* On Failure */ + UNIT_ON_FAILURE, + ++ /* Triggers (i.e. a socket triggers a service) */ ++ UNIT_TRIGGERS, ++ UNIT_TRIGGERED_BY, ++ + /* Reference information for GC logic */ + UNIT_REFERENCES, /* Inverse of 'references' is 'referenced_by' */ + UNIT_REFERENCED_BY, +@@ -156,6 +161,9 @@ struct Meta { + + usec_t job_timeout; + ++ /* References to this */ ++ LIST_HEAD(UnitRef, refs); ++ + /* Conditions to check */ + LIST_HEAD(Condition, conditions); + +@@ -237,6 +245,15 @@ struct Meta { + bool in_audit:1; + }; + ++struct UnitRef { ++ /* Keeps tracks of references to a unit. This is useful so ++ * that we can merge two units if necessary and correct all ++ * references to them */ ++ ++ Unit* unit; ++ LIST_FIELDS(UnitRef, refs); ++}; ++ + #include "service.h" + #include "timer.h" + #include "socket.h" +@@ -536,6 +553,11 @@ bool unit_condition_test(Unit *u); + + UnitFileState unit_get_unit_file_state(Unit *u); + ++Unit* unit_ref_set(UnitRef *ref, Unit *u); ++void unit_ref_unset(UnitRef *ref); ++ ++#define UNIT_DEREF(ref) ((ref).unit) ++ + const char *unit_load_state_to_string(UnitLoadState i); + UnitLoadState unit_load_state_from_string(const char *s); + +-- +1.7.7.5 + diff --git a/0121-main-fix-spelling.patch b/0121-main-fix-spelling.patch new file mode 100644 index 0000000..112c80a --- /dev/null +++ b/0121-main-fix-spelling.patch @@ -0,0 +1,87 @@ +From df9aafc94497610c8a8c9ccb0fcf5a67aa230087 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sat, 7 Jan 2012 00:59:15 +0100 +Subject: [PATCH 121/126] main: fix spelling (cherry picked from commit + 509b6efbbe8d0486d33036892293c575bd4d0736) + +--- + src/main.c | 16 ++++++++-------- + 1 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/main.c b/src/main.c +index 5c28a6c..cdf32bf 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -270,7 +270,7 @@ static int parse_proc_cmdline_word(const char *word) { + int r; + + if ((r = parse_boolean(word + 18)) < 0) +- log_warning("Failed to parse dump core switch %s, Ignoring.", word + 18); ++ log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18); + else + arg_dump_core = r; + +@@ -278,7 +278,7 @@ static int parse_proc_cmdline_word(const char *word) { + int r; + + if ((r = parse_boolean(word + 20)) < 0) +- log_warning("Failed to parse crash shell switch %s, Ignoring.", word + 20); ++ log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20); + else + arg_crash_shell = r; + +@@ -286,7 +286,7 @@ static int parse_proc_cmdline_word(const char *word) { + int r; + + if ((r = parse_boolean(word + 22)) < 0) +- log_warning("Failed to parse confirm spawn switch %s, Ignoring.", word + 22); ++ log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22); + else + arg_confirm_spawn = r; + +@@ -294,7 +294,7 @@ static int parse_proc_cmdline_word(const char *word) { + int k; + + if (safe_atoi(word + 19, &k) < 0) +- log_warning("Failed to parse crash chvt switch %s, Ignoring.", word + 19); ++ log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19); + else + arg_crash_chvt = k; + +@@ -302,21 +302,21 @@ static int parse_proc_cmdline_word(const char *word) { + int r; + + if ((r = parse_boolean(word + 20)) < 0) +- log_warning("Failed to parse show status switch %s, Ignoring.", word + 20); ++ log_warning("Failed to parse show status switch %s. Ignoring.", word + 20); + else + arg_show_status = r; + } else if (startswith(word, "systemd.default_standard_output=")) { + int r; + + if ((r = exec_output_from_string(word + 32)) < 0) +- log_warning("Failed to parse default standard output switch %s, Ignoring.", word + 32); ++ log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32); + else + arg_default_std_output = r; + } else if (startswith(word, "systemd.default_standard_error=")) { + int r; + + if ((r = exec_output_from_string(word + 31)) < 0) +- log_warning("Failed to parse default standard error switch %s, Ignoring.", word + 31); ++ log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31); + else + arg_default_std_error = r; + #ifdef HAVE_SYSV_COMPAT +@@ -324,7 +324,7 @@ static int parse_proc_cmdline_word(const char *word) { + int r; + + if ((r = parse_boolean(word + 21)) < 0) +- log_warning("Failed to parse SysV console switch %s, Ignoring.", word + 20); ++ log_warning("Failed to parse SysV console switch %s. Ignoring.", word + 20); + else + arg_sysv_console = r; + #endif +-- +1.7.7.5 + diff --git a/0122-load-fragment-fix-parsing-of-Socket-setting.patch b/0122-load-fragment-fix-parsing-of-Socket-setting.patch new file mode 100644 index 0000000..84731bf --- /dev/null +++ b/0122-load-fragment-fix-parsing-of-Socket-setting.patch @@ -0,0 +1,43 @@ +From 22af36b4ce7e01e0f50cd1a5679b54304bd06599 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sat, 7 Jan 2012 01:21:40 +0100 +Subject: [PATCH 122/126] load-fragment: fix parsing of Socket= setting + (cherry picked from commit + 4ff77f66af8bd3e7e403c81febb7a2471457c5da) + +--- + src/load-fragment.c | 6 +++++- + 1 files changed, 5 insertions(+), 1 deletions(-) + +diff --git a/src/load-fragment.c b/src/load-fragment.c +index 1903190..ef5d192 100644 +--- a/src/load-fragment.c ++++ b/src/load-fragment.c +@@ -1386,6 +1386,7 @@ int config_parse_socket_service( + Socket *s = data; + int r; + DBusError error; ++ Unit *x; + + assert(filename); + assert(lvalue); +@@ -1399,12 +1400,15 @@ int config_parse_socket_service( + return 0; + } + +- if ((r = manager_load_unit(s->meta.manager, rvalue, NULL, &error, (Unit**) &s->service)) < 0) { ++ r = manager_load_unit(s->meta.manager, rvalue, NULL, &error, &x); ++ if (r < 0) { + log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r)); + dbus_error_free(&error); + return 0; + } + ++ unit_ref_set(&s->service, x); ++ + return 0; + } + +-- +1.7.7.5 + diff --git a/0123-fix-compiler-warning.patch b/0123-fix-compiler-warning.patch new file mode 100644 index 0000000..83961f6 --- /dev/null +++ b/0123-fix-compiler-warning.patch @@ -0,0 +1,25 @@ +From e9926ed4c022cd98b6174d675546b04900df91e4 Mon Sep 17 00:00:00 2001 +From: Kay Sievers +Date: Sat, 7 Jan 2012 02:12:43 +0100 +Subject: [PATCH 123/126] fix compiler warning (cherry picked from commit + ebd91b34d749cf29308d15601b5fbc971b4dab89) + +--- + src/timer.c | 1 - + 1 files changed, 0 insertions(+), 1 deletions(-) + +diff --git a/src/timer.c b/src/timer.c +index c732076..d127a11 100644 +--- a/src/timer.c ++++ b/src/timer.c +@@ -383,7 +383,6 @@ static void timer_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + } + + void timer_unit_notify(Unit *u, UnitActiveState new_state) { +- int r; + Iterator i; + Unit *k; + +-- +1.7.7.5 + diff --git a/0124-shutdown-exclude-processes-with-argv-0-0-from-killin.patch b/0124-shutdown-exclude-processes-with-argv-0-0-from-killin.patch new file mode 100644 index 0000000..ae35f8d --- /dev/null +++ b/0124-shutdown-exclude-processes-with-argv-0-0-from-killin.patch @@ -0,0 +1,176 @@ +From 8538925add03eb761143d999baa12c11c4b6d286 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 10 Jan 2012 04:20:55 +0100 +Subject: [PATCH 124/126] shutdown: exclude processes with argv[0][0] from + killing (cherry picked from commit + 7e4ab3c5a6295193d0c58d353b6430265d842f34) + +Conflicts: + + src/systemd/sd-journal.h + src/util.c + src/util.h +--- + src/shutdown.c | 44 +++++++++++++++++++++++++++++--------------- + src/util.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ + src/util.h | 1 + + 3 files changed, 81 insertions(+), 15 deletions(-) + +diff --git a/src/shutdown.c b/src/shutdown.c +index 11213f9..46b5aea 100644 +--- a/src/shutdown.c ++++ b/src/shutdown.c +@@ -47,29 +47,45 @@ + #define FINALIZE_ATTEMPTS 50 + + static bool ignore_proc(pid_t pid) { ++ char buf[PATH_MAX]; ++ FILE *f; ++ char c; ++ size_t count; ++ uid_t uid; ++ int r; ++ ++ /* We are PID 1, let's not commit suicide */ + if (pid == 1) + return true; + +- /* TODO: add more ignore rules here: device-mapper, etc */ ++ r = get_process_uid(pid, &uid); ++ if (r < 0) ++ return true; /* not really, but better safe than sorry */ + +- return false; +-} ++ /* Non-root processes otherwise are always subject to be killed */ ++ if (uid != 0) ++ return false; + +-static bool is_kernel_thread(pid_t pid) +-{ +- char buf[PATH_MAX]; +- FILE *f; +- char c; +- size_t count; ++ snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid); ++ char_array_0(buf); + +- snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long)pid); + f = fopen(buf, "re"); + if (!f) + return true; /* not really, but has the desired effect */ + + count = fread(&c, 1, 1, f); + fclose(f); +- return count != 1; ++ ++ /* Kernel threads have an empty cmdline */ ++ if (count <= 0) ++ return true; ++ ++ /* Processes with argv[0][0] = '@' we ignore from the killing ++ * spree. */ ++ if (count == 1 && c == '@') ++ return true; ++ ++ return false; + } + + static int killall(int sign) { +@@ -77,7 +93,8 @@ static int killall(int sign) { + struct dirent *d; + unsigned int n_processes = 0; + +- if ((dir = opendir("/proc")) == NULL) ++ dir = opendir("/proc"); ++ if (!dir) + return -errno; + + while ((d = readdir(dir))) { +@@ -86,9 +103,6 @@ static int killall(int sign) { + if (parse_pid(d->d_name, &pid) < 0) + continue; + +- if (is_kernel_thread(pid)) +- continue; +- + if (ignore_proc(pid)) + continue; + +diff --git a/src/util.c b/src/util.c +index 5bac05f..497fd05 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -1090,6 +1090,57 @@ int get_process_cmdline(pid_t pid, size_t max_length, char **line) { + return 0; + } + ++int get_process_uid(pid_t pid, uid_t *uid) { ++ char *p; ++ FILE *f; ++ int r; ++ ++ assert(uid); ++ ++ if (pid == 0) ++ return getuid(); ++ ++ if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0) ++ return -ENOMEM; ++ ++ f = fopen(p, "re"); ++ free(p); ++ ++ if (!f) ++ return -errno; ++ ++ while (!feof(f)) { ++ char line[LINE_MAX], *l; ++ ++ if (!fgets(line, sizeof(line), f)) { ++ if (feof(f)) ++ break; ++ ++ r = -errno; ++ goto finish; ++ } ++ ++ l = strstrip(line); ++ ++ if (startswith(l, "Uid:")) { ++ l += 4; ++ l += strspn(l, WHITESPACE); ++ ++ l[strcspn(l, WHITESPACE)] = 0; ++ ++ r = parse_uid(l, uid); ++ goto finish; ++ } ++ } ++ ++ r = -EIO; ++ ++finish: ++ fclose(f); ++ ++ return r; ++} ++ + char *strnappend(const char *s, const char *suffix, size_t b) { + size_t a; + char *r; +diff --git a/src/util.h b/src/util.h +index 40a2a39..944c7d2 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -250,6 +250,7 @@ int rmdir_parents(const char *path, const char *stop); + + int get_process_name(pid_t pid, char **name); + int get_process_cmdline(pid_t pid, size_t max_length, char **line); ++int get_process_uid(pid_t pid, uid_t *uid); + + char hexchar(int x); + int unhexchar(char c); +-- +1.7.7.5 + diff --git a/0125-shutdown-add-link-to-root-storage-daemon-text.patch b/0125-shutdown-add-link-to-root-storage-daemon-text.patch new file mode 100644 index 0000000..8cf3914 --- /dev/null +++ b/0125-shutdown-add-link-to-root-storage-daemon-text.patch @@ -0,0 +1,29 @@ +From cd6e5f49b99a587b256857b66d37202ae5cfe027 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 11 Jan 2012 01:51:52 +0100 +Subject: [PATCH 125/126] shutdown: add link to root storage daemon text + (cherry picked from commit + bd1a69818042e85e24ec3adaf5eb3ac30ab1d9fd) + +--- + src/shutdown.c | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/src/shutdown.c b/src/shutdown.c +index 46b5aea..d157e0f 100644 +--- a/src/shutdown.c ++++ b/src/shutdown.c +@@ -81,7 +81,9 @@ static bool ignore_proc(pid_t pid) { + return true; + + /* Processes with argv[0][0] = '@' we ignore from the killing +- * spree. */ ++ * spree. ++ * ++ * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */ + if (count == 1 && c == '@') + return true; + +-- +1.7.7.5 + diff --git a/0126-unit-implement-new-PropagateReloadTo-PropagateReload.patch b/0126-unit-implement-new-PropagateReloadTo-PropagateReload.patch new file mode 100644 index 0000000..bff5a87 --- /dev/null +++ b/0126-unit-implement-new-PropagateReloadTo-PropagateReload.patch @@ -0,0 +1,161 @@ +From ca96079f33b100e32dd2eb624a946058b6ff49f1 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 11 Jan 2012 02:47:14 +0100 +Subject: [PATCH 126/126] unit: implement new + PropagateReloadTo=/PropagateReloadFrom= operations + (cherry picked from commit + 4dcc1cb4155c4a72155e36a5461ab0847d4f1bf1) + +--- + man/systemd.unit.xml | 16 ++++++++++++++++ + src/dbus-unit.h | 6 ++++++ + src/load-fragment-gperf.gperf.m4 | 2 ++ + src/manager.c | 18 +++++++++++++++++- + src/unit.c | 8 ++++++-- + src/unit.h | 4 ++++ + 6 files changed, 51 insertions(+), 3 deletions(-) + +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index 897f99f..30559b9 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -510,6 +510,22 @@ + + + ++ PropagateReloadTo= ++ PropagateReloadFrom= ++ ++ Lists one or more ++ units where reload requests on the ++ unit will be propagated to/on the ++ other unit will be propagated ++ from. Issuing a reload request on a ++ unit will automatically also enqueue a ++ reload request on all units that the ++ reload request shall be propagated to ++ via these two ++ settings. ++ ++ ++ + OnFailureIsolate= + + Takes a boolean +diff --git a/src/dbus-unit.h b/src/dbus-unit.h +index 20d5506..7a43410 100644 +--- a/src/dbus-unit.h ++++ b/src/dbus-unit.h +@@ -80,6 +80,10 @@ + " \n" \ + " \n" \ + " \n" \ ++ " \n" \ ++ " \n" \ ++ " \n" \ ++ " \n" \ + " \n" \ + " \n" \ + " \n" \ +@@ -143,6 +147,8 @@ + { "org.freedesktop.systemd1.Unit", "OnFailure", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_ON_FAILURE] }, \ + { "org.freedesktop.systemd1.Unit", "Triggers", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_TRIGGERS] }, \ + { "org.freedesktop.systemd1.Unit", "TriggeredBy", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_TRIGGERED_BY] }, \ ++ { "org.freedesktop.systemd1.Unit", "PropagateReloadTo", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_PROPAGATE_RELOAD_TO] }, \ ++ { "org.freedesktop.systemd1.Unit", "PropagateReloadFrom", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_PROPAGATE_RELOAD_FROM] }, \ + { "org.freedesktop.systemd1.Unit", "Description", bus_unit_append_description, "s", u }, \ + { "org.freedesktop.systemd1.Unit", "LoadState", bus_unit_append_load_state, "s", &u->meta.load_state }, \ + { "org.freedesktop.systemd1.Unit", "ActiveState", bus_unit_append_active_state, "s", u }, \ +diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4 +index 81e186c..11e6324 100644 +--- a/src/load-fragment-gperf.gperf.m4 ++++ b/src/load-fragment-gperf.gperf.m4 +@@ -100,6 +100,8 @@ Unit.Conflicts, config_parse_unit_deps, UNIT_CONFLI + Unit.Before, config_parse_unit_deps, UNIT_BEFORE, 0 + Unit.After, config_parse_unit_deps, UNIT_AFTER, 0 + Unit.OnFailure, config_parse_unit_deps, UNIT_ON_FAILURE, 0 ++Unit.PropagateReloadTo, config_parse_unit_deps, UNIT_PROPAGATE_RELOAD_TO, 0 ++Unit.PropagateReloadFrom, config_parse_unit_deps, UNIT_PROPAGATE_RELOAD_FROM, 0 + Unit.StopWhenUnneeded, config_parse_bool, 0, offsetof(Meta, stop_when_unneeded) + Unit.RefuseManualStart, config_parse_bool, 0, offsetof(Meta, refuse_manual_start) + Unit.RefuseManualStop, config_parse_bool, 0, offsetof(Meta, refuse_manual_stop) +diff --git a/src/manager.c b/src/manager.c +index 6acc821..98106dd 100644 +--- a/src/manager.c ++++ b/src/manager.c +@@ -1609,7 +1609,9 @@ static int transaction_add_job_and_dependencies( + dbus_error_free(e); + } + +- } else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) { ++ } ++ ++ if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) { + + SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i) + if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { +@@ -1632,6 +1634,20 @@ static int transaction_add_job_and_dependencies( + } + } + ++ if (type == JOB_RELOAD || type == JOB_RELOAD_OR_START) { ++ ++ SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_PROPAGATE_RELOAD_TO], i) { ++ r = transaction_add_job_and_dependencies(m, JOB_RELOAD, dep, ret, false, override, false, false, ignore_order, e, NULL); ++ ++ if (r < 0) { ++ log_warning("Cannot add dependency reload job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r)); ++ ++ if (e) ++ dbus_error_free(e); ++ } ++ } ++ } ++ + /* JOB_VERIFY_STARTED, JOB_RELOAD require no dependency handling */ + } + +diff --git a/src/unit.c b/src/unit.c +index 7ce783e..143b0e3 100644 +--- a/src/unit.c ++++ b/src/unit.c +@@ -1535,7 +1535,9 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen + [UNIT_REFERENCES] = UNIT_REFERENCED_BY, + [UNIT_REFERENCED_BY] = UNIT_REFERENCES, + [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY, +- [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS ++ [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS, ++ [UNIT_PROPAGATE_RELOAD_TO] = UNIT_PROPAGATE_RELOAD_FROM, ++ [UNIT_PROPAGATE_RELOAD_FROM] = UNIT_PROPAGATE_RELOAD_TO + }; + int r, q = 0, v = 0, w = 0; + +@@ -2659,7 +2661,9 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { + [UNIT_REFERENCED_BY] = "ReferencedBy", + [UNIT_ON_FAILURE] = "OnFailure", + [UNIT_TRIGGERS] = "Triggers", +- [UNIT_TRIGGERED_BY] = "TriggeredBy" ++ [UNIT_TRIGGERED_BY] = "TriggeredBy", ++ [UNIT_PROPAGATE_RELOAD_TO] = "PropagateReloadTo", ++ [UNIT_PROPAGATE_RELOAD_FROM] = "PropagateReloadFrom" + }; + + DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency); +diff --git a/src/unit.h b/src/unit.h +index 4d83309..19314d6 100644 +--- a/src/unit.h ++++ b/src/unit.h +@@ -124,6 +124,10 @@ enum UnitDependency { + UNIT_TRIGGERS, + UNIT_TRIGGERED_BY, + ++ /* Propagate reloads */ ++ UNIT_PROPAGATE_RELOAD_TO, ++ UNIT_PROPAGATE_RELOAD_FROM, ++ + /* Reference information for GC logic */ + UNIT_REFERENCES, /* Inverse of 'references' is 'referenced_by' */ + UNIT_REFERENCED_BY, +-- +1.7.7.5 + diff --git a/systemd-37-bug744415.patch b/systemd-37-bug744415.patch deleted file mode 100644 index 218847f..0000000 --- a/systemd-37-bug744415.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -up systemd-37/src/tty-ask-password-agent.c.744415 systemd-37/src/tty-ask-password-agent.c ---- systemd-37/src/tty-ask-password-agent.c.744415 2011-11-03 17:01:25.000000000 +0100 -+++ systemd-37/src/tty-ask-password-agent.c 2011-11-03 17:02:18.000000000 +0100 -@@ -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; diff --git a/systemd.spec b/systemd.spec index 3bddd03..c0590b1 100644 --- a/systemd.spec +++ b/systemd.spec @@ -2,7 +2,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Version: 37 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv2+ Group: System Environment/Base Summary: A System and Service Manager @@ -18,6 +18,8 @@ BuildRequires: docbook-style-xsl BuildRequires: vala >= 0.11 BuildRequires: pkgconfig BuildRequires: gtk2-devel +BuildRequires: glib2-devel +BuildRequires: libgee-devel BuildRequires: libnotify-devel >= 0.7 BuildRequires: libacl-devel BuildRequires: automake @@ -36,7 +38,7 @@ Requires: libudev >= 160 Requires: initscripts >= 9.28 Requires: filesystem >= 2.4.40 Conflicts: selinux-policy < 3.9.16-12.fc15 -Requires: kernel >= 2.6.35.2-9.fc14 +Conflicts: kernel < 2.6.35.2-9.fc14 Requires: nss-myhostname Source0: http://www.freedesktop.org/software/systemd/%{name}-%{version}.tar.bz2 # Adds support for the %%{_unitdir} macro @@ -44,15 +46,133 @@ Source1: macros.systemd Source2: systemd-sysv-convert # Stop-gap, just to ensure things work out-of-the-box for this driver. Source3: udlfb.conf -# We revert this one for https://bugzilla.redhat.com/show_bug.cgi?id=741078 -# Must keep until https://bugzilla.redhat.com/show_bug.cgi?id=741115 is fixed. -Patch0: 0001-unit-fix-complementing-of-requirement-deps-with-Afte.patch -# some post-v37 patches from upstream: -Patch1: 0002-manager-fix-a-crash-in-isolating.patch -Patch2: 0005-systemctl-completion-always-invoke-with-no-legend.patch -Patch3: 0001-mount-order-remote-mounts-after-both-network.target-.patch -Patch4: 0001-units-drop-Install-section-from-remote-fs-pre.target.patch -Patch5: systemd-37-bug744415.patch +# selected patches from v38 +Patch0001: 0001-util-properly-detect-what-the-last-capability-is.patch +Patch0002: 0002-manager-fix-a-crash-in-isolating.patch +Patch0003: 0003-audit-do-not-complain-if-kernel-lacks-audit.patch +Patch0004: 0004-systemctl-completion-always-invoke-with-no-legend.patch +Patch0005: 0005-systemctl-make-list-unit-files-output-more-economica.patch +Patch0006: 0006-plymouth-fix-ply-proto-endianess-issues.patch +Patch0007: 0007-random-seed-convert-poolsize-from-bits-to-bytes.patch +Patch0008: 0008-condition-Fix-file-descriptor-leak-in-test_capabilit.patch +Patch0009: 0009-initctl-don-t-use-dbus-connection-after-PID-1-got-re.patch +Patch0010: 0010-cgroup-always-recreate-cgroup-before-we-try-to-apply.patch +Patch0011: 0011-mount-order-remote-mounts-after-both-network.target-.patch +Patch0012: 0012-units-drop-Install-section-from-remote-fs-pre.target.patch +Patch0013: 0013-cryptsetup-generator-avoid-ordering-cycle-on-swap.patch +Patch0014: 0014-bash-completion-update-with-new-verbs-and-arguments.patch +Patch0015: 0015-bash-completion-add-completions-for-systemd-loginctl.patch +Patch0016: 0016-bash-completion-rename-file-since-it-is-no-longer-fo.patch +Patch0017: 0017-systemadm-break-timestamp-formatting-out-into-a-sepe.patch +Patch0018: 0018-systemadm-allow-sorting-of-jobs-and-units.patch +Patch0019: 0019-systemadm-split-the-type-status-combo-box-into-type-.patch +Patch0020: 0020-systemadm-filter-on-swaps-paths-and-timers-too.patch +Patch0021: 0021-systemadm-add-a-wrappable-label-and-use-it-for-statu.patch +Patch0022: 0022-systemadm-add-libgee-as-dependency-and-use-it-for-a-.patch +Patch0023: 0023-systemadm-display-dependencies-sorted.patch +Patch0024: 0024-systemadm-use-color-for-dependency-links.patch +Patch0025: 0025-systemadm-use-bold-for-requires-etc.patch +Patch0026: 0026-systemadm-make-the-dependency-listing-selectable.patch +Patch0027: 0027-systemadm-catch-exceptions-generated-by-dbus.patch +Patch0028: 0028-systemadm-coalesce-id-and-decription-fields.patch +Patch0029: 0029-systemadm-adjust-row-numbers-after-removing-aliases.patch +Patch0030: 0030-systemadm-use-colors-for-id-too-remove-color-from-fr.patch +Patch0031: 0031-cgroup-immediately-remove-all-cgroups-which-run-empt.patch +Patch0032: 0032-utmp-remove-unneded-parameters.patch +Patch0033: 0033-utmp-no-need-to-zero-a-struct-before-overwriting-it-.patch +Patch0034: 0034-utmp-initialize-store-with-the-found-entry-not-with-.patch +Patch0035: 0035-utmp-for-DEAD_PROCESS-write-the-current-time-to-wtmp.patch +Patch0036: 0036-man-fix-a-typo-in-signal-number.patch +Patch0037: 0037-units-drop-unnecessary-StandardOutput-syslog.patch +Patch0038: 0038-units-fedora-let-rc-local.service-log-to-syslog.patch +Patch0039: 0039-service-don-t-warn-if-the-pidfile-still-exists-after.patch +Patch0040: 0040-job-colored-status-messages-on-boot.patch +Patch0041: 0041-man-fix-typo-in-sd_notify.patch +Patch0042: 0042-Fix-same-expression-on-both-sides-of.patch +Patch0043: 0043-execute-avoid-logging-to-closed-fds.patch +Patch0044: 0044-execute-make-setup_pam-return-errno-when-possible.patch +Patch0045: 0045-execute-log-errors-from-sd-EXEC.patch +Patch0046: 0046-pam-module-use-the-correct-session-type-unspecified.patch +Patch0047: 0047-pam-module-treat-cron-in-PAM_TTY-as-empty-tty.patch +Patch0048: 0048-let-mount-and-swap-units-log-to-the-configured-defau.patch +Patch0049: 0049-socket-add-option-for-SO_PASSCRED.patch +Patch0050: 0050-shutdownd-use-PassCred-yes-in-the-socket-unit.patch +Patch0051: 0051-syslog-use-PassCred-yes-for-the-dev-log-socket.patch +Patch0052: 0052-man-document-the-PassCred-option.patch +Patch0053: 0053-add-a-generator-to-pull-rc-local.service-in.patch +Patch0054: 0054-rc-local-no-need-to-check-if-the-script-is-executabl.patch +Patch0055: 0055-rc-local-order-after-network.target.patch +Patch0056: 0056-util-fix-error-checking-after-fgets.patch +Patch0057: 0057-path-use-m-instead-of-strerror-errno.patch +Patch0058: 0058-path-refactor-PathSpec-usage.patch +Patch0059: 0059-path-add-PathModified-PathChanged-IN_MODIFY.patch +Patch0060: 0060-service-handle-services-with-racy-daemonization-grac.patch +Patch0061: 0061-service-stop-the-service-if-ExecStartPost-ends-with-.patch +Patch0062: 0062-Allow-list-unit-files-to-run-with-root.patch +Patch0063: 0063-unit-garbage-collect-units-with-load-error.patch +Patch0064: 0064-systemctl-print-error-load-state-in-red.patch +Patch0065: 0065-is-an-ampersat-not-an-ampersand-let-s-call-it-at-sym.patch +Patch0066: 0066-path-add-missing-pieces-for-PathModified.patch +Patch0067: 0067-unit-fix-false-positive-in-check-for-unneeded-unit.patch +Patch0068: 0068-unit-check-for-unneeded-dependencies-even-when-unit-.patch +Patch0069: 0069-pam-module-add-a-couple-of-debugging-prints.patch +Patch0070: 0070-fsck-Fix-typo-in-comment.patch +Patch0071: 0071-systemctl-fix-typo-in-is-enabled.patch +Patch0072: 0072-tmpfiles-use-an-enum-instead-of-plain-char-for-item-.patch +Patch0073: 0073-tmpfiles-rename-a-couple-of-functions.patch +Patch0074: 0074-tmpfiles-use-a-common-function-to-set-owner-group-mo.patch +Patch0075: 0075-tmpfiles-separate-a-generic-item-glob-processing-fun.patch +Patch0076: 0076-tmpfiles-add-RECURSIVE_RELABEL_PATH-Z.patch +Patch0077: 0077-man-document-Z-in-tmpfiles.patch +Patch0078: 0078-man-mention-that-Z-ignores-uid-gid-mode.patch +Patch0079: 0079-service-use-syslog-console-for-sysv_console.patch +Patch0080: 0080-tmpfiles-apply-chown-chmod-for-Z-entries-too.patch +Patch0081: 0081-tmpfiles-add-z-like-Z-but-not-recursive.patch +Patch0082: 0082-man-fix-misplaced-remark-in-description-of-Sockets.patch +Patch0083: 0083-execute-fix-losing-of-start-timestamps.patch +Patch0084: 0084-label-fix-labeling-of-symbolic-links.patch +Patch0085: 0085-dbus-register-to-DBus-asynchronously.patch +Patch0086: 0086-dbus-no-sync-D-Bus-connection-flushing.patch +Patch0087: 0087-log-never-block-on-syslog-in-PID-1.patch +Patch0088: 0088-macro-fix-ALIGN_TO-macro-definition.patch +Patch0089: 0089-man-document-the-sd-login-interfaces.patch +Patch0090: 0090-sd-daemon-fix-include-lines-since-we-now-ship-a-shar.patch +Patch0091: 0091-man-build-new-man-pages.patch +Patch0092: 0092-man-sd_readahead-is-not-actually-available-in-libsys.patch +Patch0093: 0093-build-sys-add-rules-for-man-page-aliases.patch +Patch0094: 0094-man-add-sd-login-7-page.patch +Patch0095: 0095-man-various-updates.patch +Patch0096: 0096-man-extend-sd-login-7-in-regards-to-mixing-D-Bus-and.patch +Patch0097: 0097-man-generate-HTML-instead-of-XHTML-with-XSL-docbook-.patch +Patch0098: 0098-man-switch-to-UTF-8-output-to-work-around-charset-is.patch +Patch0099: 0099-udev-exclude-loopback-device-from-udev-rule-based-sy.patch +Patch0100: 0100-remount-api-vfs-handle-another-OOM-condition.patch +Patch0101: 0101-socket-rename-the-PassCred-option-to-PassCredentials.patch +Patch0102: 0102-socket-only-add-dependency-on-kmsg-socket-to-socket-.patch +Patch0103: 0103-readahead-bring-export-definition-of-sd-readahead-in.patch +Patch0104: 0104-nspawn-get-rid-of-BUFFER_SIZE-use-LINE_MAX-instead.patch +Patch0105: 0105-namespace-remount-namespace-root-dir-for-SLAVE-to-av.patch +Patch0106: 0106-logind-if-we-can-t-open-dev-tty0-assume-there-is-no-.patch +Patch0107: 0107-logind-don-t-watch-vcsa-if-nobody-cares.patch +Patch0108: 0108-man-fix-SEE-ALSO-in-hostname-5.patch +Patch0109: 0109-logind-send-out-Lock-signal-when-locking.patch +Patch0110: 0110-logind-add-needed-include-for-sd_notify.patch +Patch0111: 0111-fix-compilation-error-with-PathSpec-redefined.patch +Patch0112: 0112-util-when-printing-status-updates-during-boot-take-t.patch +Patch0113: 0113-log-minor-optimization.patch +Patch0114: 0114-util-never-ellipsize-welcome-message.patch +Patch0115: 0115-headers-fix-git-URLs-for-source-files.patch +Patch0116: 0116-README-correct-license-claims.patch +Patch0117: 0117-util-fix-switching-to-console-unicode-mode.patch +Patch0118: 0118-util-switch-the-console-to-text-mode-on-reset.patch +Patch0119: 0119-service-add-dependencies-on-configured-sockets.patch +Patch0120: 0120-unit-properly-update-references-to-units-which-are-m.patch +Patch0121: 0121-main-fix-spelling.patch +Patch0122: 0122-load-fragment-fix-parsing-of-Socket-setting.patch +Patch0123: 0123-fix-compiler-warning.patch +Patch0124: 0124-shutdown-exclude-processes-with-argv-0-0-from-killin.patch +Patch0125: 0125-shutdown-add-link-to-root-storage-daemon-text.patch +Patch0126: 0126-unit-implement-new-PropagateReloadTo-PropagateReload.patch # For sysvinit tools Obsoletes: SysVinit < 2.86-24, sysvinit < 2.86-24 @@ -115,14 +235,15 @@ SysV compatibility tools for systemd %prep %setup -q -%patch0 -p1 -R -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 +set +x +for p in %{patches}; do + echo "Applying $p" + patch -p1 < $p +done +set -x %build +autoreconf -i %configure --with-rootdir= --with-distro=fedora --with-rootlibdir=/%{_lib} make %{?_smp_mflags} @@ -278,6 +399,7 @@ fi /lib/udev/rules.d/*.rules /lib/systemd/system-generators/systemd-cryptsetup-generator /lib/systemd/system-generators/systemd-getty-generator +/lib/systemd/system-generators/systemd-rc-local-generator /%{_lib}/security/pam_systemd.so /%{_lib}/libsystemd-daemon.so.* /%{_lib}/libsystemd-login.so.* @@ -336,7 +458,7 @@ fi /lib/systemd/system /bin/systemctl /bin/systemd-tmpfiles -%{_sysconfdir}/bash_completion.d/systemctl-bash-completion.sh +%{_sysconfdir}/bash_completion.d/systemd-bash-completion.sh %{_sysconfdir}/rpm/macros.systemd %{_mandir}/man1/systemctl.* %{_datadir}/pkgconfig/systemd.pc @@ -369,7 +491,10 @@ fi %{_bindir}/systemd-sysv-convert %changelog -* Thu Dec 02 2011 Karsten Hopp 37-5 +* Wed Jan 11 2012 Michal Schmidt - 37-6 +- Fixes and low-risk enhancements (no journald) from upstream v38. + +* Thu Dec 02 2011 Karsten Hopp - 37-5 - add upstream patch for bugzilla 744415, encrypted filesystem passphrases fail on runtime systems in hvc consoles