You are not logged in.
Pages: 1
I am trying to access power profiles for AMD laptop (thinkpad 14s Gen4 AMD).
Devuan daedalus works well in general on this laptop but trying to set power profiles fails.
install:
apt install power-profiles-daemon
try to access power-profiles:
# powerprofilesctl get
Failed to communicate with power-profiles-daemon: g-dbus-error-quark: Error calling StartServiceByName for net.hadess.PowerProfiles: Launch helper exited with unknown return code 1 (25)
looks like the service is not running.
There is no sysvinit definition but there is a systemd unit file:
[Unit]
Description=Power Profiles daemon
Conflicts=tuned.service auto-cpufreq.service system76-power.service
Before=multi-user.target display-manager.target
[Service]
Type=dbus
BusName=net.hadess.PowerProfiles
ExecStart=/usr/libexec/power-profiles-daemon
Restart=on-failure
# This always corresponds to /var/lib/power-profiles-daemon
StateDirectory=power-profiles-daemon
#Uncomment this to enable debug
#Environment="G_MESSAGES_DEBUG=all"
# Lockdown
ProtectSystem=strict
ProtectControlGroups=true
ProtectHome=true
ProtectKernelModules=true
PrivateTmp=true
RestrictAddressFamilies=AF_UNIX AF_LOCAL AF_NETLINK
MemoryDenyWriteExecute=true
RestrictRealtime=true
[Install]
WantedBy=graphical.target
running the command directly does allow access to power profile:
/usr/libexec/power-profiles-daemon
I am looking to create a sysvinit file for this daemon. I think I can do that with just the daemon command, but not sure if it should be connected to Dbus more explicitly?
Offline
There is another solution - power management using DE.
In Trinity, for example, there is a tdepowersave program in which everything is configured in 15 seconds.
It hangs in the tray and issues warnings when necessary.
KDE5 has something similar.
Another question is that in Daedalus, turning off the laptop when closing the lid (this is how I set it up) happens every other time, sometimes it “falls asleep” in the middle of the process and to continue you need to open the lid.
There was no such glitch in Chimaera.
Regards.
Offline
# systemd to sysvinit startup script conversion
# ref. https://dev1galaxy.org/viewtopic.php?pid=23309#p23309
...has this handy link to a converting script.
sysd2v-0.3.sh , over 500 lines, 15kb file not at the link in that post...
#!/bin/sh
# sysd2v v0.3 -- systemd unit to sysvinit script converter
# Copyright (C) 2019 Trek http://www.trek.eu.org/devel/sysd2v
# distributed under the terms of the GNU General Public License 3
nl="
"
# read a systemd unit file and set variables named ini_{section}_{key}
# usage: read_unit filename instance
# filename service unit configuration file, '-' to read from stdin
# instance instance name for template units
read_unit()
{
filename=$1
instance=$2
if [ "$filename" != - ]
then
inifile_unit_name=${filename##*/}
inifile_unit_name=${inifile_unit_name%.*}
fi
rm_comm='/^[#;]/d'
concat=':l; /\\$/ { N; s/[[:space:]]*\\\n/ /; tl }'
subst_inst="s/%[Ii]/$instance/g"
unit=$(
cat "$filename" |
sed "$rm_comm" |
sed "$concat;$subst_inst"
)
section_list=$(
printf %s "$unit" |
sed -n 's/^\[\([[:alnum:]]\+\)\].*/\1/p'
)
oldifs=$IFS
IFS=$nl
for section in $section_list
do
get_sect='/^\['"$section"'\]/,/^\[.\+\]/'
key_list=$(
printf %s "$unit" |
sed -n "$get_sect"'s/^\([[:alnum:]]\+\)[[:space:]]*=.*/\1/p' |
sort -u
)
for key in $key_list
do
val=$(
printf %s "$unit" |
sed -n "$get_sect"'s/^'"$key"'[[:space:]]*=[[:space:]]*\(.*\)/\1/p'
)
var=$(
echo "${section}_$key" |
tr '[:upper:]' '[:lower:]'
)
eval ini_$var=\$val
[ -n "$debug" ] && echo "ini_$var=$val" >&2
done
done
IFS=$oldifs
}
# read a systemd configuration value and write its prefix to stdout
# usage: get_prefix val
# val systemd configuration value
get_prefix () { printf %s "$1" | sed -n 's/^\([-@:+!|]*\).*/\1/p'; }
# read a boolean value and returns true or false
# usage: is_true val
# val boolean value
is_true () { case "$1" in 1|[Oo][Nn]|[Tt]*|[Yy]*) true;; *) false; esac }
# read systemd services list and write LSB facilities to stdout
# usage: get_provides services
# services list of service units
get_provides ()
{
lst=
for dep in $1
do
lst=${lst:+$lst }${dep%.service}
done
printf %s "$lst"
}
# read systemd units list and write LSB facilities to stdout
# usage: get_depends dependencies [ignores]
# dependencies list of required units
# ignores facilities to ignore
get_depends ()
{
lst=
for dep in $1
do
d=
case $dep in
local-fs-pre.target) d=mountkernfs;;
time-sync.target) d=\$time;;
systemd-modules-load.service) d=kmod;;
local-fs.target|network-pre.target) d=\$local_fs;;
systemd-sysctl.service) d=procps;;
network.target|network-online.target|systemd-networkd.service)
d=\$network;;
nss-lookup.target) d=\$named;;
rpcbind.target|remote-fs-pre.target) d=\$portmap;;
remote-fs.target|sysinit.target|basic.target) d=\$remote_fs;;
syslog.service) d=\$syslog;;
boot-complete.target|multi-user.target|default.target) d=\$all;;
*.service) d=${dep%.service};;
*) echo "WARNING: unsupported target '$dep'" >&2
esac
ign=${2:+$2 }$lst
[ -z "$ign" -o -n "${ign%%*"$d"*}" ] &&
lst=${lst:+$lst }$d
done
printf %s "$lst"
}
# read LSB facilities list and write runlevel to stdout
# usage: get_runlevel facilities
# facilities list of required facilities
get_runlevel ()
{
case $1 in
*\$remote_fs*) echo 2 3 4 5;;
*) echo S
esac
}
# write a list of environment files to be executed
# usage: write_env list
# list files separated by newlines, with prefix (-)
write_env ()
{
oldifs=$IFS
IFS=$nl
for env in $1
do
pre=$(get_prefix "$env")
noerr=
[ -n "$pre" -a -z "${pre%%*-*}" ] && noerr="[ -r ${env#$pre} ] && "
printf '%s\n' "$noerr. ${env#$pre}"
done
IFS=$oldifs
}
# write an environment variable containing paths
# usage: write_path name prefix list
# name name of the environment variable
# prefix path prefix to append directories
# list paths separated by spaces or newlines
write_path ()
{
lst=
for dir in $3
do
lst=${lst:+$lst:}$2/$dir
done
[ -z "$3" ] || printf '%s=%s\n' $1 $lst
}
# write a list of directories to be created
# usage: write_install prefix list [user [group [mode]]]
# prefix path prefix to append directories
# list paths separated by spaces or newlines
# user user ownership
# group group ownership
# mode permission mode
write_install ()
{
for dir in $2
do
printf ' install -d %s%s/%s || return 2\n' \
"${3:+-o $3 }${4:+-g $4 }${5:+-m $5 }" "$1" "$dir"
done
}
# write a list of commands applying systemd executable prefixes
# usage: write_commands list [run [runpriv]]
# list commands separated by newlines, with prefixes (-@:+!)
# run command line to run each command (nice, chrt, ...)
# runpriv command line to set privileges (runuser, ...)
write_commands ()
{
oldifs=$IFS
IFS=$nl
for cmd in $1
do
pre=$(get_prefix "$cmd")
beg=$3
end=' || return 2'
if [ -n "$pre" ]
then
[ -z "${pre%%*-*}" ] && end=
[ -z "${pre%%*[+!]*}" ] && beg=
[ -z "${pre%%*[@:]*}" ] &&
echo "WARNING: unsupported exec prefix '$pre'" >&2
fi
printf ' %s\n' "$2$beg${cmd#$pre}$end"
done
IFS=$oldifs
}
# read a list of commands separated by newlines and write an override function
# usage: write_function name [commands]
# name function name (start_cmd, stop_cmd, ...)
# commands list of commands, read from stdin if omitted
write_function ()
{
lst=${2-$(cat)}
[ -n "$lst" ] || return
[ "$lst" = : ] && printf "do_${1}_override () :\n\n" && return
end=' true\n'
[ -z "${lst%%*|| return [0-9]}" -o -z "${lst%%*|| return \$?}" ] && end=
printf "do_${1}_override ()\n{\n%s\n$end}\n\n" "$lst"
}
# write an init-d-script file starting from the ini_* vars (see read_unit)
# usage: write_init servicename instance
# servicename name of the service provided
# instance instance name for template units
write_init ()
{
name=$1
instance=$2
if [ "${name%@}" != "$name" ]
then
name=$name$instance
fi
daemon_pre=$(get_prefix "$ini_service_execstart")
daemon=${ini_service_execstart#$daemon_pre}
if [ "${daemon%%[[:space:]]*}" != "$daemon" ]
then
daemon_args=${daemon#*[[:space:]]}
daemon=${daemon%%[[:space:]]*}
fi
pidfile=$ini_service_pidfile
if [ -n "$ini_service_user" ]
then
start_args="--user $ini_service_user"
[ -n "$daemon_pre" -a -z "${daemon_pre%%*[+!]*}" ] ||
start_args="$start_args --chuid $ini_service_user"
stop_args="--user $ini_service_user"
runprivstart="runuser -u $ini_service_user -- "
is_true "$ini_service_permissionsstartonly" || runpriv=$runprivstart
fi
cls=$ini_service_ioschedulingclass
pri=$ini_service_ioschedulingpriority
[ -n "$cls$pri" ] &&
start_args="$start_args --iosched ${cls:-best-effort}${pri:+:$pri}" &&
run="ionice ${cls:+-c $cls }${pri:+-n $pri }"
pol=$ini_service_cpuschedulingpolicy
pri=$ini_service_cpuschedulingpriority
[ -n "$pol$pri" ] &&
start_args="$start_args --procsched ${pol:-other}${pri:+:$pri}" &&
run="${run}chrt ${pol:+--$pol }${pri:-0} "
[ -n "$ini_service_nice" ] &&
start_args="$start_args --nicelevel $ini_service_nice" &&
run="${run}nice -n $ini_service_nice "
pre=$(get_prefix "$ini_service_workingdirectory")
workdir=${ini_service_workingdirectory#$pre}
[ "$workdir" = '~' ] && workdir=\~$ini_service_user
[ -n "$workdir" ] &&
start_args="$start_args --chdir $workdir" &&
chdir="${pre}cd $workdir"
if [ -z "${service_type:=$ini_service_type}" ]
then
if [ -n "$ini_service_busname" ]
then
service_type=dbus
elif [ -n "$ini_service_execstart" ]
then
service_type=simple
else
service_type=oneshot
fi
fi
if [ "$service_type" != forking ]
then
start_args="$start_args --background"
[ -z "$pidfile" -a "$ini_service_killmode" != none ] &&
start_args="$start_args --make-pidfile" &&
pidfile="/var/run/$name-sysd2v.pid"
fi
if [ "$service_type" = notify ]
then
start_args="$start_args --notify-await"
timeout=${ini_service_timeoutstartsec:-$ini_service_timeoutsec}
timeout=${timeout%s}
[ -n "${timeout#60}" ] &&
start_args="$start_args --notify-timeout $timeout"
[ -n "$timeout" -a -z "${timeout%%*[^0-9]*}" ] &&
echo "WARNING: unsupported timeout '$timeout'" >&2
elif [ "$service_type" = dbus ]
then
: TODO
fi
signal=${ini_service_killsignal#SIG}
timeout=${ini_service_timeoutstopsec:-$ini_service_timeoutsec}
timeout=${timeout%s}
[ -n "${signal#TERM}" -o -n "${timeout#90}" ] &&
stop_args="$stop_args --retry=${signal:-TERM}/${timeout:-90}/KILL/5"
limitnofile=$ini_service_limitnofile
[ "$limitnofile" = infinity ] && limitnofile=unlimited
need_install=$ini_service_runtimedirectory
need_install=$need_install$ini_service_statedirectory
need_install=$need_install$ini_service_cachedirectory
need_install=$need_install$ini_service_logsdirectory
need_install=$need_install$ini_service_configurationdirectory
need_do_start=$ini_service_execstartpre$ini_service_execstartpost
need_do_start=$need_do_start$need_install
execstop=$ini_service_execstop
if [ "$service_type" != oneshot ]
then
[ "$pidfile" = "/var/run/${daemon##*/}.pid" ] && unset pidfile
[ "$name" = "${daemon##*/}" ] && unset name
[ -n "$daemon_args" -a -z "${daemon_args%%*[\"\\]*}" ] &&
echo "WARNING: DAEMON_ARGS needs to be escaped" >&2
errcheck=' || return $?'
if [ -n "$daemon_pre" ]
then
[ -z "${daemon_pre%%*-*}" ] && errcheck=
[ -z "${daemon_pre%%*[@:]*}" ] &&
echo "WARNING: unsupported exec prefix '$daemon_pre'" >&2
fi
# TODO: test if already running before start (pretest="+do_status_cmd")
[ -n "$need_do_start" -o -z "$errcheck" ] &&
execstart="-+do_start_cmd$errcheck"
errcheck=' || return $?'
[ -n "$execstop" ] && errcheck=
[ -n "$execstop$ini_service_execstoppost" -a \
"$ini_service_killmode" != none ] &&
killstop="-do_stop_cmd$errcheck"
[ -n "$timeout" -a -z "${timeout%%*[^0-9]*}" ] &&
echo "WARNING: unsupported timeout '$timeout'" >&2
else
daemon=none
pidfile=none
: ${name:=SERVICE_NAME}
unset daemon_args start_args stop_args
execstart=$ini_service_execstart
runstart=$run
fi
need_do_start=$need_do_start$execstart
start_args=${start_args# }
stop_args=${stop_args# }
aliases=$(get_provides "$ini_install_alias")
[ -z "$ini_unit_defaultdependencies" ] ||
is_true "$ini_unit_defaultdependencies" &&
defdep=sysinit.target
req_start=$(get_depends "$ini_unit_requires $defdep")
should_start=$(get_depends "$ini_unit_wants $ini_unit_after" "$req_start")
default_start=$(get_runlevel "$req_start $should_start")
[ "$default_start" = S ] && default_stop='0 6' || default_stop='0 1 6'
[ -z "$execstop$ini_service_execstoppost" ] &&
[ "$service_type" = oneshot -o "$ini_service_killmode" = none ] &&
default_stop=
[ "$default_start" = S ] && ignore=\$remote_fs
start_before=$(get_depends "$ini_unit_requiredby $ini_install_wantedby
$ini_unit_before" "$req_start $should_start \$all $ignore")
cat <<EOF
#!/bin/sh
# Generated by sysd2v v0.3 -- http://www.trek.eu.org/devel/sysd2v
# kFreeBSD do not accept scripts as interpreters, using #!/bin/sh and sourcing.
if [ true != "\$INIT_D_SCRIPT_SOURCED" ] ; then
set "\$0" "\$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
fi
### BEGIN INIT INFO
# Provides: ${name:-${daemon##*/}}${aliases:+ $aliases}
# Required-Start: $req_start
# Required-Stop: ${default_stop:+$req_start}
${should_start:+# Should-Start: $should_start
${default_stop:+# Should-Stop: $should_start
}}${start_before:+# X-Start-Before: $start_before
${default_stop:+# X-Stop-After: $start_before
}}# Default-Start: $default_start
# Default-Stop: $default_stop
# Description: ${ini_unit_description:-SERVICE_DESCRIPTION}
### END INIT INFO
EOF
if [ -n "$ini_service_environment$ini_service_environmentfile$need_install" ]
then
echo set -a
write_path RUNTIME_DIRECTORY /run "$ini_service_runtimedirectory"
write_path STATE_DIRECTORY /var/lib "$ini_service_statedirectory"
write_path CACHE_DIRECTORY /var/cache "$ini_service_cachedirectory"
write_path LOGS_DIRECTORY /var/log "$ini_service_logsdirectory"
write_path CONFIGURATION_DIRECTORY /etc \
"$ini_service_configurationdirectory"
printf '%s' "${ini_service_environment:+$ini_service_environment$nl}"
write_env "$ini_service_environmentfile"
printf 'set +a\n\n'
fi
cat <<EOF
${name:+DESC=\"$name\"
}DAEMON=$daemon
${daemon_args:+DAEMON_ARGS=\"$daemon_args\"
}${pidfile:+PIDFILE=$pidfile
}${start_args:+START_ARGS=\"$start_args\"
}${stop_args:+STOP_ARGS=\"$stop_args\"
}${limitnofile:+ulimit -n $limitnofile
}${ini_service_umask:+umask $ini_service_umask
}
EOF
if [ -n "$need_do_start" ]
then
{
write_install /run "$ini_service_runtimedirectory" \
"$ini_service_user" "$ini_service_group" \
"$ini_service_runtimedirectorymode"
write_install /var/lib "$ini_service_statedirectory" \
"$ini_service_user" "$ini_service_group" \
"$ini_service_statedirectorymode"
write_install /var/cache "$ini_service_cachedirectory" \
"$ini_service_user" "$ini_service_group" \
"$ini_service_cachedirectorymode"
write_install /var/log "$ini_service_logsdirectory" \
"$ini_service_user" "$ini_service_group" \
"$ini_service_logsdirectorymode"
write_install /etc "$ini_service_configurationdirectory" '' '' \
"$ini_service_configurationdirectorymode"
write_commands "$chdir"
write_commands "$ini_service_execstartpre" "$run" "$runpriv"
write_commands "$execstart" "$runstart" "$runprivstart"
write_commands "$ini_service_execstartpost" "$run" "$runpriv"
} | write_function start_cmd
else
[ "$service_type" = oneshot ] && write_function start :
fi
if [ -n "$execstop$ini_service_execstoppost" ]
then
{
write_commands "$chdir"
write_commands "$execstop" "$run" "$runpriv"
write_commands "$killstop"
write_commands "$ini_service_execstoppost" "$run" "$runpriv"
} | write_function stop_cmd
else
[ "$service_type" = oneshot -o "$ini_service_killmode" = none ] &&
write_function stop :
fi
if [ "$ini_service_execreload" = '/bin/kill -HUP $MAINPID' -a \
-z "$run$runpriv" ]
then
printf 'alias do_reload=do_reload_sigusr1\n\n'
elif [ -n "$ini_service_execreload" ]
then
{
write_commands "$chdir"
write_commands "$ini_service_execreload" "$run" "$runpriv"
} | write_function reload_cmd
cat <<"EOF"
do_reload ()
{
log_daemon_msg "Reloading $DESC configuration files" "$NAME"
MAINPID=$(cat $PIDFILE)
do_reload_cmd_override
log_end_msg $?
}
EOF
fi
[ "$service_type" = oneshot ] && write_function status :
}
# parse command line
while getopts di:n: opt
do
case $opt in
d) debug=1;;
i) instance=$OPTARG;;
n) name=$OPTARG;;
?) printf "Usage: %s [-d] [-i instance] [-n servicename] [filename]\n" \
"$0"
exit 2;;
esac
done
: ${instance=INSTANCE_NAME}
shift $(($OPTIND - 1))
# convert unit file
read_unit "${1:--}" "$instance"
write_init "${name-$inifile_unit_name}" "$instance"
I have a copy... (not sure if I may post it here in code tags???)
happy to share.
Maybe it'll work for you. Just look out for start and stop levels being consistent with your system.
Last edited by GlennW (2023-12-01 00:51:28)
pic from 1993, new guitar day.
Online
Thanks GlennW, a useful script!
There are a few things to consider as far as the best power management solution...
Here are some useful references:
- https://www.reddit.com/r/thinkpad/comme … ittle_fan/
- https://wiki.archlinux.org/title/Lenovo … -State_EPP
- https://www.phoronix.com/review/linux-65-thinkpad
- https://www.phoronix.com/news/Linux-6.6 … Management
Currently, I am using the 6.5.0.0. kernel from daedalus-backports.
aluma, if you are having sleep issues, you may want to try that kernel, no sleep issues for me.
However, the wifi driver doesn't wake from hibernate (known issue for that kernel driver)
- https://wiki.archlinux.org/title/Lenovo … ibernation
Note that I have tried the suggestion from the reddit post above and getting good power utilisation rate now (around 5.5 - 7W which should give close to 10hr battery life).
echo 'power' | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference
I will write up an install guide for Devuan for the laptop soon, but looks really good and should improve even further with new kernel releases.
Offline
Pages: 1