繁体   English   中英

如何从 2 个进程 ping /dev/watchdog?

[英]How to ping /dev/watchdog from 2 processes?

在 Linux(在 ARM 上运行)中,有一个进程对/dev/watchdog/有一个打开的 fd,并且每隔几秒发送一个ioctl()作为保持活动状态:

while (1) { 
    ioctl(fd, WDIOC_KEEPALIVE, 0);
    sleep(10);
}

我也想从另一个进程发送保持活动状态,但我无法打开另一个 fd 到/dev/watchdog/ :当我尝试回显到/dev/watchdog/我收到错误“设备或资源繁忙”。

  1. 我在哪里可以看到看门狗被定义为一次只能处理 1 个进程? (我在另一个 Linux 中看到某些进程可以打开 fd 到/dev/watchdog/ )。

  2. 我该怎么做才能从 2 个进程中喂养看门狗?

由于/dev/watchdog在内核中的实现,只有一个进程可以同时使用它,所以从两个不同的进程打开/dev/watchdog是不可能的。

您可以在 Linux 内核的源代码中看到这一点,特别是在drivers/watchdog/watchdog_dev.c 这是相关的代码片段:

/*
 *  watchdog_open: open the /dev/watchdog* devices.
 *  @inode: inode of device
 *  @file: file handle to device
 *
 *  When the /dev/watchdog* device gets opened, we start the watchdog.
 *  Watch out: the /dev/watchdog device is single open, so we make sure
 *  it can only be opened once.
 */

static int watchdog_open(struct inode *inode, struct file *file)
{
    /* ... */

    /* the watchdog is single open! */
    if (test_and_set_bit(_WDOG_DEV_OPEN, &wd_data->status))
        return -EBUSY;

    /* ... */

如果您想从两个不同的进程提供看门狗,您可以通过创建一个简单的“主”程序来解决这个问题,该程序与看门狗对话,同时根据需要编排两个子进程。 这可以通过不同的方式完成(管道、套接字、线程等)。 每个子进程一个popen()是最简单的方法。

这是一个工作示例master.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/watchdog.h>

int main(int argc, char **argv) {
    int watchdog_fd;
    FILE *child1_fp, *child2_fp;

    if (argc != 3 || !argv[1] || !*argv[1] || !argv[2] || !*argv[2]) {
        fprintf(stderr, "Usage: %s 'CHILD_1_COMMAND' 'CHILD_2_COMMAND'\n", argv[0]);
        return 1;
    }

    // Open a fd to talk to the watchdog.
    watchdog_fd = open("/dev/watchdog", O_RDWR);
    if (watchdog_fd == -1) {
        perror("open failed");
        return 1;
    }

    // Start the first process.
    child1_fp = popen(argv[1], "r");
    if (child1_fp == NULL) {
        perror("popen (1) failed");
        return 1;
    }

    // Start the second process.
    child2_fp = popen(argv[2], "r");
    if (child2_fp == NULL) {
        perror("popen (2) failed");
        return 1;
    }

    while (1) {
        char tmp;
        size_t count;

        // Get one byte of data from each of the two processes.
        count = fread(&tmp, 1, 1, child1_fp);
        count += fread(&tmp, 1, 1, child2_fp);

        // If both processes provided the data, ping the watchdog.
        if (count == 2) {
            if (ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0) < 0)
                perror("ioctl failed");
        }
    }

    return 0;
}

还有两个相同的程序acbc仅用于测试目的:

#include <stdio.h>
#include <unistd.h>

int main(void) {
    setvbuf(stdout, NULL, _IONBF, 0);

    while (1) {
        putchar('x');
        sleep(10);
    }
}

编译并运行:

$ gcc -o master master.c
$ gcc -o a a.c
$ gcc -o b b.c

$ ./master ./a ./b

在上面的示例代码中,当且仅当两个孩子还活着并且正在运行时, master ping 看门狗:如果两个孩子中的一个挂了或死了,master 将停止 ping 看门狗。 但是,重新设计逻辑以使其工作方式不同很简单,并且使其与两个以上的子进程一起工作也很简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM