2011-01-20

XFCE4 をセッションにした VNC サーバが起動しない

端末で XFCE を使用していて, その中で VNC サーバを起動すると, 以下のエラーが出て VNC は起動するが XFCE のセッションが起動しないことがある.
xfce4-session: Another session manager is already running

これは, VNC サーバを起動するときに, 端末の XFCE セッションが設定した環境変数が, VNC 中の XFCE セッションに伝わってしまって, 既にセッションが起動済みであると判断してしまっているためだろう.

こんなときには一度ローカルマシンに SSH などでログインして, その中で VNC サーバを起動すればよい.

$ ssh localhost vncserver

2011-01-15

SELinux における共有ライブラリのコンテキスト

共有ライブラリ (*.so) は, プログラムの実行時に ld.so によって自動的にリンクされるオブジェクトです. しかし, SELinux を使用していると,
error while loading shared libraries: *.so:
cannot restore segment prot after reloc: Permission denied
といったエラーが出ることがあります.

例えば, Firefox などのようにバイナリをダウンロードし展開して使用すると, このようなエラーに遭遇することがあるでしょう.

このときには, chcon を使用して, 問題の共有ライブラリのセキュリティコンテキストの種類を textrel_shlib_t に変更しましょう.

chcon -t textrel_shlib_t *.so
もし, 共有ライブラリがたくさんあるのであれば, find を使用して,
find -name '*.so*' | xargs echo chcon -t textrel_shlib_t
とすると, サブディレクトリにある共有ライブラリのセキュリティコンテキストも変えることができます.

2011-01-06

安全な rm

Linux では, rm で削除したファイルを復元する機能が提供されていません. そこで, rm をゴミ箱に移動するコマンドに置き換える方法を紹介します. ここで紹介する機能は,
  • ゴミ箱ディレクトリを作る
  • 削除するファイルがゴミ箱ディレクトリと同じファイルシステム上にあればゴミ箱に移動する.
  • 削除するファイルのあるファイルシステム上にゴミ箱ディレクトリがなければ, プロンプトを出して削除する.
を備えています.

ファイルを削除する代わりに, 同じファイルシステムにあるゴミ箱ディレクトリに移動させます. その副作用として, 削除が高速になります. ファイルの移動は, ファイルの実体への参照を書き換えるだけで行える実装になっているファイルシステムがほとんどだからです.

function rms
{
 # safe rm
 local rm_opt='-v -i'
 local mv_opt=''
 OPTIND=0
 while getopts firv flag; do
  case $flag in
   f) mv_opt="$mv_opt -f";;
   i) mv_opt="$mv_opt -i";;
   r) rm_opt="$rm_opt -r";;
   v) mv_opt="$mv_opt -v";;
   *) OPT_ERROR=1; break;;
  esac
 done
 if [[ $OPT_ERROR ]]; then
  echo "usage: $0 -firv files..." >&2
  exit $OPT_ERROR
 fi
 shift $((OPTIND-1))

 local trashes=(
  ~/.trash
  /tmp/trash-$USER
  )
 mkdir "$trashes" &>/dev/null
 local i t
 local date=$(date +'%Y%m%d-%H%M%S')
 for i in "$@"; do
  local found=''
  for t in ${trashes[@]}; do
   if test "$(stat -c '%D' "$i")" = "$(stat -c '%D' "$t")"; then
    local tt=$t/$date/
    mkdir $tt &>/dev/null
    mv $mv_opt "$i" $tt && local found=1
   fi
   test -n "$found" && break
  done
  test -z "$found" && /bin/rm $rm_opt "$i"
 done
}
alias rm=rms

K-9 Mail で Courier-IMAP サーバのメールが表示されなくなる

Android の K-9 mail は, Courier IMAP とともに使用すると, いくつかのメッセージが K-9 mail 上に表示されないことがある. とくに, 新しいメールが受信されないようで, 使用していて困る.

どうも, K-9 Mail のスレッドによると Courier IMAP 側の問題といわれていて, 対策はまだ見付かっていない模様.

とりあえず, K-9 Mail で, Recreate data (Last Resort!) を行うと, サーバからメッセージを取得しなおすことができるので, 当分は問題がないようだが, 私の経験ではしばらくするとまた再発する.

Courier IMAP 側の問題といわれているので, 別の IMAP サーバ dovecot に代えてみたところ, 同様の問題は起こらなくなった.

参考

2011-01-05

Linux におけるファイルの排他制御

