2012/03/01

GRUBでサブメニューのデフォルトエントリを指定する

Ubuntu 11.10 32bit で  kernel 3.0.0-16 に更新したら、ひどく不安定になったり kernel panic を起こして終了するようになったので 3.0.0-14 で動かすようにした。

apt のデータベースを壊したくないのでパッケージのアンインストールやダウングレード等はせず、grubにおいてマニュアルで Previous Linux versions から選択していたのだが面倒。

デフォルトで古いバージョンのカーネルを動作させる方法を調べるとここにあった。
/etc/default/grub の GRUB_DEFAULT でサブメニューまでのデフォルト値まで指定できる。

2011/12/15

Ubuntu 11.10 autofs5/synax error in nsswitch の対処

autofs5 をインストールしたら次のエラーが出た。


  syntax error in nsswitch config near [ synax error ]


ここにバグとして挙がっていた。
/etc/nsswitch に次のエントリーを追加すると直った。

  automount: files



2011/10/17

LinuxでLoadable Moduleをデバッグする

Linux のloadable moduleをデバッグしたときのメモ。
元ネタはO'Reillyの"Linuxデバイスドライバ"。
static linkしたモジュールはgdbでvmlinuxを読み込めばシンボル情報が読み込まれるが、loadable moduleは一手間かけないとシンボルが見えない。

ここでは uvcvideo モジュールをデバッグ対象とする。
まず、ターゲットとなるモジュールの.text, .bss, .dataのアドレスを得る。

# cat /sys/module/uvcvideo/sections/.{text,bss,data}
0xf86c6000
0xf86d4560
0xf86d3000


続いてデバッガでシンボルを追加する。カレントディレクトリはLinuxカーネルソースのディレクトリ。

(gdb) add-symbol-file drivers/media/video/uvc/uvcvideo.ko 0xf86c6000 -s .bss 0xf86d4560 -s .data 0xf86d3000


これで関数名を指定してブレークポイントを置いたり、ソースを追いながらステップ実行できるようになる。
もう少し楽にやる方法はないかと思う。

なお、.ko にデバッグ情報を残すにはモジュールのソースディレクトリにある Makefile に、

EXTRA_CFLAGS += -O0 -g


などと記述しておけば良い。

ついでにモジュールのみのビルド方法は、カーネルソースのトップディレクトリにおいて、"make M=[モジュールのディレクトリ]"。

2011/10/15

カーネルをデバッグするためのGRUB2設定

Ubuntu 11.04でカーネルデバッグをしたときの設定です。
VMWare同士でシリアルポートを接続する方法で、baudrate 115200で接続。

* デバッグ対象のOS

- /boot/grub/grub.cfg のデバッグしたいカーネルの menuentry をコピーして、新しい menuentry を追加する。
- 追加した menuentry の "linux" のパラメータに "kgdboc=ttyS0,115200 kgdbwait" を追加する。以下は一例。


menuentry 'Ubuntu, with Linux 2.6.38.8 (debug)' --class ubuntu --class gnu-linux --class gnu --class os {
    recordfail
    set gfxpayload=$linux_gfx_mode
    insmod part_msdos
    insmod ext2
    set root='(hd0,msdos1)'
    search --no-floppy --fs-uuid --set=root ba000129-5c3a-403c-9107-3d7649a4d051
    linux    /boot/vmlinuz-2.6.38.8 root=UUID=ba000129-5c3a-403c-9107-3d7649a4d051 ro kgdboc=ttyS0,115200 kgdbwait
    initrd    /boot/initrd.img-2.6.38.8
}



- 再起動時にSHIFTキーを押し続けてブートメニューを表示し、追加した menuentry に対応する項目を選ぶ。

* デバッガを起動するOS

GRUBとは関係ないが、ついでにデバッガ側の作業も記述しておく。
カーネルをビルドしたディレクトリに移動して、gdbを起動。以下のコマンドを入力。.gdbinit に記述しておいても良い。


(gdb) file ./vmlinux
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0



# GRUB2とはバージョン1.9以降を指すそうだ。ややこしい...。

2011/09/15

VMWare / Android x86 にadbで接続する

よく忘れるのでメモ。

