ラベル kernel の投稿を表示しています。 すべての投稿を表示
ラベル kernel の投稿を表示しています。 すべての投稿を表示

2011年4月16日土曜日

softdog / CONFIG_WATCHDOG_NOWAYOUT - 勘違い

nowayout と Magic Close の関係を思いっきり勘違い。先日のエントリでは
何とでも読み取り可。nowayout 指定しても Magic Close はできると思い込
んでた。が、nowayout の方が強いと言うか、nowayout を指定してしまうと
Magic Close すらできない。

drivers/watchdog/softdog.c の中 MODULE_PARM で探すと
soft_margin: int
Watchdog soft_margin in seconds.
(0 < soft_margin < 65536, default=60)
 
nowayout: int
Watchdog cannot be stopped once started
(default= [config WATCHDOG_NOWAYOUT?])
 
soft_noboot: int
Softdog action, set to 1 to ignore reboots, 0 to reboot
noboot でテスト。watchdog プログラムはこんなんに swd.sh と命名して
#!/bin/sh

exec 3> /dev/watchdog
trap "echo 'send V'; echo -n V >&3; exit 0" INT

while :; do
    echo >&3
    sleep 4
done
SIG_INT で止められたら Magic Close。root になってまずは nowayout なし
で Magic Close の場合は
# modprobe softdog soft_margin=10 nowayout=0 soft_noboot=1 # ./swd.sh ^Csend V (しばらく待った後に Ctrl-c) # dmesg | tail ... [ 3010.493992] Software Watchdog Timer: 0.07 initialized. soft_noboot=1 soft_margin=10 sec (nowayout= 0)
Magic Close しない場合は (rmmod しないで引き続き)
# ./swd.sh 
^Z (Ctrl-z)
[1]+  Stopped                 ./swd.sh
# (しばらく - soft_margin で指定した10 秒以上待つ)
# dmesg | tail
...
[ 3010.493992] Software Watchdog Timer: 0.07 initialized. 
    soft_noboot=1 soft_margin=10 sec (nowayout= 0)
[ 3241.819563] SoftDog: Triggered - Reboot ignored.
リブートだけど soft_noboot 指定したのでメッセージだけ。/dev/watchdog
が開きっぱになっているので、続けて
# fg
./swd.sh
^Csend V (Ctrl-c)
# rmmod softdog
次に nowayout 指定すると
# modprobe softdog soft_margin=10 nowayout=1 soft_noboot=1
# ./swd.sh 
^Csend V (Ctrl-c)
# (10 秒以上待って)
# dmesg | tail
...
[ 3757.016487] Software Watchdog Timer: 0.07 initialized. 
    soft_noboot=1 soft_margin=10 sec (nowayout= 1)
[ 3811.572991] SoftDog: Unexpected close, not stopping watchdog!
[ 3821.580111] SoftDog: Triggered - Reboot ignored.
'V' を /dev/watchdog に送ったけどリブート。で最初の通り nowayout 指定
すると Magic Close も何のその。書き込みなくば再起動という結果。

とってもシンプルだけど先の swd.sh は
nohup ./swd.sh > /var/log/watchdog.log 2>&1 &
でソレナリには動くらしい。nowayout 指定せず Magic Close 使ってリブート
せずの停止は
# killall -INT swd.sh
# cat /var/log/swd.log
nohup: ignoring input
send V

2011年3月30日水曜日

softdog / CONFIG_WATCHDOG_NOWAYOUT

いつも唐突。
Documentation/watchdog/src/watchdog-simple.c の抜粋
int fd = open("/dev/watchdog", O_WRONLY);
while (1) {
ret = write(fd, "\0", 1);
if (ret != 1) {
ret = -1;
break;
}
ret = fsync(fd);
if (ret)
break;
sleep(10);
}
close(fd);
定期的に書き込みがあればカーネルが大丈夫、問題ないよ。と判断。書き込みがないと...リブート。じゃクローズは? が次

Documentation/watchdog/watchdog-api.txt の抜粋意訳

モジュールパラメタ nowayout (CONFIG_WATCHDOG_NOWAYOUT)
"Magic Close" がサポートされていなければデバイスを close すると watchdog も (何もせず) 終了。watchdog デーモンにバグがあってクラッシュした場合なんか考えるとちょっとマズい。この挙動のためいくつかのドライバでは "Disable watchdog shutdown on close", CONFIG_WATCHDOG_NOWAYOUT
というオプション設定ができる。これを Y としてコンパイルすると一度 watchdog が開始した後に watchdog を無効にする方法がなくなる。つまりは watchdog デーモンがクラッシュするとシステムが指定のタイムアウト後にリブートする

