読者です 読者をやめる 読者になる 読者になる

2017年コンテンツメモ[固定]

  • 仮想通貨革命
  • エクサスケールの衝撃
  • 東京喰種 re: 1~11
  • D.Gray-man 1~34
  • ジョジョリオン 14
  • 星を継ぐもの
  • メイドインアビス 1~5
  • ソウルイーター 1~25
  • 人を動かす 新装版
  • 物理数学の直感的方法 <普及版>
  • 日本のいちばん長い日(決定版)
  • 体の中の異物「毒」の科学 ふつうの食べものに含まれる危ない物質

電源ゲーム

非電源ゲーム

映像

fishを使っているときにtmuxのwindow nameをコマンド履歴にしたい

サマリ

fishのfish_preexecイベントをフックして、tmuxのwindow nameをコマンド履歴に変えることができる。

はじめに

tmuxを使っていると、このwindowでは一体何をしていたんだっけという状況に陥ることがままある。 そういうとき、window nameが最後に実行したコマンドだと、何をしていたか思い出すのに役立つ*1

そんなことができるのか

以下の2つの材料から結構簡単にできちゃう。 ちなみに、"フックをかける"というのは、イベント発生時に何かコマンドが実行できるよ、って意味。

  • tmux rename-window <window name>でwindowの名前が変えられる
  • fishには、fish_preexecという、コマンド実行前にフックをかけられるイベントがある

どうするのか

fish_preexecイベントフックは、~/.config/fish/config.fishに書くのが作法らしい*2。 実際にはこんな感じになる。 tmuxを使っているときは、環境変数$TERMがscreenかtmuxになるので、そのときだけwindow nameを変えるコマンドを打つ。 あんまり長いコマンドを表示してもあれなので、16文字くらいで打ち止めするようにしている。

 # rename tmux window
 function window_rename --on-event fish_preexec
     if test -n (echo $TERM | grep -e screen -e tmux)
         tmux rename-window (printf "%.16s" $argv[1])
     end
 end

おわりに

fish_preexecイベントのおかげで、簡単にtmuxのwindow nameを動的に変えることができる。

雑感

  • fishの設定ファイルは人間に読みやすいのがよい。bashとの互換性はないけど、別にどうでもいいやという感。
  • fishは手入れが楽なのでありがたい

*1:気がする。既に慣れてしまってるのでよくわからん・・・

*2:ソースは失念

fishで手間をそこそこに使えるLinuxのシェル環境を作る

サマリ

  • fishは最悪設定ファイル書かなくても、そこそこ使えるので便利

はじめに

新しいことを覚えるのはなかなかに大変で、しかも普段使わないようなものに 労力を払いたくない人はきっと多いと思う。特に文字だけしか表示されない端末。

端末操作って見た目黒魔術っぽくて、何かとっつきにくいように思うかもしれない。 なんとなく覚えている範囲で不足なく使えるからどうでもいいやと思うかもしれない。 でも、どうせなら作業効率を上げて早く帰りたい、もっと楽をしたいと思う人もたくさんいるはずだ。

そんなあなた、特に以下に該当するあなたに、fishを導入することをおすすめしたい。

  • bashでひたすら↑キーを押して履歴を辿るが、なかなか期待の履歴までたどり着けない
  • lsに色がついていなくて見づらいんだけど、色付けするのに何をしていいのかよくわからない
  • .xxshrcが読みにくくてつらい思いをしている

fishについて

fishとは何か

いろいろ便利機能があるシェルで、設定をあまりしなくてもそれなりに整ったものが使えるのが特徴。 いろいろな便利機能とは、例えば以下。きっともっといっぱいあるけど、慣れてからでいい。

  • 何も設定しなくてもそれなりに整った見栄えを提供してくれる
  • lsに勝手に色がついている
  • 履歴を元にコマンドをサジェストしてくれる
  • 履歴を辿りやすい

fishをインストールしたい

UbuntuとかDebianだったら、aptで入る。CentOSのあなたは諦めてソースコードからビルドしろ。

$ sudo apt install fish

fishを使いたい

インストールが終わったら、単にfishと打てばいい。

