> 文档中心 > OpenHarmony恢复启动子系统init进程之启动FD代持服务

OpenHarmony恢复启动子系统init进程之启动FD代持服务

 FD代持是按需启动的一个辅助扩展机制,按需启动进程可以保持退出前的fd状态句柄不丢失。按需启动进程退出前可将fd发送给init代持,再次启动后再从init获取fd。

代持原理:

 

代持流程:

按需启动进程退出前可将fd发送给init代持,再次启动后再从init获取fd。

init提供了相关接口供服务调用,服务进程退出前调用接口将fd通过支持IPC通信的socket发送给init代持,待该服务重新启动时,init将持有的该服务相关的fd句柄通过同样的方式返回给服务。

 

 消息格式:

方法

说明

hold

由子服务发送给fdholder 服务,然后交给init进程代持

get

子服务请求fdholder,由fdholder返还fd给子服务

为避免其他进程访问,都需要验证gid,uid,pid。

发布fdholder

正常情况下,fd 是不能在进程间传递的,但是可以通过发布fd来达到目的。

代码:

static void PublishHoldFds(Service *service){    INIT_ERROR_CHECK(service != NULL, return, "Publish hold fds with invalid service");    char fdBuffer[MAX_FD_HOLDER_BUFFER] = {};    if (service->fdCount > 0 && service->fds != NULL) {        size_t pos = 0;        for (size_t i = 0; i fdCount; i++) {            /**             * 技术要点1:  dup(fd) 重定向fd,同时会清除O_CLOEXEC             *            O_CLOEXEC 标志本来用于防止fd泄露给子进程,这里清除这个标志,就是因为发布就是为了给子进程使用。             */            int fd = dup(service->fds[i]);            if (fd name, errno);                continue;            }                        if (snprintf_s((char *)fdBuffer + pos, sizeof(fdBuffer) - pos, sizeof(fdBuffer) - 1, "%d ", fd) name);        if (setenv(envName, fdBuffer, 1) name);    }}

就是发布一个环境变量,名称为: OHOS_FD_HOLD_servername, 将fd(可能有多个) 转变成字符串作为环境变量的值。 启动子服务进程之后,先去查找环境变量,获取它的值,分解出fd。

湖北工具网