harddog_user.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  3. * Licensed under the GPL
  4. */
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <errno.h>
  8. #include "user_util.h"
  9. #include "user.h"
  10. #include "mconsole.h"
  11. #include "os.h"
  12. #include "choose-mode.h"
  13. #include "mode.h"
  14. struct dog_data {
  15. int stdin;
  16. int stdout;
  17. int close_me[2];
  18. };
  19. static void pre_exec(void *d)
  20. {
  21. struct dog_data *data = d;
  22. dup2(data->stdin, 0);
  23. dup2(data->stdout, 1);
  24. dup2(data->stdout, 2);
  25. os_close_file(data->stdin);
  26. os_close_file(data->stdout);
  27. os_close_file(data->close_me[0]);
  28. os_close_file(data->close_me[1]);
  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;
  34. char pid_buf[sizeof("nnnnn\0")], c;
  35. char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL };
  36. char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL,
  37. NULL };
  38. char **args = NULL;
  39. err = os_pipe(in_fds, 1, 0);
  40. if(err < 0){
  41. printk("harddog_open - os_pipe failed, err = %d\n", -err);
  42. goto out;
  43. }
  44. err = os_pipe(out_fds, 1, 0);
  45. if(err < 0){
  46. printk("harddog_open - os_pipe failed, err = %d\n", -err);
  47. goto out_close_in;
  48. }
  49. data.stdin = out_fds[0];
  50. data.stdout = in_fds[1];
  51. data.close_me[0] = out_fds[1];
  52. data.close_me[1] = in_fds[0];
  53. if(sock != NULL){
  54. mconsole_args[2] = sock;
  55. args = mconsole_args;
  56. }
  57. else {
  58. /* XXX The os_getpid() is not SMP correct */
  59. sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid()));
  60. args = pid_args;
  61. }
  62. pid = run_helper(pre_exec, &data, args, NULL);
  63. os_close_file(out_fds[0]);
  64. os_close_file(in_fds[1]);
  65. if(pid < 0){
  66. err = -pid;
  67. printk("harddog_open - run_helper failed, errno = %d\n", -err);
  68. goto out_close_out;
  69. }
  70. n = os_read_file(in_fds[0], &c, sizeof(c));
  71. if(n == 0){
  72. printk("harddog_open - EOF on watchdog pipe\n");
  73. helper_wait(pid);
  74. err = -EIO;
  75. goto out_close_out;
  76. }
  77. else if(n < 0){
  78. printk("harddog_open - read of watchdog pipe failed, "
  79. "err = %d\n", -n);
  80. helper_wait(pid);
  81. err = n;
  82. goto out_close_out;
  83. }
  84. *in_fd_ret = in_fds[0];
  85. *out_fd_ret = out_fds[1];
  86. return(0);
  87. out_close_in:
  88. os_close_file(in_fds[0]);
  89. os_close_file(in_fds[1]);
  90. out_close_out:
  91. os_close_file(out_fds[0]);
  92. os_close_file(out_fds[1]);
  93. out:
  94. return(err);
  95. }
  96. void stop_watchdog(int in_fd, int out_fd)
  97. {
  98. os_close_file(in_fd);
  99. os_close_file(out_fd);
  100. }
  101. int ping_watchdog(int fd)
  102. {
  103. int n;
  104. char c = '\n';
  105. n = os_write_file(fd, &c, sizeof(c));
  106. if(n != sizeof(c)){
  107. printk("ping_watchdog - write failed, err = %d\n", -n);
  108. if(n < 0)
  109. return(n);
  110. return(-EIO);
  111. }
  112. return 1;
  113. }
  114. /*
  115. * Overrides for Emacs so that we follow Linus's tabbing style.
  116. * Emacs will notice this stuff at the end of the file and automatically
  117. * adjust the settings for this buffer only. This must remain at the end
  118. * of the file.
  119. * ---------------------------------------------------------------------------
  120. * Local variables:
  121. * c-file-style: "linux"
  122. * End:
  123. */