procd

系統啓動順序

  • bootloader加載內核
  • 內核開動,同時掃描mtd文件系統分區
  • 內核執行/etc/preinit腳本
  • /etc/preinit執行/sbin/init二進制程序
  • /sbin/init根據/etc/inittab定義執行啓動過程
  • /etc/inittab首先執行/etc/init.d/rcS,此腳本將順序啓動/etc/rc.d/目錄以S開關的腳本

/sbin/init

early()

  • mount /proc /sys /tmp /dev /dev/pts目錄(early_mount)
  • 建立設備節點和/dev/null文件結點(early_dev)
  • 設置PATH環境變量(early_env)
  • 初始化/dev/console

cmdline()

  • 根據/proc/cmdline內容init_debug=([0-9]+)判斷debug級別

watchdog_init()

  • 初始化內核watchdog(/dev/watchdog)

加載內核模塊

  • 建立子進程/sbin/kmodloader加載/etc/modules-boot.d/目錄中的內核模塊

preinit()

  • 建立子進程執行/etc/preinit腳本,此時PREINIT環境變量被設置爲1,主進程同時使用uloop_process_add()把/etc/preinit子進程加入uloop進行監控,當/etc/preinit執行結束時回調plugd_proc_cb()函數把監控/etc/preinit進程對應對象中pid屬性設置爲0,表示/etc/preinit已執行完成shell

  • 建立子進程執行/sbin/procd -h
    /etc/hotplug-preinit.json,主進程同時使用uloop_process_add()把/sbin/procd子進程加入uloop進行監控,當/sbin/procd進程結束時回調spawn_procd()函數json

  • spawn_procd()函數繁衍後繼真正使用的/sbin/procd進程,從/tmp/debuglevel讀出debug級別並設置到環境變量DBGLVL中,把watchdog fd設置到環境變量WDTFD中,最後調用execvp()繁衍/sbin/procd進程數據結構

watchdog

若是存在/dev/watchdog設備,設置watchdog timeout等於30秒,若是內核在30秒內沒有收到任何數據將重啓系統。用戶狀進程使用uloop定時器設置5秒週期向/dev/wathdog設備寫一些數據通知內核,表示此用戶進程在正常工做函數

/**
 * 初始化watchdog
 */
void watchdog_init(int preinit)

/**
 * 設備通知內核/dev/watchdog頻率(缺省爲5秒)
 * 返回老頻率值
 */
int watchdog_frequency(int frequency)

/**
 * 設備內核/dev/watchdog超時時間
 * 當參數timeout<=0時,表示從返回值獲取當前超時時間
 */
int watchdog_timeout(int timeout)

/**
 * val爲true時中止用戶狀通知定時器,意味着30秒內系統將重啓
 */
void watchdog_set_stopped(bool val)

signal

信息處理,下面爲procd對不一樣信息的處理方法oop

  • SIGBUS、SIGSEGV信號將調用do_reboot() RB_AUTOBOOT重啓系統
  • SIGHUP、SIGKILL、SIGSTOP信號將被忽略
  • SIGTERM信號使用RB_AUTOBOOT事件重啓系統
  • SIGUSR一、SIGUSR2信號使用RB_POWER_OFF事件關閉系統

procd

procd有5個狀態,分別爲STATE_EARLYSTATE_INITSTATE_RUNNINGSTATE_SHUTDOWNSTATE_HALT,這5個狀態將按順序變化,當前狀態保存在全局變量state中,可經過procd_state_next()函數使用狀態發生變化spa

STATE_EARLY狀態 - init前準備工做

  • 初始化watchdog
  • 根據"/etc/hotplug.json"規則監聽hotplug
  • procd_coldplug()函數處理,把/dev掛載到tmpfs中,fork udevtrigger進程產生冷插拔事件,以便讓hotplug監聽進行處理
  • udevstrigger進程處理完成後回調procd_state_next()函數把狀態從STATE_EARLY轉變爲STATE_INIT

STATE_INIT狀態 - 初始化工做

  • 鏈接ubusd,此時實際上ubusd並不存在,因此procd_connect_ubus函數使用了定時器進行重連,而uloop_run()需在初始化工做完成後才真正運行。當成功鏈接上ubusd後,將註冊service main_object對象,system_object對象、watch_event對象(procd_connect_ubus()函數),
  • 初始化services(服務)和validators(服務驗證器)全局AVL tree
  • 把ubusd服務加入services管理對象中(service_start_early)
  • 根據/etc/inittab內容把cmd、handler對應關係加入全局鏈表actions中
  • 順序加載respawnaskconsoleaskfirstsysinit命令
  • sysinit命令把/etc/rc.d/目錄下全部啓動腳本執行完成後將回調rcdone()函數把狀態從STATE_INITl轉變爲STATE_RUNNING

STATE_RUNNING狀態

  • 進入STATE_RUNNING狀態後procd運行uloop_run()主循環

trigger任務隊列

數據結構

struct trigger {
    struct list_head list;

    char *type;

    int pending;
    int remove;
    int timeout;

    void *id;

    struct blob_attr *rule;
    struct blob_attr *data;
    struct uloop_timeout delay;

    struct json_script_ctx jctx;
};

struct cmd {
    char *name;
    void (*handler)(struct job *job, struct blob_attr *exec, struct blob_attr *env);
};

struct job {
    struct runqueue_process proc;
    struct cmd *cmd;
    struct trigger *trigger;
    struct blob_attr *exec;
    struct blob_attr *env;
};

接口說明

/**
 * 初始化trigger任務隊列
 */
void trigger_init(void)

/**
 * 把服務和服務對應的規則加入trigger任務隊列
 */
void trigger_add(struct blob_attr *rule, void *id)

/**
 * 把服務從trigger任務隊列中刪除
 */
void trigger_del(void *id)

/**
 * 
 */
void trigger_event(const char *type, struct blob_attr *data)

service

Name Handler Blob_msg policy
set service_handle_set service_set_attrs
add service_handle_set service_set_attrs
list service_handle_list service_attrs
delete service_handle_delete service_del_attrs
update_start service_handle_update service_attrs
update_complete service_handle_update service_attrs
event service_handle_event event_policy
validate service_handle_validate validate_policy

system

Name Handler Blob_msg policy
board system_board
info system_info
upgrade system_upgrade
watchdog watchdog_set watchdog_policy
signal proc_signal signal_policy
nandupgrade nand_set nand_policy

shell調用接口

代碼庫路徑: package/system/procd/files/procd.sh
設備上路徑: /lib/functions/procd.shdebug

/etc/init.d/daemoncode

#!/bin/sh /etc/rc.common

START=80
STOP=20

USE_PROCD=1

start_service()
{
    procd_open_instance
    procd_set_param command /sbin/daemon
    procd_set_param respawn
    procd_close_instance
}
相關文章
相關標籤/搜索