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