Magic Close
ドライバが Magic Close をサポートしていると close 直前に特定の文字 'V' が /dev/watchdog に送られないと (書き込まれないと) watchdog が無効にならない。ユーザスペースのデーモンが、この特定の文字を送らずに close するとドライバはデーモンが watchdog を無効にする前に亡くなったと見なす。で、時間内に再度 open しないとリブート。softdog も
if (c == 'V')
expect_close = 42;
...
static long softdog_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
...
static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
...
なんてあったりする

ha.cf のサンプルコメントから
ソフトウェア watchdog を使っているならモジュールロードのパラメタに nowayout=0 あるいは CONFIG_WATCHDOG_NOWAYOUT を無効にしてコンパイルするんじゃないかな。さもないと heartbeat をマトモに終了させたとしてもリブートしてしまうって挙動はお望みじゃないと思う

うーん... heartbeat の watchdog か、別立て watchdog デーモンか...

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 に期待するしか無いのかなぁ....

2008年9月3日水曜日

PF_PACKET での vlan_tci - 気になるトコロ

間違い。
> skb->vlan_tci を設定する __vlan_hwaccel_rx() を呼んでいるのは
じゃなくて、__vlan_hwaccel_rx() を呼び出す netif_rx() や netif_receive_skb() の wrapper (とコメントに書いてある) の vlan_hwaccel_rx() や vlan_hwaccel_receive_skb() はいろんなドライバから呼ばれてる。

その他
  • (多分 NETIF_F_HW_VLAN_RX でないデバイスで使う)
    vlan_skb_recv()::net/8021q/vlan_dev.c で skb->vlan_tci をセットしてない

  • packet_sock.tp_reserve で確保する位置
    tpacket_rcv()::net/packet/af_packet.c の中
     } else {
    unsigned maclen = skb_network_offset(skb);
    netoff = TPACKET_ALIGN(po->tp_hdrlen +
    (maclen < 16 ? 16 : maclen)) +
    po->tp_reserve;
    macoff = netoff - maclen;
    }
    ....
    skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
    ....
    case TPACKET_V2:
    h.h2->tp_len = skb->len;
    h.h2->tp_snaplen = snaplen;
    h.h2->tp_mac = macoff;
    h.h2->tp_net = netoff;
    mac より前に確保してる? できれば mac と net の間に VLAN オプションフィールド入れたいけど、すんごいツラいしそーゆー用途ではない? ユーザスペースで mac ヘッダ前にずらす?

2008年8月26日火曜日

PF_PACKET での vlan_tci

tcpdump で 802.1q の続きになるのか? 2.6.27 にマージされるネットワーク周りのお話で Patrick McHardy さんのいくつか
  • vlan: uninline __vlan_hwaccel_rx
  • packet: deliver VLAN TCI to userspace
  • packet: add PACKET_RESERVE sockopt
あたりが該当しそうだけど...inline ではない、skb->vlan_tci を設定する __vlan_hwaccel_rx() を呼んでいるのは "Chelsio T3-based" なるドライバのみ?

例の lincap.c に新しい setsockopt() してみたが

/* set VERSION 2 - before pg_vec has set */
val = TPACKET_V2;
if ((setsockopt(fd, SOL_PACKET, PACKET_VERSION, (void *)&val, sizeof(val))) != 0) {
perror("setsockopt(PACKET_VERSION)");
close(fd);
return 1;
}

