wiki:jazz/09-01-22

Version 2 (modified by jazz, 16 years ago) (diff)

--

2009-01-22

DRBL Shutdown Agent

  • [源起] 由於 DRBL Client 在 NFS 斷線後會因為 ROOTFS 消失而找不到關機程序所需的檔案。因此需要有一個背景程序持續等在記憶體中來協助 DRBL Client 關閉電源。
  • 準備 sysvinit 套件環境
    # apt-get install dpkg-dev build-essential
    # apt-get source sysvinit
    # apt-get build-dep sysvinit
    # cd sysvinit-2.86.ds1/src
    ~/sysvinit-2.86.ds1/src# vi Makefile
    
    • Makefile

      old new  
      9 CFLAGS = -Wall -O2 -fomit-frame-pointer -D_GNU_SOURCE
      10 LDFLAGS= -s
       9CFLAGS = -g -Wall -O2 -fomit-frame-pointer -D_GNU_SOURCE # 加入 -g ,讓 gcc 加入 DEBUG Symbol
       10LDFLAGS=                                                 # 拿掉 -s ,讓 LD 進行 Linking 時不進行 strip
    ~/sysvinit-2.86.ds1/src# make
    ~/sysvinit-2.86.ds1/src# nm init                          # 用 nm 可以看到是否有保留 Symbol
    ~/sysvinit-2.86.ds1/src# file init                        # 顯示 not stripped 才會保留 Symbol 哦!
    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
    
  • 先前有追蹤過 shutdown.c 跟 halt.c 的原始碼,發現最後都還是呼叫 init 來執行關機程序。因此這次改追蹤 init.c
  • 用 gdb 追蹤 init 0 的程序
    ~/sysvinit-2.86.ds1/src# gdb init
    (gdb) set args 0
    (gdb) show args
    Argument list to give program being debugged when it is started is "0".
    (gdb) br 2598
    Breakpoint 1 at 0x804e140: file init.c, line 2598.
    (gdb) br 2555
    Breakpoint 2 at 0x8049bfd: file init.c, line 2555.
    (gdb) run
    Starting program: /root/sysvinit-2.86.ds1/src/init 0
    Failed to read a valid object file image from memory.
    
    Breakpoint 1, main (argc=1282785413, argv=0x54a165) at init.c:2598
    2598    {
    (gdb) c
    Continuing.
    
    Breakpoint 2, telinit (progname=0xbfff5c53 "init", argc=2, argv=0xbfff5b34)
        at init.c:2555
    2555            SETSIG(sa, SIGALRM, signal_handler, 0);
    (gdb) handle SIGALRM nopass
    Signal        Stop      Print   Pass to program Description
    SIGALRM       No        No      No              Alarm clock
    (gdb) s
    
  • 用 strace init 0 觀察關機程序
    root@debian:~/sysvinit-2.86.ds1/src# strace init 0
    execve("/sbin/init", ["init", "0"], [/* 14 vars */]) = 0
    rt_sigaction(SIGALRM, {0x8049ad0, [], 0}, NULL, 8) = 0
    alarm(3)                                = 0
    open("/dev/initctl", O_WRONLY)          = 3
    write(3, "i\31\t\3\1\0\0\0000\0\0\0\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 384) = 384
    close(3)                                = 0
    alarm(0)                                = 3
    exit_group(0)                           = ?
    

Attachments (1)

Download all attachments as: .zip