* ゲストOS (Android)側

  - IPアドレスを調べる。
    # netcfg
    (ifconfigではない)

* ホストOS側

  - Androidデバイスに接続する。
    # adb connect [ゲストOSのIPアドレス]

  - 接続したデバイスを確認する。
    # adb devices

デフォルトのポート番号は 5555。
ポート番号を例えば 5678 に変更したいときは、次のようにする。

* ゲストOS側

  # setprop service.adb.tcp.port 5678
  # kill `pgrep adbd`

* ホストOS側

  # adb connect [ゲストOSのIPアドレス]:5678

2011/08/25

HTC Desireでb-mobile talking Fairを使う

現在 HTC Desire (X06HT, CyanogenMod 6.1.1) に b-mobile talking Fair のSIMを挿して使い始めた。

元々 b-mobile Fair を契約していたが、以下の理由により移行した。
  • 携帯電話とスマフォを2台持ち歩くのが面倒だったので、1つにまとめたかった。
  • 普段電話はそれほど使わないので、電話の基本料金も安く抑えたかった。
  • b-mobile Fair 販売開始直後に契約して3ヶ月半、そろそろ更新の時期だった。b-mobile も更新のタイミングで talking Fair の製品発表をしたのだろう。
携帯は11年以上使っていたauの最安プランSS。au の解約料金と b-mobile talking Fair の初期費用を含めて計算したところ、私の場合は13ヶ月目以降に2台持ちよりも支払いが少なくなるようだ。ちょっと長いが1台になる利便性を考えると移行して良かったと思う。

# au の"誰でも割"解約料は11年目以降に安くなる。11年に達していなければ、移行費用を回収できる期間がさらに長くなるので、契約更新月まで待ったほうがトータルで安くなりそう。
# ちなみに b-mobile は契約期間1年未満で解約料10,500円が発生。

留守電等のオプションサービスは契約していない。
Android Marketから "圏外着信お知らせツール" をインストールして試したら、問題なく動作した。これは便利。

ところでちょっとしたことだが、b-mobile Fair から talking Fair の SIM に変更したら、電波強度のところに HSDPA の "H" が表示されるようになった。Fair でも通信速度を見ると HSDPA は有効になっていたので表示が変わったというだけ。

2011/06/02

Androidでb-mobile Fair 30日間の通信量

5/1-5/31の使用量: 81MB

外出した日の使用量は2MB〜8MBの範囲。
主な用途はメール・ブラウザ・RSSリーダー。
たまにアプリをダウンロード。
5月は休日に外出することが少なかったので、平均的な月より比較的通信量が低めだったと思われる。
この調子で行くと半分以上余る。

2011/05/21

Bloggerでエクスポート/インポートするとURLが変わる

ちょっとブログの記事をまとめて変更したいことがあったので、エクスポート->記事を全て削除->エクスポートしたXMLを編集->インポート をしたら記事のURLが変更されてしまった....。
記事の中の記事へのリンクも手動で変更するハメに。
しばらくGoogleのインデックスも更新されないし、やらなきゃ良かった。

2011/05/17

Android DNSの設定を変更する

bionic libcのソースコードとドキュメントを見て以下のことがわかった。

net.dns[n].[pid] => net.dns[n] => /etc/resolv.conf
の順番でDNSを見る。

[n] : 1-8
[pid] : プロセスID


* プロセス毎の設定

system propertyのnet.dns[n].[pid]で、プロセス毎にDNSの設定ができるようになっている。
この設定が対象のプロセスにおいて見つかった場合、nが一致するnet.dns[n] は使われない。
Androidの開発においてはよほど特殊なことをしない限り、プロセス毎の設定を利用することはないだろう。


* グローバルな設定

1. net.dns[n]にDNSのIPアドレスを設定する。
2. net.dnschange の値を現在値とは別の整数値に設定する。通常この値はインクリメントされている。

net.dnschange (ここではカウンターと呼ぶことにする)はnet.dns#が変更されたことを検知するための整数値。
前回DNS Queryを発行しようとしたときと異なる値のとき、net.dns#が再読み込みされる。
libcが覚えるカウンター値はstatic変数なので、プロセスごとにカウンターによるDNS更新の判断を行っている。
javaでの実装方法は、ConnectivityServiceが参考になる。


