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-all mailing list