2013-12-30

Struts2: ScopeInterceptor: Deadlock in session lock

もう数年前の話になる。Web アプリケーションの負荷テストをすると稀にエラーになることがあった。リクエストから 30 秒後にエラーになり、ログには「Deadlock in session lock」と出る。この文字列から ScopeInterceptor に辿り着き、コードを読んで不具合と判断、特に使っていなかった ScopeInterceptor を外すことで対処した。

当時は同様の事例が見つからなかったが、最近になって検索すると次が出てきた。

コードを読んだだけで動作は未確認だが、最新版でも直っていないようだ。

確か ScopeInterceptor は初期設定で組み込まれているはずで、負荷テストをやれば普通に当たりそうに思うのだが、何故これまで問題になっていないのか謎。

2013-11-24

Animes in the 3rd quarter of 2013

アニメは IT エンジニアの必須科目です。 ということで簡単なレビューを。

キャラデザや OP からして某作の二番煎じっぽいが、初話でいい意味で裏切られた。ロボット物と三枚目キャラの組み合わせは新鮮。しかし結局、その後の話が初話を超えることは無かった。キャラの魅力は十分で、特に女子キャラ 2 名は良い味を出しているので、初話の感じで通していたら大化けしたと思う。

女子向けということで期待はしておらず、そしてほぼ予想通り。イケメンキャラが程よく絡むという女子向けの定番で、男子が見てもつまらないない作品。少女マンガ原作は当たりが多いが、この系統の女子向けは基本スルーで良いような気がしてきた。

前期に引き続き視聴。浜地だけが目当てだったのに、数える程しか出て来なかった。しかもチョイ役で。まあ女子向けだから需要が無のは分かってはいたが、浜地が出ないなら私にとって見る価値が無かった。

ヒロインが十数人の義理兄弟から惚れられる、という男女逆なら昔見たパターン。ヒロインが兄弟を拒まない所に違和感を感じまくるが、よく考えたらこれが男女逆だったらそれが普通だし、異性から見るとこんなにもバカバカしく見えるということが良く分かった作品だった。

原作は大よそ既読。アニメで見返しても、女神篇からの話は違和感がある。特定のヒロインの魅力は増したが、それ以外が総潰れに。流石に新キャラを増やすのが面倒になって整理をしたのかと勘ぐってしまう。OP は好きなのだが、それ故に是非ネイティブに歌って欲しかった。ただ早見沙織の頑張りは認める。

一見して「まどマギ」にインスパイアされた作品なんだろうな、と。タロットとか対消滅とかネタ的には良いと思うが、そこから先が膨らませきれずに終わった印象。物理をネタにしている割に、実は消えてませんでしたとか、まとめ方も理不尽。作り方次第で化けた可能性を感じたので、勿体ない気がする

それなりに期待していたが、このシリーズの特徴「主人公にイイ格好させる程につまらなくなる」の典型になった。格好つけは本編に任せて、黒子たちにバカをやらせてるだけで良かったのに、どうしてこうなった。ブレンダなどは残念キャラの良い資質を持っていたのに。無論、フェブリたんが可愛いかったのは認める。

問答無用の話題作。結果、時系列で評価が↑↓↑と変化。巨人が自然法則を無視しているのが分かった時点で一旦評価が下がったが、それを受け入れれば話として非常に面白い。やはり「先が読めない」というのは重要な要素だと再認識。原作を読まなずにいて良かった。だがそれ故、じっくり一年かけてやって欲しかったとも思う。

京アニなので視聴。絵は京アニらしさが感じられ、標準以上の出来になっているとは思う。のだが、それ以上の感想が出て来ない。もっと何か、京アニにしか出来ない何かを見てみたかった。まあ私の期待が大き過ぎるのは認める所なので、もっと長い目で見守ろうとは思う。

本が主題な割に、深い話は特に出ずに薄っぺらく終わった印象。もっとビブリオマニア的なディープな話を期待していたのだが、本関連の肩書きを持つだけの単なる変態たちだった。ただ何故か秋月マキシを気に入ったので、良しとする。何かシャイニングな感じと声色の組み合わせが何処かのツボに入った模様。

最大の問題は、声優がひどい。まるで素人が当てているようにしか聞こえない。だがそれさえ乗り越えれば、結構面白い。ネタが絶妙というか、誰もが学生時に経験したであろうネタが多く、ツッコミのノリも含めて慣れると癖になる。ただ、殆んどの人はそこまで到達できなかったと思われるのが残念。

今期の伏兵。正直、完全にナメてた。最早これは「ガッチャマン」という名の完全新作と思った方が良い。 世界観に感心したのは久しぶり。ヒロインの性格さえ受け入れられれば、問題なく楽しめると思う。うつつたんも可愛かったし、OP・ED も良い。最近の内田真礼はなかなか良い仕事をする。

初見で全く期待していなかったが、良い意味で裏切ってくれた。まさか恋愛ではなくコメディ作品だったとは。ボケ役とツッコミ役が上手くハマっていて、各キャラの声も違和感が無い。非常に良く纏まっている作品だと思う。今期はコメディ作品の当たりが多くて私得なクールだった。

シリーズの勉強と思っての視聴だったが、これ見てもたぶん本編のことは勉強できないよね? しかしこれはこれで需要が有りそうな感じはするので次回も見るとは思うが、正直私には面白さが分からない。これは本編をやり込んだ人向けのファンディスク的な作品のような気がする。つまり私は予選落ちしてるっぽい。

絵的に好みでないため期待はしていなかった。各キャラが弱めなので、もう少しギャグ方向に振るか萌え要素が欲しい。ヒロインは最後まで薄いし、唯一キャラの強い実質ヒロインに萌えるのは無理だったし。寧ろ小動物の演技の方が記憶に残った。やっぱり中の人(斉藤千和)の力は侮れない。

前期からの視聴。相変わらず暖かい作品だが、やや無理やりいい話にしている感もなくはない。新キャラはキャラが弱すぎて従来四人に全く馴染めてないが、のりえが強化されていて全体としてはプラマイゼロ。ていうか最早、私はのりえを見るためにこの作品を見ていると言っても過言ではない。

2013-10-31

StandardError hides KeyboardInterrupt in Python 2.4

私は、Python で次のようなコードを書くことがある。

import datetime

def validate_date_string(s):
    try:
        assert len(s) == 8
        datetime.date(int(s[:4]), int(s[4:6]), int(s[6:]))
        return True
    except StandardError:
        return False

def test():
    assert validate_date_string('20120229') # leap year
    assert not validate_date_string('20130229') # not leap year

StandardError を捕捉するのは、Google 先生の教えによる。

  • Never use catch-all except: statements, or catch Exception or StandardError, unless you are re-raising the exception or in the outermost block in your thread (and printing an error message). Python is very tolerant in this regard and except: will really catch everything including misspelled names, sys.exit() calls, Ctrl+C interrupts, unittest failures and all kinds of other exceptions that you simply don't want to catch.

しかしここには、Python のバージョンによって例外のクラス階層が異なる、という重要な情報が抜けている。

実際、Python 2.4 以前は KeyboardInterruput が StarndardError のサブクラスになっているため、上記のコードは try ブロック中で Ctrl-C を受けると意図通りに動かない。具体的には、Ctrl-C で終了できず、無条件に False が返ってしまう。

Exception
 +-- SystemExit
 +-- StopIteration
 +-- StandardError
 |    +-- KeyboardInterrupt
<...snip...>
BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- Exception
      +-- GeneratorExit
      +-- StopIteration
      +-- StandardError
<...snip...>

