[systemd-commits] Branch 'journal' - 39 commits - Makefile.am README TODO configure.ac src/.gitignore src/cgroup.c src/condition.c src/cryptsetup-generator.c src/fsck.c src/hostname-setup.c src/initctl.c src/job.c src/locale-setup.c src/manager.c src/mount.c src/quotacheck.c src/random-seed.c src/service.c src/systemadm.vala src/systemctl-bash-completion.sh src/systemctl.c src/systemd-bash-completion.sh src/tty-ask-password-agent.c src/update-utmp.c src/vconsole-setup.c src/wraplabel.vala units/console-shell.service.m4 units/getty at .service.m4 units/mageia units/remote-fs-pre.target units/rescue.service.m4 units/serial-getty at .service.m4

Lennart Poettering lennart at kemper.freedesktop.org
Tue Nov 8 10:44:45 PST 2011


 Makefile.am                      |   37 ++++
 README                           |    5 
 TODO                             |   10 +
 configure.ac                     |   10 +
 src/.gitignore                   |    1 
 src/cgroup.c                     |   15 +-
 src/condition.c                  |    2 
 src/cryptsetup-generator.c       |    6 
 src/fsck.c                       |    2 
 src/hostname-setup.c             |    4 
 src/initctl.c                    |   11 +
 src/job.c                        |   19 +-
 src/locale-setup.c               |    2 
 src/manager.c                    |   12 +
 src/mount.c                      |    7 
 src/quotacheck.c                 |    6 
 src/random-seed.c                |    6 
 src/service.c                    |   12 +
 src/systemadm.vala               |  289 +++++++++++++++++++++++----------------
 src/systemctl-bash-completion.sh |  150 --------------------
 src/systemctl.c                  |   37 +++-
 src/systemd-bash-completion.sh   |  264 +++++++++++++++++++++++++++++++++++
 src/tty-ask-password-agent.c     |    1 
 src/update-utmp.c                |    5 
 src/vconsole-setup.c             |    4 
 src/wraplabel.vala               |   73 +++++++++
 units/console-shell.service.m4   |    3 
 units/getty at .service.m4          |    3 
 units/mageia/prefdm.service      |   21 ++
 units/remote-fs-pre.target       |    3 
 units/rescue.service.m4          |    5 
 units/serial-getty at .service.m4   |    3 
 32 files changed, 713 insertions(+), 315 deletions(-)

New commits:
commit 1e2579fdeb7608719cb28da0b5061f48ba0efc34
Merge: a40593a... 4cbd9ec...
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 8 19:44:16 2011 +0100

    Merge branch 'master' into journal

diff --cc TODO
index b993a6b,5303497..8c3034e
--- a/TODO
+++ b/TODO
@@@ -17,14 -17,16 +17,20 @@@ Bugfixes
  
  * make polkit checks async
  
 +* properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point.
 +
  Features:
  
 +* check utf8 everywhere
 +
+ * when an instanced service exits, remove its parent cgroup too if possible.
+ 
+ * as Tom Gundersen pointed out there's a always a dep loop if people use crypto file systems with random keys
+ 
  * unset container= in PID1?
  
