Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/scripts/generate-pr-plugin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,27 @@ if [ -s "$PAYLOAD/text_files.txt" ]; then
done
fi

# ---- Reactivate overlaid system daemons ------------------------------------
# The patch is applied late (on install, and at boot AFTER rc.M has already
# started these daemons with the stock config), so config we just overlaid does
# not take effect until the matching daemon is bounced — a plain reboot alone
# does not help because the plugin re-applies after rc.M each time. Restart the
# affected daemons here (after modes are restored, so their rc scripts are
# executable). Keep this to daemons that are safe to bounce live. Paths in
# text_files.txt are the packaged layout (etc/rc.d/* maps to usr/local/etc/rc.d/*).
if [ -s "$PAYLOAD/text_files.txt" ]; then
# elogind owns the physical power key unless a drop-in tells it to ignore it;
# it only reads logind.conf.d/ at startup, so reload it when that changes.
if grep -qE 'etc/elogind/|rc\.d/rc\.elogind$' "$PAYLOAD/text_files.txt" && [ -x /etc/rc.d/rc.elogind ]; then
echo "Reloading elogind (session/power-key policy changed)..."
/etc/rc.d/rc.elogind restart >/dev/null 2>&1 || true
fi
# rc.acpid installs Unraid's ACPI handler over the stock one at (re)start.
if grep -qE 'etc/acpi/|rc\.d/rc\.acpid$' "$PAYLOAD/text_files.txt" && [ -x /etc/rc.d/rc.acpid ]; then
echo "Restarting acpid (ACPI handler changed)..."
/etc/rc.d/rc.acpid restart >/dev/null 2>&1 || true
fi
fi
Comment on lines +283 to +295

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

does restarting elogind service terminate active login sessions

💡 Result:

Yes, restarting the elogind service typically causes the loss of all existing login sessions [1]. Elogind acts as a system daemon that manages user logins, tracks sessions, and maintains seat information [2][3]. When the service is restarted via the standard service manager, it generally triggers a stop operation that cleans up these sessions and seats, effectively terminating them [1][2]. Key technical considerations include: - Session Data Loss: Restarting the elogind service often results in the system failing to recognize previously active sessions, causing them to be considered stale or lost [4][5]. - Preferred Alternatives: To refresh configuration changes without terminating sessions, the command loginctl reload is recommended instead of restarting the service [1]. - Potential for Instability: Even if session processes (like the desktop environment or user shells) continue to run, the loss of elogind's tracking information can lead to various issues, such as failure to access system resources (e.g., audio, removable media) or improper handling of power management and shutdown requests [1][4][6][7]. In some specialized configurations, users may attempt to work around this by using specific signals to prevent the daemon from clearing session data upon exit, though this is generally discouraged and may not reliably preserve all session functionality across different distributions and software environments [4][6][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

git ls-files '.github/scripts/generate-pr-plugin.sh' 'README.md' 2>/dev/null || true
wc -l .github/scripts/generate-pr-plugin.sh
sed -n '260,310p' .github/scripts/generate-pr-plugin.sh

rg -n "elogind|loginctl reload|rc\.elogind" .github/scripts README.md .github -S || true

Repository: unraid/webgui

Length of output: 4019


Avoid restarting elogind live This restarts elogind and can drop active login sessions; use a non-disruptive reload path or defer the change until reboot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/generate-pr-plugin.sh around lines 283 - 295, Update the
elogind handling block in the payload-change logic to avoid invoking
`/etc/rc.d/rc.elogind restart`, which can terminate active sessions. Use the
supported non-disruptive reload mechanism, or defer elogind configuration
changes until reboot; leave the separate acpid restart behavior unchanged.

echo ""
echo "✅ Installation complete for PR #PR_PLACEHOLDER"
echo "⚠️ This is a TEST plugin — remove it before applying production updates"
Expand Down
12 changes: 12 additions & 0 deletions emhttp/languages/en_US/helptext.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,18 @@ Choose if rebooting or powering down the server needs a confirmation checkbox.
Choose if stopping the array needs a confirmation checkbox.
:end

:powerbutton_behavior_help:
Choose what happens when the server's physical power button is pressed.

**Shut down** performs a clean shutdown (stops the array and powers off). This is the default behavior.

**Reboot** performs a clean reboot.

**Do nothing** ignores the button press and only logs the event. This is useful on small form factor hardware where the power button is easily bumped, to prevent accidental shutdowns.

