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