2020年7月20日月曜日

Debian SidのMercurialがPython 3へ移行したためinfo.pyに異常が出た (workaroundあり)

Debian SidのMercurialが5.4.1→5.4.2にupgradeされた。このversionでは(Mercurialが依存する) Pythonが2.7→3へ変更された。

この影響で、Mercurialのextensionとして導入しているinfo.pyの実行に不具合が発生した:

> % hg st .
> *** failed to import extension info from ~/.hg.d/info.py: unicode 'info' found in cmdtable
> *** (use b'' to make it byte string)
> ...

info.pyを読み込む際にerrorが発生してimportに失敗している。`bytes`を想定している`cmdtable`内にUnicodeとして認識されたstringが混入したため。

Workaroundとして、「`b''`を使って (explicit type conversionして)ね!」というerror messageに従い、info.pyにて:

> - @command('info')
> + @command(b'info')

の変更を行い解決した。


Python 3.xでのstrとbytesについて


Python 3では`str`がUnicodeへ変更された (Unicodeが`str`になった)一方で、Mercurial (のAPI)は`bytes`を想定している。Python 3は (Python 2 seriesのような)`str` (Unicode)と`bytes`のimplicit type conversionを行わないので、このような事例はerrorとして検出される。

以下、Python 3.8.4のdocumentationより引用:

Note
 
For Python 2.x users: In the Python 2.x series, a variety of implicit conversions between 8-bit strings (the closest thing 2.x offers to a built-in binary data type) and Unicode strings were permitted. This was a backwards compatibility workaround to account for the fact that Python originally only supported 8-bit text, and Unicode text was a later addition. In Python 3.x, those implicit conversions are gone - conversions between 8-bit binary data and Unicode text must be explicit, and bytes and string objects will always compare unequal.