Plugins may add further actions (for example, Sleep via the S3 Sleep plugin, or running a User Script).
:end

:display_settings_help:
The display settings below determine how items are displayed on screen. Use these settings to tweak the visual effects to your likings.

Expand Down
60 changes: 60 additions & 0 deletions emhttp/plugins/dynamix/PowerButton.page
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Menu="PowerMode:2"
Title="Power Button"
Tag="icon-power"
---
<?PHP
/* Copyright 2005-2025, Lime Technology
* Copyright 2012-2025, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
$cur = _var($powermode,'powerbutton','shutdown');
?>

<form markdown="1" name="PowerButton" method="POST" action="/update.php" target="progressFrame">
<input type="hidden" name="#file" value="dynamix/dynamix.cfg">
<input type="hidden" name="#section" value="powermode">

_(Physical power button)_:
: <select name="powerbutton" id="powerbutton" onchange="powerbuttonExtra(this)">
<?=mk_option($cur, "shutdown", _('Shut down').' ('._('default').')')?>
<?=mk_option($cur, "reboot", _('Reboot'))?>
<?=mk_option($cur, "ignore", _('Do nothing'))?>
<?php
// Extension point: plugins add <option> lines for custom actions.
// In scope: $cur (current powerbutton value). See /etc/acpi/powerbutton.d/README.
foreach (glob('/usr/local/emhttp/plugins/*/include/powerbutton-option.php') ?: [] as $frag) include $frag;
?>
</select>

:powerbutton_behavior_help:

<?php
// Extension point: plugins add config rows shown when their action is selected.
// Each fragment outputs: <div class="powerbutton-extra" data-action="<action>" markdown="1"> ...fields... </div>
foreach (glob('/usr/local/emhttp/plugins/*/include/powerbutton-extra.php') ?: [] as $frag) include $frag;
?>

&nbsp;
: <span class="inline-block">
<input type="submit" name="#apply" value="_(Apply)_" disabled>
<input type="button" value="_(Done)_" onclick="done()">
</span>
</form>

<script>
function powerbuttonExtra(sel) {
var v = sel.value;
$('.powerbutton-extra').each(function(){
$(this).toggle($(this).data('action') === v);
});
}
$(function(){ powerbuttonExtra(document.getElementById('powerbutton')); });
</script>
76 changes: 2 additions & 74 deletions emhttp/plugins/dynamix/PowerMode.page
Original file line number Diff line number Diff line change
@@ -1,77 +1,5 @@
Menu="OtherSettings"
Type="xmenu"
Title="Power Mode"
Title="Power Options"
Tabs="true"
Icon="icon-energysaving"
Tag="icon-energysaving"
---
<?PHP
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
$cpufreq = '/sys/devices/system/cpu/cpu0/cpufreq';
$current = exec("cat $cpufreq/scaling_governor 2>/dev/null");
exec("cat $cpufreq/scaling_available_governors 2>/dev/null | tr ' ' '\n' | sed '/^$/d' | sort -u",$governor);

function value(...$modes) {
global $current, $governor;
$checked = $value = '';
$disabled = ' disabled';
foreach ($modes as $mode) {
if ($mode==$current) $checked = ' checked';
if (in_array($mode,$governor)) {$value = "value=\"$mode\""; $disabled = '';}
}
return $value.$checked.$disabled;
}
?>
<script>
function preparePowermode(form) {
$(form).find('[name="#arg[1]"]').val(form.powermode.value);
}
$(function(){
$('input[type=radio]').each(function(){
if ($(this).prop('disabled')) $(this).next('span').html(" <i>(_(unavailable)_)</i>");
});
<?if (exec("dmesg | grep -Pom1 'Hypervisor detected'")):?>
$('#vm').show();
<?endif;?>
});
</script>

<form markdown="1" name="PowerMode" method="POST" action="/update.php" target="progressFrame" onsubmit="preparePowermode(this)">
<input type="hidden" name="#file" value="dynamix/dynamix.cfg">
<input type="hidden" name="#section" value="powermode">
<input type="hidden" name="#command" value="/webGui/scripts/powermode">
<input type="hidden" name="#arg[1]" value="">

_(Change power mode)_:
: <span>
<input name="powermode" type="radio"<?=value('powersave')?>>_(Best power efficiency)_
</span>

