2017年1月12日木曜日

MobileOrg で Agenda ファイルを org-directry 以外の場所に置くと何が起こるか?   gblog

1.1 はじめに

何やらMobileOrgの同期がうまくいかないなぁ,と思ったときについカッとなってコードを読んだ時の簡単なメモです.

※以下,本文中では,Emacs のシンボル(関数や変数)は(シンボル)で書いてます


1.2 何が起きる?

  • (org-mobile-push) はうまくいく (Emacs –> MobileOrg アプリ)

    • (org-agenda-file) でファイルのフルパスを指定していれば.

  • (org-mobile-pull) はうまくいなかい (MobileOrg アプリ –> Emacs)

片方だけうまくいくおかげで,問題に気づくのにちょっと時間かかった.

1.3 なぜなのか?

1.3.1 org-mobile-pull の挙動

早い話が, (org-mobile-pull) は Agenda ファイルが (org-directory) 以下にあることを想定している


  • (org-mobile-pull) は独自のフォーマットで差分を読み込み,パースして,適用する.

    • Dropbox で同期していれば,MobileOrg アプリは差分情報を (org-mobile-directory)/(org-mobile-capture-file) に保存する

      • (org-mobile-directory) は設定が必要なので,init.el などで設定しているはず.

      • (org-mobile-capture-file) はデフォルトだと,"mobileorg.org"

    • (org-mobile-pull) 時に,(org-mobile-capture-file) から(org-mobile-inbox-for-pull) へコピーする

      • (org-mobile-index-for-pull) のデフォルト値は "~/org/from-mobile.org"

    • この差分を記述するフォーマットはともかく,変更箇所の記述方法が問題

      =~[[olp:<ファイル名>:H1/H2/H3][Head名]]~=
      
      となっている.

    • これを,(org-mobile-locate-entry) が実際のファイルパスとポジションに変換する.

      • このとき,ファイルパスは (org-directry) /<ファイル名>になる.

        • (org-directory) はデフォルトで "~/org"

1.3.2 org-mobile-push の挙動

じゃあ,push はどうなのよというと,実は Agenda ファイルが (org-directory) 以下になくても動くようになっている


  • (org-mobile-push) は.org ファイルを丸々転送している.

    • コピー元は, (org-agenda-files) からファイルパスごと 取ってくる

    • 暗号化しているときは,(org-mobile-capture-file) 経由で暗号化して転送するっぽい

    • でも,この時も .org は暗号化せずに転送しているように見えるけど,大丈夫か?(動かしたわけじゃないから実際はどうなのかわからないけども)


1.4 おわりに

Agenda ファイルはちゃんと,(org-directory) 以下に置きましょう.

どうしてもいやなら,MobileOrg か org-mobile.el を改造しましょう.

2015年4月9日木曜日

resize2fs と fdisk で ext4 のパーティションを縮小する


1 resize2fs と fdisk で ext4 のパーティションを縮小する




1.1 はじめに



パーティションの拡大縮小はいつもGParted を使っていた.

しかし,今回はディスプレイが繋がっていないマシンのパーティションを変更するために,CLI で操作できるresize2fs と fdisk で操作した.

結構悩んだが,わかればそんなにややこしい手順じゃないはず.






1.2 作業の流れ



パーティションを縮小すると言っても,実はパーティションのサイズだけ縮小してもダメらしい.

ファイルシステムのサイズも変えないといけないんだそうだ.

しかも,この2つのサイズが一致してないとまずいらしい.



resize2fs はサイズ指定なしで実行すると,ファイルシステムのサイズを可能な限り大きくする.

つまり,パーティションのサイズいっぱいにファイルシステムのサイズを広げてくれる.

これを利用すれば,面倒な計算なしに,ファイルシステムとパーティションサイズのサイズを合わせられる.

(逆にパーティションサイズに合わせて縮小,ということはやってくれないっぽい?)



というわけで,以下の手順を取る.



  1. resize2fs でファイルシステムを縮小(予定サイズよりもちょっと小さめに)


  2. fdisk でパーティションのサイズを縮小(予定サイズに縮小)


  3. resize2fs でファイルシステムのサイズをパーティションのサイズに合わせる(勝手に計算してくれる)







1.3 resize2fs でファイルシステム



今回は/dev/sdb1 を512GB から32GB に縮小する例を示す.



まずは,resize2fs でファイルシステムのサイズを予定サイズより少し小さめに変更.

512GB–>31GB の変更は結構時間がかかる(10分くらい?).



# e2fsck -f /dev/sdb1
e2fsck 1.42.5 (29-Jul-2012)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdb1: 184019/30777344 files (1.9% non-contiguous), 7022898/123088640 blocks
# resize2fs /dev/sdb1 31G
resize2fs 1.42.5 (29-Jul-2012)
Resizing the filesystem on /dev/sdb1 to 8388608 (4k) blocks.
The filesystem on /dev/sdb1 is now 8388608 blocks long.
#


次にfdisk でパーティションのサイズを変更する.

操作的にはサイズを変更というより,元のパーティションを削除して,同じところに小さいサイズのパーティションを作りなおすと,なる.



# fdisk /dev/sdb
The device presents a logical sector size that is smaller than
the physical sector size. Aligning to a physical sector (or optimal
I/O) size boundary is recommended, or performance may be impacted.

Command (m for help): p

Disk /dev/sdb: 512.1 GB, 512110190592 bytes
255 heads, 63 sectors/track, 62260 cylinders, total 1000215216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x000c3f6e

Device Boot Start End Blocks Id System
/dev/sdb1 * 2048 984711167 492354560 83 Linux
/dev/sdb2 984713214 1000214527 7750657 5 Extended
Partition 2 does not start on physical sector boundary.
/dev/sdb5 984713216 1000214527 7750656 82 Linux swap / Solaris

Command (m for help): d <-- パーティション削除
Partition number (1-5): 1

Command (m for help): n <-- 新しいパーティション作成
Partition type:
p primary (0 primary, 1 extended, 3 free)
l logical (numbered from 5)
Select (default p):
Using default response p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-1000215215, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-984713213, default 984713213): +32G

Command (m for help): p

Disk /dev/sdb: 512.1 GB, 512110190592 bytes
255 heads, 63 sectors/track, 62260 cylinders, total 1000215216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x000c3f6e

Device Boot Start End Blocks Id System
/dev/sdb1 2048 69208063 34603008 83 Linux
/dev/sdb2 984713214 1000214527 7750657 5 Extended
Partition 2 does not start on physical sector boundary.
/dev/sdb5 984713216 1000214527 7750656 82 Linux swap / Solaris

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
#


最後にファイルシステムのサイズをパーティションのサイズに合わせる.



# resize2fs /dev/sdb1
resize2fs 1.42.5 (29-Jul-2012)
Resizing the filesystem on /dev/sdb1 to 8650752 (4k) blocks.
The filesystem on /dev/sdb1 is now 8650752 blocks long.
#


これで完了(のはず)






1.4 おわりに



パーティションの操作にあまり慣れていなかったので,結構調べるのに時間かかった.






--
My Emacs Files At GitHub

Debian でQEMU をビルド


1 Debian でQEMU をビルド




1.1 はじめに



QEMU の環境を何度も作る機会があったので,書いておく.





1.2 参考ページ



Debian上にOSvビルド環境を構築してみた - 夜はいよいよ冴えたのだ。

記事自体はOSv の環境構築について書いているものであるが,その一部としてQEMU のビルドの方法が書かれている.

その部分をありがたく参考にさせていただいた.






1.3 環境




# cat /etc/debian_version
7.8
# uname -a
Linux kvm-host2 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux





1.4 手順



まずはqemu のソースコードを入手する.

ソースコードはgit でクローンするので,git のインストールも行う.



# apt-get install git
# git clone git://git.qemu.org/qemu.git


次にビルドに必要なパッケージをインストールする.




# apt-get install make
# apt-get install gcc
# apt-get install pkg-config
# apt-get install libglib2.0-dev
# apt-get install libcap-dev
# apt-get install libattr1-dev
# apt-get install libpixman-1-dev


次に,ビルドの準備をする.

具体的には,ビルドしたいQEMU のバージョンのソースコードへチェックアウト,configure の実行である.

