>> はじめに - 321回の再起動
改修編① で「不調の理由を画面に出す」ところまで作った.そのきっかけになった事故から始める.
夕方,外出先からテレビを見ようとして見られなかった.帰宅してログを見るとこうだった.
error - failed on B_CAS_CARD::init() : code=-4
Scheduled restart job, restart counter is at 321 B-CAS カードリーダーが応答しなくなっていた.フルセグの復号にはカードが要るので,配信は立ち上がれない.Restart=always が律儀に拾い,立てんものを321回起こし続けていた.
カードを物理的に挿し直したら直った.つまりソフトの問題ではない.
だがここで思った.前日に入れたワンセグは B-CAS を使わない.カードが死んでもテレビは映り続けられるはずだ.
>> 自動でワンセグへ逃げる
60秒もたずに終わった回を «失敗» と数える
↓ 3回続けて失敗し,今がフルセグなら
★ワンセグへ落ちる(B-CAS を使わん段)
↓
赤帯に «落ちていること» を出し続ける
↓ 画質を選び直したら
数え札と表示を消してやり直す ここで二の足を踏んだ.実は数日前,別の場面で「自動で逃げる」仕組みを外したばかりだったからだ.
当初の画面には AUTO / LIVE / DEMO という選択があり,AUTO は放送が取れんと黙って試験映像へ逃げていた.これは故障を隠す.チューナーが載った時点で外していた.
では今回の逃げは何が違うか.
DEMO への逃げ «黙って» 逃げ,故障が分からん
ワンセグへの逃げ ★«逃げたことを言う».映っても赤帯は消えん 逃げること自体は悪くない.悪いのは黙って逃げることだった.テレビが映り続けるほうが実用に適う——ただし故障は必ず目に入る形で.
>>> 短気すぎた閾値
最初は「3回失敗したら逃げる」にした.だが RestartSec=2 なので6秒で届いてしまう.
ワンセグからフルセグへ戻る際,mirakc がチューナーを離す間に2~3回躓くことはありうる.そこで落とされると「フルセグにできん」ように見える.
実際,検証中にそれが起きたと思った.だが真相は違った——カードを本当に抜いて検証していただけで,仕組みは正しく働いていた.
「回数」だけでは「速く3回死ぬ」と「長く直らん」を区別できん——時間の条件を足すべきだった,というのが残った孿題だ.
>> カードを «電気的に» 挿し直す
「ボタンで直せないか」と問われた.USB にはその手がある.
echo 1-1.5 > /sys/bus/usb/drivers/usb/unbind
sleep 2
echo 1-1.5 > /sys/bus/usb/drivers/usb/bind カーネルに「抜いて挿す」のと同じことをさせる.幸いなことに構成が良かった.
ハブ 1-1
├ 1-1.1 LAN(smsc95xx) ← ★触ってはならん
├ 1-1.4 チューナー
└ 1-1.5 カードリーダ ← 独立したポート カードリーダだけを狙える.チューナーも LAN も巻き込まない.
>>> 型番で決め打ちにせん
ここで大事なのは探し方だ.
# ✕ 型番(04e6:5116)で決め打ち → リーダを換えたら壊れる
# ✅ USB のインターフェースクラス 0x0B(スマートカード)で探す
for itf in Path("/sys/bus/usb/devices").glob("*:*"):
if (itf / "bInterfaceClass").read_text().strip().lower() == "0b":
return itf.name.split(":")[0] # → "1-1.5" 取り違えればネットワークごと落ちる.検証では「0x0B として見つかったのがカードリーダだけか」を実際に確かめてから進めた.
>>> 自動ではやらん
「3回失敗したら自動で一度だけ入れ直す」という案も出たが,人が押す形に留めた.
ハードの故障に対して機械が繰り返し reset をかけるのは筋が悪い.ボタンはカードのエラーが出ている時だけ赤帯の中に現れる.関係ない時に押せる場所へ置くと,いつか誤って押される.
✅ カードを認識しました(low)
🔴 入れ直しましたが認識されません(物理的に挿し直してください)
🔴 入れ直しましたが配信が立ちません 結果は正直に返す.直らない時に「直しました」と言うのがいちばん悪い.
>> 監視が «自分で作った関所» に締め出された
別の日,端末の登録制(→ 改修編③)を入れた.その2分後から,監視が鳴り始めた.
07:51 関所を入れた(合鍵が無ければ 403)
07:53 tv-health が «自分で» 弾かれ始める
curl 8080/ → 403
curl 8080/state → 403
以降 5分ごとに «異常2件» を検知し続ける 監視が自分で作った関所に締め出されていた.一時的な不調ではなく,放っておけば永遠に鳴る種類の壊れ方だった.
# ✕ curl 8080/ → 合鍵が無いゆえ 403
# ✅ curl 8080/enroll/ → 自宅からは通る。nginx が配れておるか判る
# ✕ curl 8080/state → 関所に弾かれる
# ✅ curl 8081/state → tv-switch を直に叩く(nginx を経由せん) 監視は «守りの内側» から確かめる.守りに弾かれては,何を測っているのか分からない.
新しい守りを入れる時は «既に通っている者» を数える.
ブラウザのことしか考えておらず,同じ入口を使う監視を忘れていた.
しかも通知は届いていたのに,自分では確かめていなかった.
>> 8日間気づかなかった穴
もう一つ,この日見つかったものがある.
再起動の後,番組表が 0件になっていた.前日も同じことが起きていて,その時は「そういうもの」と思って収集し直していた.
二度目でさすがにおかしいと思って調べた.
ExecStart -v mirakc-epg:/var/lib/mirakc/epg ← ★保存先は繋いである
config.yml epg の記述 0件 ← ★書く設定が無い 入れ物だけ用意して,中身を入れていなかった.ボリュームは8日前から繋いであったのに,mirakc に「そこへ書け」と言っていなかった.
epg:
cache-dir: /var/lib/mirakc/epg この3行が抜けていただけだった.
入れて収集し直し,わざと再起動して確かめた.
再起動 前: 6655 件
再起動 後: 6655 件 ✅ 生き残った
schedules.json 5.2MB これが無ければ,停電や不意の再起動のたびに最大21時間番組名が出ないことになる.
一度 «消えた» のを見ておるのに «仕様» で済ませたのが落ち度だ.
動いているように見えて,半分しか出来ていなかった.
>> まとめ
- 逃げること自体は悪くない.悪いのは黙って逃げること
- 回数だけでは「速く死ぬ」と「長く直らん」を区別できん.時間の条件を足す
- 型番で決め打ちにせずクラスで探す.取り違えればネットワークごと落ちる
- ハードの故障に機械が繰り返し reset をかけない.人が押す
- 新しい守りを入れる時は «既に通っている者» を数える
- 監視は守りの内側から確かめる
- 一度「消えた」を見たら,「仕様」で済ませない
次は改修編③ 外へ出す.端末の登録制と,「入口を分けねばならん」と気づいた実データの話だ.