harddog_user.c 2.4 KB

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