+ * automatically escape unit names passed on the service (i.e. think "systemctl start serial-getty.service at serial/by-path/jshdfjsdfhkjh" being automatically escaped as necessary.
+ 
  * if we can not get user quota for tmpfs, mount a separate tmpfs instance
    for every user in /run/user/$USER with a configured maximum size
  

commit a40593a0d0d740efa387e35411e1e456a6c5aba7
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 8 19:12:29 2011 +0100

    TODO

diff --git a/TODO b/TODO
index 9149018..b993a6b 100644
--- a/TODO
+++ b/TODO
@@ -17,8 +17,12 @@ Bugfixes:
 
 * make polkit checks async
 
+* properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point.
+
 Features:
 
+* check utf8 everywhere
+
 * unset container= in PID1?
 
 * if we can not get user quota for tmpfs, mount a separate tmpfs instance

commit 4cbd9ecf45f64c3a9acc99d473fbf3be3687ae24
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Nov 3 19:55:36 2011 +0100

    update TODO

diff --git a/TODO b/TODO
index fe73283..5303497 100644
--- a/TODO
+++ b/TODO
@@ -19,6 +19,8 @@ Bugfixes:
 
 Features:
 
+* when an instanced service exits, remove its parent cgroup too if possible.
+
 * as Tom Gundersen pointed out there's a always a dep loop if people use crypto file systems with random keys
 
 * unset container= in PID1?

commit 353fa6a21aab96b0b82ab40cc22b08b1fb0bf652
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Nov 3 19:42:53 2011 +0100

    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.

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;

commit 263653e10353d8ad155f1faba01981816a2bb712
Merge: f5a613c... 79b1e6c...
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Nov 2 14:08:49 2011 +0100

    Merge remote-tracking branch 'zbigniew/systemadm_changes'


commit f5a613c03c54cc82e92c38af0b3e1c130003a68b
Author: Ran Benita <ran234 at gmail.com>
Date:   Wed Nov 2 10:48:51 2011 +0200

    bash-completion: rename file since it is no longer for systemctl only

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

commit 3cdbf916d3629733fa9998d5802bf4c20d98c50e
Author: Ran Benita <ran234 at gmail.com>
Date:   Wed Nov 2 10:48:50 2011 +0200

    bash-completion: add completions for systemd-loginctl
    
    This script is straightforward and should give proper completions for
    all of systemd-loginctl's verbs.

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

commit 8aea83c718af18e6436e6bdce9437238de052dbb
Author: Ran Benita <ran234 at gmail.com>
Date:   Wed Nov 2 10:48:49 2011 +0200

    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.

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

commit 6fdae8a6a40d6a3b5f77516abaee23b3eab002f6
Author: Dexter Morgan <dmorgan at mageia.org>
Date:   Fri Oct 28 19:16:33 2011 +0200

    Add Mageia support
    
    This patch adds support for the Mageia Linux distribution:
     http://www.mageia.org/
    
    Mageia is a fork of Mandriva although some divergence has already occured
    and thus inclusion of these changes upstream allow us to (hopefully)
    migrate more rapidly to the new standard approaches systemd offers.
    Indeed, we already use the preferred mechanism of OS identification via
    the /etc/os-release file rather than a distro specific variation.
    
    This patch mostly mirrors the patch added previously for Mandriva
    support. In addition to those original authors, this patch was mostly
    written by Dexter Morgan with help from Colin Guthrie and Eugeni Dodonov.

diff --git a/Makefile.am b/Makefile.am
index dabe32a..f701a45 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -119,6 +119,13 @@ AM_CPPFLAGS += \
 	-DKBD_LOADKEYS=\"/bin/loadkeys\" \
 	-DKBD_SETFONT=\"/bin/setfont\" \
 	-DDEFAULT_FONT=\"latarcyrheb-sun16\"
+else
+if TARGET_MAGEIA
+AM_CPPFLAGS += \
+	-DKBD_LOADKEYS=\"/bin/loadkeys\" \
+	-DKBD_SETFONT=\"/bin/setfont\" \
+	-DDEFAULT_FONT=\"LatArCyrHeb-16\"
+endif
 endif
 endif
 endif
@@ -542,6 +549,13 @@ dist_systemunit_DATA += \
 	units/suse/halt-local.service
 endif
 
+if TARGET_MAGEIA
+dist_systemunit_DATA += \
+	units/mageia/prefdm.service \
+	units/fedora/rc-local.service \
+	units/fedora/halt-local.service
+endif
+
 if HAVE_PLYMOUTH
 dist_systemunit_DATA += \
 	units/plymouth-start.service \
@@ -1999,6 +2013,23 @@ if TARGET_SUSE
 		$(LN_S) $(systemunitdir)/halt-local.service halt-local.service )
 endif
 
+if TARGET_MAGEIA
+	$(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 )
+	( cd $(DESTDIR)$(systemunitdir) && \
+		rm -f display-manager.service && \
+		$(LN_S) prefdm.service display-manager.service && \
+		$(LN_S) prefdm.service dm.service )
+	( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \
+		rm -f display-manager.service && \
+		$(LN_S) $(systemunitdir)/display-manager.service display-manager.service )
+endif
+
 if HAVE_SYSV_COMPAT
 	( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \
 		rm -f var-lock.mount && \
diff --git a/configure.ac b/configure.ac
index 0ec6f69..0bc9860 100644
--- a/configure.ac
+++ b/configure.ac
@@ -371,6 +371,7 @@ if test "z$with_distro" = "z"; then
                 test -f "/etc/mandriva-release" && with_distro="mandriva"
                 test -f "/etc/meego-release" && with_distro="meego"
                 test -f "/etc/angstrom-version" && with_distro="angstrom"
+                test -f "/etc/mageia-release" && with_distro="mageia"
                 if test "x`lsb_release -is 2>/dev/null`" = "xUbuntu"; then
                         with_distro="ubuntu"
                 fi
@@ -458,6 +459,12 @@ case $with_distro in
                 AC_DEFINE(TARGET_ANGSTROM, [], [Target is Ångström])
                 M4_DEFINES=-DTARGET_ANGSTROM=1
                 ;;
+        mageia)
+                SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d
+                AC_DEFINE(TARGET_MAGEIA, [], [Target is Mageia])
+                M4_DISTRO_FLAG=-DTARGET_MAGEIA=1
+                have_plymouth=yes
+                ;;
         other)
                 ;;
         *)
@@ -515,6 +522,7 @@ AM_CONDITIONAL(TARGET_ALTLINUX, test x"$with_distro" = xaltlinux)
 AM_CONDITIONAL(TARGET_MANDRIVA, test x"$with_distro" = xmandriva)
 AM_CONDITIONAL(TARGET_MEEGO, test x"$with_distro" = xmeego)
 AM_CONDITIONAL(TARGET_ANGSTROM, test x"$with_distro" = xangstrom)