* 補足

WiFiや3GをONにすると、net.[interface name].dns[n] が変更されて、その値の1つが net.dns[n] に設定される。

/etc/resolv.conf も見る実装がソースには残っていたが、#ifdef ANDROID_CHANGES によって除外されていた。

以下、覚書として"dns"を含むsystem propertyを挙げる。


$ adb shell getprop | grep dns
[net.change]: [net.dnschange]
[net.dns1]: [192.168.3.254]
[net.rmnet0.dns1]: [202.32.159.24]
[net.rmnet0.dns2]: [210.128.58.10]
[net.dns2]: []
[net.dnschange]: [118]
[dhcp.eth0.dns1]: [192.168.3.254]
[dhcp.eth0.dns2]: []
[dhcp.eth0.dns3]: []
[dhcp.eth0.dns4]: []
[net.eth0.dns1]: [192.168.3.254]
[net.eth0.dns2]: []
[net.dns3]: []

2011/05/16

Androidでb-mobile Fair 15日間の通信量

5/1-5/15の使用量: 28MB

連休中に出かけることが少なかったとはいえ、少なすぎる...。
目標値の3分の1以下。日中に節約しすぎた。
仕事中にメールは見ないので、休憩時間以外は3Gを切っていた。

主な用途はメール・ブラウザ・RSSリーダー。
RSSリーダーでのフィードの取得はWiFiで行っていた。
なので、通勤中のメールとブラウザの使用が主な内訳。

しかしまあ、あと105日使えるのだから、気分は良い。
4ヶ月/500MB/¥5000 という少しだけ割高なライトプランを出しても売れるのではなかろうか。

2011/05/14

AndroidのProxy設定のないアプリにProxyを越えさせる(HTTP+少しHTTPS)

DeleGateとwebnamedを使い、Proxy設定のないアプリでファイアウォールを越えてHTTP/HTTPS通信することに成功した。

こちらのブログを参考にさせてもらった。
DeleGateとwebnamedのネットワーク構成は"AndroidのProxy設定のないアプリにProxyを越えさせる(HTTPのみ)"に書いた図の、squidがDeleGateに置き換わったもの。

文末にDeleGateのinit scriptを示す。
参考元のスクリプトと主に違うところは、

- chkconfigに対応している
- DeleGateが参照するDNSサーバをwebnamedノードにしている
(192.168.3.10 がwebnamed、192.168.3.20:80 がProxy)

さて、題名に"少しHTTPS"とある理由だが、DeleGateのSSL透過プロキシ機能はman-in-the-middleな仕組みなので、サーバ証明書の検証をスキップする機能があるアプリでないと、HTTPSを使えない。

Dolphin Browserを試したところ、HTTPSでアクセスすると"アクセスしようとしているサーバ名が証明書と違うがどうするか?"という意味の警告が表示され、そのままページを開くかどうか選択できる。Gmailを開くことができた。
NewsRobはGoogle Readerから同期する際にExceptionが発生して、同期することができなかった。後日他のRSS Readerを試してみようと思う。

/etc/init.d/delegate:

#!/bin/sh
# chkconfig: 345 98 20
# description: delegate server
# processname: delegated

DAEMON=/usr/local/bin/delegated
DGROOT=/var/spool/delegate
DELEGATE_PORT=8080
PROXY_HOST=192.168.3.20
PROXY_PORT=80
DNS_SERV=192.168.3.10

test -x $DAEMON || exit 0

start_proc() {
$DAEMON DGROOT=$DGROOT -P$DELEGATE_PORT \
PROXY="$PROXY_HOST:$PROXY_PORT:*" \
PERMIT="http,https:*:*" \
REMITTABLE=http,https \
STLS=mitm \
RELAY=vhost RES_NS="$DNS_SERV,END"
}

stop_proc() {
$DAEMON DGROOT=$DGROOT -P$SRC_PORT -Fkill
}

case "$1" in
start)
start_proc
;;
stop)
stop_proc
;;
restart)
stop_proc
if [ "$?" != "0" ]; then
exit 1
fi
start_proc
;;
*)
echo "Usage: $0 start|stop|restart"
exit 1
;;
esac