Python 2.4 以前でも動くようにするには、StandardError を処理する に、KeyboardInterruput を明示的に処理する必要がある。

def validate_date_string(s):
    try:
        assert len(s) == 8
        datetime.date(int(s[:4]), int(s[4:6]), int(s[6:]))
        return True
    except KeyboardInterrupt:
        raise
    except StandardError:
        return False

Python は保守的な言語だと思っていたので、まさかこんな所に罠があるとは思わなかった。これでまた 1 つ、Python が嫌いになった。:-p

2013-09-30

xyzzy: zgrep.l

エディターに Emacs を常用するようになって久しいが、その前は xyzzy を使っていた。更にその前は WZ Editor で、社会人プログラマーになって最初のエディターが WZ だった。WZ から xyzzy へ移行した動機は省くが、移行で最後までネックになったのが Grep。

使った人にしか分からないが、WZ Grep には該当行の前後を確認できるプレビュー画面があって、大量の Grep 結果を見る際に非常に便利だった。偶に秀丸などを使う機会があると、プレビューなしでどうやって仕事ができるのか不思議に思ったくらいだ。

結局、xyzzy を使いながら WZ Grep からも離れらない状況が続き、いい加減 WZ と決別するために拡張 Lisp を自作したのだった。当時、既に WZ Grep を模倣する拡張 Lisp は存在したが、使ってみて「これじゃない」感が強くて常用には至らなかった。

以上は 10 年も前のことなので今更ではあるが、その拡張 Lisp をここに公開しておく。ファイルの最終更新日は 2004-09-07。もうコードの内容も覚えてないし、読む気も更新するつもりもないが、WZ Grep から離れられない人の気持ちは良く分かるので。

今でも、Windows で大量のファイルを Grep する必要に迫られた時には、これを使うことがある。Emacs でも作れば良いのだが、今の仕事だと無くてもそれ程には困らないので、作るまでのモチベーションがない・・・。

$XYZZY/site-lisp/zgrep.l:

;;; -*- Mode: Lisp -*-
;;;
;;; This file is NOT part of xyzzy.
;;;
;;
;; 概要
;; ======
;;
;; VZ Grep / WZ Grep のように、Grep バッファにプレビューウィンドウを付ける
;; メジャーモード。
;;
;; 設定
;; ======
;;
;; .xyzzy 又は siteinit.l に下記を記述。
;;
;;   (require "zgrep")
;;   (zgrep-default-setting)
;;
;; `zgrep-default-setting' には、次の設定が含まれている。
;;
;;   ;; SPC でプレビューウィンドウをトグル
;;   (define-key *zgrep-mode-map* #\SPC 'zgrep-toggle-preview)
;;
;;   ;; RET で該当ファイルを開く
;;   (define-key *zgrep-mode-map* #\RET 'zgrep-open)
;;
;;   ;; カーソル移動で次々にプレビューする
;;   (define-key *zgrep-mode-map* #\Up 'zgrep-previous-line)
;;   (define-key *zgrep-mode-map* #\Down 'zgrep-next-line)
;;
;; その他の設定例。
;;
;;   ;; Grep 後、自動で zgrep-mode にする
;;   (defun my-grep-hook ()
;;     (delete-other-windows)
;;     (zgrep-mode (car *minibuffer-search-string-history*)))
;;   (add-hook 'ed::*grepd-hook* 'my-grep-hook)
;;   (add-hook 'ed::*grep-hook* 'my-grep-hook)
;;
;;   ;; Grep ウィンドウ(上段)のサイズ
;;   (setq *zgrep-window-size* 10)
;;
;;   ;; リードオンリーでファイルを開く
;;   (setq *zgrep-open-read-only* t)
;;
;;   ;; Grep 文字色
;;   (setq *zgrep-foreground-color* 1)
;;   (setq *zgrep-background-color* 14)
;;   (setq *zgrep-bold* t)
;;
;;   ;; 拡張子 .grep のファイルを zgrep-mode で開く
;;   (push '("\\.grep$" . zgrep-mode) *auto-mode-alist*)
;;
;; その他
;; ======
;;
;; * ファイル全体を読み込むため、巨大なファイルのプレビューには難有り。
;; * プレビューウィンドウ中での該当行の反転は、色設定によっては見難い。
;; * Grep を C-g で中断したとき zgrep-mode にする上手い方法。
;;

(provide "zgrep")

(defvar *zgrep-mode-hook* nil)

(defvar *zgrep-mode-map* nil)
(unless *zgrep-mode-map*
  (setq *zgrep-mode-map* (make-sparse-keymap)))

(defvar *zgrep-window-size* *error-window-size*)
(defvar *zgrep-open-read-only* nil)

(defvar-local *zgrep-grep-string* nil)
(defvar *zgrep-foreground-color* 1)
(defvar *zgrep-background-color* nil)
(defvar *zgrep-bold* nil)

(defvar-local *zgrep-mode* nil)
(defconstant zgrep-mode-name "zgrep:~A")
(defconstant zgrep-preview-buffer "*grep preview*")
(defvar *zgrep-preview-filename* nil)

(defun zgrep-set-string-color (str &optional from to)
  (if (and str
	   (/= (length str) 0)
	   (or *zgrep-foreground-color*
	       *zgrep-background-color*
	       *zgrep-bold*))
      (save-excursion
	(save-restriction
	  (narrow-to-region (or from (point-min)) (or to (point-max)))
	  (goto-char (point-min))
	  (while (scan-buffer (concat "\\(" str "\\)")
			      :regexp t :no-dup t :case-fold t)
	    (set-text-attribute (match-beginning 1) (match-end 1)
				'zgrep-string
				:foreground *zgrep-foreground-color*
				:background *zgrep-background-color*
				:bold *zgrep-bold*))))))

(defun zgrep-delete-preview-buffer ()
  (let ((buf (find-buffer zgrep-preview-buffer)))
    (if buf (delete-buffer buf)))
  (setq *zgrep-preview-filename* nil))

(defun zgrep-make-preview-buffer (filename)
  (let ((old-buf (selected-buffer))
	(preview-buf (find-buffer zgrep-preview-buffer))
	(grep *zgrep-grep-string*))
    (unless (and preview-buf
		 (string= filename *zgrep-preview-filename*))
      (zgrep-delete-preview-buffer)
      (setq preview-buf (get-buffer-create zgrep-preview-buffer))
      (set-buffer preview-buf)
      (insert-file-contents filename)
      (dolist (x *auto-mode-alist*)
	(when (string-matchp (car x) filename)
	  (funcall (cdr x))))
      (zgrep-set-string-color grep)
      (set-buffer-modified-p nil)
      (setq buffer-read-only t))
    (set-buffer old-buf)
    (setq *zgrep-preview-filename* filename)
    preview-buf))

;; returns (file line body)
(defun zgrep-parse-line ()
  (save-excursion
    (let ((str (buffer-substring (progn (goto-eol) (point))
				 (progn (goto-bol) (point)))))
      (if (string-match "^\\([^:]+\\):\\([0-9]+\\):\\(.*\\)$" str)
	  (list (substring str (match-beginning 1) (match-end 1))
		(parse-integer (substring str
					  (match-beginning 2)
					  (match-end 2)))
		(substring str (match-beginning 3) (match-end 3)))))))

;; Emacs like `get-buffer-window'
(defun zgrep-get-buffer-window (buffer-or-name)
  (ignore-errors
    (get-buffer-window buffer-or-name (selected-window))))

(defun zgrep-preview-p ()
  (zgrep-get-buffer-window zgrep-preview-buffer))

