svn commit: r320478 - head/usr.sbin/sesutil

Baptiste Daroussin bapt at FreeBSD.org
Thu Jun 29 18:52:38 UTC 2017


Author: bapt
Date: Thu Jun 29 18:52:36 2017
New Revision: 320478
URL: https://svnweb.freebsd.org/changeset/base/320478

Log:
  Add libxo(3) support to sesutil(8)
  
  This is useful to simplify parsing "sesutil map"
  
  Submitted by:	nikita.kozlov at blade-group.com
  MFC after:	3 weeks
  Relnotes:	yes
  Sponsored by:	blade

Modified:
  head/usr.sbin/sesutil/Makefile
  head/usr.sbin/sesutil/eltsub.c
  head/usr.sbin/sesutil/sesutil.8
  head/usr.sbin/sesutil/sesutil.c

Modified: head/usr.sbin/sesutil/Makefile
==============================================================================
--- head/usr.sbin/sesutil/Makefile	Thu Jun 29 18:42:49 2017	(r320477)
+++ head/usr.sbin/sesutil/Makefile	Thu Jun 29 18:52:36 2017	(r320478)
@@ -4,4 +4,6 @@ PROG=	sesutil
 SRCS=	sesutil.c eltsub.c
 MAN=	sesutil.8
 
+LIBADD=	xo
+
 .include <bsd.prog.mk>

Modified: head/usr.sbin/sesutil/eltsub.c
==============================================================================
--- head/usr.sbin/sesutil/eltsub.c	Thu Jun 29 18:42:49 2017	(r320477)
+++ head/usr.sbin/sesutil/eltsub.c	Thu Jun 29 18:52:36 2017	(r320478)
@@ -39,6 +39,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <cam/scsi/scsi_enc.h>
+#include <libxo/xo.h>
 
 #include "eltsub.h"
 

Modified: head/usr.sbin/sesutil/sesutil.8
==============================================================================
--- head/usr.sbin/sesutil/sesutil.8	Thu Jun 29 18:42:49 2017	(r320477)
+++ head/usr.sbin/sesutil/sesutil.8	Thu Jun 29 18:52:36 2017	(r320478)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 6, 2015
+.Dd June 29, 2017
 .Dt SESUTIL 8
 .Os
 .Sh NAME
@@ -43,9 +43,11 @@
 .Op on | off
 .Nm
 .Cm map
+.Op Fl -libxo Ar options
 .Op Fl u Ar /dev/sesN
 .Nm
 .Cm status
+.Op Fl -libxo Ar options
 .Op Fl u Ar /dev/sesN
 .Sh DESCRIPTION
 The
@@ -55,6 +57,12 @@ Services (SES) devices.
 .Pp
 List of supported commands:
 .Bl -tag -width indent
+.It Fl -libxo
+Generate output via
+.Xr libxo 3
+in a selection of different human and machine readable formats.
+See
+.Xr xo_parse_args 3
 .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 .
@@ -114,6 +122,8 @@ Turn on the fault LED for a drive bay not associated w
 .Pp
 .Dl Nm Cm fault -u /dev/ses2 7 on
 .Sh SEE ALSO
+.Xr libxo 3 ,
+.Xr xo_parse_args 3 ,
 .Xr ses 4
 .Sh HISTORY
 The

Modified: head/usr.sbin/sesutil/sesutil.c
==============================================================================
--- head/usr.sbin/sesutil/sesutil.c	Thu Jun 29 18:42:49 2017	(r320477)
+++ head/usr.sbin/sesutil/sesutil.c	Thu Jun 29 18:52:36 2017	(r320478)
@@ -46,11 +46,14 @@ __FBSDID("$FreeBSD$");
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <libxo/xo.h>
 
 #include <cam/scsi/scsi_enc.h>
 
 #include "eltsub.h"
 
+#define SESUTIL_XO_VERSION	"1"
+
 static int encstatus(int argc, char **argv);
 static int fault(int argc, char **argv);
 static int locate(int argc, char **argv);
