svn commit: r293865 - stable/10/usr.sbin/sesutil
Oliver Pinter
oliver.pinter at hardenedbsd.org
Thu Jan 14 12:17:57 UTC 2016
On 1/14/16, Allan Jude <allanjude at freebsd.org> wrote:
> Author: allanjude
> Date: Thu Jan 14 01:42:09 2016
> New Revision: 293865
> URL: https://svnweb.freebsd.org/changeset/base/293865
>
> Log:
> MFC: r287473
> Add the new sesutil(8) utility for managing SCSI Enclosure Services
> (SES) device.
>
> MFC: r287493
> Fix iteration bug
>
> MFC: r287485, r287494, r287992
> Please the angry gcc 4.2 gods
>
> MFC: r287988
> Improve and expand sesutil(8)
>
> Return an error if no matching device is found
> Locate can address a slot, in addition to a drive
> Added fault, similar to locate but blinks a different LED
> Added the map command, lists all devices connected to the SES
> controller
> Added the status command, overall status of the SES controller
>
> MFC: r292092
> sesutil: fix map not printing the status of the LED device in an array
>
> MFC: r292093
> sesutil: pass the correct element type when printing the SES map
>
> MFC: r292121
> sesutil: Add extra information specific to some SES devices to sesutil
> map
>
> MFC: r292122
> Fix sesutil locate when a sesid is passed to locate command
>
> MFC: r292262
> Show the enclosure name and id in sesutil map
>
> Relnotes: yes
> Sponsored by: Gandi.net
> Sponsored by: ScaleEngine Inc.
>
> Added:
> stable/10/usr.sbin/sesutil/eltsub.c
> - copied, changed from r287988, head/usr.sbin/sesutil/eltsub.c
> stable/10/usr.sbin/sesutil/eltsub.h
> - copied, changed from r287988, head/usr.sbin/sesutil/eltsub.h
> Modified:
> stable/10/usr.sbin/sesutil/Makefile
> stable/10/usr.sbin/sesutil/sesutil.8
> stable/10/usr.sbin/sesutil/sesutil.c
> Directory Properties:
> stable/10/ (props changed)
>
> Modified: stable/10/usr.sbin/sesutil/Makefile
This commit breaks the build on 10-STABLE::
--- rescue.all__D ---
sh_stub.c:1:66: warning: implicit declaration of function 'main' is
invalid in C99 [-Wimplicit-function-declaration]
int _crunched_sh_stub(int argc, char **argv, char **envp){return
main(argc,argv,envp);}
^
--- usr.sbin.all__D ---
--- all_subdir_sesutil ---
sesutil.o: In function `objmap':
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/sesutil.c:(.text+0x561):
undefined reference to `sbuf_len'
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/sesutil.c:(.text+0x56e):
undefined reference to `sbuf_data'
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/sesutil.c:(.text+0x588):
undefined reference to `sbuf_delete'
eltsub.o: In function `stat2sbuf':
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/eltsub.c:(.text+0x4db):
undefined reference to `sbuf_new'
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/eltsub.c:(.text+0x4fd):
undefined reference to `sbuf_printf'
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/eltsub.c:(.text+0x513):
undefined reference to `sbuf_printf'
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/eltsub.c:(.text+0x529):
undefined reference to `sbuf_printf'
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/eltsub.c:(.text+0x587):
undefined reference to `sbuf_printf'
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/eltsub.c:(.text+0x5a5):
undefined reference to `sbuf_printf'
eltsub.o:/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/eltsub.c:(.text+0x5bc):
more undefined references to `sbuf_printf' follow
eltsub.o: In function `stat2sbuf':
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/usr.sbin/sesutil/eltsub.c:(.text+0x5e6):
undefined reference to `sbuf_finish'
--- secure.all__D ---
More info about the error:
http://jenkins.hardenedbsd.org:8180/jenkins/job/HardenedBSD-10-STABLE-amd64/lastFailedBuild/console
> ==============================================================================
> --- stable/10/usr.sbin/sesutil/Makefile Thu Jan 14 01:34:41 2016 (r293864)
> +++ stable/10/usr.sbin/sesutil/Makefile Thu Jan 14 01:42:09 2016 (r293865)
> @@ -1,6 +1,9 @@
> # $FreeBSD$
>
> PROG= sesutil
> +SRCS= sesutil.c eltsub.c
> MAN= sesutil.8
>
> +LIBADD= sbuf
> +
> .include <bsd.prog.mk>
>
> Copied and modified: stable/10/usr.sbin/sesutil/eltsub.c (from r287988,
> head/usr.sbin/sesutil/eltsub.c)
> ==============================================================================
> --- head/usr.sbin/sesutil/eltsub.c Sat Sep 19 16:36:45 2015 (r287988, copy
> source)
> +++ stable/10/usr.sbin/sesutil/eltsub.c Thu Jan 14 01:42:09 2016 (r293865)
> @@ -32,6 +32,11 @@
> * mjacob at feral.com
> */
>
> +#include <sys/endian.h>
> +#include <sys/types.h>
> +#include <sys/sbuf.h>
> +
> +#include <err.h>
> #include <unistd.h>
> #include <stddef.h>
> #include <stdint.h>
> @@ -43,6 +48,13 @@
>
> #include "eltsub.h"
>
> +/*
> + * offset by +20 degrees.
> + * The range of the value expresses a temperature between -19 and +235
> degrees
> + * Celsius. A value of 00h is reserved.
> + */
> +#define TEMPERATURE_OFFSET 20
> +
> char *
> geteltnm(int type)
> {
> @@ -134,7 +146,7 @@ geteltnm(int type)
> return (rbuf);
> }
>
> -static char *
> +char *
> scode2ascii(u_char code)
> {
> static char rbuf[32];
> @@ -173,22 +185,51 @@ scode2ascii(u_char code)
> return (rbuf);
> }
>
> -
> -char *
> -stat2ascii(int eletype, u_char *cstat)
> +struct sbuf *
> +stat2sbuf(int eletype, u_char *cstat)
> {
> - static char ebuf[256], *scode;
> + struct sbuf *buf;
>
> - scode = scode2ascii(cstat[0]);
> - sprintf(ebuf, "%s%s%s%s%s%s (0x%02x 0x%02x 0x%02x 0x%02x)",
> - scode,
> - (cstat[0] & 0x40) ? ", Prd.Fail" : "",
> - (cstat[0] & 0x20) ? ", Disabled" : "",
> - (cstat[0] & 0x10) ? ", Swapped" : "",
> - (eletype == ELMTYP_DEVICE && (cstat[2] & 0x02)) ?
> - ", LED=Locate" : "",
> - (eletype == ELMTYP_DEVICE && (cstat[3] & 0x20)) ?
> - ", LED=Fault" : "",
> - cstat[0], cstat[1], cstat[2], cstat[3]);
> - return (ebuf);
> + buf = sbuf_new_auto();
> + if (buf == NULL)
> + err(EXIT_FAILURE, "sbuf_new_auto()");
> +
> + if (cstat[0] & 0x40)
> + sbuf_printf(buf, "\t\t- Predicted Failure\n");
> + if (cstat[0] & 0x20)
> + sbuf_printf(buf, "\t\t- Disabled\n");
> + if (cstat[0] & 0x10)
> + sbuf_printf(buf, "\t\t- Swapped\n");
> + switch (eletype) {
> + case ELMTYP_DEVICE:
> + if (cstat[2] & 0x02)
> + sbuf_printf(buf, "\t\t- LED=locate\n");
> + if (cstat[2] & 0x20)
> + sbuf_printf(buf, "\t\t- LED=fault\n");
> + break;
> + case ELMTYP_ARRAY_DEV:
> + if (cstat[2] & 0x02)
> + sbuf_printf(buf, "\t\t- LED=locate\n");
> + if (cstat[2] & 0x20)
> + sbuf_printf(buf, "\t\t- LED=fault\n");
> + break;
> + case ELMTYP_FAN:
> + sbuf_printf(buf, "\t\t- Speed: %d rpm\n",
> + (((0x7 & cstat[1]) << 8) + cstat[2]) * 10);
> + break;
> + case ELMTYP_THERM:
> + if (cstat[2]) {
> + sbuf_printf(buf, "\t\t- Temperature: %d C\n",
> + cstat[2] - TEMPERATURE_OFFSET);
> + } else {
> + sbuf_printf(buf, "\t\t- Temperature: -reserved-\n");
> + }
> + break;
> + case ELMTYP_VOM:
> + sbuf_printf(buf, "\t\t- Voltage: %.2f V\n",
> + be16dec(cstat + 2) / 100.0);
> + break;
> + }
> + sbuf_finish(buf);
> + return (buf);
> }
>
> Copied and modified: stable/10/usr.sbin/sesutil/eltsub.h (from r287988,
> head/usr.sbin/sesutil/eltsub.h)
> ==============================================================================
> --- head/usr.sbin/sesutil/eltsub.h Sat Sep 19 16:36:45 2015 (r287988, copy
> source)
> +++ stable/10/usr.sbin/sesutil/eltsub.h Thu Jan 14 01:42:09 2016 (r293865)
> @@ -32,5 +32,6 @@
> * mjacob at feral.com
> */
>
> -char * geteltnm(int);
> -char * stat2ascii(int, u_char *);
> +char *geteltnm(int);
> +char *scode2ascii(u_char);
> +struct sbuf *stat2sbuf(int, u_char *);
>
> Modified: stable/10/usr.sbin/sesutil/sesutil.8
> ==============================================================================
> --- stable/10/usr.sbin/sesutil/sesutil.8 Thu Jan 14 01:34:41 2016 (r293864)
> +++ stable/10/usr.sbin/sesutil/sesutil.8 Thu Jan 14 01:42:09 2016 (r293865)
> @@ -24,7 +24,7 @@
> .\"
> .\" $FreeBSD$
> .\"
> -.Dd September 1, 2015
> +.Dd September 6, 2015
> .Dt SESUTIL 8
> .Os
> .Sh NAME
> @@ -32,34 +32,87 @@
> .Nd Utility for managing SCSI Enclosure Services (SES) device
> .Sh SYNOPSIS
> .Nm
> -.Cm locate Ar disk Bq on|off
> +.Cm fault
> +.Op Fl u Ar /dev/sesN
> +.Aq Ar disk | Ar sesid | Li all
> +.Op on | off
> +.Nm
> +.Cm locate
> +.Op Fl u Ar /dev/sesN
> +.Aq Ar disk | Ar sesid | Li all
> +.Op on | off
> +.Nm
> +.Cm map
> +.Op Fl u Ar /dev/sesN
> +.Nm
> +.Cm status
> +.Op Fl u Ar /dev/sesN
> .Sh DESCRIPTION
> The
> .Nm
> -utility can be used to modify various parameter on SCSI Enclosure Services
> -(SES) device.
> +utility can be used to query and modify various parameter of SCSI
> Enclosure
> +Services (SES) devices.
> .Pp
> List of supported commands:
> .Bl -tag -width indent
> -.It Cm locate Ar disk Bq on|off
> -Change the state of the external LED associated with
> +.It Cm fault Oo Fl u Ar /dev/sesN Oc Ao Ar disk | Li all Ac Op on | off
> +Change the state of the external fault LED associated with
> +.Ar disk .
> +.Ar disk
> +can be the device name of the disk, like
> +.Cm da12 ,
> +or
> +.Ql all .
> +to indicate all disks attached to SES controllers.
> +.It Cm fault Fl u Ar /dev/sesN Ar sesid Op on | off
> +Change the state of the external fault LED associated with an element
> +connected to the SES controller.
> +.Ar sesid
> +must be the element ID of a valid item attached to the controller.
> +Use the
> +.Cm map
> +command to list the elements attached to a controller.
> +.It Cm locate Oo Fl u Ar /dev/sesN Oc Ao Ar disk | Li all Ac Op on | off
> +Change the state of the external locate LED associated with
> .Ar disk .
> .Ar disk
> can be the device name of the disk, like
> .Cm da12 ,
> or
> -.Cm all .
> +.Ql all .
> to indicate all disks attached to SES controllers.
> +.It Cm locate Fl u Ar /dev/sesN Ar sesid Op on | off
> +Change the state of the external locate LED associated with an element
> +connected to the SES controller.
> +.Ar sesid
> +must be the element ID of a valid item attached to the controller.
> +Use the
> +.Cm map
> +command to list the elements attached to a controller.
> +.It Cm map Op Fl u Ar /dev/sesN
> +Display a map of all elements connected to the specified
> +.Xr ses 4
> +controller.
> +If no controller is specified, all controllers are mapped.
> +.It Cm status Op Fl u Ar /dev/sesN
> +Display the status of the specified
> +.Xr ses 4
> +controller.
> +If no controller is specified, the status of each controller is returned.
> .El
> .Sh EXAMPLES
> -Turn off all external LEDs:
> +Turn off all locate LEDs:
> .Pp
> .Dl Nm Cm locate all off
> .Pp
> -Turn on the external LED of drive
> +Turn on the locate LED for the drive bay corresponding to
> .Pa da15 :
> .Pp
> .Dl Nm Cm locate da15 on
> +.Pp
> +Turn on the fault LED for a drive bay not associated with a device:
> +.Pp
> +.Dl Nm Cm fault -u /dev/ses2 7 on
> .Sh SEE ALSO
> .Xr ses 4
> .Sh HISTORY
> @@ -68,6 +121,10 @@ The
> utility first appeared in
> .Fx 11.0 .
> .Sh AUTHORS
> +.An -nosplit
> The
> -.Nm utility was written by
> -.An Baptiste Daroussin Aq Mt bapt at FreeBSD.org .
> +.Nm
> +utility was written by
> +.An Baptiste Daroussin Aq Mt bapt at FreeBSD.org
> +and
> +.An Allan Jude Aq Mt allanjude at FreeBSD.org .
>
> Modified: stable/10/usr.sbin/sesutil/sesutil.c
> ==============================================================================
> --- stable/10/usr.sbin/sesutil/sesutil.c Thu Jan 14 01:34:41 2016 (r293864)
> +++ stable/10/usr.sbin/sesutil/sesutil.c Thu Jan 14 01:42:09 2016 (r293865)
> @@ -1,5 +1,7 @@
> /*-
> * Copyright (c) 2015 Baptiste Daroussin <bapt at FreeBSD.org>
> + * Copyright (c) 2015 Allan Jude <allanjude at FreeBSD.org>
> + * Copyright (c) 2000 by Matthew Jacob
> * All rights reserved.
> *
> * Redistribution and use in source and binary forms, with or without
> @@ -29,10 +31,13 @@ __FBSDID("$FreeBSD$");
>
> #include <sys/param.h>
> #include <sys/ioctl.h>
> +#include <sys/types.h>
> +#include <sys/sbuf.h>
>
> #include <err.h>
> #include <errno.h>
> #include <fcntl.h>
> +#include <getopt.h>
> #include <glob.h>
> #include <stdbool.h>
> #include <stddef.h>
> @@ -45,21 +50,66 @@ __FBSDID("$FreeBSD$");
> #include <cam/scsi/scsi_all.h>
> #include <cam/scsi/scsi_enc.h>
>
> +#include "eltsub.h"
> +
> +static int encstatus(int argc, char **argv);
> +static int fault(int argc, char **argv);
> static int locate(int argc, char **argv);
> +static int objmap(int argc, char **argv);
> +static int sesled(int argc, char **argv, bool fault);
>
> static struct command {
> const char *name;
> + const char *param;
> const char *desc;
> int (*exec)(int argc, char **argv);
> } cmds[] = {
> - { "locate", "Change the state of the external LED associated with a"
> - " disk", locate} ,
> + { "fault",
> + "(<disk>|<sesid>|all) (on|off)",
> + "Change the state of the fault LED associated with a disk",
> + fault },
> + { "locate",
> + "(<disk>|<sesid>|all) (on|off)",
> + "Change the state of the locate LED associated with a disk",
> + locate },
> + { "map", "",
> + "Print a map of the devices managed by the enclosure", objmap } ,
> + { "status", "", "Print the status of the enclosure",
> + encstatus },
> };
>
> static const int nbcmds = nitems(cmds);
> +static const char *uflag;
> +
> +static void
> +usage(FILE *out, const char *subcmd)
> +{
> + int i;
> +
> + if (subcmd == NULL) {
> + fprintf(out, "Usage: %s [-u /dev/ses<N>] <command> [options]\n",
> + getprogname());
> + fprintf(out, "Commands supported:\n");
> + }
> + for (i = 0; i < nbcmds; i++) {
> + if (subcmd != NULL) {
> + if (strcmp(subcmd, cmds[i].name) == 0) {
> + fprintf(out, "Usage: %s %s [-u /dev/ses<N>] "
> + "%s\n\t%s\n", getprogname(), subcmd,
> + cmds[i].param, cmds[i].desc);
> + break;
> + }
> + continue;
> + }
> + fprintf(out, " %-12s%s\n\t\t%s\n\n", cmds[i].name,
> + cmds[i].param, cmds[i].desc);
> + }
> +
> + exit(EXIT_FAILURE);
> +}
>
> static void
> -do_locate(int fd, unsigned int idx, bool onoff)
> +do_led(int fd, unsigned int idx, bool onoff, bool setfault)
> {
> encioc_elm_status_t o;
>
> @@ -69,10 +119,11 @@ do_locate(int fd, unsigned int idx, bool
> err(EXIT_FAILURE, "ENCIOC_GETELMSTAT");
> }
> o.cstat[0] |= 0x80;
> - if (onoff)
> - o.cstat[2] |= 0x02;
> - else
> - o.cstat[2] &= 0xfd;
> + if (onoff) {
> + o.cstat[2] |= (setfault ? 0x20 : 0x02);
> + } else {
> + o.cstat[2] &= (setfault ? 0xdf : 0xfd);
> + }
>
> if (ioctl(fd, ENCIOC_SETELMSTAT, (caddr_t) &o) < 0) {
> close(fd);
> @@ -87,39 +138,54 @@ disk_match(const char *devnames, const c
>
> dname = devnames;
> while ((dname = strstr(dname, disk)) != NULL) {
> - if (dname[len] == '\0' || dname[len] == ',')
> + if (dname[len] == '\0' || dname[len] == ',') {
> return (true);
> + }
> dname++;
> }
> +
> return (false);
> }
>
> static int
> -locate(int argc, char **argv)
> +sesled(int argc, char **argv, bool setfault)
> {
> encioc_elm_devnames_t objdn;
> encioc_element_t *objp;
> glob_t g;
> - char *disk;
> - size_t len, i;
> - int fd, nobj, j;
> - bool all = false;
> - bool onoff;
> -
> - if (argc != 2) {
> - errx(EXIT_FAILURE, "usage: %s locate [disk] [on|off]",
> - getprogname());
> + char *disk, *endptr;
> + size_t len, i, ndisks;
> + int fd;
> + unsigned int nobj, j, sesid;
> + bool all, isses, onoff;
> +
> + isses = false;
> + all = false;
> + onoff = false;
> +
> + if (argc != 3) {
> + usage(stderr, (setfault ? "fault" : "locate"));
> + }
> +
> + disk = argv[1];
> +
> + sesid = strtoul(disk, &endptr, 10);
> + if (*endptr == '\0') {
> + endptr = strrchr(uflag, '*');
> + if (endptr != NULL && *endptr == '*') {
> + warnx("Must specifying a SES device (-u) to use a SES "
> + "id# to identify a disk");
> + usage(stderr, (setfault ? "fault" : "locate"));
> + }
> + isses = true;
> }
>
> - disk = argv[0];
> -
> - if (strcmp(argv[1], "on") == 0) {
> + if (strcmp(argv[2], "on") == 0) {
> onoff = true;
> - } else if (strcmp(argv[1], "off") == 0) {
> + } else if (strcmp(argv[2], "off") == 0) {
> onoff = false;
> } else {
> - errx(EXIT_FAILURE, "usage: %s locate [disk] [on|off]",
> - getprogname());
> + usage(stderr, (setfault ? "fault" : "locate"));
> }
>
> if (strcmp(disk, "all") == 0) {
> @@ -128,97 +194,367 @@ locate(int argc, char **argv)
> len = strlen(disk);
>
> /* Get the list of ses devices */
> - if (glob("/dev/ses[0-9]*", 0, NULL, &g) == GLOB_NOMATCH) {
> + if (glob((uflag != NULL ? uflag : "/dev/ses[0-9]*"), 0, NULL, &g) ==
> + GLOB_NOMATCH) {
> globfree(&g);
> errx(EXIT_FAILURE, "No SES devices found");
> }
> +
> + ndisks = 0;
> for (i = 0; i < g.gl_pathc; i++) {
> /* ensure we only got numbers after ses */
> if (strspn(g.gl_pathv[i] + 8, "0123456789") !=
> - strlen(g.gl_pathv[i] + 8))
> + strlen(g.gl_pathv[i] + 8)) {
> continue;
> + }
> if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) {
> - if (errno == EACCES)
> - err(EXIT_FAILURE, "enable to access SES device");
> - break;
> + /*
> + * Don't treat non-access errors as critical if we are
> + * accessing all devices
> + */
> + if (errno == EACCES && g.gl_pathc > 1) {
> + err(EXIT_FAILURE, "unable to access SES device");
> + }
> + warn("unable to access SES device: %s", g.gl_pathv[i]);
> + continue;
> }
>
> - if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0)
> + if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) {
> + close(fd);
> err(EXIT_FAILURE, "ENCIOC_GETNELM");
> + }
>
> objp = calloc(nobj, sizeof(encioc_element_t));
> - if (objp == NULL)
> + if (objp == NULL) {
> + close(fd);
> err(EXIT_FAILURE, "calloc()");
> + }
>
> - if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0)
> + if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0) {
> + close(fd);
> err(EXIT_FAILURE, "ENCIOC_GETELMMAP");
> + }
>
> + if (isses) {
> + if (sesid > nobj) {
> + close(fd);
> + errx(EXIT_FAILURE,
> + "Requested SES ID does not exist");
> + }
> + do_led(fd, sesid, onoff, setfault);
> + ndisks++;
> + close(fd);
> + break;
> + }
> for (j = 0; j < nobj; j++) {
> memset(&objdn, 0, sizeof(objdn));
> objdn.elm_idx = objp[j].elm_idx;
> objdn.elm_names_size = 128;
> objdn.elm_devnames = calloc(128, sizeof(char));
> - if (objdn.elm_devnames == NULL)
> + if (objdn.elm_devnames == NULL) {
> + close(fd);
> err(EXIT_FAILURE, "calloc()");
> + }
> if (ioctl(fd, ENCIOC_GETELMDEVNAMES,
> - (caddr_t) &objdn) <0)
> + (caddr_t) &objdn) <0) {
> continue;
> + }
> if (objdn.elm_names_len > 0) {
> if (all) {
> - do_locate(fd, objdn.elm_idx, onoff);
> + do_led(fd, objdn.elm_idx,
> + onoff, setfault);
> continue;
> }
> if (disk_match(objdn.elm_devnames, disk, len)) {
> - do_locate(fd, objdn.elm_idx, onoff);
> + do_led(fd, objdn.elm_idx,
> + onoff, setfault);
> + ndisks++;
> break;
> }
> }
> - }
> + }
> close(fd);
> }
> globfree(&g);
> + if (ndisks == 0 && all == false) {
> + errx(EXIT_FAILURE, "Count not find the SES id of device '%s'",
> + disk);
> + }
>
> return (EXIT_SUCCESS);
> }
>
> -static void
> -usage(FILE *out)
> +static int
> +locate(int argc, char **argv)
> {
> - int i;
>
> - fprintf(out, "Usage: %s [command] [options]\n", getprogname());
> - fprintf(out, "Commands supported:\n");
> - for (i = 0; i < nbcmds; i++)
> - fprintf(out, "\t%-15s%s\n", cmds[i].name, cmds[i].desc);
> + return (sesled(argc, argv, false));
> +}
> +
> +static int
> +fault(int argc, char **argv)
> +{
> +
> + return (sesled(argc, argv, true));
> +}
> +
> +static int
> +objmap(int argc, char **argv __unused)
> +{
> + struct sbuf *extra;
> + encioc_string_t stri;
> + encioc_elm_devnames_t e_devname;
> + encioc_elm_status_t e_status;
> + encioc_elm_desc_t e_desc;
> + encioc_element_t *e_ptr;
> + glob_t g;
> + int fd;
> + unsigned int j, nobj;
> + size_t i;
> + char str[32];
> +
> + if (argc != 1) {
> + usage(stderr, "map");
> + }
> +
> + /* Get the list of ses devices */
> + if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) {
> + globfree(&g);
> + errx(EXIT_FAILURE, "No SES devices found");
> + }
> + for (i = 0; i < g.gl_pathc; i++) {
> + /* ensure we only got numbers after ses */
> + if (strspn(g.gl_pathv[i] + 8, "0123456789") !=
> + strlen(g.gl_pathv[i] + 8)) {
> + continue;
> + }
> + if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) {
> + /*
> + * Don't treat non-access errors as critical if we are
> + * accessing all devices
> + */
> + if (errno == EACCES && g.gl_pathc > 1) {
> + err(EXIT_FAILURE, "unable to access SES device");
> + }
> + warn("unable to access SES device: %s", g.gl_pathv[i]);
> + continue;
> + }
> +
> + if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) {
> + close(fd);
> + err(EXIT_FAILURE, "ENCIOC_GETNELM");
> + }
> +
> + e_ptr = calloc(nobj, sizeof(encioc_element_t));
> + if (e_ptr == NULL) {
> + close(fd);
> + err(EXIT_FAILURE, "calloc()");
> + }
> +
> + if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) e_ptr) < 0) {
> + close(fd);
> + err(EXIT_FAILURE, "ENCIOC_GETELMMAP");
> + }
> +
> + printf("%s:\n", g.gl_pathv[i] + 5);
> + stri.bufsiz = sizeof(str);
> + stri.buf = &str[0];
> + if (ioctl(fd, ENCIOC_GETENCNAME, (caddr_t) &stri) == 0)
> + printf("\tEnclosure Name: %s\n", stri.buf);
> + stri.bufsiz = sizeof(str);
> + stri.buf = &str[0];
> + if (ioctl(fd, ENCIOC_GETENCID, (caddr_t) &stri) == 0)
> + printf("\tEnclosure ID: %s\n", stri.buf);
> +
> + for (j = 0; j < nobj; j++) {
> + /* Get the status of the element */
> + memset(&e_status, 0, sizeof(e_status));
> + e_status.elm_idx = e_ptr[j].elm_idx;
> + if (ioctl(fd, ENCIOC_GETELMSTAT,
> + (caddr_t) &e_status) < 0) {
> + close(fd);
> + err(EXIT_FAILURE, "ENCIOC_GETELMSTAT");
> + }
> + /* Get the description of the element */
> + memset(&e_desc, 0, sizeof(e_desc));
> + e_desc.elm_idx = e_ptr[j].elm_idx;
> + e_desc.elm_desc_len = UINT16_MAX;
> + e_desc.elm_desc_str = calloc(UINT16_MAX, sizeof(char));
> + if (e_desc.elm_desc_str == NULL) {
> + close(fd);
> + err(EXIT_FAILURE, "calloc()");
> + }
> + if (ioctl(fd, ENCIOC_GETELMDESC,
> + (caddr_t) &e_desc) < 0) {
> + close(fd);
> + err(EXIT_FAILURE, "ENCIOC_GETELMDESC");
> + }
> + /* Get the device name(s) of the element */
> + memset(&e_devname, 0, sizeof(e_devname));
> + e_devname.elm_idx = e_ptr[j].elm_idx;
> + e_devname.elm_names_size = 128;
> + e_devname.elm_devnames = calloc(128, sizeof(char));
> + if (e_devname.elm_devnames == NULL) {
> + close(fd);
> + err(EXIT_FAILURE, "calloc()");
> + }
> + if (ioctl(fd, ENCIOC_GETELMDEVNAMES,
> + (caddr_t) &e_devname) <0) {
> + /* We don't care if this fails */
> + e_devname.elm_devnames[0] = '\0';
> + }
> + printf("\tElement %u, Type: %s\n", e_ptr[j].elm_idx,
> + geteltnm(e_ptr[j].elm_type));
> + printf("\t\tStatus: %s (0x%02x 0x%02x 0x%02x 0x%02x)\n",
> + scode2ascii(e_status.cstat[0]), e_status.cstat[0],
> + e_status.cstat[1], e_status.cstat[2],
> + e_status.cstat[3]);
> + if (e_desc.elm_desc_len > 0) {
> + printf("\t\tDescription: %s\n",
> + e_desc.elm_desc_str);
> + }
> + if (e_devname.elm_names_len > 0) {
> + printf("\t\tDevice Names: %s\n",
> + e_devname.elm_devnames);
> + }
> + extra = stat2sbuf(e_ptr[j].elm_type, e_status.cstat);
> + if (sbuf_len(extra) > 0) {
> + printf("\t\tExtra status:\n%s",
> + sbuf_data(extra));
> + }
> + sbuf_delete(extra);
> + free(e_devname.elm_devnames);
> + }
> + close(fd);
> + }
> + globfree(&g);
> +
> + return (EXIT_SUCCESS);
> +}
> +
> +static int
> +encstatus(int argc, char **argv __unused)
> +{
> + glob_t g;
> + int fd, status;
> + size_t i, e;
> + u_char estat;
> +
> + status = 0;
> + if (argc != 1) {
> + usage(stderr, "status");
> + }
> +
> + /* Get the list of ses devices */
> + if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) {
> + globfree(&g);
> + errx(EXIT_FAILURE, "No SES devices found");
> + }
> + for (i = 0; i < g.gl_pathc; i++) {
> + /* ensure we only got numbers after ses */
> + if (strspn(g.gl_pathv[i] + 8, "0123456789") !=
> + strlen(g.gl_pathv[i] + 8)) {
> + continue;
> + }
> + if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) {
> + /*
> + * Don't treat non-access errors as critical if we are
> + * accessing all devices
> + */
> + if (errno == EACCES && g.gl_pathc > 1) {
> + err(EXIT_FAILURE, "unable to access SES device");
> + }
> + warn("unable to access SES device: %s", g.gl_pathv[i]);
> + continue;
> + }
> +
> + if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &estat) < 0) {
> + close(fd);
> + err(EXIT_FAILURE, "ENCIOC_GETENCSTAT");
> + }
> +
> + printf("%s: ", g.gl_pathv[i] + 5);
> + e = 0;
> + if (estat == 0) {
> + if (status == 0) {
> + status = 1;
> + }
> + printf("OK");
> + } else {
> + if (estat & SES_ENCSTAT_INFO) {
> + printf("INFO");
> + e++;
> + }
> + if (estat & SES_ENCSTAT_NONCRITICAL) {
> + if (e)
> + printf(",");
> + printf("NONCRITICAL");
> + e++;
> + }
> + if (estat & SES_ENCSTAT_CRITICAL) {
> + if (e)
> + printf(",");
> + printf("CRITICAL");
> + e++;
> + status = -1;
> + }
> + if (estat & SES_ENCSTAT_UNRECOV) {
> + if (e)
> + printf(",");
> + printf("UNRECOV");
> + e++;
> + status = -1;
> + }
> + }
> + printf("\n");
> +
> + close(fd);
> + }
> + globfree(&g);
> +
> + if (status == 1) {
> + return (EXIT_SUCCESS);
> + } else {
> + return (EXIT_FAILURE);
> + }
> }
>
> int
> main(int argc, char **argv)
> {
> - int i;
> + int i, ch;
> struct command *cmd = NULL;
>
> - if (argc < 2) {
> + uflag = "/dev/ses[0-9]*";
> + while ((ch = getopt_long(argc, argv, "u:", NULL, NULL)) != -1) {
> + switch (ch) {
> + case 'u':
> + uflag = optarg;
> + break;
> + case '?':
> + default:
> + usage(stderr, NULL);
> + }
> + }
> + argc -= optind;
> + argv += optind;
> +
> + if (argc < 1) {
> warnx("Missing command");
> - usage(stderr);
> - return (EXIT_FAILURE);
> + usage(stderr, NULL);
> }
>
> for (i = 0; i < nbcmds; i++) {
> - if (strcmp(argv[1], cmds[i].name) == 0) {
> + if (strcmp(argv[0], cmds[i].name) == 0) {
> cmd = &cmds[i];
> break;
> }
> }
>
> if (cmd == NULL) {
> - warnx("unknown command %s", argv[1]);
> - usage(stderr);
> - return (EXIT_FAILURE);
> + warnx("unknown command %s", argv[0]);
> + usage(stderr, NULL);
> }
>
> - argc-=2;
> - argv+=2;
> -
> return (cmd->exec(argc, argv));
> }
> _______________________________________________
> svn-src-stable-10 at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
> To unsubscribe, send any mail to
> "svn-src-stable-10-unsubscribe at freebsd.org"
>
More information about the svn-src-stable
mailing list