サジェストされたコマンドを使いたい? コマンドを途中まで打つと履歴等々含めてサジェストしてくれるので、 Ctrl-Eか、→キーを押してくれれば確定する。

履歴を簡単に辿りたい? コマンドを途中まで打って、↑キーを押せば、そのコマンドの履歴だけ辿ってくれる。例えばこんな感じ。

# cdの履歴を辿る例:まずはcdと打つ
$ cd 

# 次に↑キーを押すと、cdの履歴が順繰りに出てくるので、使いたい履歴を引いたらエンターを押す
$ cd ../xxxx/xxxx/

[やる気のあるあなたへ] PATHにデフォルト以外のディレクトリを追加する

以下のコマンドを打つと、fishのほうでPATHに追加してくれる*1。 設定ファイルに書く必要はない(書いちゃダメ)。

set -U fish_user_paths <追加したいディレクトリ> $fish_user_path

[やる気のあるあなたへ] fishの見栄えを少し調整する(その1)

まあデフォルトでそれなりに使えるfishだけど、見栄えには好みがあるので、好みの見栄えになるように調整したい。 調整するには設定ファイルを書く必要があるので、"設定ファイルを書くくらいならそのままでいいや"のあなたは 飛ばしてくれればOK。

プロンプトは、"~/.config/fish/functions/fish_prompt.fish"というファイルで設定する。

僕は

  • ログインしているユーザ名とサーバ名を、色をcyanで常に出したい
  • カレントディレクトリは省略せずに、色を黄色で出したい
  • gitで管理中のディレクトリ内では、ブランチ名を出したい
  • コマンドの開始は、">“にしたい

といったような趣味があるので、設定ファイルとしてはこんな感じになる。

function fish_prompt
    set_color cyan
    printf "%s@%s " (whoami) (hostname)
    set_color yellow
    printf "%s" (pwd)
    set_color normal
    printf "%s " (__fish_git_prompt)
    printf "\n> "
end

この設定ファイルを使うと、こんな感じに表示される。色は正しく表示されていないので、各自で。。。

bisco@bisco-server /home/bisco/.config/fish/functions
> 

[やる気のあるあなたへ] fishの見栄えを少し調整する(その2)

gitのブランチ名だけだとちょっと物足りないので、状態(未コミットのファイルがあるとか、そういうこと)を 表示するようにしたい。

その場合は、"~/.config/fish/config.fish"に以下の設定を追記すればよい。意味に関してはぐぐろう。。

# fish git prompt
set __fish_git_prompt_showdirtystate 'yes'
set __fish_git_prompt_showstashstate 'yes'
set __fish_git_prompt_showupstream 'yes'
set __fish_git_prompt_showuntrackedfiles 'yes'
set __fish_git_prompt_show_informative_status 'yes'
set __fish_git_prompt_showcolorhints 'yes'

この設定を書くと、何か状態が変化するとそれっぽいフォントで表示してくれる。なお、フォントがない場合は?になるので注意。

# 変更がないとき
bisco@bisco-server /home/bisco/dotfiles (master|✔)
# 未トラックのファイルが1つあるとき
bisco@bisco-server /home/bisco/dotfiles (master|…1)
# addしていないファイルが1つ、未トラックのファイルが1つあるとき
bisco@bisco-server /home/bisco/dotfiles (master|✚1…1)
# addしたファイルが1つあるとき
bisco@bisco-server /home/bisco/dotfiles (master|●1)
# リモートブランチよりも1つコミットが進んでいるとき
bisco@bisco-server /home/bisco/dotfiles (master↑1|✔)
# リモートブランチよりも1つコミットが遅れているとき
bisco@bisco-server /home/bisco/dotfiles (master↓1|✔)

まとめ

fishを使うと設定ファイル書かなくてもある程度使えるし、設定ファイルを書くとさらに快適になりますね。

*1:正確にはPATHに追加するんじゃなくて、fish_user_pathsという変数に追加して、PATHに付け足してくれる

Linuxにおけるplatform device APIについて

はじめに

自分でドライバ(というかカーネルモジュール)を作ることなんてほとんどないし、 昨今はそういうローレベルな話は流行らないような気がするけど、 それでもやはりドライバを作りたいときがある。 今回は、Linuxが勝手に情報を見つけてよしなにやってくれないデバイスに関して ドライバを作る際に便利そうなplatform device APIを紹介する。

