/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to initramfs-tools-script

  • Committer: Teddy Hogeborn
  • Date: 2015-05-23 20:18:34 UTC
  • mto: This revision was merged to the branch mainline in revision 756.
  • Revision ID: teddy@recompile.se-20150523201834-e89ex4ito93yni8x
mandos: Use multiprocessing module to run checkers.

For a long time, the Mandos server has occasionally logged the message
"ERROR: Child process vanished".  This was never a fatal error, but it
has been annoying and slightly worrying, since a definite cause was
not found.  One potential cause could be the "multiprocessing" and
"subprocess" modules conflicting w.r.t. SIGCHLD.  To avoid this,
change the running of checkers from using subprocess.Popen
asynchronously to instead first create a multiprocessing.Process()
(which is asynchronous) calling a function, and have that function
then call subprocess.call() (which is synchronous).  In this way, the
only thing using any asynchronous subprocesses is the multiprocessing
module.

This makes it necessary to change one small thing in the D-Bus API,
since the subprocesses.call() function does not expose the raw wait(2)
status value.

DBUS-API (CheckerCompleted): Change the second value provided by this
                             D-Bus signal from the raw wait(2) status
                             to the actual terminating signal number.
mandos (subprocess_call_pipe): New function to be called by
                               multiprocessing.Process (starting a
                               separate process).
(Client.last_checker signal): New attribute for signal which
                              terminated last checker.  Like
                              last_checker_status, only not accessible
                              via D-Bus.
(Client.checker_callback): Take new "connection" argument and use it
                           to get returncode; set last_checker_signal.
                           Return False so gobject does not call this
                           callback again.
(Client.start_checker): Start checker using a multiprocessing.Process
                        instead of a subprocess.Popen.
(ClientDBus.checker_callback): Take new "connection" argument.        Call
                               Client.checker_callback early to have
                               it set last_checker_status and
                               last_checker_signal; use those.  Change
                               second value provided to D-Bus signal
                               CheckerCompleted to use
                               last_checker_signal if checker was
                               terminated by signal.
mandos-monitor: Update to reflect DBus API change.
(MandosClientWidget.checker_completed): Take "signal" instead of
                                        "condition" argument.  Use it
                                        accordingly.  Remove dead code
                                        (os.WCOREDUMP case).

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
 
52
52
chmod a=rwxt /tmp
53
53
 
 
54
test -r /conf/conf.d/cryptroot
 
55
test -w /conf/conf.d
 
56
 