2011/05/12

rgrepでソースコードを検索する

私はC/Javaのソースコードを検索するときvim/eclipse/ctags/globalを使うが、ソースコードを解析するときに比較的rgrepを使うことが多い。

git/svnレポジトリから取得したソースコードを検索するときのために、以下のaliasを定義している。


alias rgrep='rgrep --exclude="*\.o" --exclude="*\.class" --exclude="*\.dex" --exclude="*\.swp" --exclude="tags" --exclude="GTAGS" --exclude="GSYMS" --exclude="GRTAGS" --exclude="GPATH" --exclude-dir="*\.git" --exclude-dir="*\.svn"'

2011/05/10

HTC Desire - CyanogenMod 6.1.1のバッテリー消費量(WiFi)

以下の状態において、8時間で100%=>%94 だった。
意外と減り幅が少ない印象。

- Wifi ON, 3G OFF
- K9-Mail : IMAP Idle 2アカウント, メール1件取得して6時間LED点滅
- NewsRob : 1時間毎の同期、100件くらい自動取得
- なまず速報β (速報なし)


#追記 5/11

以下の使い方で、100%=>70%

- 7.5時間WiFi、NewsRobで220件くらい自動取得、ほとんどスリープ状態
- 3時間3G、1.5時間ほどNewsRobやブラウザを使う。
- 通信量: WiFi 3.9MB、3G 4.0MB

2011/05/09

AndroidのProxy設定のないアプリにProxyを越えさせる(HTTPのみ)

ここで紹介する方法は動作はするが役立つ場面が少ない。

squid透過プロキシとProxy越えをするDNS Serverを使って、プロキシ設定のできないアプリにファイアウォールを越えさせることに成功した。

ただし、squid透過プロキシの仕組み上、HTTPSは通すことができない。squid 3.1のssl-bumpというman-in-the-middleな機能を使うとできそうだが、制約が大きそうなのでやらない。
HTTPSを通せないので、大抵HTTPSが必要なアカウント認証するWebアプリが使えないのが痛い。

これだけやってもHTTPのみ...。
はっきり言って、プロキシ設定ができるOpera Mobileだけの方が役に立つ。

以下、検証した構成。
Androidからsquidへは、iptables で80 portをsquidのホストの3128 portへリダイレクトした。

#追記 5/14
その後、squidの代わりにDeleGateを使ってHTTPSを通すことに成功した。


                       +-----------------------+
                       |  android smart phone  |
                       +-----------------------+
                          |                |
                          | DNS query      | http
                          v                v 
                    +----------+     +-------------+
                    | webnamed |     |   squid     |
                    +----------+     |(transparent)|
                          |  |       +-------------+
                DNS query |  |  http        |
                          v  +---------+    | http
                    +------------+     |    |
                    | DNS Server |     |    |
                    +------------+     v    v 
                                     +-------------+
                                     | http proxy  |
                                     |  firewall   |
                                     +-------------+
                    +--------------+   |    |
                    | resolver.cgi |<--+    | http
                    +--------------+        v
                           |         |-------------+
                 DNS query |         |   web site  |
                           v         +-------------+
                    +------------+
                    | DNS Server |
                    +------------+

2011/05/08

Androidの非公開APIを呼ぶ

リフレクションを使うと、Android SDKには公開されていないAPIを呼び出すことができる。
公開されていないAPIなので、バージョンごとの互換性が失われる可能性が高いことに注意。

以下はUSBテザリングをONにする処理。


ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(CONNECTIVITY_SERVICE);

Class c = Class.forName(cm.getClass().getName());
Field f = c.getDeclaredField("mService");
f.setAccessible(true);
Object iconn = f.get(cm);

// Method: int tether(String iface)
Method method_tether = iconn.getClass().getMethod("tether", String.class);
Object ret = method_tether.invoke(iconn, "usb0");

// Returns ConnectivityManager.TETHER_ERROR_*
int e = ((Integer) ret).intValue();

2011/05/07

Android K-9 Mail 待機時の通信量を節約する(2)

K-9 Mail通信量計測の詳細。

* 条件

- b-mobile Fair
- K-9 Mail v3.706
- Gmailの1アカウント、SSL、受信トレイが空の状態。