platform device APIとは、PCIeデバイスやUSBデバイスのようなLinux KernelとかBIOSが うまいこと情報を見つけてきてくれるようなデバイではないものに対して、 IRQ X番で割り込みが上げられるよ、とか、MMIO空間はアドレスxxxxからxxxxまでだよ、などの デバイスが持つ資源の情報を手動でカーネルに登録するためのもの。

そもそもそんなデバイスなんてあるのか

例えばOn Chipのデバイスがそうらしい。情報を出す規格があるわけではないので、MMIO空間は見えても、 何ができるか*1まではスペックシートを 見ないとわからんことが多い(と思う)。

なお、PCI(PCIeも含む)は規格でどういうことができるかを示すレジスタ(Capability Register)を 実装しなきゃいけないので、そういう心配は無用。 Capability Registerに関してはこれがわかりやすい。 BIOSがPCI Expressを初期化する手順が見えてきた: なひたふJTAG日記

USBデバイスもたぶんPCIバイスと同じ。

バイス登録までのおおよその流れ

以下の2ステップで終わる。簡単!

  1. platform deviceの資源情報を持つ構造体を作成する
  2. platform_device_register_simpleでplatform deviceを登録する

platform deviceの資源情報を持つ構造体の作成

これはまあ普通に構造体を作るだけ。新しく例を作るのも何なので、 The platform device API [LWN.net]に乗ってる例(MMIO空間が0x10000000~0x10001000まで、 IRQ 20に繋がれているデバイス)を以下に引用する。

#include <linux/platform_device.h>

static struct resource foomatic_resources[] = {
    {
        .start  = 0x10000000,
        .end    = 0x10001000,
        .flags  = IORESOURCE_MEM,
        .name   = "io-memory"
    },
    {
        .start  = 20,
        .end    = 20,
        .flags  = IORESOURCE_IRQ,
        .name   = "irq",
    }
}

platform_device_register_simpleでplatform deviceを登録する

platform_device_register_simpleのインタフェースは以下のとおり。

  • nameには、登録するデバイスの名前(自分でつけてよい)を
  • idには、(たぶん)連番でデバイスに番号を
  • *resには、先に定義した構造体のポインタを
  • numには、resの要素数

入れればよい。

// linux 4.9 include/linux/platform_device.h
136 static inline struct platform_device *platform_device_register_simple(
137                 const char *name, int id,
138                 const struct resource *res, unsigned int num)
139 {
140         return platform_device_register_resndata(NULL, name, id,
141                         res, num, NULL, 0);
142 }

platform deviceを登録したあとはどうすればいいの

platform deviceのdriverを登録する。 以下のplatform_driverの構造体のうち、 最低限

  • probe
  • remove
  • driver

があればOK。ID tableはなくてもよい。

struct platform_driver {
    int (*probe)(struct platform_device *);
    int (*remove)(struct platform_device *);
    void (*shutdown)(struct platform_device *);
    int (*suspend)(struct platform_device *, pm_message_t state);
    int (*resume)(struct platform_device *);
    struct device_driver driver;
    const struct platform_device_id *id_table;
};

要はこんな感じ(The platform device API [LWN.net]に乗ってる例を引用)。

static struct platform_driver i2c_gpio_driver = {
    .driver     = {
        .name   = "i2c-gpio",
        .owner  = THIS_MODULE,
    },
    .probe      = i2c_gpio_probe,
    .remove     = __devexit_p(i2c_gpio_remove),
};

driverを作るのに役に立つかもしれないAPI

このへんのAPIで登録したデバイス情報を引いてこられるけど、 どういう場面で使うのかいまいちよくわからない。 platform deviceのようなニッチデバイスの情報を登録する人とドライバ作る人が別なのかな。

    struct resource *platform_get_resource(struct platform_device *pdev, 
                       unsigned int type, unsigned int n);
    struct resource *platform_get_resource_byname(struct platform_device *pdev,
                       unsigned int type, const char *name);
    int platform_get_irq(struct platform_device *pdev, unsigned int n);

参考

