diff --git a/build/build-release b/build/build-release index 3a8d3939..72f7ccc6 100755 --- a/build/build-release +++ b/build/build-release @@ -43,7 +43,7 @@ for new in $(git status --short | awk -e '/^\?\?/{sub("^../","",$2);print "\\b" done for major in $(ls -d */ | grep -E '^[1-2]' | cut -d/ -f1); do case "$major" in - 17.2) exclude="dumaos";; + 17.2) exclude="dumaos unflock";; 18.1.c) exclude="transformer-cli";; 20.3.c) exclude="transformer-cli";; 2[01].4) exclude="set-optimal-bank-plan transformer-cli unpack-rbi";; diff --git a/utilities/README.md b/utilities/README.md index 1b68f6b8..ce32bf3a 100644 --- a/utilities/README.md +++ b/utilities/README.md @@ -17,6 +17,7 @@ A collection of utility scripts for your Technicolor router. Most of the names a - [set-web-admin-password](https://github.com/seud0nym/tch-gui-unhide/tree/master/utilities#set-web-admin-password) - [show-bank-plan](https://github.com/seud0nym/tch-gui-unhide/tree/master/utilities#show-bank-plan) - [transformer-cli](https://github.com/seud0nym/tch-gui-unhide/tree/master/utilities#transformer-cli) +- [unflock](https://github.com/seud0nym/tch-gui-unhide/tree/master/utilities#unflock) - [unpack-rbi](https://github.com/seud0nym/tch-gui-unhide/tree/master/utilities#unpack-rbi) - [update-ca-certificates](https://github.com/seud0nym/tch-gui-unhide/tree/master/utilities#update-ca-certificates) @@ -595,6 +596,19 @@ If run with the `-q` option, then no output is displayed, and you must rely on t ## transformer-cli Version 17 firmware does not include `/usr/bin/transformer-cli`, which is very useful for working out what is returned in the various GUI scripts. +## unflock +Checks for and optionally removes stale service file locks. +``` +Usage: ./unflock [options] + +Options: + -r Removes any found stale locks + -C Adds or removes the scheduled cron job +``` +Without the `-r` option, `unflock` will simply report any found stale locks. + +When run with the -C option (which should be the only option), the scheduled job will be added if it does not already exist, or removed if it does exist in the schedule. By default, the script will run every minute. You can modify the schedule through the Management card in `tch-gui-unhide`, or by directly modifying the /etc/crontab/root file. + ## unpack-rbi Unpacks the *.rbi* file passed as the first parameter. ``` @@ -616,6 +630,7 @@ Options: -C Adds or removes the scheduled monthly cron job -U Download the latest version of update-ca-certificates from GitHub ``` +When run with the -C option (which should be the only option), the scheduled job will be added if it does not already exist, or removed if it does exist in the schedule. By default, the script will run once month on a randomly selected day at a random time between 2:00am and 5:00am. You can modify the schedule through the Management card in `tch-gui-unhide`, or by directly modifying the /etc/crontab/root file. # How to download and execute these scripts If you download a tch-gui-unhide release archive, the scripts applicable to that firmware version are included. diff --git a/utilities/unflock b/utilities/unflock new file mode 100755 index 00000000..6fffd64b --- /dev/null +++ b/utilities/unflock @@ -0,0 +1,94 @@ +#!/bin/sh + +SCRIPT="$(basename $0)" + +if [ -z "$(which flock)" ]; then + echo "$SCRIPT: ERROR - unable to locate 'flock' executable. Aborting." + exit +fi +LSOF=$(which lsof) +if [ -z "$LSOF" ]; then + echo "$SCRIPT: ERROR - unable to locate 'lsof' executable. Aborting." + exit +fi + +usage() { +cat <> /etc/crontabs/root + echo "$SCRIPT: Scheduled file lock check for every minute." + fi + /etc/init.d/cron reload + exit;; + *) usage;; + esac +done + +services="" +for pid in $(pgrep flock); do + blocked=$(( $(date '+%s') - $(date -r /proc/$pid '+%s') )) + if [ $blocked -ge 60 ]; then + fd=$(sed -e 's/^.*flock//' /proc/$pid/cmdline | tr '\0' ' ' | xargs) + if [ -n "$fd" ]; then + if echo -n "$fd" | grep -E '[0-9]*'; then + lockfile=$(readlink /proc/$pid/fd/$fd) + else + lockfile="$fd" + fi + ppid=$(grep -i ^PPId /proc/$pid/status | cut -d: -f2 | xargs) + service=$(basename $(grep -oE '/etc/init.d/[^\0]*' /proc/$ppid/cmdline)) + if [ -n "$service" ]; then + action=$(tr '\0' ' ' < /proc/$ppid/cmdline | grep -oE '/etc/init.d/.*' | cut -d' ' -f2- | xargs) + if [ -e "$lockfile" ]; then + pids=$($LSOF $lockfile | grep $lockfile | grep -v "\b$pid\b\|\b$ppid\b" | tr -s ' ' | cut -d' ' -f2 | xargs echo $pid $ppid) + else + pids="$pid $ppid" + fi + echo "$SCRIPT: BLOCKED service='$service' lockfile='$lockfile' action='$action' pids=' $pids'" + for p in $pids; do + echo "$SCRIPT: $(ps | grep "\b$p\b")" + done + if ! echo "$services" | grep -q "^$service"; then + if [ -z "$services" ]; then + services="$service#$lockfile#$action#" + else + services="$services\n$service#$lockfile#$action#" + fi + fi + services=$(echo -e "$services" | sed -e "s|^\b$service\b.*|& $pids|") + fi + fi + fi +done + +if [ $__REMOVE = y -a -n "$services" ]; then + IFS='#' + echo -e "$services" | while read service lockfile action pids; do + [ -z "$service" -o -z "$lockfile" -o -z "$action" -o -z "$pids" ] && continue + echo "$SCRIPT: UNBLOCK service='$service' lockfile='$lockfile' action='$action' pids='$pids'" + rm $lockfile + kill $pids + /etc/init.d/$service $action + done +fi + +exit 0