configure の実行はオプションが多くなりがちなので, setup.sh というスクリプトファイルにして実行してみた.



cd ~/qemu
git checkout v2.2.1
vi setup.sh




./configure --prefix=/opt/qemu-2.2.1 \
--target-list=x86_64-softmmu,x86_64-linux-user \
--enable-kvm \
--enable-vhost-net \




# sh setup.sh 2>&1 | tee -a _setup.log
# make -j8 2>&1 | tee -a _make.log
# make install 2>&1 | tee -a _make-install.log


最後に動作確認



# /opt/qemu-2.2.1/bin/qemu-system-x86_64 --version
QEMU emulator version 2.2.1, Copyright (c) 2003-2008 Fabrice Bellard




1.5 おわりに



書いてみて気づいたが,特別難しいところはなさそう.

ビルドに必要なパッケージをいつも忘れるくらい.






--
My Emacs Files At GitHub

2015年3月20日金曜日

Grub のブートメニューををシリアルポート経由で出力する


1 Grub のブートメニューををシリアルポート経由で出力する




1.1 動作環境




  • $ uname -a

    Linux debian 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686 GNU/Linux


  • $ sudo grub-install -v

    grub-install (GRUB) 1.99-27+deb7u2






1.2 設定方法



注) コマンドはあとで思い出しながら書いたところがあるので,コピペしても動かないかも



/etc/default/grub に以下を追記



GRUB_TERMINAL_INPUT='serial console'
GRUB_TERMINAL_OUTPUT='serial console'
GRUB_SERIAL_COMMAND='serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1'


grub-mkconfig で設定ファイルを更新.



# grub-mkconfig -o /boot/grub/grub.cfg


出力された /boot/grub/grub.cfg を確認する.




# grep 'serial' /boot/grub/grub.cfg
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal_input serial console
terminal_output serial console


これで再起動すれば,GRUB のメニューがシリアルポート経由で出力される.






--
My Emacs Files At GitHub

2015年2月16日月曜日

iPXE でBitVisor をネットワークブートしよう


iPXE でBitVisor をネットワークブートしよう





はじめに



BitVisor のブートは,ローカルディレクトリにイメージを置いて,Grub から起動する方法を取ることが多いかなと思うが,これは開発時には結構面倒.

なぜなら,トライアンドエラー中にBitVisor のイメージを差し替えるためだけに,BitVisor なしで一度ブートしないといけないから.

ネットワークブートなら,サーバーにおいてあるBitVisor のイメージを差し替えればいいので,楽.

というわけで,ネットワークブートの方が楽だよ,と先輩に教わった方法をここに書く.




恐らく,ブートするのがBitVisorだからと言って特別なことはあまりない.

Linux をiPXE でネットワークブートするのと設定はほぼ同じだと思う(Linux はやったことないけど.)






環境




  • iPXEサーバーマシン: Raspberry Pi


  • OS: Raspbian






必要なもの




  1. BitVisor を起動マシンするマシン(BIOS の設定でネットワークブートを有効にできるもの)


  2. Raspberry Pi


  3. GNU make が動くx86マシン(1. のマシンでもいい)


    • iPXE のイメージとBitVisorのイメージを作るのに必要








設定方法




TFTP のインストール & 設定



使うのはtftpd-hpa.




$ sudo apt-get install tftpd-hpa
$ sudo vi /etc/default/tftpd-hpa
$ sudo service tftpd-hpa start


設定ファイルの変更は以下の通り




4c4
< TFTP_DIRECTORY="/srv/tftp"
---
> TFTP_DIRECTORY="/var/lib/tftpboot/"
6c6
< TFTP_OPTIONS="--secure"
---
> TFTP_OPTIONS="--secure -4"


上記設定では, /var/lib/tftpboot にiPXE のイメージを置く設定.

/var/lib/tftpboot がない状態でtftpd-hpa を起動しようとすると,失敗するらしい.



オプションに -4 をつけた理由.

= オプション追加せずにtftpd-hpa を起動しようとしたら,Raspbian でIPv6 が無効になってて動かなかったから.

ちょっと jot: obs600 で 再度 debian squeeze - その 1






DHCP サーバーのインストールと設定




$ sudo apt-get install isc-dhcp-server
$ sudo vi /etc/dhcp/dhcpd.conf #設定ファイルの編集
$ sudo service isc-dhcp-server


設定ファイルの変更(というより追記)は以下の通り




107a108,118
>
> subnet 192.168.0.0 netmask 255.255.255.0 {
> deny unknown-clients; # 下記でMACアドレスが登録されてない起動マシンは無視.
> host deep-desktop {
> hardware ethernet 00:60:6E:EB:5A:D8; # 起動マシンのMACアドレス.
> fixed-address 192.168.0.20; # BitVisorを起動するマシンに割り振るIPアドレス
> option host-name "deep-desktop"; # host *** の部分と同じ.
> next-server 192.168.0.30; # tftp サーバのIPアドレス.
> filename "bitvisor-boot.kpxe"; # ipxe イメージのファイル名
> }
> }


これで,MACアドレス 00:60:6E:EB:5A:D8 から要求が来たら, TFTP で /var/lib/tftpboot/bitvisor-boot.kpxe を送る.

bitvisor-boot.kpxe というのは,iPXE のイメージファイル.

このファイルの作り方は後述.





iPXE をイメージを作成



iPXE はイメージファイルをtftp で起動マシンに投げて,起動マシンで実行される.

なので,起動マシンがx86 ならx86向けにビルドする.

というわけで,以下のイメージファイルの作成の操作はx86マシンでやる.



$ git clone git://git.ipxe.org/ipxe.git
$ cd ipxe/src
$ vi bitvisor-boot.ipxe
$ cat bitvisor-boot.ipxe
#!ipxe
dhcp
boot bitvisor.elf
$ make -j4 bin/undionly.kpxe EMBED=bitvisor-boot.ipxe
# scp bin/undionly.kpxe deep@raspberrypi:~

bitvisor-boot.ipxe はiPXE でのブート処理を記述するファイル.

上記の設定で,サーバーの /var/lib/tftpboot/bitvisor.elf をブートする.

今回は書かないが,この設定をいじると,ブートするイメージを選択するメニューを出せたりもする.



make の結果, bin/undionly.kpxe が作成される.

これが,iPXE のイメージファイル.

このファイルをRaspberry Pi 上に置く.



以下は,Raspberry Pi上で操作.

TFTP のディレクトリにiPXE のイメージを置く(ついでにファイル名も変える)



$ sudo cp undionly.kpxe /var/lib/tftpboot/bitvisor-boot.kpxe





BitVisor のビルド



これもx86マシンでやる.



$ wget http://sourceforge.net/projects/bitvisor/files/latest/download?source=files -o bitvisor-1.4.tar.gz
$ tar -zxvf bitvisor-1.4.tar.gz
$ cd bitvisor-1.4/
$ tar -zxvf bitvisor-1.4.tar.gz
$ cd bitvisor-1.4/
$ history | tail -n3
$ make config # 動かすだけならデフォルト設定で大丈夫だと思う(多分)
$ make -j4
$ scp bitvisor.elf deep@raspberrypi:~


Raspberry Pi でbitvior.elf をTFTP のディレクトリに配置.



$ cp bitvisor.elf /var/lib/tftpboot/bitvisor.elf





いざブート…の前にBIOS 設定




  • ブートする前にBitVisor を起動するマシンのBIOS の設定を変更


    • ネットワークブートを有効にする(大抵どこかにあると思うので探そう,これなかったら諦めて別のマシンを用意して)




  • ブートの優先順位でネットワークブートを再優先にする


    • 優先順位の選択にネットワークブートを出すには,ネットワークブートを有効化してから一時Save&Exit しないといけないので注意.










おわりに



今回はRaspberry Pi をサーバにしてみたが,VMでもいいからx86 マシンを用意できるからそっちの方が多分よい.

なぜなら,iPXE のイメージを差し替えるときにいちいち別のマシンでビルドしないといけないから…



雑な説明になってしまったので,質問や突っ込みがあれば,是非お願いします.

(TFTP とかiPXE の仕組みはたぶん3割くらいしかわかってないので,仕組みとかは質問されても答えられないと思うけど…)






--
My Emacs Files At GitHub

