5 # Daemon for controlling the Fbsplash daemon #
7 # Author: Kurt J. Bosch <kjb-temp-2009 at alpenjodel.de> #
8 # Based on the work of: Michal Januszewski <spock at gentoo.org> #
11 # Distributed under the terms of the GNU General Public License (GPL) #
15 # * Replace splash main event shell-function by a process maintaining state
16 # * Provide smooth animation like progress (self learning, time based)
17 # * Support filesystem check progress (via status message text)
18 # * Provide a general failure status (dummy service event)
19 # * Support splash daemon started in initcpio
20 # * Wait until fbcondecor_helper fadein done before starting the daemon
21 # * Prevent auto-verbose timeout as long as message is updated
22 # * Support random splash log messages instead of writing ugly generic ones
23 # * Update splash even on 'verbose error'
24 # * On gpm start, wait until socket ready before using
25 # * Reserve some progress for late stuff to avoid looking freezed
26 # * Avoid adding to profile (splash_manager replay log) after splash exit
27 # * If in configuration, make the splash daemon fade in even on shutdown
28 # * If not available, provide a fake SysV-Init environment for theme hooks
32 # 'start' 'early' [<mountpoint> [svcs-fg-file]] Start control daemon for a bootup splash daemon started in initrd
33 # 'start' 'bootup'|'shutdown'|'reboot' [svcs-fg-file [svcs-start-file [svcs-stop-file]]]
34 # Start control daemon and splash daemon
35 # mountpoint is the directory where the splash cache tmpfs was mounted by the initrd.
36 # svcs-fg-file services started (stopped if reboot/shutdown) in foreground (those relevant for progress) - one per line.
37 # (Current working directory when reading is the splash cache tmpfs root.)
38 # svcs-start-file and svcs-stop-file
39 # are copied to svcs_start and svcs_stop in the splash cache tmpfs for theme hooks using splash_svclist_get().
40 # 'stop' ['force'] Stop (or abort) splash and control daemons (if running) and wait until gone
41 # 'comms' <splash-daemon-command>... Send one or more commands to the splash daemon (if running)
42 # 'ping' Returns a zero exit-code if control daemon is running
43 # 'fsckd' 'start'|'stop' Start/stop a daemon for pushing filesystem check progress info to the splash
44 # status message line ( {FSCK_FD}>/run/fbsplash-fsckd.fifo; fsck -C$FSCK_FD )
45 # <command>|<splash-event> Send a command or event to the control daemon FIFO (non blocking)
49 # 'comm' <splash-daemon-command> Send a command to the splash daemon
50 # 'message <text>' Update the main status message and reset the auto verbose timeout
51 # 'push-message <text>' Like message if SPLASH_PUSH_MESSAGES="yes" in configuration
52 # 'default-message' Reset message to default
53 # 'log <text>' Send a message to the log textbox
54 # 'svc-error' Set general failure service 'fbsplash-dummy' to failed (w/o a splash event)
55 # 'store' Save messured services start/stop time values to the disk
57 # FIFO Events - similar as for /sbin/splash-function.sh splash():
59 # 'critical' Change to console (Virtual Terminal # 1)
60 # '<svc-event> <service-name>' Update splash (and run theme hooks)
61 # Special case: 'svc_start'|'svc_started'|'svc_start_failed' 'fbsplash-boot-dummy'
62 # Pseudo service for SysV-Init 'boot' stage and
63 # running theme hooks for sysinit end as well as entering multi-user
67 PID_FILE
=/run
/fbsplash-controld.pid
68 FIFO
=/run
/fbsplash-controld.fifo
69 PID_LINK
=/run
/fbsplashd.pid
71 # Internal Persistent Data Cache
72 CACHE_DIR
=/lib
/fbsplash-controld
/cache
74 # Fade takes 2 sec. normally, but some machines are broken
75 SPLASH_FADE_WAIT
=10 # seconds
77 .
/sbin
/fbsplash-control-functions.bash
79 # Wait until given processes die or return 1 if timeout
80 # args: <seconds> [<pid>...]
82 local t
=$
(( $1 * 10 ))
84 while kill -0 -- $
* &>/dev
/null
; do
85 (( -- t
>= 0 )) && sleep .1 && continue
86 echo "Timeout waiting for processes to die: $*" >&2
96 [[ -f $PID_FILE ]] && read pid pids
<"$PID_FILE" && (( pid
)) && kill -0 -- $pid || error
=1
98 [[ -p $FIFO ]] || error
=1
102 splash_wait
"$(( SPLASH_FADE_WAIT + 2 ))" $pid $pids ||
exit 1 # wait a bit longer than for splash exit
103 # Never error if no daemon running, except for ping
108 # Daemon for pushing progress info from 'fsck -C$FSCK_FD' to the splash status message line
109 pid_file
="/run/fbsplash-fsckd.pid"
110 fifo
="/run/fbsplash-fsckd.fifo"
113 # Avoid starting multiple instances
114 [[ ! -e $pid_file ]] && mkfifo -m 600 "$fifo" ||
exit 1
116 trap "rm -f '$pid_file' '$fifo'" EXIT
117 trap 'exit 0' TERM
# avoid terminated message
119 while read phase step total fs
; do
120 new_pgr
=$
(( 100 * step
/ total
))
121 (( fsck_progress
== new_pgr
)) && continue
122 fsck_progress
=$new_pgr
123 printf -v fsck_msg
'[ %s phase %s %2i%% ]' "$fs" "$phase" $fsck_progress
124 splash_control progress-message
"Checking Filesystems ${fsck_msg}"
126 ) &>/dev
/null
<"$fifo" &
127 echo $
! >|
"$pid_file"
129 [[ -f "$pid_file" ]] ||
exit 0
130 read pid
<"$pid_file" && kill $pid &>/dev
/null
&& splash_wait
5 $pid
131 splash_control progress-message
# restore message
139 ## Set up environment, splash-functions and configuration
141 # Allow to start splash w/o SysV-Init, in custom pm-utils scripts, for testing ...
142 # RUNLEVEL is needed for hooks, splash_start() and splash_get_boot_message()
143 # (export to be save in case hooks use it directly)
144 export PREVLEVEL RUNLEVEL
145 [[ $PREVLEVEL = ?
]] || PREVLEVEL
=5
155 echo "Usage: ${0##*/} start bootup|early|shutdown|reboot [arg]..." >&2
159 # Note: /proc needs to be mounted at this point!
160 # /etc/conf.d/splash is also sourced by this
161 .
/sbin
/splash-functions.sh ||
exit 1
162 # Eliminate some non local splash_setup variables ## FIXME ##
163 unset -v options opt i
164 # Add path for miscsplashutils fgconsole (needed in case /usr not mounted)
165 [[ -d $spl_bindir ]] && PATH
+=":${spl_bindir}"
166 # Resolution variables (might also be required by some themes)
167 res
=$
( "$spl_util" -c getres
-t "$SPLASH_THEME" )
168 export SPLASH_XRES
=${res%x*} SPLASH_YRES
=${res#*x}
170 # Defaults, Configuration
171 SPLASH_SMOOTH_PROGRESS
="yes"
172 .
/etc
/conf.d
/splash-extras
174 # If already started, don't allow to override splash mode
175 [[ $2 = early
]] && SPLASH_MODE_REQ
="silent"
177 # Sleep interval for progress updates
178 ms_tick
=33 # milliseconds
180 # If verbose mode, just change to console
181 [[ $SPLASH_MODE_REQ = verbose
&& $PREVLEVEL != N
]] && splash_verbose
183 [[ $SPLASH_MODE_REQ = silent
]] ||
exit 0
185 ## Overrides (exported for theme hooks and used by upstream functions)
187 splash_get_boot_message
() {
188 # Use a space instead of an empty message to avoid tonns of 'Text has zero width.' ## FIXME ##
190 in 6 ) echo "${SPLASH_REBOOT_MESSAGE:- }"
191 ;; 0 ) echo "${SPLASH_SHUTDOWN_MESSAGE:- }"
192 ;; * ) echo "${SPLASH_BOOT_MESSAGE:- }"
196 # Send a command to the (non blocking) splash daemon fifo w/o forking
198 # Avoid using SysV-Init pidof
199 pgrep
-x -f "$spl_daemon .*" >/dev
/null ||
return 1
200 splash_fifo_send
"$*"
203 # Write a line to the splash profile log file
205 splash_profile_write
"$*"
208 # Open a non blocking file descriptor for the splash daemon fifo
209 # Send zero ore more commands
210 export splash_fifo_fd
=""
212 if [[ -z $splash_fifo_fd ]]; then
213 [[ -p $spl_fifo ]] && exec {splash_fifo_fd
}<>"$spl_fifo" ||
return 0
216 splash_profile_write
comm "$@"
217 printf '%s\n' "$@" >&$splash_fifo_fd
219 export -f splash_fifo_send
221 # Open a file descriptor for the splash profile log file
222 # Write zero or more lines
223 # args: [<prefix> <text>...]
224 export splash_profile_fd
=""
225 splash_profile_write
() {
226 [[ $SPLASH_PROFILE = on
]] ||
return 0
227 if [[ -z $splash_profile_fd ]]; then
228 # Avoid read-only filesystem error on shutdown
229 # Append to contents written in initcpio
230 [[ -w $spl_cachedir ]] && exec {splash_profile_fd
}>>$spl_cachedir/profile ||
return 0
234 read uptime rest
</proc
/uptime
235 printf "$uptime: ${1} %s\n" "${@:2}" >&$splash_profile_fd
238 ## Prepare for starting
242 [[ $ticker_pid ]] && kill -- $ticker_pid
243 # Send SIGKILL to any stale splash daemon and unmount the tmpfs copying
244 # the profile log file to the disk for splash_manager replay and debugging
245 # Note: If no tmpfs is mounted, this does nothing at all.
248 rm -f "$PID_FILE" "$PID_LINK" "$FIFO"
254 # If silent splash VT active, change to console
255 [[ $
( fgconsole
) = "$SPLASH_TTY" ]] && splash_verbose
261 findmnt
-n -r -t "$spl_cachetype" -T "$1" >/dev
/null
&& return 0
262 silent_err
"Unable to find the splash cache filesystem at: '${1/#./$PWD}'"
266 if [[ $2 = early
]]; then
267 cachedir
=${3:-$spl_cachedir}
268 cache_check
"$cachedir" ||
exit 1
269 [[ $cachedir = "$spl_cachedir" ]] || mount
--move "$cachedir" "$spl_cachedir" ||
exit 1
270 set -- "$1" "$2" "$4"
272 # On shutdown we might already have some control/ticker/splash daemons
273 # running (if splash_manager is in use etc.)
274 pids
=" "$
( pgrep
-d " " -x -f "($BASH ${0}|${spl_daemon})( .*)?" )" "
276 # Kill daemons to allow starting
277 kill -- $pids &>/dev
/null
278 # No fadeout should happen when killed
279 splash_wait
5 $pids ||
exit 1
280 # Make sure the splash cache tmpfs is gone
281 SPLASH_PROFILE
="off" splash_cache_cleanup
282 # Mount a new empty splash cache tmpfs
283 ( splash_cache_prep
) ||
exit 1
287 in reboot | shutdown
)
290 action_done
="stopped"
294 action_done
="started"
301 # Avoid loosing the splash cache tmpfs (on shutdown) and writing to the harddisk
302 cd "$spl_cachedir" && cache_check . ||
exit 1
304 ## Create and open the control daemon fifo non blocking and hold it to avoid loosing input or getting eof
305 mkfifo -m 600 "$FIFO" && exec {control_fifo_fd
}<>"$FIFO" ||
exit 1
307 # Run theme hook script (if any)
308 # args: 'pre'|'post' <event> [arg]...
310 local pre_post
=$1 event
=$2 args
=( "${@:3}" )
311 local hook_name
=${event}-${pre_post}
312 local hook_script
=/etc
/splash
/$SPLASH_THEME/scripts
/$hook_name
313 # Profile might be reused by splash_manager replay with different theme,
314 # so this is added even if hook isn't there.
315 splash_profile_write
"$pre_post" "$event ${args[*]}"
316 # source is faster, but not supported by old/foreign themes
317 if [[ -r ${hook_script}.sh
]]; then
318 # Export hook name to support symlinked generic scripts
319 ( SPLASH_HOOK
=$hook_name source "${hook_script}.sh" "${args[@]}" )
320 elif [[ -x $hook_script ]]; then
321 "$hook_script" "${args[@]}"
325 # Wrapper for updating the splash main status message (if needed)
326 splash_set_message
() {
328 # Send a NBSP instead of an empty/space string to avoid splash daemon crash ## FIXME ##
329 [[ $msg =~ ^
[[:space
:]]*$
]] && msg
=$
'\xC2\xA0'
330 [[ $splash_message = $msg ]] && return 0
332 # Reset autoverbose timeout (but only if needed to keep the profile clean)
333 (( SPLASH_AUTOVERBOSE
> 0 )) && splash_fifo_send
"progress $progress_elapsed"
334 # 'repaint' needed at least for 'set message' if daemon not started with '--type=bootup'
335 splash_fifo_send
"set message $splash_message" "repaint"
338 ## Start splash daemon and/or open splash daemon fifo
340 if [[ $2 = early
]]; then
341 # Override (unknown) initcpio boot message
342 splash_message
="$SPLASH_BOOT_MESSAGE -- invalid --"
343 splash_set_message
"$SPLASH_BOOT_MESSAGE"
345 # Copy services list files into the splash cache for hooks using splash_svclist_get()
346 [[ $svcs_start ]] && echo "$( <"$svcs_start" )" >|
"svcs_start"
347 [[ $svcs_stop ]] && echo "$( <"$svcs_stop" )" >|
"svcs_stop"
348 # Wait for initcpio helper fadein
349 if ! splash_wait
"$SPLASH_FADE_WAIT" $
( pgrep fbcondecor_helper
); then
350 silent_err
"Your framebuffer seems to be to slow. Please disable splash fade effects!"
353 # Run any pre rc_init hook
354 # Note: For splash_manager replay, pre rc_init needs to be the first line in the profile
355 run_hook pre rc_init
$softlevel $RUNLEVEL
356 # Enable shutdown fadein hack
357 [[ $PREVLEVEL != N
&& ,$SPLASH_EFFECTS, = *,fadein
,* && $
( fgconsole
) = "$SPLASH_TTY" ]] && chvt
63
358 # Start the splash daemon or (on boot) let the user read the error message on the splash VT
359 splash_start ||
exit 1
360 splash_message
=$
( splash_get_boot_message
)
361 # Prevent gpm from garbling the splash
362 [[ -S /dev
/gpmctl
]] && splash_control comms
"set gpm" "repaint"
365 # Symlink splash daemon PID file
366 ln -sfT "$spl_pidfile" "$PID_LINK"
368 # Run any post rc_init hook
369 run_hook post rc_init
$softlevel $RUNLEVEL
371 # Avoid blackscreen (in spite of splash daemon running) or stale fbcondecor helper splash
372 # if theme is missing or video mode and theme do not match
373 # Give some error infos additional to those of the daemon to direct users in the right direction
374 # Unfortunately we can't check a theme loaded in the initcpio, so just hope there is no difference.
375 file=/etc
/splash
/$SPLASH_THEME/${SPLASH_XRES}x
${SPLASH_YRES}.cfg
377 if ! [[ -f $file ]]; then
378 silent_err
"File not found: '$file'" >&2
379 elif ! [[ $
( <"$file" ) =~
(^|$
'\n')[[:blank
:]]*${pic}(256)?
=[^
[:space
:]] ]]; then
380 silent_err
"Silent splash mode not supported in: '$file'"
382 read bpp
</sys
/class
/graphics
/fb
0/bits_per_pixel
&& [[ $bpp = 8 ]] && pic
+="256"
383 ! [[ $
( <"$file" ) =~
(^|$
'\n')[[:blank
:]]*${pic}=[^
[:space
:]] ]]; then
384 silent_err
"Splash theme / video mode bit depth mismatch."
391 printf -v sleep '.%03i' $ms_tick
396 ) </dev
/null
&>/dev
/null
&
399 # Run half way bootup hooks once in order to make sure any extra voodoo is done
400 splash_rc_exit_sysinit
() {
401 [[ $softlevel = "sysinit" ]] ||
return 0
402 run_hook pre rc_exit
"S"
403 run_hook post rc_exit
"S"
407 splash_rc_init_boot
() {
408 splash_rc_exit_sysinit
409 [[ $softlevel = "boot" ]] ||
return 0
410 read PREVLEVEL RUNLEVEL
< <( runlevel
2>/dev
/null
)
411 [[ $PREVLEVEL = ?
]] || PREVLEVEL
="N"
412 [[ $RUNLEVEL = [^Ss
] ]] || RUNLEVEL
=5
413 run_hook pre rc_init boot
$RUNLEVEL
414 run_hook post rc_init boot
$RUNLEVEL
420 # Stop ticker and remove pid file no matter how we exit
422 # Abort avoiding terminated message
424 # Names of progress (foreground) services (those done until splash stopped)
425 declare -a SPLASH_SVCS_FG
=( )
426 # Avarage services start times in ms
427 declare -A SPLASH_SVC_TIMES_MS
=( )
428 # Weighted count of starts * 100
429 declare -A SPLASH_SVC_TIMES_N100
=( )
430 # New services start times in ms
431 declare -A SPLASH_SVC_TIMES_MS_NEW
=( )
433 times_file
=${CACHE_DIR}/svc_
${action}_times
435 # Read in stored times
436 if [[ -f $times_file ]]; then
438 # Ignore garbled and empty lines to be save
439 [[ $line =~ ^
(.
+)" "([0-9]+)" "([0-9]+)[[:blank
:]]*$
]] ||
continue
440 SPLASH_SVC_TIMES_MS
["${BASH_REMATCH[1]}"]=${BASH_REMATCH[2]}
441 SPLASH_SVC_TIMES_N100
["${BASH_REMATCH[1]}"]=${BASH_REMATCH[3]}
446 local ms
=${SPLASH_SVC_TIMES_MS["$1"]}
447 # Fall back to one tick per foreground service run
448 if [[ $SPLASH_SMOOTH_PROGRESS = yes && $ms ]]
449 then (( ms_elapsed
+= ms
))
450 else (( ms_elapsed
+= ms_tick
))
453 # Read in foreground daemons and sum up relevant services times for progress
455 if [[ $svcs_fg_file ]]; then
456 while read -r svc
; do
457 [[ $svc ]] ||
continue
458 SPLASH_SVCS_FG
+=( "$svc" )
459 ms_elapsed_add
"$svc"
460 done <"$svcs_fg_file"
464 # If in environment, start at PROGRESS as the splash daemon does
465 progress_elapsed
=${PROGRESS:-0}
466 # Reserve some progress at the end and only let 'stop' do 100%
467 progress_max
=$
(( 65535 - 65535 / 100 )) # assume 100 pixel minimum progress bar length
468 # Update progress per tick to avoid jumping in favour of accelleration in case services skipped
469 progress_tick_set
() {
471 if (( ms_remain
> 0 && progress_max
> progress_elapsed
))
472 then progress_tick
=$
(( ( progress_max
- progress_elapsed
) * ms_tick
/ ms_remain
))
476 progress_tick_set $
(( ms_total
- ms_elapsed
))
479 # Disable progress until first foreground service event
481 svc_fg_ticks_elapsed
=0
483 # Normal status message
485 (( $# )) && message_normal
=$1
486 splash_set_message
"$message_normal"
487 # Cancel any previous text progress message
489 message_progress_ticks
=0
493 normal_message
"$( splash_get_boot_message )"
495 while read -r cmd args
<"${FIFO}"; do
499 (( svc_fg_ticks_elapsed
++ ))
500 # Text progress - Override status message for some time
501 if [[ $message_progress ]]; then
502 splash_set_message
"$message_progress"
504 message_progress_ticks
=$
(( 3000 / ms_tick
))
505 elif (( message_progress_ticks
> 0 )); then
506 # On timeout, fallback to push-message or restore
507 if (( -- message_progress_ticks
== 0 )); then
508 SPLASH_AUTOVERBOSE
=0 splash_set_message
"${message_push:-$message_normal}"
512 elif [[ $SPLASH_SMOOTH_PROGRESS = yes ]] &&
513 (( svc_fg_ticks_elapsed
<= svc_fg_ticks
&& progress_elapsed
< progress_max
)); then
514 (( progress_elapsed
+= progress_tick
))
515 splash_fifo_send
"progress $progress_elapsed" "paint"
516 # No progress - Override status message after timeout
517 elif (( message_push_ticks
> 0 )); then
518 (( -- message_push_ticks
== 0 )) && splash_set_message
"$message_push"
520 ;; comm ) splash_fifo_send
"$args"
522 # Ignore empty messages to avoid splash daemon crash ## FIXME ##
523 # 'repaint' needed at least for 'set message' if daemon not started with '--type=bootup'
524 [[ $args ]] && splash_fifo_send
"log ${args}" "repaint"
525 ;; progress-message
)
527 message_progress
=$args
528 # Cancel graphical progress for current service
530 elif [[ $message_progress ]] ||
(( message_progress_ticks
)); then
535 # Temporary override after progress timeout
536 if [[ $SPLASH_PUSH_DELAY = yes ]]; then
538 message_push_ticks
=$
(( 1000 / ms_tick
))
539 # Simple old mode: Just change it until next or exit
540 elif [[ $SPLASH_PUSH_MESSAGES = yes ]]; then
541 normal_message
"$args"
544 normal_message
"$args"
546 normal_message
"$( splash_get_boot_message )"
549 run_hook pre rc_exit
$RUNLEVEL
550 # Reset status message
551 splash_set_message
"$( splash_get_boot_message )"
552 # If not aborting, set 100% progress now because we reserved some
553 [[ $args = force
]] || splash_fifo_send
"progress 65535" "paint"
554 splash_fifo_send
"exit staysilent"
555 splash_wait
"$SPLASH_FADE_WAIT" $
( pgrep
-x -f "$spl_daemon .*" )
558 # Reopen moved profile for post rc_exit
559 # Note: If not bootup, the post rc_exit hook shouldn't try to write anything to the filesystem.
560 [[ $splash_profile_fd ]] && exec {splash_profile_fd
}<&-
561 unset -v splash_profile_fd
562 run_hook post rc_exit
$RUNLEVEL
565 [[ -d ${CACHE_DIR} ]] || mkdir
-p "${CACHE_DIR}"
566 for svc
in "${!SPLASH_SVC_TIMES_MS[@]}"; do
567 # Lower weight of old values by factor 0.98 on each boot - 0.98^34 = 0.5
568 n_100
=$
(( ${SPLASH_SVC_TIMES_N100["$svc"]:-0} * 98 / 100 ))
569 ms_avg
=${SPLASH_SVC_TIMES_MS["$svc"]:-0}
570 ms_new
=${SPLASH_SVC_TIMES_MS_NEW["$svc"]}
571 if [[ $ms_new ]]; then
572 echo $svc $
(( ( 100 * ms_new
+ n_100
* ms_avg
)/( 100 + n_100
) )) $
(( 100 + n_100
))
573 elif (( n_100
> 0 )); then
574 echo $svc $ms_avg $n_100
578 # Allow to set the general failure status explicitely (w/o a splash event)
579 splash_fifo_send
"update_svc fbsplash-dummy ${action}_failed" "paint"
584 # Avoid null/blank string crashing the splash daemon ## FIXME ##
585 [[ $args =~ ^\
*$
]] && continue
589 ;;& svc_started | svc_stopped
)
590 # Backwards compatibility: Add 0 exit code to hook args.
592 esac # Ignore any garbage
594 [[ $event ]] ||
continue
597 in svc_started | svc_start_failed
)
598 [[ $svc = fbsplash-boot-dummy
]] && splash_rc_init_boot
600 run_hook pre
"$event" "${hook_args[@]}"
605 # Cancel graphical progress for current service
607 splash_input_begin
"$svc"
609 splash_input_end
"$svc"
610 # Service update events
612 if [[ $1 = gpm
]]; then
613 # This loop shouldn't be needed as newer gpm puts itself in the background
614 # after started (like a daemon), but splashutils-gentoo does this also.
616 [[ -S /dev
/gpmctl
]] && break
619 splash_fifo_send
"set gpm" "repaint"
624 if [[ ${IFS}${SPLASH_SVCS_FG[*]}${IFS} = *"${IFS}${svc}${IFS}"* ]]; then
626 svc_fg_ms=${SPLASH_SVC_TIMES_MS["$svc"]}
627 if [[ $SPLASH_SMOOTH_PROGRESS = yes && $svc_fg_ms ]]
628 # Allow one more tick than calculated to avoid jumpiness
629 then svc_fg_ticks=$(( svc_fg_ms / ms_tick + 1 ))
632 # Silent step skipping
633 for i in "${!SPLASH_SVCS_FG[@]}"; do
634 svc_i=${SPLASH_SVCS_FG[i]}
635 [[ $svc_i = "$svc_fg" ]] && break
636 unset -v SPLASH_SVCS_FG[i]
637 ms_elapsed_add "$svc_i"
639 progress_tick_set $(( ms_total - ms_elapsed ))
642 ;;& svc_${action_done} )
643 # Save new time value (taking the first one in case of repeat)
644 if [[ $svc_fg = "$svc" ]] && (( svc_fg_ticks > 0 )) &&
645 [[ $SPLASH_SMOOTH_PROGRESS = yes && -z ${SPLASH_SVC_TIMES_MS_NEW["$svc"]} ]]; then
646 SPLASH_SVC_TIMES_MS_NEW["$svc"]=$(( svc_fg_ticks_elapsed * ms_tick ))
647 SPLASH_SVC_TIMES_MS["$svc"]+=""
649 ;;& svc_${action_done} | svc_${action}_failed )
650 if [[ $svc_fg = "$svc" ]]; then
651 # One tick per service mode
652 if [[ $SPLASH_SMOOTH_PROGRESS != yes ]]; then
653 (( progress_elapsed += progress_tick ))
654 splash_fifo_send "progress
$progress_elapsed"
658 svc_fg_ticks_elapsed=0
662 ;;& svc_start_failed | svc_stop_failed )
663 # Provide a general failure status
664 splash_fifo_send "update_svc fbsplash-dummy
$event"
665 # Simple/upstream way of error handling
666 # Assume error messages are shown on console even if background service
667 [[ $SPLASH_VERBOSE_ON_ERRORS = yes ]] && splash_verbose
669 splash_fifo_send "update_svc
$svc $event" "paint
"
671 run_hook post "$event" "${hook_args[@]}"
672 [[ $event = svc_start && $svc = fbsplash-boot-dummy ]] && splash_rc_exit_sysinit
675 echo $! $ticker_pid >>"$PID_FILE"