*1:例えば割り込みがあげられるとか、そういうの

2016年読書メモ[固定]

読了

/proc/interruptsに関するメモ

この記事はぴょこりんクラスタ:Re Advent Calendar 2016 - Adventarのために書いたものです。

サマリ

特に意味もなくLinuxの/proc/interruptsのアルファベット3文字の項目について説明する。

割り込みとは何か

処理を強制的に切り替える信号のようなもの。例えばキーボードのように、 入力に対する処理に即時性が必要だけど、全力でポーリングするのには割に合わないものに使われている。 ドライブやEthernetへのI/Oも普通は割り込みで動くんだけど(常にI/Oするわけじゃないし)、 なお、全力でポーリングすることでI/O性能を最大限出そうというのがSPDKとかDPDKっていうやつね。

割り込みが上がってくると、OSが割り込みの種類に合わせて処理をする。この処理のことを割り込みハンドラと呼ぶ。 割り込みハンドラはベクタと呼ばれるテーブルでOSのカーネルが管理している。 どのIRQ*1で 上がってきたら何番のベクタに登録されてるハンドラを使う、という運用になっている。

Linuxでの割り込みの取り扱い

各割り込みに仮想的なIRQを割り当ててハンドラを管理している。何でこんな複雑なことをするかというと、 多分このへんの理由なんだろうなと思う。あくまで思うだけで正解はわからない・・・

  • 割り込みベクタの数が限られているから(たった255しかない)
  • 同じベクタで複数のハンドラを動かしたいから(1つのベクタに対しては1つのハンドラしか登録できない)

で、/proc/interruptsとは何ですかね

Linuxにおいて、どういう割り込みがどれだけ上がっているかを調べられる特殊なファイルのこと。

/proc/interruptsの例

Virtualboxに入れたCentOSから見たときの/proc/interruptsはこんな感じ。 先頭列が数字のものとアルファベット3文字のがあるのがわかると思う。 数字はLinuxが管理している仮想的なIRQ番号を示していて、 アルファベット3文字のものはちょっと特別なやつを示している。 特別といってもハードウェア的には割り込みの上げ方に差はなくて、 特別なIRQが割り当てられているとか、特別なベクタが割り当てられているとかです。

/home/bisco/work/mem% cat /proc/interrupts 
           CPU0                                                 
  0:        127   IO-APIC-edge      timer                       
  1:         10   IO-APIC-edge      i8042                       
  8:          1   IO-APIC-edge      rtc0                        
  9:          0   IO-APIC-fasteoi   acpi                        
 12:        155   IO-APIC-edge      i8042                       
 14:          0   IO-APIC-edge      ata_piix                    
 15:       8285   IO-APIC-edge      ata_piix                    
 19:      42955   IO-APIC-fasteoi   enp0s3                      
 20:          3   IO-APIC-fasteoi   vboxguest                   
 21:          0   IO-APIC-fasteoi   snd_intel8x0                
 23:          0   IO-APIC-fasteoi   ohci_hcd:usb1               
 24:      14746   PCI-MSI-edge      0000:00:1f.2                
NMI:          0   Non-maskable interrupts                       
LOC:     281405   Local timer interrupts                        
SPU:          0   Spurious interrupts                           
PMI:          0   Performance monitoring interrupts             
IWI:       5644   IRQ work interrupts                           
RTR:          0   APIC ICR read retries                         
RES:          0   Rescheduling interrupts                       
CAL:          0   Function call interrupts                      
TLB:          0   TLB shootdowns                                
TRM:          0   Thermal event interrupts                      
THR:          0   Threshold APIC interrupts                     
DFR:          0   Deferred Error APIC interrupts                
MCE:          0   Machine check exceptions                      
MCP:         28   Machine check polls                           
ERR:          0                                                 
MIS:          0                                                 
PIN:          0   Posted-interrupt notification event           
PIW:          0   Posted-interrupt wakeup event                 