2015年1月21日水曜日

org-mobile-pull/push を自動実行する設定


1.1 はじめに

org-mobile でTODO 管理とかすると,PC からの入力がストレスレスで良いのだけど,なにせ,いちいちコマンド叩いて同期するのが面倒.

というわけで,自動的にorg-mobile-pull とかorg-mobile-push とかするようにしてみた.

まだ,この設定で動かした時間短い(30分ぐらい)ので,どこかおかしなところを見逃してる可能性ある.

だから,あんまり鵜呑みにしないようにお願いします.
(追記: 後述のcapture ファイル監視でのpullは動いてないっぽい... 2015/01/21 09:12)





1.2 やること



  • Emacs が開いている間,アイドル時間が一定時間以上でpull してpush
  • org-mobile-capture-file が変更されたらpull (追記: 下記の設定では動いてないぽい)

    • capture ファイルは,org-mobile で同期取るときに使う差分を保持する一時ファイルだったかな? とにかく,他のデバイスとかで編集するとこのファイルが更新されるっぽい.
  • ファイルをセーブするときにはpush
  • ファイルを開くときにはpull




1.3 参考にしたコード



以下のリンクにあるサンプルコードを参考にした

FAQ · matburt/mobileorg-android Wiki

やってることは


  • org-mobile に登録したファイルを保存すると,その後アイドル時間30秒経過するとpush を実行
  • 24時間に一回の頻度でpush
  • Emacs 起動時にpull
  • org-mobile が更新されたらpull




1.4 やってみる




1.4.1 コード





(defvar org-mobile-sync-timer nil
  "Timer that `org-mobile-sync-timer' used to reschedule itself, or nil.")
;;pullしてpush する関数
(defun org-mobile-sync nil
  (interactive)
  (org-mobile-pull)
  (org-mobile-push))

