カーネルパラメータ net.core.[rw]mem_{default,max} の意味を考えてみた - ablog
に書いた仮説をテストプログラムを書いて検証したいけど、やらないといけないことがいっぱいあるので、ひとつだけ試してみるだけでがまんすることにした。
- tcpbuf_default_size.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> int main () { int sock_buf_size; int len = sizeof(sock_buf_size); int sock = socket(AF_INET, SOCK_STREAM, 0); getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &sock_buf_size, &len); printf("%s%d\n", "TCP receive buffer (default): ", sock_buf_size); close(sock); return 0; }
- 検証結果
% gcc -o tcpbuf_default_size tcpbuf_default_size.c % cat /proc/sys/net/ipv4/tcp_rmem 4096 87380 4194304 % ./tcpbuf_default_size TCP receive buffer (default): 87380 % sysctl -w net.ipv4.tcp_rmem='4096 4194304 4194304' net.ipv4.tcp_rmem = 4096 4194304 4194304 % cat /proc/sys/net/ipv4/tcp_rmem 4096 4194304 4194304 % ./tcpbuf_default_size TCP receive buffer (default): 4194304
カーネルパラメータ net.ipv4.tcp_rmem でTCP受信バッファのデフォルトサイズを変えたら、想定通りプログラムが使用するTCP受信バッファも変わってますね。
strace でシステムコールを調べてみる。
% strace ./tcpbuf_default_size execve("./tcpbuf_default_size", ["./tcpbuf_default_size"], [/* 25 vars */]) = 0 brk(0) = 0x8d1f000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=58804, ...}) = 0 mmap2(NULL, 58804, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f13000 close(3) = 0 open("/lib/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\37\251\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1611564, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f12000 mmap2(0xa7c000, 1332676, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x110000 mprotect(0x24f000, 4096, PROT_NONE) = 0 mmap2(0x250000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13f) = 0x250000 mmap2(0x253000, 9668, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x253000 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f11000 set_thread_area({entry_number:-1 -> 6, base_addr:0xb7f116c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 mprotect(0x250000, 8192, PROT_READ) = 0 mprotect(0xa78000, 4096, PROT_READ) = 0 munmap(0xb7f13000, 58804) = 0 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 getsockopt(3, SOL_SOCKET, SO_RCVBUF, [4194304], [4]) = 0 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f21000 write(1, "TCP receive buffer (default): 41"..., 38TCP receive buffer (default): 4194304 ) = 38 close(3) = 0 exit_group(0) = ?
ステップ実行しながら、
% gcc -g -o tcpbuf_default_size tcpbuf_default_size.c % gdb ./tcpbuf_default_size GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-23.el5) Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /root/tcpbuf_default_size...done. (gdb) b main Breakpoint 1 at 0x8048425: file tcpbuf_default_size.c, line 9. (gdb) run Starting program: /root/tcpbuf_default_size Breakpoint 1, main () at tcpbuf_default_size.c:9 9 int len = sizeof(sock_buf_size); (gdb) n 10 int sock = socket(AF_INET, SOCK_STREAM, 0); (gdb) n 12 getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &sock_buf_size, &len); (gdb) n 13 printf("%s%d\n", "TCP receive buffer (default): ", sock_buf_size); (gdb) n TCP receive buffer (default): 4194304 15 close(sock); (gdb) n 16 return 0; (gdb) n 17 } (gdb) n 0x00a91e9c in __libc_start_main () from /lib/libc.so.6 (gdb) n Single stepping until exit from function __libc_start_main, which has no line number information. Program exited normally. (gdb)
pmap で使用しているメモリをのぞいてみた。
% pmap `pgrep -f tcpbuf` 6013: gdb ./tcpbuf_default_size 0026d000 124K r-x-- /lib/libexpat.so.0.5.0 0028c000 8K rwx-- /lib/libexpat.so.0.5.0 00a5e000 104K r-x-- /lib/ld-2.5.so 00a78000 4K r-x-- /lib/ld-2.5.so 00a79000 4K rwx-- /lib/ld-2.5.so 00a7c000 1276K r-x-- /lib/libc-2.5.so 00bbb000 4K --x-- /lib/libc-2.5.so 00bbc000 8K r-x-- /lib/libc-2.5.so 00bbe000 4K rwx-- /lib/libc-2.5.so 00bbf000 12K rwx-- [ anon ] 00bc4000 148K r-x-- /lib/libm-2.5.so 00be9000 4K r-x-- /lib/libm-2.5.so 00bea000 4K rwx-- /lib/libm-2.5.so 00bed000 8K r-x-- /lib/libdl-2.5.so 00bef000 4K r-x-- /lib/libdl-2.5.so 00bf0000 4K rwx-- /lib/libdl-2.5.so 00c0d000 72K r-x-- /usr/lib/libz.so.1.2.3 00c1f000 4K rwx-- /usr/lib/libz.so.1.2.3 00d09000 188K r-x-- /usr/lib/libreadline.so.5.1 00d38000 16K rwx-- /usr/lib/libreadline.so.5.1 00d3c000 4K rwx-- [ anon ] 00fe6000 4K r-x-- [ anon ] 05f62000 256K r-x-- /usr/lib/libncurses.so.5.5 05fa2000 32K rwx-- /usr/lib/libncurses.so.5.5 05faa000 4K rwx-- [ anon ] 08047000 3672K r-x-- /usr/bin/gdb 083dd000 28K rw--- /usr/bin/gdb 083e4000 104K rw--- [ anon ] 091ed000 1648K rw--- [ anon ] b7eb0000 808K rw--- [ anon ] b7fa2000 64K r---- /lib/libc-2.5.so b7fb2000 12K rw--- [ anon ] b7fc1000 12K rw--- [ anon ] bff78000 84K rw--- [ stack ] total 8732K 6033: /root/tcpbuf_default_size 00a5e000 104K r-x-- /lib/ld-2.5.so 00a78000 4K r-x-- /lib/ld-2.5.so 00a79000 4K rwx-- /lib/ld-2.5.so 00a7c000 1276K r-x-- /lib/libc-2.5.so 00bbb000 4K --x-- /lib/libc-2.5.so 00bbc000 8K r-x-- /lib/libc-2.5.so 00bbe000 4K rwx-- /lib/libc-2.5.so 00bbf000 12K rwx-- [ anon ] 00fe8000 4K r-x-- [ anon ] 08048000 4K r-x-- /root/tcpbuf_default_size 08049000 4K rw--- /root/tcpbuf_default_size b7fef000 8K rw--- [ anon ] bffea000 84K rw--- [ stack ] total 1520K