From b00a5efe39bf1195ef0c8037093df2604afa911d Mon Sep 17 00:00:00 2001 From: Debian Live user Date: Fri, 28 Apr 2023 21:47:08 -0400 Subject: Got some new firefox launch code working. Now it uses a template file parameterized on $DISPLAY. Unfortunately, this file needs to be generated dynamically on install in order to set the IO parameters. (Might use systemd edit system for this, actually.) The ioslayer is also parameterized and started by the firefox unit file. Needs a little cleanup / removal of old code. --- src/firefox-io-slayer-redux | 95 +++++++++++++++++++++++++++++++++++++++++++++ src/firefox@.service.in | 19 +++++++++ src/generate-firefox-unit | 51 ++++++++++++++++++++++++ src/ioslay@.service | 5 +++ src/sliceweasel.lib.sh | 3 +- 5 files changed, 172 insertions(+), 1 deletion(-) create mode 100755 src/firefox-io-slayer-redux create mode 100755 src/firefox@.service.in create mode 100755 src/generate-firefox-unit create mode 100644 src/ioslay@.service (limited to 'src') diff --git a/src/firefox-io-slayer-redux b/src/firefox-io-slayer-redux new file mode 100755 index 0000000..fe54e37 --- /dev/null +++ b/src/firefox-io-slayer-redux @@ -0,0 +1,95 @@ +#!/bin/bash + +DISPLAY=$1 + +if [ -e /usr/lib/bash/sleep ] +then + enable -f /usr/lib/bash/sleep sleep +fi + +export NOTICE=y +noticeLOG() { [ "$NOTICE" ] || return; echo "Notice: $*" >&2; } +debugLOG() { [ "$DBG" ] || return; echo "Debug: $*" >&2; } + +. sliceweasel.lib.sh + +vkill() +{ + if [ $# = 0 ] + then + return + fi + ( + if [ "$(id -u)" = 0 ] + then sudo= + else sudo=sudo + fi + set -x + ps u "$@" + $sudo kill "$@" + ) +} + +slay_slayer() +{ + if [ "$ioslay" ] + then + children=$(for pid in $ioslay; do pgrep -P $ioslay; done) + grandchildren=$(for pid in $children; do pgrep -P $pid; done) + vkill $ioslay $children $grandchildren + fi +} + +group_procs=$(get_firefox_cgroup_procs) + +ioslay= +lastprocs= +SIGNALLED= +trap 'SIGNALLED=y' SIGINT SIGTERM SIGHUP +while [ ! "$SIGNALLED" ] +do + if ! [ -e "$group_procs" ] + then + [ "$warned" ] || echo "Warning: firefox not running or cgroup not found" >&2 + warned=y + else + if [ "$warned" ] + then + echo "Found firefox cgroup: $group_procs" >&2 + warned= + fi + read -N 1000100 procs < "$group_procs" + if [ "$procs" ] + then + set -- + for pid in $procs + do + read comm < /proc/$pid/comm + case "$comm" in + 'Isolated Web Content' | 'Web Content' | 'Isolated Web Co') + set -- "$@" "$pid" + debugLOG "accept /proc/$pid/comm $comm" + ;; + *) + debugLOG "reject /proc/$pid/comm $comm" + esac + done + + # echo "pids: ($*|$(echo $procs))" >&2 + if [ "$lastargs" != "$*" ] + then + slay_slayer + wait $ioslay + if [ $# -gt 0 ] + then + ioslay-firefox "$@" & + ioslay=$! + noticeLOG "Launched ioslay-firefox[$ioslay] $*" + fi + fi + lastargs=$* + fi + fi + sleep 1 +done +slay_slayer diff --git a/src/firefox@.service.in b/src/firefox@.service.in new file mode 100755 index 0000000..e3c0329 --- /dev/null +++ b/src/firefox@.service.in @@ -0,0 +1,19 @@ +[Unit] +Description = Firefox +# Requires=ioslay@%I +# Requires=pulseaudio.socket # require X11 somehow +ConditionUser = !root # seems reasonable +ConditionEnvironment = DISPLAY + +[Service] +ExecStartPre = /usr/bin/systemctl --user start ioslay@%I +ExecStart = /usr/local/bin/firefox +Restart = on-failure +PassEnvironment = DISPLAY XAUTHORITY +MemoryMax = 50% +IOReadIOPSMax = +IOWriteIOPSMax = + +[Install] +Also=ioslay@.service +WantedBy = default.target # make an X11 user target? diff --git a/src/generate-firefox-unit b/src/generate-firefox-unit new file mode 100755 index 0000000..c285ffc --- /dev/null +++ b/src/generate-firefox-unit @@ -0,0 +1,51 @@ +#!/bin/bash + +INPUT_FILE=$1 +OUTPUT_FILE=$2 + +die() { printf "%s: Error: %s\n" "$0" "$*" >&2; exit 1; } + +# Test DEVICE WRITE OPS BY WRITEOPS +test_write_ops() +{ + if ! [ -e "$1" ] + then + mkdir -p "$(dirname "$1")" + sync + begin=$(date +%s%N) + dd if=/dev/urandom of="$DIR"/urandom.out bs=1M count=300 + sync + end=$(date +%s%N) + ops=$(( (end - begin) / 1000000000 )) + rm "$DIR"/urandom.out + echo "$ops" > "$1" + fi + cat "$1" +} + +DIR=~/.mozilla +READ_OPS=1G +WRITE_OPS=$READ_OPS +CONFDIR=$HOME/.config/firestart + +if [ -e "$CONFDIR"/conf ] +then + . "$CONFDIR"/conf +fi + +WRITE_OPS=$(test_write_ops "$CONFDIR"/diskspeed.dat) +WRITE_OPS=${WRITE_OPS%.*} +READ_OPS=$WRITE_OPS + +[ -e "$DIR" ] || die "does not exist: $DIR" +[ -d "$DIR" ] || die "not a directory: $DIR" + +DEV=$(echo $(findmnt --target "$DIR" -o MAJ:MIN -n)) +[ "$DEV" ] || die "could not determine backing device for $DIR" + +IOReadIOPSMax="$DEV $READ_OPS" +IOWriteIOPSMax="$DEV $WRITE_OPS" + +sed -e "s/^IOReadIOPSMax *=.*/IOReadIOPSMax = $IOReadIOPSMax/" \ + -e "s/^IOWriteIOPSMax *=.*/IOWriteIOPSMax = $IOWriteIOPSMax/" \ + < "$INPUT_FILE" > "$OUTPUT_FILE" diff --git a/src/ioslay@.service b/src/ioslay@.service new file mode 100644 index 0000000..1a00bd4 --- /dev/null +++ b/src/ioslay@.service @@ -0,0 +1,5 @@ +[Unit] +Description = Kill firefox when it spins the disk + +[Service] +ExecStart = /usr/local/bin/firefox-io-slayer-redux %I diff --git a/src/sliceweasel.lib.sh b/src/sliceweasel.lib.sh index 3b42a61..7f70e08 100755 --- a/src/sliceweasel.lib.sh +++ b/src/sliceweasel.lib.sh @@ -112,7 +112,8 @@ get_firefox_cgroup_procs() { uid=$(get_uid) [ "$uid" ] || return - echo /sys/fs/cgroup/user.slice/user-$uid.slice/user@$uid.service/app.slice/firefox.service/cgroup.procs + [ "$DISPLAY" ] || return + echo /sys/fs/cgroup/user.slice/user-$uid.slice/user@$uid.service/app.slice/app-firefox.slice/firefox@$DISPLAY.service/cgroup.procs } get_current_group() -- cgit v1.2.3