val = 4; /* __be16 0x8100, __be16 h_vlan_TCI - before pg_vec has set, too */
if ((setsockopt(fd, SOL_PACKET, PACKET_RESERVE, (void *)&val, sizeof(val))) != 0) {
perror("setsockopt(PACKET_RESERVE)");
close(fd);
return 1;
}
....
for (i = 0;;) {
while (*(unsigned long*)ring[i].iov_base) {
struct tpacket2_hdr *h = ring[i].iov_base;
struct sockaddr_ll *sll = (void *)h + TPACKET_ALIGN(sizeof(*h));
unsigned char *bp = (unsigned char *)h + h->tp_mac;

printf("%u.%.6u: if: %u, vid: %u, type: %s, len: %u\n",
h->tp_sec, h->tp_nsec,
sll->sll_ifindex,
h->tp_vlan_tci,
names[sll->sll_pkttype],
h->tp_len);
まぁ、nsec が取れるようになったのみ。 VLAN ID 取れたら PACKET_RESERVED のところにコピーしてあげるのかな? でも RESERVE されるのは mac よりも前っぽいので、思い違い?

2008年6月8日日曜日

drop, only drop ingress qdisc

例の PF_RING であったり、web を彷徨っていると NET_RX_CONSUMED なるパッチがあったり、キャプチャしている「だけ」のインターフェースでは PF_PACKET socket に届けた後は何もしなくて良いよ。vanilla カーネルに直接手を入れるのを避けるためには...とツラツラソース眺めたところ ingress qdisc の判断が良さげ。

で、tc で何とかならないか。と
tc qdisc add dev eth1 ingress handle ffff:
tc filter del dev eth1 parent ffff: protocol ip priority 10 u32 match u8 0 0 police mtu 1 drop flowid :1
試してみたところ、かえって遅くなってしまった。恐らく毎度の勉強不足。フィルタではなく、ただただ落とす方法を探せず....とは言え何とかならないか? とダーティハック
無視するだけの - いんぐのあ (ingnore)
ネーミングセンス無さすぎ? tc コマンドのソース持って来て ingress 該当部分を ingnore とすれば使えるけど面倒そうなので、ユーザスペースのコマンドは後日予定。

こちらも毎度正確な測定はしていないけど、こちらの linpcap.c にて表示せず、送信側は pktgen で試してみたところ、数パーセントだけど確実に取得量は増えている模様。

2008年6月3日火曜日

kgdb?

ただただソース眺めているだけの私に言われたくないだろうが 2.6.26 から kgdb が vanilla にマージされるそーで rc 見ると確かに....驚いた。信念よりも嬉しい人の方が多くなったのかなぁ。十中九点九 私には使いきれない。が、ちょっと jot。

カーネルコンパイルのオプションで
CONFIG_DEBUG_INFO=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
としてコンパイル。VMWare にインストールした後で/boot/grub/menu.lstにこんな感じで update-grub
# kopt=root=/dev/sda1 ro kgdbwait kgdboc=ttyS0,115200
あっ、その前にありがたくこちらを参考にしつつシリアルの設定。一点手元の socat では
socat unix-connect:/tmp/vmware-serial-$1-$PORT \
pty:link=/tmp/ttyv$1$PORT,raw,echo=0,waitslave
では NG で pty,link=... としなくてはならんかった。その後リブートすると
....
serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
00:09 ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
00:0a ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
kgdb: Registerd I/O driver kgdboc.
kgdb: Waiting for connection from remote gdb...
で止まる。ホスト側で socat して、手元に先の vmlinux 置いて
$ pwd
/usr/src/i386linux
$ gdb -q
(gdb) set remotebaud 115200
(gdb) symbol-file vmlinux
Reading symbols from /usr/src/i386linux/vmlinux...done.
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) target remote /tmp/ttyvHOST
Remote debugging using /tmp/ttyvHOST
kgdb_breakpoint () at kernel/kgdb.c:1677
1677 wmb(); /* Sync point after breakpoint */
(gdb) n
[New Thread 1]
1678 atomic_set(&kgdb_setting_breakpoint, 0);
(gdb) n
1679 }
(gdb) list
1674 atomic_set(&kgdb_setting_breakpoint, 1);
1675 wmb(); /* Sync point before breakpoint */
1676 arch_kgdb_breakpoint();
1677 wmb(); /* Sync point after breakpoint */
1678 atomic_set(&kgdb_setting_breakpoint, 0);
1679 }
1680 EXPORT_SYMBOL_GPL(kgdb_breakpoint);
1681
1682 static int __init opt_kgdb_wait(char *str)
1683 {
(gdb)
をぉ.... # こーして夜がふけてくてくてくてく

2008年5月6日火曜日

PF_RING のパッチ

2004年 3月と結構以前の話だけど、こんなやりとりがあったらしい。jamal さんとしては PACKET_MMAP (と NAPI) で充分。でないならばプロファイル基に相談しましょ。といったところ。確かに大枠の仕組としてはソケットのバッファを mmap するという点で同じ。何が違うのか...

例のごとく読んでいないが、net/core/dev.c の netif_receive_skb() の初っ端で、ハンドラ呼び出して...む〜ん、わからん...で return(NET_RX_SUCCESS); してる。fragmentation 処理入れたり、forwarding の場合はもう一度 queue に入れたり? わからんのに、こんなことゆーと叱られそうだが、何よりソースが見難い...ごめんなさい。

という何となくの経過を経て、やっぱ使うの止めた。vanilla にある CONFIG_PACKET_MMAP で戦ってみようと思う今日この頃。こっちも聞きかじっただけだが、キャプチャではなくパケット転送するのであれば NF_CT_ACCT - この PDF辺りから始まったお話? とかどうかしら?

2007年11月7日水曜日

tcpdump で 802.1q

vconfig で vlan 作ったけど tcpdump で見えない。って話、結構ホットな内容かも。expected behavior of PF_PACKET on NETIF_F_HW_VLAN_RX device? を例のごとく一瞥すると NETIF_F_HW_VLAN_RX feature が on となっているデバイスの場合 tcpdump で見る時には vlan ヘッダが無い? とか。include/linux/netdevice.hにて
#define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */
現在利用しているデバイスの feature は cat /sys/class/net/eth#/features あたりを見ると 0x113a9 と 0x180。これかなぁ....

2007年8月18日土曜日

LSRR の受信?

受信か送信かどうでも良くなってしまったが、LSRR 使えなかった原因の一つは NIC によるものだったらしい。とっても古い (らしい) 3Com の 3c905C というもので /sys/class/net/eth0/features の値は 3。意味するところは include/linux/netdevce.h から
....
#define NETIF_F_SG 1 /* Scatter/gather IO. */
#define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */
#define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */
#define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */
....
boot パラメタに 3c59x.hw_checksums=0 と指定したら動いた...けど features も 0 に? scatter/gather は checksum 必須なの?

2007年8月8日水曜日

TCP の checksum

なさけないはなしー
 /* This routine computes an IPv4 TCP checksum. */
を見付けるまでに 1時間以上。イカンですな。未だ netcat の -g 使った lsrr を動作できたりできなかったり。tcpdump の出力信じるならば checksum がおかしい。ということで追ってみたところ net/ipv4/tcp_ipv4.c::tcp_v4_send_check() にて上記コメント発見。SYN_SENT で ack を受け取った場合を追ってみると
tcp_v4_do_rcv()
>> tcp_rcv_state_process()
>>>> tcp_rcv_synsent_state_process()
>>>>>> tcp_send_ack()
>>>>>>>> tcp_transmit_skb() この中で
inet_connection_sock_af_ops ipv4_specific->send_check() が...
tcp_v4_send_check() では CHECKSUM_PARTIAL で処理分け。lwn を見ると
That value has been replaced with CHECKSUM_PARTIAL (intended for outgoing packets where the job must be completed by the hardware) and CHECKSUM_COMPLETE (for incoming packets which have been completely checksummed by the hardware).
仰しゃる通り関数名からも、送信側の話。送受信双方共にethtook -K で変更できるらしい。TCP もドライバも何でも...深いから、まだまだ時間かかるだろうなぁ。

2007年7月11日水曜日

LSRR の受信

ちょっと情けないが、ちょっと jot。興味があちこちしてしまいデジャヴばかりの様な気がする。
ip_rcv()
NF_IP_PREROUTING
ip_rcv_finish()
ip_rcv_options() ヘッダ長 20バイト超ならばオプションあり
ip_rcv_options_compile() sk_buff 内 cb に設定
ip_opeions_rcv_srr()
ip_route_input()
ip_route_input()
dst_input()

ip_forward()
NF_IP_FORWARD
ip_forward_finish()
ip_forward_options()
dst_output()
ip_output()
ip_fragment()

skb->pkt_type は eth_type_trans() にて設定
rt->rt_type の設定は....
ip_route_input()
ip_route_input_slow()
ip_mkroute_input()
(ip_mkroute_input_def())
__mkroute_input()
rt_set_nexthop()
output側も同じ感じ。
ip_local_deliver() は ip_route_input_slow() にて rth->u.dst.input に

ip_local_deliver()
NF_IP_LOCAL_IN
ip_local_deliver_finish()

先日の見難い図を簡単にすると
hostA ---- host B ---- host C
にて
  1. host B から host A , hostB を通って hostC
  2. hostC から hostB, hostA 再度 hostB に戻って hostC
といった lsrr を投げと、1.の場合は hostB。2.の場合は hostC の PREROUTING で -j LOG は取れるものの INPUT にはログが残らず、もちろん到達せず。両方の場合で IP上は src dst 共に自アドレスとなっている。/proc の accept_source_route を 1。rp_filter を 0。netfilter の全ての hook のポリシを ACCEPT としたが、通さず。2. にて hostB を通過している点、1. 2. にて PREROUTING に LOG が残っているので、ip_rcv_finish() あたりなのか...調べること。