]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - share/examples/ses/srcs/sesd.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / share / examples / ses / srcs / sesd.c
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 <unistd.h>
44 #include <sys/ioctl.h>
45 #include <cam/scsi/scsi_all.h>
46 #include <cam/scsi/scsi_enc.h>
47
48 #define ALLSTAT (SES_ENCSTAT_UNRECOV | SES_ENCSTAT_CRITICAL | \
49         SES_ENCSTAT_NONCRITICAL | SES_ENCSTAT_INFO)
50
51 /*
52  * Monitor named SES devices and note (via syslog) any changes in status.
53  */
54
55 int
56 main(int a, char **v)
57 {
58         static const char *usage =
59             "usage: %s [ -c ] [ -d ] [ -t pollinterval ] device [ device ]\n";
60         int fd, polltime, dev, nodaemon, clear, c;
61         encioc_enc_status_t stat, nstat, *carray;
62
63         if (a < 2) {
64                 fprintf(stderr, usage, *v);
65                 return (1);
66         }
67
68         nodaemon = 0;
69         polltime = 30;
70         clear = 0;
71         while ((c = getopt(a, v, "cdt:")) != -1) {
72                 switch (c) {
73                 case 'c':
74                         clear = 1;
75                         break;
76                 case 'd':
77                         nodaemon = 1;
78                         break;
79                 case 't':
80                         polltime = atoi(optarg);
81                         break;
82                 default:
83                         fprintf(stderr, usage, *v);
84                         return (1);
85                 }
86         }
87
88         carray = malloc(a);
89         if (carray == NULL) {
90                 perror("malloc");
91                 return (1);
92         }
93         for (dev = optind; dev < a; dev++)
94                 carray[dev] = (encioc_enc_status_t) -1;
95
96         /*
97          * Check to make sure we can open all devices
98          */
99         for (dev = optind; dev < a; dev++) {
100                 fd = open(v[dev], O_RDWR);
101                 if (fd < 0) {
102                         perror(v[dev]);
103                         return (1);
104                 }
105                 if (ioctl(fd, ENCIOC_INIT, NULL) < 0) {
106                         fprintf(stderr, "%s: ENCIOC_INIT fails- %s\n",
107                             v[dev], strerror(errno));
108                         return (1);
109                 }
110                 (void) close(fd);
111         }
112         if (nodaemon == 0) {
113                 if (daemon(0, 0) < 0) {
114                         perror("daemon");
115                         return (1);
116                 }
117                 openlog("sesd", LOG_CONS, LOG_USER);
118         } else {
119                 openlog("sesd", LOG_CONS|LOG_PERROR, LOG_USER);
120         }
121
122         for (;;) {
123                 for (dev = optind; dev < a; dev++) {
124                         fd = open(v[dev], O_RDWR);
125                         if (fd < 0) {
126                                 syslog(LOG_ERR, "%s: %m", v[dev]);
127                                 continue;
128                         }
129
130                         /*
131                          * Get the actual current enclosure status.
132                          */
133                         if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &stat) < 0) {
134                                 syslog(LOG_ERR,
135                                     "%s: ENCIOC_GETENCSTAT- %m", v[dev]);
136                                 (void) close(fd);
137                                 continue;
138                         }
139                         if (stat != 0 && clear) {
140                                 nstat = 0;
141                                 if (ioctl(fd, ENCIOC_SETENCSTAT,
142                                     (caddr_t) &nstat) < 0) {
143                                         syslog(LOG_ERR,
144                                             "%s: ENCIOC_SETENCSTAT- %m", v[dev]);
145                                 }
146                         }
147                         (void) close(fd);
148
149                         if (stat == carray[dev])
150                                 continue;
151
152                         carray[dev] = stat;
153                         if ((stat & ALLSTAT) == 0) {
154                                 syslog(LOG_NOTICE,
155                                     "%s: Enclosure Status OK", v[dev]);
156                         }
157                         if (stat & SES_ENCSTAT_INFO) {
158                                 syslog(LOG_NOTICE,
159                                     "%s: Enclosure Has Information", v[dev]);
160                         }
161                         if (stat & SES_ENCSTAT_NONCRITICAL) {
162                                 syslog(LOG_WARNING,
163                                     "%s: Enclosure Non-Critical", v[dev]);
164                         }
165                         if (stat & SES_ENCSTAT_CRITICAL) {
166                                 syslog(LOG_CRIT,
167                                     "%s: Enclosure Critical", v[dev]);
168                         }
169                         if (stat & SES_ENCSTAT_UNRECOV) {
170                                 syslog(LOG_ALERT,
171                                     "%s: Enclosure Unrecoverable", v[dev]);
172                         }
173                 }
174                 sleep(polltime);
175         }
176         /* NOTREACHED */
177 }