/share/examples/ses/srcs/sesd.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 165 lines · 109 code · 13 blank · 43 comment · 30 complexity · 170ad6b8aa60404490b6ff0558efa17b MD5 · raw file

  1. /* $FreeBSD$ */
  2. /*
  3. * Copyright (c) 2000 by Matthew Jacob
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions, and the following disclaimer,
  11. * without modification, immediately at the beginning of the file.
  12. * 2. The name of the author may not be used to endorse or promote products
  13. * derived from this software without specific prior written permission.
  14. *
  15. * Alternatively, this software may be distributed under the terms of the
  16. * the GNU Public License ("GPL").
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  22. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * Matthew Jacob
  31. * Feral Software
  32. * mjacob@feral.com
  33. */
  34. #include <unistd.h>
  35. #include <stddef.h>
  36. #include <stdint.h>
  37. #include <stdlib.h>
  38. #include <stdio.h>
  39. #include <fcntl.h>
  40. #include <errno.h>
  41. #include <string.h>
  42. #include <syslog.h>
  43. #include <sys/ioctl.h>
  44. #include <cam/scsi/scsi_all.h>
  45. #include <cam/scsi/scsi_enc.h>
  46. #define ALLSTAT (SES_ENCSTAT_UNRECOV | SES_ENCSTAT_CRITICAL | \
  47. SES_ENCSTAT_NONCRITICAL | SES_ENCSTAT_INFO)
  48. /*
  49. * Monitor named SES devices and note (via syslog) any changes in status.
  50. */
  51. int
  52. main(int a, char **v)
  53. {
  54. static const char *usage =
  55. "usage: %s [ -d ] [ -t pollinterval ] device [ device ]\n";
  56. int fd, polltime, dev, devbase, nodaemon;
  57. encioc_enc_status_t stat, *carray;
  58. if (a < 2) {
  59. fprintf(stderr, usage, *v);
  60. return (1);
  61. }
  62. devbase = 1;
  63. if (strcmp(v[1], "-d") == 0) {
  64. nodaemon = 1;
  65. devbase++;
  66. } else {
  67. nodaemon = 0;
  68. }
  69. if (a > 2 && strcmp(v[2], "-t") == 0) {
  70. devbase += 2;
  71. polltime = atoi(v[3]);
  72. } else {
  73. polltime = 30;
  74. }
  75. carray = malloc(a);
  76. if (carray == NULL) {
  77. perror("malloc");
  78. return (1);
  79. }
  80. for (dev = devbase; dev < a; dev++)
  81. carray[dev] = (encioc_enc_status_t) -1;
  82. /*
  83. * Check to make sure we can open all devices
  84. */
  85. for (dev = devbase; dev < a; dev++) {
  86. fd = open(v[dev], O_RDWR);
  87. if (fd < 0) {
  88. perror(v[dev]);
  89. return (1);
  90. }
  91. if (ioctl(fd, ENCIOC_INIT, NULL) < 0) {
  92. fprintf(stderr, "%s: ENCIOC_INIT fails- %s\n",
  93. v[dev], strerror(errno));
  94. return (1);
  95. }
  96. (void) close(fd);
  97. }
  98. if (nodaemon == 0) {
  99. if (daemon(0, 0) < 0) {
  100. perror("daemon");
  101. return (1);
  102. }
  103. openlog("sesd", LOG_CONS, LOG_USER);
  104. } else {
  105. openlog("sesd", LOG_CONS|LOG_PERROR, LOG_USER);
  106. }
  107. for (;;) {
  108. for (dev = devbase; dev < a; dev++) {
  109. fd = open(v[dev], O_RDWR);
  110. if (fd < 0) {
  111. syslog(LOG_ERR, "%s: %m", v[dev]);
  112. continue;
  113. }
  114. /*
  115. * Get the actual current enclosure status.
  116. */
  117. if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &stat) < 0) {
  118. syslog(LOG_ERR,
  119. "%s: ENCIOC_GETENCSTAT- %m", v[dev]);
  120. (void) close(fd);
  121. continue;
  122. }
  123. (void) close(fd);
  124. if (stat == carray[dev])
  125. continue;
  126. carray[dev] = stat;
  127. if ((stat & ALLSTAT) == 0) {
  128. syslog(LOG_NOTICE,
  129. "%s: Enclosure Status OK", v[dev]);
  130. }
  131. if (stat & SES_ENCSTAT_INFO) {
  132. syslog(LOG_INFO,
  133. "%s: Enclosure Status Has Information",
  134. v[dev]);
  135. }
  136. if (stat & SES_ENCSTAT_NONCRITICAL) {
  137. syslog(LOG_WARNING,
  138. "%s: Enclosure Non-Critical", v[dev]);
  139. }
  140. if (stat & SES_ENCSTAT_CRITICAL) {
  141. syslog(LOG_CRIT,
  142. "%s: Enclosure Critical", v[dev]);
  143. }
  144. if (stat & SES_ENCSTAT_UNRECOV) {
  145. syslog(LOG_ALERT,
  146. "%s: Enclosure Unrecoverable", v[dev]);
  147. }
  148. }
  149. sleep(polltime);
  150. }
  151. /* NOTREACHED */
  152. }