;;idle 時間が60秒経過すると自動でpullしてpush
(defun org-mobile-set-sync-timer nil
  (interactive)
  (setq org-mobile-sync-timer (run-with-idle-timer 10 60 t 'org-mobile-sync)))  ;;修正 2015/01/21 09:04


;;自動pull, push  を無効にする(一応用意してみたが使うかどうか...)
(defun org-mobile-clear-sync-timer nil
  (interactive)
  (cancel-timer org-mobile-sync-timer))

;;↓要修正  (追記:2015/01/21 09:11)
;;指定されたファイルを指定された時間で監視,更新されたらorg-mobile-pull を実行
(defun install-monitor (file secs)
  (run-with-timer
   0 secs
   (lambda (f p)
     (unless (< p (second (time-since (elt (file-attributes f) 5))))
       (org-mobile-pull)))
   file secs))

;; capture ファイルを5秒ごとに監視,更新されたらorg-mobile-pull 実行
(install-monitor (file-truename
                  (concat
                   (file-name-as-directory org-mobile-directory)
                   org-mobile-capture-file))
                 5)

;; org-mobile に登録したファイルを保存するとpush
(add-hook 'after-save-hook
          (lambda ()
            (when (eq major-mode 'org-mode)
              (dolist (file (org-mobile-files-alist))
                (if (string= (file-truename (expand-file-name (car file)))
                             (file-truename (buffer-file-name)))
                    (org-mobile-push)))
              )))

;; org-mobile に登録したファイルを開くとpull
(add-hook 'find-file-hook
          (lambda ()
            (when (eq major-mode 'org-mode)
              (dolist (file (org-mobile-files-alist))
                (if (string= (file-truename (expand-file-name (car file)))
                             (file-truename (buffer-file-name)))
                    (org-mobile-pull)))
              )))
(org-mobile-set-sync-timer)  ;; ←追記 2015/01/21 09:00


  • ファイルをセーブするときpushするコードは,元のコードから遅延を省いただけ.
  • capture ファイル変更でpull するコードは元コードそのまま






1.5 おわりに



とりあえず,これでしばらく使ってみる.

もしかしたら何か問題あるかも知れない.

問題が見つかって,気が向いたらこの記事直します.(無責任)






--
My Emacs Files At GitHub

2015年1月19日月曜日

Emacs Lisp を少し勉強した


1 Emacs Lisp を少し勉強した   gblog



Emacs Lisp のコードを読むときに知らなくて困った(多分)基本的な所をメモ.

困ったときに調べたものだけメモしているので,網羅はしてない.




1.1 コンスセル



「CARスロットおよびCDRスロットと呼ばれる 2つのポインタから成るオブジェクトです。」らしい.

「各スロットは、任意のLispオブジェクトを指すことができます。」

ドット記法とかで表現する.

(A . B) と書くと,A がCARスロット,B がCDR スロット



参考ページ:

GNU Emacs Lispリファレンスマニュアル: Cons Cell Type







1.2 cons obj1 obj2



obj1 とobj2 から成るコンスセルを作る関数.

(cons 1 2) => (1 . 2)





1.3 リスト



リストはコンスセルの入れ子構造.

(1 2 3) と表示する.

この実態は,CARスロットが1, CDR スロットが(2 3) のコンスセル.

2と3 が要素のリスト(2 3) の実態は CARスロットが2, CDR スロットが(3) のコンスセル

3だけが要素のリスト(3) の実態は CAR スロットが3, CDR スロットが空リストの()

ドット表記だと(1 . (2 . (3 . ())

(cons 1 (2 3)) => (1 2 3)

(cons 1 ()) => (1)

また,空リスト() はnil とも書く

つまり,

(cons 1 nil) => (1)





1.4 関数car, cdr



コンスセルのCAR スロットを取り出すのがcar 関数,CDR スロットを取り出すのがcdr 関数.

リストに適用すると,以下のような感じ.

(car '(0 1 2)) => 0

(cdr '(0 1 2)) => (1 2)





1.5 シングルクォートは何?



car やcdr の例では'(0 1 2) とリストの前に「'」がついている.

これは,リストを評価しないようにするためのものらしい.

リストを評価するとは,リストのCAR スロット(第一要素)を関数名,第二引数以降を関数の引数として,計算するということ.

Lisp は(0 1 2) とだけ書いて実行すると,0 を関数名,1 を第一引数,2 を第二引数として計算しようとするらしい.

これをせずに,リストとしてそのまま置いておくために,シングルクォートをつける.

関数名や変数名の前に「'」をつけるのも同じ理由のようである.



参考ページ:

Programming in Emacs Lisp: List Processing



また,別の説明で,おそらくより厳密な説明が以下のリンクにある.

Emacs Lisp

これをちゃんと理解するためには,シンボルというものを理解しないといけないらしい.

また,シンボルなるものの構造については以下のリンクが詳しいと思う.

GNU Emacs Lispリファレンスマニュアル: シンボル

このあたりの理解は今後の課題.





1.6 let



ローカル変数を定義して,最後のリストを評価する.



(let (ローカル変数の定義のリスト) フォーム1 … フォームn)



ローカル変数の定義のリストは以下の構文

((ローカル変数名1 初期値1) ローカル変数名2 … (ローカル変数名n 初期値n))

(ローカル変数名1 初期値1) と言うリストは,ローカル変数名1 が初期値1 で初期化することを示す.

一方,ローカル変数2 とだけ書いていると,ローカル変数2 はnil で初期化する.



フォームとは,Emacs Lisp のコードと思えばいいのかな?

let 全体の戻り値は,最後のフォーム(フォームn) の戻り値になる.



例:

(let ((x 3)) x) => 3

(let ((x 3) (y 2)) x y) => 2 ;; 最後のフォームがlet の戻り値になる

(let ((x 3) (y 2)) (+ x y)) => 5

(let ((x 3) y (z 4)) (list x y z)) => (3 nil 4) ;; (list x y z) はx y z を要素とするリストを返す






1.7 スペシャルフォーム(special form) とマクロ



普通,リストの形式で書いて実行すると,全てのリストが評価される.

しかし,例外があるらしく,それがspecial form というらしい.

先のlet はその一つ.

(let ((x 3) (y 2)) (+ x y)) の(x 3) はリストだが,これを関数として評価していない(したらx なんて関数はないとエラーが出るはず)

一方,一番後ろの(+ x y) は評価されている.

このように,let の引数に関しては,一番後ろしか評価しない,ということになっているようである.

他にも,値を変数に代入するsetq などがそうらしい.



また,スペシャルフォームという言葉を調べていると,マクロという言葉もよく見かける.

マクロは,ユーザー定義のスペシャルフォームらしい.

参考ページ:

スペシャルフォームとマクロ - by shigemk2






1.8 dolist



実は,このブログの内容は,dolist のサンプルコードがわからなくて調べだしたのがきっかけ.

つまり,今回のブログはここがゴール.



dolist もlet のようにスペシャルフォーム.

構文は以下.

(dolist (ローカル変数 リスト [戻り値]) フォーム1 … フォームn)



リストの要素を一つずつローカル変数に代入してフォーム1 からフォームn の処理を繰り返す

python とかでいうforeach 的なやつ.

戻り値を設定しないと,dolist の戻り値はnil になる.

また,戻り値に未定義の変数は使えないので,予め定義する必要がある.

例:

(let ((sum 0)) ;; 戻り値に使う変数を定義

(dolist (x '(1 2 3) sum)

(setq sum (+ x sum)))) => 6






--
My Emacs Files At GitHub

2014年12月11日木曜日

org-export-as が吐く html の文字コードでハマる


1 org-export-as が吐く html の文字コードでハマる



org-googlecl (https://github.com/rileyrg/org-googlecl) でこのブログに記事を投稿するためにごにゅごにょやってたらハマった.

(ちなみに,org-googlecl は4年前から更新されてないみたいで,Org-mode のバージョンアップに合わせて自分で直さないと動かない)

僕の環境では, org-googlecl-blog というコマンドで blogger で投稿するようになってる.

このコマンドの中では,Org-mode のフォーマットを HTML に変換したあとに少し整形して googlecl のコマンドに渡すということをやってる.

この HTML に変換する処理を今は (org-export-as 'html nil t nil nil) という関数でやっているのだが,これがEUC-JP しか吐いてくれない.

EUC-JP だと googlecl さんがエンコードできねーと文句言うもんだからさて困った.



結論としては, org-googlecl-blog コマンドを叩く前に C-x RET c でコマンドを実行する際の文字コードを utf-8 に指定すればとりあえず utf-8 で HTML が吐かれるようになった.

なんか,釈然としないが,とりあえず今日はつかれたし,こんなことやってる場合ではないような気がするのでこれで置いとく.





--
My Emacs Files At GitHub

Org-mode で C-c C-e l 押下でLaTeXに\ エクスポートできなくなった時の話


1 Org-mode で C-c C-e l 押下でLaTeXにエクスポートできなくなった時の話   gblog



Org-mode で LaTeX へエクスポートしようと C-c C-e l 押下すると, Symbol's function definition is void: org-e-latex-export-to-latex とか言われたので場当たり的に対処

半年か一年か放ったらかしになっていた古いEmacs, Org-mode の設定で,Gentoo さんがバシバシアップデートしてくれるEmacs とOrg-mode を使えばやっぱり問題が起きるわけで.

とりあえず,対処療法的に問題が見つかったら潰している感じ.

今回は,Org-mode C-c C-e l でLaTeX をエクスポートしようとしたら, Symbol's function definition is void: org-e-latex-export-to-latex と言われたので対処.




1.1 環境



現環境



  • Emacs version: GNU Emacs 24.4.1


  • Org-mode version: Org-mode version 8.2.6



以前使ってた環境(うろ覚え)



  • Emacs version: GNU Emacs 23.4 くらいだったような気がする


  • Org-mode version: 7.9.3 くらいだったような気がする






1.2 org-e-latex-export-to-latex って何?



昔の Org-mode の Contrib の中にある関数らしい.

どうやら設定ファイルの中で古い Org-mode の Contrib を呼び出してるのがまずいらしい.






1.3 問題回避(解決したとは言ってない)



以前,org-md (Markdown へのエクスポートなどの機能を提供する) を試すために,org-mode/contrib/lisp をロードしていたが,正直全く使ってない.

なので,とりあえず今回は org-mode/contrib/lisp のロードをやめるようにした.

これで,=C-c C-e l l= でLaTeX へエクスポートされるようになった.






--
My Emacs Files At GitHub

2014年12月4日木曜日

OSv のパッチを送るには


はじめに




OSv Advent Calendar 2014 - Qiita 4日目(4日目に公開できたらいいな).




以前,OSvもくもく会#4 〜OSvで遊んでみよう〜 - connpass でOSv へのパッチの送り方を教えていただいたので,紹介する.




なお,この記事の中身OSv というよりはGit の使い方っぽい.






OSv のパッチ











送る流れ





  • git format-patch でパッチを生成


  • git send-email で送る


    • git send-email を使わずにメールを送ってもいいけど,使った方が無難(僕は使わずに妙なことになった)












パッチファイルを作る(git format-patch)





  • git のユーザー名とメールアドレスを設定しておく


  • 変更を加えてローカルリポジトリにコミットまでする


  • git format-patch -s <commit id>


    • OSvにパッチを送る時は -s オプションは必須.


      • このオプションはパッチファイルに署名を追加する.





    • –subject-prefix='PATCH v2' とオプションをつけると,パッチのタイトルの先頭にprefix を追加できる.


      • パッチを修正して再度送る場合などに,"PATCH v2" などとつける.








  • コマンド実行の結果,"0001-commit-message.patch" のようなファイル名でパッチファイルが生成される.








生成されるパッチの中身







From 9a81c71e4a64acdb62ffdfc8f5d5fbe77eca48a8 Mon Sep 17 00:00:00 2001
From: Takaaki Fukai <deep.wiki@gmail.com>
Date: Sun, 9 Nov 2014 07:48:23 +0000
Subject: [PATCH v2] add a native code example

Signed-off-by: Takaaki Fukai <deep.wiki@gmail.com> ←-s オプションでついた署名
---
native-example/Makefile | 10 ++++++++++
native-example/README | 1 +
native-example/hello.c | 6 ++++++
native-example/module.py | 3 +++
native-example/usr.manifest | 1 +
5 files changed, 21 insertions(+)
create mode 100644 native-example/Makefile
create mode 100644 native-example/README
create mode 100644 native-example/hello.c
create mode 100644 native-example/module.py
create mode 100644 native-example/usr.manifest

diff --git a/native-example/Makefile b/native-example/Makefile
new file mode 100644
index 0000000..0271bcb
--- /dev/null
+++ b/native-example/Makefile
@@ -0,0 +1,10 @@
+.PHONY: module
+module: hello
+
+CFLAGS = -std=gnu99 -fpie -rdynamic
+
+hello: hello.c
+ $(CC) -pie -o $@ $(CFLAGS) $(LDFLAGS) hello.c
+
+clean:
+ rm -f hello
diff --git a/native-example/README b/native-example/README
new file mode 100644
index 0000000..7ce6e3e
--- /dev/null
+++ b/native-example/README
@@ -0,0 +1 @@
+This is a minimal sample of porting native code.
diff --git a/native-example/hello.c b/native-example/hello.c
new file mode 100644
index 0000000..be1cf2b
--- /dev/null
+++ b/native-example/hello.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(){
+ printf("Hello from C code\n");
+ return 0;
+}
diff --git a/native-example/module.py b/native-example/module.py
new file mode 100644
index 0000000..16c9bae
--- /dev/null
+++ b/native-example/module.py
@@ -0,0 +1,3 @@
+from osv.modules import api
+
+default = api.run("/hello")
diff --git a/native-example/usr.manifest b/native-example/usr.manifest
new file mode 100644
index 0000000..b79ddd9
--- /dev/null
+++ b/native-example/usr.manifest
@@ -0,0 +1 @@
+/hello: ${MODULE_DIR}/hello
--
1.9.3














パッチを送る








前準備: メーリスの購読











前準備: git send-email の設定




(これが一番面倒)






# yum install git-email
# yum install msmtp
# yum install ca-certificates



  • ~/.gitconfig に以下を追記







[sendemail]
smtpserver = /usr/bin/msmtp



  • ~/.msmtprc を作成(以下はGmail アカウントからメールを送るための設定)







# Example for a user configuration file
# Set default values for all following accounts.
defaults
tls on
tls_trust_file /etc/ssl/certs/ca-bundle.crt ←(※1)
logfile ~/.msmtp.log
# My email service
account gmail
host smtp.gmail.com
port 587
from deep.wiki@gmail.com
auth on
user deep.wiki@gmail.com
password ****************** ←(※2)
# Set a default account
account default : gmail



  • (※1)ディストリによってはファイルのパスが違うかもしれない.上はFedoraの例.


  • (※2)Google の2段階認証を有効にしているときは,アプリケーション固有パスワード









メールを送る





  • git send-email 0001-add-a-native-code-example.patch を実行


  • 起動すると"Who should the emails be sent to (if any)?" と送り先メールアドレスを聞かれる.


    • osv-dev@googlegroups.com と入力





  • "Message-ID to be used as In-Reply-To for the first email (if any)?" と聞かれる.

    とりあえず何も入れずにEnter で良かったはず.


  • 送信するメールの中身が表示されるので,確認してyを入力










[root@openstack-host apps]# git send-email 0001-add-a-native-code-example.patch 
0001-add-a-native-code-example.patch
Who should the emails be sent to (if any)? osv-dev@googlegroups.com
Message-ID to be used as In-Reply-To for the first email (if any)?
(mbox) Adding cc: Takaaki Fukai <deep.wiki@gmail.com> from line 'From: Takaaki Fukai <deep.wiki@gmail.com>'
(body) Adding cc: Takaaki Fukai <deep.wiki@gmail.com> from line 'Signed-off-by: Takaaki Fukai <deep.wiki@gmail.com>'

From: Takaaki Fukai <deep.wiki@gmail.com>
To: osv-dev@googlegroups.com
Cc: Takaaki Fukai <deep.wiki@gmail.com>
Subject: [PATCH v2] add a native code example
Date: Thu, 4 Dec 2014 14:10:45 +0000
Message-Id: <1417702245-4428-1-git-send-email-deep.wiki@gmail.com>
X-Mailer: git-send-email 1.9.3

The Cc list above has been expanded by additional
addresses found in the patch commit message. By default
send-email prompts before sending whenever this occurs.
This behavior is controlled by the sendemail.confirm
configuration setting.

For additional information, run 'git send-email --help'.
To retain the current behavior, but squelch this message,
run 'git config --global sendemail.confirm auto'.

Send this email? ([y]es|[n]o|[q]uit|[a]ll): y
OK. Log says:
Sendmail: /usr/bin/msmtp -i osv-dev@googlegroups.com deep.wiki@gmail.com
From: Takaaki Fukai <deep.wiki@gmail.com>
To: osv-dev@googlegroups.com
Cc: Takaaki Fukai <deep.wiki@gmail.com>
Subject: [PATCH v2] add a native code example
Date: Thu, 4 Dec 2014 14:10:45 +0000
Message-Id: <1417702245-4428-1-git-send-email-deep.wiki@gmail.com>
X-Mailer: git-send-email 1.9.3

Result: OK


(ブログ書くときにやりかたを思い出すために別のアドレスに送ったときのログから送り先だけ"osv-dev@…"に変えたもの.実際のパッチを投げた時のではないので日付とかはお察し)










おわりに




パッチを送るまでに少々面倒な手順が必要だけど,一度設定してしまえば, git format-patchgit send-email コマンドだけでパッチを送れるようになる.

最初は git send-email を使わずにメーラーにパッチをコピペして送ったろうとしてみた.

しかし,妙な空行が入ったりして逆に面倒だったので,最初から git send-email 使った方がよい.







--
My Emacs Files At GitHub

2014年11月10日月曜日

OSv もくもく会#4 の作業メモ


はじめに




以前 https://github.com/syuu1228/fedora-chroot-image を使わせて頂いて,OSv をビルドできる環境を整えた.

で,自分で書いたC のHello World を動かそうとしてうまくいかなくて終わったような気がする.




今回こそはC のHello World を動かす.









最新版のコードをビルドする




自分の環境は2,3ヶ月放置していたものなので,まずはOSv の最新のコードをpull してくる.

まぁ,pull してmake すればいいだろうと軽い気持ちでpull し始めたわけだが…




chroot 環境で




# cd /root/osv
# git pull



とりあえず何も考えずにmake 叩く




# make



ばばーん




 ...(中略)
make[1]: Entering directory `/root/osv/build/release.x64'
/root/osv/build.mk:928: *** Error: libstdc++.a needs to be installed.. Stop.
make[1]: Leaving directory `/root/osv/build/release.x64'

make: *** [all] Error 2



新しいライブラリが必要になっているみたいなので,それをインストール




# yum install libstdc++-static.x86_64



もう一回make




# make -j7



ばばーん(2回目)




...(中略)
CC libc/errno/strerror.o
/root/osv/libc/errno/strerror.c:12:45: fatal error: ../../musl/src/errno/__strerror.h: No such file or directory
#include "../../musl/src/errno/__strerror.h"
^
compilation terminated.
CC libc/locale/duplocale.o
make[1]: *** [libc/errno/strerror.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make[1]: Leaving directory `/root/osv/build/release.x64'
make: *** [all] Error 2



サブモジュールが増えてるらしい.

サブモジュールもちゃんとアップデートする.




# git submodule update --init --recursive



3度目の正直




# make -j7




ばばーん




...(中略)
make[3]: Leaving directory `/root/osv/modules/lua/build/luarocks-2.1.2'
out/bin/luarocks install luasocket 3.0-rc1
Warning: Failed searching manifest: Failed loading manifest: Failed extracting manifest file
Installing http://luarocks.giga.puc-rio.br/luasocket-3.0rc1-1.src.rock...
Using http://luarocks.giga.puc-rio.br/luasocket-3.0rc1-1.src.rock... switching to 'build' mode

Error: Failed unpacking rock file: /tmp/luarocks_luarocks-rock-luasocket-3.0rc1-1-2801/luasocket-3.0rc1-1.src.rock
make[2]: *** [out/lib/lua/5.2/socket/core.so] Error 1
make[2]: Leaving directory `/root/osv/modules/lua'
Traceback (most recent call last):
File "/root/osv/scripts/module.py", line 239, in <module>
args.func(args)
File "/root/osv/scripts/module.py", line 196, in build
make_modules(modules, args)
File "/root/osv/scripts/module.py", line 100, in make_modules
raise Exception('make failed for ' + module.name)
Exception: make failed for lua
make[1]: *** [process-modules] Error 1
make[1]: Leaving directory `/root/osv/build/release.x64'
make: *** [all] Error 2



要らないファイルが残ってたらしい.

とりあえずmake clean, git clean した.




# make clean
# git clean -xdf


で解決.




4度目の正直




# make -j7



でやっとビルドができた.

これでスタート地点.









リハビリ: Java のHello World の組み込み型を思い出す




参考URL https://github.com/cloudius-systems/osv-apps/tree/master/java-example


  • 最低限必要なファイルは以下の模様.


    • Hello.java


    • Makefile


    • module.py


    • usr.manifest











Hello.java




Java プログラムの本体




public class Hello{
public static void main(String args[]){
System.out.println("Hello");
}
}










Makefile




特に難しいところはなさそう.

普通と違うのは module: Hello.class の行くらいか?




module: Hello.class

%.class: %.java
javac $^

clean:
rm -rf *.class








module.py




デフォルトの起動コマンドや引数を指定しているっぽい.




from osv.modules import api

api.require('java')

default = api.run_java(classpath=['/my-example'], args=['Hello'])








usr.manifest




これはあんまりわかってない.




/my-example/Hello.class: ${MODULE_DIR}/Hello.class









ビルド&実行




ここでは,my-example というイメージ名で上記のプログラムを組み込んだイメージを作る.

上記4つのプログラムをapps/my-example 以下に置く.

osv のルートディレクトリで以下のコマンドを実行.




make image=my-example
scripts/run.py








本題: C のプログラムを組み込む





memcached をビルドしてみる




参考にしているmemchached のソースツリーにあるMakefile を見てみると,make 時にusr.manifest などを作成しているらしい.

作成した後の状態を見たいので,まずはこれをビルドしてみる




ビルドしようとしたら,あれこれ無いと言われるのでインストールする




# yum install libevent-devel.x86_64



僕がビルドしたときは,apps/memcached/src が空っぽだった.

本来はここにソースコードがダウンロードされるはずなのだが,何かが原因でうまくダウンロードされていなかったみたい.

これは,以下のようにmemcached ディレクトリをclean すれば解決した.




# pushd apps/memcached/
# make clean
# popd



memcached のビルド完了









Makefile




色々見た結果,気をつけないといけなさそうなのはMakefile のCFLAGS くらいに見える.

memcached では以下のように指定されている.




CFLAGS = -std=gnu99 -fpie -rdynamic -DHAVE_CONFIG_H


CFLAGSのオプション


-std=gnu99
C99+GNU拡張


-fpie
位置独立実行形式(Position-Independent Executalbe)

ちなみに,共有ライブラリをコンパイルするときの-fpicは位置独立コード(Position-Independent Code)


rdynamic
動的リンク可能なバイナリを作る


-DHAVECONFIGH
…よくわからん







たぶん,-DHAVECONFIGH はmemcached 特有な気がするので,今回のHello World アプリからは削除.









最終的なコード




あとは,細々した要らないところを消していくだけで動いた.

最終的なコードは以下の通り.

(以下のdiff のルートディレクトリはapps/ なので注意)




---
native-example/Makefile | 10 ++++++++++
native-example/hello.c | 6 ++++++
native-example/module.py | 3 +++
native-example/usr.manifest | 1 +
4 files changed, 20 insertions(+)
create mode 100644 native-example/Makefile
create mode 100644 native-example/hello.c
create mode 100644 native-example/module.py
create mode 100644 native-example/usr.manifest

diff --git a/native-example/Makefile b/native-example/Makefile
new file mode 100644
index 0000000..0271bcb
--- /dev/null
+++ b/native-example/Makefile
@@ -0,0 +1,10 @@
+.PHONY: module
+module: hello
+
+CFLAGS = -std=gnu99 -fpie -rdynamic
+
+hello: hello.c
+ $(CC) -pie -o $@ $(CFLAGS) $(LDFLAGS) hello.c
+
+clean:
+ rm -f hello
diff --git a/native-example/hello.c b/native-example/hello.c
new file mode 100644
index 0000000..be1cf2b
--- /dev/null
+++ b/native-example/hello.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(){
+ printf("Hello from C code\n");
+ return 0;
+}
diff --git a/native-example/module.py b/native-example/module.py
new file mode 100644
index 0000000..16c9bae
--- /dev/null
+++ b/native-example/module.py
@@ -0,0 +1,3 @@
+from osv.modules import api
+
+default = api.run("/hello")
diff --git a/native-example/usr.manifest b/native-example/usr.manifest
new file mode 100644
index 0000000..b79ddd9
--- /dev/null
+++ b/native-example/usr.manifest
@@ -0,0 +1 @@
+/hello: ${MODULE_DIR}/hello
--
1.9.3



以上で,C のHello World をOSv に組み込めました.










おわりに




実は上記のようなCで書かれたHello Worldをポーティングするようなサンプルコードはこれまでosv-apps のリポジトリになかった.

そこで,syuu先生の勧めで上記のパッチをOSvのメーリングリストに送ってみたところめでたくマージされた.




--
My Emacs Files At GitHub

2014年11月6日木曜日

glibc のビルドでハマったポイント&手順

諸事情でglibc をビルドした時にハマったことのメモ.
記事中のコマンドはコピペで書いたのではなく,記憶を頼りに手打ちしているので,コピペして動かしたりすると危険.参考程度に見てください.


ハマったポイント

- gawk ないとmake でこける
- make install の前に/target_dir/ld.so.conf を作らないとこける

ビルド準備

- glibc をダウンロード(Git でクローンしたりアーカイブをダウンロード&解凍したり)
- gawk をインストールする.
これがないとmake でこける(こけてハマったのでこの記事書いてる).
# apt-get install gawk

あとはいろんなところで解説があるのと同じようにビルド作業

ビルド手順

- 以下では~/glibc_ver にダウンロードしてきたglibc があることにする
- 諸事情(ユーザーアカウントを作るのが面倒というとても深刻な事情)のため,すべてroot で作業しているが,ユーザーアカウントがある場合はユーザーアカウントでやったほうが安全.--prefix=${HOME}/install_target_dir とかにすればsudo なしでインストールまでできるはず(参考URLを見るとそう書いてあるからきっとそう)
- インストール先は/root/my_glibc

# cd ~/glibc_ver
# mkdir build
# cd build
# ../configure --prefix=/root/my_glibc
# make
# touch /root/my_glibc/etc/ld.so.conf
# make install

参考URL

Linux From Scratch:gcc、glibcインストール « 仙人の心得
http://blog.mktime.com/archive/340.html

chroot 環境に glibc を突っ込むメモ — togakushi.bitbucket.org 0.1 documentation
http://togakushi.bitbucket.org/build/html/glic2.5_install.html

2014年9月13日土曜日

Ubuntu でKVM のブリッジ接続の設定をする


/etc/network/interfaces の設定.

編集前にはバックアップをとっておくべき.




/etc/network/interfaces の設定例(固定IP)




# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto p6p1
iface p6p1 inet manual

auto br0
iface br0 inet static
  address xx.xx.xx.xx
  netmask 255.255.255.0
  network xx.xx.xx.0 #最後は大抵0
  gateway xx.xx.xx.1 #最後は大抵1?
  broadcast xx.xx.xx.255 #最後は大抵255 
  bridge_ports p6p1
  bridge_fd 9
  bridge_hello 2
  bridge_maxage 12
  bridge_stp off
  dns-nameservers xx.xx.xx.xx #わからなかったらとりあえずgateway と同じで



libvirt が勝手に作るNAT 用のブリッジインターフェイスを削除.(大抵はvirbr0 という名前かな)




$ sudo virsh net-autostart default --disable
$ sudo virsh net-destroy default


brctl show で確認するとvirbr0 が消えてる.




network-manager がいると設定を上書きされるらしい(未検証)なので,とりあえず network-manager を消しとく.




$ sudo apt-get remove network-manager



ネットワークを再起動




$ sudo service networking restart


これで br0 にIP がふられてたらOK.

以上.





--
My Emacs Files At GitHub

2014年5月19日月曜日

Mac OS X+ Virtual Box + CapstanでOSvを動かす


OSvもくもく会#1 〜OSvで遊んでみよう〜 - connpass に行って,OSv を動かしてきたので,それのまとめ.




この記事では,OSv のイメージのダウンロード,実行を勝手にやってくれるCapstan というアプリケーションを使って,OSv を動かす方法を書く.

以下では,OSv のデフォルトイメージをVirtualboxで動作させ,ホストマシンからSSH で接続する.



動作環境





  • マシン: Mac Book Air 2011


  • OS: Mac OS X 10.9.2


  • Virtual Box: version 4.2.18









前提




Virtual Box は既にインストールされているものとします.






Go のインストール




Capstan はGo で書かれている.

このため,Capstan を実行するために,まずGo をインストールする.




以下のURL から,Mac 用のパッケージである go1.2.2.darwin-amd64-osx10.8.pkg ダウンロードして,インストールする.

https://code.google.com/p/go/wiki/Downloads?tm=2




Go はパッケージをインストールしただけでは動作せず,以下のように環境変数を設定しないといけない.




$ export GOROOT=/usr/local/go 
$ export PATH=$PATH:$GOROOT/bin


GOROOT はGo がインストールされた先を設定する.

上記のパッケージからインストールした場合だと /usr/local/go になる.

また,2行目では,Go の実行ファイルにパスを通している.






Capstan のインストール




Capstan のインストールには,go のパッケージマネージャ的なものを使う.

使う前に,パッケージマネージャがインストールする先を GOPATH という環境変数で設定する必要がある.

今回は, $HOME/go にインストールするようにした.




その後, go get で,Capstan のGit リポジトリを指定し,インストールする.




$ mkdir $HOME/go
$ export GOPATH=$HOME/go
$ go get github.com/cloudius-systems/capstan








Capstan によるOSv の実行




Capstan の実行ファイルは $HOME/go/bin 以下にある.

下記のようにCapstan を実行すれば,OSv のデフォルトイメージをダウンロードして,起動する.




cd $HOME/go/bin
./capstan run cloudius/osv


初回は,イメージをダウンロードするため,時間がかかる.

2度目移行は,既にダウンロードされたイメージを実行するので,あまり時間はかからない.




上記コマンドによってOSv が動作すれば,ターミナルに [/] % と表示される.

これは,OSv のデフォルトイメージに入っているシェルである.

ls とか ifconfig が使える.

使えるコマンド一覧は help コマンドで表示できる.




上記の起動コマンドでは指定していないが, -p オプションを付けることで,VMMを指定することができる.

Virtual Box であれば, -p vbox といった感じ.

Virtual Box しか入ってない環境ならば,上記のように,何も指定しなくても勝手にVirtual Box 用のイメージをダウンロードして実行する.




ちなみに,Virtual Box のGUI管理ツールを起動してみると, cloudius/osv というインスタンスが実行中になっていることが確認できる.






ホストマシンからSSHを繋ぐ




OSv のデフォルトイメージでは,sshd が動作しているため,ホストマシンからSSHで入ることができる.

Virtual Box 上のOSv にSSHでログインするには,起動時のコマンドでにポートフォワーディングの指定をする必要がある.

OSv は一度止めて(shell で exit コマンドを叩くと止まる) 以下のコマンドで再度OSv を起動する.




./capstan run -f 2222:22 cloudius/osv


その後,別のターミナルで以下のようにすれば,OSv にSSHで入れる.

ユーザ名は admin, パスワードも admin である.




$ ssh admin@localhost -p 2222


僕の環境では,SSHログインの際にパスワードを聞かれるまでに5分か10分くらいかかった.

(原因はよくわかっていない.)

なかなかパスワードを聞かれなくても気長に待つように.






余談





  • ssh で入ってifconfig と叩くと,出力がssh 側ではなく,シリアル側に出てしまう.

    ls はちゃんとssh 側に出力される.





  • 自分のマシンでOSv をビルドしたい場合は,Mac OS X では無理なのでLinux を使いましょうとのこと.









--
My Emacs Files At GitHub

2014年4月10日木曜日

git diff で色をつける


git diff で色をつける設定は以下のコマンドで



$ git config --global color.ui true




diff を表示するために使う pager プログラムが lv になっていると文字化けしてうまくdiffが表示されないらしい.
(僕の環境では,何も設定してなかったが,どうもlvが使われているようだった.)
そこで,pager を設定する.
ここでは "lv -c" とオプション付きでlv を実行するようにしているが,"less" にしても大丈夫.



$ git config --global core.pager "less"





Table of Contents







--
My Emacs Files At GitHub

2014年3月30日日曜日

Raspberry Pi で Radikorec を使ってみる.


家で目的もなく動いてるRaspberry Pi さんにラジオを録音してもらいたくなった.
そこで, Raspberry Pi に radikorec をインストールしてみた.
Raspberry Pi に限らず,たいていのUnix 系OSならほぼ同じ手順でインストールできそうだった.




環境




<マシン>
Raspberry Pi

<OS>
Raspbian 7.1

<カーネル>
Linux raspberrypi 3.6.11+ #538 PREEMPT Fri Aug 30 20:42:08 BST 2013 armv6l GNU/Linux







radikorec のソースコードをダウンロード




radikorec のリポジトリは akiradeveloper/radikorec · GitHub にある.
ここから,クローンする.




git clone https://github.com/akiradeveloper/radikorec.git








setuptools distribute をインストール

(2015/08/22 更新: setuptools を使うように内容を変更)

radikorec のインストールのために、python のパッケージ管理ツールであるsetuptools を使うため、これをインストールする.

(この記事ではもともとdistribute を使うように書いていたが、distribute は2013年にsetuptools に取り込まれているらしいので、setuptools を使うほうがよいらしい
また、元々この記事で紹介していた distribute インストール用のスクリプトへのリンクが切れてしまっている.
このため、setuptools を使うように内容を変更した.)


distributete というpython のライブラリ? をインストール.
因みに,何のためのライブラリかはよくわかってない.

昔は distributete でなはく setuptools というライブラリが主流だったらしい.
現在は, setuptools の開発は止まっており,それを引き継いで開発されているのが distribute ということらしい.
というわけで,今回は distribute をインストールする.
(このことに関連して,あとでradikorecのインストールスクリプトを修正する必要がある.)

参考URL: Pythonパッケージ管理ツールまとめ | サイト運営の私的メモ




$ curl -O http://python-distribute.org/distribute_setup.py
$ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py
$ sudo python distribute_setup.py








その他必要なものをインストール




以下のコマンド(Debian 系)



sudo apt-get update
sudo apt-get install libssl-dev 
sudo apt-get install ffmpeg







インストールスクリプトの編集

(2015/08/22 更新: setuptools を使うように内容を変更)



compilesetup.py ファイルを編集.
compile の方は rtmpdump のソースコードをgitリポジトリからクローンしてくるのだが,このリポジトリの指定先が参照できないので,変更.
setup.pysetuptools ではなく distributete をインストールしたための変更.


編集内容は以下の通り.



$ git --no-pager diff
diff --git a/compile b/compile
index ef82607..8cf921e 100755
--- a/compile
+++ b/compile
@@ -6,7 +6,8 @@ pwd
 make
 cd -

-git clone https://github.com/svnpenn/rtmpdump.git
+git clone git://git.ffmpeg.org/rtmpdump
+# git clone https://github.com/svnpenn/rtmpdump.git
 cd rtmpdump
 pwd
 make SYS=posix      
diff --git a/setup.py b/setup.py
index ecba8a4..5b2df88 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,5 @@
-#from distutils.core import setup
-from setuptools import setup
+from distutils.core import setup
+#from setuptools import setup

 setup(
     name = 'radikorec',








インストールスクリプトの実行




以下のコマンドを実行する.



sudo make install
./compile 
sudo ./setup 








試験的に動かしてみる.




以下のコマンドでradikorecを試してみることができる.



./runtest


これを実行すると. /tmp/ 以下にログや録音した音声ファイルができるはず.
ffmpeg のインストールを忘れてると,録音したのにエンコードできなくて音声ファイルが出力されない.
僕は,毎度この段階で ffmpeg がないことに気づくので,実際に ./runtest で音声ファイルを出力したことはなかったりする.








放送局コードについて




radikorec を使うときに,録音したい放送局を放送局コードで指定する.
これを知るためには,http://radiko.jp/v2/api/program/today?area_id=JP14 へアクセスして返ってきたxml を見ればいいっぽい.
<station io=hoge>hoge の部分が放送局コード
その放送局が何かはすぐしたの <name> に書いている.

参考URL: FreeBSD で radiko を録音する。






おまけ: mp3に変換して,コマンドラインから再生する.




raspberry pi イヤホン端子もあるので,再生して聞くこともできる.
m4a 形式を直接コマンドラインから再生する方法がよくわからなかったのでmp3に変換してから再生してみた.
以下のようにやればできた.

m4a → mp3 は以下のようにやればできる.



ffmpeg -i NHR-2014-03-30-04-20.m4a  hoge.mp3




再生は, mpg321 をインストールして使えばOKっぽい.
デバイスファイルへのアクセス権限の関係で,何も設定しないとユーザ権限では動作しない.
今回は面倒だったのでsudo を付けないと動かした.
sudo を付けたくない人は,ブログログ mpg321を一般ユーザーで再生できるようにする。 などを見て,デバイスファイルにアクセスできるように権限を設定しよう.
mpg321 のインストールおよび再生コマンドは以下の通り.



sudo apt-get install mpg321 
sudo mpg321 hoge.mp3 



ここに書いた方法で,Raspberry Pi から直接再生することができる.
しかし,上記のエンコード処理はRaspberry Pi でやると非常に遅い.
また,録音した音声ファイルのサイズは大きくなりがちなので,SDカードの容量も心配である.
なので,音声ファイルは聞くときに別のマシンに移してしまって,そのマシンでエンコードなり再生なりしたほうがいいと思ったのがやってみた感想である.

参考URL: ブログログ mpg321を一般ユーザーで再生できるようにする。






コマンドリスト







git clone https://github.com/akiradeveloper/radikorec.git
cd radikorec/
curl -O http://python-distribute.org/distribute_setup.py
sudo python distribute_setup.py 
vi ./compile 
vi ./setup.py 
sudo make install
./compile  #失敗
sudo apt-get update
sudo apt-get install libssl-dev 
./compile 
sudo ./setup 
sudo apt-get install ffmpeg
./runtest 
vi my_script.sh
chmod +x my_script.sh 
mkdir ../radiko_data
./my_script.sh 
ffmpeg -i NHR-2014-03-30-04-20.m4a  hoge.mp3
sudo apt-get install mpg321 
sudo mpg321 hoge.mp3 








my_script.sh の中身







#!/bin/sh
radikorec \
 --channel=LFR \
 --duration=1 \
 --prefix=NHR \
 --directory=/home/deep/radiko_data





--
My Emacs Files At GitHub

2014年3月11日火曜日

Mac Port のselfupdate ができなかった時のメモ


長らく放置していたMac port.
Mac OS X も Mervericks にアップデートしたし,いい加減アップデートしないとなぁ,とselfupdate しようとすると…



$ sudo port selfupdate
---> Updating MacPorts base sources using rsync
MacPorts base version 2.1.2 installed,
MacPorts base version 2.2.1 downloaded.
---> Updating the ports tree
---> MacPorts base is outdated, installing new version 2.2.1
Installing new MacPorts release in /opt/local as root:admin; permissions 0755; Tcl-Package in /Library/Tcl

Error: /opt/local/bin/port: port selfupdate failed: Error installing new MacPorts base: command execution failed


などと,エラーがでてしまった.

これの解決は,以下のページを参考(というかそのまま)にしたらできた.
macportをアップデートしようとしたらエラーになった。 - @thorikiriのてょりっき

要は,xcode のコマンドラインツールが入ってなかったらしい.
Mac OS X をMervericks にアップデートするとインストールし直さないといけないんだったっけ?
以下の通りコマンドを叩くと,ポップアップが出てきて,コマンドラインツールをインストールするか否かを聞いてくる.
OKを押せばインストールしてくれる.



$ sudo xcode-select --install


で,再度selfupdate を実行してみると…



$ sudo port selfupdate
Password:
---> Updating MacPorts base sources using rsync
MacPorts base version 2.1.2 installed,
MacPorts base version 2.2.1 downloaded.
---> Updating the ports tree
---> MacPorts base is outdated, installing new version 2.2.1
Installing new MacPorts release in /opt/local as root:admin; permissions 0755; Tcl-Package in /Library/Tcl


The ports tree has been updated. To upgrade your installed ports, you should run
port upgrade outdated
$ port version
Version: 2.2.1



とちゃんとMac port が2.2.1へアップデートされたっぽい.

余談だが,バージョンを確認するときは port --version ではないので注意.
port --version と叩くと,以下の様に怒られる.




$ port --version
Error: global does not accept --version
Usage: port
[-bcdfknopqRstuvy] [-D portdir] [-F cmdfile] action [privopts] [actionflags]
[[portname|pseudo-portname|port-url] [@version] [+-variant]... [option=value]...]...

"port help" or "man 1 port" for more information.





--
My Emacs Files At GitHub

2013年12月20日金曜日

岡山から離れて9ヶ月 〜岡山を離れて変わったこと,変わらなかったこと,etc〜


はじめに




この記事は大都会岡山 Advent Calendar 2013 - Adventarの20日目の記事となります.

昨日は仁志 能野さんのYOKIZO.com - 「本自炊」はじめました でした.

僕は,「本を自炊すれば部屋の荷物が少なくなっていいだろうなぁ」と思いつつ重い腰が上がらない今日このごろです.







岡山ではなにやってたの?




9ヶ月前までは,大都会岡山の国立大学である岡山大学で残念大学生をやってました.

岡山では勉強会にあちこち顔を出したり,たまに主催したりしてました.

研究室時代にはLinux カーネルの中弄って面白いことする研究をしてました.





今どこでなにやってるの?




現在は,関東の国立大学である某T大学で大学院生をやってます.

(まぁ,T大学って筑波大学なわけですが.)

つくばや東京でも,ときどき勉強会に参加してます.

研究室ではVMMを弄って面白いことをする研究をしてます.







岡山を離れて変わったこと








列車に乗るときにICカードを使うようになった




岡山にいるときはICカードなど持ってもいませんでした.

つくばに引っ越してからも,しばらくはICカードを持たずに生活してました.

ただ,東京近辺の列車は切符を買うのがあまりにも難しい!

えっ,乗り換え後の料金表が切符売り場にないんだが…? 連絡切符って言われても何円の切符買えばいいの??? という事態になります.

そんなわけで,いちいち値段調べて切符買って,なんてことしてられないのでICカードを買いました.



余談ですが,こちらではICカードはPASUMOとSUICAのどちらかが手に入ります.

ただ,どうせICカードを持つのならICOCAが良かったなぁと思います.

あの青いカモノハシのキャラ「イコちゃん」は割と好きなキャラだったので.

イコちゃん - Google Search







あれ?勉強会って懇親会が本番じゃないの?




つくばに来てから,何度か勉強会に参加することがありました.

そこでカルチャーショックだったのが「懇親会が地味」ということです.



岡山の勉強会というと,勉強会後の懇親会は結構盛大にやります.

飲み屋で懇親会して,さらに元気があればボーリングやカラオケへ,というのが割とよくありました,

また,勉強会参加者の半数以上は懇親会に参加してたと思います.

岡山の勉強会文化で育った僕は,「勉強会は懇親会が本番だ」と教わったほどです.

(もちろん,勉強会自体もちゃんとやりますよ)



しかし,関東での勉強会はどうも状況が違います.

懇親会というと飲み屋ではなく,飲食店で夕食会というのが多かったように思います.

また,あったとしても参加者も3割から多くて6割と言ったところだったと思います.

ときには,懇親会があるのかないのかよくわからないときもありました.



この文化が悪いというわけではありません.



東京の勉強会は平日夜におこなうものも少なくありません.

また,勉強会の頻度も多いです.

さらに,参加者が多いということもあります.

人が多く,頻度も多いため,内容も濃いものになっていると思います.

これは関東の勉強会の良い所だと思います.

ただ,このような状況で,毎回盛大な懇親会しようとして,勉強会本体がお座なりになったら本末転倒なわけです.

なので,関東での勉強会の懇親会が盛大でないのも自然といえば自然です.



端的にいえば,関東の勉強会は岡山の勉強会よりも,勉強会自体に注力している印象です.



一方で,岡山の勉強会の懇親会の良さは,楽しく色々は人とコミュニケーションをとることができる点だと思います.

他の技術者と交流を深めるという点で,これは非常よかったと思います.

この点は,関東の勉強会にはあまりない良さなのかなと思います.








岡山を離れても変わらなかったこと




まぁ,なんと言っても

  • 彼女できない









今後やろうと企んでいること




大都会岡山では,Web系やJVM系言語の勉強会は活発なのですが,カーネルのようなシステムソフトウェアの分野はあまり活発でないように思います.



そう思った僕は以前,「岡山でLinuxカーネルと戯れる会」という勉強会を主催しました.

第1回 は僕が主催し,第2回 は僕の後輩が主催してくれました.

ただ,3回目以降が続かず,元気がない状態です.



岡山を離れた僕ですが,やはり岡山でシステムソフトウェア分野を活発にしたいと思うわけです.

ただ,つくばから岡山まで行って勉強会の主催をするのは厳しいわけです…



そこで,Webでカーネルのソースコードリーディングを配信してみたらどうだろうと考えました.

ソフトウェアを勉強する上で,ソースコードを読むことは非常に実り多いことです.

しかし,ソースコード,特にカーネルのソースコードを読むのは結構な労力がかかります.

なので,ソースコードリーディングを配信して,見てる人からの質問に答えたり,アドバイスをもらったりしながら読めればいいなと思ったわけです.



最近研究の都合でNIC周りを勉強しないといけないので,最初はNICドライバのコードを読みたいと考えています.

年内はバタバタしそうなので,年を越して1月中にしたいと思います.







最後に




列車の切符のことや,勉強会の違いなど,思いつくままにいろいろ書いてみました.



明日はpatorashさんの番となります.



--
My Emacs Files At GitHub