@@ -116,7 +119,7 @@ do_led(int fd, unsigned int idx, bool onoff, bool setf
 	o.elm_idx = idx;
 	if (ioctl(fd, ENCIOC_GETELMSTAT, (caddr_t) &o) < 0) {
 		close(fd);
-		err(EXIT_FAILURE, "ENCIOC_GETELMSTAT");
+		xo_err(EXIT_FAILURE, "ENCIOC_GETELMSTAT");
 	}
 	o.cstat[0] |= 0x80;
 	if (setfault) {
@@ -133,7 +136,7 @@ do_led(int fd, unsigned int idx, bool onoff, bool setf
 
 	if (ioctl(fd, ENCIOC_SETELMSTAT, (caddr_t) &o) < 0) {
 		close(fd);
-		err(EXIT_FAILURE, "ENCIOC_SETELMSTAT");
+		xo_err(EXIT_FAILURE, "ENCIOC_SETELMSTAT");
 	}
 }
 
@@ -179,7 +182,7 @@ sesled(int argc, char **argv, bool setfault)
 	if (*endptr == '\0') {
 		endptr = strrchr(uflag, '*');
 		if (endptr != NULL && *endptr == '*') {
-			warnx("Must specifying a SES device (-u) to use a SES "
+			xo_warnx("Must specifying a SES device (-u) to use a SES "
 			    "id# to identify a disk");
 			usage(stderr, (setfault ? "fault" : "locate"));
 		}
@@ -203,7 +206,7 @@ sesled(int argc, char **argv, bool setfault)
 	if (glob((uflag != NULL ? uflag : "/dev/ses[0-9]*"), 0, NULL, &g) ==
 	    GLOB_NOMATCH) {
 		globfree(&g);
-		errx(EXIT_FAILURE, "No SES devices found");
+		xo_errx(EXIT_FAILURE, "No SES devices found");
 	}
 
 	ndisks = 0;
@@ -219,32 +222,32 @@ sesled(int argc, char **argv, bool setfault)
 			 * accessing all devices
 			 */
 			if (errno == EACCES && g.gl_pathc > 1) {
-				err(EXIT_FAILURE, "unable to access SES device");
+				xo_err(EXIT_FAILURE, "unable to access SES device");
 			}
-			warn("unable to access SES device: %s", g.gl_pathv[i]);
+			xo_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");
+			xo_err(EXIT_FAILURE, "ENCIOC_GETNELM");
 		}
 
 		objp = calloc(nobj, sizeof(encioc_element_t));
 		if (objp == NULL) {
 			close(fd);
-			err(EXIT_FAILURE, "calloc()");
+			xo_err(EXIT_FAILURE, "calloc()");
 		}
 
 		if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0) {
 			close(fd);
-			err(EXIT_FAILURE, "ENCIOC_GETELMMAP");
+			xo_err(EXIT_FAILURE, "ENCIOC_GETELMMAP");
 		}
 
 		if (isses) {
 			if (sesid > nobj) {
 				close(fd);
-				errx(EXIT_FAILURE,
+				xo_errx(EXIT_FAILURE,
 				     "Requested SES ID does not exist");
 			}
 			do_led(fd, sesid, onoff, setfault);
@@ -263,7 +266,7 @@ sesled(int argc, char **argv, bool setfault)
 			objdn.elm_devnames = calloc(128, sizeof(char));
 			if (objdn.elm_devnames == NULL) {
 				close(fd);
-				err(EXIT_FAILURE, "calloc()");
+				xo_err(EXIT_FAILURE, "calloc()");
 			}
 			if (ioctl(fd, ENCIOC_GETELMDEVNAMES,
 			    (caddr_t) &objdn) <0) {
@@ -283,7 +286,7 @@ sesled(int argc, char **argv, bool setfault)
 	}
 	globfree(&g);
 	if (ndisks == 0 && all == false) {
-		errx(EXIT_FAILURE, "Count not find the SES id of device '%s'",
+		xo_errx(EXIT_FAILURE, "Count not find the SES id of device '%s'",
 		    disk);
 	}
 
@@ -311,11 +314,12 @@ sesutil_print(bool *title, const char *fmt, ...)
 	va_list args;
 
 	if (!*title) {
-		printf("\t\tExtra status:\n");
+		xo_open_container("extra_status");
+		xo_emit("\t\tExtra status:\n");
 		*title = true;
 	}
 	va_start(args, fmt);
-	vprintf(fmt, args);
+	xo_emit_hv(NULL, fmt, args);
 	va_end(args);
 }
 
@@ -325,48 +329,44 @@ print_extra_status(int eletype, u_char *cstat)
 	bool title = false;
 
 	if (cstat[0] & 0x40) {
-		sesutil_print(&title, "\t\t- Predicted Failure\n");
+		sesutil_print(&title, "\t\t-{e:predicted_failure/true} Predicted Failure\n");
 	}
 	if (cstat[0] & 0x20) {
-		sesutil_print(&title, "\t\t- Disabled\n");
+		sesutil_print(&title, "\t\t-{e:disabled/true} Disabled\n");
 	}
 	if (cstat[0] & 0x10) {
-		sesutil_print(&title, "\t\t- Swapped\n");
+		sesutil_print(&title, "\t\t-{e:swapped/true} Swapped\n");
 	}
 	switch (eletype) {
 	case ELMTYP_DEVICE:
-		if (cstat[2] & 0x02) {
-			sesutil_print(&title, "\t\t- LED=locate\n");
-		}
-		if (cstat[2] & 0x20) {
-			sesutil_print(&title, "\t\t- LED=fault\n");
-		}
-		break;
 	case ELMTYP_ARRAY_DEV:
 		if (cstat[2] & 0x02) {
-			sesutil_print(&title, "\t\t- LED=locate\n");
+			sesutil_print(&title, "\t\t- LED={q:led/locate}\n");
 		}
 		if (cstat[2] & 0x20) {
-			sesutil_print(&title, "\t\t- LED=fault\n");
+			sesutil_print(&title, "\t\t- LED={q:led/fault}\n");
 		}
 		break;
 	case ELMTYP_FAN:
-		sesutil_print(&title, "\t\t- Speed: %d rpm\n",
+		sesutil_print(&title, "\t\t- Speed: {:speed/%d}{Uw:rpm}\n",
 		    (((0x7 & cstat[1]) << 8) + cstat[2]) * 10);
 		break;
 	case ELMTYP_THERM:
 		if (cstat[2]) {
-			sesutil_print(&title, "\t\t- Temperature: %d C\n",
+			sesutil_print(&title, "\t\t- Temperature: {:temperature/%d}{Uw:C}\n",
 			    cstat[2] - TEMPERATURE_OFFSET);
 		} else {
-			sesutil_print(&title, "\t\t- Temperature: -reserved-\n");
+			sesutil_print(&title, "\t\t- Temperature: -{q:temperature/reserved}-\n");
 		}
 		break;
 	case ELMTYP_VOM:
-		sesutil_print(&title, "\t\t- Voltage: %.2f V\n",
+		sesutil_print(&title, "\t\t- Voltage: {:voltage/%.2f}{Uw:V}\n",
 		    be16dec(cstat + 2) / 100.0);
 		break;
 	}
+	if (title) {
+		xo_close_container("extra_status");
+	}
 }
 
 static int
@@ -390,8 +390,11 @@ objmap(int argc, char **argv __unused)
 	/* Get the list of ses devices */
 	if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) {
 		globfree(&g);
-		errx(EXIT_FAILURE, "No SES devices found");
+		xo_errx(EXIT_FAILURE, "No SES devices found");
 	}
+	xo_set_version(SESUTIL_XO_VERSION);
+	xo_open_container("sesutil");
+	xo_open_list("enclosures");
 	for (i = 0; i < g.gl_pathc; i++) {
 		/* ensure we only got numbers after ses */
 		if (strspn(g.gl_pathv[i] + 8, "0123456789") !=
@@ -404,38 +407,40 @@ objmap(int argc, char **argv __unused)
 			 * accessing all devices
 			 */
 			if (errno == EACCES && g.gl_pathc > 1) {
-				err(EXIT_FAILURE, "unable to access SES device");
+				xo_err(EXIT_FAILURE, "unable to access SES device");
 			}
-			warn("unable to access SES device: %s", g.gl_pathv[i]);
+			xo_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");
+			xo_err(EXIT_FAILURE, "ENCIOC_GETNELM");
 		}
 
 		e_ptr = calloc(nobj, sizeof(encioc_element_t));
 		if (e_ptr == NULL) {
 			close(fd);
-			err(EXIT_FAILURE, "calloc()");
+			xo_err(EXIT_FAILURE, "calloc()");
 		}
 
 		if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) e_ptr) < 0) {
 			close(fd);
-			err(EXIT_FAILURE, "ENCIOC_GETELMMAP");
+			xo_err(EXIT_FAILURE, "ENCIOC_GETELMMAP");
 		}
 
-		printf("%s:\n", g.gl_pathv[i] + 5);
+		xo_open_instance("enclosures");
+		xo_emit("{t:enc/%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);
+			xo_emit("\tEnclosure Name: {t: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);
+			xo_emit("\tEnclosure ID: {t:id/%s}\n", stri.buf);
 
+		xo_open_list("elements");
 		for (j = 0; j < nobj; j++) {
 			/* Get the status of the element */
 			memset(&e_status, 0, sizeof(e_status));
@@ -443,7 +448,7 @@ objmap(int argc, char **argv __unused)
 			if (ioctl(fd, ENCIOC_GETELMSTAT,
 			    (caddr_t) &e_status) < 0) {
 				close(fd);
-				err(EXIT_FAILURE, "ENCIOC_GETELMSTAT");
+				xo_err(EXIT_FAILURE, "ENCIOC_GETELMSTAT");
 			}
 			/* Get the description of the element */
 			memset(&e_desc, 0, sizeof(e_desc));
@@ -452,12 +457,12 @@ objmap(int argc, char **argv __unused)
 			e_desc.elm_desc_str = calloc(UINT16_MAX, sizeof(char));
 			if (e_desc.elm_desc_str == NULL) {
 				close(fd);
-				err(EXIT_FAILURE, "calloc()");
+				xo_err(EXIT_FAILURE, "calloc()");
 			}
 			if (ioctl(fd, ENCIOC_GETELMDESC,
 			    (caddr_t) &e_desc) < 0) {
 				close(fd);
-				err(EXIT_FAILURE, "ENCIOC_GETELMDESC");
+				xo_err(EXIT_FAILURE, "ENCIOC_GETELMDESC");
 			}
 			/* Get the device name(s) of the element */
 			memset(&e_devname, 0, sizeof(e_devname));
@@ -466,34 +471,40 @@ objmap(int argc, char **argv __unused)
 			e_devname.elm_devnames = calloc(128, sizeof(char));
 			if (e_devname.elm_devnames == NULL) {
 				close(fd);
-				err(EXIT_FAILURE, "calloc()");
+				xo_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,
+			xo_open_instance("elements");
+			xo_emit("\tElement {:id/%u}, Type: {: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",
+			xo_emit("\t\tStatus: {:status/%s} ({q:status_code/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",
+				xo_emit("\t\tDescription: {:description/%s}\n",
 				    e_desc.elm_desc_str);
 			}
 			if (e_devname.elm_names_len > 0) {
-				printf("\t\tDevice Names: %s\n",
+				xo_emit("\t\tDevice Names: {:device_names/%s}\n",
 				    e_devname.elm_devnames);
 			}
 			print_extra_status(e_ptr[j].elm_type, e_status.cstat);
+			xo_close_instance("elements");
 			free(e_devname.elm_devnames);
 		}
+		xo_close_list("elements");
 		free(e_ptr);
 		close(fd);
 	}
 	globfree(&g);
+	xo_close_list("enclosures");
+	xo_close_container("sesutil");
+	xo_finish();
 
 	return (EXIT_SUCCESS);
 }
@@ -514,8 +525,12 @@ encstatus(int argc, char **argv __unused)
 	/* Get the list of ses devices */
 	if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) {
 		globfree(&g);
-		errx(EXIT_FAILURE, "No SES devices found");
+		xo_errx(EXIT_FAILURE, "No SES devices found");
 	}
+
+	xo_set_version(SESUTIL_XO_VERSION);
+	xo_open_container("sesutil");
+	xo_open_list("enclosures");
 	for (i = 0; i < g.gl_pathc; i++) {
 		/* ensure we only got numbers after ses */
 		if (strspn(g.gl_pathv[i] + 8, "0123456789") !=
@@ -528,56 +543,61 @@ encstatus(int argc, char **argv __unused)
 			 * accessing all devices
 			 */
 			if (errno == EACCES && g.gl_pathc > 1) {
-				err(EXIT_FAILURE, "unable to access SES device");
+				xo_err(EXIT_FAILURE, "unable to access SES device");
 			}
-			warn("unable to access SES device: %s", g.gl_pathv[i]);
+			xo_warn("unable to access SES device: %s", g.gl_pathv[i]);
 			continue;
 		}
 
 		if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &estat) < 0) {
+			xo_err(EXIT_FAILURE, "ENCIOC_GETENCSTAT");
 			close(fd);
-			err(EXIT_FAILURE, "ENCIOC_GETENCSTAT");
 		}
 
-		printf("%s: ", g.gl_pathv[i] + 5);
+		xo_open_instance("enclosures");
+		xo_emit("{:enc/%s}: ", g.gl_pathv[i] + 5);
 		e = 0;
 		if (estat == 0) {
 			if (status == 0) {
 				status = 1;
 			}
-			printf("OK");
+			xo_emit("{q:status/OK}");
 		} else {
 			if (estat & SES_ENCSTAT_INFO) {
-				printf("INFO");
+				xo_emit("{lq:status/INFO}");
 				e++;
 			}
 			if (estat & SES_ENCSTAT_NONCRITICAL) {
 				if (e)
-					printf(",");
-				printf("NONCRITICAL");
+					xo_emit(",");
+				xo_emit("{lq:status/NONCRITICAL}");
 				e++;
 			}
 			if (estat & SES_ENCSTAT_CRITICAL) {
 				if (e)
-					printf(",");
-				printf("CRITICAL");
+					xo_emit(",");
+				xo_emit("{lq:status/CRITICAL}");
 				e++;
 				status = -1;
 			}
 			if (estat & SES_ENCSTAT_UNRECOV) {
 				if (e)
-					printf(",");
-				printf("UNRECOV");
+					xo_emit(",");
+				xo_emit("{lq:status/UNRECOV}");
 				e++;
 				status = -1;
 			}
 		}
-		printf("\n");
-
+		xo_close_instance("enclosures");
+		xo_emit("\n");
 		close(fd);
 	}
 	globfree(&g);
 
+	xo_close_list("enclosures");
+	xo_close_container("sesutil");
+	xo_finish();
+
 	if (status == 1) {
 		return (EXIT_SUCCESS);
 	} else {
@@ -590,6 +610,10 @@ main(int argc, char **argv)
 {
 	int i, ch;
 	struct command *cmd = NULL;
+
+	argc = xo_parse_args(argc, argv);
+	if (argc < 0)
+		exit(1);
 
 	uflag = "/dev/ses[0-9]*";
 	while ((ch = getopt_long(argc, argv, "u:", NULL, NULL)) != -1) {


More information about the svn-src-all mailing list