(defun zgrep-preview ()
  (interactive)
  (let ((parsed (zgrep-parse-line)))
    (when (and parsed
	       (file-exist-p (nth 0 parsed)))
      (let ((preview-buf (zgrep-make-preview-buffer (nth 0 parsed))))
	(delete-other-windows)
	(split-window *zgrep-window-size*)
	(other-window)
	(set-buffer preview-buf)
	(goto-line (nth 1 parsed))
	(reverse-region (progn (goto-eol) (point))
			(progn (goto-bol) (point)))
	(refresh-screen)
	(recenter)
	(other-window)
	(recenter)))))

(defun zgrep-toggle-preview ()
  (interactive)
  (if (zgrep-preview-p)
      (progn
	(delete-other-windows)
	;;(zgrep-delete-preview-buffer)
	)
    (zgrep-preview)))

(defun zgrep-find-file (filename)
  (let ((old-buffer (get-file-buffer filename)))
    (if old-buffer
	(progn
	  (ed::find-file-verify old-buffer filename nil nil nil nil)
	  (set-buffer old-buffer))
      (if *zgrep-open-read-only*
	  (find-file-read-only filename)
	(find-file filename)))))

(defun zgrep-open ()
  (interactive)
  (let ((parsed (zgrep-parse-line)))
    (when (and parsed
	       (file-exist-p (nth 0 parsed)))
      ;;(zgrep-delete-preview-buffer)
      (zgrep-find-file (nth 0 parsed))
      (delete-other-windows)
      (goto-line (nth 1 parsed))
      (refresh-screen)
      (recenter))))

(defun zgrep-set-grep-string (grep)
  (interactive "sGrep string (Regexp): ")
  (setq *zgrep-grep-string* grep)
  (zgrep-set-string-color grep))

