2009年12月14日月曜日

lisp の quicksort

まぁ、まだ元気だよ。と言うことで、とっても久しぶり。

年に一度位。歳と共に頻度が少なくなる気がするけど SICP を中途半端なまま眺めたりすることがある。少し前くらいかな。関数型言語が流行ったらしくていくつか入門書らしきものも購入したり。その中に Haskell の quick ソートがあった。3.1 Quicksort in Haskell
qsort []     = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)
すんごいシンプル。
  • 遅延評価
  • 副作用はモナドが引き受ける
あたりが魅力的。同じようなものは...と探したところ、Lisp のものもあった。swisspig.net - The Beauty of a Lisp Quicksort
(defun quicksort (lis) (if (null lis) nil
(let* ((x (car lis)) (r (cdr lis)) (fn (lambda (a) (< a x))))
(append (quicksort (remove-if-not fn r)) (list x)
(quicksort (remove-if fn r))))))
で、拙い Scheme では....
(use srfi-1)

(define (qsort lst)
(if (null? lst) '()
(let* ((x (car lst))
(r (cdr lst)))
(append
(qsort (filter (lambda (a) (< a x)) r))
(list x)
(qsort (filter (lambda (a) (>= a x)) r))))))
さらに Shiro さん の続きを早く読みたい なんでも継続を眺めつつ.... こんな感じなのかなぁ。
(define (qsort/cps lst cont)
(if (null? lst) (cont '())
(let* ((x (car lst))
(r (cdr lst)))
(qsort/cps (filter (lambda (a) (< a x)) r)
(lambda (n)
(qsort/cps (filter (lambda (a) (>= a x)) r)
(lambda (m) (cont (append n (list x) m)))))))))
メジャーどころの Python でも同じようにするには、こんなん?
def qsort(lst):
if len(lst) < 1: return []

x = lst[0]
r = lst[1:]

return qsort([i for i in r if i < x]) \
+ [x] \
+ qsort([i for i in r if i >= x])

2009年6月30日火曜日

lxc の (今までの) ごめんなさい

いくつか嘘ついていました。
devpts
lxc.mount に指定する fstab にて devpts を
/dev/pts /opt/lxc/sshd/rootfs/dev/pts none bind,newinstance 0 0
なんて書いていましたが、意図した正しくは
lxcpts /opt/lxc/sshd/rootfs/dev/pts devpts newinstance,ptmxmode=0666 0 0
でした。

quagga のユーザ、グループ
ホスト側とコンテナ内の uid gid が一致しないと動きませんでした。修正しましたので、良ろしかったらお試し下さい。quagga はこちら。sshd はこちらです。debian/lenny の amd64 です。i386 の方は fstab から /lib64 削除すれば動くと思います。

/usr/local/lib の liblxc-*.so
やっぱ /usr/lib にコピーした方が良さげです。相変わらずの勉強不足で ld.so.cache のフォーマットが x86_64 と i386 が同じで良いかわからず、動かせませんでした
付き合ってくれた人、ごめんなさい。

2009年6月23日火曜日

veth に ping

lxc で使っている veth は OpenVZ 由来だそうだ。何かちょっと不思議に思って veth 作って ping 投げてみた。
# ip link add type veth
# ip link ls veth0
11: veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 9a:87:c9:92:6b:91 brd ff:ff:ff:ff:ff:ff
# ip link ls veth1
12: veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 42:01:93:00:97:d9 brd ff:ff:ff:ff:ff:ff
# ip link set veth0 up
# ip link set veth1 up
# ip addr add 192.168.1.10/24 dev veth0
# ip addr add 192.168.1.11/24 dev veth1
# ping -c 4 192.168.1.10
PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=0.074 ms
64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from 192.168.1.10: icmp_seq=3 ttl=64 time=0.070 ms
64 bytes from 192.168.1.10: icmp_seq=4 ttl=64 time=0.072 ms

--- 192.168.1.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.070/0.072/0.074/0.006 ms
# ping -c 4 192.168.1.11
PING 192.168.1.11 (192.168.1.11) 56(84) bytes of data.
64 bytes from 192.168.1.11: icmp_seq=1 ttl=64 time=0.094 ms
64 bytes from 192.168.1.11: icmp_seq=2 ttl=64 time=0.026 ms
64 bytes from 192.168.1.11: icmp_seq=3 ttl=64 time=0.078 ms
64 bytes from 192.168.1.11: icmp_seq=4 ttl=64 time=0.069 ms

--- 192.168.1.11 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.026/0.066/0.094/0.027 ms
まぁ loopback みたいな感じ。で veth0 から veth1 - 192.168.1.11 に ping 投げてみると
# ping -I veth0 192.168.1.11
PING 192.168.1.11 (192.168.1.11) from 192.168.1.10 veth0: 56(84) bytes of data.
From 192.168.1.10 icmp_seq=2 Destination Host Unreachable
From 192.168.1.10 icmp_seq=3 Destination Host Unreachable
From 192.168.1.10 icmp_seq=4 Destination Host Unreachable
音沙汰なしっ。tcpdump で眺めてみると
# tcpdump -ntei veth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth0, link-type EN10MB (Ethernet), capture size 96 bytes
9a:87:c9:92:6b:91 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: arp who-has 192.168.1.11 tell 192.168.1.10
9a:87:c9:92:6b:91 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: arp who-has 192.168.1.11 tell 192.168.1.10
9a:87:c9:92:6b:91 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: arp who-has 192.168.1.11 tell 192.168.1.10
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
# tcpdump -ntei veth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth1, link-type EN10MB (Ethernet), capture size 96 bytes
9a:87:c9:92:6b:91 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: arp who-has 192.168.1.11 tell 192.168.1.10
9a:87:c9:92:6b:91 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: arp who-has 192.168.1.11 tell 192.168.1.10
9a:87:c9:92:6b:91 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: arp who-has 192.168.1.11 tell 192.168.1.10
9a:87:c9:92:6b:91 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: arp who-has 192.168.1.11 tell 192.168.1.10
^C
4 packets captured
4 packets received by filter
0 packets dropped by kernel
lxc 追って調べてみるのは面倒だなぁ。と Google 先生に相談したところ lxc の前、ns_exec なるソースを見つけた。既に昔のものになっているらしく
  • ここから持ってきたけど無くなりそうなので
  • ちょっと変更して
    --- ns_exec.c.orig 2009-06-21 23:02:41.000000000 +0900
    +++ ns_exec.c 2009-06-21 23:03:08.000000000 +0900
    @@ -12,7 +12,7 @@
    #include <sys/wait.h>
    #include <sys/mount.h>

    -#include "clone.h"
    +#include <linux/sched.h>

    extern pid_t getpgid(pid_t pid);
    extern pid_t getsid(pid_t pid);
  • ローカルコピー
コンパイルして起動してみる
# cc -o ns_exec ns_exec.c
# echo $$
30530
# ./ns_exec -c -n /bin/bash
about to clone with 40000000
# echo $$
30549
# ip link ls
28: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
29: gre0: <NOARP> mtu 1476 qdisc noop state DOWN
link/gre 0.0.0.0 brd 0.0.0.0

で PID 30549 に veth1 を渡してあげる
(って言い回しが正しいかわからないけど - 別ターミナルから)
# ip link set veth1 netns 30549
ns_exec したターミナルに戻ってみると
# ip link ls
28: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
29: gre0: <NOARP> mtu 1476 qdisc noop state DOWN
link/gre 0.0.0.0 brd 0.0.0.0
31: veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 1e:cf:fa:8f:a4:4b brd ff:ff:ff:ff:ff:ff
おぉ、わたってる。リンク上げたりアドレス設定すると期待通り
# ip link set veth1 up
# ip addr ls
28: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
29: gre0: <NOARP> mtu 1476 qdisc noop state DOWN
link/gre 0.0.0.0 brd 0.0.0.0
31: veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 1e:cf:fa:8f:a4:4b brd ff:ff:ff:ff:ff:ff
inet6 fe80::1ccf:faff:fe8f:a44b/64 scope link
valid_lft forever preferred_lft forever
# ip addr add 192.168.1.11/24 dev veth1
# ping -I veth1 192.168.1.10
PING 192.168.1.10 (192.168.1.10) from 192.168.1.11 veth1: 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=3.72 ms
64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=0.131 ms
64 bytes from 192.168.1.10: icmp_seq=3 ttl=64 time=0.108 ms
64 bytes from 192.168.1.10: icmp_seq=4 ttl=64 time=0.111 ms
^C
--- 192.168.1.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.108/1.019/3.727/1.563 ms

なぜ?

例のごとく深く追ってないけど....ARP については
veth_xmit()::driver/net/veth.c
netif_rx()::net/core/dev.c
net_rx_action()::net/core/dev.c - softirq
process_backlog()::net/core/dev.c - dev->poll()
netif_receive_skb()::net/core/dev.c
arp_rcv()::net/ipv4/arp.c
arp_process()::net/ipv4/arp.c
arp_ignore()::net/ipv4/arp.c
inet_confirm_addr()::net/ipv4/devinet.c
confirm_addr_indev()::net/ipv4/devinet.c
この内 inet_confir_addr() から引用
struct net *net;
....
net = dev_net(in_dev->dev);
....
for_each_netdev(net, dev) {
if ((in_dev = __in_dev_get_rcu(dev))) {
addr = confirm_addr_indev(in_dev, dst, local, scope);
struct net は include/net/net_namespace.h で定義されている。上記はネットワークの「名前空間毎に」 net_device / in dev を保持していて、これを加味した上で指定された IP アドレスがローカルか否か判断しているらしい。

ローカルだよ (って表現も上手くないと思うけど) って判断が下り通常は arp_process() にて ARP に応答しない。ns_exec で CLONE_NEWNET してあると、ローカルと判断しない... ``らしい'' ばかりでごめんなさい。

2009年6月15日月曜日

rt73usb rt2500usb で hostapd

相変わらずの TXDONE_UNKNOWN
2.6.30 がリリースされたけど /drivers/net/wireless/rt2x00/rt2x00usb の TXDONE_UNKNOWN については以前のまま。チェックしている辺を grep すると何となく....
$ fgrep -C 4 'test_bit(TXDONE' *.c
rt2x00dev.c- /*
rt2x00dev.c- * Update TX statistics.
rt2x00dev.c- */
rt2x00dev.c- rt2x00dev->link.qual.tx_success +=
rt2x00dev.c: test_bit(TXDONE_SUCCESS, &txdesc->flags);
rt2x00dev.c- rt2x00dev->link.qual.tx_failed +=
rt2x00dev.c: test_bit(TXDONE_FAILURE, &txdesc->flags);
rt2x00dev.c-
rt2x00dev.c- rate_idx = skbdesc->tx_rate_idx;
rt2x00dev.c- rate_flags = skbdesc->tx_rate_flags;
rt2x00dev.c-
--
rt2x00dev.c- tx_info->status.rates[0].count = txdesc->retry + 1;
rt2x00dev.c- tx_info->status.rates[1].idx = -1; /* terminate */
rt2x00dev.c-
rt2x00dev.c- if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
rt2x00dev.c: if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
rt2x00dev.c- tx_info->flags |= IEEE80211_TX_STAT_ACK;
rt2x00dev.c: else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
rt2x00dev.c- rt2x00dev->low_level_stats.dot11ACKFailureCount++;
rt2x00dev.c- }
rt2x00dev.c-
rt2x00dev.c- if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
rt2x00dev.c: if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
rt2x00dev.c- rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
rt2x00dev.c: else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
rt2x00dev.c- rt2x00dev->low_level_stats.dot11RTSFailureCount++;
rt2x00dev.c- }
rt2x00dev.c-
rt2x00dev.c- /*
上の方はリンク品質、結果送信レートに。下の方が肝心の hostapd で送信可否の判断材料IEEE80211_RADIOTAP_F_TX_FAILになるらしい
$ cd net/mac80211/
$ fgrep -C 2 IEEE80211_RADIOTAP_F_TX_FAIL *.c
main.c- if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
main.c- !is_multicast_ether_addr(hdr->addr1))
main.c: rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
main.c-
main.c- /*
で、仕方が無いと言うか無理矢理稼働させるがための二行パッチ
$ cd drivers/net/wireless/rt2x00/
$ diff -ubB rt2x00usb.c.orig rt2x00usb.c
--- rt2x00usb.c.orig 2009-06-15 20:14:27.000000000 +0900
+++ rt2x00usb.c 2009-06-15 20:14:53.000000000 +0900
@@ -200,7 +200,7 @@
*/
txdesc.flags = 0;
if (!urb->status)
- __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
+ __set_bit(TXDONE_SUCCESS, &txdesc.flags);
else
__set_bit(TXDONE_FAILURE, &txdesc.flags);
txdesc.retry = 0;

コンパイル
hostapd を git やら CVS やらで持って来てl.... 後出しじゃんけんだけど
$ ldd /usr/local/sbin/hostapd
linux-vdso.so.1 => (0x00007fff06b95000)
libnl.so.1 => /usr/lib/libnl.so.1 (0x00007f8916e67000)
libssl.so.0.9.8 => /usr/lib/libssl.so.0.9.8 (0x00007f8916c16000)
libcrypto.so.0.9.8 => /usr/lib/libcrypto.so.0.9.8 (0x00007f891687b000)
libc.so.6 => /lib/libc.so.6 (0x00007f8916528000)
libm.so.6 => /lib/libm.so.6 (0x00007f89162a5000)
libdl.so.2 => /lib/libdl.so.2 (0x00007f89160a1000)
libz.so.1 => /usr/lib/libz.so.1 (0x00007f8915e8a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f89170b6000)
openssl と libz ほか libnl が必要。debian/lenny では libnl1 libnl-dev でバージョンが 1。どうも新しい方が良さそうなので git で持って来た方が吉。以前の $HOSTAPD/defconfig には CONFIG_LIBNL20 なんてあったけど、今は無し。まとめて
  • git などで hostapdlibnl 持ってくる
  • lib〜-dev は libc6-dev zlib1g-dev libssl-dev
  • libnl を ./configure --prefix=/usr/local でコンパイル & ld.so.conf 周りに /usr/local/lib が含まれていること確認して ldconfig
  • hostap/hostapd に移って defconfig を .config に変更。適当に変更するも CONFIG_DRIVER_NL80211=y は忘れずに

その他
やべ、面倒になってきた....国によって異なる利用可能な無線スペクトラム? に従うために、この辺りも、多分最近のものは必須。これらコンパイルに必要な追加パッケージは crda の README に書かれている通り python-m2crypto。
同じく crda の方で make install すると udev の rule が /usr/lib/udev/rules.d/85-regulatory.rules にコピーされてしまうので /etc/udev/rules.d/ に移してあげるコト。

おまけ
  • It's All Text なるもの試してみました。ラクチンだけど考えまとめてないと、こんな風にとりとめなくウダウダは相変わらず。
  • Wikipedia の 802.11 カテゴリがまとまっている。
  • Adobe labs からの 64bit 版 Adobe Flash Player 10 でも Googlel/検察ツール/ワンダーホイールで落ちる....

# チラシの裏

2009年6月9日火曜日

quagga on lxc

T/O debian/lenny amd64 でやってみました。こちらにイメージ? 置いときます。/opt/lxc 配下に展開仮定なので fstab を適宜直して使ってやって下さい。# レイノゴトクルートデ....
# seq とゆーもの覚えた。
# for i in `seq 0 7`; do
> br=br${i}
> brctl addbr $br
> brctl setfd $br 0
> brctl stp $br off
> ip link set $br up
> done

# ip link ls | grep "br[0-7]"
630: br0: mtu 1500 qdisc noqueue state UNKNOWN
631: br1: mtu 1500 qdisc noqueue state UNKNOWN
632: br2: mtu 1500 qdisc noqueue state UNKNOWN
633: br3: mtu 1500 qdisc noqueue state UNKNOWN
634: br4: mtu 1500 qdisc noqueue state UNKNOWN
635: br5: mtu 1500 qdisc noqueue state UNKNOWN
636: br6: mtu 1500 qdisc noqueue state UNKNOWN
637: br7: mtu 1500 qdisc noqueue state UNKNOWN
# ip addr add 192.168.200.1/24 dev br0
# pwd
/opt/lxc/quagga
# lxc-execute -n quagga -f lxc-quagga.conf -- /etc/init.d/quagga start &
[1] 5417
# Loading capability module if not yet done.
Starting Quagga daemons (prio:10): zebra ospfd ospf6d.

#
で稼働。起動の仕方がイマイチの気もするけど、まぁ。zebra と ospfd、 ospf6d が起動しているハズです。ホスト側のアドレスはこんな感じ。
# ip addr ls | egrep "(^[0-9]|inet )"
1: lo: mtu 16436 qdisc noqueue state UNKNOWN
inet 127.0.0.1/8 scope host lo
2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
3: sit0: mtu 1480 qdisc noop state DOWN
4: ip6tnl0: mtu 1460 qdisc noop state DOWN
5: wmaster0: <> mtu 0 qdisc noop state DOWN qlen 1000
6: wlan0: mtu 1500 qdisc noop state DOWN qlen 1000
7: vlan10@eth0: mtu 1500 qdisc noqueue state UP
inet 172.27.129.2/24 brd 172.27.129.255 scope global vlan10
8: vlan11@eth0: mtu 1500 qdisc noqueue state UP
inet 192.168.1.3/24 brd 192.168.1.255 scope global vlan11
630: br0: mtu 1500 qdisc noqueue state UNKNOWN
inet 192.168.200.1/24 scope global br0
631: br1: mtu 1500 qdisc noqueue state UNKNOWN
632: br2: mtu 1500 qdisc noqueue state UNKNOWN
....
やっぱりホスト側でも ospfd 動いているので、寂しい経路数ですが....
# telnet 192.168.200.10 zebra
Trying 192.168.200.10...
Connected to 192.168.200.10.
Escape character is '^]'.

Hello, this is Quagga (version 0.99.10).
Copyright 1996-2005 Kunihiro Ishiguro, et al.


User Access Verification

Password:
zebra@quagga> en
Password:
zebra@quagga# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
I - ISIS, B - BGP, > - selected route, * - FIB route

C>* 127.0.0.0/8 is directly connected, lo
C>* 192.168.200.0/24 is directly connected, eth0
C>* 192.168.201.0/24 is directly connected, eth1
C>* 192.168.202.0/24 is directly connected, eth2
C>* 192.168.203.0/24 is directly connected, eth3
C>* 192.168.204.0/24 is directly connected, eth4
C>* 192.168.205.0/24 is directly connected, eth5
C>* 192.168.206.0/24 is directly connected, eth6
C>* 192.168.207.0/24 is directly connected, eth7
zebra@quagga#
申し遅れましたが、パスワードは共に zebra です。
# telnet 192.168.200.10 ospfd
Trying 192.168.200.10...
Connected to 192.168.200.10.
Escape character is '^]'.

Hello, this is Quagga (version 0.99.10).
Copyright 1996-2005 Kunihiro Ishiguro, et al.


User Access Verification

Password:
ospfd@quagga> en
Password:
ospfd@quagga# conf t
ospfd@quagga(config)# router ospf
ospfd@quagga(config-router)# network 192.168.200.0/24 area 0.0.0.128
ospfd@quagga(config-router)#
で再度 zebra に
# telnet 192.168.200.10 zebra
Trying 192.168.200.10...
Connected to 192.168.200.10.
Escape character is '^]'.

Hello, this is Quagga (version 0.99.10).
Copyright 1996-2005 Kunihiro Ishiguro, et al.


User Access Verification

Password:
zebra@quagga> en
Password:
zebra@quagga# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
I - ISIS, B - BGP, > - selected route, * - FIB route

C>* 127.0.0.0/8 is directly connected, lo
O>* 172.27.1.0/24 [110/40] via 192.168.200.1, eth0, 00:00:58
O>* 172.27.68.0/24 [110/40] via 192.168.200.1, eth0, 00:00:58
O>* 172.27.129.0/24 [110/20] via 192.168.200.1, eth0, 00:00:59
O>* 172.27.193.0/24 [110/30] via 192.168.200.1, eth0, 00:00:59
O 192.168.200.0/24 [110/10] is directly connected, eth0, 00:00:59
C>* 192.168.200.0/24 is directly connected, eth0
C>* 192.168.201.0/24 is directly connected, eth1
C>* 192.168.202.0/24 is directly connected, eth2
C>* 192.168.203.0/24 is directly connected, eth3
C>* 192.168.204.0/24 is directly connected, eth4
C>* 192.168.205.0/24 is directly connected, eth5
C>* 192.168.206.0/24 is directly connected, eth6
C>* 192.168.207.0/24 is directly connected, eth7
をぉ....後片付けは
# lxc-stop -n quagga
#
[1]+ Exit 137 lxc-execute -n quagga -f lxc-quagga.conf -- /etc/init.d/quagga start
# lxc-destroy -n quagga
最近のものを git で持ってこないと、後が何かおかしくなるコトあり。

# 沢山稼働させる場合は、きちんと絵を描いてから。って自分に言いきかせる。

/dev/pts -o newinstance,ptmxmode= その 2

udev やっぱわかってない。ごめんなさい....当面、こんなんで繕っていますが udev 絡めた方法や、イカンと思った方は教えてやって下さい。udev 周りイジらず /etc/init.d 配下のファイルだけ。正統派で無い気がする。
~# diff -ubB /etc/init.d/mountdevsubfs.sh.orig /etc/init.d/mountdevsubfs.sh
--- /etc/init.d/mountdevsubfs.sh.orig 2009-05-27 21:40:09.000000000 +0900
+++ /etc/init.d/mountdevsubfs.sh 2009-06-09 21:06:46.000000000 +0900
@@ -60,7 +60,8 @@
fi
if [ -d /dev/pts ]
then
- if [ ! -c /dev/ptmx ]
+ domount devpts "" /dev/pts devpts -onoexec,nosuid,gid=$TTYGRP,mode=$TTYMODE,newinstance,ptmxmode=0666
+ if [ ! -c /dev/ptmx -a ! -c /dev/pts/ptmx ]
then
mknod --mode=666 /dev/ptmx c 5 2
ES=$?
@@ -69,8 +70,9 @@
log_warning_msg "Failed making node /dev/ptmx with error code ${ES}."
fi
[ -x /sbin/restorecon ] && /sbin/restorecon /dev/ptmx
+ else
+ ln -sf /dev/pts/ptmx /dev/ptmx
fi
- domount devpts "" /dev/pts devpts -onoexec,nosuid,gid=$TTYGRP,mode=$TTYMODE
fi
fi
}
diff -ubB /etc/init.d/mtab.sh.orig /etc/init.d/mtab.sh
--- /etc/init.d/mtab.sh.orig 2009-06-01 22:25:45.000000000 +0900
+++ /etc/init.d/mtab.sh 2009-06-01 23:18:15.000000000 +0900
@@ -137,7 +137,7 @@
SHM_OPT=
[ "${SHM_SIZE:=$TMPFS_SIZE}" ] && SHM_OPT=",size=$SHM_SIZE"
domtab tmpfs /dev/shm tmpfs -onosuid,nodev$SHM_OPT
- domtab devpts /dev/pts "devpts" -onoexec,nosuid,gid=$TTYGRP,mode=$TTYMODE
+ domtab devpts /dev/pts "devpts" -onoexec,nosuid,gid=$TTYGRP,mode=$TTYMODE,newinstance,ptmxmode=0666

