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 15 struct dog_data { 16 int stdin; 17 int stdout; 18 int close_me[2]; 19 }; 20 21 static 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 34 int 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 /* XXX The os_getpid() is not SMP correct */ 67 sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid())); 68 args = pid_args; 69 } 70 71 pid = run_helper(pre_exec, &data, args); 72 73 os_close_file(out_fds[0]); 74 os_close_file(in_fds[1]); 75 76 if(pid < 0){ 77 err = -pid; 78 printk("harddog_open - run_helper failed, errno = %d\n", -err); 79 goto out_close_out; 80 } 81 82 n = os_read_file(in_fds[0], &c, sizeof(c)); 83 if(n == 0){ 84 printk("harddog_open - EOF on watchdog pipe\n"); 85 helper_wait(pid); 86 err = -EIO; 87 goto out_close_out; 88 } 89 else if(n < 0){ 90 printk("harddog_open - read of watchdog pipe failed, " 91 "err = %d\n", -n); 92 helper_wait(pid); 93 err = n; 94 goto out_close_out; 95 } 96 *in_fd_ret = in_fds[0]; 97 *out_fd_ret = out_fds[1]; 98 return 0; 99 100 out_close_in: 101 os_close_file(in_fds[0]); 102 os_close_file(in_fds[1]); 103 out_close_out: 104 os_close_file(out_fds[0]); 105 os_close_file(out_fds[1]); 106 out: 107 return err; 108 } 109 110 void stop_watchdog(int in_fd, int out_fd) 111 { 112 os_close_file(in_fd); 113 os_close_file(out_fd); 114 } 115 116 int ping_watchdog(int fd) 117 { 118 int n; 119 char c = '\n'; 120 121 n = os_write_file(fd, &c, sizeof(c)); 122 if(n != sizeof(c)){ 123 printk("ping_watchdog - write failed, err = %d\n", -n); 124 if(n < 0) 125 return n; 126 return -EIO; 127 } 128 return 1; 129 130 } 131