xref: /openbmc/linux/arch/um/drivers/harddog_user.c (revision 1da177e4)
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