# Add everything else in /proc/mounts into /etc/mtab, with
# special exceptions.
むーん....

2009年6月4日木曜日

lxc のインストール 4

まとめてみると
  • debian/lenny で git から持ってきた lxc-sshd はそのままは動きそうになさげ。
    動かすにあたっては....

  • /usr/local/ 配下などにインストールする場合はコンテナ内で liblxc.*.so が見付けられるようにする

  • コンテナ側での /dev/pts マウント

  • より独立したコンテナを望むのであればホスト側で devpts を newinstance オプション付でマウントする。
    (詳細は /usr/src/linux/Documentation/filesystems/devpts.txt参照)
ってコトでしょうか。

lxc のインストールと言うより lxc-sshd を動かすまでの道のりになってしまいました。
ごめんなさい....おやすみなさい....

lxc のインストール 3

続き。別ターミナルから
# killall slogin
戻って
# lxc-stop -n tetest
#
[1]+ Exit 137 lxc-execute -n tetest /usr/sbin/sshd
# lxc-execute -n tetest /bin/bash
# /usr/sbin/sshd -dD
....
Server listening on 0.0.0.0 port 22.
また別ターミナル行って
# slogin -v 192.168.1.100
....
debug1: Next authentication method: password
root@192.168.1.100's password:
....
debug1: permanently_set_uid: 0/0
Environment:
LANG=en_US
USER=root
LOGNAME=root
戻ってみると
debug1: Allocating pty.
openpty: No such file or directory
session_pty_req: session 0 alloc failed
....
debug1: session_input_channel_req: session 0 req shell
^CExiting on signal 2
debug1: do_cleanup
# exit
わかる人には、わかるのでしょうが、この後のコンテナで strace したり、デーモン君のソース探検読んだり。で、結果 /dev/pts が マウントされていないため。に気付くに至る....
# lxc-execute -n tetest /bin/bash
# mount -t devpts none /dev/pts
# mount
none on /dev/pts type devpts (rw)
# /usr/sbin/sshd
#
で、別ターミナルから
# slogin 192.168.1.100
root@192.168.1.100's password:
-bash-3.2#
おぉ....。ひとしきり遊んだ後で止めて、更にターミナル戻って # 変なところで試していてごめんなさい
# cat /usr/local/var/lib/lxc/tetest/fstab
/lib /opt/src/lxc/./rootfs.tetest/lib none ro,bind 0 0
/bin /opt/src/lxc/./rootfs.tetest/bin none ro,bind 0 0
/usr /opt/src/lxc/./rootfs.tetest/usr none ro,bind 0 0
/sbin /opt/src/lxc/./rootfs.tetest/sbin none ro,bind 0 0
/opt/src/lxc/rootfs.tetest /usr/local/var/lib/lxc/tetest/rootfs none rbind 0 0
# vi !$
....
# cat /usr/local/var/lib/lxc/tetest/fstab
/lib /opt/src/lxc/./rootfs.tetest/lib none ro,bind 0 0
/bin /opt/src/lxc/./rootfs.tetest/bin none ro,bind 0 0
/usr /opt/src/lxc/./rootfs.tetest/usr none ro,bind 0 0
/sbin /opt/src/lxc/./rootfs.tetest/sbin none ro,bind 0 0
/dev/pts /opt/src/lxc/./rootfs.tetest/dev/pts none bind 0 0
# none /opt/src/lxc/./rootfs.tetest/dev/pts devpts defaults 0 0 も同じようなモン
/opt/src/lxc/rootfs.tetest /usr/local/var/lib/lxc/tetest/rootfs none rbind 0 0
# lxc-execute -n tetest /usr/sbin/sshd &
[1] 30491
で OK なんだけど....
# echo $$
29056
# ls -l /proc/29056/fd/
total 0
lrwx------ 1 root root 64 2009-06-04 22:31 0 -> /dev/pts/1
lrwx------ 1 root root 64 2009-06-04 22:31 1 -> /dev/pts/1
lrwx------ 1 root root 64 2009-06-04 22:31 2 -> /dev/pts/1
lrwx------ 1 root root 64 2009-06-04 22:31 255 -> /dev/pts/1
別ターミナルで
# slogin 192.168.1.100
root@192.168.1.100's password:
-bash-3.2# echo hogehoge > /dev/pts/1
として、ターミナル戻ってみると... がイカンと言うことで newinstance という devpts マウントのオプションができたらしいです。

lxc のインストール 2

続き。
# lxc-execute -n tetest /bin/bash
/usr/local/libexec/lxc-init: error while loading shared libraries: liblxc-0.6.2.so: cannot open shared object file: No such file or directory
# ldd /usr/local/libexec/lxc-init
linux-gate.so.1 => (0xb8070000)
libutil.so.1 => /lib/i686/cmov/libutil.so.1 (0xb8060000)
liblxc-0.6.2.so => /usr/local/lib/liblxc-0.6.2.so (0xb804a000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7eef000)
/lib/ld-linux.so.2 (0xb8071000)
# ls -l /usr/local/lib/liblxc-0.6.2.so
-rwxr-xr-x 1 root staff 271005 2009-06-04 20:48 /usr/local/lib/liblxc-0.6.2.so
って何よ何。で Google 様に尋ねたところ chroot 先 ldconfig の問題との事。liblxc-0.6.2.so/usr/lib にコピーしてあげれば OK でこだわる必要無いけど....
lxc-createした後 chroot 先は var/lib/lxc。今回の場合は /usr/local/var/lxc なので
# cd /usr/local/var/lib/lxc/
# ls
tetest
# cd tetest
# ls
config fstab network rootfs state utsname
# cd rootfs
# ls
rootfs
# cd rootfs
# ls
bin dev etc lib lib64 proc root sbin sys tmp usr var
# cd etc
# ls
group gshadow passwd shadow ssh
# cat > ld.so.conf
/usr/local/lib
# cp /usr/local/lib/liblxc-0.6.2.so /usr/lib/
# lxc-execute -n tetest /sbin/ldconfig
# pwd
/usr/local/var/lib/lxc/tetest/rootfs/rootfs/etc
# ls -l ld.so.cache
-rw-r--r-- 1 root root 37669 2009-06-04 21:29 ld.so.cache
# rm /usr/lib/liblxc-0.6.2.so
# cd
# lxc-execute -n tetest /bin/bash
# hostname
tetest
鶏卵だけど /usr/local にインストールした場合、chroot 先に /usr/local/lib 含んだ /etc/ld.so.cache が必要。で 本筋に戻って
# lxc-execute -n tetest /usr/sbin/sshd
^Z
[1]+ Stopped lxc-execute -n tetest /usr/sbin/sshd
# bg
[1]+ lxc-execute -n tetest /usr/sbin/sshd &
# ping 192.168.1.100
PING 192.168.1.100 (192.168.1.100) 56(84) bytes of data.
64 bytes from 192.168.1.100: icmp_seq=1 ttl=64 time=1.08 ms
64 bytes from 192.168.1.100: icmp_seq=2 ttl=64 time=0.157 ms
64 bytes from 192.168.1.100: icmp_seq=3 ttl=64 time=0.159 ms
^C
--- 192.168.1.100 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.157/0.466/1.082/0.435 ms
おぉ....
# slogin 192.168.1.100
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
RSA key fingerprint is ff:9e:86:97:0e:98:44:23:98:44:93:b0:2e:2c:a8:ee.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.100' (RSA) to the list of known hosts.
root@192.168.1.100's password:
PTY allocation request failed on channel 0
# 応答なし
もぉ....
# あと二つ三つつづく。