(defun zgrep-next-line-internal (n)
  (ed::next-line-1 n #'forward-virtual-line #'goto-virtual-column))

(defun zgrep-next-line (&optional (n 1))
  (interactive)
  (let ((old-line (current-line-number)))
    (zgrep-next-line-internal n)
    (when (and (/= old-line (current-line-number))
	       (zgrep-preview-p))
      (zgrep-preview))))

(defun zgrep-previous-line (&optional (n 1))
  (interactive)
  (zgrep-next-line (- n)))

(defun zgrep-mode-toggle ()
  (interactive)
  (if *zgrep-mode*
      (progn
	(setq mode-name (format nil zgrep-mode-name "off"))
	(use-keymap (make-sparse-keymap))
	(local-set-key '(#\C-c #\C-c) 'zgrep-mode-toggle))
    (progn
      (setq mode-name (format nil zgrep-mode-name "on"))
      (use-keymap *zgrep-mode-map*)))
  (setq *zgrep-mode* (null *zgrep-mode*)))

(defun zgrep-mode (&optional grep)
  (interactive)
  (kill-all-local-variables)
  (setq buffer-mode 'zgrep-mode)
  (zgrep-mode-toggle)
  (setq *zgrep-grep-string* grep)
  (run-hooks '*zgrep-mode-hook*))

(defun zgrep-default-setting ()
  (define-key *zgrep-mode-map* #\SPC 'zgrep-toggle-preview)
  (define-key *zgrep-mode-map* #\RET 'zgrep-open)
  (define-key *zgrep-mode-map* #\Up 'zgrep-previous-line)
  (define-key *zgrep-mode-map* #\Down 'zgrep-next-line)
  (define-key *zgrep-mode-map* #\S 'zgrep-set-grep-string)
  (define-key *zgrep-mode-map* #\R 'rename-buffer)
  (define-key *zgrep-mode-map* '(#\C-c #\C-c) 'zgrep-mode-toggle))

2013-08-01

Animes in the 2nd quarter of 2013

アニメは IT エンジニアの必須科目です。 ということで簡単なレビューを。

前回に続き、今回も素晴らしい出来。新キャラ達は個性的なだけでなく、どれも魅力的。今回は「潘めぐみ」を覚えた。途中、ピンチを演出する意図的な展開はあるものの、作品の評価を下げるほどではない。話は今回で一区切りついているので、次回の展開が楽しみでもあり不安でもある。まあ期待し過ぎず、次回を待とうと思う。

名前も中の人も同じキャラが居るせいで、「ゆるゆり」の二番煎じに見えた。ただ、本作の方がマニアックな感じ。あの年代の、箸が転んでも可笑しいというか、周りには何が楽しいのかサッパリというか、そういう空気がある。これを楽しむには、自分の精神年齢を下げるスキルが必要かも知れない。まあ私には問題なかった。

今期のロボット物で本命になるはずだったのだろうが、他のロボット作品に埋もれてしまった。絵は綺麗でキャラデザも目力があって好きだが、話は強引でちぐはぐ。黒い方のヒロインが本性を出す辺りから面白くなり始めるが、それまでを挽回する程では無かった。第二期も期待はしていないが、黒い方目当てで見ると思う。

前作は確かに話題作ではあったが、個人的な評価はイマイチだった。なので今期も特に期待はしていなかったが、結果、寧ろ劣化した印象。だがしかし、クー子が攻略対象になったことだけは評価に値する。というか、製作側はいい加減にクー子以外に萌え要素が無いことに気付くべき。特に黄色、お前は要らない(断言)。

このシリーズは原作派だが、今回はアニメも面白かった。理由を考えるに、ヒロインの出番が少なかったせいかも知れない。実のところ、ヒロインは話のテンポを損なう重荷なのでは。あと最後のキス話は覚えてないと思ったら、やはりオリジナルだった。この作品に限らないが、オリジナル話がつまらないのは何故だろう。

イケメンキャラが一杯出てきて、声優も有名どころが揃っている。スペックは豪華だが、話的には至って普通で特に見るべきものは無かった。女子向けの作品らしいので、男子が見ればこんなものだろうか。ただ、悔しいがツクモたんの可愛さは認めざるを得ない。次回があるなら、彼女を目当てに絶対に見ると思う。

前作は好きだったが、続編が来るとは予想してなかった。ただ、妹が何を考えてるか分からない感じが良かったのに、両思いが判明してラブラブ、いつの間にかあやせルートどころかハーレムルートまで立っていたとか、こんなに視聴者に媚びた作品だっけ?と。まあ面白かったので問題ないが、距離感は前作の方が好きだった。

いきなり忍者とか陰陽師とか出てきて、さぞ安っぽい作品だろうと思ったら、意外にしっかりとした作りだった。もし中二時分に見ていたらヤバかったかも知れない、と思うくらいに、それっぽい空気を持っている。ただ、万人受けは難しいとは思う。個人的な話だが、間が悪くて数話ほど見逃してしまったのが残念。

原作は流し読みする程度。前期が未見なのでどんな感じか興味があったが、なかなか楽しめた。元がかなり下品な作品ではあるが、深夜アニメを良いことに殆どそのまま移植している気がする。その変態キャラを有名声優が演じるのが興味深い。ただ、何故 15 分作品なのかは謎。普通に 30 分で良かったように思う。

少年マガジンに連載してることすら知らなかった程、絵が全く好みでない。純粋にアザゼルさんの「ついで」に視聴。全く期待してなかったせいか、意外に楽しめた。何というか、ヒロインの勢いに押されてしまう。慣れてくるとウザさが勝ってくるが、ハーピーが可愛いので許す。このハーピー、原作より可愛いくね?

西尾維新という作家を見極めるため、興味深く視聴。結果、やはり只者では無いと結論。この人のキャラは「喋る」ではなく「語る」が相応しい。余程キャラを作り込んでいるのか、天然の才能か、各キャラの台詞回しに引き込まれてしまう。最初こそ絵が不安だったが、全くの杞憂だった。彼の作品に絵は重要では無いと悟った。

「世界を殺す少女を止めるため、デートして、デレさせろ!?」とか、日本人のこういうバカな所は世界に誇って良いと思う。と期待して見たのだが、中身は平凡だった。よくある既存パーツを組み合わせた感じ。既存でなかったのはキャッチコピーだけだった。とは言え、ヤンとツン担当の両キャラは結構好きだったりする。

それなりに楽しくは見られたのだが、何かもう一押し足りない。キャラがウリの作品なのは分かるが、そこからギャグとシナリオの両方に振ろうとして、どちらも中途半端に終わった感じ。キャラの魅力は十分だと思うので、素直にギャグ方面に振り切った方が良かったのでは。あと悔しいが、OP/ED は結構好き。

今期ロボット物の中では最も斬新。初話を見て、これはとんでもない作品かも知れない、と期待値は高かったものの、結局は既存の範疇に収束した感じ。こっち(地球)側ではなく、あっち側での話の展開を見てみたかった。とはいえ、本作はネタとして見ておくことを推奨。今後のロボット物の可能性を広げた作品だと思う。

女子に大人気、ということで視聴。初話の OP (通常話の ED)を見て、全てを理解した。普段アニメを見ている人なら、三次元の女子が二次元に勝てないのは常識だが、その逆も然り。女子の理想そのものがそこに描かれているので、ジャニーズなんて敵にならない。話は男子が見てもつまらないが、色々と勉強にはなった。

初見の感じで全く期待してなかったが、かなり楽しめた。主人公の自虐っぷりが半端なくて、同じボッチ属性の私のツボに嵌った。ヒロインとの掛け合いも良い。ただボッチ設定の割には、主人公にリア充要素が多過ぎた感はある。次回に続きそうで楽しみだが、原作の方がストック切れという噂。あと、OP は良かった。

2013-07-02

RHEL5.7: rsync doesn't work

久しぶりにハマった件について。

[rhel57]# rsync -az --delete --inplace --timeout=10 \
                -e 'ssh -i /path/to/key' \
                remote-host:/path/to/sync/ /path/to/sync
usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]
           [-D [bind_address:]port] [-e escape_char] [-F configfile]
           [-i identity_file] [-L [bind_address:]port:host:hostport]
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
           [-R [bind_address:]port:host:hostport] [-S ctl_path]
           [-w tunnel:tunnel] [user@]hostname [command]
rsync: writefd_unbuffered failed to write 4 bytes to socket [receiver]: Broken pipe (32)
rsync error: unexplained error (code 255) at io.c(1525) [receiver=3.0.6]

いつも通り rsync を動かしたら、何か ssh のヘルプ出てきた。何これ、訳分かんない。

これにハマった理由は、

  • 見た目が如何にも ssh の引数不備に見えた。
  • 実際に動かなくなったスクリプトも ssh を使っていた。
  • とはいえ、この間は確かに RHEL5.9 で動いていたのを確認済み。

これらに惑わされて原因の特定に手間取ってしまった。結局、「RHEL5.7 同梱の rsync でのみ発生する不具合」というオチだった。

原因は分かったので、後は自作インストーラー側での対処。勿論、rsync をアップデートして貰えば解決する問題だが、「RHEL5.7 だったら rsync をアップデートしてね」とお願いするくらいなら、最初からインストーラー側で対処すべき。やることが「明確」ならば、自動化するのがセオリーだ。(逆に「臨機応変」が求められるものは、人間がやるべき)

バグ持ち rsync のバージョンは分かっているので、RHEL バージョンよりも rsync バージョンで判断する方がベター、ということでこんな感じ。

if [ 3.0.6-4.el5 = "`rpm -q --qf '%{VERSION}-%{RELEASE}' rsync`" ] ; then
    rpm -Uvh rsync-3.0.6-4.el5_7.1.x86_64.rpm
fi

修正はこれで良いとして、いい加減、OS のマイナーアップデートでパッケージのメジャーバージョンを上げるのは止めて欲しい。

[rhel56]# rpm -q rsync
rsync-2.6.8-3.1
[rhel57]# rpm -q rsync
rsync-3.0.6-4.el5

RHEL に求めるのは安定性であって、最新パッケージを使いたかったら自分でビルドするか rpm を拾ってくるし。特に今回、基本的なツールである rsync が動かなくなったことで、泣かされた人も(当時は)多かったのではなかろうか。今回の不具合の拙さを考えると、「安易にパッケージのメジャーバージョンを上げるからだ」と言われても仕方ない。

2013-06-04

HP SPP makes system slow

暫く前に HP サーバーをセットアップした時のこと。

  • Proliant DL380e
  • RHEL5.9
  • HP Service Pack for ProLiant (2013.02.0)

SPP (Service Pack for ProLiant)をインストールした途端、サーバーに断続的な負荷が掛かるようになった。

# top
top - 18:43:29 up  2:31,  3 users,  load average: 0.36, 0.37, 0.30
Tasks: 183 total,   2 running, 181 sleeping,   0 stopped,   0 zombie
Cpu0  : 41.9%us,  1.0%sy,  0.0%ni, 57.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu1  : 23.0%us,  1.0%sy,  0.0%ni, 76.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu2  :  7.6%us,  0.3%sy,  0.0%ni, 92.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu3  : 25.2%us,  0.7%sy,  0.0%ni, 74.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   7992008k total,   576248k used,  7415760k free,    33204k buffers
Swap: 10482404k total,        0k used, 10482404k free,   262040k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 9695 root      23   0  6600 1252  396 R  2.3  0.0   0:00.07 lsusb
30295 root      15   0 12764 1184  840 R  0.3  0.0   0:03.24 top
    1 root      18   0 10372  684  580 S  0.0  0.0   0:01.04 init
<...snip...>
# pstree -ap
<...snip...>
  |-cmastdeqd,4029 -p 30 -l /var/log/hp-snmp-agents/cma.log
  |   `-sh,9806 -c /opt/hp/hp-snmp-agents/utils/usb-device.sh\0402>/dev/null
  |       `-sh,9807 -c /opt/hp/hp-snmp-agents/utils/usb-device.sh\0402>/dev/null
  |           `-sh,9862 -c /opt/hp/hp-snmp-agents/utils/usb-device.sh\0402>/dev/null
  |               |-grep,9864 bInterfaceSubClass
  |               |-lsusb,9863 -v -s 002 002
  |               `-sed,9865 -e s/^\040*bInterfaceSubClass\040\+[0-9]\+\040//
# sar | tail -n 5
18:10:01          all      6.04      0.00      0.40      0.00      0.00     93.56
18:20:01          all      8.40      0.01      0.47      0.00      0.00     91.12
18:30:01          all      8.65      0.00      0.47      0.00      0.00     90.88
18:40:01          all      8.81      0.00      0.48      0.00      0.00     90.71
Average:          all      3.90      0.00      0.34      0.00      0.00     95.76

cmastdeqd が数十秒毎に lsusb を大量に実行するのが原因。lsusb 単発は微々たるものだが、全体では相当な負荷になっていて、USB キーボードを使っていたりすると酷い目に遭う。文字が入らなかったり、一度に何文字も入ったり。特にシャドウパスワードが最悪(何が入ったか見えないの)で、まともにログインすらできない。

USB HDD の取り外しを検出するのが目的らしいが、USB HDD なんて付けるつもりはないし、例え付けたとしてもこんなものは速攻で無効にすべき。

ところが、cmastdeqd の自動起動を off にすると、あろうことかサーバーが起動しなくなった。どうやら cmastdeqd を見ている別のサービスがあって、cmastdeqd が起動するまで 永遠に 待ち続けるらしい。全く、何というクソ実装。

仕方がないので、usb-device.sh (lsusb の呼び出し元)の方を無効にすることにした。

# pwd
/opt/hp/hp-snmp-agents/utils
# cp -p usb-device.sh usb-device.sh.orig
# echo : >usb-device.sh

結果、

# sar | tail -n 10
18:10:01          all      6.04      0.00      0.40      0.00      0.00     93.56
18:20:01          all      8.40      0.01      0.47      0.00      0.00     91.12
18:30:01          all      8.65      0.00      0.47      0.00      0.00     90.88
18:40:01          all      8.81      0.00      0.48      0.00      0.00     90.71
18:50:01          all      8.80      0.00      0.47      0.00      0.00     90.73
19:00:01          all      2.16      0.00      0.29      0.00      0.00     97.55
19:10:01          all      0.17      0.00      0.24      0.00      0.00     99.59
19:20:01          all      0.17      0.01      0.23      0.00      0.00     99.59
19:30:01          all      0.17      0.00      0.24      0.00      0.00     99.59
Average:          all      3.48      0.00      0.32      0.00      0.00     96.19

今回の件で、SPP はロクな品質でないことを確信した。私はこれにハマる前に別の地雷を踏んでいるから、そう断言できる。以下はその体験談。

  • サーバーのファームウェアをオンラインアップデートできるらしいので、やってみる。
  • アップデートのチェックに「数分かかるかも」と出る。
  • 実際は、百個程度の項目を 1 個ずつサイトへ接続してチェックするので、最短でも十数分は掛かる。
  • サイトが重いのか、チェックに時間が掛かったり、止まったりする。
  • タイムアウト・リトライ処理がないらしく、一度止まると永遠に止まる → リセット。
  • マグレでチェック処理が終わったので、先に進む。
  • 途中、前の画面はどうだったっけ?と「戻る」ボタンを押してみる。
  • 「前の画面」ではなく、全てが無かったことにされて一番最初のメニューまで戻される。
  • 気を取り直して、メニューから再びアップデート。
  • データにゴミが残っているらしく、エラーで先に進めず → リセット。
  • 再びマグレでチェックが終わり、今度は絶対に「戻る」なんて押すもんか、と心に誓って先へ進む。
  • 最後、アップデートの実行ボタンを押す。wktk
  • メッセージも何もない空白のダイアログが出て止まる → 呆然 → リセット。
  • 再びマグレで最後まで進み実行ボタンを押す → 当たり前のように空白ダイアログが出て止まる → give up。
  • その後、SPP DVD をダウンロードすればオフラインでアップデートできることを知る。
  • 実際、それでサクッと完了。オレの 1 日を返せ。

今まで触ったソフトウェアで、これほど殺意を覚えたのは初めてかも知れない。どうせ他の部分も似たような品質に違いない。永遠に止まるところなど、作った人が同じか、同じレベルであることを物語っている。

この様なものを見せられては、正直もう HP サーバーは使いたくない。本当は SPP もインストールしたくなかったが、デバイスドライバー系があるので、入れない訳にもいかないのが歯痒いところ。

2013-05-07

Can't install IE9 offline on Windows 7

下記の環境で、

IE9 のインストールに失敗する。スタンドアロン版インストーラーのくせに、こともあろうかインストール時に Windows Update に繋ごうとして失敗している。オプション /update-no や /passive も試してみたが効果なし。こういう時に /update-no が使えなくて、いつ使えというのだろう。

IE9 がインストールできない現象は様々にあるようだが、今回の場合、

で記載されている下記の更新プログラムをインストールすることで解決した。

こういう面倒を見てくれる所まで含めて、スタンドアロン版インストーラーと言うのではなくて?

2013-04-30

Animes in the 1st quarter of 2013

アニメは IT エンジニアの必須科目です。 ということで簡単なレビューを。

まず先に、原作を未読なのを謝罪しておく。話の内容より、テンポが速過ぎてまるでアメリカのアニメを見ているようだった。これがジョジョらしいのか私には判断不能だが、新鮮な感覚ではあった。中だるみがないので見るのは苦でなかったが、声優のチョイスはあれで良かったのか疑問が残る。

女子向けとかいう以前に、まずヒロインに問題あり。自己主張が乏しく、始終相手に流されっ放しでフラストレーションが溜まる。更に相棒がそれに輪を掛けて役立たずで、見ていて爆発しそうになる。途中から開き直って、何処までつまらないか見届けるつもりになったら、楽になった。OP が良かったのがせめてもの救い。

この辺から原作をチラ見していた。なので気付いたが、アニメ版は結構と端折られているらしい。話は、前作までを見ているなら安定して見れる。ただ「熱さ」は若干薄れたように思う。正直、原作を読んだ方が面白いような気もする。あと、アニメで見返してみても、扉絵のネタは凝りすぎて全然ウマくない思うのは私だけだろうか。

本編(絶チル)とは逆のシリアス路線は、完全に失敗だったと思う。ギャグの無い本シリーズなんて、つまらないにも程がある。何よりも致命的なのは、本作の女子キャラが可愛くないこと。原作のパティが何故あんな風になるのか、責任者を小一時間ほど問い詰めたい。このシリーズは原作を読むのが一番という結論。

見始めたときは、まさか一年続くとは思わなかった。知ってたら見なかったと思う。前宣伝通り声優陣は豪華で、ギャグがイマイチな分を声優の力量で補ってもらった感が大きい。今回の演技では、神谷浩史、森川智之を見直した。当初は笹子さん目当てで見ていたのだが、作画のブレが大きく、何か途中からどうでも良くなった。

企画自体は数年前から進行中らしく、キャラ付けはできている模様。聞いたことの無い声優を使うのは構わないが、歌がヘタなのが問題。逆に歌が上手い声優は演技がダメという。話も、1 クールしかないんだからメンバー集めに四苦八苦する描写とか要らなかった。決して嫌いでは無いのだが、イマイチ感の残る作品だった。

京アニということで視聴。キャラがけい○ん!を彷彿とさせるのは置いておいて、見る分には退屈することは無かった。しかし、この作品を京アニが作った意図が分からない。今までの作品は何らかチャレンジ精神的なものを感じたのだが、今回はそれを感じ取れなかった。まあ、某鳥が Gu-Gu ガ○モっぽい件は挑戦と言えなくも無い。

魔王と勇者、在り来たりな題材をどう料理するのかと思ったら、魔法は使わず経済で世界に挑むという予想外の展開。普通なら勇者一行の人外の強さがバランスを崩すところだが、バトルは本質では無いので何とか保っている。ただ話が少し難解。もっとバカ向けに「おっぱい」を前面に持ってきて良かった、というか寧ろそれを希望。

オーソドックスなファンタジーかと思いきや、銀魂臭の漂うギャグ作品。OP のルビ振りは一度は見ておくべき。しかし、見るべきものはそれだけ。肝心のギャグは面白くないのに加え、作ってる連中は面白いと思っている感が伝わってきて、特に後半になる程に鬱陶しい。真面目路線で作ってハズすのよりは幾分マシか、という所。

絵は綺麗。OP を見れば、製作陣のこの作品に対する思いが伺える。しかし中身がそれに付いていっていない。四人目の登場で猛烈な挽回を見せるが、というか、もうこの娘がメインヒロインで良くね? という程にヒロインのキャラが弱い。いっそのこと、主人公を除くヒロイン全員が中二病、という設定の方が面白かったのでは。

前期からの視聴。そのまま楽しく歌っていれば良かったものを、苦悩や葛藤を織り込んだせいで、在り来たりな話になった。また、メインキャラとサブキャラがはっきり分かれてしまい、前期でいい味を出しつつあったサブキャラがこぞって潰れてしまった。色んな意味で前期からデグレードしたと思う。

鍵っ子が生まれる理由に興味があり視聴。筋肉バカは論外として、最初はベタなキャラばかりの印象を受けるが、2 クールかけて各キャラを掘り下げていくため、感情移入もあって気にならなくなる。しかし結局キャラ紹介に終始した感があり、どう終わらせるのかと思ったら、まさか続くとは思わなかった。OP・ED は良い。

一般に相棒が頼りになる奴の場合、その相方は引っ込み思案で内気キャラというのが相場だが、本作では中々に強かで度胸のあるキャラで好感が持てる。しかしそれも前半の話。後半はとても同じ作者が作ったとは思えないくらい、見ていられない話になる。これ本当に同一人物が作った? 前半で期待しただけ、残念な結果だった。

影のあるイケメンが沢山出てきて適度に絡む、という女子向け作品に良くあるパターン。男子にとって一番つまらないパターンとも言う。唯一、浜路の存在が救い。彼女にだけは萌えられる。ただ女子的に需要が無いのだろう、出番が少ないのが悲しい。次回はもっと浜路を頼む。最早それだけがこの作品を見るモチベーション。

原作は序盤でリタイア。アニメで魅力を発見できるかと思ったが、やはり叶わなかった。まず主人公に魅力が無い。アリババは正義感をかざすくせにウジウジで見ててイライラする。モルさんはもっと萌えるキャラにできたはず。やはりこの作者は王道ファンタジーではなく、すもも(前半)のようなノリが合っていると思う。

思ったよりも早い再開だったな、と思ったら、やっぱり早すぎた模様。それも「原作」ではなく「製作」の方が、というのが問題。映画と平行のせいか、製作が追いつかないなら素直に止めた方が良かったのでは。これでは映画の宣伝がやりたかっただけ、と思われても仕方がない。次回は万全の状態でお願いしたい。

最初、凝ってはいるが地味な作品だと思ったが、最後まで見て評価が変わった。世界観は一貫してブレが無く、ギャグも息抜きも無いシリアス一辺倒でありながら、見るのが苦にならず最後まで見ることができた。OP/ED も含め、隅々まで製作者の拘りを感じる。目を惹く華やかさは無いが、大人が楽しめる良作。

見る前からフラウ坊のイメージしかない作品だが、この作品の不幸は前作(シュタインズ)が偉大過ぎたこと。普通ならば十分に良作だと思うが、相対的に評価が下がってしまうのは仕方が無いところ。しかし OP/ED の作詞・作曲までをも手掛ける志倉千代丸のマルチタレント性は、悔しいが認めざるを得ない。

見た感じで期待はしていなかったが、大方は予想通りだった。各キャラの個性が微妙な上に、全体的に取って付けたような話で終始している。所詮はパチンコが出自の作品か。ただ例外として、第十一話だけは面白かった。ああいうノリで全編を通していたら、もっと評価は違ったと思う。

心が読めてしまう超能力者、まともに描けば重くなるのは必至。いきなり初話で重い話を突きつけられるが、二話目で救われる。以降も周りキャラの明るさに助けられるので、安心して見ていられる。やはりアニメはこうでないと。○○ロ○ネクトも少しは見習って欲しい。ただ、森谷さんは途中でキャラが変わり過ぎだと思う。

パステル調の絵に惹かれて視聴。何というか、青緑色が目に心地よい。この作品は部長が可愛いと思えるかが全てだと思う。私は三話目くらいから可愛く見えてきたので問題なし。今回は内田真礼の頑張りを評価。あと途中参加のタマの必要性が疑問だったが、意外に SD キャラが一番可愛いのがタマで、これも問題なかった。

弱小コミュニティの成り上がり物語かと思ったら、最後の方は何か違った。主人公が万能過ぎるのと最後の謎解きが独りよがりなのがマイナスポイント。前半の話は嫌いではなかったが、最終的にはラノベをアニメにしました、という以上にはならなかったように思う。

2013-03-31

RHEL6: ifconfig is obsolete!

前回エントリで、expand_config を見て気付いたことがある。

RHEL6 では、インターフェイスに複数の IP アドレスを設定できるらしい。そういえば OS インストール時のネットワーク設定画面では、複数 IP アドレスが登録できそうな UI になっていた。今まで試したことはなかったが、実際にそこで複数 IP アドレスを設定してみると、ifcfg-* は次のようになる。

RHEL6.4: /etc/sysconfig/network-scripts/ifcfg-eth0:

DEVICE=eth0
TYPE=Ethernet
UUID=7f36ffb3-0b2a-48d5-9e81-18b685396f06
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=none
HWADDR=00:0C:29:94:42:BD
IPADDR=192.168.0.1
PREFIX=24
IPADDR2=192.168.0.2
PREFIX2=24
IPADDR3=192.168.0.3
PREFIX3=24
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME="System eth0"

これは完全に意図通りに動く。もう仮想インターフェイスなんて(eth0:1 とか)必要ない。ていうか、できるんだったらもっと早く(略)。尤も、IP アドレス毎に ifup / ifdown する必要があるなら、仮想インターフェイスは相変わらず有用ではある。

しかしインターフェイスに複数の IP アドレスを設定できるなら、今現在インターフェイスで有効な IP アドレスを知る手段も必要になる。これらは 2 つで 1 つ、どちらか一方だけでは意味がない。しかし残念ながら、ifconfig はその役には立たないらしい。

[rhel64]# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:0C:29:94:42:BD
          inet addr:192.168.0.1  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe94:42bd/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:42649 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18439 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:26605808 (25.3 MiB)  TX bytes:2001382 (1.9 MiB)

困った時の、man 頼み。

[rhel64]# man ifconfig
NAME
       ifconfig - configure a network interface

SYNOPSIS
       ifconfig [interface]
       ifconfig interface [aftype] options | address ...

NOTE
       This  program  is obsolete!  For replacement check ip addr and ip link.
       For statistics use ip -s link.

obsolete! と言ってくれたところで、一体どれだけの人が気付くというのか。今回のことがなければ、私も man を読もうとは思わなかったし。それはともかく、これからは ip addr を使え、と。

[rhel64]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:94:42:bd brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0
    inet 192.168.0.2/24 brd 192.168.0.255 scope global secondary eth0
    inet 192.168.0.3/24 brd 192.168.0.255 scope global secondary eth0
    inet6 fe80::20c:29ff:fe94:42bd/64 scope link
       valid_lft forever preferred_lft forever

この ip addr は RHEL5 でも動く。(RHEL4 以前は知らない)

以上より、

もう ifconfig は時代遅れらしいよ。

ちなみに前回の話に出た Webmin (1.620)だが、やはりこの複数 IP アドレスには対応していない。2 番目以降の設定は Webmin 画面からは見えないし、変更することもできない。よって Webmin でネットワーク設定を行うつもりなら、この複数 IP アドレス機能も使わない方が良い。

2013-03-27

RHEL6: PREFIX overrides NETMASK in `ifcfg-*'

RHEL6 インストール画面で固定 IP アドレスを設定すると、ifcfg-* には NETMASK の代わりに PREFIX という項目が記入される。名前から NETMASK の代替であることは分かるし、実際にそう動く。しかし、もし PREFIX と NETMASK の両方が設定され、その内容が矛盾していたらどうなるのか。

似た関係に NETMASK / NETWORK / BROADCAST があるが、これは公式ドキュメントに記載がある。

BROADCAST=address
where address is the broadcast address. This directive is deprecated, as the value is calculated automatically with ipcalc.
NETMASK=mask
where mask is the netmask value.
NETWORK=address
where address is the network address. This directive is deprecated, as the value is calculated automatically with ipcalc.

曰く、「NETWORK と BROADCAST は非推奨です」と。しかし、PREFIX については何処にも記述が見当たらない。試しに grep -i prefix /etc/sysconfig/network-scripts/* してみると、この辺りの処理を行っている場所は 1 か所しかない。

RHEL6.4: /etc/sysconfig/network-scripts/network-functions:

expand_config ()
{
    local i=0 val
    for idx in '' {0..255} ; do
        ipaddr[$i]=$(eval echo '$'IPADDR$idx)
        if [ -z "${ipaddr[$i]}" ]; then
           [ "$idx" ] && [ $idx -gt 2 ] && break
           continue
        fi
        prefix[$i]=$(eval echo '$'PREFIX$idx)
        netmask[$i]=$(eval echo '$'NETMASK$idx)
        broadcast[$i]=$(eval echo '$'BROADCAST$idx)
        arpcheck[$i]=$(eval echo '$'ARPCHECK$idx)

        if [ "${prefix[$i]}x" != "x" ]; then
            val=$(/bin/ipcalc --netmask "${ipaddr[$i]}/${prefix[$i]}")
            netmask[$i]=${val##NETMASK=}
        fi

        if [ "${netmask[$i]}x" = "x" ]; then
            val=$(/bin/ipcalc --netmask "${ipaddr[$i]}")
            netmask[$i]=${val##NETMASK=}
        fi

        if [ "${prefix[$i]}x" = "x" ]; then
            val=$(/bin/ipcalc --prefix ${ipaddr[$i]} ${netmask[$i]})
            prefix[$i]=${val##PREFIX=}
        fi

        if [ "${broadcast[$i]}x" = "x" ]; then
            val=$(/bin/ipcalc --broadcast ${ipaddr[$i]} ${netmask[$i]})
            broadcast[$i]=${val##BROADCAST=}
        fi

        if [ "${arpcheck[$i]}x" != "x" ]; then
            arpcheck[$i]=${arpcheck[$i]##ARPCHECK=}
            arpcheck[$i]=${arpcheck[$i],,*}
        fi

        i=$((i+1))
    done

    if [ -z "${NETWORK}" ]; then
        eval $(/bin/ipcalc --network ${ipaddr[0]} ${netmask[0]})
    fi
}

これによると、

  1. PREFIX が設定されていれば、PREFIX から NETMASK が計算される。
  2. NETMASK が未設定(空)であれば、IPADDR から NETMASK が計算(推測)される。
  3. PREFIX が未設定(空)であれば、IPADDR / NETMASK から PREFIX が計算される。

つまり、PREFIX は NETMASK より強い。ついでに言うと、公式ドキュメント通り BROADCAST と NETWORK はどちらも IPADDR / NETMASK から自動計算されるが、それは値が未設定(空)である場合に限られる。

念のため RHEL5 でも確認しておくと、

RHEL5.9: /etc/sysconfig/network-scripts/network-functions:

expand_config ()
{
    if [ -z "${NETMASK}" ]; then
	eval `/bin/ipcalc --netmask ${IPADDR}`
    fi

    if [ -z "${PREFIX}" ]; then
	eval `/bin/ipcalc --prefix ${IPADDR} ${NETMASK}`
    fi

    if [ -z "${BROADCAST}" ]; then
	eval `/bin/ipcalc --broadcast ${IPADDR} ${NETMASK}`
    fi

    if [ -z "${NETWORK}" ]; then
	eval `/bin/ipcalc --network ${IPADDR} ${NETMASK}`
    fi
}
  1. NETMASK が未設定(空)であれば、IPADDR から NETMASK が計算(推測)される。
  2. PREFIX が未設定(空)であれば、IPADDR / NETMASK から PREFIX が計算される。

これだけではどちらが強いのか分からないが、合わせて expand_config の呼び出し元(/etc/sysconfig/network-scripts/ifup-eth)を見ると、実際に使われるのは PREFIX の方だと分かる。

よって RHEL5 でも、PREFIX は NETMASK より強い。RHEL4 以前は使ってないので知らない。

そもそも何故こんなことを気にするかというと、現在の Webmin (1.620)が PREFIX に対応してないっぽいから。Webmin は NETMASK を設定するが、PREFIX には一切関与しない(消しもしない)。よって PREFIX と NETMASK の両方が ifcfg-* に記述される状況が生まれてしまう。もし Webmin でネットワーク設定を行うなら、事前に全ての PREFIX を NETMASK に変換しておいた方が良い。でないと、いつか痛い目を見る可能性がある。


2014-06-19 追記

今更だが、Webmin 1.630 にて PREFIX 対応が行われた。

2013-02-27

RHEL6: ssh-keygen: Permission denied

SSH 鍵を作ろうとすると、「Permission denied」と言われる。

[rhel62]# mkdir ~/.ssh

[rhel62]# chmod 700 ~/.ssh

[rhel62]# ls -dl ~/.ssh
drwx------. 2 root root 4096 Feb 27 09:04 /root/.ssh

[rhel62]# ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa ; echo $?
Generating public/private rsa key pair.
open /root/.ssh/id_rsa failed: Permission denied.
Saving the key failed: /root/.ssh/id_rsa.

パーミッションに抜かりなどある訳がない。失礼な。こういう時、真っ先に疑うべきは SELinux。

/var/log/audit/audit.log:

type=AVC msg=audit(1361923639.970:20915): avc:  denied  { create } for  pid=1932 comm="ssh-keygen" name="id_rsa" scontext=unconfined_u:unconfined_r:ssh_keygen_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
type=SYSCALL msg=audit(1361923639.970:20915): arch=c000003e syscall=2 success=no exit=-13 a0=7f6f3282cb80 a1=241 a2=180 a3=fffffff7 items=0 ppid=1875 pid=1932 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts3 ses=2 comm="ssh-keygen" exe="/usr/bin/ssh-keygen" subj=unconfined_u:unconfined_r:ssh_keygen_t:s0-s0:c0.c1023 key=(null)

案の定、何か文句を言っている。~/.ssh のコンテキストを確認すると、

[rhel62]# ls -dZ ~/.ssh
drwx------. root root unconfined_u:object_r:admin_home_t:s0 /root/.ssh

何処が気に入らないのかは良く分からないが、ともかく restorecon してみる。

[rhel62]# restorecon ~/.ssh

[rhel62]# ls -dZ ~/.ssh
drwx------. root root unconfined_u:object_r:ssh_home_t:s0 /root/.ssh

何か修正されたっぽいので、リトライ。

[rhel62]# ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
Generating public/private rsa key pair.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
a7:14:6f:f0:8a:72:64:20:01:55:2b:24:4c:aa:a7:30 root@rhel62
The key's randomart image is:
+--[ RSA 2048]----+
|=++..            |
|.+ . .           |
|. o o   o        |
|.  o .   =       |
|E .   o S =      |
|.+   o o =       |
|.   . o o        |
|     o           |
|                 |
+-----------------+

動いた。ちなみに ~/.ssh を作るのを ssh-keygen に任せると、何もしなくても上手くいく。

[rhel62]# rm -fr ~/.ssh

[rhel62]# ls -dl ~/.ssh
ls: cannot access /root/.ssh: No such file or directory

[rhel62]# ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa ; echo $?
Generating public/private rsa key pair.
Created directory '/root/.ssh'.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
e6:83:f6:38:dc:fc:eb:6a:45:f1:39:05:34:7d:ad:68 root@rhel62
The key's randomart image is:
+--[ RSA 2048]----+
|           .+o  .|
|          .  .o o|
|           o + o |
|          . E .  |
|        S. . .   |
|       +  .      |
|     .ooo.       |
|     .oo+.       |
|      .oo++.     |
+-----------------+

これは理屈としては理解できるが、非常に分かり辛い動作だと思う。

この理屈に従うと、作ったファイル・ディレクトリが SELinux のポリシーに沿っているかどうか、逐一確認しなければならくなってしまう。そういうことを平気で要求する SELinux の気が知れない。だから「SELinux 氏ね」とか言われるんだよ。:-p

ところでコンテキストの修正は restorecon で行えるが、現在のコンテキストが正しいかどうかはどうやって確認すれば良いのか。

matchpathcon を使え、と。

[rhel62]# rm -fr ~/.ssh

[rhel62]# mkdir ~/.ssh

[rhel62]# chmod 700 ~/.ssh

[rhel62]# matchpathcon -V ~/.ssh ; echo $?
/root/.ssh has context unconfined_u:object_r:admin_home_t:s0, should be system_u:object_r:ssh_home_t:s0
1

[rhel62]# restorecon ~/.ssh

[rhel62]# matchpathcon -V ~/.ssh ; echo $?
/root/.ssh verified.
0

注意点として、matchpathcon には絶対パスを渡す必要がある。でないと判定に失敗する。

[rhel62]# ls -dZ .ssh
drwx------. root root unconfined_u:object_r:ssh_home_t:s0 .ssh

[rhel62]# matchpathcon -V .ssh ; echo $?
.ssh has context unconfined_u:object_r:ssh_home_t:s0, should be <<none>>
1

これも理解できる動作ではあるが、やはり分かり辛い。もう少しマシなメッセージは出せないのかと文句を言いたい。

と、いうようなことを実は 1 年以上前にやっていたのだが、最近になって RHEL6.3 では本現象が起こらないことに気が付いた。調べてみると、この辺か。

「理解できる」と言っておいてアレだが、どうやら仕様ではなかったらしい。

2013-01-20

Animes in the 4th quarter of 2012

アニメは IT エンジニアの必須科目です。 ということで簡単なレビューを。

最初、主人公は一匹狼的でカッコ良さげなのだが、ヒロインと合流してからヘタれてしまう。このヒロインは男をダメにするサゲ○○に思えてならない。アクセル・ワールドと同じ作者と聞いて、妙に納得した。この人は世界観は良いが、脚本がダメなんだと思う。音楽だけは良いと思ったら、梶浦由紀だった。これも納得。

序盤は人類が天敵にエサにされるという展開。またキツいのが始まったなあ、と思っていたら、後半は殆ど人間の話になった。人の敵は人の心の中にこそある、というのは真実だとは思うが、結果として至って普通の話になった。個人的には、最初の絶望的な雰囲気で進めて欲しかった。きっと見るのは鬱になっただろうけど。

第一章はさっぱり面白くなかったが、第二章も変わらず。団結力だけが取り柄の弱っちい主人公達が仲間割れしたら、いったい何を褒めれば良いのか。最後に強くカッコよくなるが、その過程が理不尽。想いだけで強くなれたら世話ない。第一章と同様、OP くらいしか褒められるところが無かった。

少女マンガ原作ながらイマイチだった。ヒロインが惚れっぽくて話の展開が読める。神様の仕事そっちのけで狐とイチャつくことしか頭にない神様ってどうよ。まあ確かに年頃の女子とはそういうものだろうが、話もギャグも中途半端でお気に入りのキャラも無し、というのが正直な感想。ただ OP・ED は作品の雰囲気に合った良作。

原作は読んでたつもりだったが話がさっぱり思い出せない。と思ったら、実はアニメ用のオリジナルだったらしい(by Wikipedia)。そのせいかは分からないが、個人的にはイマイチな内容だった。本シリーズにしては、話が真面目すぎる気がする。まあ私はアニメより漫画の方が面白いと思ってるので、私的には問題ない。

今度は戦車を女子化か!?と思ったら流石にそれは無かった。戦車のことは知らないが、戦車の挙動がやけにリアルで、嘘かも知れないが本当にドリフトとかしそうに思える。個人的には好きな作品だったが、決勝戦の最中に「私たちの戦いはこれからです!!」と衝撃の終わり方。決して不人気のせいではなく、内部事情だと思いたい。

本シリーズは初めての視聴。原作も未読なので、最初は女子キャラの区別が付かなかった。ご都合展開全開の作品だが(何故いちいちパンツに突っ込む?という台詞は道理)、長寿作品なだけあって各キャラの個性は立っている(主人公を除く)。ただ長女の扱いがサブキャラ並みだなと思ったら、本作は一応スピンオフ作品だとは知らなかった。

原作は最初の五話くらいで挫折。ただ現在も連載中なので、アニメで魅力を発見できるかと期待したが、もう全然ダメだった。主人公、ヒロイン、敵の親玉、どいつの台詞も嘘くさくて私には全く受け付けられない。これは次回作があっても見ないと断言できる。

前期からの続き。序盤は雰囲気が変わったように思えて心配になったが、中盤以降は元に戻ったので安心。ただし最終回は消化不良。いきなり「2 年後」もそうだが、ヨナの心の変化、どう納得したのかが良く分からなかった。サブキャラの近況描写も一瞬だし、「風」の意味も不明。まあそれを差し引いても、全体としては十分に満足。

今クールの少女マンガ原作では、ダントツの出来。ギャグベースのドタバタ劇に、出てくる女子キャラは(サブキャラでさえも)魅力的で、見ていて飽きない。少女マンガ原作はこうでないとね。今回は「種﨑敦美」を覚えた。鈴木達央も今回の演技で見直した。唯一の不満は、最終回があっさり過ぎて終わったことに気付かなかったこと。

典型的な少女マンガという印象。内気なヒロイン、自分勝手で強引なイケメン、ライバルの出現。最初「君に届け」とデジャヴったが、君届には全く及ばなかった。風早くんの方がよっぽどいい奴だし、シリアス一辺倒で話に遊びがない(最終回を除く)。次回予告は良かったが、そういう遊びを本編にも入れて欲しかった。

まず目を引くのが独特な画質。特に空間制御魔法の描写が印象的。キャラも主人公以外は魅力的で、個人的にはネコがお気に入り。ただ、話がキャラに追いついていない感じがする。キャッチコピーの「きずな」は何処に出てきた? 結局ネコが何者かも分からないし。まあ既に続編が決定しているらしいので、そちらでの解決に期待。

大して期待していなかったが、賑やかさ・パロディー・エロス(?)など、その方面で期待していた「生徒会の一存」を食ってしまった。しかしそれは同時に、万人から見るととても「疲れる」作品になってしまった可能性も否定できない。個人的には元ネタが分からないパロディーがあったのが悔しい。まだまだ勉強が足りないようだ。

前作が結構好きだったので、引き続き視聴。しかし前作の勢いが感じられず、前半は空回りが目立つ印象。林檎、飛鳥での話のような盛り上がりがもっとあれば良かった。この作品の肝は生徒会メンバーの「デレ」だから。制作会社や声優が変わったりと扱いが不憫だが、そこまでして第二期を製作する必要があったのかは疑問。