| 3 | == DRBL Shutdown Agent == |
| 4 | |
| 5 | * [源起] 由於 DRBL Client 在 NFS 斷線後會因為 ROOTFS 消失而找不到關機程序所需的檔案。因此需要有一個背景程序持續等在記憶體中來協助 DRBL Client 關閉電源。 |
| 6 | * 準備 sysvinit 套件環境 |
| 7 | {{{ |
| 8 | # apt-get install dpkg-dev build-essential |
| 9 | # apt-get source sysvinit |
| 10 | # apt-get build-dep sysvinit |
| 11 | # cd sysvinit-2.86.ds1/src |
| 12 | ~/sysvinit-2.86.ds1/src# vi Makefile |
| 13 | }}} |
| 14 | {{{ |
| 15 | #!diff |
| 16 | --- Makefile.org 2009-01-22 10:00:03.000000000 +0800 |
| 17 | +++ Makefile 2009-01-22 09:15:42.000000000 +0800 |
| 18 | @@ -9,8 +9,8 @@ |
| 19 | -CFLAGS = -Wall -O2 -fomit-frame-pointer -D_GNU_SOURCE |
| 20 | -LDFLAGS= -s |
| 21 | +CFLAGS = -g -Wall -O2 -fomit-frame-pointer -D_GNU_SOURCE # 加入 -g ,讓 gcc 加入 DEBUG Symbol |
| 22 | +LDFLAGS= # 拿掉 -s ,讓 LD 進行 Linking 時不進行 strip |
| 23 | }}} |
| 24 | {{{ |
| 25 | #!sh |
| 26 | ~/sysvinit-2.86.ds1/src# make |
| 27 | ~/sysvinit-2.86.ds1/src# nm init # 用 nm 可以看到是否有保留 Symbol |
| 28 | ~/sysvinit-2.86.ds1/src# file init # 顯示 not stripped 才會保留 Symbol 哦! |
| 29 | init: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.4.1, dynamically linked (uses shared libs), for GNU/Linux 2.4.1, not stripped |
| 30 | }}} |
| 31 | * 先前有追蹤過 shutdown.c 跟 halt.c 的原始碼,發現最後都還是呼叫 init 來執行關機程序。因此這次改追蹤 init.c |
| 32 | * 用 gdb 追蹤 init 0 的程序 |
| 33 | {{{ |
| 34 | ~/sysvinit-2.86.ds1/src# gdb init |
| 35 | (gdb) set args 0 |
| 36 | (gdb) show args |
| 37 | Argument list to give program being debugged when it is started is "0". |
| 38 | (gdb) br 2598 |
| 39 | Breakpoint 1 at 0x804e140: file init.c, line 2598. |
| 40 | (gdb) br 2555 |
| 41 | Breakpoint 2 at 0x8049bfd: file init.c, line 2555. |
| 42 | (gdb) run |
| 43 | Starting program: /root/sysvinit-2.86.ds1/src/init 0 |
| 44 | Failed to read a valid object file image from memory. |
| 45 | |
| 46 | Breakpoint 1, main (argc=1282785413, argv=0x54a165) at init.c:2598 |
| 47 | 2598 { |
| 48 | (gdb) c |
| 49 | Continuing. |
| 50 | |
| 51 | Breakpoint 2, telinit (progname=0xbfff5c53 "init", argc=2, argv=0xbfff5b34) |
| 52 | at init.c:2555 |
| 53 | 2555 SETSIG(sa, SIGALRM, signal_handler, 0); |
| 54 | (gdb) handle SIGALRM nopass |
| 55 | Signal Stop Print Pass to program Description |
| 56 | SIGALRM No No No Alarm clock |
| 57 | (gdb) s |
| 58 | }}} |
7 | | uname({sys="Linux", node="debian", ...}) = 0 |
8 | | brk(0) = 0x8051000 |
9 | | access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) |
10 | | mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f8c000 |
11 | | access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) |
12 | | open("/etc/ld.so.cache", O_RDONLY) = 3 |
13 | | fstat64(3, {st_mode=S_IFREG|0644, st_size=18455, ...}) = 0 |
14 | | mmap2(NULL, 18455, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f87000 |
15 | | close(3) = 0 |
16 | | access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) |
17 | | open("/lib/libsepol.so.1", O_RDONLY) = 3 |
18 | | read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\0200\0"..., 512) = 512 |
19 | | fstat64(3, {st_mode=S_IFREG|0644, st_size=219824, ...}) = 0 |
20 | | mmap2(NULL, 265152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7f46000 |
21 | | mmap2(0xb7f7c000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x35) = 0xb7f7c000 |
22 | | mmap2(0xb7f7d000, 39872, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f7d000 |
23 | | close(3) = 0 |
24 | | access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) |
25 | | open("/lib/libselinux.so.1", O_RDONLY) = 3 |
26 | | read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0P8\0\000"..., 512) = 512 |
27 | | fstat64(3, {st_mode=S_IFREG|0644, st_size=79368, ...}) = 0 |
28 | | mmap2(NULL, 84884, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7f31000 |
29 | | mmap2(0xb7f44000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x12) = 0xb7f44000 |
30 | | close(3) = 0 |
31 | | access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) |
32 | | open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3 |
33 | | read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240O\1"..., 512) = 512 |
34 | | fstat64(3, {st_mode=S_IFREG|0644, st_size=1241392, ...}) = 0 |
35 | | mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f30000 |
36 | | mmap2(NULL, 1247388, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7dff000 |
37 | | mmap2(0xb7f26000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x127) = 0xb7f26000 |
38 | | mmap2(0xb7f2d000, 10396, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f2d000 |
39 | | close(3) = 0 |
40 | | access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) |
41 | | open("/lib/tls/i686/cmov/libdl.so.2", O_RDONLY) = 3 |
42 | | read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20\f\0"..., 512) = 512 |
43 | | fstat64(3, {st_mode=S_IFREG|0644, st_size=9592, ...}) = 0 |
44 | | mmap2(NULL, 12404, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7dfb000 |
45 | | mmap2(0xb7dfd000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1) = 0xb7dfd000 |
46 | | close(3) = 0 |
47 | | mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7dfa000 |
48 | | mprotect(0xb7f26000, 20480, PROT_READ) = 0 |
49 | | set_thread_area({entry_number:-1 -> 6, base_addr:0xb7dfa6c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, usea ble:1}) = 0 |
50 | | munmap(0xb7f87000, 18455) = 0 |
51 | | access("/etc/selinux/", F_OK) = -1 ENOENT (No such file or directory) |
52 | | brk(0) = 0x8051000 |
53 | | brk(0x8072000) = 0x8072000 |
54 | | open("/proc/mounts", O_RDONLY|O_LARGEFILE) = 3 |
55 | | fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 |
56 | | mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f8b000 |
57 | | read(3, "rootfs / rootfs rw 0 0\nnone /sys"..., 1024) = 305 |
58 | | read(3, "", 1024) = 0 |
59 | | close(3) = 0 |
60 | | munmap(0xb7f8b000, 4096) = 0 |
61 | | umask(022) = 022 |
62 | | geteuid32() = 0 |
63 | | getpid() = 2159 |