lxc のインストール

順序がおかしいけど debian/lenny で git リポジトリからのインストールをちょっと jot。
debian/sid ではパッケージ化されていて、依存関係眺めると libc6-dev の他は libcap2-dev と libcap2-bin があれば OK。マニュアル作成に docbook-utils が必要だけど tex 関連の依存大きいので割愛。カーネルは 2.6.30-rc では
CONFIG_CGROUP_NS=y
....
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
....
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
最後は先日の /dev/pts のお話。git リポジトリは大元参考にして....
#  git-clone git://lxc.git.sourceforge.net/gitroot/lxc 
Initialized empty Git repository in /opt/src/lxc/.git/
remote: Counting objects: 2234, done.
remote: Compressing objects: 100% (1099/1099), done.
remote: Total 2234 (delta 1740), reused 1461 (delta 1123)
Receiving objects: 100% (2234/2234), 559.49 KiB | 125 KiB/s, done.
Resolving deltas: 100% (1740/1740), done.
# ls
lxc
# cd lxc
# ls
AUTHORS configure.ac doc lxc.spec.in NEWS scripts TODO
autogen.sh CONTRIBUTING etc MAINTAINERS README src
config COPYING INSTALL Makefile.am RELEASE-NOTES test
# ./autogen.sh
....
# ./configure --prefix=/usr/local && make && make install
....
# lxc-setcap -h
lxc-setcap [-d] : set or remove capabilities on the lxc tools
libcap2 関係入れある lxc-setcap で root でなくても動かせるらしいけど、面倒なのでそのまま。先にネットワーク周り。後の lxc-sshd にて名称 br0 は固定なので
# brctl addbr br0
# brctl stp br0 off
# ip addr add 192.168.1.1/24 dev br0
# ip link set br0 up
その後 lxc-sshd
# lxc-sshd -h
Usage: /usr/local/bin/lxc-sshd {create|destroy|help}
# lxc-sshd create
What is the container name ? [sshd] tetest
What hostname do you wish for this container ? [tetest] tetest
What IP address do you wish for this container ? [172.20.0.20/24] 192.168.1.100/24
Done.

