ablog

不器用で落着きのない技術者のメモ

net.ipv4.tcp_rmem を変更してプログラムが使用するTCP受信バッファのサイズを変更する

カーネルパラメータ 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