&nbsp;
: <span>
<input name="powermode" type="radio"<?=value('ondemand','balance_power')?>>_(Balanced operation)_
</span>

&nbsp;
: <span>
<input name="powermode" type="radio"<?=value('performance')?>>_(Best performance)_
</span>

&nbsp;
: <span class="inline-block">
<input type="submit" name="#apply" value="_(Apply)_" disabled>
<input type="button" value="_(Done)_" onclick="done()">
</span>
</form>

<div id="vm" class="notice">_(When running Unraid virtualized, there are no available power modes)_</div>
75 changes: 75 additions & 0 deletions emhttp/plugins/dynamix/PowerModeCpu.page
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
Menu="PowerMode:1"
Title="Power Mode"
Tag="icon-energysaving"
---
<?PHP
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
$cpufreq = '/sys/devices/system/cpu/cpu0/cpufreq';
$current = exec("cat $cpufreq/scaling_governor 2>/dev/null");
exec("cat $cpufreq/scaling_available_governors 2>/dev/null | tr ' ' '\n' | sed '/^$/d' | sort -u",$governor);

function value(...$modes) {
global $current, $governor;
$checked = $value = '';
$disabled = ' disabled';
foreach ($modes as $mode) {
if ($mode==$current) $checked = ' checked';
if (in_array($mode,$governor)) {$value = "value=\"$mode\""; $disabled = '';}
}
return $value.$checked.$disabled;
}
?>
<script>
function preparePowermode(form) {
$(form).find('[name="#arg[1]"]').val(form.powermode.value);
}
$(function(){
$('input[type=radio]').each(function(){
if ($(this).prop('disabled')) $(this).next('span').html(" <i>(_(unavailable)_)</i>");
});
Comment on lines +38 to +40

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Unavailable-label injection currently never matches the DOM.

At Line 39, $(this).next('span') does not find anything because the radio inputs are followed by text nodes, not <span> siblings. As written, disabled options won’t get the “unavailable” note.

Suggested fix
 $(function(){
   $('input[type=radio]').each(function(){
-    if ($(this).prop('disabled')) $(this).next('span').html(" <i>(_(unavailable)_)</i>");
+    if ($(this).prop('disabled')) {
+      $(this).after(" <i>(_(unavailable)_)</i>");
+    }
   });
 <?if (exec("dmesg | grep -Pom1 'Hypervisor detected'")):?>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$('input[type=radio]').each(function(){
if ($(this).prop('disabled')) $(this).next('span').html(" <i>(_(unavailable)_)</i>");
});
$(function(){
$('input[type=radio]').each(function(){
if ($(this).prop('disabled')) {
$(this).after(" <i>(_(unavailable)_)</i>");
}
});
<?if (exec("dmesg | grep -Pom1 'Hypervisor detected'")):?>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@emhttp/plugins/dynamix/PowerModeCpu.page` around lines 38 - 40, The jQuery
selector `$(this).next('span')` in the disabled radio button check loop is not
finding the correct elements because radio inputs are not directly followed by
span siblings, but rather by text nodes or differently structured elements.
Inspect the actual HTML structure around the radio inputs to determine what
element actually follows them, then update the traversal method in the loop
(replacing `.next('span')`) to correctly locate the element that should receive
the unavailable label text. This may require using a different jQuery method
like .closest(), .parent(), or .find() depending on the actual DOM hierarchy.

<?if (exec("dmesg | grep -Pom1 'Hypervisor detected'")):?>
$('#vm').show();
<?endif;?>
});
</script>

<form markdown="1" name="PowerMode" method="POST" action="/update.php" target="progressFrame" onsubmit="preparePowermode(this)">
<input type="hidden" name="#file" value="dynamix/dynamix.cfg">
<input type="hidden" name="#section" value="powermode">
<input type="hidden" name="#command" value="/webGui/scripts/powermode">
<input type="hidden" name="#arg[1]" value="">

_(Change power mode)_:
: <span>
<input name="powermode" type="radio"<?=value('powersave')?>>_(Best power efficiency)_
</span>

&nbsp;
: <span>
<input name="powermode" type="radio"<?=value('ondemand','balance_power')?>>_(Balanced operation)_
</span>

&nbsp;
: <span>
<input name="powermode" type="radio"<?=value('performance')?>>_(Best performance)_
</span>

&nbsp;
: <span class="inline-block">
<input type="submit" name="#apply" value="_(Apply)_" disabled>
<input type="button" value="_(Done)_" onclick="done()">
</span>
</form>

<div id="vm" class="notice" style="height:auto;min-height:6rem;line-height:2.4rem;padding-top:1.8rem;padding-bottom:1.8rem">_(When running Unraid virtualized, there are no available power modes)_</div>
48 changes: 48 additions & 0 deletions etc/acpi/powerbutton.d/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/etc/acpi/powerbutton.d/ - Unraid power button action handlers (extension point)
================================================================================

The physical power button behavior is configured in the WebUI at
Settings > Power Options > Power Button. The selected action is stored as
[powermode]
powerbutton="<action>"
in /boot/config/plugins/dynamix/dynamix.cfg and dispatched at press time by
/etc/acpi/unraid_power_handler.sh.

Built-in actions: shutdown (default), reboot, ignore.

Actions that need their own setup or prep (suspend/sleep, running a User
Script, etc.) are NOT built in - they are provided by plugins through the
two-part hook below, so core stays free of plugin-specific or hardware-risky
behavior.

Plugins can ADD or OVERRIDE actions in two parts:

1) Action handler (required)
Ship an executable here, named after the action value:
/etc/acpi/powerbutton.d/<action>
It runs when the power button is pressed and that action is selected.
(e.g. the S3 Sleep plugin ships powerbutton.d/sleep to suspend with its
own array-aware prep.)

2) WebUI option (so users can pick it)
Add the action to the selector by shipping:
/usr/local/emhttp/plugins/<plugin>/include/powerbutton-option.php
which echoes one or more options, e.g.:
<?=mk_option($cur, "script", _('Run script'))?>
($cur is the currently saved powerbutton value.)

For extra fields shown only when your action is selected, also ship:
/usr/local/emhttp/plugins/<plugin>/include/powerbutton-extra.php
which outputs a block tagged with your action value:
<div class="powerbutton-extra" data-action="script" markdown="1">
_(Script)_:
: <select name="powerbuttonscript"> ... </select>
</div>
Fields are POSTed into dynamix.cfg [powermode] alongside powerbutton, so
your handler can read them with the same grep pattern used above.

Example (User Scripts plugin, "Run script" action):
- include/powerbutton-option.php : adds the "script" option + script picker
- include/powerbutton-extra.php : script selection dropdown
- /etc/acpi/powerbutton.d/script : reads powerbuttonscript= from dynamix.cfg
and executes the chosen user script
78 changes: 78 additions & 0 deletions etc/acpi/unraid_power_handler.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/bin/bash
#
# script: unraid_power_handler.sh
#
# Unraid ACPI event handler. Installed over /etc/acpi/acpi_handler.sh at boot
# by /etc/rc.d/rc.acpid, so it reliably overrides the stock Slackware acpid
# handler regardless of package install order.
#
# The physical power button behavior is configurable from the WebUI
# (Settings > Power Options > Power Button). The choice is stored in
# dynamix.cfg and read live on each event, so no acpid reload is needed
# when the setting changes.
#
# Plugins can add or override actions by dropping an executable handler in
# /etc/acpi/powerbutton.d/<action> - see /etc/acpi/powerbutton.d/README.
#
# LimeTech - modified for Unraid OS

CFG=/boot/config/plugins/dynamix/dynamix.cfg
PLUGIN_DIR=/etc/acpi/powerbutton.d

# acpid passes the raw event line, e.g.: "button/power PBTN 00000080 00000000"
set -- $@
group=${1%%/*}
action=${1#*/}

run_powerbutton(){
local behavior=$1
case "$behavior" in
ignore)
logger -t acpid "Power button: ignored (Power Options setting)"
;;
reboot)
logger -t acpid "Power button: rebooting"
/sbin/init 6
;;
shutdown)
logger -t acpid "Power button: initiating clean shutdown"
/sbin/init 0
;;
*)
# Extension point: plugin-provided action handler.
if [[ -n $behavior && -x $PLUGIN_DIR/$behavior ]]; then
logger -t acpid "Power button: running plugin action '$behavior'"
"$PLUGIN_DIR/$behavior"
else
logger -t acpid "Power button: unknown action '$behavior', ignoring"
fi
;;
Comment on lines +41 to +49

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Unexpected config values don't fall back to shutdown, contradicting the documented default.

The PR spec states the power button "defaults to shutdown for unset or unexpected values," but this code only defaults to shutdown when behavior is empty (${behavior:-shutdown} at line 68). Once inside run_powerbutton, a non-empty value that matches no built-in and has no executable under $PLUGIN_DIR falls into the *) branch and merely logs "unknown action ... ignoring" — the button silently does nothing instead of shutting down. A corrupted or stale dynamix.cfg value (e.g. from a removed plugin) would leave the physical power button unresponsive.

🔧 Proposed fix
     else
-      logger -t acpid "Power button: unknown action '$behavior', ignoring"
+      logger -t acpid "Power button: unknown action '$behavior', defaulting to shutdown"
+      /sbin/init 0
     fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
*)
# Extension point: plugin-provided action handler.
if [[ -n $behavior && -x $PLUGIN_DIR/$behavior ]]; then
logger -t acpid "Power button: running plugin action '$behavior'"
"$PLUGIN_DIR/$behavior"
else
logger -t acpid "Power button: unknown action '$behavior', ignoring"
fi
;;
*)
# Extension point: plugin-provided action handler.
if [[ -n $behavior && -x $PLUGIN_DIR/$behavior ]]; then
logger -t acpid "Power button: running plugin action '$behavior'"
"$PLUGIN_DIR/$behavior"
else
logger -t acpid "Power button: unknown action '$behavior', defaulting to shutdown"
/sbin/init 0
fi
;;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@etc/acpi/unraid_power_handler.sh` around lines 41 - 49, Update the
unknown-action fallback in run_powerbutton so non-empty values that match
neither a built-in action nor an executable plugin invoke the documented
shutdown behavior instead of being ignored. Preserve the plugin execution path
for valid executable handlers and retain shutdown handling for unset values.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Unsanitized config value used as a path component enables path traversal.

$behavior comes straight from dynamix.cfg (line 67) and is concatenated into $PLUGIN_DIR/$behavior with only an -x existence check — no validation that it excludes /. A value like powerbutton="../../../some/other/executable" would pass the -x check and get executed by root on every power-button press, reaching outside the intended /etc/acpi/powerbutton.d/ extension point. PowerButton.page's client-side validation isn't visible in this batch, so the handler shouldn't rely on it being the only guard.

🔒 Proposed fix
   *)
     # Extension point: plugin-provided action handler.
-    if [[ -n $behavior && -x $PLUGIN_DIR/$behavior ]]; then
+    if [[ -n $behavior && $behavior != */* && -x $PLUGIN_DIR/$behavior ]]; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
*)
# Extension point: plugin-provided action handler.
if [[ -n $behavior && -x $PLUGIN_DIR/$behavior ]]; then
logger -t acpid "Power button: running plugin action '$behavior'"
"$PLUGIN_DIR/$behavior"
else
logger -t acpid "Power button: unknown action '$behavior', ignoring"
fi
;;
*)
# Extension point: plugin-provided action handler.
if [[ -n $behavior && $behavior != */* && -x $PLUGIN_DIR/$behavior ]]; then
logger -t acpid "Power button: running plugin action '$behavior'"
"$PLUGIN_DIR/$behavior"
else
logger -t acpid "Power button: unknown action '$behavior', ignoring"
fi
;;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@etc/acpi/unraid_power_handler.sh` around lines 41 - 49, Validate the
config-derived behavior value before using it in the plugin path within the
wildcard action branch: accept only a simple executable name with no slash or
path traversal components, and ignore invalid values. Keep the existing
executable check, logging, and invocation behavior for validated plugin names,
using the behavior handling in the power-button case as the change point.

esac
}

case "$group" in
button)
case "$action" in
power)
# Debounce: some boards/acpid setups deliver the same power-button event
# more than once in quick succession, which would log (and act on) it
# twice. Ignore a repeat within 1 second of the previous press.
STAMP=/run/unraid_powerbutton.stamp
now=$(date +%s%N)
last=$(cat "$STAMP" 2>/dev/null)
echo "$now" >"$STAMP"
if [[ -n $last && $(( (now - last) / 1000000 )) -lt 1000 ]]; then
exit 0
fi
behavior=$(grep -Pom1 '^powerbutton="\K[^"]+' "$CFG" 2>/dev/null)
run_powerbutton "${behavior:-shutdown}"
;;
*)
logger -t acpid "ACPI action button/$action is not handled"
;;
esac
;;
*)
logger -t acpid "ACPI event $1 is not handled"
;;
esac
Loading
Loading