You can run your container with:
'lxc-execute -n tetest /usr/sbin/sshd &'

# lxc-execute -n tetest /usr/sbin/sshd
/usr/local/libexec/lxc-init: error while loading shared libraries: liblxc-0.6.2.so: cannot open shared object file: No such file or directory
むーん、見事に動かず。長くなったので続きは次のエントリで。

2009年6月1日月曜日

/dev/pts -o newinstance,ptmxmode=

唐突に lxc を試し始めてみました。 IBM dw の記事 が詳しいです。で、唐突ついでに /dev/pts のお話。
lxc.mount = ./fstab
....

/dev/pts /opt/lxc/rootfs/dev/pts none bind 0 0
ではコンテナを root で実行して、コンテナ内で
echo hogehoge > /dev/pts/0
なんてすると、見事? ホスト側の /dev/pts/0 に hogehoge と出力されてしまうのはイカンでしょ。で devpts を mount するオプションで newinstance なるモノが登場。こちらで /dev/pts/ についても別空間にしましょう。というコトらしい。詳しくは /usr/src/linux/Documentation/filesystems/devpts.txt を参照してみて下さい。こちら有効するために格闘。etch からのバージョンアップなので、未確認の部分もあるけど
--- /etc/init.d/mountdevsubfs.sh.orig 2009-05-27 21:40:09.000000000 +0900
+++ /etc/init.d/mountdevsubfs.sh 2009-06-01 23:35:42.000000000 +0900
@@ -70,7 +70,7 @@
fi
[ -x /sbin/restorecon ] && /sbin/restorecon /dev/ptmx
fi
- domount devpts "" /dev/pts devpts -onoexec,nosuid,gid=$TTYGRP,mode=$TTYMODE
+ domount devpts "" /dev/pts devpts -onoexec,nosuid,gid=$TTYGRP,mode=$TTYMODE,newinstance,ptmxmode=0666
fi
fi
}