アルファベット3文字のものについてざっくりとした解説

  • NMI:割り込みの世界では受取拒否のことを「割り込みをマスクする」と言うんだけど、文字通り受取拒否ができないもの。 0除算とかページフォルトとか、そういう緊急事態に上がってくる割り込み。

  • LOC:タイマ割り込み。それっぽい言葉でtickと言って、OSが時間管理に使う割り込みのこと。タイマで定期的に割り込みを上げてもらって、 時限処理とか、プロセスのスケジューリングをやったりする。割り込みを上げるのはLocal APICTSCの組み合わせであったり、 HPETやらACPIやらのCPU外のデバイスについてる時計だったりする。昨今はLocal APICTSCの組み合わせでやることが多い。

  • SPU:割り込み発生元がわからない割り込みのこと。(たぶん)ハードウェアが壊れたときとか設定を間違えたときに上がる割り込み。

  • PMI:Intel CPUにはPerformance Counter(PMC)を積んでるものがあって、クロック数やらキャッシュミス回数をカウントしてくれる。 そのカウンタが一定以上になったときに割り込みを上げる機能があって、それのこと。

  • IWI:割り込みハンドラを動かしているときは、CPUはちょっと特別なモードになっているんだけど、その特別なモードで割り込みじゃない処理を動かしたい ときがある*2。そのときにカウントされるのがこれ。 自分で自分に割り込み*3を打ち込んで動かすようである。

// Linux/arch/x86/kernel/irq_work.c
 35 void arch_irq_work_raise(void)
 36 {
 37 #ifdef CONFIG_X86_LOCAL_APIC
 38         if (!arch_irq_work_has_interrupt())
 39                 return;
 40 
 41         apic->send_IPI_self(IRQ_WORK_VECTOR); ★これ
 42         apic_wait_icr_idle();
 43 #endif
 44 }
  • RTR:割り込みを上げようとして、Local APIC*4の ICR(Interrupt Command Register)を読んだときにbusyが返ってきたらリトライするんだけど、そのbusyが返ってきた回数をカウントしてる項目。 これ割り込みじゃないっぽいんだよなー。なお、このルートに入るのはNMI指定でIPIを投げつけたとき*5に限る。
// http://lxr.free-electrons.com/source/arch/x86/kernel/apic/apic.c#L250
250 u32 native_safe_apic_wait_icr_idle(void)
251 {
252         u32 send_status;
253         int timeout;
254 
255         timeout = 0;
256         do {
257                 send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
258                 if (!send_status)
259                         break;
260                 inc_irq_stat(icr_read_retry_count); ★ここでRTRがカウントされる
261                 udelay(100);
262         } while (timeout++ < 1000);
263 
264         return send_status;
265 }
  • RES:他のコアへスケジューリング要求を出すときの割り込み。

  • CAL:他のコアに何か関数コールしてほしいときに上げる割り込み。

  • TLB:TLB Shootdown*6のための割り込み。 特別枠になってるけど、実装はCALと同じでFunction Call Interruptsになっている。

  • TRM:CPUの温度が上がりすぎてるときに上がる割り込み。

  • THR:コレクタブルなエラー*7が発生したときに上がる割り込み

  • DFR:何かエラーが発生して、ハードウェアは何とかできなかったけど、ソフトウェアで何かする必要はないときに上がる割り込み。

  • MCE:Machine Check Exception。とにかくやばい障害。

  • MCP:定期的にMachine Checkが発生していないかを調べる割り込み。デフォルト5分だったかな。

  • ERR:Local APIC自体の障害

  • MIS:IOAPICの障害

  • PIN/POS:VMならではのもの。VMが割り込みを発生させるだけさせといて、VT-dが処理を遅らせたときに発生するようなやつ。

まとめ

Linuxの/proc/interruptsの、特にアルファベット3文字のものについて調べた。 わからない項目があっても、最悪ソースを読めばわかるというのはオープンソースのありがたいところですね。

*1:Interrupt ReQuest。どのハードウェアが割り込みを上げてきたかを識別するためのIDのようなもので、マザーボードごとに固有のものが振られている。

*2:らしい。具体的にはわからないが・・・

*3:IPI:Inter Processor Interrupt。コア間で飛ばしあう割り込みのこと

*4:割り込みコントローラのこと。各コアに1つずつついてる

*5:立ち上げのときとか障害発生したとき

*6:論物アドレス変換のキャッシュを捨てる

