linux/arch/um/drivers/harddog_user.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
   4 */
   5
   6#include <stdio.h>
   7#include <unistd.h>
   8#include <errno.h>
   9#include <os.h>
  10
  11struct dog_data {
  12        int stdin_fd;
  13        int stdout_fd;
  14        int close_me[2];
  15};
  16
  17static void pre_exec(void *d)
  18{
  19        struct dog_data *data = d;
  20
  21        dup2(data->stdin_fd, 0);
  22        dup2(data->stdout_fd, 1);
  23        dup2(data->stdout_fd, 2);
  24        close(data->stdin_fd);
  25        close(data->stdout_fd);
  26        close(data->close_me[0]);
  27        close(data->close_me[1]);
  28}
  29
  30int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
  31{
  32        struct dog_data data;
  33        int in_fds[2], out_fds[2], pid, n, err;
  34        char pid_buf[sizeof("nnnnnnn\0")], c;
  35        char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL };
  36        char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL,
  37                                  NULL };
  38        char **args = NULL;
  39
  40        err = os_pipe(in_fds, 1, 0);
  41        if (err < 0) {
  42                printk("harddog_open - os_pipe failed, err = %d\n", -err);
  43                goto out;
  44        }
  45
  46        err = os_pipe(out_fds, 1, 0);
  47        if (err < 0) {
  48                printk("harddog_open - os_pipe failed, err = %d\n", -err);
  49                goto out_close_in;
  50        }
  51
  52        data.stdin_fd = out_fds[0];
  53        data.stdout_fd = in_fds[1];
  54        data.close_me[0] = out_fds[1];
  55        data.close_me[1] = in_fds[0];
  56
  57        if (sock != NULL) {
  58                mconsole_args[2] = sock;
  59                args = mconsole_args;
  60        }
  61        else {
  62                /* XXX The os_getpid() is not SMP correct */
  63                sprintf(pid_buf, "%d", os_getpid());
  64                args = pid_args;
  65        }
  66
  67        pid = run_helper(pre_exec, &data, args);
  68
  69        close(out_fds[0]);
  70        close(in_fds[1]);
  71
  72        if (pid < 0) {
  73                err = -pid;
  74                printk("harddog_open - run_helper failed, errno = %d\n", -err);
  75                goto out_close_out;
  76        }
  77
  78        n = read(in_fds[0], &c, sizeof(c));
  79        if (n == 0) {
  80                printk("harddog_open - EOF on watchdog pipe\n");
  81                helper_wait(pid);
  82                err = -EIO;
  83                goto out_close_out;
  84        }
  85        else if (n < 0) {
  86                printk("harddog_open - read of watchdog pipe failed, "
  87                       "err = %d\n", errno);
  88                helper_wait(pid);
  89                err = n;
  90                goto out_close_out;
  91        }
  92        *in_fd_ret = in_fds[0];
  93        *out_fd_ret = out_fds[1];
  94        return 0;
  95
  96 out_close_in:
  97        close(in_fds[0]);
  98        close(in_fds[1]);
  99 out_close_out:
 100        close(out_fds[0]);
 101        close(out_fds[1]);
 102 out:
 103        return err;
 104}
 105
 106void stop_watchdog(int in_fd, int out_fd)
 107{
 108        close(in_fd);
 109        close(out_fd);
 110}
 111
 112int ping_watchdog(int fd)
 113{
 114        int n;
 115        char c = '\n';
 116
 117        n = write(fd, &c, sizeof(c));
 118        if (n != sizeof(c)) {
 119                printk("ping_watchdog - write failed, ret = %d, err = %d\n",
 120                       n, errno);
 121                if (n < 0)
 122                        return n;
 123                return -EIO;
 124        }
 125        return 1;
 126
 127}
 128