--- /etc/init.d/mtab.sh.orig 2009-06-01 22:25:45.000000000 +0900
+++ /etc/init.d/mtab.sh 2009-06-01 23:18:15.000000000 +0900
@@ -137,7 +137,7 @@
SHM_OPT=
[ "${SHM_SIZE:=$TMPFS_SIZE}" ] && SHM_OPT=",size=$SHM_SIZE"
domtab tmpfs /dev/shm tmpfs -onosuid,nodev$SHM_OPT
- domtab devpts /dev/pts "devpts" -onoexec,nosuid,gid=$TTYGRP,mode=$TTYMODE
+ domtab devpts /dev/pts "devpts" -onoexec,nosuid,gid=$TTYGRP,mode=$TTYMODE,newinstance,ptmxmode=0666

# Add everything else in /proc/mounts into /etc/mtab, with
# special exceptions.

--- /etc/udev/rules.d/50-udev.rules.orig 2009-06-01 23:37:47.000000000 +0900
+++ /etc/udev/rules.d/50-udev.rules 2009-06-01 23:05:15.000000000 +0900
@@ -99,3 +99,5 @@
SUBSYSTEM=="aoe", NAME="etherd/%k"

KERNEL=="device-mapper", NAME="mapper/control"
+
+KERNEL=="ptmx", NAME="pts/ptmx"
/dev/pts/ptmx をイキナリ 0666 にしてはイカンらしいが、まぁ X でターミナルも開いたし、ssh でログインもできた。

つづきはまた後日。

2009年5月6日水曜日

ralink USB で hostapd

どこで何を調べていたか定かではないけど hostapd での nl80211 ドライバはつい最近、2.6.30 からだよ。といった ML のアーカイブを見かけた... はさて置き。

ralink 謹製のドライバが、この辺り にあるので ``RT2501USB(RT73:RT2571W/RT2573/RT2671)'' を持ってきて眺めてみた。が、送信については ACK のチェックは無いようで、USB - urb? のステータスがエラーで無ければ送信 OK というスタンス。一方 linux では SUCCESS は送信フレームの ACK が返ってきたときだけ。と厳しいためrt2x00usb.c にてエラーだったら FAILURE。それ以外はエラーじゃないけど ACK が確認できないので UNKNOWN。この UNKNOWN が enum mac80211_tx_control_flags::include/net/mac80211.h の IEEE80211_TX_STAT_ACK か否か。で否との結果送信できなかったぁ。で動かない。

ralink で OK。に従うならば TXDONE_UNKNOWN を TXDONE_SUCCESS にするのもアリかと。

tcpdump で wlan - 復習

にっ、二年前ですか。こんなことちょっと調べた後も進歩なし。もう一度 MAC フレームの先頭、フレームコントロールフィールドについて。tcpdump でフィルタする時には wlan[0] あるいは wlan[1] で指定。
wlan[0]
  • sub type: 4bit
  • type: 2bit
  • version: 2bit

  • wlan[1]: すべて 1bit
  • ToDS
  • FromDS
  • MoreFragment
  • Retry
  • PowerManagement
  • MoreData
  • WEP
  • Order
  • 先日の tcpdump-workers へのリンクが切れていたので、こちら参照しつつ、バージョンは 0。管理フレームの type は 0。subtype は
    • 0000 association request
    • 0001 association response
    • 0010 reassociation request
    • 0011 reassociation response
    • 0100 probe request
    • 0101 probe response
    • 1000 beacon
    • 1010 deassociation
    • 1011 authentication
    • 1100 deauthentication
    を踏まえるとビーコンフレームは
    # iw dev wlan0 interface add mon0 type monitor flags none
    # ip link set mon0 up
    # ip link ls
    5: mon0: mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ieee802.11/radiotap xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    # tcpdump -ntvvi mon0 '(wlan[0] & 0xff) == 0x80'
    tcpdump: WARNING: mon0: no IPv4 address assigned
    tcpdump: listening on mon0, link-type IEEE802_11_RADIO (802.11 plus BSD radio information header), capture size 96 bytes
    157275684377us tsft 1.0 Mb/s 2472 MHz (0x00a0) -33dB signal antenna 1 [0x0000000e] 0us Beacon (foobar) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] ESS, PRIVACY
    157275945495us tsft 1.0 Mb/s 2472 MHz (0x00a0) -34dB signal antenna 1 [0x0000000e] 0us Beacon (foobar) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] ESS, PRIVACY
    ....
    radiotap でも wlan[] 指定は OK。も一つ良くリンク忘れるので備忘録
    IEEE 802.11-2007 IEEE Standard for Information technology-Telecommunications and information exchange between systems-Local and metropolitan area networks-Specific requirements - Part 11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications

    2009年4月20日月曜日

    USB デバイスで hostapd

    # 半年以上放置....

    2.6.29 から AP モードサポートっ! で試してみた。こちら参照すると ralink の USB デバイスが OK とのことで
    $ lsusb
    Bus 001 Device 002: ID 0411:00d8 MelCo., Inc. WLI-U2-SG54HP

    で挑戦するも今一つと言うか、中途ハンパな状態だけど、チラシのウラ。強い電波で ARP ごにょごにょだったら Linux。なんて言わせないぜっ。か定かではないけど、こちら
    • git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/crda.git
    • git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git
    持って来る。debian であれば 85-regulatory.rules は /etc/udev/rules.d の下。libnl や python-crypto もパッケージそのままで OK。hostapd も
    • git://w1.fi/srv/git/hostap.git
    で、長くなるけど設定はこんな感じ
    interface=wlan0
    driver=nl80211
    logger_syslog=-1
    logger_syslog_level=4
    logger_stdout=-1
    logger_stdout_level=0
    dump_file=/tmp/hostapd.dump
    ctrl_interface=/var/run/hostapd
    ctrl_interface_group=0
    ssid=foobar
    country_code=JP
    ieee80211d=1
    hw_mode=g
    channel=2
    beacon_int=256
    dtim_period=2
    max_num_sta=255
    macaddr_acl=0
    accept_mac_file=/etc/hostapd/mac.accept
    deny_mac_file=/etc/hostapd/mac.deny
    auth_algs=1
    ieee8021x=1
    eapol_version=2
    own_ip_addr=192.168.1.1
    wpa=3
    wpa_passphrase=tetest1234
    wpa_key_mgmt=WPA-PSK
    wpa_pairwise=CCMP TKIP
    wpa_group_rekey=600
    wpa_strict_rekey=1
    wpa_gmk_rekey=86400
    wpa_ptk_rekey=600
    # とてつもなく適当
    で動かん...こちら が未解決の模様。

    rt2x00usb_interrupt_txdone()::drivers/net/wireless/rt2x00/rt2x00usb.c のコメントそのままに、失敗した訳では無いが、成功 (ACK を受信した) 訳でも無いと。曰く hostapd の不備との話を踏まえて、hostapd 側で IEEE80211_RADIOTAP_F_TX_FAIL のチェックを無効にしたら、動くコトは動いたが、むーん。レートが 1M から上がらん。

    で、結局は先の未解決のすったもんだ、そのままに TXDONE_UNKNOWN を TXDONE_SUCCESS にして自宅内運用中。iPhone でひっかかるような感じになることあるけど、まぁ。ralink の USB デバイスは全て (と言っても別系は 2.6.29 では rt2500usb のみ) ブチ当ってしまう模様。

    2.6.30 以降の ar9170 か rt3070 に期待するしか無いのかなぁ....