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