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