157580Smjacob/* $FreeBSD$ */ 257580Smjacob/* 357580Smjacob * Copyright (c) 2000 by Matthew Jacob 457580Smjacob * All rights reserved. 557580Smjacob * 657580Smjacob * Redistribution and use in source and binary forms, with or without 757580Smjacob * modification, are permitted provided that the following conditions 857580Smjacob * are met: 957580Smjacob * 1. Redistributions of source code must retain the above copyright 1057580Smjacob * notice, this list of conditions, and the following disclaimer, 1157580Smjacob * without modification, immediately at the beginning of the file. 1257580Smjacob * 2. The name of the author may not be used to endorse or promote products 1357580Smjacob * derived from this software without specific prior written permission. 1457580Smjacob * 1557580Smjacob * Alternatively, this software may be distributed under the terms of the 1657580Smjacob * the GNU Public License ("GPL"). 1757580Smjacob * 1857580Smjacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1957580Smjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2057580Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2157580Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 2257580Smjacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2357580Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2457580Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2557580Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2657580Smjacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2757580Smjacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2857580Smjacob * SUCH DAMAGE. 2957580Smjacob * 3057580Smjacob * Matthew Jacob 3157580Smjacob * Feral Software 3257580Smjacob * mjacob@feral.com 3357580Smjacob */ 3457580Smjacob#include <unistd.h> 35235911Smav#include <stddef.h> 36235911Smav#include <stdint.h> 3757580Smjacob#include <stdlib.h> 3857580Smjacob#include <stdio.h> 3957580Smjacob#include <fcntl.h> 4057580Smjacob#include <errno.h> 4157580Smjacob#include <string.h> 4257580Smjacob#include <syslog.h> 43242638Smav#include <unistd.h> 4457580Smjacob#include <sys/ioctl.h> 45235911Smav#include <cam/scsi/scsi_all.h> 46235911Smav#include <cam/scsi/scsi_enc.h> 4757580Smjacob 4857580Smjacob#define ALLSTAT (SES_ENCSTAT_UNRECOV | SES_ENCSTAT_CRITICAL | \ 4957580Smjacob SES_ENCSTAT_NONCRITICAL | SES_ENCSTAT_INFO) 5057580Smjacob 5157580Smjacob/* 5257580Smjacob * Monitor named SES devices and note (via syslog) any changes in status. 5357580Smjacob */ 5457580Smjacob 5557580Smjacobint 56198934Sdelphijmain(int a, char **v) 5757580Smjacob{ 58198934Sdelphij static const char *usage = 59242638Smav "usage: %s [ -c ] [ -d ] [ -t pollinterval ] device [ device ]\n"; 60242638Smav int fd, polltime, dev, nodaemon, clear, c; 61242638Smav encioc_enc_status_t stat, nstat, *carray; 6257580Smjacob 6357580Smjacob if (a < 2) { 6457580Smjacob fprintf(stderr, usage, *v); 6557580Smjacob return (1); 6657580Smjacob } 6757580Smjacob 68242638Smav nodaemon = 0; 69242638Smav polltime = 30; 70242638Smav clear = 0; 71242638Smav while ((c = getopt(a, v, "cdt:")) != -1) { 72242638Smav switch (c) { 73242638Smav case 'c': 74242638Smav clear = 1; 75242638Smav break; 76242638Smav case 'd': 77242638Smav nodaemon = 1; 78242638Smav break; 79242638Smav case 't': 80242638Smav polltime = atoi(optarg); 81242638Smav break; 82242638Smav default: 83242638Smav fprintf(stderr, usage, *v); 84242638Smav return (1); 85242638Smav } 8657580Smjacob } 8757580Smjacob 8857580Smjacob carray = malloc(a); 8957580Smjacob if (carray == NULL) { 9057580Smjacob perror("malloc"); 9157580Smjacob return (1); 9257580Smjacob } 93242638Smav for (dev = optind; dev < a; dev++) 94235911Smav carray[dev] = (encioc_enc_status_t) -1; 9557580Smjacob 9657580Smjacob /* 9757580Smjacob * Check to make sure we can open all devices 9857580Smjacob */ 99242638Smav for (dev = optind; dev < a; dev++) { 10057580Smjacob fd = open(v[dev], O_RDWR); 10157580Smjacob if (fd < 0) { 10257580Smjacob perror(v[dev]); 10357580Smjacob return (1); 10457580Smjacob } 105235911Smav if (ioctl(fd, ENCIOC_INIT, NULL) < 0) { 106235911Smav fprintf(stderr, "%s: ENCIOC_INIT fails- %s\n", 10757580Smjacob v[dev], strerror(errno)); 10857580Smjacob return (1); 10957580Smjacob } 11057580Smjacob (void) close(fd); 11157580Smjacob } 11257580Smjacob if (nodaemon == 0) { 11357580Smjacob if (daemon(0, 0) < 0) { 11457580Smjacob perror("daemon"); 11557580Smjacob return (1); 11657580Smjacob } 11757580Smjacob openlog("sesd", LOG_CONS, LOG_USER); 11857580Smjacob } else { 11957580Smjacob openlog("sesd", LOG_CONS|LOG_PERROR, LOG_USER); 12057580Smjacob } 12157580Smjacob 12257580Smjacob for (;;) { 123242638Smav for (dev = optind; dev < a; dev++) { 12457580Smjacob fd = open(v[dev], O_RDWR); 12557580Smjacob if (fd < 0) { 12657580Smjacob syslog(LOG_ERR, "%s: %m", v[dev]); 12757580Smjacob continue; 12857580Smjacob } 12957580Smjacob 13057580Smjacob /* 13157580Smjacob * Get the actual current enclosure status. 13257580Smjacob */ 133235911Smav if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &stat) < 0) { 13457580Smjacob syslog(LOG_ERR, 135235911Smav "%s: ENCIOC_GETENCSTAT- %m", v[dev]); 13657580Smjacob (void) close(fd); 13757580Smjacob continue; 13857580Smjacob } 139242638Smav if (stat != 0 && clear) { 140242638Smav nstat = 0; 141242638Smav if (ioctl(fd, ENCIOC_SETENCSTAT, 142242638Smav (caddr_t) &nstat) < 0) { 143242638Smav syslog(LOG_ERR, 144242638Smav "%s: ENCIOC_SETENCSTAT- %m", v[dev]); 145242638Smav } 146242638Smav } 14757580Smjacob (void) close(fd); 14857580Smjacob 14957580Smjacob if (stat == carray[dev]) 15057580Smjacob continue; 15157580Smjacob 15257580Smjacob carray[dev] = stat; 15357580Smjacob if ((stat & ALLSTAT) == 0) { 15457580Smjacob syslog(LOG_NOTICE, 15557580Smjacob "%s: Enclosure Status OK", v[dev]); 15657580Smjacob } 15757580Smjacob if (stat & SES_ENCSTAT_INFO) { 158242634Smav syslog(LOG_NOTICE, 159242634Smav "%s: Enclosure Has Information", v[dev]); 16057580Smjacob } 16157580Smjacob if (stat & SES_ENCSTAT_NONCRITICAL) { 16257580Smjacob syslog(LOG_WARNING, 16357580Smjacob "%s: Enclosure Non-Critical", v[dev]); 16457580Smjacob } 16557580Smjacob if (stat & SES_ENCSTAT_CRITICAL) { 16657580Smjacob syslog(LOG_CRIT, 16757580Smjacob "%s: Enclosure Critical", v[dev]); 16857580Smjacob } 16957580Smjacob if (stat & SES_ENCSTAT_UNRECOV) { 17057580Smjacob syslog(LOG_ALERT, 17157580Smjacob "%s: Enclosure Unrecoverable", v[dev]); 17257580Smjacob } 17357580Smjacob } 17457580Smjacob sleep(polltime); 17557580Smjacob } 17657580Smjacob /* NOTREACHED */ 17757580Smjacob} 178