android init重启service(进程)

Posted aspirs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android init重启service(进程)相关的知识,希望对你有一定的参考价值。

 

在init进程的main函数中有调用sigchld_handler_init() 设置SIGCHLD signal。

在子进程比如收到signal时,init进程会收到通知,在SIGCHLD_handler()中write;然后在handle_signal()中read;然后会调用ReapOneProcess();然后调用这个service对象的reap()

void sigchld_handler_init() 
    // Create a signalling mechanism for SIGCHLD.
    int s[2];
    if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == -1) 
        PLOG(FATAL) << "socketpair failed in sigchld_handler_init";
    

    signal_write_fd = s[0];
    signal_read_fd = s[1];

    // Write to signal_write_fd if we catch SIGCHLD.
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_handler = SIGCHLD_handler;
    act.sa_flags = SA_NOCLDSTOP;
    sigaction(SIGCHLD, &act, 0);

    ReapAnyOutstandingChildren();

    register_epoll_handler(signal_read_fd, handle_signal);

 

在Reap()中,以media service为例,它应该是没有SVC_ONESHOT flag的,所以会调Service::KillProcessGroup(),这个函数会发signal SIGKILL(9)给media进程以杀掉它。

然后调用onrestart_.ExecuteAllCommands()

void Service::Reap(const siginfo_t& siginfo) 
    if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) 
        KillProcessGroup(SIGKILL);
    

    // Remove any descriptor resources we may have created.
    std::for_each(descriptors_.begin(), descriptors_.end(),
                  std::bind(&DescriptorInfo::Clean, std::placeholders::_1));

    for (const auto& f : reap_callbacks_) 
        f(siginfo);
    

    if (flags_ & SVC_EXEC) UnSetExec();

    if (flags_ & SVC_TEMPORARY) return;

    pid_ = 0;
    flags_ &= (~SVC_RUNNING);
    start_order_ = 0;

    // Oneshot processes go into the disabled state on exit,
    // except when manually restarted.
    if ((flags_ & SVC_ONESHOT) && !(flags_ & SVC_RESTART)) 
        flags_ |= SVC_DISABLED;
    

    // Disabled and reset processes do not get restarted automatically.
    if (flags_ & (SVC_DISABLED | SVC_RESET))  
        NotifyStateChange("stopped");
        return;
    

    // If we crash > 4 times in 4 minutes, reboot into recovery.
    boot_clock::time_point now = boot_clock::now();
    if ((flags_ & SVC_CRITICAL) && !(flags_ & SVC_RESTART)) 
        if (now < time_crashed_ + 4min) 
            if (++crash_count_ > 4) 
                LOG(FATAL) << "critical process ‘" << name_ << "‘ exited 4 times in 4 minutes";
            
         else 
            time_crashed_ = now;
            crash_count_ = 1;
        
    

    flags_ &= (~SVC_RESTART);
    flags_ |= SVC_RESTARTING;

    // Execute all onrestart commands for this service.
    onrestart_.ExecuteAllCommands();

    NotifyStateChange("restarting");
    return;

 

这个onrestart_.ExecuteAllCommands()对于media进程来说,它没有添加command(如下面的mediaserver.rc),所以不会做什么事情。

frameworks/av/media/mediaserver/mediaserver.rc

service media /system/bin/mediaserver
    class main
    user media
    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
    ioprio rt 4
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks

  

  

  

 

以上是关于android init重启service(进程)的主要内容,如果未能解决你的问题,请参考以下文章

Android 12 init 子进程回收与服务重启分析

Android 12 init 子进程回收与服务重启分析

[android] init进程 .rc文件中serviceaction的parsing

android中当Service在运行时怎么重启Service?

Android-深入理解init

Android service进程保护