+AM_CONDITIONAL(TARGET_MAGEIA, test x"$with_distro" = xmageia)
 
 AM_CONDITIONAL(HAVE_PLYMOUTH, test "$have_plymouth" = "yes")
 AM_CONDITIONAL(HAVE_SYSV_COMPAT, test "$SYSTEM_SYSV_COMPAT" = "yes")
diff --git a/src/fsck.c b/src/fsck.c
index c5088ad..3477ba1 100644
--- a/src/fsck.c
+++ b/src/fsck.c
@@ -127,7 +127,7 @@ static int parse_proc_cmdline(void) {
                         arg_skip = true;
                 else if (startswith(w, "fsck.mode"))
                         log_warning("Invalid fsck.mode= parameter. Ignoring.");
-#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA)
+#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
                 else if (strneq(w, "fastboot", l))
                         arg_skip = true;
                 else if (strneq(w, "forcefsck", l))
diff --git a/src/hostname-setup.c b/src/hostname-setup.c
index 7216b75..2c2f10c 100644
--- a/src/hostname-setup.c
+++ b/src/hostname-setup.c
@@ -30,7 +30,7 @@
 #include "util.h"
 #include "log.h"
 
-#if defined(TARGET_FEDORA) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO)
+#if defined(TARGET_FEDORA) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO) || defined(TARGET_MAGEIA)
 #define FILENAME "/etc/sysconfig/network"
 #elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE)
 #define FILENAME "/etc/HOSTNAME"
@@ -64,7 +64,7 @@ static int read_and_strip_hostname(const char *path, char **hn) {
 
 static int read_distro_hostname(char **hn) {
 
-#if defined(TARGET_FEDORA) || defined(TARGET_ARCH) || defined(TARGET_GENTOO) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO)
+#if defined(TARGET_FEDORA) || defined(TARGET_ARCH) || defined(TARGET_GENTOO) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO) || defined(TARGET_MAGEIA)
         int r;
         FILE *f;
 
diff --git a/src/locale-setup.c b/src/locale-setup.c
index 3402936..7f692e9 100644
--- a/src/locale-setup.c
+++ b/src/locale-setup.c
@@ -199,7 +199,7 @@ int locale_setup(void) {
                 if (r != -ENOENT)
                         log_warning("Failed to read /etc/profile.env: %s", strerror(-r));
         }
-#elif defined(TARGET_MANDRIVA)
+#elif defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA )
         if (r <= 0 &&
             (r = parse_env_file("/etc/sysconfig/i18n", NEWLINE,
                                 "LANG",              &variables[VARIABLE_LANG],
diff --git a/src/quotacheck.c b/src/quotacheck.c
index 98b59a0..60033a8 100644
--- a/src/quotacheck.c
+++ b/src/quotacheck.c
@@ -54,7 +54,7 @@ static int parse_proc_cmdline(void) {
                         arg_skip = true;
                 else if (startswith(w, "quotacheck.mode"))
                         log_warning("Invalid quotacheck.mode= parameter. Ignoring.");
-#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA)
+#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
                 else if (strneq(w, "forcequotacheck", l))
                         arg_force = true;
 #endif
@@ -65,8 +65,8 @@ static int parse_proc_cmdline(void) {
 }
 
 static void test_files(void) {
-#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA)
-        /* This exists only on Fedora or Mandriva */
+#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+        /* This exists only on Fedora, Mandriva or Mageia */
         if (access("/forcequotacheck", F_OK) >= 0)
                 arg_force = true;
 #endif
diff --git a/src/service.c b/src/service.c
index 6184390..eb475d9 100644
--- a/src/service.c
+++ b/src/service.c
@@ -277,7 +277,8 @@ static int sysv_translate_facility(const char *name, const char *filename, char
         static const char * const table[] = {
                 /* LSB defined facilities */
                 "local_fs",             SPECIAL_LOCAL_FS_TARGET,
-#ifndef TARGET_MANDRIVA
+#if defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+#else
                 /* Due to unfortunate name selection in Mandriva,
                  * $network is provided by network-up which is ordered
                  * after network which actually starts interfaces.
diff --git a/src/systemctl.c b/src/systemctl.c
index b0baf8d..175159d 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -3462,7 +3462,7 @@ finish:
 static int enable_sysv_units(char **args) {
         int r = 0;
 
-#if defined (HAVE_SYSV_COMPAT) && (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_MEEGO) || defined(TARGET_ALTLINUX))
+#if defined (HAVE_SYSV_COMPAT) && (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_MEEGO) || defined(TARGET_ALTLINUX) || defined(TARGET_MAGEIA))
         const char *verb = args[0];
         unsigned f = 1, t = 1;
         LookupPaths paths;
diff --git a/src/vconsole-setup.c b/src/vconsole-setup.c
index c5f3628..9196789 100644
--- a/src/vconsole-setup.c
+++ b/src/vconsole-setup.c
@@ -160,7 +160,7 @@ int main(int argc, char **argv) {
 #ifdef TARGET_GENTOO
         char *vc_unicode = NULL;
 #endif
-#ifdef TARGET_MANDRIVA
+#if defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
         char *vc_keytable = NULL;
 #endif
         int fd = -1;
@@ -371,7 +371,7 @@ int main(int argc, char **argv) {
                                 log_warning("Failed to read /etc/conf.d/keymaps: %s", strerror(-r));
                 }
 
-#elif defined(TARGET_MANDRIVA)
+#elif defined(TARGET_MANDRIVA) || defined (TARGET_MAGEIA)
 
                 if ((r = parse_env_file("/etc/sysconfig/i18n", NEWLINE,
                                         "SYSFONT", &vc_font,
diff --git a/units/console-shell.service.m4 b/units/console-shell.service.m4
index a4a9108..02adc84 100644
--- a/units/console-shell.service.m4
+++ b/units/console-shell.service.m4
@@ -23,6 +23,9 @@ After=rc-local.service
 m4_ifdef(`TARGET_MANDRIVA',
 After=rc-local.service
 )m4_dnl
+m4_ifdef(`TARGET_MAGEIA',
+After=rc-local.service
+)m4_dnl
 Before=getty.target
 
 [Service]
diff --git a/units/getty at .service.m4 b/units/getty at .service.m4
index 14d8187..d2a145d 100644
--- a/units/getty at .service.m4
+++ b/units/getty at .service.m4
@@ -24,6 +24,9 @@ After=rc-local.service
 m4_ifdef(`TARGET_MANDRIVA',
 After=rc-local.service
 )m4_dnl
+m4_ifdef(`TARGET_MAGEIA',
+After=rc-local.service
+)m4_dnl
 
 # If additional gettys are spawned during boot then we should make
 # sure that this is synchronized before getty.target, even though
diff --git a/units/mageia/prefdm.service b/units/mageia/prefdm.service
new file mode 100644
index 0000000..4a896bf
--- /dev/null
+++ b/units/mageia/prefdm.service
@@ -0,0 +1,21 @@
+#  This file is part of systemd.
+#
+#  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.
+
+[Unit]
+Description=Display Manager
+After=livesys-late.service rc-local.service systemd-user-sessions.service
+After=network.target acpid.service fs.service haldaemon.service
+
+# Do not stop plymouth, it is done in prefdm if required
+Conflicts=plymouth-quit.service
+After=plymouth-quit.service
+
+[Service]
+ExecStart=/etc/X11/prefdm
+Type=forking
+Restart=always
+RestartSec=0
diff --git a/units/rescue.service.m4 b/units/rescue.service.m4
index 19b30d8..7dd8a22 100644
--- a/units/rescue.service.m4
+++ b/units/rescue.service.m4
@@ -25,10 +25,13 @@ ExecStart=-/bin/bash -c "exec ${SINGLE}"',
 m4_ifdef(`TARGET_MANDRIVA',
 `EnvironmentFile=/etc/sysconfig/init
 ExecStart=-/bin/bash -c "exec ${SINGLE}"',
+m4_ifdef(`TARGET_MAGEIA',
+`EnvironmentFile=/etc/sysconfig/init
+ExecStart=-/bin/bash -c "exec ${SINGLE}"',
 m4_ifdef(`TARGET_MEEGO',
 `EnvironmentFile=/etc/sysconfig/init
 ExecStart=-/bin/bash -c "exec ${SINGLE}"',
-`ExecStart=-/sbin/sulogin')))
+`ExecStart=-/sbin/sulogin'))))
 ExecStopPost=-/bin/systemctl --fail --no-block default
 StandardInput=tty-force
 StandardOutput=inherit
diff --git a/units/serial-getty at .service.m4 b/units/serial-getty at .service.m4
index 082290c..e5f0ca6 100644
--- a/units/serial-getty at .service.m4
+++ b/units/serial-getty at .service.m4
@@ -24,6 +24,9 @@ After=rc-local.service
 m4_ifdef(`TARGET_MANDRIVA',
 After=rc-local.service
 )m4_dnl
+m4_ifdef(`TARGET_MAGEIA',
+After=rc-local.service
+)m4_dnl
 
 # If additional gettys are spawned during boot then we should make
 # sure that this is synchronized before getty.target, even though

commit 25d6283acfeb87730c2c0c4c2ef76a66fa397e87
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 1 23:53:15 2011 +0100

    update TODO

diff --git a/TODO b/TODO
index 16cfd21..fe73283 100644
--- a/TODO
+++ b/TODO
@@ -19,6 +19,8 @@ Bugfixes:
 
 Features:
 
+* as Tom Gundersen pointed out there's a always a dep loop if people use crypto file systems with random keys
+
 * unset container= in PID1?
 
 * automatically escape unit names passed on the service (i.e. think "systemctl start serial-getty.service at serial/by-path/jshdfjsdfhkjh" being automatically escaped as necessary.

commit 87e75fddbb3701fd5f4e0d62dc1d661e8d94b071
Author: Tom Gundersen <teg at jklm.no>
Date:   Mon Oct 17 13:01:08 2011 +0200

    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).

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"

commit fc8f0b5c9cb8277950a2fefdb7f754c47b172dfd
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 1 22:29:48 2011 +0100

    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.

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

commit 7fc2a89a7387db1e5daa4892393c9e9536920c25
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 1 22:27:48 2011 +0100

    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

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;
 

commit 6ddaf1ca4ab0e6a094f6d37fa1e0c604c6d867ba
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 1 22:02:36 2011 +0100

    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

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));

commit f632a6634dd4eff041425aa9b3fb48ccfa98c014
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 1 18:18:17 2011 +0100

    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.

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;
 

commit 7670e5a2aab543bc6b442ab0683411770e06fe26
Author: Thomas Jarosch <thomas.jarosch at intra2net.com>
Date:   Wed Oct 26 09:38:39 2011 +0200

    condition: Fix file descriptor leak in test_capability()
    
    Detected by cppcheck.

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));
 }
 

commit 7c2ec00930ce1f4aabfbb405d84b67eb9d065ef0
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat Oct 22 18:47:08 2011 +0200

    random-seed: convert poolsize from bits to bytes
    
    The problem was first noted in a bug report against Arch's initscripts.
    
    Reported-by: Taylan Ulrich Bayırlı <taylanbayirli at gmail.com>
    Reported-by: Gerardo Exequiel Pozzi <vmlinuz386 at yahoo.com.ar>

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);
         }
 

commit bb53abeb8c3407ea250be69bc43510b03c0df3da
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 1 14:20:31 2011 +0100

    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

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;

commit b7f44df59a7f76d2bd5302df2f5ec9be9b7fa2fa
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 1 13:52:28 2011 +0100

    README: explain dependency on cgroups

diff --git a/README b/README
index 15afb2c..a4cbeae 100644
--- a/README
+++ b/README
@@ -30,7 +30,10 @@ LICENSE:
         GPLv2+ for all code, except sd-daemon.[ch] which is MIT
 
 REQUIREMENTS:
-        Linux kernel >= 2.6.39 (with devtmpfs, cgroups; optional but strongly recommended: autofs4, ipv6)
+        Linux kernel >= 2.6.39
+                with devtmpfs
+                with cgroups (but it's OK to disable all controllers)
+                optional but strongly recommended: autofs4, ipv6
         libudev >= 172
         dbus >= 1.4.0
         libcap

commit a6eb9147a820d1c08b315867373a21bd0ece2f05
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 1 13:48:30 2011 +0100

    update TODO

diff --git a/TODO b/TODO
index 9149018..16cfd21 100644
--- a/TODO
+++ b/TODO
@@ -21,6 +21,8 @@ Features:
 
 * unset container= in PID1?
 
+* automatically escape unit names passed on the service (i.e. think "systemctl start serial-getty.service at serial/by-path/jshdfjsdfhkjh" being automatically escaped as necessary.
+
 * if we can not get user quota for tmpfs, mount a separate tmpfs instance
   for every user in /run/user/$USER with a configured maximum size
 

commit 1c0a113fd3fe3344b2c947ca9948760057052716
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Oct 24 11:49:59 2011 +0200

    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 ]

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);
 }
 

commit 74eeab044e506a39786f484b160d9f64d48ad243
Author: Dave Reisner <d at falconindy.com>
Date:   Tue Oct 11 20:56:53 2011 -0400

    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.

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 <http://www.gnu.org/licenses/>.
 
+__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
 

commit 5a8d081c58f7b83172ad5031a8fdac0c33072b2a
Author: Jonathan Nieder <jrnieder at gmail.com>
Date:   Mon Oct 17 21:01:40 2011 +0200

    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.

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
 

commit e51db373c242b7541794affb2b5e411bcce26d0f
Author: Tollef Fog Heen <tfheen at err.no>
Date:   Mon Oct 17 21:00:42 2011 +0200

    service: Drop rcN.d runlevels from SysV services that also exist in rcS.d
    
    Services which claim to start in both rcN.d and rcS.d generate
    loops which for some reason seems to usually end up with dbus not
    starting and the whole machine being quite unhappy. We now rather
    assume that if a service can be started in rcS, it should not also
    start in rcN.d.
    
    Fixes Debian bug #637037

diff --git a/src/service.c b/src/service.c
index e64d289..6184390 100644
--- a/src/service.c
+++ b/src/service.c
@@ -83,7 +83,7 @@ static const struct {
 
 #define RUNLEVELS_UP "12345"
 /* #define RUNLEVELS_DOWN "06" */
-/* #define RUNLEVELS_BOOT "bBsS" */
+#define RUNLEVELS_BOOT "bBsS"
 #endif
 
 static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
@@ -811,6 +811,13 @@ static int service_load_sysv_path(Service *s, const char *path) {
 
         if ((r = sysv_exec_commands(s)) < 0)
                 goto finish;
+        if (s->sysv_runlevels &&
+            chars_intersect(RUNLEVELS_BOOT, s->sysv_runlevels) &&
+            chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) {
+                /* Service has both boot and "up" runlevels
+                   configured.  Kill the "up" ones. */
+                delete_chars(s->sysv_runlevels, RUNLEVELS_UP);
+        }
 
         if (s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) {
                 /* If there a runlevels configured for this service

commit 563ba9ea6e60774086555998b957edf923e24b46
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Mon Oct 17 11:12:12 2011 +0200

    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()
    can recursively remove other entries.
    
    It triggered an assertion failure:
      Assertion 'j->installed' failed at src/manager.c:1218, function
      transaction_apply(). Aborting.
    
    Fix the crash by iterating from the beginning when there is a
    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

diff --git a/src/job.c b/src/job.c
index 5c0913b..20971da 100644
--- a/src/job.c
+++ b/src/job.c
@@ -527,6 +527,7 @@ int job_finish_and_invalidate(Job *j, JobResult result) {
         Unit *other;
         JobType t;
         Iterator i;
+        bool recursed = false;
 
         assert(j);
         assert(j->installed);
@@ -573,23 +574,29 @@ int job_finish_and_invalidate(Job *j, JobResult result) {
                                 if (other->meta.job &&
                                     (other->meta.job->type == JOB_START ||
                                      other->meta.job->type == JOB_VERIFY_ACTIVE ||
-                                     other->meta.job->type == JOB_RELOAD_OR_START))
+                                     other->meta.job->type == JOB_RELOAD_OR_START)) {
                                         job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY);
+                                        recursed = true;
+                                }
 
                         SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i)
                                 if (other->meta.job &&
                                     (other->meta.job->type == JOB_START ||
                                      other->meta.job->type == JOB_VERIFY_ACTIVE ||
-                                     other->meta.job->type == JOB_RELOAD_OR_START))
+                                     other->meta.job->type == JOB_RELOAD_OR_START)) {
                                         job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY);
+                                        recursed = true;
+                                }
 
                         SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
                                 if (other->meta.job &&
                                     !other->meta.job->override &&
                                     (other->meta.job->type == JOB_START ||
                                      other->meta.job->type == JOB_VERIFY_ACTIVE ||
-                                     other->meta.job->type == JOB_RELOAD_OR_START))
+                                     other->meta.job->type == JOB_RELOAD_OR_START)) {
                                         job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY);
+                                        recursed = true;
+                                }
 
                 } else if (t == JOB_STOP) {
 
@@ -597,8 +604,10 @@ int job_finish_and_invalidate(Job *j, JobResult result) {
                                 if (other->meta.job &&
                                     (other->meta.job->type == JOB_START ||
                                      other->meta.job->type == JOB_VERIFY_ACTIVE ||
-                                     other->meta.job->type == JOB_RELOAD_OR_START))
+                                     other->meta.job->type == JOB_RELOAD_OR_START)) {
                                         job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY);
+                                        recursed = true;
+                                }
                 }
         }
 
@@ -626,7 +635,7 @@ finish:
 
         manager_check_finished(u->meta.manager);
 
-        return 0;
+        return recursed;
 }
 
 int job_start_timer(Job *j) {
diff --git a/src/manager.c b/src/manager.c
index e626347..6d20258 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -1214,13 +1214,18 @@ static int transaction_apply(Manager *m, JobMode mode) {
 
                 /* When isolating first kill all installed jobs which
                  * aren't part of the new transaction */
+        rescan:
                 HASHMAP_FOREACH(j, m->jobs, i) {
                         assert(j->installed);
 
                         if (hashmap_get(m->transaction_jobs, j->unit))
                                 continue;
 
-                        job_finish_and_invalidate(j, JOB_CANCELED);
+                        /* 'j' itself is safe to remove, but if other jobs
+                           are invalidated recursively, our iterator may become
+                           invalid and we need to start over. */
+                        if (job_finish_and_invalidate(j, JOB_CANCELED) > 0)
+                                goto rescan;
                 }
         }
 

commit 79b1e6cb8080e5c88754484f5af591ce74714ff0
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Sep 19 08:20:17 2011 +0200

    systemadm: use colors for id too, remove color from fragment link

diff --git a/src/systemadm.vala b/src/systemadm.vala
index 1118999..5971ac0 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -452,7 +452,7 @@ public class MainWindow : Window {
                 unit_cgroup_label.set_text_or_na();
         }
 
-        public string format_unit_link(string i) {
+        public string format_unit_link(string i, bool link) {
                 Unit? u = get_unit(i);
                 if(u == null)
                         return "<span color='grey'>" + i + "</span";
@@ -467,7 +467,10 @@ public class MainWindow : Window {
                 string span = "<span underline='none' color='" + color + "'>"
                               + i + "(" +
                               u.sub_state + ")" + "</span>";
-                return  " <a href='" + i + "'>" + span + "</a>";
+                if(link)
+                        return  " <a href='" + i + "'>" + span + "</a>";
+                else
+                        return span;
         }
 
 
@@ -493,7 +496,7 @@ public class MainWindow : Window {
                                 first = false;
                         }
 
-                        r += format_unit_link(i);
+                        r += format_unit_link(i, true);
                 }
 
                 return r;
@@ -502,7 +505,7 @@ public class MainWindow : Window {
         public void show_unit(Unit unit) {
                 current_unit_id = unit.id;
 
-                string id_display = current_unit_id;
+                string id_display = format_unit_link(current_unit_id, false);
                 bool has_alias = false;
                 foreach (string i in unit.names) {
                         if (i == current_unit_id)
@@ -518,7 +521,7 @@ public class MainWindow : Window {
                 if(has_alias)
                         id_display += ")";
 
-                unit_id_label.set_text_or_na(id_display);
+                unit_id_label.set_markup_or_na(id_display);
 
                 string[]
                         requires = unit.requires,
@@ -564,7 +567,9 @@ public class MainWindow : Window {
 
                 string fp = unit.fragment_path;
                 if (fp != "")
-                        unit_fragment_path_label.set_markup_or_na("<a href=\"file://" + fp +"\">" + fp + "</a>" );
+                        unit_fragment_path_label.set_markup_or_na(
+                                "<a href=\"file://" + fp +"\">" +
+                                "<span underline='none' color='black'>" + fp + "</span></a>");
                 else
                         unit_fragment_path_label.set_text_or_na();
 

commit fe7e28146f30ec442c0dd7f71002a1b482d910a9
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Sep 19 08:14:02 2011 +0200

    systemadm: adjust row numbers after removing 'aliases'

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);

commit 8f38d5a4c6e627180809db739b2bdaa5ca0c645a
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sun Sep 18 17:00:12 2011 +0200

    systemadm: coalesce id and decription fields
    
    This is just in interest of saving space (e.g. 5 lines for multi-user.target).

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,

commit 734b60d7961a28adab45ef141807a0f3e0ba11e5
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Thu Feb 24 16:30:55 2011 +0100

    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 :).

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);
                 }
 

commit 37d3b881f1cc7c18d23013ff29429ab67ab5b61d
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sun Sep 18 11:06:07 2011 +0200

    systemadm: make the dependency listing  selectable
    
    There's no reason to forbid selecting the text.

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);

commit 8b1451ade7794c21d29141dc363d0f626e2070ee
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sat Sep 17 14:57:19 2011 +0100

    systemadm: use bold for "requires", etc.

diff --git a/src/systemadm.vala b/src/systemadm.vala
index eed46b5..a3068f1 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -494,7 +494,7 @@ public class MainWindow : Window {
                                 r += first ? "\n" : ",";
 
                         if (first) {
-                                r += word;
+                                r += "<b>" + word + ":</b>";
                                 first = false;
                         }
 

commit 23b51f17b1cf473bff3ae5332477e2028a5c5f53
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Thu Mar 3 22:20:19 2011 +0100

    systemadm: use color for dependency links

diff --git a/src/systemadm.vala b/src/systemadm.vala
index 088ba26..eed46b5 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -457,6 +457,25 @@ public class MainWindow : Window {
                 unit_cgroup_label.set_text_or_na();
         }
 
+        public string format_unit_link(string i) {
+                Unit? u = get_unit(i);
+                if(u == null)
+                        return "<span color='grey'>" + i + "</span";
+
+                string color;
+                switch (u.sub_state) {
+                case "active": color = "blue"; break;
+                case "dead": color = "red"; break;
+                case "running": color = "green"; break;
+                default: color = "black"; break;
+                }
+                string span = "<span underline='none' color='" + color + "'>"
+                              + i + "(" +
+                              u.sub_state + ")" + "</span>";
+                return  " <a href='" + i + "'>" + span + "</a>";
+        }
+
+
         public string make_dependency_string(string? prefix, string word, string[] dependencies) {
                 Gee.Collection<unowned string> sorted = new Gee.TreeSet<string>();
                 foreach (string i in dependencies)
@@ -479,7 +498,7 @@ public class MainWindow : Window {
                                 first = false;
                         }
 
-                        r += " <a href=\"" + i + "\">" + i + "</a>";
+                        r += format_unit_link(i);
                 }
 
                 return r;

commit 8278f06953f5339646e5ff98900321f1525c0a21
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Thu Mar 3 01:30:08 2011 +0100

    systemadm: display dependencies sorted

diff --git a/src/systemadm.vala b/src/systemadm.vala
index c893da0..088ba26 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -458,6 +458,10 @@ public class MainWindow : Window {
         }
 
         public string make_dependency_string(string? prefix, string word, string[] dependencies) {
+                Gee.Collection<unowned string> sorted = new Gee.TreeSet<string>();
+                foreach (string i in dependencies)
+                        sorted.add(i);
+
                 bool first = true;
                 string r;
 
@@ -466,7 +470,7 @@ public class MainWindow : Window {
                 else
                         r = prefix;
 
-                foreach (string i in dependencies) {
+                foreach (string i in sorted) {
                         if (r != "")
                                 r += first ? "\n" : ",";
 

commit 11216eb0bd5aab6b14af004fd2f24d423e3d356d
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Thu Mar 3 20:54:01 2011 +0100

    systemadm: add libgee as dependency and use it for a unit map

diff --git a/Makefile.am b/Makefile.am
index ec0f7b5..0712945 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1432,6 +1432,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 ca07456..b2411c9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -327,7 +327,7 @@ AM_CONDITIONAL(ENABLE_LOCALED, [test "$have_localed" = "yes"])
 have_gtk=no
 AC_ARG_ENABLE(gtk, AS_HELP_STRING([--disable-gtk], [disable GTK tools]))
 if test "x$enable_gtk" != "xno"; then
-        PKG_CHECK_MODULES(GTK, [ gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 ],
+        PKG_CHECK_MODULES(GTK, [ gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0],
                 [AC_DEFINE(HAVE_GTK, 1, [Define if GTK is available]) have_gtk=yes], have_gtk=no)
         AC_SUBST(GTK_CFLAGS)
         AC_SUBST(GTK_LIBS)
diff --git a/src/systemadm.vala b/src/systemadm.vala
index 68652d0..c893da0 100644
--- a/src/systemadm.vala
+++ b/src/systemadm.vala
@@ -79,6 +79,8 @@ public class MainWindow : Window {
         private ListStore unit_model;
         private ListStore job_model;
 
+        private Gee.HashMap<string, Unit> unit_map;
+
         private Button start_button;
         private Button stop_button;
         private Button restart_button;
@@ -180,6 +182,8 @@ public class MainWindow : Window {
                 unit_model = new ListStore(7, typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(Unit));
                 job_model = new ListStore(6, typeof(string), typeof(string), typeof(string), typeof(string), typeof(Job), typeof(uint32));
 
+                unit_map = new Gee.HashMap<string, Unit>();
+
                 TreeModelFilter unit_model_filter;
                 unit_model_filter = new TreeModelFilter(unit_model, null);
                 unit_model_filter.set_visible_func(unit_filter);
@@ -355,6 +359,8 @@ public class MainWindow : Window {
                                         "org.freedesktop.systemd1",
                                         i.unit_path);
 
+                        unit_map[i.id] = u;
+
                         unit_model.append(out iter);
                         unit_model.set(iter,
                                        0, i.id,
@@ -415,6 +421,10 @@ public class MainWindow : Window {
                 return u;
         }
 
+        public Unit? get_unit(string id) {
+                return this.unit_map[id];
+        }
+
         public void unit_changed() {
                 Unit u = get_current_unit();
 
@@ -712,6 +722,8 @@ public class MainWindow : Window {
                                         "org.freedesktop.systemd1",
                                         path);
 
+                        unit_map[id] = u;
+
                         update_unit_iter(iter, id, u);
                 } catch (IOError e) {
                         show_error(e.message);
@@ -773,6 +785,8 @@ public class MainWindow : Window {
                         }
 
                 } while (unit_model.iter_next(ref iter));
+
+                unit_map.unset(id);
         }
 
         public void on_job_removed(uint32 id, ObjectPath path, string res) {

commit 0dd27daff4ba4bdad99b12b85b630ab21c84fa9e
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Tue Mar 1 11:18:13 2011 +0100

    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.

diff --git a/Makefile.am b/Makefile.am
index e1d1186..ec0f7b5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1418,7 +1418,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/.gitignore b/src/.gitignore
index cafff82..a3fd20b 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -12,4 +12,5 @@ org.freedesktop.systemd1.policy
 gnome-ask-password-agent.c
 systemd-interfaces.c
 systemadm.c
+wraplabel.c
 73-seat-late.rules
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();
+                }
+        }
+}

commit e377ad0d11e1bd9954c6084956494ebbf41b4486
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Feb 28 10:35:23 2011 +0100

    systemadm: filter on swaps, paths, and timers too.

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);

commit a3c159a23c7cae889f89ed69bbe82c272bf163ca
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Feb 25 18:20:16 2011 +0100

    systemadm: split the type+status combo box into type combo & status checkbox

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() {

commit 661ece1029ea454ff76093a5f1b40e9209cac86d
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Thu Feb 24 16:29:24 2011 +0100

    systemadm: allow sorting of jobs and units

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();
         }

commit 8401f1533d6936add337a621c5e58e3bbe9f346a
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Wed Feb 23 14:03:59 2011 +0100

    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.

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);



More information about the systemd-commits mailing list