*7:CMCI:Correctable Machine Check Interrupt。エラー発生したけどなんとかなったやつ。

今年読んだ本を振り返る

この記事はぴょこりんクラスタ:Re Advent Calendar 2016 - Adventarのために書いたものです。

サマリ

  • ベスト本は失敗の本質
  • ベスト漫画は東京喰種 re:。特別枠としてARIA

良かった本(非漫画)とひとくちメモ

失敗の本質

  • 思いつく限りの、俗に言う大企業の悪いところが網羅された本。僕たち(というか僕たちよりも上の世代だと思うけど)は60年以上たった今でも何も変わっていないことがわかる。多分自分もそのうち感化されてしまうので、これを定期的に読み返して心に釘をささねばという気持ちにさせられた本だった。読むのに体力を使うので来年かな・・・*1
  • 今年のベスト

大本営参謀の情報戦記―情報なき国家の悲劇

  • 失敗の本質とセットでどうぞ。この戦時中からの変わらなさは絶望であるけれど、問題がはっきりしているという点ではいいのかもしれない。

この世界が消えたあとの科学文明のつくりかた

  • リアル北斗の拳状態になったあとで、どうやって生き延びて、どうやって文明レベルを戻していくかを書いた本。これ読んでると自分でだいたい何でもできそうな気がしてくるけどきっと気のせい。なお、冷静に考えると文明がなくなったあとで生きていける気はしなかった。。。
  • いちばん印象に残っているのは、今食べてる農作物は実はそのまま種にできないということと(理由は忘れた)、種子バンクというものが世の中にはあって、ものすごく厳重に管理されているということだった。毎年祖父が苗やら種やら買ってるのが不思議でならなかったけど、そういうわけかと納得した覚えがある。

スティル・ライフ

  • どことなく漂う他人事感というか、村上春樹とは違ったドライですっきりな感じが印象に残っている。1度読んだきりなのでうろ覚え。もう1度読まねば。

カエアンの聖衣

  • キルラキルの原作(らしい)。服(というか服を作っている繊維)が意思を持っていて、着た人間を乗っ取ってしまうというお話。アニメをほとんどみない僕だけど、キルラキルは大変楽しく見られたし、このカエアンの聖衣も大変楽しく読めた。

コンテナ物語(まだ読んでる途中)

  • コンピュータの世界でもコンテナが当たり前になりつつあるけれど、これは実世界のコンテナの話。コンテナがどのように始まって、どのように広がったかはもちろん、コンテナを中心に世界がどのように変わっていったかを書いた本。コンテナの拡大により仕事を失うことを恐れた沖仲仕(荷降ろしとかする人のこと)が、コンテナの拡大をなんとか防ごうと、ロビー活動したり組合活動したりストライキしたりしてがんばるシーンがあるんだけど(もちろん最後はコンテナが勝ってしまうが)、身近に似たようなことがあったのであまり笑えなかった。

闘うプログラマー ビル・ゲイツの野望を担った男達

  • Windows 95を作ったときの話。すごいものはすごい天才からしか生まれないという厳しい現実を感じた。

ピープルウエア、ビジョナリーカンパニー、HARD THINGS

  • この辺は面白かったのは覚えているけど、すでに記憶がおぼろげになっている。

正法眼蔵随聞記

  • 「世を捨てたからといって、汚い身なりをしていいと思ったら大間違いだ。人並みに身なりに気を使え」という話があってびっくりした。
  • 気分が沈んだときにこれを読むと、元気は出ないがあきらめに似た気持ちで前向きになれるのでよい。
  • 全部が全部いい話かというとそういうわけでもなく、よくわからん話もけっこうある。

良かった本(漫画)

東京喰種 re:

  • 「ハイルと食べたメロンパンはおいしかった」、このセリフの悲しさがたまらなく好き。
  • だんだんと変わっていく初代Qsを見ていると心臓が鷲掴みされたような、そんな気持ちになる。

ARIA

  • 僕はこれを読んで文字通り泣いてしまったわけだけど、何で泣いたかいまだによくわかっていない。

さびしすぎてレズ風俗に行きましたレポ

  • 服装に気を使うようになったきっかけその2。自分は大切にしよう。

*1:これが悪いところかもしれない