diff options
author | melifaro <melifaro@FreeBSD.org> | 2014-08-23 14:58:31 +0000 |
---|---|---|
committer | melifaro <melifaro@FreeBSD.org> | 2014-08-23 14:58:31 +0000 |
commit | cf94663e69b2c927e4a44dcb922c93483f11bc29 (patch) | |
tree | f43a461c97f3db054606f6367939a61652f0db97 /sbin | |
parent | 2e65f120c886a9d09b274b1953783df2b995e799 (diff) | |
parent | 19be009a4f8eb0d239ec3e465b0a9b2a2947dcf8 (diff) | |
download | FreeBSD-src-cf94663e69b2c927e4a44dcb922c93483f11bc29.zip FreeBSD-src-cf94663e69b2c927e4a44dcb922c93483f11bc29.tar.gz |
Sync to HEAD@r270409.
Diffstat (limited to 'sbin')
30 files changed, 1116 insertions, 88 deletions
diff --git a/sbin/atm/atmconfig/Makefile b/sbin/atm/atmconfig/Makefile index 34c2989..f3dce26 100644 --- a/sbin/atm/atmconfig/Makefile +++ b/sbin/atm/atmconfig/Makefile @@ -8,29 +8,24 @@ .include <src.opts.mk> PROG= atmconfig -.ifndef RESCUE -SRCS= ${.OBJDIR}/oid.h -.endif -SRCS+= main.c diag.c natm.c -.ifndef RESCUE -SRCS+= atmconfig_device.c -.endif +SRCS= main.c diag.c natm.c MAN= atmconfig.8 # CFLAGS+= -DPATH_HELP='".:/usr/share/doc/atm:/usr/local/share/doc/atm"' CFLAGS+= -I${.OBJDIR} -.ifndef RESCUE -DPADD= ${LIBBSNMP} -LDADD= -lbsnmp +.if !defined(RESCUE) && ${MK_BSNMP} != "no" +CFLAGS+= -DWITH_BSNMP +SRCS+= oid.h atmconfig_device.c +DPADD+= ${LIBBSNMP} +LDADD+= -lbsnmp . if ${MK_DYNAMICROOT} == "no" && ${MK_OPENSSL} != "no" +DPADD+= ${LIBCRYPTO} LDADD+= -lcrypto . endif .endif -.ifndef RESCUE CLEANFILES+= oid.h -.endif # XXX - this is verboten .if ${MACHINE_CPUARCH} == "arm" @@ -43,8 +38,8 @@ FILESDIR= /usr/share/doc/atm SNMP_ATM_DEF= ${.CURDIR}/../../../contrib/ngatm/snmp_atm/atm_tree.def \ ${.CURDIR}/../../../usr.sbin/bsnmpd/modules/snmp_atm/atm_freebsd.def -${.OBJDIR}/oid.h: atm_oid.list ${SNMP_ATM_DEF} +oid.h: atm_oid.list ${SNMP_ATM_DEF} cat ${SNMP_ATM_DEF} | gensnmptree -e `tail -n +2 ${.CURDIR}/atm_oid.list` \ - > ${.OBJDIR}/oid.h + > ${.TARGET} .include <bsd.prog.mk> diff --git a/sbin/atm/atmconfig/main.c b/sbin/atm/atmconfig/main.c index 73e1fac..1374218 100644 --- a/sbin/atm/atmconfig/main.c +++ b/sbin/atm/atmconfig/main.c @@ -38,7 +38,7 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <fnmatch.h> #include <dirent.h> -#ifndef RESCUE +#ifdef WITH_BSNMP #include <bsnmp/asn1.h> #include <bsnmp/snmp.h> #include <bsnmp/snmpclient.h> @@ -444,7 +444,7 @@ help_func(int argc, char *argv[]) exit(1); } -#ifndef RESCUE +#ifdef WITH_BSNMP /* * Parse a server specification * @@ -527,16 +527,16 @@ main(int argc, char *argv[]) int opt, i; const struct cmdtab *match, *cc, *tab; -#ifndef RESCUE +#ifdef WITH_BSNMP snmp_client_init(&snmp_client); snmp_client.trans = SNMP_TRANS_LOC_STREAM; snmp_client_set_host(&snmp_client, PATH_ILMI_SOCK); #endif -#ifdef RESCUE -#define OPTSTR "htv" -#else +#ifdef WITH_BSNMP #define OPTSTR "htvs:" +#else +#define OPTSTR "htv" #endif while ((opt = getopt(argc, argv, OPTSTR)) != -1) @@ -545,7 +545,7 @@ main(int argc, char *argv[]) case 'h': help_func(0, argv); -#ifndef RESCUE +#ifdef WITH_BSNMP case 's': parse_server(optarg); break; @@ -570,7 +570,7 @@ main(int argc, char *argv[]) err(1, NULL); memcpy(main_tab, static_main_tab, sizeof(static_main_tab)); -#ifndef RESCUE +#ifdef WITH_BSNMP /* XXX while this is compiled in */ device_register(); #endif diff --git a/sbin/devd/Makefile b/sbin/devd/Makefile index c53f094..518e5e2 100644 --- a/sbin/devd/Makefile +++ b/sbin/devd/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.include <src.opts.mk> + PROG_CXX=devd SRCS= devd.cc token.l parse.y y.tab.h MAN= devd.8 devd.conf.5 @@ -16,4 +18,8 @@ CFLAGS+=-I. -I${.CURDIR} CLEANFILES= y.output +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include <bsd.prog.mk> diff --git a/sbin/devd/devd.8 b/sbin/devd/devd.8 index fa34df2..12a92d9 100644 --- a/sbin/devd/devd.8 +++ b/sbin/devd/devd.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 30, 2013 +.Dd August 14, 2014 .Dt DEVD 8 .Os .Sh NAME @@ -55,9 +55,7 @@ If option .Fl f is specified more than once, the last file specified is used. .It Fl l Ar num -Limit concurrent -.Pa /var/run/devd.pipe -connections to +Limit concurrent socket connections to .Ar num . The default connection limit is 10. .It Fl n @@ -130,22 +128,27 @@ wish to hook into the system without modifying the user's other config files. .Pp -All messages that +Since +.Xr devctl 4 +allows only one active reader, .Nm -receives are forwarded to the +multiplexes it, forwarding all events to any number of connected clients. +Clients connect by opening the SOCK_SEQPACKET .Ux domain socket at -.Pa /var/run/devd.pipe . +.Pa /var/run/devd.seqpacket.pipe . .Sh FILES -.Bl -tag -width ".Pa /var/run/devd.pipe" -compact +.Bl -tag -width ".Pa /var/run/devd.seqpacket.pipe" -compact .It Pa /etc/devd.conf The default .Nm configuration file. -.It Pa /var/run/devd.pipe +.It Pa /var/run/devd.seqpacket.pipe The socket used by .Nm to communicate with its clients. +.It Pa /var/run/devd.pipe +A deprecated socket retained for use with old clients. .El .Sh SEE ALSO .Xr devctl 4 , diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc index ce2a4f3..c770204 100644 --- a/sbin/devd/devd.cc +++ b/sbin/devd/devd.cc @@ -100,7 +100,8 @@ __FBSDID("$FreeBSD$"); #include "devd.h" /* C compatible definitions */ #include "devd.hh" /* C++ class definitions */ -#define PIPE "/var/run/devd.pipe" +#define STREAMPIPE "/var/run/devd.pipe" +#define SEQPACKETPIPE "/var/run/devd.seqpacket.pipe" #define CF "/etc/devd.conf" #define SYSCTL "hw.bus.devctl_queue" @@ -119,6 +120,11 @@ __FBSDID("$FreeBSD$"); using namespace std; +typedef struct client { + int fd; + int socktype; +} client_t; + extern FILE *yyin; extern int lineno; @@ -822,12 +828,12 @@ process_event(char *buffer) } int -create_socket(const char *name) +create_socket(const char *name, int socktype) { int fd, slen; struct sockaddr_un sun; - if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) + if ((fd = socket(PF_LOCAL, socktype, 0)) < 0) err(1, "socket"); bzero(&sun, sizeof(sun)); sun.sun_family = AF_UNIX; @@ -846,12 +852,13 @@ create_socket(const char *name) unsigned int max_clients = 10; /* Default, can be overriden on cmdline. */ unsigned int num_clients; -list<int> clients; + +list<client_t> clients; void notify_clients(const char *data, int len) { - list<int>::iterator i; + list<client_t>::iterator i; /* * Deliver the data to all clients. Throw clients overboard at the @@ -861,11 +868,17 @@ notify_clients(const char *data, int len) * kernel memory or tie up the limited number of available connections). */ for (i = clients.begin(); i != clients.end(); ) { - if (write(*i, data, len) != len) { + int flags; + if (i->socktype == SOCK_SEQPACKET) + flags = MSG_EOR; + else + flags = 0; + + if (send(i->fd, data, len, flags) != len) { --num_clients; - close(*i); + close(i->fd); i = clients.erase(i); - devdlog(LOG_WARNING, "notify_clients: write() failed; " + devdlog(LOG_WARNING, "notify_clients: send() failed; " "dropping unresponsive client\n"); } else ++i; @@ -877,7 +890,7 @@ check_clients(void) { int s; struct pollfd pfd; - list<int>::iterator i; + list<client_t>::iterator i; /* * Check all existing clients to see if any of them have disappeared. @@ -888,12 +901,12 @@ check_clients(void) */ pfd.events = 0; for (i = clients.begin(); i != clients.end(); ) { - pfd.fd = *i; + pfd.fd = i->fd; s = poll(&pfd, 1, 0); if ((s < 0 && s != EINTR ) || (s > 0 && (pfd.revents & POLLHUP))) { --num_clients; - close(*i); + close(i->fd); i = clients.erase(i); devdlog(LOG_NOTICE, "check_clients: " "dropping disconnected client\n"); @@ -903,9 +916,9 @@ check_clients(void) } void -new_client(int fd) +new_client(int fd, int socktype) { - int s; + client_t s; int sndbuf_size; /* @@ -914,13 +927,14 @@ new_client(int fd) * by sending large buffers full of data we'll never read. */ check_clients(); - s = accept(fd, NULL, NULL); - if (s != -1) { + s.socktype = socktype; + s.fd = accept(fd, NULL, NULL); + if (s.fd != -1) { sndbuf_size = CLIENT_BUFSIZE; - if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf_size, + if (setsockopt(s.fd, SOL_SOCKET, SO_SNDBUF, &sndbuf_size, sizeof(sndbuf_size))) err(1, "setsockopt"); - shutdown(s, SHUT_RD); + shutdown(s.fd, SHUT_RD); clients.push_back(s); ++num_clients; } else @@ -934,7 +948,7 @@ event_loop(void) int fd; char buffer[DEVCTL_MAXBUF]; int once = 0; - int server_fd, max_fd; + int stream_fd, seqpacket_fd, max_fd; int accepting; timeval tv; fd_set fds; @@ -942,9 +956,10 @@ event_loop(void) fd = open(PATH_DEVCTL, O_RDONLY | O_CLOEXEC); if (fd == -1) err(1, "Can't open devctl device %s", PATH_DEVCTL); - server_fd = create_socket(PIPE); + stream_fd = create_socket(STREAMPIPE, SOCK_STREAM); + seqpacket_fd = create_socket(SEQPACKETPIPE, SOCK_SEQPACKET); accepting = 1; - max_fd = max(fd, server_fd) + 1; + max_fd = max(fd, max(stream_fd, seqpacket_fd)) + 1; while (!romeo_must_die) { if (!once && !no_daemon && !daemonize_quick) { // Check to see if we have any events pending. @@ -965,24 +980,28 @@ event_loop(void) } /* * When we've already got the max number of clients, stop - * accepting new connections (don't put server_fd in the set), - * shrink the accept() queue to reject connections quickly, and - * poll the existing clients more often, so that we notice more - * quickly when any of them disappear to free up client slots. + * accepting new connections (don't put the listening sockets in + * the set), shrink the accept() queue to reject connections + * quickly, and poll the existing clients more often, so that we + * notice more quickly when any of them disappear to free up + * client slots. */ FD_ZERO(&fds); FD_SET(fd, &fds); if (num_clients < max_clients) { if (!accepting) { - listen(server_fd, max_clients); + listen(stream_fd, max_clients); + listen(seqpacket_fd, max_clients); accepting = 1; } - FD_SET(server_fd, &fds); + FD_SET(stream_fd, &fds); + FD_SET(seqpacket_fd, &fds); tv.tv_sec = 60; tv.tv_usec = 0; } else { if (accepting) { - listen(server_fd, 0); + listen(stream_fd, 0); + listen(seqpacket_fd, 0); accepting = 0; } tv.tv_sec = 2; @@ -1022,8 +1041,14 @@ event_loop(void) break; } } - if (FD_ISSET(server_fd, &fds)) - new_client(server_fd); + if (FD_ISSET(stream_fd, &fds)) + new_client(stream_fd, SOCK_STREAM); + /* + * Aside from the socket type, both sockets use the same + * protocol, so we can process clients the same way. + */ + if (FD_ISSET(seqpacket_fd, &fds)) + new_client(seqpacket_fd, SOCK_SEQPACKET); } close(fd); } diff --git a/sbin/devd/tests/Makefile b/sbin/devd/tests/Makefile new file mode 100644 index 0000000..ee679ce --- /dev/null +++ b/sbin/devd/tests/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/sbin/devd + +ATF_TESTS_C= client_test +TEST_METADATA.client_test= required_programs="devd" +TEST_METADATA.client_test+= required_user="root" +TEST_METADATA.client_test+= timeout=15 + +WARNS?= 5 + +.include <bsd.test.mk> diff --git a/sbin/devd/tests/client_test.c b/sbin/devd/tests/client_test.c new file mode 100644 index 0000000..dda9a89 --- /dev/null +++ b/sbin/devd/tests/client_test.c @@ -0,0 +1,198 @@ +/*- + * Copyright (c) 2014 Spectra Logic Corporation. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdbool.h> +#include <stdio.h> + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <atf-c.h> +/* Helper functions*/ + +/* + * Create two devd events. The easiest way I know of, that requires no special + * hardware, is to create md(4) devices. + */ +static void +create_two_events(void) +{ + FILE *create_stdout; + FILE *destroy_stdout; + char mdname[80]; + char destroy_cmd[80]; + char *error; + + create_stdout = popen("mdconfig -a -s 64 -t null", "r"); + ATF_REQUIRE(create_stdout != NULL); + error = fgets(mdname, sizeof(mdname), create_stdout); + ATF_REQUIRE(error != NULL); + /* We only expect one line of output */ + ATF_REQUIRE_EQ(0, pclose(create_stdout)); + + snprintf(destroy_cmd, nitems(destroy_cmd), "mdconfig -d -u %s", mdname); + destroy_stdout = popen(destroy_cmd, "r"); + ATF_REQUIRE(destroy_stdout != NULL); + /* We expect no output */ + ATF_REQUIRE_EQ(0, pclose(destroy_stdout)); +} + +/* + * Test Cases + */ + +/* + * Open a client connection to devd, create some events, and test that they can + * be read _whole_ and _one_at_a_time_ from the socket + */ +ATF_TC_WITHOUT_HEAD(seqpacket); +ATF_TC_BODY(seqpacket, tc) +{ + int s; + int error; + struct sockaddr_un devd_addr; + bool got_create_event = false; + bool got_destroy_event = false; + const char create_pat[] = + "!system=DEVFS subsystem=CDEV type=CREATE cdev=md"; + const char destroy_pat[] = + "!system=DEVFS subsystem=CDEV type=DESTROY cdev=md"; + + memset(&devd_addr, 0, sizeof(devd_addr)); + devd_addr.sun_family = PF_LOCAL; + strlcpy(devd_addr.sun_path, "/var/run/devd.seqpacket.pipe", + sizeof(devd_addr.sun_path)); + + s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); + ATF_REQUIRE(s >= 0); + error = connect(s, (struct sockaddr*)&devd_addr, SUN_LEN(&devd_addr)); + ATF_REQUIRE_EQ(0, error); + + create_two_events(); + + /* + * Loop until both events are detected on _different_ reads + * There may be extra events due to unrelated system activity + * If we never get both events, then the test will timeout. + */ + while (!(got_create_event && got_destroy_event)) { + int cmp; + ssize_t len; + char event[1024]; + + /* Read 1 less than sizeof(event) to allow space for NULL */ + len = recv(s, event, sizeof(event) - 1, MSG_WAITALL); + ATF_REQUIRE(len != -1); + /* NULL terminate the result */ + event[len] = '\0'; + printf("%s", event); + cmp = strncmp(event, create_pat, sizeof(create_pat) - 1); + if (cmp == 0) + got_create_event = true; + + cmp = strncmp(event, destroy_pat, sizeof(destroy_pat) - 1); + if (cmp == 0) + got_destroy_event = true; + } + + close(s); +} + +/* + * Open a client connection to devd using the stream socket, create some + * events, and test that they can be read in any number of reads. + */ +ATF_TC_WITHOUT_HEAD(stream); +ATF_TC_BODY(stream, tc) +{ + int s; + int error; + struct sockaddr_un devd_addr; + bool got_create_event = false; + bool got_destroy_event = false; + const char create_pat[] = + "!system=DEVFS subsystem=CDEV type=CREATE cdev=md"; + const char destroy_pat[] = + "!system=DEVFS subsystem=CDEV type=DESTROY cdev=md"; + ssize_t len = 0; + + memset(&devd_addr, 0, sizeof(devd_addr)); + devd_addr.sun_family = PF_LOCAL; + strlcpy(devd_addr.sun_path, "/var/run/devd.pipe", + sizeof(devd_addr.sun_path)); + + s = socket(PF_LOCAL, SOCK_STREAM, 0); + ATF_REQUIRE(s >= 0); + error = connect(s, (struct sockaddr*)&devd_addr, SUN_LEN(&devd_addr)); + ATF_REQUIRE_EQ(0, error); + + create_two_events(); + + /* + * Loop until both events are detected on _different_ reads + * There may be extra events due to unrelated system activity + * If we never get both events, then the test will timeout. + */ + while (!(got_create_event && got_destroy_event)) { + char event[1024]; + ssize_t newlen; + char *create_pos, *destroy_pos; + + /* Read 1 less than sizeof(event) to allow space for NULL */ + newlen = read(s, &event[len], sizeof(event) - len - 1); + ATF_REQUIRE(newlen != -1); + len += newlen; + /* NULL terminate the result */ + event[newlen] = '\0'; + printf("%s", event); + + create_pos = strstr(event, create_pat); + if (create_pos != NULL) + got_create_event = true; + + destroy_pos = strstr(event, destroy_pat); + if (destroy_pos != NULL) + got_destroy_event = true; + } + + close(s); +} + +/* + * Main. + */ + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, seqpacket); + ATF_TP_ADD_TC(tp, stream); + + return (atf_no_error()); +} + diff --git a/sbin/dhclient/tests/Makefile b/sbin/dhclient/tests/Makefile index b092eea..a460f7f 100644 --- a/sbin/dhclient/tests/Makefile +++ b/sbin/dhclient/tests/Makefile @@ -8,6 +8,7 @@ PLAIN_TESTS_C= option-domain-search_test SRCS.option-domain-search_test= alloc.c convert.c hash.c options.c \ tables.c fake.c option-domain-search.c CFLAGS.option-domain-search_test+= -I${.CURDIR}/.. +DPADD.option-domain-search_test= ${LIBUTIL} LDADD.option-domain-search_test= -lutil WARNS?= 2 diff --git a/sbin/fsck/Makefile b/sbin/fsck/Makefile index d0c45db..22de03c 100644 --- a/sbin/fsck/Makefile +++ b/sbin/fsck/Makefile @@ -5,6 +5,4 @@ PROG= fsck SRCS= fsck.c fsutil.c preen.c MAN= fsck.8 -NO_PIE= yes - .include <bsd.prog.mk> diff --git a/sbin/hastd/Makefile b/sbin/hastd/Makefile index 306c83a..7dd4d63 100644 --- a/sbin/hastd/Makefile +++ b/sbin/hastd/Makefile @@ -31,7 +31,7 @@ CFLAGS+=-DINET6 .endif DPADD= ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} ${LIBL} ${LIBPTHREAD} ${LIBUTIL} -LDADD= -lgeom -lbsdxml -lsbuf -lpthread -lutil +LDADD= -lgeom -lbsdxml -lsbuf -ll -lpthread -lutil .if ${MK_OPENSSL} != "no" DPADD+= ${LIBCRYPTO} LDADD+= -lcrypto diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile index aae6724..c357aff 100644 --- a/sbin/ifconfig/Makefile +++ b/sbin/ifconfig/Makefile @@ -33,6 +33,10 @@ SRCS+= ifvlan.c # SIOC[GS]ETVLAN support SRCS+= ifgre.c # GRE keys etc SRCS+= ifgif.c # GIF reversed header workaround +SRCS+= sfp.c # SFP/SFP+ information +DPADD+= ${LIBM} +LDADD+= -lm + SRCS+= ifieee80211.c regdomain.c # SIOC[GS]IEEE80211 support DPADD+= ${LIBBSDXML} ${LIBSBUF} LDADD+= -lbsdxml -lsbuf diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 1f93a0d..61fd155 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1011,6 +1011,9 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl, if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) printf("%s", ifs.ascii); + if (verbose > 0) + sfp_status(s, &ifr, verbose); + close(s); return; } diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h index ea21db5..e449c1d 100644 --- a/sbin/ifconfig/ifconfig.h +++ b/sbin/ifconfig/ifconfig.h @@ -143,6 +143,8 @@ void ifmaybeload(const char *name); typedef void clone_callback_func(int, struct ifreq *); void clone_setdefcallback(const char *, clone_callback_func *); +void sfp_status(int s, struct ifreq *ifr, int verbose); + /* * XXX expose this so modules that neeed to know of any pending * operations on ifmedia can avoid cmd line ordering confusion. diff --git a/sbin/ifconfig/sfp.c b/sbin/ifconfig/sfp.c new file mode 100644 index 0000000..9647eb3 --- /dev/null +++ b/sbin/ifconfig/sfp.c @@ -0,0 +1,789 @@ +/*- + * Copyright (c) 2014 Alexander V. Chernikov. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/ioctl.h> +#include <sys/socket.h> + +#include <net/if.h> +#include <net/sff8436.h> +#include <net/sff8472.h> + +#include <math.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "ifconfig.h" + +struct i2c_info; +typedef int (read_i2c)(struct i2c_info *ii, uint8_t addr, uint8_t off, + uint8_t len, caddr_t buf); + +struct i2c_info { + int s; + int error; + int bshift; + int qsfp; + int do_diag; + struct ifreq *ifr; + read_i2c *f; + char *textbuf; + size_t bufsize; + int cfd; + int port_id; + int chip_id; +}; + +struct _nv { + int v; + const char *n; +}; + +const char *find_value(struct _nv *x, int value); +const char *find_zero_bit(struct _nv *x, int value, int sz); + +/* SFF-8472 Rev. 11.4 table 3.4: Connector values */ +static struct _nv conn[] = { + { 0x00, "Unknown" }, + { 0x01, "SC" }, + { 0x02, "Fibre Channel Style 1 copper" }, + { 0x03, "Fibre Channel Style 2 copper" }, + { 0x04, "BNC/TNC" }, + { 0x05, "Fibre Channel coaxial" }, + { 0x06, "FiberJack" }, + { 0x07, "LC" }, + { 0x08, "MT-RJ" }, + { 0x09, "MU" }, + { 0x0A, "SG" }, + { 0x0B, "Optical pigtail" }, + { 0x0C, "MPO Parallel Optic" }, + { 0x20, "HSSDC II" }, + { 0x21, "Copper pigtail" }, + { 0x22, "RJ45" }, + { 0x23, "No separate connector" }, /* SFF-8436 */ + { 0, NULL } +}; + +/* SFF-8472 Rev. 11.4 table 3.5: Transceiver codes */ +/* 10G Ethernet/IB compliance codes, byte 3 */ +static struct _nv eth_10g[] = { + { 0x80, "10G Base-ER" }, + { 0x40, "10G Base-LRM" }, + { 0x20, "10G Base-LR" }, + { 0x10, "10G Base-SR" }, + { 0x08, "1X SX" }, + { 0x04, "1X LX" }, + { 0x02, "1X Copper Active" }, + { 0x01, "1X Copper Passive" }, + { 0, NULL } +}; + +/* Ethernet compliance codes, byte 6 */ +static struct _nv eth_compat[] = { + { 0x80, "BASE-PX" }, + { 0x40, "BASE-BX10" }, + { 0x20, "100BASE-FX" }, + { 0x10, "100BASE-LX/LX10" }, + { 0x08, "1000BASE-T" }, + { 0x04, "1000BASE-CX" }, + { 0x02, "1000BASE-LX" }, + { 0x01, "1000BASE-SX" }, + { 0, NULL } +}; + +/* FC link length, byte 7 */ +static struct _nv fc_len[] = { + { 0x80, "very long distance" }, + { 0x40, "short distance" }, + { 0x20, "intermediate distance" }, + { 0x10, "long distance" }, + { 0x08, "medium distance" }, + { 0, NULL } +}; + +/* Channel/Cable technology, byte 7-8 */ +static struct _nv cab_tech[] = { + { 0x0400, "Shortwave laser (SA)" }, + { 0x0200, "Longwave laser (LC)" }, + { 0x0100, "Electrical inter-enclosure (EL)" }, + { 0x80, "Electrical intra-enclosure (EL)" }, + { 0x40, "Shortwave laser (SN)" }, + { 0x20, "Shortwave laser (SL)" }, + { 0x10, "Longwave laser (LL)" }, + { 0x08, "Active Cable" }, + { 0x04, "Passive Cable" }, + { 0, NULL } +}; + +/* FC Transmission media, byte 9 */ +static struct _nv fc_media[] = { + { 0x80, "Twin Axial Pair" }, + { 0x40, "Twisted Pair" }, + { 0x20, "Miniature Coax" }, + { 0x10, "Viao Coax" }, + { 0x08, "Miltimode, 62.5um" }, + { 0x04, "Multimode, 50um" }, + { 0x02, "" }, + { 0x01, "Single Mode" }, + { 0, NULL } +}; + +/* FC Speed, byte 10 */ +static struct _nv fc_speed[] = { + { 0x80, "1200 MBytes/sec" }, + { 0x40, "800 MBytes/sec" }, + { 0x20, "1600 MBytes/sec" }, + { 0x10, "400 MBytes/sec" }, + { 0x08, "3200 MBytes/sec" }, + { 0x04, "200 MBytes/sec" }, + { 0x01, "100 MBytes/sec" }, + { 0, NULL } +}; + +/* SFF-8436 Rev. 4.8 table 33: Specification compliance */ + +/* 10/40G Ethernet compliance codes, byte 128 + 3 */ +static struct _nv eth_1040g[] = { + { 0x80, "Reserved" }, + { 0x40, "10GBASE-LRM" }, + { 0x20, "10GBASE-LR" }, + { 0x10, "10GBASE-SR" }, + { 0x08, "40GBASE-CR4" }, + { 0x04, "40GBASE-SR4" }, + { 0x02, "40GBASE-LR4" }, + { 0x01, "40G Active Cable" }, + { 0, NULL } +}; + +const char * +find_value(struct _nv *x, int value) +{ + for (; x->n != NULL; x++) + if (x->v == value) + return (x->n); + return (NULL); +} + +const char * +find_zero_bit(struct _nv *x, int value, int sz) +{ + int v, m; + const char *s; + + v = 1; + for (v = 1, m = 1 << (8 * sz); v < m; v *= 2) { + if ((value & v) == 0) + continue; + if ((s = find_value(x, value & v)) != NULL) { + value &= ~v; + return (s); + } + } + + return (NULL); +} + +static void +convert_sff_identifier(char *buf, size_t size, uint8_t value) +{ + const char *x; + + x = NULL; + if (value <= SFF_8024_ID_LAST) + x = sff_8024_id[value]; + else { + if (value > 0x80) + x = "Vendor specific"; + else + x = "Reserved"; + } + + snprintf(buf, size, "%s", x); +} + +static void +convert_sff_connector(char *buf, size_t size, uint8_t value) +{ + const char *x; + + if ((x = find_value(conn, value)) == NULL) { + if (value >= 0x0D && value <= 0x1F) + x = "Unallocated"; + else if (value >= 0x24 && value <= 0x7F) + x = "Unallocated"; + else + x = "Vendor specific"; + } + + snprintf(buf, size, "%s", x); +} + +static void +get_sfp_identifier(struct i2c_info *ii, char *buf, size_t size) +{ + uint8_t data; + + ii->f(ii, SFF_8472_BASE, SFF_8472_ID, 1, (caddr_t)&data); + convert_sff_identifier(buf, size, data); +} + +static void +get_sfp_connector(struct i2c_info *ii, char *buf, size_t size) +{ + uint8_t data; + + ii->f(ii, SFF_8472_BASE, SFF_8472_CONNECTOR, 1, (caddr_t)&data); + convert_sff_connector(buf, size, data); +} + +static void +get_qsfp_identifier(struct i2c_info *ii, char *buf, size_t size) +{ + uint8_t data; + + ii->f(ii, SFF_8436_BASE, SFF_8436_ID, 1, (caddr_t)&data); + convert_sff_identifier(buf, size, data); +} + +static void +get_qsfp_connector(struct i2c_info *ii, char *buf, size_t size) +{ + uint8_t data; + + ii->f(ii, SFF_8436_BASE, SFF_8436_CONNECTOR, 1, (caddr_t)&data); + convert_sff_connector(buf, size, data); +} + +static void +printf_sfp_transceiver_descr(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[12]; + const char *tech_class, *tech_len, *tech_tech, *tech_media, *tech_speed; + + tech_class = NULL; + tech_len = NULL; + tech_tech = NULL; + tech_media = NULL; + tech_speed = NULL; + + /* Read bytes 3-10 at once */ + ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, &xbuf[3]); + + /* Check 10G ethernet first */ + tech_class = find_zero_bit(eth_10g, xbuf[3], 1); + if (tech_class == NULL) { + /* No match. Try 1G */ + tech_class = find_zero_bit(eth_compat, xbuf[6], 1); + } + + tech_len = find_zero_bit(fc_len, xbuf[7], 1); + tech_tech = find_zero_bit(cab_tech, xbuf[7] << 8 | xbuf[8], 2); + tech_media = find_zero_bit(fc_media, xbuf[9], 1); + tech_speed = find_zero_bit(fc_speed, xbuf[10], 1); + + printf("Class: %s\n", tech_class); + printf("Length: %s\n", tech_len); + printf("Tech: %s\n", tech_tech); + printf("Media: %s\n", tech_media); + printf("Speed: %s\n", tech_speed); +} + +static void +get_sfp_transceiver_class(struct i2c_info *ii, char *buf, size_t size) +{ + const char *tech_class; + uint8_t code; + + /* Check 10G Ethernet/IB first */ + ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 1, (caddr_t)&code); + tech_class = find_zero_bit(eth_10g, code, 1); + if (tech_class == NULL) { + /* No match. Try Ethernet 1G */ + ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START + 3, + 1, (caddr_t)&code); + tech_class = find_zero_bit(eth_compat, code, 1); + } + + if (tech_class == NULL) + tech_class = "Unknown"; + + snprintf(buf, size, "%s", tech_class); +} + +static void +get_qsfp_transceiver_class(struct i2c_info *ii, char *buf, size_t size) +{ + const char *tech_class; + uint8_t code; + + /* Check 10/40G Ethernet class only */ + ii->f(ii, SFF_8436_BASE, SFF_8436_CODE_E1040G, 1, (caddr_t)&code); + tech_class = find_zero_bit(eth_1040g, code, 1); + if (tech_class == NULL) + tech_class = "Unknown"; + + snprintf(buf, size, "%s", tech_class); +} + +/* + * Print SFF-8472/SFF-8436 string to supplied buffer. + * All (vendor-specific) strings are padded right with '0x20'. + */ +static void +convert_sff_name(char *buf, size_t size, char *xbuf) +{ + char *p; + + for (p = &xbuf[16]; *(p - 1) == 0x20; p--) + ; + *p = '\0'; + snprintf(buf, size, "%s", xbuf); +} + +static void +convert_sff_date(char *buf, size_t size, char *xbuf) +{ + + snprintf(buf, size, "20%c%c-%c%c-%c%c", xbuf[0], xbuf[1], + xbuf[2], xbuf[3], xbuf[4], xbuf[5]); +} + +static void +get_sfp_vendor_name(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[17]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8472_BASE, SFF_8472_VENDOR_START, 16, xbuf); + convert_sff_name(buf, size, xbuf); +} + +static void +get_sfp_vendor_pn(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[17]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8472_BASE, SFF_8472_PN_START, 16, xbuf); + convert_sff_name(buf, size, xbuf); +} + +static void +get_sfp_vendor_sn(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[17]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8472_BASE, SFF_8472_SN_START, 16, xbuf); + convert_sff_name(buf, size, xbuf); +} + +static void +get_sfp_vendor_date(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[6]; + + memset(xbuf, 0, sizeof(xbuf)); + /* Date code, see Table 3.8 for description */ + ii->f(ii, SFF_8472_BASE, SFF_8472_DATE_START, 6, xbuf); + convert_sff_date(buf, size, xbuf); +} + +static void +get_qsfp_vendor_name(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[17]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8436_BASE, SFF_8436_VENDOR_START, 16, xbuf); + convert_sff_name(buf, size, xbuf); +} + +static void +get_qsfp_vendor_pn(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[17]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8436_BASE, SFF_8436_PN_START, 16, xbuf); + convert_sff_name(buf, size, xbuf); +} + +static void +get_qsfp_vendor_sn(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[17]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8436_BASE, SFF_8436_SN_START, 16, xbuf); + convert_sff_name(buf, size, xbuf); +} + +static void +get_qsfp_vendor_date(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[6]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8436_BASE, SFF_8436_DATE_START, 6, xbuf); + convert_sff_date(buf, size, xbuf); +} + +static void +print_sfp_vendor(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[80]; + + memset(xbuf, 0, sizeof(xbuf)); + if (ii->qsfp != 0) { + get_qsfp_vendor_name(ii, xbuf, 20); + get_qsfp_vendor_pn(ii, &xbuf[20], 20); + get_qsfp_vendor_sn(ii, &xbuf[40], 20); + get_qsfp_vendor_date(ii, &xbuf[60], 20); + } else { + get_sfp_vendor_name(ii, xbuf, 20); + get_sfp_vendor_pn(ii, &xbuf[20], 20); + get_sfp_vendor_sn(ii, &xbuf[40], 20); + get_sfp_vendor_date(ii, &xbuf[60], 20); + } + + snprintf(buf, size, "vendor: %s PN: %s SN: %s DATE: %s", + xbuf, &xbuf[20], &xbuf[40], &xbuf[60]); +} + +/* + * Converts internal templerature (SFF-8472, SFF-8436) + * 16-bit unsigned value to human-readable representation: + * + * Internally measured Module temperature are represented + * as a 16-bit signed twos complement value in increments of + * 1/256 degrees Celsius, yielding a total range of –128C to +128C + * that is considered valid between –40 and +125C. + * + */ +static void +convert_sff_temp(char *buf, size_t size, char *xbuf) +{ + double d; + + d = (double)(int8_t)xbuf[0]; + d += (double)(uint8_t)xbuf[1] / 256; + + snprintf(buf, size, "%.2f C", d); +} + +/* + * Retrieves supplied voltage (SFF-8472, SFF-8436). + * 16-bit usigned value, treated as range 0..+6.55 Volts + */ +static void +convert_sff_voltage(char *buf, size_t size, char *xbuf) +{ + double d; + + d = (double)(((uint8_t)xbuf[0] << 8) | (uint8_t)xbuf[1]); + snprintf(buf, size, "%.2f Volts", d / 10000); +} + +/* + * Converts value in @xbuf to both milliwats and dBm + * human representation. + */ +static void +convert_sff_power(struct i2c_info *ii, char *buf, size_t size, char *xbuf) +{ + uint16_t mW; + double dbm; + + mW = ((uint8_t)xbuf[0] << 8) + (uint8_t)xbuf[1]; + + /* Convert mw to dbm */ + dbm = 10.0 * log10(1.0 * mW / 10000); + + /* + * Assume internally-calibrated data. + * This is always true for SFF-8346, and explicitly + * checked for SFF-8472. + */ + + /* Table 3.9, bit 5 is set, internally calibrated */ + snprintf(buf, size, "%d.%02d mW (%.2f dBm)", + mW / 10000, (mW % 10000) / 100, dbm); +} + +static void +get_sfp_temp(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[2]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8472_DIAG, SFF_8472_TEMP, 2, xbuf); + convert_sff_temp(buf, size, xbuf); +} + +static void +get_sfp_voltage(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[2]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8472_DIAG, SFF_8472_VCC, 2, xbuf); + convert_sff_voltage(buf, size, xbuf); +} + +static void +get_qsfp_temp(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[2]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8436_BASE, SFF_8436_TEMP, 2, xbuf); + convert_sff_temp(buf, size, xbuf); +} + +static void +get_qsfp_voltage(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[2]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8436_BASE, SFF_8436_VCC, 2, xbuf); + convert_sff_voltage(buf, size, xbuf); +} + +static void +get_sfp_rx_power(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[2]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8472_DIAG, SFF_8472_RX_POWER, 2, xbuf); + convert_sff_power(ii, buf, size, xbuf); +} + +static void +get_sfp_tx_power(struct i2c_info *ii, char *buf, size_t size) +{ + char xbuf[2]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8472_DIAG, SFF_8472_TX_POWER, 2, xbuf); + convert_sff_power(ii, buf, size, xbuf); +} + +static void +get_qsfp_rx_power(struct i2c_info *ii, char *buf, size_t size, int chan) +{ + char xbuf[2]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8436_BASE, SFF_8436_RX_CH1_MSB + (chan - 1) * 2, 2, xbuf); + convert_sff_power(ii, buf, size, xbuf); +} + +static void +get_qsfp_tx_power(struct i2c_info *ii, char *buf, size_t size, int chan) +{ + char xbuf[2]; + + memset(xbuf, 0, sizeof(xbuf)); + ii->f(ii, SFF_8436_BASE, SFF_8436_TX_CH1_MSB + (chan -1) * 2, 2, xbuf); + convert_sff_power(ii, buf, size, xbuf); +} + +/* Intel ixgbe-specific structures and handlers */ +struct ixgbe_i2c_req { + uint8_t dev_addr; + uint8_t offset; + uint8_t len; + uint8_t data[8]; +}; +#define SIOCGI2C SIOCGIFGENERIC + +static int +read_i2c_ixgbe(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len, + caddr_t buf) +{ + struct ixgbe_i2c_req ixreq; + int i; + + if (ii->error != 0) + return (ii->error); + + ii->ifr->ifr_data = (caddr_t)&ixreq; + + memset(&ixreq, 0, sizeof(ixreq)); + ixreq.dev_addr = addr; + + for (i = 0; i < len; i += 1) { + ixreq.offset = off + i; + ixreq.len = 1; + ixreq.data[0] = '\0'; + + if (ioctl(ii->s, SIOCGI2C, ii->ifr) != 0) { + ii->error = errno; + return (errno); + } + memcpy(&buf[i], ixreq.data, 1); + } + + return (0); +} + +/* Generic handler */ +static int +read_i2c_generic(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len, + caddr_t buf) +{ + + ii->error = EINVAL; + return (-1); +} + +static void +print_qsfp_status(struct i2c_info *ii, int verbose) +{ + char buf[80], buf2[40], buf3[40]; + uint8_t diag_type; + int i; + + /* Read diagnostic monitoring type */ + ii->f(ii, SFF_8436_BASE, SFF_8436_DIAG_TYPE, 1, (caddr_t)&diag_type); + if (ii->error != 0) + return; + + /* + * Read monitoring data it is supplied. + * XXX: It is not exactly clear from standard + * how one can specify lack of measurements (passive cables case). + */ + if (diag_type != 0) + ii->do_diag = 1; + ii->qsfp = 1; + + /* Transceiver type */ + get_qsfp_identifier(ii, buf, sizeof(buf)); + get_qsfp_transceiver_class(ii, buf2, sizeof(buf2)); + get_qsfp_connector(ii, buf3, sizeof(buf3)); + if (ii->error == 0) + printf("\tplugged: %s %s (%s)\n", buf, buf2, buf3); + print_sfp_vendor(ii, buf, sizeof(buf)); + if (ii->error == 0) + printf("\t%s\n", buf); + + /* Request current measurements if they are provided: */ + if (ii->do_diag != 0) { + get_qsfp_temp(ii, buf, sizeof(buf)); + get_qsfp_voltage(ii, buf2, sizeof(buf2)); + printf("\tmodule temperature: %s voltage: %s\n", buf, buf2); + for (i = 1; i <= 4; i++) { + get_qsfp_rx_power(ii, buf, sizeof(buf), i); + get_qsfp_tx_power(ii, buf2, sizeof(buf2), i); + printf("\tlane %d: RX: %s TX: %s\n", i, buf, buf2); + } + } +} + +static void +print_sfp_status(struct i2c_info *ii, int verbose) +{ + char buf[80], buf2[40], buf3[40]; + uint8_t diag_type, flags; + + /* Read diagnostic monitoring type */ + ii->f(ii, SFF_8472_BASE, SFF_8472_DIAG_TYPE, 1, (caddr_t)&diag_type); + if (ii->error != 0) + return; + + /* + * Read monitoring data IFF it is supplied AND is + * internally calibrated + */ + flags = SFF_8472_DDM_DONE | SFF_8472_DDM_INTERNAL; + if ((diag_type & flags) == flags) + ii->do_diag = 1; + + /* Transceiver type */ + get_sfp_identifier(ii, buf, sizeof(buf)); + get_sfp_transceiver_class(ii, buf2, sizeof(buf2)); + get_sfp_connector(ii, buf3, sizeof(buf3)); + if (ii->error == 0) + printf("\tplugged: %s %s (%s)\n", buf, buf2, buf3); + if (verbose > 2) + printf_sfp_transceiver_descr(ii, buf, sizeof(buf)); + print_sfp_vendor(ii, buf, sizeof(buf)); + if (ii->error == 0) + printf("\t%s\n", buf); + + /* + * Request current measurements iff they are provided: + */ + if (ii->do_diag != 0) { + get_sfp_temp(ii, buf, sizeof(buf)); + get_sfp_voltage(ii, buf2, sizeof(buf2)); + printf("\tmodule temperature: %s Voltage: %s\n", buf, buf2); + get_sfp_rx_power(ii, buf, sizeof(buf)); + get_sfp_tx_power(ii, buf2, sizeof(buf2)); + printf("\tRX: %s TX: %s\n", buf, buf2); + } +} + +void +sfp_status(int s, struct ifreq *ifr, int verbose) +{ + struct i2c_info ii; + + /* Prepare necessary into to pass to NIC handler */ + ii.s = s; + ii.ifr = ifr; + + /* + * Check if we have i2c support for particular driver. + * TODO: Determine driver by original name. + */ + memset(&ii, 0, sizeof(ii)); + if (strncmp(ifr->ifr_name, "ix", 2) == 0) { + ii.f = read_i2c_ixgbe; + print_sfp_status(&ii, verbose); + } else if (strncmp(ifr->ifr_name, "cxl", 3) == 0) { + ii.port_id = atoi(&ifr->ifr_name[3]); + ii.f = read_i2c_generic; + ii.cfd = -1; + print_qsfp_status(&ii, verbose); + } else + return; +} + diff --git a/sbin/init/init.c b/sbin/init/init.c index 8583ba5..5ab3527 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -242,7 +242,7 @@ invalid: * Note that this does NOT open a file... * Does 'init' deserve its own facility number? */ - openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH); + openlog("init", LOG_CONS, LOG_AUTH); /* * Create an initial session. diff --git a/sbin/ipf/ipf/Makefile b/sbin/ipf/ipf/Makefile index 73888b2..c3938c6 100644 --- a/sbin/ipf/ipf/Makefile +++ b/sbin/ipf/ipf/Makefile @@ -39,6 +39,4 @@ DPADD+= ${LIBPCAP} LDADD+= -lpcap .endif -NO_PIE= yes - .include <bsd.prog.mk> diff --git a/sbin/ipf/ipfstat/Makefile b/sbin/ipf/ipfstat/Makefile index c2b422d..a33c5df 100644 --- a/sbin/ipf/ipfstat/Makefile +++ b/sbin/ipf/ipfstat/Makefile @@ -8,6 +8,4 @@ MAN= ipfstat.8 DPADD+= ${LIBCURSES} LDADD+= -lcurses -NO_PIE= yes - .include <bsd.prog.mk> diff --git a/sbin/ipf/ipftest/Makefile b/sbin/ipf/ipftest/Makefile index 57f3c4e..32b074c 100644 --- a/sbin/ipf/ipftest/Makefile +++ b/sbin/ipf/ipftest/Makefile @@ -32,8 +32,6 @@ CLEANFILES+= ipnat.tab.c ipnat.tab.h CLEANFILES+= ippool_y.c ippool_l.c CLEANFILES+= ippool.tab.c ippool.tab.h -NO_PIE= yes - ipnat_y.c: ipnat_y.y ${YACC} -b ipnat -d ${.ALLSRC} sed -e 's/yy/ipnat_yy/g' \ diff --git a/sbin/ipf/ipmon/Makefile b/sbin/ipf/ipmon/Makefile index 2ecfed1..3639f87 100644 --- a/sbin/ipf/ipmon/Makefile +++ b/sbin/ipf/ipmon/Makefile @@ -11,8 +11,6 @@ DPSRCS+= ${GENHDRS} CLEANFILES+= ${GENHDRS} ipmon_y.c ipmon_l.c -NO_PIE= yes - ipmon_y.c: ipmon_y.y ${YACC} -d ${.ALLSRC} sed -e 's/yy/ipmon_yy/g' \ diff --git a/sbin/ipf/ipnat/Makefile b/sbin/ipf/ipnat/Makefile index aafb014..1c017e1 100644 --- a/sbin/ipf/ipnat/Makefile +++ b/sbin/ipf/ipnat/Makefile @@ -11,8 +11,6 @@ DPSRCS+= ${GENHDRS} CLEANFILES+= ${GENHDRS} ipnat_y.c ipnat_l.c -NO_PIE= yes - ipnat_y.c: ipnat_y.y ${YACC} -d ${.ALLSRC} sed -e 's/yy/ipnat_yy/g' \ diff --git a/sbin/ipf/ippool/Makefile b/sbin/ipf/ippool/Makefile index bb7e9ce..6e3f85d 100644 --- a/sbin/ipf/ippool/Makefile +++ b/sbin/ipf/ippool/Makefile @@ -10,8 +10,6 @@ DPSRCS+= ${GENHDRS} CLEANFILES+= ${GENHDRS} ippool_y.c ippool_l.c -NO_PIE= yes - ippool_y.c: ippool_y.y ${YACC} -d ${.ALLSRC} sed -e 's/yy/ippool_yy/g' \ diff --git a/sbin/ipf/ipresend/Makefile b/sbin/ipf/ipresend/Makefile index 492451c..5e0ac15 100644 --- a/sbin/ipf/ipresend/Makefile +++ b/sbin/ipf/ipresend/Makefile @@ -4,8 +4,6 @@ PROG= ipresend SRCS= ipresend.c ip.c resend.c sbpf.c sock.c 44arp.c MAN= ipresend.1 -NO_PIE= yes - .PATH: ${.CURDIR}/../../../contrib/ipfilter/ipsend .include <bsd.prog.mk> diff --git a/sbin/mksnap_ffs/Makefile b/sbin/mksnap_ffs/Makefile index 9247cb2..de96fa0 100644 --- a/sbin/mksnap_ffs/Makefile +++ b/sbin/mksnap_ffs/Makefile @@ -10,9 +10,9 @@ WARNS?= 2 CFLAGS+=-I${.CURDIR}/../mount .if defined(NOSUID) -BINMODE=550 +BINMODE=554 .else -BINMODE=4550 +BINMODE=4554 BINOWN= root .endif BINGRP= operator diff --git a/sbin/mount/mntopts.h b/sbin/mount/mntopts.h index 86a350f..d273dde 100644 --- a/sbin/mount/mntopts.h +++ b/sbin/mount/mntopts.h @@ -33,7 +33,7 @@ struct mntopt { const char *m_option; /* option name */ int m_inverse; /* if a negative option, e.g. "atime" */ - int m_flag; /* bit to set, e.g. MNT_RDONLY */ + long long m_flag; /* bit to set, e.g. MNT_RDONLY */ int m_altloc; /* 1 => set bit in altflags */ }; @@ -55,6 +55,7 @@ struct mntopt { #define MOPT_MULTILABEL { "multilabel", 0, MNT_MULTILABEL, 0 } #define MOPT_ACLS { "acls", 0, MNT_ACLS, 0 } #define MOPT_NFS4ACLS { "nfsv4acls", 0, MNT_NFS4ACLS, 0 } +#define MOPT_AUTOMOUNTED { "automounted",0, MNT_AUTOMOUNTED, 0 } /* Control flags. */ #define MOPT_FORCE { "force", 0, MNT_FORCE, 0 } @@ -89,7 +90,8 @@ struct mntopt { MOPT_NOCLUSTERW, \ MOPT_MULTILABEL, \ MOPT_ACLS, \ - MOPT_NFS4ACLS + MOPT_NFS4ACLS, \ + MOPT_AUTOMOUNTED void getmntopts(const char *, const struct mntopt *, int *, int *); void rmslashes(char *, char *); diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8 index 3b5c254..bfa70b6 100644 --- a/sbin/mount/mount.8 +++ b/sbin/mount/mount.8 @@ -28,7 +28,7 @@ .\" @(#)mount.8 8.8 (Berkeley) 6/16/94 .\" $FreeBSD$ .\" -.Dd June 6, 2011 +.Dd August 20, 2014 .Dt MOUNT 8 .Os .Sh NAME @@ -150,6 +150,11 @@ For this reason, the .Cm async flag should be used sparingly, and only when some data recovery mechanism is present. +.It Cm automounted +This flag indicates that the file system was mounted by +.Xr automountd 8 . +Automounted file systems are automatically unmounted by +.Xr autounmountd 8 . .It Cm current When used with the .Fl u diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c index 91c7d7c..5ea45df 100644 --- a/sbin/mount/mount.c +++ b/sbin/mount/mount.c @@ -114,6 +114,7 @@ static struct opt { { MNT_ACLS, "acls" }, { MNT_NFS4ACLS, "nfsv4acls" }, { MNT_GJOURNAL, "gjournal" }, + { MNT_AUTOMOUNTED, "automounted" }, { 0, NULL } }; diff --git a/sbin/newfs_msdos/newfs_msdos.c b/sbin/newfs_msdos/newfs_msdos.c index 4bfb219..f315d98 100644 --- a/sbin/newfs_msdos/newfs_msdos.c +++ b/sbin/newfs_msdos/newfs_msdos.c @@ -689,7 +689,7 @@ main(int argc, char *argv[]) ((u_int)tm->tm_hour << 8 | (u_int)tm->tm_min)); mk4(bsx->exVolumeID, x); - mklabel(bsx->exVolumeLabel, opt_L ? opt_L : "NO_NAME"); + mklabel(bsx->exVolumeLabel, opt_L ? opt_L : "NO NAME"); sprintf(buf, "FAT%u", fat); setstr(bsx->exFileSysType, buf, sizeof(bsx->exFileSysType)); if (!opt_B) { diff --git a/sbin/rcorder/Makefile b/sbin/rcorder/Makefile index dc48b4c..b71aa4b 100644 --- a/sbin/rcorder/Makefile +++ b/sbin/rcorder/Makefile @@ -14,8 +14,6 @@ CFLAGS+= -DORDER -I. SRCS+= util.h CLEANFILES+= util.h -NO_PIE= yes - util.h: ln -sf ${.CURDIR}/../../lib/libutil/libutil.h ${.TARGET} diff --git a/sbin/shutdown/Makefile b/sbin/shutdown/Makefile index a6ecb93..905d1bc 100644 --- a/sbin/shutdown/Makefile +++ b/sbin/shutdown/Makefile @@ -8,6 +8,6 @@ MLINKS= shutdown.8 poweroff.8 BINOWN= root BINGRP= operator -BINMODE=4550 +BINMODE=4554 .include <bsd.prog.mk> diff --git a/sbin/umount/umount.c b/sbin/umount/umount.c index f2e02f2..521bbc8 100644 --- a/sbin/umount/umount.c +++ b/sbin/umount/umount.c @@ -394,7 +394,7 @@ umountfs(struct statfs *sfs) * has been unmounted. */ if (ai != NULL && !(fflag & MNT_FORCE) && do_rpc) { - clp = clnt_create(hostp, MOUNTPROG, MOUNTVERS, "udp"); + clp = clnt_create(hostp, MOUNTPROG, MOUNTVERS3, "udp"); if (clp == NULL) { warnx("%s: %s", hostp, clnt_spcreateerror("MOUNTPROG")); |