129 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 | |
|  * Licensed under the GPL
 | |
|  */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <unistd.h>
 | |
| #include <errno.h>
 | |
| #include "os.h"
 | |
| #include "user.h"
 | |
| 
 | |
| struct dog_data {
 | |
| 	int stdin;
 | |
| 	int stdout;
 | |
| 	int close_me[2];
 | |
| };
 | |
| 
 | |
| static void pre_exec(void *d)
 | |
| {
 | |
| 	struct dog_data *data = d;
 | |
| 
 | |
| 	dup2(data->stdin, 0);
 | |
| 	dup2(data->stdout, 1);
 | |
| 	dup2(data->stdout, 2);
 | |
| 	close(data->stdin);
 | |
| 	close(data->stdout);
 | |
| 	close(data->close_me[0]);
 | |
| 	close(data->close_me[1]);
 | |
| }
 | |
| 
 | |
| int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
 | |
| {
 | |
| 	struct dog_data data;
 | |
| 	int in_fds[2], out_fds[2], pid, n, err;
 | |
| 	char pid_buf[sizeof("nnnnn\0")], c;
 | |
| 	char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL };
 | |
| 	char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL,
 | |
| 				  NULL };
 | |
| 	char **args = NULL;
 | |
| 
 | |
| 	err = os_pipe(in_fds, 1, 0);
 | |
| 	if (err < 0) {
 | |
| 		printk("harddog_open - os_pipe failed, err = %d\n", -err);
 | |
| 		goto out;
 | |
| 	}
 | |
| 
 | |
| 	err = os_pipe(out_fds, 1, 0);
 | |
| 	if (err < 0) {
 | |
| 		printk("harddog_open - os_pipe failed, err = %d\n", -err);
 | |
| 		goto out_close_in;
 | |
| 	}
 | |
| 
 | |
| 	data.stdin = out_fds[0];
 | |
| 	data.stdout = in_fds[1];
 | |
| 	data.close_me[0] = out_fds[1];
 | |
| 	data.close_me[1] = in_fds[0];
 | |
| 
 | |
| 	if (sock != NULL) {
 | |
| 		mconsole_args[2] = sock;
 | |
| 		args = mconsole_args;
 | |
| 	}
 | |
| 	else {
 | |
| 		/* XXX The os_getpid() is not SMP correct */
 | |
| 		sprintf(pid_buf, "%d", os_getpid());
 | |
| 		args = pid_args;
 | |
| 	}
 | |
| 
 | |
| 	pid = run_helper(pre_exec, &data, args);
 | |
| 
 | |
| 	close(out_fds[0]);
 | |
| 	close(in_fds[1]);
 | |
| 
 | |
| 	if (pid < 0) {
 | |
| 		err = -pid;
 | |
| 		printk("harddog_open - run_helper failed, errno = %d\n", -err);
 | |
| 		goto out_close_out;
 | |
| 	}
 | |
| 
 | |
| 	n = read(in_fds[0], &c, sizeof(c));
 | |
| 	if (n == 0) {
 | |
| 		printk("harddog_open - EOF on watchdog pipe\n");
 | |
| 		helper_wait(pid);
 | |
| 		err = -EIO;
 | |
| 		goto out_close_out;
 | |
| 	}
 | |
| 	else if (n < 0) {
 | |
| 		printk("harddog_open - read of watchdog pipe failed, "
 | |
| 		       "err = %d\n", errno);
 | |
| 		helper_wait(pid);
 | |
| 		err = n;
 | |
| 		goto out_close_out;
 | |
| 	}
 | |
| 	*in_fd_ret = in_fds[0];
 | |
| 	*out_fd_ret = out_fds[1];
 | |
| 	return 0;
 | |
| 
 | |
|  out_close_in:
 | |
| 	close(in_fds[0]);
 | |
| 	close(in_fds[1]);
 | |
|  out_close_out:
 | |
| 	close(out_fds[0]);
 | |
| 	close(out_fds[1]);
 | |
|  out:
 | |
| 	return err;
 | |
| }
 | |
| 
 | |
| void stop_watchdog(int in_fd, int out_fd)
 | |
| {
 | |
| 	close(in_fd);
 | |
| 	close(out_fd);
 | |
| }
 | |
| 
 | |
| int ping_watchdog(int fd)
 | |
| {
 | |
| 	int n;
 | |
| 	char c = '\n';
 | |
| 
 | |
| 	n = write(fd, &c, sizeof(c));
 | |
| 	if (n != sizeof(c)) {
 | |
| 		printk("ping_watchdog - write failed, ret = %d, err = %d\n",
 | |
| 		       n, errno);
 | |
| 		if (n < 0)
 | |
| 			return n;
 | |
| 		return -EIO;
 | |
| 	}
 | |
| 	return 1;
 | |
| 
 | |
| }
 |