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_util.h" 10 #include "user.h" 11 #include "helper.h" 12 #include "mconsole.h" 13 #include "os.h" 14 #include "choose-mode.h" 15 #include "mode.h" 16 17 struct dog_data { 18 int stdin; 19 int stdout; 20 int close_me[2]; 21 }; 22 23 static void pre_exec(void *d) 24 { 25 struct dog_data *data = d; 26 27 dup2(data->stdin, 0); 28 dup2(data->stdout, 1); 29 dup2(data->stdout, 2); 30 os_close_file(data->stdin); 31 os_close_file(data->stdout); 32 os_close_file(data->close_me[0]); 33 os_close_file(data->close_me[1]); 34 } 35 36 int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) 37 { 38 struct dog_data data; 39 int in_fds[2], out_fds[2], pid, n, err; 40 char pid_buf[sizeof("nnnnn\0")], c; 41 char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL }; 42 char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, 43 NULL }; 44 char **args = NULL; 45 46 err = os_pipe(in_fds, 1, 0); 47 if(err < 0){ 48 printk("harddog_open - os_pipe failed, err = %d\n", -err); 49 goto out; 50 } 51 52 err = os_pipe(out_fds, 1, 0); 53 if(err < 0){ 54 printk("harddog_open - os_pipe failed, err = %d\n", -err); 55 goto out_close_in; 56 } 57 58 data.stdin = out_fds[0]; 59 data.stdout = in_fds[1]; 60 data.close_me[0] = out_fds[1]; 61 data.close_me[1] = in_fds[0]; 62 63 if(sock != NULL){ 64 mconsole_args[2] = sock; 65 args = mconsole_args; 66 } 67 else { 68 /* XXX The os_getpid() is not SMP correct */ 69 sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid())); 70 args = pid_args; 71 } 72 73 pid = run_helper(pre_exec, &data, args, NULL); 74 75 os_close_file(out_fds[0]); 76 os_close_file(in_fds[1]); 77 78 if(pid < 0){ 79 err = -pid; 80 printk("harddog_open - run_helper failed, errno = %d\n", -err); 81 goto out_close_out; 82 } 83 84 n = os_read_file(in_fds[0], &c, sizeof(c)); 85 if(n == 0){ 86 printk("harddog_open - EOF on watchdog pipe\n"); 87 helper_wait(pid); 88 err = -EIO; 89 goto out_close_out; 90 } 91 else if(n < 0){ 92 printk("harddog_open - read of watchdog pipe failed, " 93 "err = %d\n", -n); 94 helper_wait(pid); 95 err = n; 96 goto out_close_out; 97 } 98 *in_fd_ret = in_fds[0]; 99 *out_fd_ret = out_fds[1]; 100 return(0); 101 102 out_close_in: 103 os_close_file(in_fds[0]); 104 os_close_file(in_fds[1]); 105 out_close_out: 106 os_close_file(out_fds[0]); 107 os_close_file(out_fds[1]); 108 out: 109 return(err); 110 } 111 112 void stop_watchdog(int in_fd, int out_fd) 113 { 114 os_close_file(in_fd); 115 os_close_file(out_fd); 116 } 117 118 int ping_watchdog(int fd) 119 { 120 int n; 121 char c = '\n'; 122 123 n = os_write_file(fd, &c, sizeof(c)); 124 if(n != sizeof(c)){ 125 printk("ping_watchdog - write failed, err = %d\n", -n); 126 if(n < 0) 127 return(n); 128 return(-EIO); 129 } 130 return 1; 131 132 } 133 134 /* 135 * Overrides for Emacs so that we follow Linus's tabbing style. 136 * Emacs will notice this stuff at the end of the file and automatically 137 * adjust the settings for this buffer only. This must remain at the end 138 * of the file. 139 * --------------------------------------------------------------------------- 140 * Local variables: 141 * c-file-style: "linux" 142 * End: 143 */ 144