gdm 用シャットダウンスクリプト (2007/06/05)

gdmのデフォルト設定ではどんな場合にもかかわらず一般ユーザのシャットダウンが可能です./etc/gdm/gdm.confを設定すれば一般ユーザによるシャットダウンは禁止できます(gdm の一般ユーザのシャットダウン禁止についてを参照).しかし,一般ユーザがシャットダウンを全くできないというのも不便です.そこで,ユーザのログイン及びプロセスをチェックしてからシャットダウンするシェルスクリプトを用意して,gdmからシャットダウンする際にはそのシェルスクリプトをたたく方法をとりました(gdm の一般ユーザのシャットダウン許可についてを参照).

しかし,そのシェルスクリプトでは,ローカルユーザがログインしている場合にもシャットダウンできない,といった問題がありました.また,シャットダウンするかどうかを判断する際に無視するプロセスを記述しなくてはならない,といった柔軟性に欠ける問題もありました.そこで,そのシェルスクリプトを書き直しました.

シャットダウンを阻止するときのルールは,

  1. リモートログインしているユーザがいる (whoコマンドの最後のフィールドで判断)
  2. CPU使用率が50%を越えるプロセスが走っている (psコマンドの出力をgawkコマンドでフィルタ)
のいずれかが成立している場合としました.この2つの条件がどちらも成立しない場合に限り,gdmのシャットダウンコマンドとしてこのコマンドをたたけば一般ユーザによるシャットダウンが可能です.以下が,そのシェルスクリプトです.

#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin
TEMP_FILE=/tmp/shutdown-gdm.$$
PS_FORMAT="user,uid,pid,%cpu,%mem,tname,command"
LOCAL_DOMAIN="hoge.jp"
START_UID=10000
END_UID=15000
THRESHOLD=50.0

# error: gdm startup
gdm_startup() {
  rm $TEMP_FILE
  /etc/init.d/gdm start
  exit 1
}

# interrupt
trap 'gdm_startup' 1 2 3 15

# check remote login users
who | egrep $LOCAL_DOMAIN > $TEMP_FILE
if [ -s $TEMP_FILE ]; then
  echo "Remote users login now. Shutdown is rejected."
  cat $TEMP_FILE
  sleep 5
  gdm_startup
fi

# check running process
ps --no-headers -eo $PS_FORMAT | \
 gawk '$2>='$START_UID | \
 gawk '$2<'$END_UID | \
 gawk '$4>='$THRESHOLD > $TEMP_FILE
if [ -s $TEMP_FILE ]; then
  echo "User heavy processes are running. Shutdown is rejected."
  cat $TEMP_FILE
  sleep 5
  gdm_startup
fi

# halt or reboot
sync; sync; sync
shutdown $@

上記のスクリプト内のLOCAL_DOMAIN, START_UID, END_UID, THRESHOLDは環境に応じて変更する必要がることに注意して下さい.このシェルスクリプトを/usr/local/sbin/shutdown-gdmにおきます.そして,/etc/gdm/gdm.confに次のように記述すれば,リモートログイン及びCPU使用率の高いプロセスをチェックしてからシャットダウンするようになります.

[daemon]
HaltCommand=/usr/local/sbin/shutdown-gdm -h now
RebootCommand=/usr/local/sbin/shutdown-gdm -r now

梅原 大祐 / UMEHARA Daisuke umehara@kit.ac.jp
Last modified: 2020/05/01 15:37
Total Access Count