54
57
# Get DEVICE from /conf/initramfs.conf and other files
55
58
. /conf/initramfs.conf
56
59
for conf in /conf/conf.d/*; do
57
 
    [ -f "${conf}" ] && . "${conf}"
 
60
    [ -f ${conf} ] && . ${conf}
58
61
done
59
62
if [ -e /conf/param.conf ]; then
60
63
    . /conf/param.conf
91
94
# If we are connecting directly, run "configure_networking" (from
92
95
# /scripts/functions); it needs IPOPTS and DEVICE
93
96
if [ "${connect+set}" = set ]; then
94
 
    set +e                      # Required by library functions
95
97
    configure_networking
96
 
    set -e
97
98
    if [ -n "$connect" ]; then
98
99
        cat <<-EOF >>/conf/conf.d/mandos/plugin-runner.conf
99
100
        
102
103
    fi
103
104
fi
104
105
 
105
 
if [ -r /conf/conf.d/cryptroot ]; then
106
 
    test -w /conf/conf.d
107
 
 
108
 
    # Do not replace cryptroot file unless we need to.
109
 
    replace_cryptroot=no
110
 
 
111
 
    # Our keyscript
112
 
    mandos=/lib/mandos/plugin-runner
113
 
    test -x "$mandos"
114
 
 
115
 
    # parse /conf/conf.d/cryptroot.  Format:
116
 
    # target=sda2_crypt,source=/dev/sda2,rootdev,key=none,keyscript=/foo/bar/baz
117
 
    # Is the root device specially marked?
118
 
    changeall=yes
119
 
    while read -r options; do
120
 
        case "$options" in
121
 
            rootdev,*|*,rootdev,*|*,rootdev)
122
 
                # If the root device is specially marked, don't change all
123
 
                # lines in crypttab by default.
124
 
                changeall=no
 
106
# Do not replace cryptroot file unless we need to.
 
107
replace_cryptroot=no
 
108
 
 
109
# Our keyscript
 
110
mandos=/lib/mandos/plugin-runner
 
111
test -x "$mandos"
 
112
 
 
113
# parse /conf/conf.d/cryptroot.  Format:
 
114
# target=sda2_crypt,source=/dev/sda2,key=none,keyscript=/foo/bar/baz
 
115
exec 3>/conf/conf.d/cryptroot.mandos
 
116
while read options; do
 
117
    newopts=""
 
118
    # Split option line on commas
 
119
    old_ifs="$IFS"
 
120
    IFS="$IFS,"
 
121
    for opt in $options; do
 
122
        # Find the keyscript option, if any
 
123
        case "$opt" in
 
124
            keyscript=*)
 
125
                keyscript="${opt#keyscript=}"
 
126
                newopts="$newopts,$opt"
 
127
                ;;
 
128
            "") : ;;
 
129
            *)
 
130
                newopts="$newopts,$opt"
125
131
                ;;
126
132
        esac
127
 
    done < /conf/conf.d/cryptroot
128
 
 
129
 
    exec 3>/conf/conf.d/cryptroot.mandos
130
 
    while read -r options; do
131
 
        newopts=""
132
 
        keyscript=""
133
 
        changethis="$changeall"
134
 
        # Split option line on commas
135
 
        old_ifs="$IFS"
136
 
        IFS="$IFS,"
137
 
        for opt in $options; do
138
 
            # Find the keyscript option, if any
139
 
            case "$opt" in
140
 
                keyscript=*)
141
 
                    keyscript="${opt#keyscript=}"
142
 
                    newopts="$newopts,$opt"
143
 
                    ;;
144
 
                "") : ;;
145
 
                # Always use Mandos on the root device, if marked
146
 
                rootdev)
147
 
                    changethis=yes
148
 
                    newopts="$newopts,$opt"
149
 
                    ;;
150
 
                # Don't use Mandos on resume device, if marked
151
 
                resumedev)
152
 
                    changethis=no
153
 
                    newopts="$newopts,$opt"
154
 
                    ;;
155
 
                *)
156
 
                    newopts="$newopts,$opt"
157
 
                    ;;
158
 
            esac
159
 
        done
160
 
        IFS="$old_ifs"
161
 
        unset old_ifs
162
 
        # If there was no keyscript option, add one.
163
 
        if [ "$changethis" = yes ] && [ -z "$keyscript" ]; then
164
 
            replace_cryptroot=yes
165
 
            newopts="$newopts,keyscript=$mandos"
166
 
        fi
167
 
        newopts="${newopts#,}"
168
 
        echo "$newopts" >&3
169
 
    done < /conf/conf.d/cryptroot
170
 
    exec 3>&-
171
 
 
172
 
    # If we need to, replace the old cryptroot file with the new file.
173
 
    if [ "$replace_cryptroot" = yes ]; then
174
 
        mv /conf/conf.d/cryptroot /conf/conf.d/cryptroot.mandos-old
175
 
        mv /conf/conf.d/cryptroot.mandos /conf/conf.d/cryptroot
176
 
    else
177
 
        rm -f /conf/conf.d/cryptroot.mandos
178
 
    fi
179
 
elif [ -x /usr/bin/cryptroot-unlock ]; then
180
 
    # Use setsid if available
181
 
    if command -v setsid >/dev/null 2>&1; then
182
 
        setsid /lib/mandos/mandos-to-cryptroot-unlock &
183
 
    else
184
 
        /lib/mandos/mandos-to-cryptroot-unlock &
185
 
    fi
 
133
    done
 
134
    IFS="$old_ifs"
 
135
    unset old_ifs
 
136
    # If there was no keyscript option, add one.
 
137
    if [ -z "$keyscript" ]; then
 
138
        replace_cryptroot=yes
 
139
        newopts="$newopts,keyscript=$mandos"
 
140
    fi
 
141
    newopts="${newopts#,}"
 
142
    echo "$newopts" >&3
 
143
done < /conf/conf.d/cryptroot
 
144
exec 3>&-
 
145
 
 
146
# If we need to, replace the old cryptroot file with the new file.
 
147
if [ "$replace_cryptroot" = yes ]; then
 
148
    mv /conf/conf.d/cryptroot /conf/conf.d/cryptroot.mandos-old
 
149
    mv /conf/conf.d/cryptroot.mandos /conf/conf.d/cryptroot
 
150
else
 
151
    rm /conf/conf.d/cryptroot.mandos
186
152
fi