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