* 計測結果

計測値はIMAP同期が5回の同期での平均値、IMAP IDLEが1時間の間に発生した通信の平均値。
()内は128 Bytes換算のパケット数

[IMAP同期の同期毎の平均値]
- IPパケット数 = 12 (12)
- IPパケットサイズ合計 = 2.01 KBytes

[IMAP IDLEの平均値 (リフレッシュ間隔24分)]
- IPパケット数 = 5分毎に12 (12), 初回接続時に47 (62)
- IPパケットサイズ合計 = 5分毎に1.54 KBytes, 初回接続時に8.47 KBytes


* どちらが節約できるか

5分毎のIMAP同期とIMAP IDLEは、パケット数においてほぼ同等と見なせる。
したがって、メールが通知されるまで5分以上かかっても良い人はIMAP同期の方が節約できて、それほど待てない人はIMAP IDLEにするしかない。IDLE接続のリフレッシュ時間はデフォルトの24分が良い。


* パケット数の算出について

実測したパケット数はIPパケット数なので、モバイルデータ通信時のパケット数はもっと多くなるかもしれない。
節約するならばデータサイズだけでなく、パケット数の削減を考えなければならない。
実際は単純には計算できないと思うが、b-mobile Fairのサイトでは便宜上1パケット=128 Bytesで計算する方法を紹介している。
私はモバイルデータ通信のプロトコルについて詳しくないので、この方法にあやかってみる。

b-mobile Fairでは4ヶ月で1GBytesまでという契約だが、通信量とパケット数は関係する。
b-mobileのサポートに問い合わせて見たら、純粋な送受信したいデータの他にヘッダ、デリミタといったオーバヘッドも通信量として計算されるので、100バイトを1回送信するよりも1バイトを100回送信する方が通信量が多いということだ。


* IMAP IDLE接続のタイムアウト

IMAP IDLEの5分毎というのはサーバから送られてくるKeepAliveのパケットだと思われる。
IMAP IDLE接続のリフレッシュ間隔とは関係がない。
上記のパケット以外に、約25分間隔でFINパケットが来た。FINパケットの後、K-9 Mailは同一のIPアドレスへ再接続した。
そして特筆すべきは、たまにRSTパケットがサーバから来た。RSTパケットが来る条件は不明。
RSTは接続を強制終了する要求であり、K-9 Mailが再接続を試みたようだが、さらにRSTが返された。
RSTに続く通信は9.27 KBytes、54(69)パケットのやりとりが発生した後に別のサーバへ接続。
これらの現象はIMAP IDLE接続のタイムアウトと関係しているようだが、明確な仕様がわからなかった。

FIN、RSTはIDLE接続のリフレッシュ時間を24分(デフォルト)に設定しておくと返されない。
そのかわり、リフレッシュ間隔毎に再接続のためのやりとりが発生する。
デフォルトが24分なのはFINが返ってくる25分という時間と関係があるのかもしれない。

Android K-9 Mail 待機時の通信量を節約する(1)

私はb-mobile Fairの回線を使用し、メーラーはK-9 Mailを使っている。
待機時のメーラーの通信量が気になったので、パケット代節約の方法を探るために計測した。

ここでの計測対象はGmailに限った話しで、他のメールサーバだと結果が異なるかもしれない。

結論を言うと、
  • プッシュ接続(IMAP IDLE)より、5分より大きい間隔での定期的な同期(IMAP同期)の方が、パケット数的にはお得。
  • 節約したいならばIMAP同期で同期時間を10分以上に設定。
  • 節約したいけどプッシュ通知は必須というときは、IMAP IDLEのリフレッシュ時間を24分(デフォルト)に設定。
  • いずれにせよ、1ヶ月で5~6万パケットの大した数ではないので、倹約家以外はあまり気にする必要はなさそう。

である。

詳細は Android K-9 Mail 待機時の通信量を節約する(2) に。


補足としては、どちらの方法でも取得するフォルダの数は少ない方が通信量を節約できる。
K-9 Mailではプッシュフォルダの数だけ通信の接続数が増えるようだ。