Linux でのファイルロックの実装はいくつかある. ここでは,
  • flock
  • lockf
  • fcntl
を紹介する.

ロック機構の指標

ファイルのロック機構を比較する上で, 指標になる項目は, たとえば,
  • 強制力: アドバイザリロック, 強制ロック
  • 範囲: ファイル全体, バイト単位, など
  • 種類: 排他, 共有
  • 所有者: プロセスがロックを所有, ファイルディスクリプタ毎にロックを所有
  • ファイルディスクリプタの複製時の振舞
このうち, 強制力については, Linux でのデフォルトはアドバイザリロックで, 強制ロックに変更するにはマウントオプションに mandを追加しなければならない. アドバイザリロックでは, ファイルが「ロック」されていても, 他のプロセスが読み書きなどのアクセスを行うことができる.

比較

機構種類範囲所有者
fcntl排他, 共有バイト単位で範囲指定プロセス
flock排他, 共有ファイル単位ファイルディスクリプタ
lockf排他のみバイト単位で範囲指定

flock では, ファイルディスクリプタがロックを所有し, 複製 (fork, dup などで作成されるもの) は同じロックを参照する. 複製したファイルディスクリプタのうちいずれかに対して明示的にアンロック操作をした場合か, ロックを参照する全てのファイルディスクリプタが閉じられたときにロックが開放される. ひとつのプロセスが同じファイルに対する複数のファイルディスクリプタを取得した場合には, それぞれに対して独立したロックが生成される.

Linux では, lockffcntl へのインターフェイスとして実装されている.

fcntl では, プロセスがロックを所有し, fork で作成された子プロセスには継承されないが, execve の前後ではロックが保存される. ひとつのプロセスが同じファイルに対して複数のファイルディスクリプタを取得している場合には, ロックは共通している. ロックが適用されているファイルを参照しているファイルディスクリプタのいずれかが閉じられたとき, ロックが開放される. すなわち, 例えば /etc/passwd のロックを所有しているときに, あるライブラリ関数がそのファイルを open, close すると, そのファイルへのロックが開放される.

参考

2011-01-04

Samba サーバを SELinux 環境で使用する

Fedora 14 で smb サービスを起動し, Windows から Linux 上のホームディレクトリを読み出そうとすると,
smbd/notify_inotify.c:421(inotify_watch) inotify_add_watch returned Permission denied
といったログが出力され, Windows からディレクトリ内のファイル一覧を取得できないことがある.

このとき, SELinux がファイルへのアクセスを妨げている可能性がある.

SELinux のマニュアルはいくつかあるが, samba_selinux(8) に samba を使用する際の操作方法などが例を交えてかかれている.

これにしたがって,

sudo setsebool -P samba_enable_home_dirs 1
と命令すると, Windows からホームディレクトリを読み出せるようになるだろう.

VIM で Emacs 的な字下げ

Emacs の標準的な字下げは 2 文字で, さらにブロック{ }の前後で 2 文字づつ字下げするようになっています. 以下の例のような字下げです.
int
func (int a)
{
  if (a==0)
    return 0;
  else
    {
      if (a>0)
        return 1;
      else
        return -1;
    }
}
VIM でこの字下げに対応するには,
sw=4 cino={.5s,n-2
と設定すると良いようです.

ちなみに, このインデントは, GCC のソースコードでも採用されているようです.

2011-01-03

マウスカーソルの移動でアクティブウィンドウの切替

Linux 上の X では, マウスカーソルが上にあるウィンドウをフォーカスし, 全面に移す機能がある. タスクリストから目的のウィンドウを選択したりタイトルバーをクリックしなくても, 別のウィンドウを選択できるので, 便利なことがある.

Windows でも同様の機能がないかと探して見たところ, よく似た機能が備わっていることが分かった. このページ Activate a window by hovering over it with the mouse にかかれていた.

これによると, マウスカーソルが上にくると (1秒くらい経ってから), ウィンドウがアクティブになる. すなわち, ウィンドウにフォーカスが移り, 全面に表示される.

X と違い Windows では, フォーカスが移ると同時に全面に表示される.

X では, マウス移動からウィンドウがフォーカス取得までの時間を短くし, フォーカス取得から全面に移動するまでの時間を長くしておくことで, マウスを文献からエディタへ移動してすぐプログラムをタイプし始めるといった使い方ができた. しかし, Windows で同じように操作すると. アクティブになる前に 最初の数文字をタイプして思い通りの動作をしなかった.

X と Windows とで動作がやや異なるが, それでもこの機能は便利であると思う.