harddog_user.c 2.9 KB

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