cf. [Built-in Types — Python 3.8.4 documentation](https://docs.python.org/3/library/stdtypes.html#bytes)

(要約)

Python 2.xまでは色々な過去の経緯もあってUnicode文字列と8bit文字列の暗黙的な変換が横行していた。Python 3.xからは一切暗黙的に変換しないのでプログラマは明示的に変換する必要がある。`str`と`bytes`の比較は常に等しくない。


2020年7月15日水曜日

SwissMicros DM15LのfirmwareをV29にrevert (downgrade)

具体的にいつごろrevertが推奨されたのか把握していないが、少なくとも2020-07-09には以下の文言がfirmwareのupdate historyに追加されていた:

!!! V30 firmware was removed after confirmation of excessive consumption in OFF mode
!!! Everybody should revert to V29 firmware.

cf. <https://www.swissmicros.com/voyager/firmware/history.txt>

(私訳) V30ファームウェアは、OFFモードにおける過大な電力消費が確認されたので削除された。全ての人はV29ファームウェアに差し戻すべき。

V30 firmwareの不具合が影響したのかは不明だが、最近DM15Lの電池 (CR2032 ×1)を交換した記憶がある。もっとも、リチウムを使用しているため長期保存に向く (〜10年)とされるCR2032とは言え、古い物であることが影響していた可能性はある。

なお、firmwareの差し戻し (revert)の手順は、upgradeの手順と全く同じ。例えば、lpc2lispを使ってLinux boxからUSB cableで行う場合は指定するfirmware fileが異なるだけである。


2020年6月10日水曜日

[Minecraft] 快適な建築のための環境設定

2020-06-10現在の最新安定版であるJava Edition (JE) v1.15.2向け。

まとめ


Create New World (新しいワールドの作成時)


* Game Mode: Creative
* Generate Structure: Off
* World Type: Superflat

Play Selected World (作成したワールドを遊ぶ時に一度だけ設定)


* /gamerule doMobSpawn false
* /gamerule doWeatherCycle false
* /gamerule doTileDrops false


蛇足


ブロックを積んでちょっとした「建築」を楽しみたい時には、Creative modeでなおかつSuperflatなworld typeが良い。

Creative inventoryが使える上に飛行でき、どんなブロックも1回で破壊できるので試行錯誤にはぴったりだ。また、Superflatな世界なら地形を平らにならす「整地」が必要なくなる。村やダンジョンなどの生成を禁止するのも良い。

ただし、これだけでは:

* 夜間や暗い場所にゾンビやコウモリが湧く
* エンダーマンにブロックを持って行かれる
* クリーパーが出て爆発する
* 天気が悪化して視界不良になる

と言った妨害を受ける。

敵対的なmobs (ゾンビ、クリーパー、エンダーマン、etc)については、/difficulty peacefulへの設定で即座に存在を消せる。しかし、夜間や暗所に湧くコウモリは中間的mobsのためこれだけでは不十分である。そもそも建築に集中するのにmobsは邪魔なため、/gamerule doMobSpawn falseですっきりする。

特にコウモリが湧かなくなるといわゆる「湧き潰し」のため至る所で明るさを確保する必要がなくなり手間が省ける。

天候の悪化 (雨)も視界不良の原因となるので、/gamerule doWeatherCycle falseで切る。個人的に夜の雰囲気は好きなので昼夜の変化は切っていないが、必要なら/gamerule doDailyLightCycle falseで切れる。

細かいことだが、ドアなどを破壊した際にitem化しても邪魔なだけなので/gamerule doTileDrops falseで止める。そもそも建築時にはcreative inventoryが使えるのでitemを回収する必要がない。

cf. [Commands/gamerule – Official Minecraft Wiki](https://minecraft.gamepedia.com/Commands/gamerule)


残る課題


* creative modeで空を飛んでいる時の挙動が嫌 → 所謂「慣性」 (inertia, momentum)が残るのが操作しにくい原因。キーを押している時だけ動いて、話したら即止まって欲しい
* ↑一応そういう感じのmodがあるようなので導入を検討したい

2020年4月18日土曜日

Windows 10 version 1909へのupdate

Windows 10 version 1809のEOLが約1ヶ月後の2020-05-21に迫っていることもありversion 1909へupdateした。

Downloadやinstallationなどで2〜3時間掛かったが正常にupdateは終了した。2020-04-18現在、使っていて特に問題はない。

なお、version 1909のEOLは2021-05-11の予定。

cf. [Windows ライフサイクルのファクト シート - Windows Help](https://support.microsoft.com/ja-jp/help/13853/windows-lifecycle-fact-sheet)

SwissMicros DM1X series向けのfirmware V30がreleaseされていた (2020-01-17)

(注意)

2020-07-15現在、V30 firmwareには「OFFモード中の過大な電力消費」という不具合が公式に確認されている。V29の方はそのままで、V30にupdateした方はV29へのrevertが推奨される。

(注意ここまで)


SwissMicros DM1X向けのlatest firmwareであるV30が2020-01-17にreleaseされていた。

気付いたのが2020-02-24で、その日のうちにupdateを実行した。

変更点を引用:
V30: 17.01.2020
ALL: Added 'bootloader' serial console command
ALL: Abandoned support for 32kB firmwares
ALL: Improvements to Nut emulation layer
DM41: Stopwatch now generates 'TIMER ALARM' when SW is hidden as well when calculator is turned off.
cf. [Firmware History](https://www.swissmicros.com/voyager/firmware/history.txt)

Firmware updateはいつも通り、Linux boxからlpc2lispを使って実行。具体的な手順については以前の記事 (cf. https://typeinf-memo.blogspot.com/2016/07/swissmicros-dm-15lfirmware-upgrade.html)を参照されたい。


SwissMicros DM42のfirmware update (DMCP 3.18 + DM42 3.15)

SwissMicros DM42のfirmware (DMCP 3.18 + DM42 3.15)が2020-03-30にreleaseされていた (cf. [Index of /dm42/firmware](https://www.swissmicros.com/dm42/firmware/))。

今回はDMCP OS (OSのcore)+DM42 program (HP42 emulator)をまとめてdfu-utilでupdateした。具体的な手順については以前の記事 (https://typeinf-memo.blogspot.com/2017/12/swissmicros-dm42firmware-update.html)を参照されたい。

なお、一つ前のversionは2020-02にupdateされており、それも適用していたのだが記事にし忘れていた。



2020年1月21日火曜日

Chromium 79.0.3945.79-1 (Debian sid)がSEGVる (1/21: version upで解決済み)

*** update ***

2020-01-21、Sidにてchromiumがupdateされていて (79.0.3945.79-1 → 79.0.3945.130-2)、こちらのversionでは特に問題なく使用できている。

*** updateここまで ***


Web browserのchromiumを79.0.3945.79-1 (12/19現在の最新版)にupgradeしてからSEGVるようになった。起動しないとか、起動してすぐとかではなく、しばらくするといつの間にか落ちている感じ。

Debian Bug Tracking System (BTS)を見てみると既に複数の報告がなされている:

cf. [#945920 - Chromium randomly crashes in the latest version. - Debian Bug report logs](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=945920)

現状でできる対策は前のversion (78.0.3904.108-1とか)に戻すことだが、もしかしたらsecurity flawとかがあるかも知れない。


2019年12月1日日曜日

VirtualBox 6.0.14のdkmsがLinux kernel 5.4の仕様変更でbuildできない (VBox 6.1で対応)

*** update ***

2020-01-21更新: Linux kernel 5.4.13 (1/21現在5.4.x系列の最新版)を試している。既にVBox側で対応済みなため、特に問題なくkernel modulesをbuild、使用できている。

*** updateここまで ***


Linux kernel 5.4からset_pages_x()とset_pages_nx()というfunctionsが削除された。

Debian unstableに入っているVirtualBox 6.0.14はこの変更に対応しておらず、現状ではkernel moduleがbuildできずにerrorになる。

VBoxのdevelopersは既に対応するpatchを作製済みで、6.1RC1としてreleaseしている (cf. [#18945 (Linux 5.4: no more arbitrary executable pages and more changes) – Oracle VM VirtualBox](https://www.virtualbox.org/ticket/18945))。

何れDebian unstableかexperimentalに入るだろう。 2020-01-21現在sidに6.1が入っている。

Linux kernel 5.4 seriesにはi915でgpu resetがtimeoutしてin-flight renderingが止まる問題もあるので、当面は5.3で運用する予定。 2020-01-21現在、5.4.13で特に問題がなさそうなのでこのまま移行できそう。

Linux kernel 5.4.1でgpu resetがtimeoutしてXの画面が止まる (1/22: 5.4.13でも発生 → 1/24: 5.5-rc7で解決か)

*** update ***

2020-01-21追記: 5.3系列がEOLっぽいので5.4.13を試してみているが、rebootから2hrsぐらい経過して特に問題なく使えている。少なくとも"Resetting rcs0"は出ていない。

2020-01-22追記: 気付いたら止まっていた……5.5-rc7をテスト中。

2020-01-24追記: 2日以上安定して使えているので5.5-rc7に移行する。

*** updateここまで ***


5.3.10の時点で既に出ていた症状だが、5.4.1にversionが上がって改善されるかなと思いきや、freezeしたまま延々とerror messageがsyslogに吐かれている状況で寧ろ悪化している?

syslogに残っていたerror messagesはこんな感じ (この時のkernelは5.4.0):

Dec  1 00:00:06 kernel: i915 0000:00:02.0: Resetting rcs0 for hang on rcs0
Dec  1 00:00:08 kernel: i915 0000:00:02.0: Resetting rcs0 for hang on rcs0
Dec  1 00:00:10 kernel: i915 0000:00:02.0: Resetting rcs0 for hang on rcs0
Dec  1 00:00:12 kernel: i915 0000:00:02.0: Resetting rcs0 for hang on rcs0
Dec  1 00:00:14 kernel: i915 0000:00:02.0: Resetting rcs0 for hang on rcs0
Dec  1 00:00:16 kernel: i915 0000:00:02.0: Resetting rcs0 for hang on rcs0
Dec  1 00:00:18 kernel: i915 0000:00:02.0: GPU recovery timed out, cancelling all in-flight rendering.
Dec  1 00:00:18 kernel: i915 0000:00:02.0: Resetting chip for hang on rcs0

中途半端に止まったり (resetによって)動いたりを繰り返すよりは、いっそ止まって使えないというはっきりした状態の方がマシという考え方もあるが。

5.4.0では普通に使えているので取り敢えず様子見。
5.4.0でも止まったので、5.3.14に戻して暫く使ってみる。Debian unstableのVirtualBox (6.0.14-dsfg-3)だとkernelの仕様変更で5.4に対応できていないのもあるので。

(12/4追記) 5.3.14でも時々画面のrenderingが止まるが、数秒後に回復する。その時のsyslog:

Dec  4 03:16:10 kernel: i915 0000:00:02.0: Resetting rcs0 for hang on rcs0

resetが掛かった後5.3だと復帰するけど、5.4では復帰できずにin-flight renderingが停止する。5.4で変更された中に何かあるようだ。


2019年9月29日日曜日

Apple iOS 12.4.2へupgrade

Apple iPad mini 2などに向けてiOS 12.4.2がreleaseされた。

内容はsecurity update。

設定 → 一般 → ソフトウェア・アップデート → 自動アップデート が「オン」になっていれば、自動的に適用されるはず。

2019年9月1日日曜日

Apple iOS 12.4.1へupgrade

手持ちのiPad mini2では、今日9/1の夜あたりに自動でupgradeされる予定だったが、今すぐ更新のボタンを押した。

軽く使ってみた感じ特に不具合には遭遇していない。


2019年8月31日土曜日

yascrollがemacsの仕様変更で動かなくなったので修正してみた

yascrollが動かなくなっていることに今頃気付いた。

試しに M-x yascroll:show-scroll-bar を実行してみると:
Wrong number of arguments: (left-width right-width outside-margins), 4
なるerror messageが返って来る。どうやらEmacs側の仕様変更があった模様。

git logで調べてみるとこれだった:
commit 8e0ebb9a3cb9beef2f5ff50436fef1c54a3e3c92
Author: Martin Rudalics <rudalics@gmx.at>
Date:   Mon Jul 22 09:19:18 2019 +0200
    Handle persistence of windows' scroll bar and fringes settings (Bug#36193)
src/window.cに含まれるwindow-fringesというCで書かれたfunctionは、これまで指定された (Emacsにおける) windowのleft-widgh, right-width, outside-marginsの3つのparametersを返していた。

このcommitで加えられた変更により、新たに4つ目のpersistentというparameterが追加された。これがyascrollの側でparametersの数が合わないというerrorの原因となっていた。

なお、window-fringesの詳細はEmacsからF1 helpで参照できる:
window-fringes is a built-in function in ‘C source code’.
(window-fringes &optional WINDOW)
  Probably introduced at or before Emacs version 22.1.
  This function does not change global state, including the match data.
Return fringe settings for specified WINDOW.
WINDOW must be a live window and defaults to the selected one.
Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS
PERSISTENT), see ‘set-window-fringes’.
さて、実際にerrorを起こしていたのはyascroll.el内に定義されたyascroll:choose-scroll-barである:
(defun yascroll:choose-scroll-bar ()
  (when (memq window-system yascroll:enabled-window-systems)
    (cl-destructuring-bind (left-width right-width outside-margins)
        (window-fringes)
      (cl-loop for scroll-bar in (yascroll:listify yascroll:scroll-bar)
               if (or (eq scroll-bar 'text-area)
                      (and (eq scroll-bar 'left-fringe)
                           (> left-width 0))
                      (and (eq scroll-bar 'right-fringe)
                           (> right-width 0)))
               return scroll-bar))))
left-width, right-width, outside-marginesの3つがcl-destructuring-bindに指定されているため、新たに4つ目のpersistentを返すようになったwindow-fringesと不整合を起こした。

解決方法は簡単で、
(cl-destructuring-bind (left-width right-width outside-margins persistent)
のように適当な名前のvariableを追加すれば良い (なお、このvariableは使われない)。

fileを修正したら、M-x byte-recompile-fileなどでyascroll.elcを再生成し、el-get-reload (他お好みのpackage management systemの作法)でyascrollをreloadする。

2019年8月3日土曜日

Debian sidのchromium (76.0.3809.87-1)でextensionが使えない

*** 2019-08-04更新 ***

* chromium 76.0.3809.87-2で修正されたことを確認した。

*** 更新ここまで ***


Debian BTSに同様の報告が既に上がっている。

何れ修正されたversionがuploadされるだろうが、workaroundとしてはdowngradeすれば直るとのこと。

cf. [#933598 - Most extensions now crash upon browser start - Debian Bug report logs](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=933598)


yaskkservがgeneral protection faultで死ぬのでlocal dictionaryに移行した

yaskkserv (1.1.0-2+b1)が以下のような感じで死んで使いものにならないので、Emacsのddskk側にlocal dictionaryを持たせてそこから変換することにした。

% dmesg
...
[ 6720.501847] yaskkserv_hairy[24540]: segfault at ffffffff65c2a470 ip 0000557bd2ec4550 sp 00007ffc5c73ac38 error 5 in yaskkserv_hairy[557bd2ec3000+11000]
[ 6720.501852] Code: 41 8b 7c 24 10 49 8b 5c 24 08 99 f7 ff 48 63 d2 4c 8b 34 d3 4d 85 f6 0f 84 7c 02 00 00 85 ff 0f 84 74 02 00 00 45 85 c0 74 46 <41> 0f b6 06 45 8d 68 fe 41 bb 01 00 00 00 49 83 c5 02 84 c0 0f 84
[ 6731.709864] traps: yaskkserv_hairy[24640] general protection fault ip:560bc7400550  sp:7ffc61b6d098 error:0 in yaskkserv_hairy[560bc73ff000+11000]
[ 6742.007321] traps: yaskkserv_hairy[24729] general protection fault ip:5633f951d550 sp:7ffd18e31568 error:0 in yaskkserv_hairy[5633f951c000+11000]
[ 6780.822601] traps: yaskkserv_hairy[24917] general protection fault ip:55eed261a550 sp:7fffa84c1108 error:0 in yaskkserv_hairy[55eed2619000+11000]
[ 6784.167264] traps: yaskkserv_hairy[25045] general protection fault ip:561fa6e21550 sp:7ffd698daa68 error:0 in yaskkserv_hairy[561fa6e20000+11000]
[ 6787.968865] traps: yaskkserv_hairy[25093] general protection fault ip:557eda003550 sp:7ffe8633b038 error:0 in yaskkserv_hairy[557eda002000+11000]
...


移行先の候補


* yaskkserv以外のskkserver → 未だにuim-skkを使っているので利点もあるが今回はパス
* EmacsのDDSKKにdictionaryを持たせる → 今回採用

yaskkservを使っていた一番の理由が複数の辞書を指定できることだった。SKKの辞書には一般的な使用に適するL辞書 (SKK-JISYO.L)の他にも、複数の専門的な辞書が存在していて、それを一括して指定できるのが便利だった。

ただし、他の辞書を1つしか指定できないskkserverであっても、複数に分割されている辞書を統合して1つの辞書にしてしまえば機能的に何ら変わらない。辞書を操作するためのツールであるskkdic-expr2を用いて作業する。

skkdic-exprとskkdic-expr2の違いは:

* 動作が高速 (expr2)
* skkdic-sortが必要ない (expr2)
* annotationに対応している (expr2)

など。


作業例


統合辞書の作製


必要なdictionaries (eg. /usr/share/skk/以下にあるものとか)を'+' operatorで結合する。個人的に旧仮名の北極三號も結合している。

% skkdic-expr2 dic1 + dic2 + ... + dicn

このあたりは一度適当なscriptに記述しておくと後は一発で同じ作業できるようになって面倒事が減る。bashとかzshの機能とかをうまく使って柔軟性の高いscriptを書けるのだろうが怠いのでabsolute pathを決め打ちした。

/etc/default/yaskkservの記述を参考にして取り込む辞書を決めてabsolute pathでリスト (というか空白で要素を区切った文字列)に記述し、bashの機能で空白' 'を' + 'に変換するという雑な方法でskkdic-expr2に与えている。

dic_list="\
/path/to/skk/dic1 \
/path/to/skk/dic2 \
...
/path/to/skk/dicn"

↓ ${dic_list// / + } # 文字列内のすべての' 'を' + 'にreplace

/path/to/skk/dic1 + /path/to/skk/dic2 + ... + /path/to/skk/dicn

なお、SKKの辞書はDebianならskkdicやskkdic-extraあたりに収録されていて、/usr/share/skk/以下に展開される。他にもCVS repositoryから引っ張って来ることもできるが、その場合はcvs update -dPしてmake allしないと辞書が生成されない (或いは最新版にupdateされない)ので注意。

使っているRuby scriptが想定しているversionが古いため、nitemsというobsoleteなmethod (Ruby 1.9で廃止)が使われていたりした。これはcount {|item| !item.nil?| }というRuby 1.9移行の等価な(?)記述に変更すれば動くようになる。

cf. [nitems (Array) - Rubyリファレンス](https://ref.xaio.jp/ruby/classes/array/nitems)

作製した辞書を使うための設定


Emacsの設定ではSKKのdictioaryのcharacter encodingをUTF-8にしている (defaultではEUC-JP)ので、nkfを使って結合済みのdictionary (SKK-JISYO.my)をUTF-8に変換する。

% nkf -w -Lu SKK-JISYO.my > SKK-JISYO.my.utf8

~/.skkの記述を変更してskkserverではなくlocal dictionaryを直接読み込む設定に変更。Dictionaryのcharacter encodingをUTF-8に指定するのも忘れずに。

(setq skk-large-jisyo "/path/to/SKK-JISYO.my.utf8")
(setq skk-jisyo-code 'utf-8)

M-x skk-restartを実行して設定を最新の状態に更新する。

*scratch* bufferあたりで適当に変換して期待する動作が行われることを確認して終了。

UIMなどimput methodにSKKを用いている場合は、それぞれのtoolbarとかから設定できるはず。UIMの場合はuim-pref-gtk3とかがあるのでそこから辞書サーバではなくてlocalの辞書fileを指定する。

これで設定が反映されれば良いが、されない場合は既存のprocess(es)を皆殺しにするか、Xのsessionをrestartすれば多分反映される。


2019年7月28日日曜日

Debianで暗号化したroot fsを読めなくなりunbootableになった

Linux kernel 5.2.3のreleaseに伴ったupgradeを実施してrebootした所、LUKSで暗号化したroot filesystemが読めず (passphraseを尋ねてくるpromptも出ず)にunbootableに陥った。

原因は、dependencyの関連でcryptsetup-initramfsというpackageがuninstallされ、その後にregenerateされた/boot/initrd.imgにcryptsetup関連のbinaryが含まれなくなったことだった。


症状と対策



* Linux kernelがloadされboot processは進行するが、暗号化されたroot filesystemが開けずにretryを繰り返して何れgive upする
* 前回別のmachineでGRUB2関連のトラブルを経験していたので、GRUB2 (今回はx86_64-efi)を入れ直したのだが↑と同じ症状でbootできず
* 以前のkernel (v5.1.15)からbootできることに気付き、kernel optionなどの変更によるものかと疑いはじめる。また、他のinitrd.imgと比較した所、bootできないinitrd.imgは1MBほどsizeが小さくなっていると気付き、ここに問題が潜んでいると推定
* 通常の方法では中に含まれているものが見えないので、lsinitramfsという専用のprogramで中身を検めた所、cryptsetup関連のprogramなどが含まれていないと判明
* 最終的にcryptsetup-initramfsというpackageがuninstallされていたことに気付いて再びinstallし、initrd.imgをregenerate (update-initramfs)して解決した


蛇足


根本的な理由に辿り着くまで非常に時間が掛かったのだが、それは以下の要因のため。

* 数日前に別のmachine (Linux box)でGRUB2関連のトラブルに遭遇していた。今回もそれに類似する、或いは見た目は違っていても根本に同じ問題があるのではないかと推定し (結果的に外れていた)、そちらの問題の解消のため作業に取り掛かった
* 前回のmachineと今回のmachineでは使っているGRUB2の種類が違っており、作業に慣れていなかった。前回はDOS形式のdiskにi386-pc方式でMBRにGRUBをinstallしていたが、今回はGPT形式のdiskにx86_64-efi方式でEFI領域にGRUBをinstallしていた
* LVMの扱いに習熟していなかった

2019年7月24日水曜日

Apple iOS 12.4がreleaseされた

手持ちのiPad mini 2にてupgradeを実施。今の所は特に問題なく使えている。

WWDC 2019で発表されたiOS 13 iPadOSでは、残念ながらiPad mini 2が対象外となりそうだが。


2019年7月19日金曜日

Debian sid (unstable)でgrub2がおかしくなりunbootableになったのを修正した

Linux kernel 5.2.1がreleaseされたのでいつも通りにcustom kernelをbuildしてupdateした所、grub2 (bootloader)の設定がどこかの時点でおかしくなっていたらしくunbootableとなった。

色々と調べつつDebian liveからGRUB2を入れ直して復旧できたので手順を記録しておく。


症状と原因


...
symbol `grub_file_filters' not found
grub rescue>

lsすると(hd0,msdos1)みたいなのが表示される。環境依存だが、今回は(hd0,msdos1)が/dev/sda1で/bootに割り当ててあるpartition。

insmod normal.mod
を実行するとsymbol not foundが出る。insmod normal.modできないとnormalになれずbootもできない、と。

どうやらupgradeしたgrub2のpackageそのものか、grub2のinstallation processに問題があったようだ。

rebootのlogとaptitudeによるupgradeのlog


* grub2関連packagesがupgradeされたのは7/10 (2.02+dfsg1-20 → 2.04-1)
* それ以降のrebootは今回 (7/18)が初めてだった (`last reboot`で調べられる)


復旧の用意


正常に稼働するmachineでDebian liveのUSB flash memoryを作製する。今回は別のLinux boxを利用した。

Debian liveのUSB用imageをdownloadする


速度や負荷の面からrikenやjaistなど日本国内のmirror siteを使うと良いだろう。今回はrikenからdebian-live-10.0.0-amd64-standard.isoをdownloadした。GUIは不要との判断からstandardを選択したが、好みでXfceなどのdesktop environmentのflavorsも使える。

standardだとDEがないのでfilesizeが小さい、USB flash memoryへの書き込みが速く終わる、起動が速い、などの利点がある(ように思う)。boot後は自動loginですぐconsoleが使えるようになるので面倒がない点も良い。

USB flash memoryに書き込み


書き込み先のUSB flash memoryは/dev/sdbとして認識したが環境依存。危険なcommandなので必ず書き込み先を確認する。あとblocksize (bs)は適当なので最適値かどうかは不明。

% sudo dd if=debian-live-10.0.0-amd64-standard.iso of=/dev/sdb bs=10M


復旧の手順


ここから復旧対象のmachineでの作業。

BIOS/UEFIのmenuからboot deviceの順序を変更する


USB flash memoryを最優先にする。BIOS/UEFIによって様々だが、一通り眺めればわかるだろう。今時のUEFIだとどんなdevice(s)が接続されているかも表示されることが多いと思う。

Debian liveから起動


USB flash memoryからbootするとmenuが表示される。Installではなく、Debian liveを選ぶ。standardだとconsoleに自動loginなので面倒がなくて良い。

なお、Debian liveでは(次回のsessionには保存されないが)必要なDebian packagesを後付けでinstallできる。defaultではLUKSやGRUB2のpackagesが入っていないので、これを導入する。

packageを導入するにはまずnetworkをどうにかする必要がある。ここも環境依存なのだが、今回復旧対象のmachineはstaticにIPv4 addressを割り当てているのでip commandで関連の設定を行う。

IPv4 addressの割り当て


対象のnetwork interfaceはenp0s****として認識された。環境依存。

% ip addr show # どんなnetwork interface(s)があるか、どんなaddressが割り当てられているか
% sudo ip addr del 169.254.13.127/16 dev enp0s**** # 不要なaddress (多分autoで設定されているやつ)を削除しておく。不要だとは思うが念のため
% sudo ip addr add 192.168.11.2/24 dev enp0s**** # 普段machineに割り当てているaddressをassignする

routingの設定


このままだと外に出て行けないのでdefault gatewayを設定する。今回使うrouterのaddressは192.168.11.1。

% ip route show # 現在のrouting tableの確認
% sudo ip route add default via 192.168.11.1 # routerのaddressをdefault gatewayに指定

nameserverの設定


まだdomain nameのresolveができないのでnameserverを指定する。今回はdefault gatewayと同じaddress。

% sudoedit /etc/resolv.conf

> nameserver 192.168.11.1

aptのmirrorを設定


ここまででnetwork installが使えるようになったので、日本国内のmirror serverを設定する。今回はftp.jp.debian.orgを指定した。

% sudoedit /etc/apt/sources.list

> ftp.jp.debian.org

必要なDebian packageのinstallation (#1 LUKS)


前述の通り、Debian liveにはLUKSもGRUB2もdefaultでは入っていないので、別途installする必要がある。networkを設定したので導入可能な状態。

まずはcryptsetupを導入する。grub2は後で別にinstallする。

% sudo apt-get update
% sudo apt-get install cryptsetup

cryptsetupでLUKSの領域をmount


復旧対象machineのSSDは/dev/sdaとして認識されていて、/dev/sda1が/boot、/dev/sda5がroot (LUKSでencrypted)。

% sudo cryptsetup luksOpen /dev/sda5 secured_root # "secured_root"は何でも良いので適当な名前をつける
% sudo mount /dev/mapper/secured_root /mnt # ↑で適当に付けた名前が/dev/mapper/以下に現われるのでそれをmountする
% sudo mount /dev/sda1 /mnt/boot # LUKSで暗号化されたroot partitionに本来の (現在は壊れているので復旧対象の)/bootをmountする

必要なDebian packageのinstallation (#2 GRUB2)


% sudo apt-get install grub2

installationの最中に、grubの設定に関するgraphical menuが出るがcancel。

GRUB2をSSDへinstallし直す


あくまで対象はSSD (/dev/sda)であって、USB flash memoryではないことに注意。

% sudo grub-install --root-directory=/mnt /dev/sda

再起動してUSB flash memoryを引き抜く


% sudo shutdown -r now

reboot後、本来のGRUB menuが出れば復旧完了。

必要に応じて変更したBIOS/UEFIの設定(boot deviceの優先順位)を元に戻す。


参照したwebsites

* [Linux Set Up Routing with ip Command - nixCraft](https://www.cyberciti.biz/faq/howto-linux-configuring-default-route-with-ipcommand/)
* [grub rescueでnormal.modがnot foundですとか言われた話 - ひびっちぇ どっとこむ](http://hibitche.hatenablog.jp/entry/2015/07/17/012051)
* [WM×LI: grub rescue が表示されても慌てずに.](http://nort-wmli.blogspot.com/2013/06/grub-rescue.html)
* [#931896 - grub-efi-amd64: symbol `grub_file_filters` not found - Debian Bug report logs](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=931896)


2019年7月18日木曜日

SwissMicros DM15Lのfirmware update (V29)

SwissMicros DM15Lのfirmware (V29)がreleaseされていたのでupdateした。

いつも通り、Linux boxからlpc21ipcを用いた。

firmware updateの手順については以前の記事で触れているので必要に応じて参照されたい。

cf. https://typeinf-memo.blogspot.com/2016/07/swissmicros-dm-15lfirmware-upgrade.html

SwissMicros DM42のfirmware update (DMCP v3.14)

SwissMicros DM42のfirmware (DMCP)のv3.14がreleaseされていたのでupgradeした。

今回はDM42のinternal storageのFAT領域にDMCP v3.14のfileをuploadして、DM42のmenuからupgradeを試みた (7/8)。

なおDMCPのみなので、upgradeが終了してDM42をresetするとDMCP menuで立ち上がって、そのままでは計算機として使えない状態となる。別途DM42-3.14.pgmをdownloadしてFAT areaのrootにinstallした後、DMCP menuのload programから実行する必要がある。

7/18現在ではfirmwareのdownload pageより、DMCP_flash_3.14_DM42-3.14.binをdownloadしてupgradeする方が楽だろう。

cf.

* [Index of /dm42/firmware](https://www.swissmicros.com/dm42/firmware/)

2019年5月24日金曜日

Raspbianで/lib/modules以下のfilesがdisk容量を喰っていた

概要


* Raspbianで/lib/modules以下が肥大していた
* 不要なfilesの削除で8GB → 230MBにダイエット成功
* rpi-updateを頻繁にする人は気をつけよう


本編


Raspberry Pi 3 model Bで32GB (≒29.8GiB)のUSB flash memoryを使っているのだが、妙に使用量が多い気がしていた。DE (GNOMEとかKDEとか)をinstallしている訳でもないのに、30GiBのおおよそ半分程度が消費されている。

経験則に過ぎないが、Debian系distributionをCLI環境のみでinstallした場合は2〜3GB程度が良い所だ。そこにちょっと容量を食うdevelopment関連のpackageとか、gitのrepositoryのcloneとかを入れても5〜6GBぐらいだろう。

最初はBME280で取っているlogが消費しているのかとも思っていたのだが、それらをNASに移動しても容量にほぼ変化がなかった。

% sudo du -hc . | sort -h
...
8.0G /lib/modules
8.1G /lib
13G /
13G total

プログラム開発の格言に「何処で時間を消費しているのか計測しないうちから最適化するな」という意味合いの言葉があるけど正にその通り。思い込みって怖いな。

さて、/lib/modules以下に何があるのか?

% ls /lib/modules
...
drwxr-xr-x 3 root root 4.0K May 18 20:54 4.19.42+/
drwxr-xr-x 3 root root 4.0K May 18 20:54 4.19.42-v7+/

とまぁ、こんな感じで過去から現在最新版に至るまでのkernel modulesを収めたdirectoriesがある。古いのは4.9.Xとか4.14.Xなんてのがずらりと並んでいた。

1つのversionに対応するpairで100MiBちょっとあるので、うっかり消し忘れていると膨大な領域が消費され続ける (今回は8Gぐらいだったので、80弱のversionが残っていたようだ)。

なお、最新版と1つ前 (念のため)だけ残して全てrmした後は:

% du -hc /lib/modules
...
229M /lib/modules
229M total

全体で見ても:

% df -h
...
/dev/root        29G  4.5G   23G  17% /
...

rpi-updateでよくupgradeを行う方は注意されたい。