私はK-9 Mailでプッシュフォルダを"1stクラスフォルダのみ"として、受信トレイのみを1stクラスに設定している。
基本的に受信トレイからの振り分けはPCからまとめてやっている。

逆USBテザリングでメール待ち受けができるCyanogenModパッチ(2)

環境: Ubuntu 10.10 Desktop, HTC Desire, CyanogenMod 6.1.1

前回のパッチの欠点を改善したものを作った。一応patchと、jarを固めたzipをここに置いてある。

このパッチにできることは、次のとおり。

- 一度だけAndroidとPCに設定をしておけば、USBケーブルを刺したときに通信できるようになる。
- 逆USBテザリングと通常の正方向のUSBテザリングを切り替えられる。

これで晴れて快適な逆USBテザリング生活?ができるようになった。

必要な設定は
- PC
    USB RNDIS (Ubuntuだとusb0)のPC側IPアドレスを固定アドレスにする。
- Android
    システムプロパティを設定する。
    - usb.reverse.dns1 ... DNSアドレス
    - usb.reverse.gw ... PC側のusb0のアドレス
    これらのプロパティのいずれかが空のとき、通常のUSBテザリングになる。

RNDISドライバさえあれば他のOSでも動くはずだが、試していない。


以下、設定方法。

ここに記述してあることは当然上記パッチをAndroidに焼かないと動作しないので、あしからず。

AndroidをUSBで接続したときに現れるusb0インターフェースのIPアドレスを固定する。

Ubuntu Desktopに標準インストールされるNetwork Managerとethtoolではこれができなかった。なぜなら、usb0のMACアドレスは接続するたびに変化する。Network Managerが前回接続したことのあるインターフェースであると認識せず、usb0に施したはずの設定が反映されない。

ということで、Network Managerは消して、/etc/network/interfaces での運用に変更する。
# Network Managerと共存する方法があるかもしれないが、私は上手く行っていない。


# apt-get remove network-manager



これは私の環境のinterfaces。usb0 以外の設定は、環境に合わせて変更する必要がある。
usb0 のPC側アドレスは 192.168.42.100 とする。192.168.42.0/24 のうち、192.168.42.129 以外なら他のアドレスでも良い。

PC: /etc/network/interfaces

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto usb0
iface usb0 inet static
    address 192.168.42.100
    netmask 255.255.255.0 



Androidで次のファイルを作成する。system partitionなのでadb remountや、recovery modeで変更する。

android: /data/local.prop:

net.dns1=
usb.reverse.dns1=
usb.reverse.gw=



Androidを再起動する。
PCからadbでシステムプロパティの値を設定する。
192.168.3.254 はDNSのアドレスなので、環境に合わせて変更する。


adb shell setprop usb.reverse.dns1 192.168.3.254
adb shell setprop usb.reverse.gw 192.168.42.100



以上で設定完了。

この状態でAndroidをUSBケーブルでPCに接続し、USBテザリングを有効にしてWebブラウザ等が使用できるかを確認する。
なお、Android Marketでダウンロードできないときは、Google Talkに一度ログインするとダウンロードが開始するかもしれない。

通常の正方向のUSBテザリングに戻したいときは、usb.reverse.dns1かusb.reverse.gwを空にすれば良い。

adb shell setprop usb.reverse.gw ""



このパッチでも不便な点がある。
それは複数の異なるLAN上のPCに接続するとき、DNSとゲートウェイの設定を変更しなければならないことだ。

2011/05/06

git pullとgit pull --rebaseの違い

git pull          ... git fetch, git merge [origin/master]
git pull --rebase ... git fetch, git rebase [origin/master]

古いgitだと git pull に --rebase オプションがない。


それでは merge と rebase の違いは?というと、他に詳しく説明しているページをご参考に。

はしょって言うと、次のとおり。

個人のブランチに他のコミットを取り込む ... rebase
公開されたコミットを統合する ... merge (rebaseしてはいけない)

ADWLauncherで地味にうれしいこと

アイコンをドラッグしてゴミ箱に入れるとき、1秒くらい待つと"アンインストールしますか?"と聞いてくる。
アプリケーションの管理を開かなくてもアンインストールできる。
アプリの入れ替えをちょくちょくやるのでうれしい。