2016年12月26日月曜日

helm-recentf-directoriesの修正

(2017-10-04更新) migemoに対応した

(2017-06-14更新) helmのupgradeに伴って(?)不具合が発生したのでcodeを修正。actionの定義が問題を起こしていたので関連部分を削除

helm-recentf-directoriesは、recentf listの中からdirectoriesを抽出し表示するfunction。

http://d.hatena.ne.jp/syohex/20120911/1347378503で紹介されていたcodeを便利に使わせて貰っているのだが、helmの更新で上手く動かない状態になっていた。

helm-imenu.elをベースに、きちんとした方法でsourceを作製する方法へ修正してみた。


(defun helm-recentf-directories-candidates ()
  "Make candidate list of recentf directories."
  (loop for file in recentf-list
when (file-directory-p file)
collect file))

(defclass helm-recentf-directories-source (helm-source-sync)
  ((candidates :initform 'helm-recentf-directories-candidates)
   (keymap :initform helm-find-files-map)
   (migemo :initform t)
   (action :initform 'helm-find-files-actions)))

(defvar helm-source-recentf-directories
  (helm-make-source "Recent Directories"
    'helm-recentf-directories-source))

(defun helm-recentf-directories ()
  "Alternative for helm-recentf that displays only directories."
  (interactive)
  (helm :sources 'helm-source-recentf-directories
:buffer "*helm recentf directories*"))


やっていることは:

* recentf-listからdirectoryな要素を取り出すfunctionを定義
* 以上のfunctionを候補とし、keymapとactionはfind-filesのものを流用したclassを作製
* helm-make-sourceに引き渡しsourceを作製
* sourceを使うfunctionを定義


2016年12月12日月曜日

Emacsのdiff-modeでdiff-hunk-prev/next等の挙動が変更された

diff-hunk-prevやdiff-hunk-nextといった、変更箇所間を移動するfunctionsにおいて、「header直下にあるhunkをskipする」よう挙動が変更された (@ commit 2c8a7e50d24daf19ea7d86f1cfeaa98a41c56085)。

例:

diff-modeで次のような表示があったとする (※1〜※3は場所の明示のためのマーク)

※1 diff --git a/path/to/changed/file b/path/to/changed/file
--- a/path/to/changed/file
+++ b/path/to/changed/file
※2 @@ -343,5 +343,10 @@
...HUNK 1...
※3 @@ -451,1 +451,3 @@
...HUNK 2...


最初のcursor positionが※1の時、従来はdiff-hunk-next ("n")で※2 → ※3と移動していた。しかし、今回の変更により※2は最初のhunkなのでskipされ、いきなり※3に飛んでしまう。

diff-hunk-prevも同じで、header直下のhunkはskipされるのがdefaultの挙動となっている。

何が問題か?


diff-modeで、具体的にどこが変更されたのかをわかりやすくする為に、diff-auto-refine-modeを設定している。これは、wdiffのように文字単位での変更を色付けしてくれるのだが、処理速度の問題からdiff-hunk-prevやdiff-hunk-nextでそのhunkをvisitした際に色付けされる仕組みである。

従って、今回の挙動変更によりheader直下の@@部分へのjumpがskipされると、diff-refine-hunkが適用されずに困る。

解決法

diff-hunk-next, diff-hunk-prevなどのoptional argumentsの一つであるskip-hunk-startにnilを渡して呼び出せば従来の挙動に戻る。

1. lambdaを使う

(with-eval-after-load "diff-mode"
  ;; diff-hunk-next
  (define-key diff-mode-shared-map "n"
    (lambda (&optional count)
      (interactive)
      (diff-hunk-next count nil)))
  ;; diff-hunk-prev
  (define-key diff-mode-shared-map "p"
    (lambda (&optional count)
      (interactive)
      (diff-hunk-prev count nil))))

2. オレオレfunctionを定義しkeybindする

(with-eval-after-load "diff-mode"
  (defun my-diff-hunk-next (&optional count)
    (interactive)
    (diff-hunk-next count nil))
  (defun my-diff-hunk-prev (&optional count)
    (interactive)
    (diff-hunk-prev count nil))
  ;; key bindings
  (define-key diff-mode-shared-map "n" 'my-diff-hunk-next)
  (define-key diff-mode-shared-map "p" 'my-diff-hunk-prev))

3. 気に入らない挙動を修正する

  • adviceを使う?
  • noflet, dfletあたりを使う?

2016年10月23日日曜日

Debian unstableのgcc-6 6.2.0-7以降でLinux kernelなどのbuildができない件への対処 (2016-12-03更新)

Debian unstableのgcc-6は、6.2.0-7から--enable-default-pieというflag付きでbuildされており、これがあちこちで問題を引き起こしている。

cf. https://bugs.debian.org/cgi-bin/pkgreport.cgi?package=gcc-6

影響を受けているのはLinux kernelやSeaBIOSなど。

今の所backoutされる予定はなさそうなので、upstream (kernel側)で対応する迄は以下のworkaroundで我慢するか、自前でgcc-6 (6.2.0-6)をbuildするしかない。

Linux kernelのbuild

(2016-12-03追記)

Linux kernel 4.8.11でDebianのGCCで行われた変更に対応した。よって、それ以降のversionを利用する場合以下のworkaroundは不要。

stack protectorをenableにしていると:

> -fstack-protector not supported by compiler

と出てbuildが止まったり、そうでなくても:

> error: code model kernel does not support PIC mode

と出てbuildが止まったりする。

何れも、KCPPFLAGS=-fno-picをmake-kpkgあたりに渡してbuildするというworkaroundが紹介されている (cf. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=841533)。

著者の環境ではworkaroundによりmake-kpkgでkernelがbuildできた。

ccache userへ


FirefoxやEmacsのbuildにも影響が出た。

一旦、ccache -C -zでcacheを破棄してrebuildすると良い。


ZoL (ZFS on Linux)

(2016-10-28追記)

ZoLはkernel modulesとしてbuildする関係から、もろにこの変更の影響を受ける。しかも、KCPPFLAGS=-fno-picを渡しても./configure scriptが途中でコケる。

(2016-12-03追記)

SPLもZFSも正常にbuildできるようになった。

それがGCC側の変更なのか、kernel sourceのupgradeの結果なのかは切り分けられなかった。

2016年10月5日水曜日

PulseAudio w/o systemd

以前、ffmpegでsound cardからのrecordingを取り扱ったが、systemdを排除した場合に変化が生じたのでメモ。

無論、以下のcommand lineで示すのは著者の環境に固有のものである。

以前:

% XDG_RUNTIME_DIR=/run/user/1000 ffmpeg -f pulse -ac 2 -ar 44100 -i alsa_input.pci-0000_00_1f.3.analog-stereo -acodec libvorbis -q 3 output.ogg

以降:

% ffmpeg -f pulse -ac 2 -ar 44100 -i alsa_input.pci-0000_00_1f.3.analog-stereo -acodec libvorbis -q 3 output.ogg

systemdを排除した場合、XDG_RUNTIME_DIRを設定しているpam_systemdも排除されるので、この指定が不要になる。というか/run/userが作られないのでerrorになる。

2016年9月24日土曜日

ZoLでZFSのdiskをmountする

zpool createでpoolを作製すると自動でmountされるが、これをexplicitに行う方法。


  • zfs importでimport可能なpoolを検出
  • zfs import <pool>で実際にimportを行う。このcommandが完了するとmountも行われる


PostgreSQL 9.5→9.6へupgradeに伴うMediaWikiへの影響と対策

Debian Sidで、PostgreSQLが9.5→9.6にupgradeされた。MediaWikiをPostgreSQL +textsearch_jaで使っている人は、clusterのupgradeをする前にtextsearch_jaのinstallが必要。

Upgrade手順の概要


  • database clusterのbackupを取る
  • (aptitudeとかで) PostgreSQLをupgrade (今回は9.5→9.6)
  • PostgreSQLやweb serverなどを停止
  • textsearch_jaを9.6のdevelopment filesでrebuild & install
  • pg_upgradeclusterでclusterをupgrade
  • textsearch_ja.sqlを修正し、対象databseに適用
  • web serverなどをstart
  • MediaWikiの動作確認
  • 古い (9.5の)clusterをdrop

実際にいろいろとやってみた結果、上記の手順なら不具合が出ないか少なくて済むと思う。

なお、以下の個別の詳細手順については↑とは一致しない。というのも、aptitudeでupgradeすると、9.6がinstallされた時点でserverが9.6の空cluster+port 5433でstartしてしまっているから。

PostgreSQLのupgrade

PostgreSQLそのもののupgradeに関しては/usr/share/doc/postgresql-9.6/README.Debian.gzを参照のこと。

ざっくりまとめると、install scriptによって新しいversion (9.6)の空っぽのclusterが自動で作られるので、それをdropしてから古いversion (9.5)のclusterを9.6にupgradeしてね、ということ。

pg_dropcluster 9.6 main
pg_upgradecluster 9.5 main

なお、不要になった古いversionのclusterは、変換したclusterが正常であることを確認した後に削除して良い。

portの修正

この時点で9.5のserverがport 5432を使っていたため、9.6のserverはport 5433を使ってしまった。/etc/postgresql/9.6/main/postgresql.confにportの設定があるので、これを5432に修正しておく。

portが変更されたままだとphp-fpmとかがPostgreSQLを見付けられなくなる。

MediaWiki関連のupgrade

textsearch_jaの更新

MediaWikiで全文検索できるようにするため、PostgreSQLで日本語の全文検索を行うためのtextsearch_jaをinstallする。SourceからbuildするのにPostgreSQLのdeveloment packageが必要なのでpostgresql-server-devをinstallしておく。

textsearch_jaのdirectoryにて:

make PGXS_USE=1
sudo make PGXS_USE=1 install

これで/usr/share/postgresql/9.6/contrib/あたりに関連filesがinstallされる。

※この手順が終わるより前にpg_upgradeclusterを実行すると、functionが見付からないとかでMediaWiki関連のdatabaseでerrorが大量に出る。

textsearch_jaの適用

MediaWikiが使用しているdatabaseにtextsearch_jaをinstallする。しかし、その前にPostgreSQLの仕様変更に伴う修正をtextsearch_ja.sqlに行う必要がある。

具体的には"LANGUAGE 'C'" → "LANGUAGE c"に全て変更する。

cf. http://stackoverflow.com/questions/12514664/postgresql-procedural-language-c-not-found

修正後、

psql -f /usr/share/postgresql/9.6/contrib/textsearch_ja.sql <database>

既にfunctionがあるとかでerrorが出る場合は、一旦

psql -f /usr/share/postgresql/9.6/contrib/uninstall_textsearch_ja.sql <database>

を実行してから、あらためてやりなおす。


2016年9月9日金曜日

GCC 5.x → GCC 6.xへ完全移行 @Debian Sid

Debian GNU/Linux Sidではしばらく前にdefaultのGCCが5→6になったのだが、Firefoxのbuildに不具合がありGCC 5.xを残してあった。

今日、Firefox 49 (release)をbuildしてみた所、mach packageがうまくいかない不具合が解消されていたので、晴れてGCC 5 seriesをuninstallした。

helm-swoopのwindowを下部にfull widthで表示する

動機


Full HD (1920x1080)のLCDを使っている関係で、Emacsを縦に3分割 (こんな感じ → [||])している。

この使い方だと、複数のbuffersの内容を参照できて便利だ。一方で、window widthが2分割に比べて狭くなるので、helm関連のwindowでは一度に表示できる情報量が減ってしまう。

特に困るのはhelm-filelist+のように1行の情報量が多いbufferを表示する時で、これを解決するためにhelm関連windowはframeのwidthいっぱいに表示する設定をしている。

(add-to-list 'display-buffer-alist
     `(,(rx bos "*helm" (* not-newline) "*" eos)
       (display-buffer-in-side-window)
       (inhibit-same-window . t)
       (window-height . 0.4)))

cf. https://www.reddit.com/r/emacs/comments/345vtl/make_helm_window_at_the_bottom_without_using_any/

しかし、helm-swoopのwindowには何故か適用されず困っていた。

原因と対策


helm-swoopはbufferを表示する際に何らかの理由でhelm標準となっているfunctionを使っていないらしく (おそらくはswoop.elとの兼ね合いか、helmの更新が早過ぎて書き換えられていないか)、これを変更すれば他のhelm関連windowと同じ設定にできる。

(setq helm-swoop-split-window-function
      '(lambda (buffer)
         (helm-default-display-buffer buffer)))

なお、spacemacsで同じ疑問と回答が掲載されており、それを参考に以上の設定を行った。

cf. [How do I make helm-swoop to open at bottom with full window width? · Issue #4117 · syl20bnr/spacemacs · GitHub](https://github.com/syl20bnr/spacemacs/issues/4117)


2016年9月8日木曜日

Linux kernel 4.8-rc4でZoL (2016-12-26更新)

ZFS on Linux (ZoL)を試してみたいと思い、Linux kernel 4.8-rc4 (注: 9/8現在の最新版は4.8-rc5)で実験してみた。

(2016-12-26追記)

Linux kernel 4.9.0でも利用可能。

(2016-12-03追記)

Linux kernel 4.8.12でも以下の手順でZoLを利用可能。

Installation

Debian package版ではbuildに失敗した (確か9/8現在で対応しているkernel versionは4.6が最新)ので、gitから直接build & installする。

まずはSPL (Solaris Porting Layer)から:

% git clone https://github.com/zfsonlinux/spl.git
% cd spl
% ./autogen.sh
% make
% sudo make install

ZFSも手順は同じ:

% git clone https://github.com/zfsonlinux/zfs.git
% cd zfs
% ./autogen.sh
% make
% sudo make install

これで、spl.koやzfs.koなどのkernel modulesや、zfs、zpool、zdb commandsなどがinstallされるはず。

もしかしたら、buildの際にlibzfsとかのdevelopment package (header file)が必要かも知れない。

Pool作り

まず、zfs関連のkernel moduleをmodprobeして突っ込む。

% sudo modprobe zfs

多分、自動的にdependencyが解決されてsplとかも突っ込まれるはず。

% lsmod | grep zfs

あたりでcheckする。

% sudo zpool create -o ashift=12 -f -m <mount_point> <pool> <disks>

Poolが作られると自動的にmountされる。

ちなみに、最近のHDDはAFTを使っていると思うのでその場合はashift=12を指定すると速くなるとのこと。

zdbが"no such file or directory"を吐く問題

必要な(?) cache fileがgenerateされていないのが原因っぽい。Package systemとかDKMSとかで入れれば何かしらのscriptで自動生成されたりするんだろうか?

% sudo mkdir /etc/zfs/
% sudo zpool set cachefile=/etc/zfs/zpool.cache <pool>

これでgenerateされたので、後は好き放題zdbを使えるはず。

% sudo zdb -C -U /etc/zfs/zpool.cache <pool>

でも、

% sudo zdb -S -U /etc/zfs/zpool.cache <pool>

でもissueし放題。

cf. [FAQ · zfsonlinux/zfs Wiki · GitHub](https://github.com/zfsonlinux/zfs/wiki/faq)

In-band deduplication

ZFSを使う利点 (というか動機)にもなるであろうdeduplication (重複排除)だが、

どんなdataを抱えているかにもよるが、一度zdb -Sでどのくらい節約できるかを見てみると良い。ratioが2を割るようであれば無駄かなと。何しろ仕組み上ものすごく時間が掛かるし、diskに負荷も掛かるので。

cf. [How To Size Main Memory for ZFS Deduplication](http://www.oracle.com/technetwork/articles/servers-storage-admin/o11-113-size-zfs-dedup-1354231.html)

2016年9月3日土曜日

Mercurialのhg histeditでやらかした時、unbundleで元に(近い状態に)戻す

概要

Mercurial (以下hg)には、履歴を改編する為のhisteditという拡張がある。

履歴を見易く綺麗にするには便利なのだが、うっかり「やらかして」しまったので、その顛末について残しておく。

やらかした内容


  • 関連のあるchangesetをまとめるためにhg histeditを実行した
  • 順序を変える必要があるのを忘れてうっかりeditor (vim)を終了
  • commit logの変更に進んでしまい、そこで:q!を実行してabortしたつもりがhisteditが実行された

復旧の手順


  • hg unbundleを使い、histeditを実行した際に保存されているbackup (bundle file)から復旧する
  • 実行するとheadsが2つに増えた。この状態でhisteditは使えないので、一旦rebaseして履歴をlinearにする
  • histeditを改めて実行して、commitを意図した順に並び換えた上で、不要なcommitをdrop

最後に


  • やらかしても慌てない
  • 自動backupと、hg unbundleは救世主 (間違ってstripした場合とかも戻せる)


2016年8月17日水曜日

Scientific calculatorsにおけるcomplex numbersの扱い

Complex numbersを扱える手持ちのscientific calculatorsについて。


  • SwissMicros DM15L (HP 15Cのclone)
  • HP 35s
  • WP 34S
  • HP 50g (正確にはGraphing calculator)
  • (参考) Maxima (代数処理システム)


Complex numbersの扱い・利点と欠点

DM15L (HP 15C)


  • 初期状態ではReal mode
  • Re, Imの順にstackに積み[I]でcomplex stackに変換するとcomplex mode発動
  • 以降のoperationはcomplex mode

pro

  • Re, Imの入力順が直感的で分かり易い

con


  • 1行しか表示できないのでImを確認するには[(i)]を押す必要がある (もしくは[Re←→Im])
  • Complex number非対応のfunctions (!とか)はimaginary part (Im)を無視する

HP 35s


  • Real / Complex modeの区別なし
  • [i] keyがあり、1i2のように直感的に分かり易く入力/出力される
  • Real part (Re)とImを1つのregisterにセットで扱う

pro


  • 複素数の入力が楽
  • 表示が分かり易い

con

  • 四則演算やy^x、trigonometric functionsは普通に扱えるが、その他の演算に制約が多い (随所で「complex numberの扱いが中途半端」と言われる所以)
  • √x → x^(1/2), y√x → x^(1/y), LOG → ln(x)/ln(10) で代用可能なので、どうして等価なoperationで"invalid input"を吐くのかがよくわからない
  • ASIN, ACOS, ATANは"invalid input"かつ代用手段なし (多分)

WP 34S


  • Real / Complex modeの区別なし
  • Y registerをIm、X registerをReとして扱う
  • [CPX] prefix keyを押してfunctionにcomplex numberだと伝える (=2つのregistersを組み合わせて1つのcomplex numberとして扱うよう指示する)

pro


  • Complex number固有の操作は[CPX]をprefixすることのみなので、特別な操作を覚えなくて良い、操作に一貫性がある
  • [CPX] prefixをつければcomplex numberとして、つけなければ普通のreal numberとして扱える
  • X registerとY registerを表示するmodeがあるので確認が楽
  • Stackを8段modeにしておけば4つのcomplex numberを積んでおける

con


  • 一々[CPX]を押すのが面倒。Stack operationとかの際はうっかり忘れがち

HP 50g


  • Rectangular modeでは(1,2)と書く ※ = 1 + 2i
  • [i] keyもあるが↑の方が楽
  • とにかくたくさんstackに積んでおける
  • functionsも豊富にある

Maxima (おまけ)


  • 1 + 2 * %i; みたいな感じで書く




2016年7月7日木曜日

SwissMicros DM15Lのfirmware upgrade (2018-09-05更新)

(更新履歴)

* 2020-01-17: V30が公開された
* 2019-06-05: V29が公開された
* 2018-09-05: V27が公開された
* 2018-03-26: V26が公開された
* 2017-12-26: V24が公開された
* 2017-06-14: V23が公開された

(更新履歴ここまで)


2016-03-03にSwissMicros DM15L (RPNなscientific calculatorであるHP-15Cのclone)のfirmware V21が公開されていたことに今更気付いたのでupgradeしてみた。

必要な道具やsoftware


DM15Lのfirmware upgradeをLinux boxで行うには、以下の準備が必要:

* Linux kernelに"CP201x USB to UART Bridge VCP driver" (3.3以降in-tree)を組み込む
* lpc21ispをinstall (In-circuit programming (ISP) of ARM and Cortex microcontrollers)
* Latest firmware (自分の場合はDM15_M1B_21.hex)をdownload

DM15L側は:

* 背面のRESET buttonを押す為の爪楊枝
* PCとDM15Lを接続する為のUSB cable (多分Type-A 〜 mini-B)

環境

(2016-03-03)

* Linux box (ASUS X200LA)
* Linux kernel 4.6.3
* Debian GNU/Linux Sid
* SwissMicros DM15L (DM15 M1B V19)

(2017-06-14)

* Linux box (Shuttle SZ170R8)
* Linux kernel 4.11.3
* Debian GNU/Linux Sid
* SwissMicros DM15L (DM15 M1B V21)

手順


https://www.swissmicros.com/firmware.phpの"Firmware upgrade under Linux"に解説されている。

Upgrade操作により、DM15L内のprogramやregisterの内容は消えてしまうので注意。ただ、firmware upgradeに失敗してもDM15Lが使えなくなったりはしない (所謂「文鎮化」しない)とのこと。

> Don't worry, it is not possible to break or brick the calculator with this or any other upgrade procedure.

実際の手順


* Linux kernelにCP210x USB to UART Bridge VCP driverを組み込む
  + Device drivers → USB support → USB Serial Converter support → USB CP210x family of UART Bridge Controllers
  + Kernelをrebuild → installしてreboot
* Latest firmwareをdownload
* USB cableでDM15LとLinux boxを接続
* dmesgで確認すると/dev/ttyUSB0とかそれっぽいdeviceが検出されているはず
* sudo lpc21isp DM15_M1B_V21.hex /dev/ttyUSB0 115200 12000
* "Synchronizing"とmessageが出ている間にDM15Lの背面にあるRESETを押す
* flashが終わったらcableを外してもう一度DM15LのRESETを押す

(2017-06-14追記)

DM15Lはこんな感じで認識された:

% dmesg
...
[695628.530638] usb 1-5: new full-speed USB device number 9 using xhci_hcd
[695628.700180] usb 1-5: New USB device found, idVendor=10c4, idProduct=ea60
[695628.700181] usb 1-5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[695628.700183] usb 1-5: Product: CP2102 USB to UART Bridge Controller
[695628.700183] usb 1-5: Manufacturer: Silicon Labs
[695628.700184] usb 1-5: SerialNumber: 0001
[695628.709685] usbcore: registered new interface driver cp210x
[695628.709692] usbserial: USB Serial support registered for cp210x
[695628.709707] cp210x 1-5:1.0: cp210x converter detected
[695628.711611] usb 1-5: cp210x converter now attached to ttyUSB0

実際の手順のlog (firmwareは~/Downloadsにある)

% sudo lpc21isp Downloads/DM15_M1B_23.hex /dev/ttyUSB0 115200 12000
lpc21isp version 1.97
File Downloads/DM15_M1B_23.hex:
        loaded...
        converted to binary format...
        image size : 39283
Image size : 39283
Warning:  data not aligned to 32 bits, padded (length was 9973, now 9974)
Synchronizing (ESC to abort).......... OK
Read bootcode version: 2
7
Read part ID: LPC1115.../303, 64 kiB FLASH / 8 kiB SRAM (0x00050080)
Will start programming at Sector 1 if possible, and conclude with Sector 0 to ensure that checksum is written last.
Erasing sector 0 first, to invalidate checksum. OK
Sector 1: ...............................................................................................
Sector 2: ...............................................................................................
Sector 3: ...............................................................................................
Sector 4: ...............................................................................................
Sector 5: ...............................................................................................
Sector 6: ...............................................................................................
Sector 7: ...............................................................................................
Sector 8: ...............................................................................................
Sector 9: ...........................................................
Sector 0: ..............................................................................................
Download Finished... taking 6 seconds
Now launching the brand new code

Documentされていなかった事柄


DM15LのRESETを押すと最後に"PR Error"が出るが、これは"HP-15C Owner's Handbook"にある通り正常な反応。一度offにしてもう一度電源を入れ直すと正常に使える。ちなみに"PR Error"はprogram errorではなくてpower error。

> Pr Error
> Continuous Memory interrupted and reset because of power failure.

cf. 208 Appendix A: Error Conditions - HP-15C Owner's Handbook

2016年6月24日金曜日

Emacsのshow-paren-match-faceがremoved

emacsのgit versionを使っているのだが、今日のupdateでshow-paren-match-faceが削除された。

commit c430f7e23fc2c22f251ace4254e37dea1452dfc3
Author: Mark Oteiza <mvoteiza@udel.edu>
Date: Thu Jun 23 17:13:11 2016 -0400
Remove some face aliases obsoleted in 22.1
...
* lisp/paren.el (show-paren-match-face, show-paren-mismatch-face):
...
以下のように、show-paren-matchを設定すれば良い:

(set-face-attribute 'show-paren-match nil
   :background 'unspecified
   :underline "turquoise")

2016年6月1日水曜日

Linux kernel 4.7-rc1をmake-kpkgでbuildする

概要

Linux kernel 4.7-rc1がreleaseされたが、buildでコケた。

Build environment

* Intel Core i7-6700K + DDR4 64GByte
* Debian Sid / Experimental
* gcc.real (Debian 6.1.1-4) 6.1.1 20160519
* Linux 4.7-rc1 (from Git)
* time (MAKEFLAGS= DEBIAN_BUILDARCH=native CONCURRENCY_LEVEL=8 CC='ccache gcc' CXX='ccache g++' fakeroot make-kpkg --initrd kernel_image)

error message

いつも通り、早速make-kpkgでbuildを試みたのだが、見事にコケた:

>   CC      arch/x86/boot/edd.o
> /tmp/ccENSHy1.s: Assembler messages:
> /tmp/ccENSHy1.s:35: Error: instruction `shlx' isn't supported in 16-bit mode.
> /tmp/ccENSHy1.s:39: Error: instruction `andn' isn't supported in 16-bit mode.
>   CC      arch/x86/boot/main.o
> scripts/Makefile.build:289: recipe for target 'arch/x86/boot/cpucheck.o' failed
> make[2]: *** [arch/x86/boot/cpucheck.o] Error 1
> make[2]: *** Waiting for unfinished jobs....

見ての通り、16bit modeでsupportされていないinstructionが使われている。

workaround

arch/x86/以下にあるcodeは-m32でcompileされるんじゃないのかな?と思い、関係しているであろうarch/x86/boot/Makefile@68を編集 (-m32を追加):

KBUILD_CFLAGS   := $(USERINCLUDE) $(REALMODE_CFLAGS) -D_SETUP
KBUILD_CFLAGS   := $(USERINCLUDE) $(REALMODE_CFLAGS) -D_SETUP -m32

これでbuildは通ったが、本当にこんなworkaroundで大丈夫なのかは不明。

ちなみに、Linux 4.6では全く同じ環境でbuildが通っているので、Linux 4.7で色々変わった関係だろう。

2016年5月5日木曜日

ASUS X200LAのFocaltech touchpadがうまく動かなくなった件

概要

  • Debian SidでX関連packageの変更?によりsynclientが動かなくなった
  • /etc/X11/xorg.conf.d/以下にsynaptics関連のfileを配置したら直った

不具合とworkaround

以前のpostで、ASUS X200LAに搭載されているFocaltech touchpadをsynclientで設定すると使いやすくなると書いたが、Linux kernelのupgradeに際してrebootした後、tapなどが動作しなくなっていることに気付いた。

何かの拍子に設定が戻ったのかとsynclient -lで設定を確認してみようとしたら"Couldn't find synaptics properties. No synaptics driver loaded?"を吐く。~/.xsessionにtouchpadを設定する一連のcommandsを書いているので、synclientのこのerrorのせいで動作がおかしくなっている。

当初はkernelを疑って以前のversionに戻したり、幾つかkernel optionsを弄ってみたが関係ないと分かった。

結局、cp -i /usr/share/X11/xorg.conf.d/50-synaptics.conf /etc/X11/xorg.conf.d/を実行した後にXをrestartしたら解決した。よくわからないが、Linux kernelではなく、X側の設定で何かしら変更があったようだ。

参考リンク




2016年4月21日木曜日

GCC 6でbuildできる/できないリスト (2016-04-20現在)

概要


Debian experimentalに入っているGCC 6でbuild可能/失敗するものの一覧。勿論、自分がbuildしてみたものだけ。

成功


  • Linux kernel (4.6-rc4)
  • Emacs
  • FFmpeg
  • mpv
  • MPlayer
  • VLC
  • Mesa
  • xf86-video-intel
  • drm
  • DeaDBeeF
  • Stellarium
  • Zsh


失敗


  • Firefox
  • Glibc


どちらもwarningをerror扱いするoptionのせいでbuild stop。

2016年4月20日水曜日

cmigemoで複数の辞書を使う

概要


C/Migemoは複数の辞書を扱える便利な機能がある。但し、Emacsからmigemo.elを通して使う時には少々fileに細工する必要がある。

C/MigemoとRuby/Migemoの違い


man cmigemoすると明らかな通り、cmigemoはmain dictionaryに加えて、最大8つのsub dictionariesを指定できる。こんな感じ:

cmigemo -s <SUB_DICTIONARY_1> -s <SUB_DICTIONARY_2> ... -s <SUB_DICTIONARY_8> -d <MAIN_DICTIONARY>

Sub dictionariesの何が便利なのかと言えば:

  • mainの辞書を弄るほどでもない内部的なentryを好き放題追加できる
  • mainの辞書とは別にrevision controlしたり配布したりできる

例えば、cmigemoに付属のmigemo-dictをmainとして、それを補完する2つのsub dictionariesを指定すると:

cmigemo -q --emacs -s /home/user/.emacs.d/migemo/migemo-dict.user -s /home/user/.emacs.d/migemo/migemo-dict.sub -d /home/user/.emacs.d/migemo/migemo-dict

この例ではsub dictionariesとしてmigemo-dict.subとmigemo-dict.userの2つを指定している。

Emacsから複数辞書を活用する


複数辞書を指定する場合、Emacsでmigemoを使うためのmigemo.elには細工が必要。

migemo.elは、cmigemoを呼び出すcommand lineを組み立てているのだが、そこでcmigemoに与えているoptionが実はRuby/Migemoのもので、そのままではsub dictionariesを指定できない。2016年現在実際に利用されているのはC/Migemoだけだと思うんだが……。

具体的にはmigemo-initの内部でuser-dictionaryを指定する部分の"-u"及びregex-dictionaryを指定する部分の"-r"をそれぞれ"-s"に設定し、migemo-user-dictionaryとmigemo-regex-dictionaryをそれぞれsub dictionariesのabsolute pathに変更すれば良い。

3つ以上のsub dictionariesを使いたい場合は、非常にダサい実装だが、migemo-sub-dictionary-1〜8を定義し:

(when (and migemo-sub-dictionary-1
           (file-exists-p migemo-sub-dictionary-1))
  (list "-s" migemo-sub-dictionary-1))

を8回copy'n'paste (-1〜-8に変更しつつ)すれば動く (と思う)。

勿論、loopとかmapとかを使ってsmartに書きたい所。

2016年4月13日水曜日

Emacsのimenuをmarkdownで活用する

imenuとは

Emacsには、構造化されたtextの目次を表示しそこへジャンプするimenuという機能がある。

Textによって「目次」とすべき内容が異なるので、imenuにはtextに応じたindexingを行うfunctionを渡せるように作られている。

imenuはprogramming languageには勿論、HTMLやMarkdownのようなtextにも応用できる。

markdown-modeにおけるimenu

markdown-modeはindexを作製するfunctionを2種類提供してくれている:

  • markdown-imenu-create-flat-index
  • markdown-imenu-create-nested-index

この2つの違いはfunction nameそのままで、flatの方はtreeのleaf nodeのみを列挙するのに対し、nestedは言わばleaf nodeへのfull pathを列挙する。

Defaultではflatがimenu-create-index-functionにbindされているので、markdown-modeのhookを使ってnestedをbindすればそちらを利用できる。


実際の活用に際して

imenuはそのままでは使いにくいので、helm-imenuを使うと良いだろう。

この際、which-function (which-funcはobsolete)で現在位置を表示させるのも便利だ。


Indexの実例

# H1
## H2-1
### H3-1
### H3-2
## H2-2
### H3-3

のようなMarkdown textがあるとする。


flat-index

H1
H2-1
H3-1
H3-2
H2-2
H3-3


nested-index

H1 / .
H1 / H2-1 / .
H1 / H2-1 / H3-1
H1 / H2-1 / H3-2
H1 / H2-2 / .
H1 / H2-2 / H3-3

参考Link




個人的にemacsを使う理由

個人的にemacsを日本語文書の記述や編集に使っている。

大きな理由は:

* DDSKK → 日本語入力
* helm (特にhelm-filelist+) → 最近開いたfileをincrementalに絞り込み
* auto-save-buffers-enhanced → 自動save
* migemo → ローマ字で日本語検索
* helm-swoop → 検索語をlistして一覧 & jump

今の所emacs以外でこれらを実現できる環境はなさそう。

あと、fileを開いた時にbufferをview-modeで開くhookを仕込んでいるので、半ばViみたいな使い方になっている。

ちなみに、設定ファイルとかプログラムの記述とかには専らVimを使っている。

2016年3月28日月曜日

PulseAudioのloopback moduleを使う

Loginした時にmodule-loopbackがloadされるように設定した。

  • /etc/pulse/default.paをcopyする
  • loopback moduleの設定を加える

具体例

motherboard内蔵のIntel HD Audioで、line-in → line-outへ音声を流す設定 (~/.config/pulse/default.paの最後の部分):

> ...
> ### loopback
> .ifexists module-loopback.so
> load-module module-loopback source=alsa_input.pci-0000_00_1b.0.analog-stereo sink=alsa_output.pci-0000_00_1b.0.analog-stereo
> .endif

module-loopbackへのparamterはsourceが入力元、sinkが出力先。これらはindex numberか (長い) unique nameで指定できる。Deviceの認識順とかでindexは変化するみたいなので、nameで指定しておいた。

unique nameやindexはpactl listやpacmd list-sources、pacmd list-sinksで表示できる。

参考リンク


Debian Sid + Linux 4.6-rc1でPlanex GW-450D KATANAを使う

Google等で検索すると既に様々な方が実施されているのだが、GCC 6だからなのか、それともLinux kernelが4.6rc1だからなのか、そのままではdriverがbuildできなかったのでメモしておく。

全体の流れ

  • x86_64対応のdriverをdownloadし展開して修正する
    • tarballを展開するかgit clone
    • Makefileに変更: CHIPSETへ追加、LINUX_SRCの変更
    • common/utusb_dev_id.cへUSB_DEVICE_ID追加
    • conf/RT2870STA.datを修正
    • os/linux/config.mkを修正 (-Wno-error=incompatible-pointer-types)
    • os/linux/rt_linux.cを修正 (__vfs_read, __vfs_writeへ変更)
  • Kernelの修正とrebuild (CONFIG_WIRELESS_EXT=y, CONFIG_WEXT_PRIV=y)
  • buildしてinstall
    • make
    • make install (もしくは手動でcopy)
    • depmod -a
  • Debian specificなnetworkの設定 (or NetworkManagerやwicdで設定する)
    • /etc/Wireless/RT2870STA/RT2870STA.datの調整
    • /etc/networking/interfacesの変更
    • modprobe mt7650u_sta
    • service networking restart

今回遭遇した問題

主にdriverのbuildに際して問題があった。

  • incompatible-pointer-typesのwarningがerror扱いされてbuildが止まる
  • net_device、iw_handler_defなどstructの初期化を行う部分でerrorが出る

incompatible-pointer-types対策

1つ目のincompatible-pointer-typesに関しては、gccに-Wno-error=incompatible-pointer-typesを渡して見逃してもらった。os/linux/rt_linux.cのWFLAGSに直接書き込むという力技を使ったが、たぶんもっと適切な場所 (もしくは方法)があると思う。

unknown field対策

2つ目のstructの初期化 (designated initializer)に関しては、kernel moduleとしてbuildする際に見ているLinux kernelの設定に問題があった。

具体的には"error: unknown field 'private' specified in initializer"といったerrorが出るのだが、kernel sourceの側で必要なsymbolを有効にしていないのが原因だった。必要なのはCONFIG_WIRELESS_EXTとCONFIG_WEXT_PRIV。

これらはmake menuconfigで'/'を使って調べると出て来るが、依存関係の問題なのか有効にできなかったのでnet/wireless/Kconfigを直接編集して対応。make oldconfigを実行して.configに2つが=yで出力されているのを確認して、kernelをrebuild & install。

以上でdriver (mt7650u_sta.ko)をbuildできる。

Pitfalls


  • 普段楽をしてmake-kpkgでkernel packageをbuildしているので、driverをinstallした後にdepmod -aを忘れていた
  • SSIDがstealthなので/etc/networking/interfacesあたりにap_scan=1とかssid_scan=1を設定する必要があった

追記

Rebootが必要とあるが、本当に必要なのはkernelでCONFIG_WIRELESS_EXTとCONFIG_WEXT_PRIVが有効になっていない場合に新しくbuildしたkernelに切り替える時だけで、後はservice networking restartとかmodprobe (-r) mt7650u_staでどうにかなる。


参考リンク

Driverのsource code


GW-460DをLinuxで使う方法について



Buildに必要なLinux kernelの設定について


/etc/Wireless/RT2870STA/RT2870STA.datの読み込みに失敗する問題への対策


Cのdesignated initializerについて




2016年3月27日日曜日

Linux kernel 4.6-rc1をdebianでbuildする

Linux kernel 4.6-rc1がreleaseされたので、早速make-kpkgでbuildしようとしたら……

> In file included from arch/x86/decode.c:26:0:
> arch/x86/../../elf.h:22:18: fatal error: gelf.h: No such file or directory
>  #include <gelf.h>
>                   ^
> compilation terminated.

gelf.h……?

今までこんなerrorは出ていなかったので検索してみた所:

> I guess your system didn't install libelf library.

cf. [compiling error gelf.h · Issue #34 · ktap/ktap · GitHub](https://github.com/ktap/ktap/issues/34)

なる記述を発見。取り敢えずaptitudeでlibelf-devというpackageをinstallしたら解決した。

なお、Debian experimentalに入っているgcc-6 seriesで無事buildできたことを申し添えたい。

2016年3月10日木曜日

Debian GNU/LinuxでUSB3.0なGigabit Ethernet

LogitechのLAN-GTJU3というUSB3.0のnetwork adapterを使ってみた。

何故か100Mbpsまでしか有効にならず色々と試してみたのだが、switching hubのportを別の場所に変更したら1000Mbpsが有効になった。

理由はよく分からないが、想像するに、元々100Mbpsのadapterが接続されていたportだったので、switching hub側が「100Mbpsまで」と記憶していたのが問題なんじゃないかと。

2016年2月11日木曜日

再・emacs-gitのisearchでmigemoを利用可能にする

最近の更新でisearchからmigemoれないことに気付いた。

git logでlogを漁ってみたら、b3fc7a3e763fb260cd932dc6aedbe7b4c810a73cでsearch-default-regexp-mode (cf. http://typeinf-memo.blogspot.com/2015/11/emacs-gitisearchmigemo.html)がsearch-default-modeにrenameされたとある。これにnilをbindするとmigemoが使えるようになる。

(setq search-default-mode nil)

2016年1月31日日曜日

Linux boxでラジオ番組を自動録音する

*** 注意 (2018-12-09追記) ***

この記事は古いため以下の記事を参照されたい:

cf. [Linux boxでラジオ番組を自動録音する]

*** 注意ここまで ***

概要


やりたいこと


Linux boxのline-inに接続されているtunerから流れてくるラジオ番組を自動で録音したい

Solution


  • line-inから録音してOgg Vorbisにencodingするscriptを書く
  • cronに登録して定期的に走らせる

これだけのいたって簡単なお仕事……のはずがどうしてこうなった。

落とし穴と対策


  1. pipeしたprocessの殺し方にハマる
  2. cronのdefaultのshellは/bin/sh
  3. PulseAudio関連のprogramをcronから呼んだ時の挙動にハマる

対策としては:
  1. parec ... | oggenc ... の組み合わせではなくffmpegで録音する → 1、2
  2. 環境変数XDG_RUNTIME_DIRを渡す → 3

わかったこと


  • pipeでつないだprocessesの殺し方
  • parecの他にもffmpegで録音できる
  • PulseAudioを使う時は環境変数に注意

結論


こんな感じのscriptをcronで回している:

# 録音
XDG_RUNTIME_DIR=/run/user/1000 /usr/local/bin/ffmpeg -f pulse -ac 2 -ar 44100 -i
alsa_input.pci-0000_00_1b.0.analog-stereo -acodec libvorbis -q 3 "${FILEPATH}" &
RECPID=$!

# 録音停止
sleep ${DURATION}
kill -TERM ${RECPID}

補足


なお、ffmpegではdurationを指定できるので:

... /usr/local/bin/ffmpeg -f pulse -ac 2 -ar 44100 -i alsa_input.pci-0000_00_1b.0.analog-stereo -acodec libvorbis -q 3 -t ${DURATION} ${FILEPATH} &

とかでも良さそう。また、ffmpegのかわりにparecとoggencを組み合わせても良い:

parec --fix-format --fix-rate --file-format=raw --format=s16ne > >(oggenc -B 16
 -C 2 -q 3 -o "${FILEPATH}" - >/dev/null 2>&1) &

ただし、この方法 (process substitution)はbashやzshでないと使えないので注意が必要。因みに:

parec ... | oggenc ...

とpipeでつないでも良いが、この場合job単位でprocessesを殺す必要がある (kill %%とかで殺せる)ので少々面倒。

補足2


暫くの間:

XDG_RUNTIME_DIR=/run/user/1000 /usr/local/bin/ffmpeg -f alsa -ac 2 -ar 44100 -i
 pulse -acodec libvorbis -q 3 "${FILEPATH}" &

で運用していたが、これだとdeviceの認識順と共にdefaultのsourceが変わって、無音の状態になることがあった。そこでdeviceを限定するため以下のように変更:

XDG_RUNTIME_DIR=/run/user/1000 /usr/local/bin/ffmpeg -f pulse -ac 2 -ar 44100 -i
alsa_input.pci-0000_00_1b.0.analog-stereo -acodec libvorbis -q 3 "${FILEPATH}" &

おまけ


cronで実行したscriptの出力を見ようと思ったら/usr/bin/mailがsymbol lookup errorを吐いた。原因を追求していると本来の目的を忘れそうだったので、とりあえず/var/mail/以下のfileを直接読んで凌いだ。

また、Debian sidだと/usr/bin/mailは/etc/alternatives/mailへのsymlinkであり、これは更に/usr/bin/mail.mailutilsへのsymlinkで、如何なるpackageにも属していない。

参考URL



補足2関連