diff options
Diffstat (limited to 'usr.sbin')
539 files changed, 20181 insertions, 5747 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index df9f867..36585d9 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -5,11 +5,8 @@ SUBDIR= adduser \ arp \ - autofs \ binmiscctl \ - bootparamd \ bsdconfig \ - bsdinstall \ cdcontrol \ chkgrp \ chown \ @@ -22,6 +19,7 @@ SUBDIR= adduser \ ctld \ daemon \ dconschat \ + devctl \ devinfo \ digictl \ diskinfo \ @@ -29,15 +27,15 @@ SUBDIR= adduser \ extattr \ extattrctl \ fifolog \ + fstyp \ fwcontrol \ getfmac \ getpmac \ gstat \ i2c \ ifmcstat \ - inetd \ iostat \ - iscsid \ + iovctl \ kldxref \ mailwrapper \ makefs \ @@ -84,15 +82,14 @@ SUBDIR= adduser \ spray \ syslogd \ sysrc \ - tcpdchk \ - tcpdmatch \ tcpdrop \ tcpdump \ - timed \ traceroute \ trpt \ tzsetup \ + uefisign \ ugidfw \ + vigr \ vipw \ wake \ watch \ @@ -124,10 +121,22 @@ SUBDIR+= praudit SUBDIR+= authpf .endif +.if ${MK_AUTOFS} != "no" +SUBDIR+= autofs +.endif + .if ${MK_BLUETOOTH} != "no" SUBDIR+= bluetooth .endif +.if ${MK_BOOTPARAMD} != "no" +SUBDIR+= bootparamd +.endif + +.if ${MK_BSDINSTALL} != "no" +SUBDIR+= bsdinstall +.endif + .if ${MK_BSNMP} != "no" SUBDIR+= bsnmpd .endif @@ -172,10 +181,18 @@ SUBDIR+= rtsold SUBDIR+= traceroute6 .endif +.if ${MK_INETD} != "no" +SUBDIR+= inetd +.endif + .if ${MK_IPFW} != "no" SUBDIR+= ipfwpcap .endif +.if ${MK_ISCSI} != "no" +SUBDIR+= iscsid +.endif + .if ${MK_JAIL} != "no" SUBDIR+= jail SUBDIR+= jexec @@ -256,6 +273,7 @@ SUBDIR+= pkg SUBDIR+= pmcannotate SUBDIR+= pmccontrol SUBDIR+= pmcstat +SUBDIR+= pmcstudy .endif .if ${MK_PORTSNAP} != "no" @@ -288,10 +306,19 @@ SUBDIR+= praliases SUBDIR+= sendmail .endif +.if ${MK_TCP_WRAPPERS} != "no" +SUBDIR+= tcpdchk +SUBDIR+= tcpdmatch +.endif + .if ${MK_TESTS} != "no" SUBDIR+= tests .endif +.if ${MK_TIMED} != "no" +SUBDIR+= timed +.endif + .if ${MK_TOOLCHAIN} != "no" SUBDIR+= config SUBDIR+= crunch diff --git a/usr.sbin/Makefile.amd64 b/usr.sbin/Makefile.amd64 index 2d1a3e8..3f40974 100644 --- a/usr.sbin/Makefile.amd64 +++ b/usr.sbin/Makefile.amd64 @@ -10,9 +10,11 @@ SUBDIR+= acpi SUBDIR+= apm .endif SUBDIR+= asf +.if ${MK_BHYVE} != "no" SUBDIR+= bhyve SUBDIR+= bhyvectl SUBDIR+= bhyveload +.endif SUBDIR+= boot0cfg .if ${MK_TOOLCHAIN} != "no" SUBDIR+= btxld diff --git a/usr.sbin/acpi/acpiconf/acpiconf.c b/usr.sbin/acpi/acpiconf/acpiconf.c index 5ca2f98..1fab4b6 100644 --- a/usr.sbin/acpi/acpiconf/acpiconf.c +++ b/usr.sbin/acpi/acpiconf/acpiconf.c @@ -136,16 +136,30 @@ acpi_battinfo(int num) if (ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) == -1) err(EX_IOERR, "get battery user info (%d) failed", num); if (battio.battinfo.state != ACPI_BATT_STAT_NOT_PRESENT) { - printf("State:\t\t\t"); - if (battio.battinfo.state == 0) - printf("high "); - if (battio.battinfo.state & ACPI_BATT_STAT_CRITICAL) - printf("critical "); - if (battio.battinfo.state & ACPI_BATT_STAT_DISCHARG) - printf("discharging "); - if (battio.battinfo.state & ACPI_BATT_STAT_CHARGING) - printf("charging "); - printf("\n"); + const char *state; + switch (battio.battinfo.state & ACPI_BATT_STAT_BST_MASK) { + case 0: + state = "high"; + break; + case ACPI_BATT_STAT_DISCHARG: + state = "discharging"; + break; + case ACPI_BATT_STAT_CHARGING: + state = "charging"; + break; + case ACPI_BATT_STAT_CRITICAL: + state = "critical"; + break; + case ACPI_BATT_STAT_DISCHARG | ACPI_BATT_STAT_CRITICAL: + state = "critical discharging"; + break; + case ACPI_BATT_STAT_CHARGING | ACPI_BATT_STAT_CRITICAL: + state = "critical charging"; + break; + default: + state = "invalid"; + } + printf("State:\t\t\t%s\n", state); if (battio.battinfo.cap == -1) printf("Remaining capacity:\tunknown\n"); else diff --git a/usr.sbin/acpi/acpidb/Makefile b/usr.sbin/acpi/acpidb/Makefile index 15d114d..d470a9b 100644 --- a/usr.sbin/acpi/acpidb/Makefile +++ b/usr.sbin/acpi/acpidb/Makefile @@ -12,9 +12,9 @@ SRCS+= dbcmds.c dbconvert.c dbdisply.c dbexec.c dbfileio.c \ dbtest.c dbutils.c dbxface.c # components/disassembler -SRCS+= dmbuffer.c dmdeferred.c dmnames.c dmobject.c dmopcode.c \ - dmresrc.c dmresrcl.c dmresrcl2.c dmresrcs.c dmutils.c \ - dmwalk.c +SRCS+= dmbuffer.c dmcstyle.c dmdeferred.c dmnames.c dmobject.c \ + dmopcode.c dmresrc.c dmresrcl.c dmresrcl2.c dmresrcs.c \ + dmutils.c dmwalk.c # components/dispatcher SRCS+= dsargs.c dscontrol.c dsfield.c dsinit.c dsmethod.c \ @@ -74,7 +74,6 @@ MAN= acpidb.8 WARNS?= 3 CFLAGS+= -DACPI_EXEC_APP -fno-strict-aliasing -DPADD= ${LIBPTHREAD} -LDADD= -lpthread +LIBADD= pthread .include <bsd.prog.mk> diff --git a/usr.sbin/acpi/acpidb/acpidb.c b/usr.sbin/acpi/acpidb/acpidb.c index 3688caf..b3d0021 100644 --- a/usr.sbin/acpi/acpidb/acpidb.c +++ b/usr.sbin/acpi/acpidb/acpidb.c @@ -74,6 +74,7 @@ static struct ACPIRegionContentList RegionContentList; static int aml_simulation_initialized = 0; ACPI_PHYSICAL_ADDRESS AeLocalGetRootPointer(void); +void AeDoObjectOverrides(void); void AeTableOverride(ACPI_TABLE_HEADER *, ACPI_TABLE_HEADER **); static void aml_simulation_init(void); @@ -99,6 +100,11 @@ AcpiOsGetRootPointer(void) } void +AeDoObjectOverrides(void) +{ +} + +void AeTableOverride(ACPI_TABLE_HEADER *ExistingTable, ACPI_TABLE_HEADER **NewTable) { } @@ -472,7 +478,7 @@ load_dsdt(const char *dsdtfile) return (-1); } - AcpiDbGetTableFromFile(filetmp, NULL); + AcpiDbGetTableFromFile(filetmp, NULL, TRUE); AcpiDbInitialize(); AcpiGbl_DebuggerConfiguration = 0; diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c index ae7ebf2..52a9e8a 100644 --- a/usr.sbin/acpi/acpidump/acpi.c +++ b/usr.sbin/acpi/acpidump/acpi.c @@ -168,12 +168,18 @@ acpi_print_gas(ACPI_GENERIC_ADDRESS *gas) { switch(gas->SpaceId) { case ACPI_GAS_MEMORY: - printf("0x%08lx:%u[%u] (Memory)", (u_long)gas->Address, - gas->BitOffset, gas->BitWidth); + if (gas->BitWidth <= 32) + printf("0x%08x:%u[%u] (Memory)", + (u_int)gas->Address, gas->BitOffset, + gas->BitWidth); + else + printf("0x%016jx:%u[%u] (Memory)", + (uintmax_t)gas->Address, gas->BitOffset, + gas->BitWidth); break; case ACPI_GAS_IO: - printf("0x%02lx:%u[%u] (IO)", (u_long)gas->Address, - gas->BitOffset, gas->BitWidth); + printf("0x%02x:%u[%u] (IO)", (u_int)gas->Address, + gas->BitOffset, gas->BitWidth); break; case ACPI_GAS_PCI: printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32), @@ -194,7 +200,7 @@ acpi_print_gas(ACPI_GENERIC_ADDRESS *gas) case ACPI_GAS_DATATABLE: case ACPI_GAS_FIXED: default: - printf("0x%08lx (?)", (u_long)gas->Address); + printf("0x%016jx (?)", (uintmax_t)gas->Address); break; } } @@ -831,7 +837,7 @@ acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd) #undef PRINTFLAG printf("\tSegment=%d\n", drhd->Segment); - printf("\tAddress=0x%0jx\n", (uintmax_t)drhd->Address); + printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address); remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT); if (remaining > 0) @@ -856,8 +862,8 @@ acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr) printf("\tType=RMRR\n"); printf("\tLength=%d\n", rmrr->Header.Length); printf("\tSegment=%d\n", rmrr->Segment); - printf("\tBaseAddress=0x%0jx\n", (uintmax_t)rmrr->BaseAddress); - printf("\tLimitAddress=0x%0jx\n", (uintmax_t)rmrr->EndAddress); + printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress); + printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress); remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY); if (remaining > 0) @@ -912,7 +918,7 @@ acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa) printf("\n"); printf("\tType=RHSA\n"); printf("\tLength=%d\n", rhsa->Header.Length); - printf("\tBaseAddress=0x%0jx\n", (uintmax_t)rhsa->BaseAddress); + printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress); printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain); } @@ -1074,7 +1080,6 @@ acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) ACPI_TABLE_RSDT *rsdt; ACPI_TABLE_XSDT *xsdt; int i, entries; - u_long addr; rsdt = (ACPI_TABLE_RSDT *)rsdp; xsdt = (ACPI_TABLE_XSDT *)rsdp; @@ -1085,18 +1090,11 @@ acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp) for (i = 0; i < entries; i++) { if (i > 0) printf(", "); - switch (addr_size) { - case 4: - addr = le32toh(rsdt->TableOffsetEntry[i]); - break; - case 8: - addr = le64toh(xsdt->TableOffsetEntry[i]); - break; - default: - addr = 0; - } - assert(addr != 0); - printf("0x%08lx", addr); + if (addr_size == 4) + printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i])); + else + printf("0x%016jx", + (uintmax_t)le64toh(xsdt->TableOffsetEntry[i])); } printf(" }\n"); printf(END_COMMENT); @@ -1212,8 +1210,8 @@ acpi_print_fadt(ACPI_TABLE_HEADER *sdp) printf(", RESET_VALUE=%#x\n", fadt->ResetValue); } if (acpi_get_fadt_revision(fadt) > 1) { - printf("\tX_FACS=0x%08lx, ", (u_long)fadt->XFacs); - printf("X_DSDT=0x%08lx\n", (u_long)fadt->XDsdt); + printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs); + printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt); printf("\tX_PM1a_EVT_BLK="); acpi_print_gas(&fadt->XPm1aEventBlock); if (fadt->XPm1bEventBlock.Address != 0) { @@ -1268,10 +1266,9 @@ acpi_print_facs(ACPI_TABLE_FACS *facs) printf("S4BIOS"); printf("\n"); - if (facs->XFirmwareWakingVector != 0) { - printf("\tX_Firm_Wake_Vec=%08lx\n", - (u_long)facs->XFirmwareWakingVector); - } + if (facs->XFirmwareWakingVector != 0) + printf("\tX_Firm_Wake_Vec=%016jx\n", + (uintmax_t)facs->XFirmwareWakingVector); printf("\tVersion=%u\n", facs->Version); printf(END_COMMENT); @@ -1321,8 +1318,8 @@ acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp) printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress, rp->Checksum); } else { - printf("\tXSDT=0x%08lx, length=%u, cksum=%u\n", - (u_long)rp->XsdtPhysicalAddress, rp->Length, + printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n", + (uintmax_t)rp->XsdtPhysicalAddress, rp->Length, rp->ExtendedChecksum); } printf(END_COMMENT); @@ -1342,17 +1339,12 @@ acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) xsdt = (ACPI_TABLE_XSDT *)rsdp; entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; for (i = 0; i < entries; i++) { - switch (addr_size) { - case 4: + if (addr_size == 4) addr = le32toh(rsdt->TableOffsetEntry[i]); - break; - case 8: + else addr = le64toh(xsdt->TableOffsetEntry[i]); - break; - default: - assert((addr = 0)); - } - + if (addr == 0) + continue; sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); if (acpi_checksum(sdp, sdp->Length)) { warnx("RSDT entry %d (sig %.4s) is corrupt", i, @@ -1547,16 +1539,12 @@ sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last) xsdt = (ACPI_TABLE_XSDT *)rsdp; entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size; for (i = 0; i < entries; i++) { - switch (addr_size) { - case 4: + if (addr_size == 4) addr = le32toh(rsdt->TableOffsetEntry[i]); - break; - case 8: + else addr = le64toh(xsdt->TableOffsetEntry[i]); - break; - default: - assert((addr = 0)); - } + if (addr == 0) + continue; sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr); if (last != NULL) { if (sdt == last) diff --git a/usr.sbin/acpi/iasl/Makefile b/usr.sbin/acpi/iasl/Makefile index 8f021a3..e9faad2 100644 --- a/usr.sbin/acpi/iasl/Makefile +++ b/usr.sbin/acpi/iasl/Makefile @@ -4,8 +4,8 @@ PROG= iasl # common SRCS= adfile.c adisasm.c adwalk.c ahids.c ahpredef.c \ - ahuuids.c cmfsize.c dmextern.c dmrestag.c dmtable.c \ - dmtbdump.c dmtbinfo.c getopt.c + ahtable.c ahuuids.c cmfsize.c dmextern.c dmrestag.c \ + dmtable.c dmtbdump.c dmtbinfo.c getopt.c # compiler SRCS+= aslanalyze.c aslascii.c aslbtypes.c aslcodegen.c \ @@ -16,23 +16,24 @@ SRCS+= aslanalyze.c aslascii.c aslbtypes.c aslcodegen.c \ aslmapenter.c aslmapoutput.c aslmaputils.c \ aslmessages.c aslmethod.c aslnamesp.c asloffset.c \ aslopcodes.c asloperands.c aslopt.c asloptions.c \ - aslpredef.c aslprepkg.c aslresource.c aslrestype1.c \ - aslrestype1i.c aslrestype2.c aslrestype2d.c \ - aslrestype2e.c aslrestype2q.c aslrestype2s.c \ - aslrestype2w.c aslstartup.c aslstubs.c asltransform.c \ - asltree.c aslutils.c asluuid.c aslwalks.c aslxref.c \ - dtcompile.c dtexpress.c dtfield.c dtio.c dtparser.y.h \ - dtparserlex.c dtparserparse.c dtsubtable.c dttable.c \ - dttemplate.c dtutils.c prexpress.c prmacros.c \ - prparser.y.h prparserlex.c prparserparse.c prscan.c \ - prutils.c + aslpredef.c aslprepkg.c aslprintf.c aslprune.c \ + aslresource.c aslrestype1.c aslrestype1i.c \ + aslrestype2.c aslrestype2d.c aslrestype2e.c \ + aslrestype2q.c aslrestype2s.c aslrestype2w.c \ + aslstartup.c aslstubs.c asltransform.c asltree.c \ + aslutils.c asluuid.c aslwalks.c aslxref.c dtcompile.c \ + dtexpress.c dtfield.c dtio.c dtparser.y.h dtparserlex.c \ + dtparserparse.c dtsubtable.c dttable.c dttemplate.c \ + dtutils.c prexpress.c prmacros.c prparser.y.h \ + prparserlex.c prparserparse.c prscan.c prutils.c # components/debugger SRCS+= dbfileio.c # components/disassembler -SRCS+= dmbuffer.c dmdeferred.c dmnames.c dmopcode.c dmresrc.c \ - dmresrcl.c dmresrcl2.c dmresrcs.c dmutils.c dmwalk.c +SRCS+= dmbuffer.c dmcstyle.c dmdeferred.c dmnames.c dmopcode.c \ + dmresrc.c dmresrcl.c dmresrcl2.c dmresrcs.c dmutils.c \ + dmwalk.c # components/dispatcher SRCS+= dsargs.c dscontrol.c dsfield.c dsobject.c dsopcode.c \ diff --git a/usr.sbin/acpi/iasl/Makefile.depend b/usr.sbin/acpi/iasl/Makefile.depend index 82b4665..0630151 100644 --- a/usr.sbin/acpi/iasl/Makefile.depend +++ b/usr.sbin/acpi/iasl/Makefile.depend @@ -10,6 +10,7 @@ DIRDEPS = \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ + usr.bin/yacc.host \ .include <dirdeps.mk> @@ -60,6 +61,10 @@ aslpredef.o: aslcompiler.y.h aslpredef.po: aslcompiler.y.h aslprepkg.o: aslcompiler.y.h aslprepkg.po: aslcompiler.y.h +aslprintf.o: aslcompiler.y.h +aslprintf.po: aslcompiler.y.h +aslprune.o: aslcompiler.y.h +aslprune.po: aslcompiler.y.h aslresource.o: aslcompiler.y.h aslresource.po: aslcompiler.y.h aslrestype1.o: aslcompiler.y.h diff --git a/usr.sbin/amd/Makefile b/usr.sbin/amd/Makefile index 37e4200..2255f14 100644 --- a/usr.sbin/amd/Makefile +++ b/usr.sbin/amd/Makefile @@ -5,7 +5,7 @@ # # $FreeBSD$ -SUBDIR= include libamu amd amq doc fixmount fsinfo hlfsd mk-amd-map pawd \ +SUBDIR= include libamu amd amq fixmount fsinfo hlfsd mk-amd-map pawd \ scripts wire-test .include <bsd.subdir.mk> diff --git a/usr.sbin/amd/Makefile.inc b/usr.sbin/amd/Makefile.inc index e4425f5..8c397cf 100644 --- a/usr.sbin/amd/Makefile.inc +++ b/usr.sbin/amd/Makefile.inc @@ -29,13 +29,6 @@ CFLAGS+= -DYES_HESIOD CFLAGS+= -DHOST_CPU=\"${MACHINE_CPUARCH}\" -DHOST_ARCH=\"${MACHINE_ARCH}\" -.if exists(${.OBJDIR}/../libamu) -LIBAMUDIR= ${.OBJDIR}/../libamu -.else -LIBAMUDIR= ${.CURDIR}/../libamu -.endif -LIBAMU= ${LIBAMUDIR}/libamu.a - RPCCOM= RPCGEN_CPP=${CPP:Q} rpcgen MOUNT_X= ${DESTDIR}/usr/include/rpcsvc/mount.x NFS_PROT_X= ${DESTDIR}/usr/include/rpcsvc/nfs_prot.x diff --git a/usr.sbin/amd/amd/Makefile b/usr.sbin/amd/amd/Makefile index 1fc41bf..602c941 100644 --- a/usr.sbin/amd/amd/Makefile +++ b/usr.sbin/amd/amd/Makefile @@ -27,8 +27,7 @@ SRCS+= srvr_amfs_auto.c srvr_nfs.c CFLAGS+= -I${.CURDIR}/../../../contrib/amd/amd \ -I${DESTDIR}/usr/include/rpcsvc -DPADD= ${LIBAMU} ${LIBWRAP} -LDADD= ${LIBAMU} -lwrap +LIBADD= amu wrap CLEANFILES+= conf_parse.c conf_parse.h conf_tok.c diff --git a/usr.sbin/amd/amd/Makefile.depend b/usr.sbin/amd/amd/Makefile.depend index bdfb4b3..507b7ad 100644 --- a/usr.sbin/amd/amd/Makefile.depend +++ b/usr.sbin/amd/amd/Makefile.depend @@ -14,6 +14,7 @@ DIRDEPS = \ lib/libc \ lib/libcompiler_rt \ lib/libwrap \ + usr.bin/yacc.host \ usr.sbin/amd/include \ usr.sbin/amd/libamu \ diff --git a/usr.sbin/amd/amq/Makefile b/usr.sbin/amd/amq/Makefile index 74fc749..968ae4c 100644 --- a/usr.sbin/amd/amq/Makefile +++ b/usr.sbin/amd/amq/Makefile @@ -14,7 +14,6 @@ SRCS= amq.c amq_clnt.c amq_xdr.c CFLAGS+= -I${.CURDIR}/../../../contrib/amd/amq -DPADD= ${LIBAMU} -LDADD= ${LIBAMU} +LIBADD= amu .include <bsd.prog.mk> diff --git a/usr.sbin/amd/doc/Makefile b/usr.sbin/amd/doc/Makefile deleted file mode 100644 index e9c7707..0000000 --- a/usr.sbin/amd/doc/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This file is under a "BSD" copyright (c) by David O'Brien 1998. - -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../../contrib/amd/doc - -INFO= am-utils - -INFOSECTION= "AMD Documentation" -INFOENTRY= "* Am-utils: (am-utils). The Amd automounter suite of utilities" - -MAKEINFOFLAGS+= -I ${.CURDIR}/../../../contrib/amd/doc - -.include <bsd.info.mk> diff --git a/usr.sbin/amd/fixmount/Makefile b/usr.sbin/amd/fixmount/Makefile index 7f96a45..8137ffb 100644 --- a/usr.sbin/amd/fixmount/Makefile +++ b/usr.sbin/amd/fixmount/Makefile @@ -10,12 +10,11 @@ PROG= fixmount MAN= fixmount.8 -SRCS= fixmount.c +SRCS= fixmount.c # These would be links created by the GNU-style configure SRCS+= checkmount_bsd44.c -DPADD= ${LIBAMU} ${LIBRPCSVC} -LDADD= ${LIBAMU} -lrpcsvc +LIBADD+= amu rpcsvc .include <bsd.prog.mk> diff --git a/usr.sbin/amd/fsinfo/Makefile b/usr.sbin/amd/fsinfo/Makefile index 1695a46..a059da6 100644 --- a/usr.sbin/amd/fsinfo/Makefile +++ b/usr.sbin/amd/fsinfo/Makefile @@ -15,8 +15,7 @@ SRCS+= wr_bparam.c wr_dumpset.c wr_exportfs.c wr_fstab.c CFLAGS+= -I${.CURDIR}/../../../contrib/amd/fsinfo -DPADD= ${LIBAMU} -LDADD= ${LIBAMU} +LIBADD= amu CLEANFILES+= fsi_gram.c fsi_gram.h fsi_lex.c diff --git a/usr.sbin/amd/fsinfo/Makefile.depend b/usr.sbin/amd/fsinfo/Makefile.depend index bec1372..d78eb4f 100644 --- a/usr.sbin/amd/fsinfo/Makefile.depend +++ b/usr.sbin/amd/fsinfo/Makefile.depend @@ -14,6 +14,7 @@ DIRDEPS = \ lib/libc \ lib/libcompiler_rt \ lib/libwrap \ + usr.bin/yacc.host \ usr.sbin/amd/include \ usr.sbin/amd/libamu \ diff --git a/usr.sbin/amd/hlfsd/Makefile b/usr.sbin/amd/hlfsd/Makefile index 5b863dd..96d05c4 100644 --- a/usr.sbin/amd/hlfsd/Makefile +++ b/usr.sbin/amd/hlfsd/Makefile @@ -13,7 +13,6 @@ SRCS= hlfsd.c homedir.c nfs_prot_svc.c stubs.c CFLAGS+= -I${.CURDIR}/../../../contrib/amd/hlfsd -DPADD= ${LIBAMU} -LDADD= ${LIBAMU} +LIBADD= amu .include <bsd.prog.mk> diff --git a/usr.sbin/amd/include/Makefile.depend b/usr.sbin/amd/include/Makefile.depend index 18f420a..57b7e10 100644 --- a/usr.sbin/amd/include/Makefile.depend +++ b/usr.sbin/amd/include/Makefile.depend @@ -3,7 +3,6 @@ DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} DIRDEPS = \ - bin/cat.host \ .include <dirdeps.mk> diff --git a/usr.sbin/amd/include/config.h b/usr.sbin/amd/include/config.h index 5817a46..cffb82a 100644 --- a/usr.sbin/amd/include/config.h +++ b/usr.sbin/amd/include/config.h @@ -668,9 +668,6 @@ /* Define to 1 if you have the <net/if.h> header file. */ #define HAVE_NET_IF_H 1 -/* Define to 1 if you have the <net/if_var.h> header file. */ -#define HAVE_NET_IF_VAR_H 1 - /* Define to 1 if you have the <net/route.h> header file. */ #define HAVE_NET_ROUTE_H 1 diff --git a/usr.sbin/amd/mk-amd-map/Makefile b/usr.sbin/amd/mk-amd-map/Makefile index 57fd6a5..417ea2a 100644 --- a/usr.sbin/amd/mk-amd-map/Makefile +++ b/usr.sbin/amd/mk-amd-map/Makefile @@ -10,7 +10,6 @@ PROG= mk-amd-map MAN= mk-amd-map.8 -DPADD= ${LIBAMU} -LDADD= ${LIBAMU} +LIBADD= amu .include <bsd.prog.mk> diff --git a/usr.sbin/amd/pawd/Makefile b/usr.sbin/amd/pawd/Makefile index c6bb1cc..2870ab4 100644 --- a/usr.sbin/amd/pawd/Makefile +++ b/usr.sbin/amd/pawd/Makefile @@ -14,7 +14,6 @@ SRCS= pawd.c amq_clnt.c amq_xdr.c CFLAGS+= -I${.CURDIR}/../../../contrib/amd/amq -DPADD= ${LIBAMU} -LDADD= ${LIBAMU} +LIBADD= amu .include <bsd.prog.mk> diff --git a/usr.sbin/amd/wire-test/Makefile b/usr.sbin/amd/wire-test/Makefile index a07e690..edde2eb 100644 --- a/usr.sbin/amd/wire-test/Makefile +++ b/usr.sbin/amd/wire-test/Makefile @@ -10,7 +10,6 @@ PROG= wire-test MAN= wire-test.8 -DPADD= ${LIBAMU} -LDADD= ${LIBAMU} +LIBADD= amu .include <bsd.prog.mk> diff --git a/usr.sbin/ancontrol/Makefile b/usr.sbin/ancontrol/Makefile index b0f66cd..f06b943 100644 --- a/usr.sbin/ancontrol/Makefile +++ b/usr.sbin/ancontrol/Makefile @@ -6,7 +6,6 @@ MAN= ancontrol.8 WARNS?= 3 CFLAGS+= -DANCACHE -I${.CURDIR}/../../sys -DPADD= ${LIBMD} -LDADD= -lmd +LIBADD= md .include <bsd.prog.mk> diff --git a/usr.sbin/ancontrol/ancontrol.c b/usr.sbin/ancontrol/ancontrol.c index 839cdcb..4ff32ff 100644 --- a/usr.sbin/ancontrol/ancontrol.c +++ b/usr.sbin/ancontrol/ancontrol.c @@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$"); #include <arpa/inet.h> #include <net/if.h> -#include <net/if_var.h> #include <net/ethernet.h> #include <dev/an/if_aironet_ieee.h> diff --git a/usr.sbin/apmd/Makefile b/usr.sbin/apmd/Makefile index 9a0dc0d..b2afdfaf 100644 --- a/usr.sbin/apmd/Makefile +++ b/usr.sbin/apmd/Makefile @@ -7,8 +7,7 @@ SRCS= apmd.c apmdlex.l apmdparse.y y.tab.h WARNS?= 3 -DPADD= ${LIBL} -LDADD= -ll +LIBADD= l CFLAGS+= -I${.CURDIR} diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c index 932ac95..60f776f 100644 --- a/usr.sbin/arp/arp.c +++ b/usr.sbin/arp/arp.c @@ -282,6 +282,7 @@ valid_type(int type) switch (type) { case IFT_ETHER: case IFT_FDDI: + case IFT_INFINIBAND: case IFT_ISO88023: case IFT_ISO88024: case IFT_ISO88025: @@ -656,6 +657,9 @@ print_entry(struct sockaddr_dl *sdl, case IFT_BRIDGE: printf(" [bridge]"); break; + case IFT_INFINIBAND: + printf(" [infiniband]"); + break; default: break; } diff --git a/usr.sbin/asf/Makefile b/usr.sbin/asf/Makefile index 0db69e8..49f9305 100644 --- a/usr.sbin/asf/Makefile +++ b/usr.sbin/asf/Makefile @@ -4,7 +4,6 @@ PROG= asf SRCS= asf.c asf_kld.c asf_kvm.c asf_prog.c MAN= asf.8 -DPADD= ${LIBKVM} -LDADD= -lkvm +LIBADD= kvm .include <bsd.prog.mk> diff --git a/usr.sbin/audit/Makefile b/usr.sbin/audit/Makefile index a3f7fbf..14fc893 100644 --- a/usr.sbin/audit/Makefile +++ b/usr.sbin/audit/Makefile @@ -10,8 +10,7 @@ CFLAGS+= -I${OPENBSMDIR} PROG= audit MAN= audit.8 -DPADD= ${LIBBSM} -LDADD= -lbsm +LIBADD= bsm WARNS?= 5 diff --git a/usr.sbin/auditd/Makefile b/usr.sbin/auditd/Makefile index 47ffd0b..3fb6a40 100644 --- a/usr.sbin/auditd/Makefile +++ b/usr.sbin/auditd/Makefile @@ -11,8 +11,7 @@ PROG= auditd SRCS= auditd.c audit_warn.c auditd_fbsd.c MAN= auditd.8 -DPADD= ${LIBAUDITD} ${LIBBSM} -LDADD= -lauditd -lbsm +LIBADD= auditd bsm WARNS?= 3 diff --git a/usr.sbin/auditdistd/Makefile b/usr.sbin/auditdistd/Makefile index b323dcd..8d32884 100644 --- a/usr.sbin/auditdistd/Makefile +++ b/usr.sbin/auditdistd/Makefile @@ -21,10 +21,7 @@ SRCS+= sandbox.c sender.c subr.c SRCS+= token.l trail.c MAN= auditdistd.8 auditdistd.conf.5 -DPADD= ${LIBL} ${LIBPTHREAD} ${LIBUTIL} -LDADD= -ll -lpthread -lutil -DPADD+= ${LIBCRYPTO} ${LIBSSL} -LDADD+= -lcrypto -lssl +LIBADD+= l pthread util crypto ssl YFLAGS+=-v diff --git a/usr.sbin/auditreduce/Makefile b/usr.sbin/auditreduce/Makefile index 7dc9553..a462e1b 100644 --- a/usr.sbin/auditreduce/Makefile +++ b/usr.sbin/auditreduce/Makefile @@ -10,8 +10,7 @@ CFLAGS+= -I${OPENBSMDIR} PROG= auditreduce MAN= auditreduce.1 -DPADD= ${LIBBSM} -LDADD= -lbsm +LIBADD= bsm WARNS?= 3 diff --git a/usr.sbin/authpf/Makefile b/usr.sbin/authpf/Makefile index 744df61..be95a4b 100644 --- a/usr.sbin/authpf/Makefile +++ b/usr.sbin/authpf/Makefile @@ -13,8 +13,7 @@ SRCS= authpf.c # XXX ALTQ: CFLAGS+= -DENABLE_ALTQ -LDADD+= -lm -lmd -lutil -DPADD+= ${LIBM} ${LIBMD} ${LIBUTIL} +LIBADD= m util WARNS?= 3 diff --git a/usr.sbin/authpf/Makefile.depend b/usr.sbin/authpf/Makefile.depend index b28c0ae..ef2646c 100644 --- a/usr.sbin/authpf/Makefile.depend +++ b/usr.sbin/authpf/Makefile.depend @@ -11,7 +11,6 @@ DIRDEPS = \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ - lib/libmd \ lib/libutil \ lib/msun \ diff --git a/usr.sbin/autofs/Makefile b/usr.sbin/autofs/Makefile index fab6865..00c79dd 100644 --- a/usr.sbin/autofs/Makefile +++ b/usr.sbin/autofs/Makefile @@ -16,8 +16,7 @@ CFLAGS+=-I${.CURDIR}/../../sys/fs/autofs MAN= automount.8 automountd.8 autounmountd.8 auto_master.5 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util # Needed for getmntopts.c MOUNT= ${.CURDIR}/../../sbin/mount diff --git a/usr.sbin/autofs/auto_master.5 b/usr.sbin/autofs/auto_master.5 index 892ce32..89100f7 100644 --- a/usr.sbin/autofs/auto_master.5 +++ b/usr.sbin/autofs/auto_master.5 @@ -27,13 +27,17 @@ .\" .\" $FreeBSD$ .\" -.Dd November 17, 2014 +.Dd March 13, 2015 .Dt AUTO_MASTER 5 .Os .Sh NAME .Nm auto_master .Nd auto_master and map file format .Sh DESCRIPTION +The automounter configuration consists of the +.Nm +configuration file, which assigns filesystem paths to map names, +and maps, which contain actual mount information. The .Nm configuration file is used by the @@ -120,6 +124,12 @@ is the path component used by .Xr automountd 8 to find the right map entry to use. It is also used to form the final mountpoint. +A wildcard +.Pq Ql * +can be used for the key. +It matches every directory that does not match other keys. +Those directories will not be visible to the user +until accessed. .Pp The .Ar options @@ -132,8 +142,12 @@ The special option .Li fstype is used to specify filesystem type. It is not passed to the mount program as an option. -Instead, it is passed as argument to +Instead, it is passed as an argument to .Cm "mount -t". +The default +.Li fstype +is +.Ql nfs . The special option .Li nobrowse is used to disable creation of top-level directories for special @@ -147,15 +161,64 @@ for a single key. The .Ar location field specifies the filesystem to be mounted. -To pass location that begins with +Ampersands +.Pq Ql & +in the +.Ar location +field are replaced with the value of +.Ar key . +This is typically used with wildcards, like: +.Bd -literal -offset indent +.Li * 192.168.1.1:/share/& +.Ed +.Pp +The +.Ar location +field may contain references to variables, like: +.Bd -literal -offset indent +.Li sys 192.168.1.1:/sys/${OSNAME} +.Ed +.Pp +Defined variables are: +.Pp +.Bl -tag -width "-OSNAME" -compact +.It Li ARCH +Expands to the output of +.Li "uname -p" . +.It Li CPU +Same as ARCH. +.It Li HOST +Expands to the output of +.Li "uname -n" . +.It Li OSNAME +Expands to the output of +.Li "uname -s" . +.It Li OSREL +Expands to the output of +.Li "uname -r" . +.It Li OSVERS +Expands to the output of +.Li "uname -v" . +.El +.Pp +Additional variables can be defined with the +.Fl D +option of +.Xr automount 8 +and +.Xr automountd 8 . +.Pp +To pass a location that begins with .Li / , -prefix it with colon. +prefix it with a colon. For example, .Li :/dev/cd0 . .Pp -This example, when used with the +This example, when put into +.Pa /etc/auto_example , +and with .Nm -example above, specifies that the NFS share +referring to the map as described above, specifies that the NFS share .Li 192.168.1.1:/share/example/x will be mounted on .Pa /example/x/ @@ -163,11 +226,18 @@ when any process attempts to access that mountpoint, with .Li intr and .Li nfsv4 -mount options: +mount options, described in +.Xr mount_nfs 8 : .Bd -literal -offset indent .Li x -intr,nfsv4 192.168.1.1:/share/example/x .Ed .Pp +Automatically mount an SMB share on access, as a guest user, +without prompting for a password: +.Bd -literal -offset indent +.Li share -fstype=smbfs,-N ://@server/share +.Ed +.Pp Automatically mount the CD drive on access: .Bd -literal -offset indent .Li cd -fstype=cd9660 :/dev/cd0 @@ -179,24 +249,48 @@ Supported special maps are: .Pp .Bl -tag -width "-hosts" -compact .It Li -hosts -This map queries the remote NFS server and maps exported volumes. -It is traditionally mounted on +Query the remote NFS server and map exported shares. +This map is traditionally mounted on .Pa /net . -It enables access to files on a remote NFS server by accessing -.Pa /net/nfs-server-ip/share-name/ -directory, without the need for any further configuration. +Access to files on a remote NFS server is provided through the +.Pf /net/ Ar nfs-server-ip Ns / Ns Ar share-name Ns/ +directory without any additional configuration. +Directories for individual NFS servers are not present until the first access, +when they are automatically created. +.It Li -media +Query devices that are not yet mounted, but contain valid filesystems. +Generally used to access files on removable media. +.It Li -noauto +Mount filesystems configured in +.Xr fstab 5 +as "noauto". +This needs to be set up as a direct map. .It Li -null -This map prevents the +Prevent .Xr automountd 8 from mounting anything on the mountpoint. .El +.Pp +It is possible to add custom special maps by adding them, as executable +maps named +.Pa special_foo , +to the +.Pa /etc/autofs/ +directory. .Sh EXECUTABLE MAPS If the map file specified in .Nm -has execute bit set, the +has the execute bit set, .Xr automountd 8 will execute it and parse the standard output instead of parsing the file contents. +When called without command line arguments, the executable is +expected to output a list of available map keys separated by +newline characters. +Otherwise, the executable will be called with a key name as +a command line argument. +Output from the executable is expected to be the entry for that key, +not including the key itself. .Sh INDIRECT VERSUS DIRECT MAPS Indirect maps are referred to in .Nm @@ -224,6 +318,7 @@ and this in map file: .Bd -literal -offset indent .Li /example/x -intr,nfsv4 192.168.1.1:/share/example/x +.Li /example/share -fstype=smbfs,-N ://@server/share .Li /example/cd -fstype=cd9660 :/dev/cd0 .Ed .Sh DIRECTORY SERVICES @@ -262,6 +357,9 @@ It can be symlinked to The default location of the .Pa auto_master file. +.It Pa /etc/autofs/ +Directory containing shell scripts to implement special maps and directory +services. .El .Sh SEE ALSO .Xr autofs 5 , diff --git a/usr.sbin/autofs/automount.8 b/usr.sbin/autofs/automount.8 index 2988c68..c111a99 100644 --- a/usr.sbin/autofs/automount.8 +++ b/usr.sbin/autofs/automount.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 20, 2014 +.Dd November 22, 2014 .Dt AUTOMOUNT 8 .Os .Sh NAME @@ -37,6 +37,7 @@ .Nm .Op Fl D Ar name=value .Op Fl L +.Op Fl c .Op Fl f .Op Fl o Ar options .Op Fl v @@ -64,6 +65,9 @@ and any direct maps, then print them to standard output. When specified more than once, all the maps, including indirect ones, will be parsed and shown. This is useful when debugging configuration problems. +.It Fl c +Flush caches, discarding possibly stale information obtained from maps +and directory services. .It Fl f Force unmount, to be used with .Fl u . diff --git a/usr.sbin/autofs/automount.c b/usr.sbin/autofs/automount.c index a956b08..ce5d861 100644 --- a/usr.sbin/autofs/automount.c +++ b/usr.sbin/autofs/automount.c @@ -141,8 +141,8 @@ mount_autofs(const char *from, const char *fspath, const char *options, } static void -mount_if_not_already(const struct node *n, const char *map, - const struct statfs *mntbuf, int nitems) +mount_if_not_already(const struct node *n, const char *map, const char *options, + const char *prefix, const struct statfs *mntbuf, int nitems) { const struct statfs *sb; char *mountpoint; @@ -175,7 +175,7 @@ mount_if_not_already(const struct node *n, const char *map, mountpoint); } - mount_autofs(from, mountpoint, n->n_options, n->n_key); + mount_autofs(from, mountpoint, options, prefix); free(from); free(mountpoint); } @@ -184,7 +184,7 @@ static void mount_unmount(struct node *root) { struct statfs *mntbuf; - struct node *n, *n2, *n3; + struct node *n, *n2; int i, nitems; nitems = getmntinfo(&mntbuf, MNT_WAIT); @@ -216,20 +216,70 @@ mount_unmount(struct node *root) TAILQ_FOREACH(n, &root->n_children, n_next) { if (!node_is_direct_map(n)) { - mount_if_not_already(n, n->n_map, mntbuf, nitems); + mount_if_not_already(n, n->n_map, n->n_options, + n->n_key, mntbuf, nitems); continue; } TAILQ_FOREACH(n2, &n->n_children, n_next) { - TAILQ_FOREACH(n3, &n2->n_children, n_next) { - mount_if_not_already(n3, n->n_map, - mntbuf, nitems); - } + mount_if_not_already(n2, n->n_map, n->n_options, + "/", mntbuf, nitems); } } } static void +flush_autofs(const char *fspath) +{ + struct iovec *iov = NULL; + char errmsg[255]; + int error, iovlen = 0; + + log_debugx("flushing %s", fspath); + memset(errmsg, 0, sizeof(errmsg)); + + build_iovec(&iov, &iovlen, "fstype", + __DECONST(void *, "autofs"), (size_t)-1); + build_iovec(&iov, &iovlen, "fspath", + __DECONST(void *, fspath), (size_t)-1); + build_iovec(&iov, &iovlen, "errmsg", + errmsg, sizeof(errmsg)); + + error = nmount(iov, iovlen, MNT_UPDATE); + if (error != 0) { + if (*errmsg != '\0') { + log_err(1, "cannot flush %s: %s", + fspath, errmsg); + } else { + log_err(1, "cannot flush %s", fspath); + } + } +} + +static void +flush_caches(void) +{ + struct statfs *mntbuf; + int i, nitems; + + nitems = getmntinfo(&mntbuf, MNT_WAIT); + if (nitems <= 0) + log_err(1, "getmntinfo"); + + log_debugx("flushing autofs caches"); + + for (i = 0; i < nitems; i++) { + if (strcmp(mntbuf[i].f_fstypename, "autofs") != 0) { + log_debugx("skipping %s, filesystem type is not autofs", + mntbuf[i].f_mntonname); + continue; + } + + flush_autofs(mntbuf[i].f_mntonname); + } +} + +static void unmount_automounted(bool force) { struct statfs *mntbuf; @@ -262,7 +312,7 @@ static void usage_automount(void) { - fprintf(stderr, "usage: automount [-D name=value][-o opts][-Lfuv]\n"); + fprintf(stderr, "usage: automount [-D name=value][-o opts][-Lcfuv]\n"); exit(1); } @@ -272,7 +322,7 @@ main_automount(int argc, char **argv) struct node *root; int ch, debug = 0, show_maps = 0; char *options = NULL; - bool do_unmount = false, force_unmount = false; + bool do_unmount = false, force_unmount = false, flush = false; /* * Note that in automount(8), the only purpose of variable @@ -280,7 +330,7 @@ main_automount(int argc, char **argv) */ defined_init(); - while ((ch = getopt(argc, argv, "D:Lfo:uv")) != -1) { + while ((ch = getopt(argc, argv, "D:Lfco:uv")) != -1) { switch (ch) { case 'D': defined_parse_and_add(optarg); @@ -288,16 +338,14 @@ main_automount(int argc, char **argv) case 'L': show_maps++; break; + case 'c': + flush = true; + break; case 'f': force_unmount = true; break; case 'o': - if (options == NULL) { - options = checked_strdup(optarg); - } else { - options = - separated_concat(options, optarg, ','); - } + options = concat(options, ',', optarg); break; case 'u': do_unmount = true; @@ -319,6 +367,11 @@ main_automount(int argc, char **argv) log_init(debug); + if (flush) { + flush_caches(); + return (0); + } + if (do_unmount) { unmount_automounted(force_unmount); return (0); @@ -328,16 +381,12 @@ main_automount(int argc, char **argv) parse_master(root, AUTO_MASTER_PATH); if (show_maps) { - if (options != NULL) { - root->n_options = separated_concat(options, - root->n_options, ','); - } if (show_maps > 1) { node_expand_indirect_maps(root); node_expand_ampersand(root, NULL); } node_expand_defined(root); - node_print(root); + node_print(root, options); return (0); } diff --git a/usr.sbin/autofs/automountd.8 b/usr.sbin/autofs/automountd.8 index 31fc8f2..175633b 100644 --- a/usr.sbin/autofs/automountd.8 +++ b/usr.sbin/autofs/automountd.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 20, 2014 +.Dd March 10, 2015 .Dt AUTOMOUNTD 8 .Os .Sh NAME @@ -78,7 +78,7 @@ The default is 30. Debug mode: increase verbosity and do not daemonize. .It Fl o Ar options Specify mount options. -Options specified here ill be overridden by options entered in maps or +Options specified here will be overridden by options entered in maps or .Xr auto_master 5 . .It Fl v Increase verbosity. diff --git a/usr.sbin/autofs/automountd.c b/usr.sbin/autofs/automountd.c index 44143e5..2c9b1a9 100644 --- a/usr.sbin/autofs/automountd.c +++ b/usr.sbin/autofs/automountd.c @@ -82,14 +82,8 @@ done(int request_error, bool wildcards) request_id, request_error); error = ioctl(autofs_fd, AUTOFSDONE, &add); - if (error != 0) { - /* - * Do this instead of log_err() to avoid calling - * done() again with error, from atexit handler. - */ + if (error != 0) log_warn("AUTOFSDONE"); - } - quick_exit(1); } /* @@ -183,7 +177,7 @@ handle_request(const struct autofs_daemon_request *adr, char *cmdline_options, const char *map; struct node *root, *parent, *node; FILE *f; - char *options, *fstype, *nobrowse, *retrycnt, *tmp; + char *key, *options, *fstype, *nobrowse, *retrycnt, *tmp; int error; bool wildcards; @@ -205,11 +199,25 @@ handle_request(const struct autofs_daemon_request *adr, char *cmdline_options, map = adr->adr_from + 4; /* 4 for strlen("map "); */ root = node_new_root(); if (adr->adr_prefix[0] == '\0' || strcmp(adr->adr_prefix, "/") == 0) { + /* + * Direct map. autofs(4) doesn't have a way to determine + * correct map key, but since it's a direct map, we can just + * use adr_path instead. + */ parent = root; + key = checked_strdup(adr->adr_path); } else { + /* + * Indirect map. + */ parent = node_new_map(root, checked_strdup(adr->adr_prefix), - checked_strdup(adr->adr_options), checked_strdup(map), + NULL, checked_strdup(map), checked_strdup("[kernel request]"), lineno); + + if (adr->adr_key[0] == '\0') + key = NULL; + else + key = checked_strdup(adr->adr_key); } /* @@ -219,8 +227,7 @@ handle_request(const struct autofs_daemon_request *adr, char *cmdline_options, * needs to be done for maps with wildcard entries, but also * for special and executable maps. */ - parse_map(parent, map, adr->adr_key[0] != '\0' ? adr->adr_key : NULL, - &wildcards); + parse_map(parent, map, key, &wildcards); if (!wildcards) wildcards = node_has_wildcards(parent); if (wildcards) @@ -228,8 +235,8 @@ handle_request(const struct autofs_daemon_request *adr, char *cmdline_options, else log_debugx("map does not contain wildcard entries"); - if (adr->adr_key[0] != '\0') - node_expand_wildcard(root, adr->adr_key); + if (key != NULL) + node_expand_wildcard(root, key); node = node_find(root, adr->adr_path); if (node == NULL) { @@ -237,22 +244,24 @@ handle_request(const struct autofs_daemon_request *adr, char *cmdline_options, "failing mount", map, adr->adr_path); } + options = node_options(node); + + /* + * Append options from auto_master. + */ + options = concat(options, ',', adr->adr_options); + + /* + * Prepend options passed via automountd(8) command line. + */ + options = concat(cmdline_options, ',', options); + if (node->n_location == NULL) { log_debugx("found node defined at %s:%d; not a mountpoint", node->n_config_file, node->n_config_line); - options = node_options(node); - - /* - * Prepend options passed via automountd(8) command line. - */ - if (cmdline_options != NULL) { - options = - separated_concat(cmdline_options, options, ','); - } - nobrowse = pick_option("nobrowse", &options); - if (nobrowse != NULL && adr->adr_key[0] == '\0') { + if (nobrowse != NULL && key == NULL) { log_debugx("skipping map %s due to \"nobrowse\" " "option; exiting", map); done(0, true); @@ -269,13 +278,12 @@ handle_request(const struct autofs_daemon_request *adr, char *cmdline_options, */ create_subtree(node, incomplete_hierarchy); - if (incomplete_hierarchy && adr->adr_key[0] != '\0') { + if (incomplete_hierarchy && key != NULL) { /* * We still need to create the single subdirectory * user is trying to access. */ - tmp = separated_concat(adr->adr_path, - adr->adr_key, '/'); + tmp = concat(adr->adr_path, '/', key); node = node_find(root, tmp); if (node != NULL) create_subtree(node, false); @@ -293,26 +301,18 @@ handle_request(const struct autofs_daemon_request *adr, char *cmdline_options, log_debugx("found node defined at %s:%d; it is a mountpoint", node->n_config_file, node->n_config_line); - node_expand_ampersand(node, - adr->adr_key[0] != '\0' ? adr->adr_key : NULL); + if (key != NULL) + node_expand_ampersand(node, key); error = node_expand_defined(node); if (error != 0) { log_errx(1, "variable expansion failed for %s; " "failing mount", adr->adr_path); } - options = node_options(node); - - /* - * Prepend options passed via automountd(8) command line. - */ - if (cmdline_options != NULL) - options = separated_concat(cmdline_options, options, ','); - /* * Append "automounted". */ - options = separated_concat(options, "automounted", ','); + options = concat(options, ',', "automounted"); /* * Remove "nobrowse", mount(8) doesn't understand it. @@ -340,11 +340,10 @@ handle_request(const struct autofs_daemon_request *adr, char *cmdline_options, if (retrycnt == NULL) { log_debugx("retrycnt not specified in options; " "defaulting to 1"); - options = separated_concat(options, - separated_concat("retrycnt", "1", '='), ','); + options = concat(options, ',', "retrycnt=1"); } else { - options = separated_concat(options, - separated_concat("retrycnt", retrycnt, '='), ','); + options = concat(options, ',', + concat("retrycnt", '=', retrycnt)); } } @@ -468,12 +467,7 @@ main_automountd(int argc, char **argv) maxproc = atoi(optarg); break; case 'o': - if (options == NULL) { - options = checked_strdup(optarg); - } else { - options = - separated_concat(options, optarg, ','); - } + options = concat(options, ',', optarg); break; case 'v': debug++; diff --git a/usr.sbin/autofs/autounmountd.8 b/usr.sbin/autofs/autounmountd.8 index 1b5d9a8..bf7afa4 100644 --- a/usr.sbin/autofs/autounmountd.8 +++ b/usr.sbin/autofs/autounmountd.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 20, 2014 +.Dd December 13, 2014 .Dt AUTOUNMOUNTD 8 .Os .Sh NAME @@ -36,8 +36,8 @@ .Sh SYNOPSIS .Nm .Op Fl d -.Op Fl r time -.Op Fl t time +.Op Fl r Ar time +.Op Fl t Ar time .Op Fl v .Sh DESCRIPTION The diff --git a/usr.sbin/autofs/autounmountd.c b/usr.sbin/autofs/autounmountd.c index 0f52b66..b85f3ca 100644 --- a/usr.sbin/autofs/autounmountd.c +++ b/usr.sbin/autofs/autounmountd.c @@ -182,7 +182,7 @@ expire_automounted(double expiration_time) { struct automounted_fs *af, *tmpaf; time_t now; - double mounted_for, mounted_max = 0; + double mounted_for, mounted_max = -1.0; int error; now = time(NULL); @@ -231,21 +231,28 @@ do_wait(int kq, double sleep_time) { struct timespec timeout; struct kevent unused; - int error; - - assert(sleep_time > 0); - timeout.tv_sec = sleep_time; - timeout.tv_nsec = 0; - - log_debugx("waiting for filesystem event for %.0f seconds", sleep_time); - error = kevent(kq, NULL, 0, &unused, 1, &timeout); - if (error < 0) + int nevents; + + if (sleep_time != -1.0) { + assert(sleep_time > 0.0); + timeout.tv_sec = sleep_time; + timeout.tv_nsec = 0; + + log_debugx("waiting for filesystem event for %.0f seconds", sleep_time); + nevents = kevent(kq, NULL, 0, &unused, 1, &timeout); + } else { + log_debugx("waiting for filesystem event"); + nevents = kevent(kq, NULL, 0, &unused, 1, NULL); + } + if (nevents < 0) log_err(1, "kevent"); - if (error == 0) + if (nevents == 0) { log_debugx("timeout reached"); - else + assert(sleep_time > 0.0); + } else { log_debugx("got filesystem event"); + } } int @@ -324,7 +331,10 @@ main_autounmountd(int argc, char **argv) for (;;) { refresh_automounted(); mounted_max = expire_automounted(expiration_time); - if (mounted_max < expiration_time) { + if (mounted_max == -1.0) { + sleep_time = mounted_max; + log_debugx("no filesystems to expire"); + } else if (mounted_max < expiration_time) { sleep_time = difftime(expiration_time, mounted_max); log_debugx("some filesystems expire in %.0f seconds", sleep_time); diff --git a/usr.sbin/autofs/common.c b/usr.sbin/autofs/common.c index 6fd8a05..eae118f 100644 --- a/usr.sbin/autofs/common.c +++ b/usr.sbin/autofs/common.c @@ -86,58 +86,36 @@ checked_strdup(const char *s) } /* - * Take two pointers to strings, concatenate the contents with "/" in the - * middle, make the first pointer point to the result, the second pointer - * to NULL, and free the old strings. - * - * Concatenate pathnames, basically. - */ -static void -concat(char **p1, char **p2) -{ - int ret; - char *path; - - assert(p1 != NULL); - assert(p2 != NULL); - - if (*p1 == NULL) - *p1 = checked_strdup(""); - - if (*p2 == NULL) - *p2 = checked_strdup(""); - - ret = asprintf(&path, "%s/%s", *p1, *p2); - if (ret < 0) - log_err(1, "asprintf"); - - /* - * XXX - */ - //free(*p1); - //free(*p2); - - *p1 = path; - *p2 = NULL; -} - -/* * Concatenate two strings, inserting separator between them, unless not needed. - * - * This function is very convenient to use when you do not care about freeing - * memory - which is okay here, because we are a short running process. */ char * -separated_concat(const char *s1, const char *s2, char separator) +concat(const char *s1, char separator, const char *s2) { char *result; + char s1last, s2first; int ret; - assert(s1 != NULL); - assert(s2 != NULL); + if (s1 == NULL) + s1 = ""; + if (s2 == NULL) + s2 = ""; - if (s1[0] == '\0' || s2[0] == '\0' || - s1[strlen(s1) - 1] == separator || s2[0] == separator) { + if (s1[0] == '\0') + s1last = '\0'; + else + s1last = s1[strlen(s1) - 1]; + + s2first = s2[0]; + + if (s1last == separator && s2first == separator) { + /* + * If s1 ends with the separator and s2 begins with + * it - skip the latter; otherwise concatenating "/" + * and "/foo" would end up returning "//foo". + */ + ret = asprintf(&result, "%s%s", s1, s2 + 1); + } else if (s1last == separator || s2first == separator || + s1[0] == '\0' || s2[0] == '\0') { ret = asprintf(&result, "%s%s", s1, s2); } else { ret = asprintf(&result, "%s%c%s", s1, separator, s2); @@ -145,7 +123,7 @@ separated_concat(const char *s1, const char *s2, char separator) if (ret < 0) log_err(1, "asprintf"); - //log_debugx("separated_concat: got %s and %s, returning %s", s1, s2, result); + //log_debugx("%s: got %s and %s, returning %s", __func__, s1, s2, result); return (result); } @@ -153,7 +131,7 @@ separated_concat(const char *s1, const char *s2, char separator) void create_directory(const char *path) { - char *component, *copy, *tofree, *partial; + char *component, *copy, *tofree, *partial, *tmp; int error; assert(path[0] == '/'); @@ -163,12 +141,14 @@ create_directory(const char *path) */ copy = tofree = checked_strdup(path + 1); - partial = NULL; + partial = checked_strdup(""); for (;;) { component = strsep(©, "/"); if (component == NULL) break; - concat(&partial, &component); + tmp = concat(partial, '/', component); + free(partial); + partial = tmp; //log_debugx("creating \"%s\"", partial); error = mkdir(partial, 0755); if (error != 0 && errno != EEXIST) { @@ -480,6 +460,18 @@ node_expand_defined(struct node *n) return (cumulated_error); } +static bool +node_is_direct_key(const struct node *n) +{ + + if (n->n_parent != NULL && n->n_parent->n_parent == NULL && + strcmp(n->n_key, "/-") == 0) { + return (true); + } + + return (false); +} + bool node_is_direct_map(const struct node *n) { @@ -491,11 +483,7 @@ node_is_direct_map(const struct node *n) n = n->n_parent; } - assert(n->n_key != NULL); - if (strcmp(n->n_key, "/-") != 0) - return (false); - - return (true); + return (node_is_direct_key(n)); } bool @@ -561,7 +549,6 @@ static char * node_path_x(const struct node *n, char *x) { char *path; - size_t len; if (n->n_parent == NULL) return (x); @@ -570,24 +557,13 @@ node_path_x(const struct node *n, char *x) * Return "/-" for direct maps only if we were asked for path * to the "/-" node itself, not to any of its subnodes. */ - if (n->n_parent->n_parent == NULL && - strcmp(n->n_key, "/-") == 0 && - x[0] != '\0') { + if (node_is_direct_key(n) && x[0] != '\0') return (x); - } assert(n->n_key[0] != '\0'); - path = separated_concat(n->n_key, x, '/'); + path = concat(n->n_key, '/', x); free(x); - /* - * Strip trailing slash. - */ - len = strlen(path); - assert(len > 0); - if (path[len - 1] == '/') - path[len - 1] = '\0'; - return (node_path_x(n->n_parent, path)); } @@ -598,8 +574,19 @@ node_path_x(const struct node *n, char *x) char * node_path(const struct node *n) { + char *path; + size_t len; - return (node_path_x(n, checked_strdup(""))); + path = node_path_x(n, checked_strdup("")); + + /* + * Strip trailing slash, unless the whole path is "/". + */ + len = strlen(path); + if (len > 1 && path[len - 1] == '/') + path[len - 1] = '\0'; + + return (path); } static char * @@ -607,9 +594,11 @@ node_options_x(const struct node *n, char *x) { char *options; - options = separated_concat(x, n->n_options, ','); - if (n->n_parent == NULL) - return (options); + if (n == NULL) + return (x); + + options = concat(x, ',', n->n_options); + free(x); return (node_options_x(n->n_parent, options)); } @@ -627,13 +616,16 @@ node_options(const struct node *n) } static void -node_print_indent(const struct node *n, int indent) +node_print_indent(const struct node *n, const char *cmdline_options, + int indent) { const struct node *child, *first_child; - char *path, *options; + char *path, *options, *tmp; path = node_path(n); - options = node_options(n); + tmp = node_options(n); + options = concat(cmdline_options, ',', tmp); + free(tmp); /* * Do not show both parent and child node if they have the same @@ -664,49 +656,73 @@ node_print_indent(const struct node *n, int indent) free(options); TAILQ_FOREACH(child, &n->n_children, n_next) - node_print_indent(child, indent + 2); + node_print_indent(child, cmdline_options, indent + 2); } +/* + * Recursively print node with all its children. The cmdline_options + * argument is used for additional options to be prepended to all the + * others - usually those are the options passed by command line. + */ void -node_print(const struct node *n) +node_print(const struct node *n, const char *cmdline_options) { const struct node *child; TAILQ_FOREACH(child, &n->n_children, n_next) - node_print_indent(child, 0); + node_print_indent(child, cmdline_options, 0); } -struct node * -node_find(struct node *node, const char *path) +static struct node * +node_find_x(struct node *node, const char *path) { struct node *child, *found; char *tmp; size_t tmplen; - //log_debugx("looking up %s in %s", path, node->n_key); + //log_debugx("looking up %s in %s", path, node_path(node)); - tmp = node_path(node); - tmplen = strlen(tmp); - if (strncmp(tmp, path, tmplen) != 0) { - free(tmp); - return (NULL); - } - if (path[tmplen] != '/' && path[tmplen] != '\0') { - /* - * If we have two map entries like 'foo' and 'foobar', make - * sure the search for 'foobar' won't match 'foo' instead. - */ + if (!node_is_direct_key(node)) { + tmp = node_path(node); + tmplen = strlen(tmp); + if (strncmp(tmp, path, tmplen) != 0) { + free(tmp); + return (NULL); + } + if (path[tmplen] != '/' && path[tmplen] != '\0') { + /* + * If we have two map entries like 'foo' and 'foobar', make + * sure the search for 'foobar' won't match 'foo' instead. + */ + free(tmp); + return (NULL); + } free(tmp); - return (NULL); } - free(tmp); TAILQ_FOREACH(child, &node->n_children, n_next) { - found = node_find(child, path); + found = node_find_x(child, path); if (found != NULL) return (found); } + if (node->n_parent == NULL || node_is_direct_key(node)) + return (NULL); + + return (node); +} + +struct node * +node_find(struct node *root, const char *path) +{ + struct node *node; + + assert(root->n_parent == NULL); + + node = node_find_x(root, path); + if (node != NULL) + assert(node != root); + return (node); } diff --git a/usr.sbin/autofs/common.h b/usr.sbin/autofs/common.h index 16a8d73..dc84415 100644 --- a/usr.sbin/autofs/common.h +++ b/usr.sbin/autofs/common.h @@ -70,7 +70,7 @@ void log_warnx(const char *, ...) __printflike(1, 2); void log_debugx(const char *, ...) __printf0like(1, 2); char *checked_strdup(const char *); -char *separated_concat(const char *s1, const char *s2, char separator); +char *concat(const char *s1, char separator, const char *s2); void create_directory(const char *path); struct node *node_new_root(void); @@ -87,7 +87,7 @@ void node_expand_ampersand(struct node *root, const char *key); void node_expand_wildcard(struct node *root, const char *key); int node_expand_defined(struct node *root); void node_expand_indirect_maps(struct node *n); -void node_print(const struct node *n); +void node_print(const struct node *n, const char *cmdline_options); void parse_master(struct node *root, const char *path); void parse_map(struct node *parent, const char *map, const char *args, bool *wildcards); diff --git a/usr.sbin/autofs/popen.c b/usr.sbin/autofs/popen.c index 6cd964d..e114880 100644 --- a/usr.sbin/autofs/popen.c +++ b/usr.sbin/autofs/popen.c @@ -104,7 +104,7 @@ auto_popen(const char *argv0, ...) if (arg == NULL) break; - command = separated_concat(command, arg, ' '); + command = concat(command, ' ', arg); } va_end(ap); diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile index 377a2e6..bb81bcb 100644 --- a/usr.sbin/bhyve/Makefile +++ b/usr.sbin/bhyve/Makefile @@ -4,7 +4,7 @@ PROG= bhyve -DEBUG_FLAGS= -g -O0 +DEBUG_FLAGS= -g -O0 MAN= bhyve.8 @@ -43,8 +43,7 @@ SRCS= \ .PATH: ${.CURDIR}/../../sys/amd64/vmm SRCS+= vmm_instruction_emul.c -DPADD= ${LIBVMMAPI} ${LIBMD} ${LIBUTIL} ${LIBPTHREAD} -LDADD= -lvmmapi -lmd -lutil -lpthread +LIBADD= vmmapi md pthread WARNS?= 2 diff --git a/usr.sbin/bhyve/acpi.c b/usr.sbin/bhyve/acpi.c index a5a6559..a9dd1cc 100644 --- a/usr.sbin/bhyve/acpi.c +++ b/usr.sbin/bhyve/acpi.c @@ -386,7 +386,7 @@ basl_fwrite_fadt(FILE *fp) EFPRINTF(fp, "[0001]\t\tDuty Cycle Width : 00\n"); EFPRINTF(fp, "[0001]\t\tRTC Day Alarm Index : 00\n"); EFPRINTF(fp, "[0001]\t\tRTC Month Alarm Index : 00\n"); - EFPRINTF(fp, "[0001]\t\tRTC Century Index : 00\n"); + EFPRINTF(fp, "[0001]\t\tRTC Century Index : 32\n"); EFPRINTF(fp, "[0002]\t\tBoot Flags (decoded below) : 0000\n"); EFPRINTF(fp, "\t\t\tLegacy Devices Supported (V2) : 0\n"); EFPRINTF(fp, "\t\t\t8042 Present on ports 60/64 (V2) : 0\n"); diff --git a/usr.sbin/bhyve/ahci.h b/usr.sbin/bhyve/ahci.h index 7101dc5..1fd9f20 100644 --- a/usr.sbin/bhyve/ahci.h +++ b/usr.sbin/bhyve/ahci.h @@ -96,13 +96,14 @@ #define ATA_SS_SPD_NO_SPEED 0x00000000 #define ATA_SS_SPD_GEN1 0x00000010 #define ATA_SS_SPD_GEN2 0x00000020 -#define ATA_SS_SPD_GEN3 0x00000040 +#define ATA_SS_SPD_GEN3 0x00000030 #define ATA_SS_IPM_MASK 0x00000f00 #define ATA_SS_IPM_NO_DEVICE 0x00000000 #define ATA_SS_IPM_ACTIVE 0x00000100 #define ATA_SS_IPM_PARTIAL 0x00000200 #define ATA_SS_IPM_SLUMBER 0x00000600 +#define ATA_SS_IPM_DEVSLEEP 0x00000800 #define ATA_SERROR 14 #define ATA_SE_DATA_CORRECTED 0x00000001 @@ -133,17 +134,19 @@ #define ATA_SC_SPD_NO_SPEED 0x00000000 #define ATA_SC_SPD_SPEED_GEN1 0x00000010 #define ATA_SC_SPD_SPEED_GEN2 0x00000020 -#define ATA_SC_SPD_SPEED_GEN3 0x00000040 +#define ATA_SC_SPD_SPEED_GEN3 0x00000030 #define ATA_SC_IPM_MASK 0x00000f00 #define ATA_SC_IPM_NONE 0x00000000 #define ATA_SC_IPM_DIS_PARTIAL 0x00000100 #define ATA_SC_IPM_DIS_SLUMBER 0x00000200 +#define ATA_SC_IPM_DIS_DEVSLEEP 0x00000400 #define ATA_SACTIVE 16 #define AHCI_MAX_PORTS 32 #define AHCI_MAX_SLOTS 32 +#define AHCI_MAX_IRQS 16 /* SATA AHCI v1.0 register defines */ #define AHCI_CAP 0x00 @@ -208,6 +211,9 @@ #define AHCI_CAP2_BOH 0x00000001 #define AHCI_CAP2_NVMP 0x00000002 #define AHCI_CAP2_APST 0x00000004 +#define AHCI_CAP2_SDS 0x00000008 +#define AHCI_CAP2_SADM 0x00000010 +#define AHCI_CAP2_DESO 0x00000020 #define AHCI_OFFSET 0x100 #define AHCI_STEP 0x80 @@ -265,6 +271,7 @@ #define AHCI_P_CMD_ACTIVE 0x10000000 #define AHCI_P_CMD_PARTIAL 0x20000000 #define AHCI_P_CMD_SLUMBER 0x60000000 +#define AHCI_P_CMD_DEVSLEEP 0x80000000 #define AHCI_P_TFD 0x20 #define AHCI_P_SIG 0x24 @@ -284,6 +291,17 @@ #define AHCI_P_FBS_ADO_SHIFT 12 #define AHCI_P_FBS_DWE 0x000f0000 #define AHCI_P_FBS_DWE_SHIFT 16 +#define AHCI_P_DEVSLP 0x44 +#define AHCI_P_DEVSLP_ADSE 0x00000001 +#define AHCI_P_DEVSLP_DSP 0x00000002 +#define AHCI_P_DEVSLP_DETO 0x000003fc +#define AHCI_P_DEVSLP_DETO_SHIFT 2 +#define AHCI_P_DEVSLP_MDAT 0x00007c00 +#define AHCI_P_DEVSLP_MDAT_SHIFT 10 +#define AHCI_P_DEVSLP_DITO 0x01ff8000 +#define AHCI_P_DEVSLP_DITO_SHIFT 15 +#define AHCI_P_DEVSLP_DM 0x0e000000 +#define AHCI_P_DEVSLP_DM_SHIFT 25 /* Just to be sure, if building as module. */ #if MAXPHYS < 512 * 1024 diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 index 755fa33..ee0f2ca 100644 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -32,7 +32,7 @@ .Nd "run a guest operating system inside a virtual machine" .Sh SYNOPSIS .Nm -.Op Fl abehwxACHPWY +.Op Fl abehuwxACHPWY .Op Fl c Ar numcpus .Op Fl g Ar gdbport .Op Fl l Ar lpcdev Ns Op , Ns Ar conf @@ -70,7 +70,8 @@ Required for guests. .It Fl b Enable a low-level console device supported by -.Fx kernels compiled with +.Fx +kernels compiled with .Cd "device bvmconsole" . This option will be deprecated in a future version. .It Fl c Ar numcpus @@ -192,8 +193,13 @@ format. .Pp Block storage devices: .Bl -tag -width 10n -.It Pa /filename Ns Oo , Ns Li nocache Oc Ns Oo , Ns Li direct Oc Ns Oo , Ns Li ro Oc -.It Pa /dev/xxx Ns Oo , Ns Ar nocache Oc Ns Oo , Ns Ar direct Oc Ns Oo , Ns Ar ro Oc +.It Pa /filename Ns Oo , Ns Ar block-device-options Oc +.It Pa /dev/xxx Ns Oo , Ns Ar block-device-options Oc +.El +.Pp +The +.Ar block-device-options +are: .Bl -tag -width 8n .It Li nocache Open the file with @@ -203,14 +209,10 @@ Open the file using .Dv O_SYNC . .It Li ro Force the file to be opened read-only. -.El -.Pp -The -.Li nocache , -.Li direct , -and -.Li ro -options are not available for virtio block devices. +.It Li sectorsize= Ns Ar logical Ns Oo / Ns Ar physical Oc +Specify the logical and physical sector sizes of the emulated disk. +The physical sector size is optional and is equal to the logical sector size +if not explicitly specified. .El .Pp TTY devices: @@ -238,6 +240,8 @@ The host device must have been reserved at boot-time using the loader variable as described in .Xr vmm 4 . .El +.It Fl u +RTC keeps UTC time. .It Fl U Ar uuid Set the universally unique identifier .Pq UUID diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c index 5971993..47a7699 100644 --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -122,7 +122,7 @@ usage(int code) { fprintf(stderr, - "Usage: %s [-abehwxACHPWY] [-c vcpus] [-g <gdb port>] [-l <lpc>]\n" + "Usage: %s [-abehuwxACHPWY] [-c vcpus] [-g <gdb port>] [-l <lpc>]\n" " %*s [-m mem] [-p vcpu:hostcpu] [-s <pci>] [-U uuid] <vm>\n" " -a: local apic is in xAPIC mode (deprecated)\n" " -A: create ACPI tables\n" @@ -137,6 +137,7 @@ usage(int code) " -p: pin 'vcpu' to 'hostcpu'\n" " -P: vmexit from the guest on pause\n" " -s: <slot,driver,configinfo> PCI slot config\n" + " -u: RTC keeps UTC time\n" " -U: uuid\n" " -w: ignore unimplemented MSRs\n" " -W: force virtio to use single-vector MSI\n" @@ -185,20 +186,14 @@ vm_inject_fault(void *arg, int vcpu, int vector, int errcode_valid, int errcode) { struct vmctx *ctx; - int error; + int error, restart_instruction; ctx = arg; - if (errcode_valid) - error = vm_inject_exception2(ctx, vcpu, vector, errcode); - else - error = vm_inject_exception(ctx, vcpu, vector); - assert(error == 0); + restart_instruction = 1; - /* - * Set the instruction length to 0 to ensure that the instruction is - * restarted when the fault handler returns. - */ - vmexit[vcpu].inst_length = 0; + error = vm_inject_exception(ctx, vcpu, vector, errcode_valid, errcode, + restart_instruction); + assert(error == 0); } void * @@ -329,15 +324,11 @@ vmexit_inout(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) } error = emulate_inout(ctx, vcpu, vme, strictio); - if (!error && in && !string) { - error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, - vme->u.inout.eax); - assert(error == 0); - } - if (error) { - fprintf(stderr, "Unhandled %s%c 0x%04x\n", in ? "in" : "out", - bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'), port); + fprintf(stderr, "Unhandled %s%c 0x%04x at 0x%lx\n", + in ? "in" : "out", + bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'), + port, vmexit->rip); return (VMEXIT_ABORT); } else { return (VMEXIT_CONTINUE); @@ -358,7 +349,7 @@ vmexit_rdmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) vme->u.msr.code, *pvcpu); if (strictmsr) { vm_inject_gp(ctx, *pvcpu); - return (VMEXIT_RESTART); + return (VMEXIT_CONTINUE); } } @@ -384,7 +375,7 @@ vmexit_wrmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) vme->u.msr.code, vme->u.msr.wval, *pvcpu); if (strictmsr) { vm_inject_gp(ctx, *pvcpu); - return (VMEXIT_RESTART); + return (VMEXIT_CONTINUE); } } return (VMEXIT_CONTINUE); @@ -462,9 +453,11 @@ static int vmexit_bogus(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) { + assert(vmexit->inst_length == 0); + stats.vmexit_bogus++; - return (VMEXIT_RESTART); + return (VMEXIT_CONTINUE); } static int @@ -494,30 +487,37 @@ static int vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) { + assert(vmexit->inst_length == 0); + stats.vmexit_mtrap++; - return (VMEXIT_RESTART); + return (VMEXIT_CONTINUE); } static int vmexit_inst_emul(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) { - int err; + int err, i; + struct vie *vie; + stats.vmexit_inst_emul++; + vie = &vmexit->u.inst_emul.vie; err = emulate_mem(ctx, *pvcpu, vmexit->u.inst_emul.gpa, - &vmexit->u.inst_emul.vie, &vmexit->u.inst_emul.paging); + vie, &vmexit->u.inst_emul.paging); if (err) { - if (err == EINVAL) { - fprintf(stderr, - "Failed to emulate instruction at 0x%lx\n", - vmexit->rip); - } else if (err == ESRCH) { + if (err == ESRCH) { fprintf(stderr, "Unhandled memory access to 0x%lx\n", vmexit->u.inst_emul.gpa); } + fprintf(stderr, "Failed to emulate instruction ["); + for (i = 0; i < vie->num_valid; i++) { + fprintf(stderr, "0x%02x%s", vie->inst[i], + i != (vie->num_valid - 1) ? " " : ""); + } + fprintf(stderr, "] at 0x%lx\n", vmexit->rip); return (VMEXIT_ABORT); } @@ -581,7 +581,7 @@ static vmexit_handler_t handler[VM_EXITCODE_MAX] = { }; static void -vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip) +vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip) { int error, rc, prevcpu; enum vm_exitcode exitcode; @@ -596,8 +596,11 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip) error = vm_active_cpus(ctx, &active_cpus); assert(CPU_ISSET(vcpu, &active_cpus)); + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, startrip); + assert(error == 0); + while (1) { - error = vm_run(ctx, vcpu, rip, &vmexit[vcpu]); + error = vm_run(ctx, vcpu, &vmexit[vcpu]); if (error != 0) break; @@ -614,10 +617,6 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip) switch (rc) { case VMEXIT_CONTINUE: - rip = vmexit[vcpu].rip + vmexit[vcpu].inst_length; - break; - case VMEXIT_RESTART: - rip = vmexit[vcpu].rip; break; case VMEXIT_ABORT: abort(); @@ -694,6 +693,7 @@ main(int argc, char *argv[]) { int c, error, gdb_port, err, bvmcons; int dump_guest_memory, max_vcpus, mptgen; + int rtc_localtime; struct vmctx *ctx; uint64_t rip; size_t memsize; @@ -705,8 +705,9 @@ main(int argc, char *argv[]) guest_ncpus = 1; memsize = 256 * MB; mptgen = 1; + rtc_localtime = 1; - while ((c = getopt(argc, argv, "abehwxACHIPWYp:g:c:s:m:l:U:")) != -1) { + while ((c = getopt(argc, argv, "abehuwxACHIPWYp:g:c:s:m:l:U:")) != -1) { switch (c) { case 'a': x2apic_mode = 0; @@ -766,6 +767,9 @@ main(int argc, char *argv[]) case 'e': strictio = 1; break; + case 'u': + rtc_localtime = 0; + break; case 'U': guest_uuid_str = optarg; break; @@ -801,6 +805,11 @@ main(int argc, char *argv[]) exit(1); } + if (guest_ncpus < 1) { + fprintf(stderr, "Invalid guest vCPUs (%d)\n", guest_ncpus); + exit(1); + } + max_vcpus = num_vcpus_allowed(ctx); if (guest_ncpus > max_vcpus) { fprintf(stderr, "%d vCPUs requested but only %d available\n", @@ -829,7 +838,7 @@ main(int argc, char *argv[]) pci_irq_init(ctx); ioapic_init(ctx); - rtc_init(ctx); + rtc_init(ctx, rtc_localtime); sci_init(ctx); /* diff --git a/usr.sbin/bhyve/bhyverun.h b/usr.sbin/bhyve/bhyverun.h index 87824ef..c51bf48 100644 --- a/usr.sbin/bhyve/bhyverun.h +++ b/usr.sbin/bhyve/bhyverun.h @@ -35,9 +35,8 @@ #define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] #endif -#define VMEXIT_CONTINUE 1 /* continue from next instruction */ -#define VMEXIT_RESTART 2 /* restart current instruction */ -#define VMEXIT_ABORT 3 /* abort the vm run loop */ +#define VMEXIT_CONTINUE (0) +#define VMEXIT_ABORT (-1) struct vmctx; extern int guest_ncpus; diff --git a/usr.sbin/bhyve/block_if.c b/usr.sbin/bhyve/block_if.c index 8687e9a..ef8e11e 100644 --- a/usr.sbin/bhyve/block_if.c +++ b/usr.sbin/bhyve/block_if.c @@ -54,16 +54,19 @@ __FBSDID("$FreeBSD$"); #define BLOCKIF_SIG 0xb109b109 -#define BLOCKIF_MAXREQ 33 +#define BLOCKIF_NUMTHR 8 +#define BLOCKIF_MAXREQ (64 + BLOCKIF_NUMTHR) enum blockop { BOP_READ, BOP_WRITE, - BOP_FLUSH + BOP_FLUSH, + BOP_DELETE }; enum blockstat { BST_FREE, + BST_BLOCK, BST_PEND, BST_BUSY, BST_DONE @@ -75,24 +78,29 @@ struct blockif_elem { enum blockop be_op; enum blockstat be_status; pthread_t be_tid; + off_t be_block; }; struct blockif_ctxt { int bc_magic; int bc_fd; + int bc_ischr; + int bc_isgeom; + int bc_candelete; int bc_rdonly; off_t bc_size; int bc_sectsz; - pthread_t bc_btid; + int bc_psectsz; + int bc_psectoff; + int bc_closing; + pthread_t bc_btid[BLOCKIF_NUMTHR]; pthread_mutex_t bc_mtx; pthread_cond_t bc_cond; - int bc_closing; /* Request elements and free/pending/busy queues */ TAILQ_HEAD(, blockif_elem) bc_freeq; TAILQ_HEAD(, blockif_elem) bc_pendq; TAILQ_HEAD(, blockif_elem) bc_busyq; - u_int bc_req_count; struct blockif_elem bc_reqs[BLOCKIF_MAXREQ]; }; @@ -111,83 +119,195 @@ static int blockif_enqueue(struct blockif_ctxt *bc, struct blockif_req *breq, enum blockop op) { - struct blockif_elem *be; - - assert(bc->bc_req_count < BLOCKIF_MAXREQ); + struct blockif_elem *be, *tbe; + off_t off; + int i; be = TAILQ_FIRST(&bc->bc_freeq); assert(be != NULL); assert(be->be_status == BST_FREE); - TAILQ_REMOVE(&bc->bc_freeq, be, be_link); - be->be_status = BST_PEND; be->be_req = breq; be->be_op = op; + switch (op) { + case BOP_READ: + case BOP_WRITE: + case BOP_DELETE: + off = breq->br_offset; + for (i = 0; i < breq->br_iovcnt; i++) + off += breq->br_iov[i].iov_len; + break; + default: + off = OFF_MAX; + } + be->be_block = off; + TAILQ_FOREACH(tbe, &bc->bc_pendq, be_link) { + if (tbe->be_block == breq->br_offset) + break; + } + if (tbe == NULL) { + TAILQ_FOREACH(tbe, &bc->bc_busyq, be_link) { + if (tbe->be_block == breq->br_offset) + break; + } + } + if (tbe == NULL) + be->be_status = BST_PEND; + else + be->be_status = BST_BLOCK; TAILQ_INSERT_TAIL(&bc->bc_pendq, be, be_link); - - bc->bc_req_count++; - - return (0); + return (be->be_status == BST_PEND); } static int -blockif_dequeue(struct blockif_ctxt *bc, struct blockif_elem **bep) +blockif_dequeue(struct blockif_ctxt *bc, pthread_t t, struct blockif_elem **bep) { struct blockif_elem *be; - if (bc->bc_req_count == 0) - return (ENOENT); - - be = TAILQ_FIRST(&bc->bc_pendq); - assert(be != NULL); - assert(be->be_status == BST_PEND); + TAILQ_FOREACH(be, &bc->bc_pendq, be_link) { + if (be->be_status == BST_PEND) + break; + assert(be->be_status == BST_BLOCK); + } + if (be == NULL) + return (0); TAILQ_REMOVE(&bc->bc_pendq, be, be_link); be->be_status = BST_BUSY; - be->be_tid = bc->bc_btid; + be->be_tid = t; TAILQ_INSERT_TAIL(&bc->bc_busyq, be, be_link); - *bep = be; - - return (0); + return (1); } static void blockif_complete(struct blockif_ctxt *bc, struct blockif_elem *be) { - assert(be->be_status == BST_DONE); + struct blockif_elem *tbe; - TAILQ_REMOVE(&bc->bc_busyq, be, be_link); + if (be->be_status == BST_DONE || be->be_status == BST_BUSY) + TAILQ_REMOVE(&bc->bc_busyq, be, be_link); + else + TAILQ_REMOVE(&bc->bc_pendq, be, be_link); + TAILQ_FOREACH(tbe, &bc->bc_pendq, be_link) { + if (tbe->be_req->br_offset == be->be_block) + tbe->be_status = BST_PEND; + } be->be_tid = 0; be->be_status = BST_FREE; be->be_req = NULL; TAILQ_INSERT_TAIL(&bc->bc_freeq, be, be_link); - - bc->bc_req_count--; } static void -blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be) +blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be, uint8_t *buf) { struct blockif_req *br; - int err; + off_t arg[2]; + ssize_t clen, len, off, boff, voff; + int i, err; br = be->be_req; + if (br->br_iovcnt <= 1) + buf = NULL; err = 0; - switch (be->be_op) { case BOP_READ: - if (preadv(bc->bc_fd, br->br_iov, br->br_iovcnt, - br->br_offset) < 0) - err = errno; + if (buf == NULL) { + if ((len = preadv(bc->bc_fd, br->br_iov, br->br_iovcnt, + br->br_offset)) < 0) + err = errno; + else + br->br_resid -= len; + break; + } + i = 0; + off = voff = 0; + while (br->br_resid > 0) { + len = MIN(br->br_resid, MAXPHYS); + if (pread(bc->bc_fd, buf, len, br->br_offset + + off) < 0) { + err = errno; + break; + } + boff = 0; + do { + clen = MIN(len - boff, br->br_iov[i].iov_len - + voff); + memcpy(br->br_iov[i].iov_base + voff, + buf + boff, clen); + if (clen < br->br_iov[i].iov_len - voff) + voff += clen; + else { + i++; + voff = 0; + } + boff += clen; + } while (boff < len); + off += len; + br->br_resid -= len; + } break; case BOP_WRITE: - if (bc->bc_rdonly) + if (bc->bc_rdonly) { err = EROFS; - else if (pwritev(bc->bc_fd, br->br_iov, br->br_iovcnt, - br->br_offset) < 0) - err = errno; + break; + } + if (buf == NULL) { + if ((len = pwritev(bc->bc_fd, br->br_iov, br->br_iovcnt, + br->br_offset)) < 0) + err = errno; + else + br->br_resid -= len; + break; + } + i = 0; + off = voff = 0; + while (br->br_resid > 0) { + len = MIN(br->br_resid, MAXPHYS); + boff = 0; + do { + clen = MIN(len - boff, br->br_iov[i].iov_len - + voff); + memcpy(buf + boff, + br->br_iov[i].iov_base + voff, clen); + if (clen < br->br_iov[i].iov_len - voff) + voff += clen; + else { + i++; + voff = 0; + } + boff += clen; + } while (boff < len); + if (pwrite(bc->bc_fd, buf, len, br->br_offset + + off) < 0) { + err = errno; + break; + } + off += len; + br->br_resid -= len; + } break; case BOP_FLUSH: + if (bc->bc_ischr) { + if (ioctl(bc->bc_fd, DIOCGFLUSH)) + err = errno; + } else if (fsync(bc->bc_fd)) + err = errno; + break; + case BOP_DELETE: + if (!bc->bc_candelete) + err = EOPNOTSUPP; + else if (bc->bc_rdonly) + err = EROFS; + else if (bc->bc_ischr) { + arg[0] = br->br_offset; + arg[1] = br->br_resid; + if (ioctl(bc->bc_fd, DIOCGDELETE, arg)) + err = errno; + else + br->br_resid = 0; + } else + err = EOPNOTSUPP; break; default: err = EINVAL; @@ -204,28 +324,34 @@ blockif_thr(void *arg) { struct blockif_ctxt *bc; struct blockif_elem *be; + pthread_t t; + uint8_t *buf; bc = arg; + if (bc->bc_isgeom) + buf = malloc(MAXPHYS); + else + buf = NULL; + t = pthread_self(); + pthread_mutex_lock(&bc->bc_mtx); for (;;) { - pthread_mutex_lock(&bc->bc_mtx); - while (!blockif_dequeue(bc, &be)) { + while (blockif_dequeue(bc, t, &be)) { pthread_mutex_unlock(&bc->bc_mtx); - blockif_proc(bc, be); + blockif_proc(bc, be, buf); pthread_mutex_lock(&bc->bc_mtx); blockif_complete(bc, be); } - pthread_cond_wait(&bc->bc_cond, &bc->bc_mtx); - pthread_mutex_unlock(&bc->bc_mtx); - - /* - * Check ctxt status here to see if exit requested - */ + /* Check ctxt status here to see if exit requested */ if (bc->bc_closing) - pthread_exit(NULL); + break; + pthread_cond_wait(&bc->bc_cond, &bc->bc_mtx); } + pthread_mutex_unlock(&bc->bc_mtx); - /* Not reached */ + if (buf) + free(buf); + pthread_exit(NULL); return (NULL); } @@ -265,15 +391,19 @@ struct blockif_ctxt * blockif_open(const char *optstr, const char *ident) { char tname[MAXCOMLEN + 1]; - char *nopt, *xopts; + char name[MAXPATHLEN]; + char *nopt, *xopts, *cp; struct blockif_ctxt *bc; struct stat sbuf; - off_t size; + struct diocgattr_arg arg; + off_t size, psectsz, psectoff; int extra, fd, i, sectsz; - int nocache, sync, ro; + int nocache, sync, ro, candelete, geom, ssopt, pssopt; pthread_once(&blockif_once, blockif_init); + fd = -1; + ssopt = 0; nocache = 0; sync = 0; ro = 0; @@ -282,16 +412,25 @@ blockif_open(const char *optstr, const char *ident) * The first element in the optstring is always a pathname. * Optional elements follow */ - nopt = strdup(optstr); - for (xopts = strtok(nopt, ","); - xopts != NULL; - xopts = strtok(NULL, ",")) { - if (!strcmp(xopts, "nocache")) + nopt = xopts = strdup(optstr); + while (xopts != NULL) { + cp = strsep(&xopts, ","); + if (cp == nopt) /* file or device pathname */ + continue; + else if (!strcmp(cp, "nocache")) nocache = 1; - else if (!strcmp(xopts, "sync")) + else if (!strcmp(cp, "sync") || !strcmp(cp, "direct")) sync = 1; - else if (!strcmp(xopts, "ro")) + else if (!strcmp(cp, "ro")) ro = 1; + else if (sscanf(cp, "sectorsize=%d/%d", &ssopt, &pssopt) == 2) + ; + else if (sscanf(cp, "sectorsize=%d", &ssopt) == 1) + pssopt = ssopt; + else { + fprintf(stderr, "Invalid device option \"%s\"\n", cp); + goto err; + } } extra = 0; @@ -309,13 +448,12 @@ blockif_open(const char *optstr, const char *ident) if (fd < 0) { perror("Could not open backing file"); - return (NULL); + goto err; } if (fstat(fd, &sbuf) < 0) { perror("Could not stat backing file"); - close(fd); - return (NULL); + goto err; } /* @@ -323,45 +461,93 @@ blockif_open(const char *optstr, const char *ident) */ size = sbuf.st_size; sectsz = DEV_BSIZE; + psectsz = psectoff = 0; + candelete = geom = 0; if (S_ISCHR(sbuf.st_mode)) { if (ioctl(fd, DIOCGMEDIASIZE, &size) < 0 || ioctl(fd, DIOCGSECTORSIZE, §sz)) { perror("Could not fetch dev blk/sector size"); - close(fd); - return (NULL); + goto err; } assert(size != 0); assert(sectsz != 0); + if (ioctl(fd, DIOCGSTRIPESIZE, &psectsz) == 0 && psectsz > 0) + ioctl(fd, DIOCGSTRIPEOFFSET, &psectoff); + strlcpy(arg.name, "GEOM::candelete", sizeof(arg.name)); + arg.len = sizeof(arg.value.i); + if (ioctl(fd, DIOCGATTR, &arg) == 0) + candelete = arg.value.i; + if (ioctl(fd, DIOCGPROVIDERNAME, name) == 0) + geom = 1; + } else + psectsz = sbuf.st_blksize; + + if (ssopt != 0) { + if (!powerof2(ssopt) || !powerof2(pssopt) || ssopt < 512 || + ssopt > pssopt) { + fprintf(stderr, "Invalid sector size %d/%d\n", + ssopt, pssopt); + goto err; + } + + /* + * Some backend drivers (e.g. cd0, ada0) require that the I/O + * size be a multiple of the device's sector size. + * + * Validate that the emulated sector size complies with this + * requirement. + */ + if (S_ISCHR(sbuf.st_mode)) { + if (ssopt < sectsz || (ssopt % sectsz) != 0) { + fprintf(stderr, "Sector size %d incompatible " + "with underlying device sector size %d\n", + ssopt, sectsz); + goto err; + } + } + + sectsz = ssopt; + psectsz = pssopt; + psectoff = 0; } bc = calloc(1, sizeof(struct blockif_ctxt)); if (bc == NULL) { - close(fd); - return (NULL); + perror("calloc"); + goto err; } bc->bc_magic = BLOCKIF_SIG; bc->bc_fd = fd; + bc->bc_ischr = S_ISCHR(sbuf.st_mode); + bc->bc_isgeom = geom; + bc->bc_candelete = candelete; bc->bc_rdonly = ro; bc->bc_size = size; bc->bc_sectsz = sectsz; + bc->bc_psectsz = psectsz; + bc->bc_psectoff = psectoff; pthread_mutex_init(&bc->bc_mtx, NULL); pthread_cond_init(&bc->bc_cond, NULL); TAILQ_INIT(&bc->bc_freeq); TAILQ_INIT(&bc->bc_pendq); TAILQ_INIT(&bc->bc_busyq); - bc->bc_req_count = 0; for (i = 0; i < BLOCKIF_MAXREQ; i++) { bc->bc_reqs[i].be_status = BST_FREE; TAILQ_INSERT_HEAD(&bc->bc_freeq, &bc->bc_reqs[i], be_link); } - pthread_create(&bc->bc_btid, NULL, blockif_thr, bc); - - snprintf(tname, sizeof(tname), "blk-%s", ident); - pthread_set_name_np(bc->bc_btid, tname); + for (i = 0; i < BLOCKIF_NUMTHR; i++) { + pthread_create(&bc->bc_btid[i], NULL, blockif_thr, bc); + snprintf(tname, sizeof(tname), "blk-%s-%d", ident, i); + pthread_set_name_np(bc->bc_btid[i], tname); + } return (bc); +err: + if (fd >= 0) + close(fd); + return (NULL); } static int @@ -373,13 +559,13 @@ blockif_request(struct blockif_ctxt *bc, struct blockif_req *breq, err = 0; pthread_mutex_lock(&bc->bc_mtx); - if (bc->bc_req_count < BLOCKIF_MAXREQ) { + if (!TAILQ_EMPTY(&bc->bc_freeq)) { /* * Enqueue and inform the block i/o thread * that there is work available */ - blockif_enqueue(bc, breq, op); - pthread_cond_signal(&bc->bc_cond); + if (blockif_enqueue(bc, breq, op)) + pthread_cond_signal(&bc->bc_cond); } else { /* * Callers are not allowed to enqueue more than @@ -419,6 +605,14 @@ blockif_flush(struct blockif_ctxt *bc, struct blockif_req *breq) } int +blockif_delete(struct blockif_ctxt *bc, struct blockif_req *breq) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (blockif_request(bc, breq, BOP_DELETE)); +} + +int blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq) { struct blockif_elem *be; @@ -437,11 +631,7 @@ blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq) /* * Found it. */ - TAILQ_REMOVE(&bc->bc_pendq, be, be_link); - be->be_status = BST_FREE; - be->be_req = NULL; - TAILQ_INSERT_TAIL(&bc->bc_freeq, be, be_link); - bc->bc_req_count--; + blockif_complete(bc, be); pthread_mutex_unlock(&bc->bc_mtx); return (0); @@ -502,7 +692,7 @@ int blockif_close(struct blockif_ctxt *bc) { void *jval; - int err; + int err, i; err = 0; @@ -511,9 +701,12 @@ blockif_close(struct blockif_ctxt *bc) /* * Stop the block i/o thread */ + pthread_mutex_lock(&bc->bc_mtx); bc->bc_closing = 1; - pthread_cond_signal(&bc->bc_cond); - pthread_join(bc->bc_btid, &jval); + pthread_mutex_unlock(&bc->bc_mtx); + pthread_cond_broadcast(&bc->bc_cond); + for (i = 0; i < BLOCKIF_NUMTHR; i++) + pthread_join(bc->bc_btid[i], &jval); /* XXX Cancel queued i/o's ??? */ @@ -595,6 +788,15 @@ blockif_sectsz(struct blockif_ctxt *bc) return (bc->bc_sectsz); } +void +blockif_psectsz(struct blockif_ctxt *bc, int *size, int *off) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + *size = bc->bc_psectsz; + *off = bc->bc_psectoff; +} + int blockif_queuesz(struct blockif_ctxt *bc) { @@ -610,3 +812,11 @@ blockif_is_ro(struct blockif_ctxt *bc) assert(bc->bc_magic == BLOCKIF_SIG); return (bc->bc_rdonly); } + +int +blockif_candelete(struct blockif_ctxt *bc) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (bc->bc_candelete); +} diff --git a/usr.sbin/bhyve/block_if.h b/usr.sbin/bhyve/block_if.h index c2c21f6..8e63407 100644 --- a/usr.sbin/bhyve/block_if.h +++ b/usr.sbin/bhyve/block_if.h @@ -39,12 +39,13 @@ #include <sys/uio.h> #include <sys/unistd.h> -#define BLOCKIF_IOV_MAX 32 /* not practical to be IOV_MAX */ +#define BLOCKIF_IOV_MAX 33 /* not practical to be IOV_MAX */ struct blockif_req { struct iovec br_iov[BLOCKIF_IOV_MAX]; int br_iovcnt; off_t br_offset; + ssize_t br_resid; void (*br_callback)(struct blockif_req *req, int err); void *br_param; }; @@ -55,11 +56,14 @@ off_t blockif_size(struct blockif_ctxt *bc); void blockif_chs(struct blockif_ctxt *bc, uint16_t *c, uint8_t *h, uint8_t *s); int blockif_sectsz(struct blockif_ctxt *bc); +void blockif_psectsz(struct blockif_ctxt *bc, int *size, int *off); int blockif_queuesz(struct blockif_ctxt *bc); int blockif_is_ro(struct blockif_ctxt *bc); +int blockif_candelete(struct blockif_ctxt *bc); int blockif_read(struct blockif_ctxt *bc, struct blockif_req *breq); int blockif_write(struct blockif_ctxt *bc, struct blockif_req *breq); int blockif_flush(struct blockif_ctxt *bc, struct blockif_req *breq); +int blockif_delete(struct blockif_ctxt *bc, struct blockif_req *breq); int blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq); int blockif_close(struct blockif_ctxt *bc); diff --git a/usr.sbin/bhyve/inout.c b/usr.sbin/bhyve/inout.c index 1041a59..929bb3c 100644 --- a/usr.sbin/bhyve/inout.c +++ b/usr.sbin/bhyve/inout.c @@ -104,10 +104,10 @@ int emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict) { int addrsize, bytes, flags, in, port, prot, rep; - uint32_t val; + uint32_t eax, val; inout_func_t handler; void *arg; - int error, retval; + int error, fault, retval; enum vm_reg_name idxreg; uint64_t gla, index, iterations, count; struct vm_inout_str *vis; @@ -163,11 +163,11 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict) } error = vm_copy_setup(ctx, vcpu, &vis->paging, gla, - bytes, prot, iov, nitems(iov)); - if (error == -1) { + bytes, prot, iov, nitems(iov), &fault); + if (error) { retval = -1; /* Unrecoverable error */ break; - } else if (error == 1) { + } else if (fault) { retval = 0; /* Resume guest to handle fault */ break; } @@ -214,16 +214,20 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict) } /* Restart the instruction if more iterations remain */ - if (retval == 0 && count != 0) - vmexit->inst_length = 0; - } else { - if (!in) { - val = vmexit->u.inout.eax & vie_size2mask(bytes); + if (retval == 0 && count != 0) { + error = vm_restart_instruction(ctx, vcpu); + assert(error == 0); } + } else { + eax = vmexit->u.inout.eax; + val = eax & vie_size2mask(bytes); retval = handler(ctx, vcpu, in, port, bytes, &val, arg); if (retval == 0 && in) { - vmexit->u.inout.eax &= ~vie_size2mask(bytes); - vmexit->u.inout.eax |= val & vie_size2mask(bytes); + eax &= ~vie_size2mask(bytes); + eax |= val & vie_size2mask(bytes); + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, + eax); + assert(error == 0); } } return (retval); diff --git a/usr.sbin/bhyve/ioapic.c b/usr.sbin/bhyve/ioapic.c index 2950d9a..0ad69d9 100644 --- a/usr.sbin/bhyve/ioapic.c +++ b/usr.sbin/bhyve/ioapic.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014 Advanced Computing Technologies LLC + * Copyright (c) 2014 Hudson River Trading LLC * Written by: John H. Baldwin <jhb@FreeBSD.org> * All rights reserved. * diff --git a/usr.sbin/bhyve/ioapic.h b/usr.sbin/bhyve/ioapic.h index 3cfca4f..efdd3c6 100644 --- a/usr.sbin/bhyve/ioapic.h +++ b/usr.sbin/bhyve/ioapic.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014 Advanced Computing Technologies LLC + * Copyright (c) 2014 Hudson River Trading LLC * Written by: John H. Baldwin <jhb@FreeBSD.org> * All rights reserved. * diff --git a/usr.sbin/bhyve/pci_ahci.c b/usr.sbin/bhyve/pci_ahci.c index ab40854..35a0859 100644 --- a/usr.sbin/bhyve/pci_ahci.c +++ b/usr.sbin/bhyve/pci_ahci.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include <pthread.h> #include <pthread_np.h> #include <inttypes.h> +#include <md5.h> #include "bhyverun.h" #include "pci_emul.h" @@ -86,6 +87,7 @@ enum sata_fis_type { #define READ_TOC 0x43 #define GET_EVENT_STATUS_NOTIFICATION 0x4A #define MODE_SENSE_10 0x5A +#define REPORT_LUNS 0xA0 #define READ_12 0xA8 #define READ_CD 0xBE @@ -122,7 +124,7 @@ struct ahci_ioreq { uint32_t len; uint32_t done; int slot; - int prdtl; + int more; }; struct ahci_port { @@ -130,12 +132,16 @@ struct ahci_port { struct pci_ahci_softc *pr_sc; uint8_t *cmd_lst; uint8_t *rfis; + char ident[20 + 1]; int atapi; int reset; + int waitforclear; int mult_sectors; uint8_t xfermode; + uint8_t err_cfis[20]; uint8_t sense_key; uint8_t asc; + u_int ccs; uint32_t pending; uint32_t clb; @@ -200,6 +206,8 @@ struct pci_ahci_softc { }; #define ahci_ctx(sc) ((sc)->asc_pi->pi_vmctx) +static void ahci_handle_port(struct ahci_port *p); + static inline void lba_to_msf(uint8_t *buf, int lba) { lba += 150; @@ -265,22 +273,26 @@ ahci_write_fis(struct ahci_port *p, enum sata_fis_type ft, uint8_t *fis) case FIS_TYPE_REGD2H: offset = 0x40; len = 20; - irq = AHCI_P_IX_DHR; + irq = (fis[1] & (1 << 6)) ? AHCI_P_IX_DHR : 0; break; case FIS_TYPE_SETDEVBITS: offset = 0x58; len = 8; - irq = AHCI_P_IX_SDB; + irq = (fis[1] & (1 << 6)) ? AHCI_P_IX_SDB : 0; break; case FIS_TYPE_PIOSETUP: offset = 0x20; len = 20; - irq = 0; + irq = (fis[1] & (1 << 6)) ? AHCI_P_IX_PS : 0; break; default: WPRINTF("unsupported fis type %d\n", ft); return; } + if (fis[2] & ATA_S_ERROR) { + p->waitforclear = 1; + irq |= AHCI_P_IX_TFE; + } memcpy(p->rfis + offset, fis, len); if (irq) { p->is |= irq; @@ -299,19 +311,29 @@ ahci_write_fis_piosetup(struct ahci_port *p) } static void -ahci_write_fis_sdb(struct ahci_port *p, int slot, uint32_t tfd) +ahci_write_fis_sdb(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t tfd) { uint8_t fis[8]; uint8_t error; error = (tfd >> 8) & 0xff; + tfd &= 0x77; memset(fis, 0, sizeof(fis)); - fis[0] = error; - fis[2] = tfd & 0x77; - *(uint32_t *)(fis + 4) = (1 << slot); - if (fis[2] & ATA_S_ERROR) - p->is |= AHCI_P_IX_TFE; - p->tfd = tfd; + fis[0] = FIS_TYPE_SETDEVBITS; + fis[1] = (1 << 6); + fis[2] = tfd; + fis[3] = error; + if (fis[2] & ATA_S_ERROR) { + p->err_cfis[0] = slot; + p->err_cfis[2] = tfd; + p->err_cfis[3] = error; + memcpy(&p->err_cfis[4], cfis + 4, 16); + } else { + *(uint32_t *)(fis + 4) = (1 << slot); + p->sact &= ~(1 << slot); + } + p->tfd &= ~0x77; + p->tfd |= tfd; ahci_write_fis(p, FIS_TYPE_SETDEVBITS, fis); } @@ -337,15 +359,33 @@ ahci_write_fis_d2h(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t tfd) fis[11] = cfis[11]; fis[12] = cfis[12]; fis[13] = cfis[13]; - if (fis[2] & ATA_S_ERROR) - p->is |= AHCI_P_IX_TFE; - else + if (fis[2] & ATA_S_ERROR) { + p->err_cfis[0] = 0x80; + p->err_cfis[2] = tfd & 0xff; + p->err_cfis[3] = error; + memcpy(&p->err_cfis[4], cfis + 4, 16); + } else p->ci &= ~(1 << slot); p->tfd = tfd; ahci_write_fis(p, FIS_TYPE_REGD2H, fis); } static void +ahci_write_fis_d2h_ncq(struct ahci_port *p, int slot) +{ + uint8_t fis[20]; + + p->tfd = ATA_S_READY | ATA_S_DSC; + memset(fis, 0, sizeof(fis)); + fis[0] = FIS_TYPE_REGD2H; + fis[1] = 0; /* No interrupt */ + fis[2] = p->tfd; /* Status */ + fis[3] = 0; /* No error */ + p->ci &= ~(1 << slot); + ahci_write_fis(p, FIS_TYPE_REGD2H, fis); +} + +static void ahci_write_reset_fis_d2h(struct ahci_port *p) { uint8_t fis[20]; @@ -372,9 +412,11 @@ ahci_check_stopped(struct ahci_port *p) */ if (!(p->cmd & AHCI_P_CMD_ST)) { if (p->pending == 0) { + p->ccs = 0; p->cmd &= ~(AHCI_P_CMD_CR | AHCI_P_CMD_CCS_MASK); p->ci = 0; p->sact = 0; + p->waitforclear = 0; } } } @@ -401,7 +443,8 @@ ahci_port_stop(struct ahci_port *p) slot = aior->slot; cfis = aior->cfis; if (cfis[2] == ATA_WRITE_FPDMA_QUEUED || - cfis[2] == ATA_READ_FPDMA_QUEUED) + cfis[2] == ATA_READ_FPDMA_QUEUED || + cfis[2] == ATA_SEND_FPDMA_QUEUED) ncq = 1; if (ncq) @@ -431,7 +474,6 @@ ahci_port_stop(struct ahci_port *p) static void ahci_port_reset(struct ahci_port *pr) { - pr->sctl = 0; pr->serr = 0; pr->sact = 0; pr->xfermode = ATA_UDMA6; @@ -443,8 +485,11 @@ ahci_port_reset(struct ahci_port *pr) pr->tfd = 0x7F; return; } - pr->ssts = ATA_SS_DET_PHY_ONLINE | ATA_SS_SPD_GEN2 | - ATA_SS_IPM_ACTIVE; + pr->ssts = ATA_SS_DET_PHY_ONLINE | ATA_SS_IPM_ACTIVE; + if (pr->sctl & ATA_SC_SPD_MASK) + pr->ssts |= (pr->sctl & ATA_SC_SPD_MASK); + else + pr->ssts |= ATA_SS_SPD_GEN3; pr->tfd = (1 << 8) | ATA_S_DSC | ATA_S_DMA; if (!pr->atapi) { pr->sig = PxSIG_ATA; @@ -470,6 +515,10 @@ ahci_reset(struct pci_ahci_softc *sc) for (i = 0; i < sc->ports; i++) { sc->port[i].ie = 0; sc->port[i].is = 0; + sc->port[i].cmd = (AHCI_P_CMD_SUD | AHCI_P_CMD_POD); + if (sc->port[i].bctx) + sc->port[i].cmd |= AHCI_P_CMD_CPS; + sc->port[i].sctl = 0; ahci_port_reset(&sc->port[i]); } } @@ -500,32 +549,87 @@ atapi_string(uint8_t *dest, const char *src, int len) } } +/* + * Build up the iovec based on the PRDT, 'done' and 'len'. + */ static void -ahci_handle_dma(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done, - int seek) +ahci_build_iov(struct ahci_port *p, struct ahci_ioreq *aior, + struct ahci_prdt_entry *prdt, uint16_t prdtl) +{ + struct blockif_req *breq = &aior->io_req; + int i, j, skip, todo, left, extra; + uint32_t dbcsz; + + /* Copy part of PRDT between 'done' and 'len' bytes into the iov. */ + skip = aior->done; + left = aior->len - aior->done; + todo = 0; + for (i = 0, j = 0; i < prdtl && j < BLOCKIF_IOV_MAX && left > 0; + i++, prdt++) { + dbcsz = (prdt->dbc & DBCMASK) + 1; + /* Skip already done part of the PRDT */ + if (dbcsz <= skip) { + skip -= dbcsz; + continue; + } + dbcsz -= skip; + if (dbcsz > left) + dbcsz = left; + breq->br_iov[j].iov_base = paddr_guest2host(ahci_ctx(p->pr_sc), + prdt->dba + skip, dbcsz); + breq->br_iov[j].iov_len = dbcsz; + todo += dbcsz; + left -= dbcsz; + skip = 0; + j++; + } + + /* If we got limited by IOV length, round I/O down to sector size. */ + if (j == BLOCKIF_IOV_MAX) { + extra = todo % blockif_sectsz(p->bctx); + todo -= extra; + assert(todo > 0); + while (extra > 0) { + if (breq->br_iov[j - 1].iov_len > extra) { + breq->br_iov[j - 1].iov_len -= extra; + break; + } + extra -= breq->br_iov[j - 1].iov_len; + j--; + } + } + + breq->br_iovcnt = j; + breq->br_resid = todo; + aior->done += todo; + aior->more = (aior->done < aior->len && i < prdtl); +} + +static void +ahci_handle_rw(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done) { struct ahci_ioreq *aior; struct blockif_req *breq; - struct pci_ahci_softc *sc; struct ahci_prdt_entry *prdt; struct ahci_cmd_hdr *hdr; uint64_t lba; uint32_t len; - int i, err, iovcnt, ncq, readop; + int err, first, ncq, readop; - sc = p->pr_sc; prdt = (struct ahci_prdt_entry *)(cfis + 0x80); hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); ncq = 0; readop = 1; + first = (done == 0); - prdt += seek; - if (cfis[2] == ATA_WRITE_DMA || cfis[2] == ATA_WRITE_DMA48 || - cfis[2] == ATA_WRITE_FPDMA_QUEUED) + if (cfis[2] == ATA_WRITE || cfis[2] == ATA_WRITE48 || + cfis[2] == ATA_WRITE_MUL || cfis[2] == ATA_WRITE_MUL48 || + cfis[2] == ATA_WRITE_DMA || cfis[2] == ATA_WRITE_DMA48 || + cfis[2] == ATA_WRITE_FPDMA_QUEUED) readop = 0; if (cfis[2] == ATA_WRITE_FPDMA_QUEUED || - cfis[2] == ATA_READ_FPDMA_QUEUED) { + cfis[2] == ATA_READ_FPDMA_QUEUED) { lba = ((uint64_t)cfis[10] << 40) | ((uint64_t)cfis[9] << 32) | ((uint64_t)cfis[8] << 24) | @@ -536,7 +640,9 @@ ahci_handle_dma(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done, if (!len) len = 65536; ncq = 1; - } else if (cfis[2] == ATA_READ_DMA48 || cfis[2] == ATA_WRITE_DMA48) { + } else if (cfis[2] == ATA_READ48 || cfis[2] == ATA_WRITE48 || + cfis[2] == ATA_READ_MUL48 || cfis[2] == ATA_WRITE_MUL48 || + cfis[2] == ATA_READ_DMA48 || cfis[2] == ATA_WRITE_DMA48) { lba = ((uint64_t)cfis[10] << 40) | ((uint64_t)cfis[9] << 32) | ((uint64_t)cfis[8] << 24) | @@ -556,57 +662,33 @@ ahci_handle_dma(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done, lba *= blockif_sectsz(p->bctx); len *= blockif_sectsz(p->bctx); - /* - * Pull request off free list - */ + /* Pull request off free list */ aior = STAILQ_FIRST(&p->iofhd); assert(aior != NULL); STAILQ_REMOVE_HEAD(&p->iofhd, io_flist); + aior->cfis = cfis; aior->slot = slot; aior->len = len; aior->done = done; breq = &aior->io_req; breq->br_offset = lba + done; - iovcnt = hdr->prdtl - seek; - if (iovcnt > BLOCKIF_IOV_MAX) { - aior->prdtl = iovcnt - BLOCKIF_IOV_MAX; - iovcnt = BLOCKIF_IOV_MAX; - } else - aior->prdtl = 0; - breq->br_iovcnt = iovcnt; + ahci_build_iov(p, aior, prdt, hdr->prdtl); - /* - * Mark this command in-flight. - */ + /* Mark this command in-flight. */ p->pending |= 1 << slot; - /* - * Stuff request onto busy list - */ + /* Stuff request onto busy list. */ TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist); - /* - * Build up the iovec based on the prdt - */ - for (i = 0; i < iovcnt; i++) { - uint32_t dbcsz; + if (ncq && first) + ahci_write_fis_d2h_ncq(p, slot); - dbcsz = (prdt->dbc & DBCMASK) + 1; - breq->br_iov[i].iov_base = paddr_guest2host(ahci_ctx(sc), - prdt->dba, dbcsz); - breq->br_iov[i].iov_len = dbcsz; - aior->done += dbcsz; - prdt++; - } if (readop) err = blockif_read(p->bctx, breq); else err = blockif_write(p->bctx, breq); assert(err == 0); - - if (ncq) - p->ci &= ~(1 << slot); } static void @@ -626,7 +708,7 @@ ahci_handle_flush(struct ahci_port *p, int slot, uint8_t *cfis) aior->slot = slot; aior->len = 0; aior->done = 0; - aior->prdtl = 0; + aior->more = 0; breq = &aior->io_req; /* @@ -644,6 +726,112 @@ ahci_handle_flush(struct ahci_port *p, int slot, uint8_t *cfis) } static inline void +read_prdt(struct ahci_port *p, int slot, uint8_t *cfis, + void *buf, int size) +{ + struct ahci_cmd_hdr *hdr; + struct ahci_prdt_entry *prdt; + void *to; + int i, len; + + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); + len = size; + to = buf; + prdt = (struct ahci_prdt_entry *)(cfis + 0x80); + for (i = 0; i < hdr->prdtl && len; i++) { + uint8_t *ptr; + uint32_t dbcsz; + int sublen; + + dbcsz = (prdt->dbc & DBCMASK) + 1; + ptr = paddr_guest2host(ahci_ctx(p->pr_sc), prdt->dba, dbcsz); + sublen = len < dbcsz ? len : dbcsz; + memcpy(to, ptr, sublen); + len -= sublen; + to += sublen; + prdt++; + } +} + +static void +ahci_handle_dsm_trim(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done) +{ + struct ahci_ioreq *aior; + struct blockif_req *breq; + uint8_t *entry; + uint64_t elba; + uint32_t len, elen; + int err, first, ncq; + uint8_t buf[512]; + + first = (done == 0); + if (cfis[2] == ATA_DATA_SET_MANAGEMENT) { + len = (uint16_t)cfis[13] << 8 | cfis[12]; + len *= 512; + ncq = 0; + } else { /* ATA_SEND_FPDMA_QUEUED */ + len = (uint16_t)cfis[11] << 8 | cfis[3]; + len *= 512; + ncq = 1; + } + read_prdt(p, slot, cfis, buf, sizeof(buf)); + +next: + entry = &buf[done]; + elba = ((uint64_t)entry[5] << 40) | + ((uint64_t)entry[4] << 32) | + ((uint64_t)entry[3] << 24) | + ((uint64_t)entry[2] << 16) | + ((uint64_t)entry[1] << 8) | + entry[0]; + elen = (uint16_t)entry[7] << 8 | entry[6]; + done += 8; + if (elen == 0) { + if (done >= len) { + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); + p->pending &= ~(1 << slot); + ahci_check_stopped(p); + if (!first) + ahci_handle_port(p); + return; + } + goto next; + } + + /* + * Pull request off free list + */ + aior = STAILQ_FIRST(&p->iofhd); + assert(aior != NULL); + STAILQ_REMOVE_HEAD(&p->iofhd, io_flist); + aior->cfis = cfis; + aior->slot = slot; + aior->len = len; + aior->done = done; + aior->more = (len != done); + + breq = &aior->io_req; + breq->br_offset = elba * blockif_sectsz(p->bctx); + breq->br_resid = elen * blockif_sectsz(p->bctx); + + /* + * Mark this command in-flight. + */ + p->pending |= 1 << slot; + + /* + * Stuff request onto busy list + */ + TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist); + + if (ncq && first) + ahci_write_fis_d2h_ncq(p, slot); + + err = blockif_delete(p->bctx, breq); + assert(err == 0); +} + +static inline void write_prdt(struct ahci_port *p, int slot, uint8_t *cfis, void *buf, int size) { @@ -673,29 +861,68 @@ write_prdt(struct ahci_port *p, int slot, uint8_t *cfis, } static void +ahci_checksum(uint8_t *buf, int size) +{ + int i; + uint8_t sum = 0; + + for (i = 0; i < size - 1; i++) + sum += buf[i]; + buf[size - 1] = 0x100 - sum; +} + +static void +ahci_handle_read_log(struct ahci_port *p, int slot, uint8_t *cfis) +{ + struct ahci_cmd_hdr *hdr; + uint8_t buf[512]; + + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); + if (p->atapi || hdr->prdtl == 0 || cfis[4] != 0x10 || + cfis[5] != 0 || cfis[9] != 0 || cfis[12] != 1 || cfis[13] != 0) { + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + return; + } + + memset(buf, 0, sizeof(buf)); + memcpy(buf, p->err_cfis, sizeof(p->err_cfis)); + ahci_checksum(buf, sizeof(buf)); + + if (cfis[2] == ATA_READ_LOG_EXT) + ahci_write_fis_piosetup(p); + write_prdt(p, slot, cfis, (void *)buf, sizeof(buf)); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); +} + +static void handle_identify(struct ahci_port *p, int slot, uint8_t *cfis) { struct ahci_cmd_hdr *hdr; hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); if (p->atapi || hdr->prdtl == 0) { - p->tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR; - p->is |= AHCI_P_IX_TFE; + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); } else { uint16_t buf[256]; uint64_t sectors; + int sectsz, psectsz, psectoff, candelete, ro; uint16_t cyl; uint8_t sech, heads; - sectors = blockif_size(p->bctx) / blockif_sectsz(p->bctx); + ro = blockif_is_ro(p->bctx); + candelete = blockif_candelete(p->bctx); + sectsz = blockif_sectsz(p->bctx); + sectors = blockif_size(p->bctx) / sectsz; blockif_chs(p->bctx, &cyl, &heads, &sech); + blockif_psectsz(p->bctx, &psectsz, &psectoff); memset(buf, 0, sizeof(buf)); buf[0] = 0x0040; buf[1] = cyl; buf[3] = heads; buf[6] = sech; - /* TODO emulate different serial? */ - ata_string((uint8_t *)(buf+10), "123456", 20); + ata_string((uint8_t *)(buf+10), p->ident, 20); ata_string((uint8_t *)(buf+23), "001", 8); ata_string((uint8_t *)(buf+27), "BHYVE SATA DISK", 40); buf[47] = (0x8000 | 128); @@ -705,56 +932,86 @@ handle_identify(struct ahci_port *p, int slot, uint8_t *cfis) buf[53] = (1 << 1 | 1 << 2); if (p->mult_sectors) buf[59] = (0x100 | p->mult_sectors); - buf[60] = sectors; - buf[61] = (sectors >> 16); + if (sectors <= 0x0fffffff) { + buf[60] = sectors; + buf[61] = (sectors >> 16); + } else { + buf[60] = 0xffff; + buf[61] = 0x0fff; + } buf[63] = 0x7; if (p->xfermode & ATA_WDMA0) buf[63] |= (1 << ((p->xfermode & 7) + 8)); buf[64] = 0x3; - buf[65] = 100; - buf[66] = 100; - buf[67] = 100; - buf[68] = 100; + buf[65] = 120; + buf[66] = 120; + buf[67] = 120; + buf[68] = 120; + buf[69] = 0; buf[75] = 31; - buf[76] = (1 << 8 | 1 << 2); - buf[80] = 0x1f0; + buf[76] = (ATA_SATA_GEN1 | ATA_SATA_GEN2 | ATA_SATA_GEN3 | + ATA_SUPPORT_NCQ); + buf[77] = (ATA_SUPPORT_RCVSND_FPDMA_QUEUED | + (p->ssts & ATA_SS_SPD_MASK) >> 3); + buf[80] = 0x3f0; buf[81] = 0x28; - buf[82] = (1 << 5 | 1 << 14); - buf[83] = (1 << 10 | 1 << 12 | 1 << 13 | 1 << 14); + buf[82] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_WRITECACHE| + ATA_SUPPORT_LOOKAHEAD | ATA_SUPPORT_NOP); + buf[83] = (ATA_SUPPORT_ADDRESS48 | ATA_SUPPORT_FLUSHCACHE | + ATA_SUPPORT_FLUSHCACHE48 | 1 << 14); buf[84] = (1 << 14); - buf[85] = (1 << 5 | 1 << 14); - buf[86] = (1 << 10 | 1 << 12 | 1 << 13); + buf[85] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_WRITECACHE| + ATA_SUPPORT_LOOKAHEAD | ATA_SUPPORT_NOP); + buf[86] = (ATA_SUPPORT_ADDRESS48 | ATA_SUPPORT_FLUSHCACHE | + ATA_SUPPORT_FLUSHCACHE48 | 1 << 15); buf[87] = (1 << 14); buf[88] = 0x7f; if (p->xfermode & ATA_UDMA0) buf[88] |= (1 << ((p->xfermode & 7) + 8)); - buf[93] = (1 | 1 <<14); buf[100] = sectors; buf[101] = (sectors >> 16); buf[102] = (sectors >> 32); buf[103] = (sectors >> 48); + if (candelete && !ro) { + buf[69] |= ATA_SUPPORT_RZAT | ATA_SUPPORT_DRAT; + buf[105] = 1; + buf[169] = ATA_SUPPORT_DSM_TRIM; + } + buf[106] = 0x4000; + buf[209] = 0x4000; + if (psectsz > sectsz) { + buf[106] |= 0x2000; + buf[106] |= ffsl(psectsz / sectsz) - 1; + buf[209] |= (psectoff / sectsz); + } + if (sectsz > 512) { + buf[106] |= 0x1000; + buf[117] = sectsz / 2; + buf[118] = ((sectsz / 2) >> 16); + } + buf[119] = (ATA_SUPPORT_RWLOGDMAEXT | 1 << 14); + buf[120] = (ATA_SUPPORT_RWLOGDMAEXT | 1 << 14); + buf[222] = 0x1020; + buf[255] = 0x00a5; + ahci_checksum((uint8_t *)buf, sizeof(buf)); ahci_write_fis_piosetup(p); write_prdt(p, slot, cfis, (void *)buf, sizeof(buf)); - p->tfd = ATA_S_DSC | ATA_S_READY; - p->is |= AHCI_P_IX_DP; - p->ci &= ~(1 << slot); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); } - ahci_generate_intr(p->pr_sc); } static void handle_atapi_identify(struct ahci_port *p, int slot, uint8_t *cfis) { if (!p->atapi) { - p->tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR; - p->is |= AHCI_P_IX_TFE; + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); } else { uint16_t buf[256]; memset(buf, 0, sizeof(buf)); buf[0] = (2 << 14 | 5 << 8 | 1 << 7 | 2 << 5); - /* TODO emulate different serial? */ - ata_string((uint8_t *)(buf+10), "123456", 20); + ata_string((uint8_t *)(buf+10), p->ident, 20); ata_string((uint8_t *)(buf+23), "001", 8); ata_string((uint8_t *)(buf+27), "BHYVE SATA DVD ROM", 40); buf[49] = (1 << 9 | 1 << 8); @@ -762,27 +1019,34 @@ handle_atapi_identify(struct ahci_port *p, int slot, uint8_t *cfis) buf[53] = (1 << 2 | 1 << 1); buf[62] = 0x3f; buf[63] = 7; + if (p->xfermode & ATA_WDMA0) + buf[63] |= (1 << ((p->xfermode & 7) + 8)); buf[64] = 3; - buf[65] = 100; - buf[66] = 100; - buf[67] = 100; - buf[68] = 100; - buf[76] = (1 << 2 | 1 << 1); + buf[65] = 120; + buf[66] = 120; + buf[67] = 120; + buf[68] = 120; + buf[76] = (ATA_SATA_GEN1 | ATA_SATA_GEN2 | ATA_SATA_GEN3); + buf[77] = ((p->ssts & ATA_SS_SPD_MASK) >> 3); buf[78] = (1 << 5); - buf[80] = (0x1f << 4); - buf[82] = (1 << 4); + buf[80] = 0x3f0; + buf[82] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_PACKET | + ATA_SUPPORT_RESET | ATA_SUPPORT_NOP); buf[83] = (1 << 14); buf[84] = (1 << 14); - buf[85] = (1 << 4); + buf[85] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_PACKET | + ATA_SUPPORT_RESET | ATA_SUPPORT_NOP); buf[87] = (1 << 14); - buf[88] = (1 << 14 | 0x7f); + buf[88] = 0x7f; + if (p->xfermode & ATA_UDMA0) + buf[88] |= (1 << ((p->xfermode & 7) + 8)); + buf[222] = 0x1020; + buf[255] = 0x00a5; + ahci_checksum((uint8_t *)buf, sizeof(buf)); ahci_write_fis_piosetup(p); write_prdt(p, slot, cfis, (void *)buf, sizeof(buf)); - p->tfd = ATA_S_DSC | ATA_S_READY; - p->is |= AHCI_P_IX_DHR; - p->ci &= ~(1 << slot); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); } - ahci_generate_intr(p->pr_sc); } static void @@ -791,22 +1055,41 @@ atapi_inquiry(struct ahci_port *p, int slot, uint8_t *cfis) uint8_t buf[36]; uint8_t *acmd; int len; + uint32_t tfd; acmd = cfis + 0x40; - buf[0] = 0x05; - buf[1] = 0x80; - buf[2] = 0x00; - buf[3] = 0x21; - buf[4] = 31; - buf[5] = 0; - buf[6] = 0; - buf[7] = 0; - atapi_string(buf + 8, "BHYVE", 8); - atapi_string(buf + 16, "BHYVE DVD-ROM", 16); - atapi_string(buf + 32, "001", 4); - - len = sizeof(buf); + if (acmd[1] & 1) { /* VPD */ + if (acmd[2] == 0) { /* Supported VPD pages */ + buf[0] = 0x05; + buf[1] = 0; + buf[2] = 0; + buf[3] = 1; + buf[4] = 0; + len = 4 + buf[3]; + } else { + p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; + p->asc = 0x24; + tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, tfd); + return; + } + } else { + buf[0] = 0x05; + buf[1] = 0x80; + buf[2] = 0x00; + buf[3] = 0x21; + buf[4] = 31; + buf[5] = 0; + buf[6] = 0; + buf[7] = 0; + atapi_string(buf + 8, "BHYVE", 8); + atapi_string(buf + 16, "BHYVE DVD-ROM", 16); + atapi_string(buf + 32, "001", 4); + len = sizeof(buf); + } + if (len > acmd[4]) len = acmd[4]; cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; @@ -1010,8 +1293,20 @@ atapi_read_toc(struct ahci_port *p, int slot, uint8_t *cfis) } static void -atapi_read(struct ahci_port *p, int slot, uint8_t *cfis, - uint32_t done, int seek) +atapi_report_luns(struct ahci_port *p, int slot, uint8_t *cfis) +{ + uint8_t buf[16]; + + memset(buf, 0, sizeof(buf)); + buf[3] = 8; + + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + write_prdt(p, slot, cfis, buf, sizeof(buf)); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); +} + +static void +atapi_read(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done) { struct ahci_ioreq *aior; struct ahci_cmd_hdr *hdr; @@ -1021,14 +1316,13 @@ atapi_read(struct ahci_port *p, int slot, uint8_t *cfis, uint8_t *acmd; uint64_t lba; uint32_t len; - int i, err, iovcnt; + int err; sc = p->pr_sc; acmd = cfis + 0x40; hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); prdt = (struct ahci_prdt_entry *)(cfis + 0x80); - prdt += seek; lba = be32dec(acmd + 2); if (acmd[0] == READ_10) len = be16dec(acmd + 7); @@ -1053,37 +1347,14 @@ atapi_read(struct ahci_port *p, int slot, uint8_t *cfis, aior->done = done; breq = &aior->io_req; breq->br_offset = lba + done; - iovcnt = hdr->prdtl - seek; - if (iovcnt > BLOCKIF_IOV_MAX) { - aior->prdtl = iovcnt - BLOCKIF_IOV_MAX; - iovcnt = BLOCKIF_IOV_MAX; - } else - aior->prdtl = 0; - breq->br_iovcnt = iovcnt; + ahci_build_iov(p, aior, prdt, hdr->prdtl); - /* - * Mark this command in-flight. - */ + /* Mark this command in-flight. */ p->pending |= 1 << slot; - /* - * Stuff request onto busy list - */ + /* Stuff request onto busy list. */ TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist); - /* - * Build up the iovec based on the prdt - */ - for (i = 0; i < iovcnt; i++) { - uint32_t dbcsz; - - dbcsz = (prdt->dbc & DBCMASK) + 1; - breq->br_iov[i].iov_base = paddr_guest2host(ahci_ctx(sc), - prdt->dba, dbcsz); - breq->br_iov[i].iov_len = dbcsz; - aior->done += dbcsz; - prdt++; - } err = blockif_read(p->bctx, breq); assert(err == 0); } @@ -1278,9 +1549,12 @@ handle_packet_cmd(struct ahci_port *p, int slot, uint8_t *cfis) case READ_TOC: atapi_read_toc(p, slot, cfis); break; + case REPORT_LUNS: + atapi_report_luns(p, slot, cfis); + break; case READ_10: case READ_12: - atapi_read(p, slot, cfis, 0, 0); + atapi_read(p, slot, cfis, 0); break; case REQUEST_SENSE: atapi_request_sense(p, slot, cfis); @@ -1308,6 +1582,7 @@ static void ahci_handle_cmd(struct ahci_port *p, int slot, uint8_t *cfis) { + p->tfd |= ATA_S_BUSY; switch (cfis[2]) { case ATA_ATA_IDENTIFY: handle_identify(p, slot, cfis); @@ -1363,26 +1638,58 @@ ahci_handle_cmd(struct ahci_port *p, int slot, uint8_t *cfis) p->mult_sectors = cfis[12]; p->tfd = ATA_S_DSC | ATA_S_READY; } - p->is |= AHCI_P_IX_DP; - p->ci &= ~(1 << slot); - ahci_generate_intr(p->pr_sc); + ahci_write_fis_d2h(p, slot, cfis, p->tfd); break; + case ATA_READ: + case ATA_WRITE: + case ATA_READ48: + case ATA_WRITE48: + case ATA_READ_MUL: + case ATA_WRITE_MUL: + case ATA_READ_MUL48: + case ATA_WRITE_MUL48: case ATA_READ_DMA: case ATA_WRITE_DMA: case ATA_READ_DMA48: case ATA_WRITE_DMA48: case ATA_READ_FPDMA_QUEUED: case ATA_WRITE_FPDMA_QUEUED: - ahci_handle_dma(p, slot, cfis, 0, 0); + ahci_handle_rw(p, slot, cfis, 0); break; case ATA_FLUSHCACHE: case ATA_FLUSHCACHE48: ahci_handle_flush(p, slot, cfis); break; - case ATA_STANDBY_CMD: + case ATA_DATA_SET_MANAGEMENT: + if (cfis[11] == 0 && cfis[3] == ATA_DSM_TRIM && + cfis[13] == 0 && cfis[12] == 1) { + ahci_handle_dsm_trim(p, slot, cfis, 0); + break; + } + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + break; + case ATA_SEND_FPDMA_QUEUED: + if ((cfis[13] & 0x1f) == ATA_SFPDMA_DSM && + cfis[17] == 0 && cfis[16] == ATA_DSM_TRIM && + cfis[11] == 0 && cfis[13] == 1) { + ahci_handle_dsm_trim(p, slot, cfis, 0); + break; + } + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + break; + case ATA_READ_LOG_EXT: + case ATA_READ_LOG_DMA_EXT: + ahci_handle_read_log(p, slot, cfis); break; case ATA_NOP: + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + break; + case ATA_STANDBY_CMD: case ATA_STANDBY_IMMEDIATE: + case ATA_IDLE_CMD: case ATA_IDLE_IMMEDIATE: case ATA_SLEEP: ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); @@ -1392,17 +1699,15 @@ ahci_handle_cmd(struct ahci_port *p, int slot, uint8_t *cfis) break; case ATA_PACKET_CMD: if (!p->atapi) { - p->tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR; - p->is |= AHCI_P_IX_TFE; - ahci_generate_intr(p->pr_sc); + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); } else handle_packet_cmd(p, slot, cfis); break; default: WPRINTF("Unsupported cmd:%02x\n", cfis[2]); - p->tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR; - p->is |= AHCI_P_IX_TFE; - ahci_generate_intr(p->pr_sc); + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); break; } } @@ -1459,20 +1764,23 @@ ahci_handle_slot(struct ahci_port *p, int slot) static void ahci_handle_port(struct ahci_port *p) { - int i; if (!(p->cmd & AHCI_P_CMD_ST)) return; /* * Search for any new commands to issue ignoring those that - * are already in-flight. + * are already in-flight. Stop if device is busy or in error. */ - for (i = 0; (i < 32) && p->ci; i++) { - if ((p->ci & (1 << i)) && !(p->pending & (1 << i))) { + for (; (p->ci & ~p->pending) != 0; p->ccs = ((p->ccs + 1) & 31)) { + if ((p->tfd & (ATA_S_BUSY | ATA_S_DRQ)) != 0) + break; + if (p->waitforclear) + break; + if ((p->ci & ~p->pending & (1 << p->ccs)) != 0) { p->cmd &= ~AHCI_P_CMD_CCS_MASK; - p->cmd |= i << AHCI_P_CMD_CCS_SHIFT; - ahci_handle_slot(p, i); + p->cmd |= p->ccs << AHCI_P_CMD_CCS_SHIFT; + ahci_handle_slot(p, p->ccs); } } } @@ -1490,22 +1798,26 @@ ata_ioreq_cb(struct blockif_req *br, int err) struct pci_ahci_softc *sc; uint32_t tfd; uint8_t *cfis; - int pending, slot, ncq; + int slot, ncq, dsm; DPRINTF("%s %d\n", __func__, err); - ncq = 0; + ncq = dsm = 0; aior = br->br_param; p = aior->io_pr; cfis = aior->cfis; slot = aior->slot; - pending = aior->prdtl; sc = p->pr_sc; hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); if (cfis[2] == ATA_WRITE_FPDMA_QUEUED || - cfis[2] == ATA_READ_FPDMA_QUEUED) + cfis[2] == ATA_READ_FPDMA_QUEUED || + cfis[2] == ATA_SEND_FPDMA_QUEUED) ncq = 1; + if (cfis[2] == ATA_DATA_SET_MANAGEMENT || + (cfis[2] == ATA_SEND_FPDMA_QUEUED && + (cfis[13] & 0x1f) == ATA_SFPDMA_DSM)) + dsm = 1; pthread_mutex_lock(&sc->mtx); @@ -1519,29 +1831,24 @@ ata_ioreq_cb(struct blockif_req *br, int err) */ STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist); - if (pending && !err) { - ahci_handle_dma(p, slot, cfis, aior->done, - hdr->prdtl - pending); + if (!err) + hdr->prdbc = aior->done; + + if (!err && aior->more) { + if (dsm) + ahci_handle_dsm_trim(p, slot, cfis, aior->done); + else + ahci_handle_rw(p, slot, cfis, aior->done); goto out; } - if (!err && aior->done == aior->len) { + if (!err) tfd = ATA_S_READY | ATA_S_DSC; - if (ncq) - hdr->prdbc = 0; - else - hdr->prdbc = aior->len; - } else { + else tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR; - hdr->prdbc = 0; - if (ncq) - p->serr |= (1 << slot); - } - - if (ncq) { - p->sact &= ~(1 << slot); - ahci_write_fis_sdb(p, slot, tfd); - } else + if (ncq) + ahci_write_fis_sdb(p, slot, cfis, tfd); + else ahci_write_fis_d2h(p, slot, cfis, tfd); /* @@ -1550,6 +1857,7 @@ ata_ioreq_cb(struct blockif_req *br, int err) p->pending &= ~(1 << slot); ahci_check_stopped(p); + ahci_handle_port(p); out: pthread_mutex_unlock(&sc->mtx); DPRINTF("%s exit\n", __func__); @@ -1564,7 +1872,7 @@ atapi_ioreq_cb(struct blockif_req *br, int err) struct pci_ahci_softc *sc; uint8_t *cfis; uint32_t tfd; - int pending, slot; + int slot; DPRINTF("%s %d\n", __func__, err); @@ -1572,7 +1880,6 @@ atapi_ioreq_cb(struct blockif_req *br, int err) p = aior->io_pr; cfis = aior->cfis; slot = aior->slot; - pending = aior->prdtl; sc = p->pr_sc; hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + aior->slot * AHCI_CL_SIZE); @@ -1588,21 +1895,21 @@ atapi_ioreq_cb(struct blockif_req *br, int err) */ STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist); - if (pending && !err) { - atapi_read(p, slot, cfis, aior->done, hdr->prdtl - pending); + if (!err) + hdr->prdbc = aior->done; + + if (!err && aior->more) { + atapi_read(p, slot, cfis, aior->done); goto out; } - if (!err && aior->done == aior->len) { + if (!err) { tfd = ATA_S_READY | ATA_S_DSC; - hdr->prdbc = aior->len; } else { p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; p->asc = 0x21; tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; - hdr->prdbc = 0; } - cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; ahci_write_fis_d2h(p, slot, cfis, tfd); @@ -1612,6 +1919,7 @@ atapi_ioreq_cb(struct blockif_req *br, int err) p->pending &= ~(1 << slot); ahci_check_stopped(p); + ahci_handle_port(p); out: pthread_mutex_unlock(&sc->mtx); DPRINTF("%s exit\n", __func__); @@ -1676,8 +1984,15 @@ pci_ahci_port_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value) break; case AHCI_P_CMD: { - p->cmd = value; - + p->cmd &= ~(AHCI_P_CMD_ST | AHCI_P_CMD_SUD | AHCI_P_CMD_POD | + AHCI_P_CMD_CLO | AHCI_P_CMD_FRE | AHCI_P_CMD_APSTE | + AHCI_P_CMD_ATAPI | AHCI_P_CMD_DLAE | AHCI_P_CMD_ALPE | + AHCI_P_CMD_ASP | AHCI_P_CMD_ICC_MASK); + p->cmd |= (AHCI_P_CMD_ST | AHCI_P_CMD_SUD | AHCI_P_CMD_POD | + AHCI_P_CMD_CLO | AHCI_P_CMD_FRE | AHCI_P_CMD_APSTE | + AHCI_P_CMD_ATAPI | AHCI_P_CMD_DLAE | AHCI_P_CMD_ALPE | + AHCI_P_CMD_ASP | AHCI_P_CMD_ICC_MASK) & value; + if (!(value & AHCI_P_CMD_ST)) { ahci_port_stop(p); } else { @@ -1701,10 +2016,14 @@ pci_ahci_port_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value) } if (value & AHCI_P_CMD_CLO) { - p->tfd = 0; + p->tfd &= ~(ATA_S_BUSY | ATA_S_DRQ); p->cmd &= ~AHCI_P_CMD_CLO; } + if (value & AHCI_P_CMD_ICC_MASK) { + p->cmd &= ~AHCI_P_CMD_ICC_MASK; + } + ahci_handle_port(p); break; } @@ -1714,10 +2033,10 @@ pci_ahci_port_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value) WPRINTF("pci_ahci_port: read only registers 0x%"PRIx64"\n", offset); break; case AHCI_P_SCTL: + p->sctl = value; if (!(p->cmd & AHCI_P_CMD_ST)) { if (value & ATA_SC_DET_RESET) ahci_port_reset(p); - p->sctl = value; } break; case AHCI_P_SERR: @@ -1774,7 +2093,7 @@ pci_ahci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, struct pci_ahci_softc *sc = pi->pi_arg; assert(baridx == 5); - assert(size == 4); + assert((offset % 4) == 0 && size == 4); pthread_mutex_lock(&sc->mtx); @@ -1863,24 +2182,29 @@ pci_ahci_port_read(struct pci_ahci_softc *sc, uint64_t offset) static uint64_t pci_ahci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size) + uint64_t regoff, int size) { struct pci_ahci_softc *sc = pi->pi_arg; + uint64_t offset; uint32_t value; assert(baridx == 5); - assert(size == 4); + assert(size == 1 || size == 2 || size == 4); + assert((regoff & (size - 1)) == 0); pthread_mutex_lock(&sc->mtx); + offset = regoff & ~0x3; /* round down to a multiple of 4 bytes */ if (offset < AHCI_OFFSET) value = pci_ahci_host_read(sc, offset); else if (offset < AHCI_OFFSET + sc->ports * AHCI_STEP) value = pci_ahci_port_read(sc, offset); else { value = 0; - WPRINTF("pci_ahci: unknown i/o read offset 0x%"PRIx64"\n", offset); + WPRINTF("pci_ahci: unknown i/o read offset 0x%"PRIx64"\n", + regoff); } + value >>= 8 * (regoff & 0x3); pthread_mutex_unlock(&sc->mtx); @@ -1894,6 +2218,8 @@ pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts, int atapi) struct blockif_ctxt *bctxt; struct pci_ahci_softc *sc; int ret, slots; + MD5_CTX mdctx; + u_char digest[16]; ret = 0; @@ -1931,6 +2257,16 @@ pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts, int atapi) sc->port[0].pr_sc = sc; /* + * Create an identifier for the backing file. Use parts of the + * md5 sum of the filename + */ + MD5Init(&mdctx); + MD5Update(&mdctx, opts, strlen(opts)); + MD5Final(digest, &mdctx); + sprintf(sc->port[0].ident, "BHYVE-%02X%02X-%02X%02X-%02X%02X", + digest[0], digest[1], digest[2], digest[3], digest[4], digest[5]); + + /* * Allocate blockif request structures and add them * to the free list */ @@ -1968,7 +2304,8 @@ pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts, int atapi) open_fail: if (ret) { - blockif_close(sc->port[0].bctx); + if (sc->port[0].bctx != NULL) + blockif_close(sc->port[0].bctx); free(sc); } diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c index 6b906ed..03ff0c0 100644 --- a/usr.sbin/bhyve/pci_emul.c +++ b/usr.sbin/bhyve/pci_emul.c @@ -59,17 +59,6 @@ __FBSDID("$FreeBSD$"); #define CONF1_ENABLE 0x80000000ul -#define CFGWRITE(pi,off,val,b) \ -do { \ - if ((b) == 1) { \ - pci_set_cfgdata8((pi),(off),(val)); \ - } else if ((b) == 2) { \ - pci_set_cfgdata16((pi),(off),(val)); \ - } else { \ - pci_set_cfgdata32((pi),(off),(val)); \ - } \ -} while (0) - #define MAXBUSES (PCI_BUSMAX + 1) #define MAXSLOTS (PCI_SLOTMAX + 1) #define MAXFUNCS (PCI_FUNCMAX + 1) @@ -124,6 +113,30 @@ static void pci_lintr_update(struct pci_devinst *pi); static void pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, int coff, int bytes, uint32_t *val); +static __inline void +CFGWRITE(struct pci_devinst *pi, int coff, uint32_t val, int bytes) +{ + + if (bytes == 1) + pci_set_cfgdata8(pi, coff, val); + else if (bytes == 2) + pci_set_cfgdata16(pi, coff, val); + else + pci_set_cfgdata32(pi, coff, val); +} + +static __inline uint32_t +CFGREAD(struct pci_devinst *pi, int coff, int bytes) +{ + + if (bytes == 1) + return (pci_get_cfgdata8(pi, coff)); + else if (bytes == 2) + return (pci_get_cfgdata16(pi, coff)); + else + return (pci_get_cfgdata32(pi, coff)); +} + /* * I/O access */ @@ -1653,27 +1666,31 @@ pci_emul_hdrtype_fixup(int bus, int slot, int off, int bytes, uint32_t *rv) } } -static uint32_t -bits_changed(uint32_t old, uint32_t new, uint32_t mask) -{ - - return ((old ^ new) & mask); -} - static void -pci_emul_cmdwrite(struct pci_devinst *pi, uint32_t new, int bytes) +pci_emul_cmdsts_write(struct pci_devinst *pi, int coff, uint32_t new, int bytes) { - int i; - uint16_t old; + int i, rshift; + uint32_t cmd, cmd2, changed, old, readonly; + + cmd = pci_get_cfgdata16(pi, PCIR_COMMAND); /* stash old value */ /* - * The command register is at an offset of 4 bytes and thus the - * guest could write 1, 2 or 4 bytes starting at this offset. + * From PCI Local Bus Specification 3.0 sections 6.2.2 and 6.2.3. + * + * XXX Bits 8, 11, 12, 13, 14 and 15 in the status register are + * 'write 1 to clear'. However these bits are not set to '1' by + * any device emulation so it is simpler to treat them as readonly. */ + rshift = (coff & 0x3) * 8; + readonly = 0xFFFFF880 >> rshift; - old = pci_get_cfgdata16(pi, PCIR_COMMAND); /* stash old value */ - CFGWRITE(pi, PCIR_COMMAND, new, bytes); /* update config */ - new = pci_get_cfgdata16(pi, PCIR_COMMAND); /* get updated value */ + old = CFGREAD(pi, coff, bytes); + new &= ~readonly; + new |= (old & readonly); + CFGWRITE(pi, coff, new, bytes); /* update config */ + + cmd2 = pci_get_cfgdata16(pi, PCIR_COMMAND); /* get updated value */ + changed = cmd ^ cmd2; /* * If the MMIO or I/O address space decoding has changed then @@ -1686,7 +1703,7 @@ pci_emul_cmdwrite(struct pci_devinst *pi, uint32_t new, int bytes) break; case PCIBAR_IO: /* I/O address space decoding changed? */ - if (bits_changed(old, new, PCIM_CMD_PORTEN)) { + if (changed & PCIM_CMD_PORTEN) { if (porten(pi)) register_bar(pi, i); else @@ -1696,7 +1713,7 @@ pci_emul_cmdwrite(struct pci_devinst *pi, uint32_t new, int bytes) case PCIBAR_MEM32: case PCIBAR_MEM64: /* MMIO address space decoding changed? */ - if (bits_changed(old, new, PCIM_CMD_MEMEN)) { + if (changed & PCIM_CMD_MEMEN) { if (memen(pi)) register_bar(pi, i); else @@ -1776,14 +1793,8 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, needcfg = 1; } - if (needcfg) { - if (bytes == 1) - *eax = pci_get_cfgdata8(pi, coff); - else if (bytes == 2) - *eax = pci_get_cfgdata16(pi, coff); - else - *eax = pci_get_cfgdata32(pi, coff); - } + if (needcfg) + *eax = CFGREAD(pi, coff, bytes); pci_emul_hdrtype_fixup(bus, slot, coff, bytes, eax); } else { @@ -1853,8 +1864,8 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, } else if (pci_emul_iscap(pi, coff)) { pci_emul_capwrite(pi, coff, bytes, *eax); - } else if (coff == PCIR_COMMAND) { - pci_emul_cmdwrite(pi, *eax, bytes); + } else if (coff >= PCIR_COMMAND && coff < PCIR_REVID) { + pci_emul_cmdsts_write(pi, coff, *eax, bytes); } else { CFGWRITE(pi, coff, *eax, bytes); } @@ -1927,7 +1938,7 @@ INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+3, IOPORT_F_INOUT, pci_emul_cfgdata); #define DMEMSZ 4096 struct pci_emul_dsoftc { uint8_t ioregs[DIOSZ]; - uint8_t memregs[DMEMSZ]; + uint8_t memregs[2][DMEMSZ]; }; #define PCI_EMUL_MSI_MSGS 4 @@ -1956,6 +1967,9 @@ pci_emul_dinit(struct vmctx *ctx, struct pci_devinst *pi, char *opts) error = pci_emul_alloc_bar(pi, 1, PCIBAR_MEM32, DMEMSZ); assert(error == 0); + error = pci_emul_alloc_bar(pi, 2, PCIBAR_MEM32, DMEMSZ); + assert(error == 0); + return (0); } @@ -1995,21 +2009,23 @@ pci_emul_diow(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, } } - if (baridx == 1) { + if (baridx == 1 || baridx == 2) { if (offset + size > DMEMSZ) { printf("diow: memw too large, offset %ld size %d\n", offset, size); return; } + i = baridx - 1; /* 'memregs' index */ + if (size == 1) { - sc->memregs[offset] = value; + sc->memregs[i][offset] = value; } else if (size == 2) { - *(uint16_t *)&sc->memregs[offset] = value; + *(uint16_t *)&sc->memregs[i][offset] = value; } else if (size == 4) { - *(uint32_t *)&sc->memregs[offset] = value; + *(uint32_t *)&sc->memregs[i][offset] = value; } else if (size == 8) { - *(uint64_t *)&sc->memregs[offset] = value; + *(uint64_t *)&sc->memregs[i][offset] = value; } else { printf("diow: memw unknown size %d\n", size); } @@ -2019,7 +2035,7 @@ pci_emul_diow(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, */ } - if (baridx > 1) { + if (baridx > 2) { printf("diow: unknown bar idx %d\n", baridx); } } @@ -2030,6 +2046,7 @@ pci_emul_dior(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, { struct pci_emul_dsoftc *sc = pi->pi_arg; uint32_t value; + int i; if (baridx == 0) { if (offset + size > DIOSZ) { @@ -2048,29 +2065,31 @@ pci_emul_dior(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, printf("dior: ior unknown size %d\n", size); } } - - if (baridx == 1) { + + if (baridx == 1 || baridx == 2) { if (offset + size > DMEMSZ) { printf("dior: memr too large, offset %ld size %d\n", offset, size); return (0); } - + + i = baridx - 1; /* 'memregs' index */ + if (size == 1) { - value = sc->memregs[offset]; + value = sc->memregs[i][offset]; } else if (size == 2) { - value = *(uint16_t *) &sc->memregs[offset]; + value = *(uint16_t *) &sc->memregs[i][offset]; } else if (size == 4) { - value = *(uint32_t *) &sc->memregs[offset]; + value = *(uint32_t *) &sc->memregs[i][offset]; } else if (size == 8) { - value = *(uint64_t *) &sc->memregs[offset]; + value = *(uint64_t *) &sc->memregs[i][offset]; } else { printf("dior: ior unknown size %d\n", size); } } - if (baridx > 1) { + if (baridx > 2) { printf("dior: unknown bar idx %d\n", baridx); return (0); } diff --git a/usr.sbin/bhyve/pci_hostbridge.c b/usr.sbin/bhyve/pci_hostbridge.c index 54a25ae..5c9ea28 100644 --- a/usr.sbin/bhyve/pci_hostbridge.c +++ b/usr.sbin/bhyve/pci_hostbridge.c @@ -38,7 +38,7 @@ pci_hostbridge_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) /* config space */ pci_set_cfgdata16(pi, PCIR_VENDOR, 0x1275); /* NetApp */ pci_set_cfgdata16(pi, PCIR_DEVICE, 0x1275); /* NetApp */ - pci_set_cfgdata8(pi, PCIR_HDRTYPE, PCIM_HDRTYPE_BRIDGE); + pci_set_cfgdata8(pi, PCIR_HDRTYPE, PCIM_HDRTYPE_NORMAL); pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_HOST); diff --git a/usr.sbin/bhyve/pci_irq.c b/usr.sbin/bhyve/pci_irq.c index 20e033f..f22b15c 100644 --- a/usr.sbin/bhyve/pci_irq.c +++ b/usr.sbin/bhyve/pci_irq.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014 Advanced Computing Technologies LLC + * Copyright (c) 2014 Hudson River Trading LLC * Written by: John H. Baldwin <jhb@FreeBSD.org> * All rights reserved. * diff --git a/usr.sbin/bhyve/pci_irq.h b/usr.sbin/bhyve/pci_irq.h index 9d331a5..24f9c99 100644 --- a/usr.sbin/bhyve/pci_irq.h +++ b/usr.sbin/bhyve/pci_irq.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014 Advanced Computing Technologies LLC + * Copyright (c) 2014 Hudson River Trading LLC * Written by: John H. Baldwin <jhb@FreeBSD.org> * All rights reserved. * diff --git a/usr.sbin/bhyve/pci_virtio_block.c b/usr.sbin/bhyve/pci_virtio_block.c index c66ad68..8500be6 100644 --- a/usr.sbin/bhyve/pci_virtio_block.c +++ b/usr.sbin/bhyve/pci_virtio_block.c @@ -51,11 +51,10 @@ __FBSDID("$FreeBSD$"); #include "bhyverun.h" #include "pci_emul.h" #include "virtio.h" +#include "block_if.h" #define VTBLK_RINGSZ 64 -#define VTBLK_MAXSEGS 32 - #define VTBLK_S_OK 0 #define VTBLK_S_IOERR 1 #define VTBLK_S_UNSUPP 2 @@ -64,7 +63,9 @@ __FBSDID("$FreeBSD$"); /* Capability bits */ #define VTBLK_F_SEG_MAX (1 << 2) /* Maximum request segments */ -#define VTBLK_F_BLK_SIZE (1 << 6) /* cfg block size valid */ +#define VTBLK_F_BLK_SIZE (1 << 6) /* cfg block size valid */ +#define VTBLK_F_FLUSH (1 << 9) /* Cache flush support */ +#define VTBLK_F_TOPOLOGY (1 << 10) /* Optimal I/O alignment */ /* * Host capabilities @@ -72,6 +73,8 @@ __FBSDID("$FreeBSD$"); #define VTBLK_S_HOSTCAPS \ ( VTBLK_F_SEG_MAX | \ VTBLK_F_BLK_SIZE | \ + VTBLK_F_FLUSH | \ + VTBLK_F_TOPOLOGY | \ VIRTIO_RING_F_INDIRECT_DESC ) /* indirect descriptors */ /* @@ -81,11 +84,19 @@ struct vtblk_config { uint64_t vbc_capacity; uint32_t vbc_size_max; uint32_t vbc_seg_max; - uint16_t vbc_geom_c; - uint8_t vbc_geom_h; - uint8_t vbc_geom_s; + struct { + uint16_t cylinders; + uint8_t heads; + uint8_t sectors; + } vbc_geometry; uint32_t vbc_blk_size; - uint32_t vbc_sectors_max; + struct { + uint8_t physical_block_exp; + uint8_t alignment_offset; + uint16_t min_io_size; + uint32_t opt_io_size; + } vbc_topology; + uint8_t vbc_writeback; } __packed; /* @@ -110,6 +121,13 @@ static int pci_vtblk_debug; #define DPRINTF(params) if (pci_vtblk_debug) printf params #define WPRINTF(params) printf params +struct pci_vtblk_ioreq { + struct blockif_req io_req; + struct pci_vtblk_softc *io_sc; + uint8_t *io_status; + uint16_t io_idx; +}; + /* * Per-device softc */ @@ -117,9 +135,10 @@ struct pci_vtblk_softc { struct virtio_softc vbsc_vs; pthread_mutex_t vsc_mtx; struct vqueue_info vbsc_vq; - int vbsc_fd; - struct vtblk_config vbsc_cfg; + struct vtblk_config vbsc_cfg; + struct blockif_ctxt *bc; char vbsc_ident[VTBLK_BLK_ID_BYTES]; + struct pci_vtblk_ioreq vbsc_ios[VTBLK_RINGSZ]; }; static void pci_vtblk_reset(void *); @@ -149,19 +168,43 @@ pci_vtblk_reset(void *vsc) } static void +pci_vtblk_done(struct blockif_req *br, int err) +{ + struct pci_vtblk_ioreq *io = br->br_param; + struct pci_vtblk_softc *sc = io->io_sc; + + /* convert errno into a virtio block error return */ + if (err == EOPNOTSUPP || err == ENOSYS) + *io->io_status = VTBLK_S_UNSUPP; + else if (err != 0) + *io->io_status = VTBLK_S_IOERR; + else + *io->io_status = VTBLK_S_OK; + + /* + * Return the descriptor back to the host. + * We wrote 1 byte (our status) to host. + */ + pthread_mutex_lock(&sc->vsc_mtx); + vq_relchain(&sc->vbsc_vq, io->io_idx, 1); + vq_endchains(&sc->vbsc_vq, 0); + pthread_mutex_unlock(&sc->vsc_mtx); +} + +static void pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq) { struct virtio_blk_hdr *vbh; - uint8_t *status; + struct pci_vtblk_ioreq *io; int i, n; int err; - int iolen; + ssize_t iolen; int writeop, type; off_t offset; - struct iovec iov[VTBLK_MAXSEGS + 2]; - uint16_t flags[VTBLK_MAXSEGS + 2]; + struct iovec iov[BLOCKIF_IOV_MAX + 2]; + uint16_t idx, flags[BLOCKIF_IOV_MAX + 2]; - n = vq_getchain(vq, iov, VTBLK_MAXSEGS + 2, flags); + n = vq_getchain(vq, &idx, iov, BLOCKIF_IOV_MAX + 2, flags); /* * The first descriptor will be the read-only fixed header, @@ -171,13 +214,16 @@ pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq) * XXX - note - this fails on crash dump, which does a * VIRTIO_BLK_T_FLUSH with a zero transfer length */ - assert(n >= 2 && n <= VTBLK_MAXSEGS + 2); + assert(n >= 2 && n <= BLOCKIF_IOV_MAX + 2); + io = &sc->vbsc_ios[idx]; assert((flags[0] & VRING_DESC_F_WRITE) == 0); assert(iov[0].iov_len == sizeof(struct virtio_blk_hdr)); vbh = iov[0].iov_base; - - status = iov[--n].iov_base; + memcpy(&io->io_req.br_iov, &iov[1], sizeof(struct iovec) * (n - 2)); + io->io_req.br_iovcnt = n - 2; + io->io_req.br_offset = vbh->vbh_sector * DEV_BSIZE; + io->io_status = iov[--n].iov_base; assert(iov[n].iov_len == 1); assert(flags[n] & VRING_DESC_F_WRITE); @@ -189,8 +235,6 @@ pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq) type = vbh->vbh_type & ~VBH_FLAG_BARRIER; writeop = (type == VBH_OP_WRITE); - offset = vbh->vbh_sector * DEV_BSIZE; - iolen = 0; for (i = 1; i < n; i++) { /* @@ -202,46 +246,35 @@ pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq) assert(((flags[i] & VRING_DESC_F_WRITE) == 0) == writeop); iolen += iov[i].iov_len; } + io->io_req.br_resid = iolen; - DPRINTF(("virtio-block: %s op, %d bytes, %d segs, offset %ld\n\r", + DPRINTF(("virtio-block: %s op, %zd bytes, %d segs, offset %ld\n\r", writeop ? "write" : "read/ident", iolen, i - 1, offset)); switch (type) { - case VBH_OP_WRITE: - err = pwritev(sc->vbsc_fd, iov + 1, i - 1, offset); - break; case VBH_OP_READ: - err = preadv(sc->vbsc_fd, iov + 1, i - 1, offset); + err = blockif_read(sc->bc, &io->io_req); break; - case VBH_OP_IDENT: - /* Assume a single buffer */ - strlcpy(iov[1].iov_base, sc->vbsc_ident, - MIN(iov[1].iov_len, sizeof(sc->vbsc_ident))); - err = 0; + case VBH_OP_WRITE: + err = blockif_write(sc->bc, &io->io_req); break; case VBH_OP_FLUSH: case VBH_OP_FLUSH_OUT: - err = fsync(sc->vbsc_fd); + err = blockif_flush(sc->bc, &io->io_req); break; + case VBH_OP_IDENT: + /* Assume a single buffer */ + /* S/n equal to buffer is not zero-terminated. */ + memset(iov[1].iov_base, 0, iov[1].iov_len); + strncpy(iov[1].iov_base, sc->vbsc_ident, + MIN(iov[1].iov_len, sizeof(sc->vbsc_ident))); + pci_vtblk_done(&io->io_req, 0); + return; default: - err = -ENOSYS; - break; + pci_vtblk_done(&io->io_req, EOPNOTSUPP); + return; } - - /* convert errno into a virtio block error return */ - if (err < 0) { - if (err == -ENOSYS) - *status = VTBLK_S_UNSUPP; - else - *status = VTBLK_S_IOERR; - } else - *status = VTBLK_S_OK; - - /* - * Return the descriptor back to the host. - * We wrote 1 byte (our status) to host. - */ - vq_relchain(vq, 1); + assert(err == 0); } static void @@ -249,22 +282,20 @@ pci_vtblk_notify(void *vsc, struct vqueue_info *vq) { struct pci_vtblk_softc *sc = vsc; - vq_startchains(vq); while (vq_has_descs(vq)) pci_vtblk_proc(sc, vq); - vq_endchains(vq, 1); /* Generate interrupt if appropriate. */ } static int pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) { - struct stat sbuf; + char bident[sizeof("XX:X:X")]; + struct blockif_ctxt *bctxt; MD5_CTX mdctx; u_char digest[16]; struct pci_vtblk_softc *sc; - off_t size; - int fd; - int sectsz; + off_t size; + int i, sectsz, sts, sto; if (opts == NULL) { printf("virtio-block: backing device required\n"); @@ -274,38 +305,26 @@ pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) /* * The supplied backing file has to exist */ - fd = open(opts, O_RDWR); - if (fd < 0) { + snprintf(bident, sizeof(bident), "%d:%d", pi->pi_slot, pi->pi_func); + bctxt = blockif_open(opts, bident); + if (bctxt == NULL) { perror("Could not open backing file"); return (1); } - if (fstat(fd, &sbuf) < 0) { - perror("Could not stat backing file"); - close(fd); - return (1); - } - - /* - * Deal with raw devices - */ - size = sbuf.st_size; - sectsz = DEV_BSIZE; - if (S_ISCHR(sbuf.st_mode)) { - if (ioctl(fd, DIOCGMEDIASIZE, &size) < 0 || - ioctl(fd, DIOCGSECTORSIZE, §sz)) { - perror("Could not fetch dev blk/sector size"); - close(fd); - return (1); - } - assert(size != 0); - assert(sectsz != 0); - } + size = blockif_size(bctxt); + sectsz = blockif_sectsz(bctxt); + blockif_psectsz(bctxt, &sts, &sto); sc = calloc(1, sizeof(struct pci_vtblk_softc)); - - /* record fd of storage device/file */ - sc->vbsc_fd = fd; + sc->bc = bctxt; + for (i = 0; i < VTBLK_RINGSZ; i++) { + struct pci_vtblk_ioreq *io = &sc->vbsc_ios[i]; + io->io_req.br_callback = pci_vtblk_done; + io->io_req.br_param = io; + io->io_sc = sc; + io->io_idx = i; + } pthread_mutex_init(&sc->vsc_mtx, NULL); @@ -328,13 +347,19 @@ pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) /* setup virtio block config space */ sc->vbsc_cfg.vbc_capacity = size / DEV_BSIZE; /* 512-byte units */ - sc->vbsc_cfg.vbc_seg_max = VTBLK_MAXSEGS; - sc->vbsc_cfg.vbc_blk_size = sectsz; sc->vbsc_cfg.vbc_size_max = 0; /* not negotiated */ - sc->vbsc_cfg.vbc_geom_c = 0; /* no geometry */ - sc->vbsc_cfg.vbc_geom_h = 0; - sc->vbsc_cfg.vbc_geom_s = 0; - sc->vbsc_cfg.vbc_sectors_max = 0; + sc->vbsc_cfg.vbc_seg_max = BLOCKIF_IOV_MAX; + sc->vbsc_cfg.vbc_geometry.cylinders = 0; /* no geometry */ + sc->vbsc_cfg.vbc_geometry.heads = 0; + sc->vbsc_cfg.vbc_geometry.sectors = 0; + sc->vbsc_cfg.vbc_blk_size = sectsz; + sc->vbsc_cfg.vbc_topology.physical_block_exp = + (sts > sectsz) ? (ffsll(sts / sectsz) - 1) : 0; + sc->vbsc_cfg.vbc_topology.alignment_offset = + (sto != 0) ? ((sts - sto) / sectsz) : 0; + sc->vbsc_cfg.vbc_topology.min_io_size = 0; + sc->vbsc_cfg.vbc_topology.opt_io_size = 0; + sc->vbsc_cfg.vbc_writeback = 0; /* * Should we move some of this into virtio.c? Could @@ -345,11 +370,13 @@ pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE); pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_BLOCK); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); - pci_lintr_request(pi); - - if (vi_intr_init(&sc->vbsc_vs, 1, fbsdrun_virtio_msix())) + if (vi_intr_init(&sc->vbsc_vs, 1, fbsdrun_virtio_msix())) { + blockif_close(sc->bc); + free(sc); return (1); + } vi_set_io_bar(&sc->vbsc_vs, 0); return (0); } diff --git a/usr.sbin/bhyve/pci_virtio_net.c b/usr.sbin/bhyve/pci_virtio_net.c index 5ac9ecd..3781ea9 100644 --- a/usr.sbin/bhyve/pci_virtio_net.c +++ b/usr.sbin/bhyve/pci_virtio_net.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <sys/select.h> #include <sys/uio.h> #include <sys/ioctl.h> +#include <machine/atomic.h> #include <net/ethernet.h> #include <errno.h> @@ -288,6 +289,7 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) struct vqueue_info *vq; void *vrx; int len, n; + uint16_t idx; /* * Should never be called without a valid tap fd @@ -310,7 +312,6 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) * Check for available rx buffers */ vq = &sc->vsc_queues[VTNET_RXQ]; - vq_startchains(vq); if (!vq_has_descs(vq)) { /* * Drop the packet and try later. Interrupt on @@ -325,7 +326,7 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) /* * Get descriptor chain. */ - n = vq_getchain(vq, iov, VTNET_MAXSEGS, NULL); + n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); assert(n >= 1 && n <= VTNET_MAXSEGS); /* @@ -342,6 +343,7 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) * No more packets, but still some avail ring * entries. Interrupt if needed/appropriate. */ + vq_retchain(vq); vq_endchains(vq, 0); return; } @@ -362,7 +364,7 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) /* * Release this chain and handle more chains. */ - vq_relchain(vq, len + sc->rx_vhdrlen); + vq_relchain(vq, idx, len + sc->rx_vhdrlen); } while (vq_has_descs(vq)); /* Interrupt if needed, including for NOTIFY_ON_EMPTY. */ @@ -392,6 +394,7 @@ pci_vtnet_ping_rxq(void *vsc, struct vqueue_info *vq) */ if (sc->vsc_rx_ready == 0) { sc->vsc_rx_ready = 1; + vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; } } @@ -401,13 +404,14 @@ pci_vtnet_proctx(struct pci_vtnet_softc *sc, struct vqueue_info *vq) struct iovec iov[VTNET_MAXSEGS + 1]; int i, n; int plen, tlen; + uint16_t idx; /* * Obtain chain of descriptors. The first one is * really the header descriptor, so we need to sum * up two lengths: packet length and transfer length. */ - n = vq_getchain(vq, iov, VTNET_MAXSEGS, NULL); + n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); assert(n >= 1 && n <= VTNET_MAXSEGS); plen = 0; tlen = iov[0].iov_len; @@ -420,7 +424,7 @@ pci_vtnet_proctx(struct pci_vtnet_softc *sc, struct vqueue_info *vq) pci_vtnet_tap_tx(sc, &iov[1], n - 1, plen); /* chain is processed, release it and set tlen */ - vq_relchain(vq, tlen); + vq_relchain(vq, idx, tlen); } static void @@ -436,6 +440,7 @@ pci_vtnet_ping_txq(void *vsc, struct vqueue_info *vq) /* Signal the tx thread for processing */ pthread_mutex_lock(&sc->tx_mtx); + vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; if (sc->tx_in_progress == 0) pthread_cond_signal(&sc->tx_cond); pthread_mutex_unlock(&sc->tx_mtx); @@ -449,7 +454,7 @@ pci_vtnet_tx_thread(void *param) { struct pci_vtnet_softc *sc = param; struct vqueue_info *vq; - int have_work, error; + int error; vq = &sc->vsc_queues[VTNET_TXQ]; @@ -463,23 +468,20 @@ pci_vtnet_tx_thread(void *param) for (;;) { /* note - tx mutex is locked here */ - do { - if (sc->resetting) - have_work = 0; - else - have_work = vq_has_descs(vq); - - if (!have_work) { - sc->tx_in_progress = 0; - error = pthread_cond_wait(&sc->tx_cond, - &sc->tx_mtx); - assert(error == 0); - } - } while (!have_work); + while (sc->resetting || !vq_has_descs(vq)) { + vq->vq_used->vu_flags &= ~VRING_USED_F_NO_NOTIFY; + mb(); + if (!sc->resetting && vq_has_descs(vq)) + break; + + sc->tx_in_progress = 0; + error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx); + assert(error == 0); + } + vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; sc->tx_in_progress = 1; pthread_mutex_unlock(&sc->tx_mtx); - vq_startchains(vq); do { /* * Run through entries, placing them into @@ -638,11 +640,10 @@ pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); - pci_lintr_request(pi); - - /* link always up */ - sc->vsc_config.status = 1; + /* Link is up if we managed to open tap device. */ + sc->vsc_config.status = (opts == NULL || sc->vsc_tapfd >= 0); /* use BAR 1 to map MSI-X table and PBA, if we're using MSI-X */ if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix())) diff --git a/usr.sbin/bhyve/pci_virtio_rnd.c b/usr.sbin/bhyve/pci_virtio_rnd.c index 0a31080..78448f5 100644 --- a/usr.sbin/bhyve/pci_virtio_rnd.c +++ b/usr.sbin/bhyve/pci_virtio_rnd.c @@ -103,18 +103,17 @@ pci_vtrnd_notify(void *vsc, struct vqueue_info *vq) struct iovec iov; struct pci_vtrnd_softc *sc; int len; + uint16_t idx; sc = vsc; - vq_startchains(vq); - if (sc->vrsc_fd < 0) { vq_endchains(vq, 0); return; } while (vq_has_descs(vq)) { - vq_getchain(vq, &iov, 1, NULL); + vq_getchain(vq, &idx, &iov, 1, NULL); len = read(sc->vrsc_fd, iov.iov_base, iov.iov_len); @@ -126,7 +125,7 @@ pci_vtrnd_notify(void *vsc, struct vqueue_info *vq) /* * Release this chain and handle more */ - vq_relchain(vq, len); + vq_relchain(vq, idx, len); } vq_endchains(vq, 1); /* Generate interrupt if appropriate. */ } @@ -171,6 +170,7 @@ pci_vtrnd_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_CRYPTO); pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_ENTROPY); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); if (vi_intr_init(&sc->vrsc_vs, 1, fbsdrun_virtio_msix())) return (1); diff --git a/usr.sbin/bhyve/pm.c b/usr.sbin/bhyve/pm.c index f5a2d43..f7c1c23 100644 --- a/usr.sbin/bhyve/pm.c +++ b/usr.sbin/bhyve/pm.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2013 Advanced Computing Technologies LLC + * Copyright (c) 2013 Hudson River Trading LLC * Written by: John H. Baldwin <jhb@FreeBSD.org> * All rights reserved. * diff --git a/usr.sbin/bhyve/rtc.c b/usr.sbin/bhyve/rtc.c index 459c900..5c70154 100644 --- a/usr.sbin/bhyve/rtc.c +++ b/usr.sbin/bhyve/rtc.c @@ -30,10 +30,7 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> -#include <sys/time.h> -#include <stdio.h> -#include <string.h> #include <time.h> #include <assert.h> @@ -41,47 +38,11 @@ __FBSDID("$FreeBSD$"); #include <vmmapi.h> #include "acpi.h" -#include "inout.h" #include "pci_lpc.h" #include "rtc.h" -#define IO_RTC 0x70 +#define IO_RTC 0x70 -#define RTC_SEC 0x00 /* seconds */ -#define RTC_SEC_ALARM 0x01 -#define RTC_MIN 0x02 -#define RTC_MIN_ALARM 0x03 -#define RTC_HRS 0x04 -#define RTC_HRS_ALARM 0x05 -#define RTC_WDAY 0x06 -#define RTC_DAY 0x07 -#define RTC_MONTH 0x08 -#define RTC_YEAR 0x09 -#define RTC_CENTURY 0x32 /* current century */ - -#define RTC_STATUSA 0xA -#define RTCSA_TUP 0x80 /* time update, don't look now */ - -#define RTC_STATUSB 0xB -#define RTCSB_DST 0x01 -#define RTCSB_24HR 0x02 -#define RTCSB_BIN 0x04 /* 0 = BCD, 1 = Binary */ -#define RTCSB_PINTR 0x40 /* 1 = enable periodic clock interrupt */ -#define RTCSB_HALT 0x80 /* stop clock updates */ - -#define RTC_INTR 0x0c /* status register C (R) interrupt source */ - -#define RTC_STATUSD 0x0d /* status register D (R) Lost Power */ -#define RTCSD_PWR 0x80 /* clock power OK */ - -#define RTC_NVRAM_START 0x0e -#define RTC_NVRAM_END 0x7f -#define RTC_NVRAM_SZ (128 - RTC_NVRAM_START) -#define nvoff(x) ((x) - RTC_NVRAM_START) - -#define RTC_DIAG 0x0e -#define RTC_RSTCODE 0x0f -#define RTC_EQUIPMENT 0x14 #define RTC_LMEM_LSB 0x34 #define RTC_LMEM_MSB 0x35 #define RTC_HMEM_LSB 0x5b @@ -92,249 +53,30 @@ __FBSDID("$FreeBSD$"); #define m_16MB (16*1024*1024) #define m_4GB (4ULL*1024*1024*1024) -static int addr; - -static uint8_t rtc_nvram[RTC_NVRAM_SZ]; - -/* XXX initialize these to default values as they would be from BIOS */ -static uint8_t status_a, status_b; - -static struct { - uint8_t hours; - uint8_t mins; - uint8_t secs; -} rtc_alarm; - -static u_char const bin2bcd_data[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99 -}; -#define bin2bcd(bin) (bin2bcd_data[bin]) - -#define rtcout(val) ((status_b & RTCSB_BIN) ? (val) : bin2bcd((val))) - -static void -timevalfix(struct timeval *t1) -{ - - if (t1->tv_usec < 0) { - t1->tv_sec--; - t1->tv_usec += 1000000; - } - if (t1->tv_usec >= 1000000) { - t1->tv_sec++; - t1->tv_usec -= 1000000; - } -} - -static void -timevalsub(struct timeval *t1, const struct timeval *t2) -{ - - t1->tv_sec -= t2->tv_sec; - t1->tv_usec -= t2->tv_usec; - timevalfix(t1); -} - -static int -rtc_addr_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) -{ - if (bytes != 1) - return (-1); - - if (in) { - /* straight read of this register will return 0xFF */ - *eax = 0xff; - return (0); - } - - switch (*eax & 0x7f) { - case RTC_SEC: - case RTC_SEC_ALARM: - case RTC_MIN: - case RTC_MIN_ALARM: - case RTC_HRS: - case RTC_HRS_ALARM: - case RTC_WDAY: - case RTC_DAY: - case RTC_MONTH: - case RTC_YEAR: - case RTC_STATUSA: - case RTC_STATUSB: - case RTC_INTR: - case RTC_STATUSD: - case RTC_NVRAM_START ... RTC_NVRAM_END: - break; - default: - return (-1); - } - - addr = *eax & 0x7f; - return (0); -} - -static int -rtc_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +/* + * Returns the current RTC time as number of seconds since 00:00:00 Jan 1, 1970 + */ +static time_t +rtc_time(struct vmctx *ctx, int use_localtime) { - int hour; + struct tm tm; time_t t; - struct timeval cur, delta; - - static struct timeval last; - static struct tm tm; - - if (bytes != 1) - return (-1); - - gettimeofday(&cur, NULL); - /* - * Increment the cached time only once per second so we can guarantee - * that the guest has at least one second to read the hour:min:sec - * separately and still get a coherent view of the time. - */ - delta = cur; - timevalsub(&delta, &last); - if (delta.tv_sec >= 1 && (status_b & RTCSB_HALT) == 0) { - t = cur.tv_sec; + time(&t); + if (use_localtime) { localtime_r(&t, &tm); - last = cur; + t = timegm(&tm); } - - if (in) { - switch (addr) { - case RTC_SEC_ALARM: - *eax = rtc_alarm.secs; - break; - case RTC_MIN_ALARM: - *eax = rtc_alarm.mins; - break; - case RTC_HRS_ALARM: - *eax = rtc_alarm.hours; - break; - case RTC_SEC: - *eax = rtcout(tm.tm_sec); - return (0); - case RTC_MIN: - *eax = rtcout(tm.tm_min); - return (0); - case RTC_HRS: - if (status_b & RTCSB_24HR) - hour = tm.tm_hour; - else - hour = (tm.tm_hour % 12) + 1; - - *eax = rtcout(hour); - - /* - * If we are representing time in the 12-hour format - * then set the MSB to indicate PM. - */ - if ((status_b & RTCSB_24HR) == 0 && tm.tm_hour >= 12) - *eax |= 0x80; - - return (0); - case RTC_WDAY: - *eax = rtcout(tm.tm_wday + 1); - return (0); - case RTC_DAY: - *eax = rtcout(tm.tm_mday); - return (0); - case RTC_MONTH: - *eax = rtcout(tm.tm_mon + 1); - return (0); - case RTC_YEAR: - *eax = rtcout(tm.tm_year % 100); - return (0); - case RTC_STATUSA: - *eax = status_a; - return (0); - case RTC_STATUSB: - *eax = status_b; - return (0); - case RTC_INTR: - *eax = 0; - return (0); - case RTC_STATUSD: - *eax = RTCSD_PWR; - return (0); - case RTC_NVRAM_START ... RTC_NVRAM_END: - *eax = rtc_nvram[addr - RTC_NVRAM_START]; - return (0); - default: - return (-1); - } - } - - switch (addr) { - case RTC_STATUSA: - status_a = *eax & ~RTCSA_TUP; - break; - case RTC_STATUSB: - /* XXX not implemented yet XXX */ - if (*eax & RTCSB_PINTR) - return (-1); - status_b = *eax; - break; - case RTC_STATUSD: - /* ignore write */ - break; - case RTC_SEC_ALARM: - rtc_alarm.secs = *eax; - break; - case RTC_MIN_ALARM: - rtc_alarm.mins = *eax; - break; - case RTC_HRS_ALARM: - rtc_alarm.hours = *eax; - break; - case RTC_SEC: - case RTC_MIN: - case RTC_HRS: - case RTC_WDAY: - case RTC_DAY: - case RTC_MONTH: - case RTC_YEAR: - /* - * Ignore writes to the time of day registers - */ - break; - case RTC_NVRAM_START ... RTC_NVRAM_END: - rtc_nvram[addr - RTC_NVRAM_START] = *eax; - break; - default: - return (-1); - } - return (0); + return (t); } void -rtc_init(struct vmctx *ctx) +rtc_init(struct vmctx *ctx, int use_localtime) { - struct timeval cur; - struct tm tm; size_t himem; size_t lomem; int err; - err = gettimeofday(&cur, NULL); - assert(err == 0); - (void) localtime_r(&cur.tv_sec, &tm); - - memset(rtc_nvram, 0, sizeof(rtc_nvram)); - - rtc_nvram[nvoff(RTC_CENTURY)] = bin2bcd((tm.tm_year + 1900) / 100); - /* XXX init diag/reset code/equipment/checksum ? */ /* @@ -344,17 +86,22 @@ rtc_init(struct vmctx *ctx) * 0x5b/0x5c/0x5d - 64KB chunks above 4GB */ lomem = (vm_get_lowmem_size(ctx) - m_16MB) / m_64KB; - rtc_nvram[nvoff(RTC_LMEM_LSB)] = lomem; - rtc_nvram[nvoff(RTC_LMEM_MSB)] = lomem >> 8; + err = vm_rtc_write(ctx, RTC_LMEM_LSB, lomem); + assert(err == 0); + err = vm_rtc_write(ctx, RTC_LMEM_MSB, lomem >> 8); + assert(err == 0); himem = vm_get_highmem_size(ctx) / m_64KB; - rtc_nvram[nvoff(RTC_HMEM_LSB)] = himem; - rtc_nvram[nvoff(RTC_HMEM_SB)] = himem >> 8; - rtc_nvram[nvoff(RTC_HMEM_MSB)] = himem >> 16; -} + err = vm_rtc_write(ctx, RTC_HMEM_LSB, himem); + assert(err == 0); + err = vm_rtc_write(ctx, RTC_HMEM_SB, himem >> 8); + assert(err == 0); + err = vm_rtc_write(ctx, RTC_HMEM_MSB, himem >> 16); + assert(err == 0); -INOUT_PORT(rtc, IO_RTC, IOPORT_F_INOUT, rtc_addr_handler); -INOUT_PORT(rtc, IO_RTC + 1, IOPORT_F_INOUT, rtc_data_handler); + err = vm_rtc_settime(ctx, rtc_time(ctx, use_localtime)); + assert(err == 0); +} static void rtc_dsdt(void) diff --git a/usr.sbin/bhyve/rtc.h b/usr.sbin/bhyve/rtc.h index 72cffb3..5b08ca3 100644 --- a/usr.sbin/bhyve/rtc.h +++ b/usr.sbin/bhyve/rtc.h @@ -29,6 +29,6 @@ #ifndef _RTC_H_ #define _RTC_H_ -void rtc_init(struct vmctx *ctx); +void rtc_init(struct vmctx *ctx, int use_localtime); #endif /* _RTC_H_ */ diff --git a/usr.sbin/bhyve/task_switch.c b/usr.sbin/bhyve/task_switch.c index b939c1a..69dfaae 100644 --- a/usr.sbin/bhyve/task_switch.c +++ b/usr.sbin/bhyve/task_switch.c @@ -202,7 +202,8 @@ desc_table_limit_check(struct vmctx *ctx, int vcpu, uint16_t sel) */ static int desc_table_rw(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - uint16_t sel, struct user_segment_descriptor *desc, bool doread) + uint16_t sel, struct user_segment_descriptor *desc, bool doread, + int *faultptr) { struct iovec iov[2]; uint64_t base; @@ -215,28 +216,30 @@ desc_table_rw(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, assert(limit >= SEL_LIMIT(sel)); error = vm_copy_setup(ctx, vcpu, paging, base + SEL_START(sel), - sizeof(*desc), doread ? PROT_READ : PROT_WRITE, iov, nitems(iov)); - if (error == 0) { - if (doread) - vm_copyin(ctx, vcpu, iov, desc, sizeof(*desc)); - else - vm_copyout(ctx, vcpu, desc, iov, sizeof(*desc)); - } - return (error); + sizeof(*desc), doread ? PROT_READ : PROT_WRITE, iov, nitems(iov), + faultptr); + if (error || *faultptr) + return (error); + + if (doread) + vm_copyin(ctx, vcpu, iov, desc, sizeof(*desc)); + else + vm_copyout(ctx, vcpu, desc, iov, sizeof(*desc)); + return (0); } static int desc_table_read(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - uint16_t sel, struct user_segment_descriptor *desc) + uint16_t sel, struct user_segment_descriptor *desc, int *faultptr) { - return (desc_table_rw(ctx, vcpu, paging, sel, desc, true)); + return (desc_table_rw(ctx, vcpu, paging, sel, desc, true, faultptr)); } static int desc_table_write(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - uint16_t sel, struct user_segment_descriptor *desc) + uint16_t sel, struct user_segment_descriptor *desc, int *faultptr) { - return (desc_table_rw(ctx, vcpu, paging, sel, desc, false)); + return (desc_table_rw(ctx, vcpu, paging, sel, desc, false, faultptr)); } /* @@ -248,7 +251,7 @@ desc_table_write(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, */ static int read_tss_descriptor(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, - uint16_t sel, struct user_segment_descriptor *desc) + uint16_t sel, struct user_segment_descriptor *desc, int *faultptr) { struct vm_guest_paging sup_paging; int error; @@ -267,7 +270,7 @@ read_tss_descriptor(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, sup_paging = ts->paging; sup_paging.cpl = 0; /* implicit supervisor mode */ - error = desc_table_read(ctx, vcpu, &sup_paging, sel, desc); + error = desc_table_read(ctx, vcpu, &sup_paging, sel, desc, faultptr); return (error); } @@ -301,14 +304,10 @@ ldt_desc(int sd_type) /* * Validate the descriptor 'seg_desc' associated with 'segment'. - * - * Returns 0 on success. - * Returns 1 if an exception was injected into the guest. - * Returns -1 otherwise. */ static int validate_seg_desc(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, - int segment, struct seg_desc *seg_desc) + int segment, struct seg_desc *seg_desc, int *faultptr) { struct vm_guest_paging sup_paging; struct user_segment_descriptor usd; @@ -369,8 +368,8 @@ validate_seg_desc(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, /* Read the descriptor from the GDT/LDT */ sup_paging = ts->paging; sup_paging.cpl = 0; /* implicit supervisor mode */ - error = desc_table_read(ctx, vcpu, &sup_paging, sel, &usd); - if (error) + error = desc_table_read(ctx, vcpu, &sup_paging, sel, &usd, faultptr); + if (error || *faultptr) return (error); /* Verify that the descriptor type is compatible with the segment */ @@ -476,14 +475,10 @@ update_seg_desc(struct vmctx *ctx, int vcpu, int reg, struct seg_desc *sd) /* * Update the vcpu registers to reflect the state of the new task. - * - * Returns 0 on success. - * Returns 1 if an exception was injected into the guest. - * Returns -1 otherwise. */ static int tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, - uint16_t ot_sel, struct tss32 *tss, struct iovec *iov) + uint16_t ot_sel, struct tss32 *tss, struct iovec *iov, int *faultptr) { struct seg_desc seg_desc, seg_desc2; uint64_t *pdpte, maxphyaddr, reserved; @@ -565,8 +560,9 @@ tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, vm_copyout(ctx, vcpu, tss, iov, sizeof(*tss)); /* Validate segment descriptors */ - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_LDTR, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_LDTR, &seg_desc, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_LDTR, &seg_desc); @@ -579,33 +575,40 @@ tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, * VM-entry checks so the guest can handle any exception injected * during task switch emulation. */ - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_CS, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_CS, &seg_desc, + faultptr); + if (error || *faultptr) return (error); - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_SS, &seg_desc2); - if (error) + + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_SS, &seg_desc2, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_CS, &seg_desc); update_seg_desc(ctx, vcpu, VM_REG_GUEST_SS, &seg_desc2); ts->paging.cpl = tss->tss_cs & SEL_RPL_MASK; - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_DS, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_DS, &seg_desc, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_DS, &seg_desc); - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_ES, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_ES, &seg_desc, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_ES, &seg_desc); - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_FS, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_FS, &seg_desc, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_FS, &seg_desc); - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_GS, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_GS, &seg_desc, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_GS, &seg_desc); @@ -616,14 +619,10 @@ tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, * Push an error code on the stack of the new task. This is needed if the * task switch was triggered by a hardware exception that causes an error * code to be saved (e.g. #PF). - * - * Returns 0 on success. - * Returns 1 if an exception was injected into the guest. - * Returns -1 otherwise. */ static int push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - int task_type, uint32_t errcode) + int task_type, uint32_t errcode, int *faultptr) { struct iovec iov[2]; struct seg_desc seg_desc; @@ -632,6 +631,8 @@ push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, uint32_t esp; uint16_t stacksel; + *faultptr = 0; + cr0 = GETREG(ctx, vcpu, VM_REG_GUEST_CR0); rflags = GETREG(ctx, vcpu, VM_REG_GUEST_RFLAGS); stacksel = GETREG(ctx, vcpu, VM_REG_GUEST_SS); @@ -666,17 +667,19 @@ push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, if (vie_calculate_gla(paging->cpu_mode, VM_REG_GUEST_SS, &seg_desc, esp, bytes, stacksize, PROT_WRITE, &gla)) { sel_exception(ctx, vcpu, IDT_SS, stacksel, 1); - return (1); + *faultptr = 1; + return (0); } if (vie_alignment_check(paging->cpl, bytes, cr0, rflags, gla)) { vm_inject_ac(ctx, vcpu, 1); - return (1); + *faultptr = 1; + return (0); } error = vm_copy_setup(ctx, vcpu, paging, gla, bytes, PROT_WRITE, - iov, nitems(iov)); - if (error) + iov, nitems(iov), faultptr); + if (error || *faultptr) return (error); vm_copyout(ctx, vcpu, &errcode, iov, bytes); @@ -687,16 +690,13 @@ push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, /* * Evaluate return value from helper functions and potentially return to * the VM run loop. - * 0: success - * +1: an exception was injected into the guest vcpu - * -1: unrecoverable/programming error */ -#define CHKERR(x) \ +#define CHKERR(error,fault) \ do { \ - assert(((x) == 0) || ((x) == 1) || ((x) == -1)); \ - if ((x) == -1) \ + assert((error == 0) || (error == EFAULT)); \ + if (error) \ return (VMEXIT_ABORT); \ - else if ((x) == 1) \ + else if (fault) \ return (VMEXIT_CONTINUE); \ } while (0) @@ -711,7 +711,7 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) struct iovec nt_iov[2], ot_iov[2]; uint64_t cr0, ot_base; uint32_t eip, ot_lim, access; - int error, ext, minlimit, nt_type, ot_type, vcpu; + int error, ext, fault, minlimit, nt_type, ot_type, vcpu; enum task_switch_reason reason; uint16_t nt_sel, ot_sel; @@ -725,21 +725,11 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) assert(paging->cpu_mode == CPU_MODE_PROTECTED); /* - * Calculate the %eip to store in the old TSS before modifying the - * 'inst_length'. + * Calculate the instruction pointer to store in the old TSS. */ eip = vmexit->rip + vmexit->inst_length; /* - * Set the 'inst_length' to '0'. - * - * If an exception is triggered during emulation of the task switch - * then the exception handler should return to the instruction that - * caused the task switch as opposed to the subsequent instruction. - */ - vmexit->inst_length = 0; - - /* * Section 4.6, "Access Rights" in Intel SDM Vol 3. * The following page table accesses are implicitly supervisor mode: * - accesses to GDT or LDT to load segment descriptors @@ -749,8 +739,9 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) sup_paging.cpl = 0; /* implicit supervisor mode */ /* Fetch the new TSS descriptor */ - error = read_tss_descriptor(ctx, vcpu, task_switch, nt_sel, &nt_desc); - CHKERR(error); + error = read_tss_descriptor(ctx, vcpu, task_switch, nt_sel, &nt_desc, + &fault); + CHKERR(error, fault); nt = usd_to_seg_desc(&nt_desc); @@ -802,8 +793,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) /* Fetch the new TSS */ error = vm_copy_setup(ctx, vcpu, &sup_paging, nt.base, minlimit + 1, - PROT_READ | PROT_WRITE, nt_iov, nitems(nt_iov)); - CHKERR(error); + PROT_READ | PROT_WRITE, nt_iov, nitems(nt_iov), &fault); + CHKERR(error, fault); vm_copyin(ctx, vcpu, nt_iov, &newtss, minlimit + 1); /* Get the old TSS selector from the guest's task register */ @@ -828,13 +819,14 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) assert(ot_type == SDT_SYS386BSY || ot_type == SDT_SYS286BSY); /* Fetch the old TSS descriptor */ - error = read_tss_descriptor(ctx, vcpu, task_switch, ot_sel, &ot_desc); - CHKERR(error); + error = read_tss_descriptor(ctx, vcpu, task_switch, ot_sel, &ot_desc, + &fault); + CHKERR(error, fault); /* Get the old TSS */ error = vm_copy_setup(ctx, vcpu, &sup_paging, ot_base, minlimit + 1, - PROT_READ | PROT_WRITE, ot_iov, nitems(ot_iov)); - CHKERR(error); + PROT_READ | PROT_WRITE, ot_iov, nitems(ot_iov), &fault); + CHKERR(error, fault); vm_copyin(ctx, vcpu, ot_iov, &oldtss, minlimit + 1); /* @@ -844,8 +836,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) if (reason == TSR_IRET || reason == TSR_JMP) { ot_desc.sd_type &= ~0x2; error = desc_table_write(ctx, vcpu, &sup_paging, ot_sel, - &ot_desc); - CHKERR(error); + &ot_desc, &fault); + CHKERR(error, fault); } if (nt_type == SDT_SYS286BSY || nt_type == SDT_SYS286TSS) { @@ -863,8 +855,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) if (reason != TSR_IRET) { nt_desc.sd_type |= 0x2; error = desc_table_write(ctx, vcpu, &sup_paging, nt_sel, - &nt_desc); - CHKERR(error); + &nt_desc, &fault); + CHKERR(error, fault); } /* Update task register to point at the new TSS */ @@ -883,12 +875,13 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) * after this point will be handled in the context of the new task and * the saved instruction pointer will belong to the new task. */ - vmexit->rip = newtss.tss_eip; - assert(vmexit->inst_length == 0); + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, newtss.tss_eip); + assert(error == 0); /* Load processor state from new TSS */ - error = tss32_restore(ctx, vcpu, task_switch, ot_sel, &newtss, nt_iov); - CHKERR(error); + error = tss32_restore(ctx, vcpu, task_switch, ot_sel, &newtss, nt_iov, + &fault); + CHKERR(error, fault); /* * Section "Interrupt Tasks" in Intel SDM, Vol 3: if an exception @@ -899,8 +892,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) assert(task_switch->ext); assert(task_switch->reason == TSR_IDT_GATE); error = push_errcode(ctx, vcpu, &task_switch->paging, nt_type, - task_switch->errcode); - CHKERR(error); + task_switch->errcode, &fault); + CHKERR(error, fault); } /* diff --git a/usr.sbin/bhyve/virtio.c b/usr.sbin/bhyve/virtio.c index 19c0d47..11b1e62 100644 --- a/usr.sbin/bhyve/virtio.c +++ b/usr.sbin/bhyve/virtio.c @@ -97,6 +97,7 @@ vi_reset_dev(struct virtio_softc *vs) for (vq = vs->vs_queues, i = 0; i < nvq; vq++, i++) { vq->vq_flags = 0; vq->vq_last_avail = 0; + vq->vq_save_used = 0; vq->vq_pfn = 0; vq->vq_msix_idx = VIRTIO_MSI_NO_VECTOR; } @@ -147,8 +148,13 @@ vi_intr_init(struct virtio_softc *vs, int barnum, int use_msix) return (1); } else vs->vs_flags &= ~VIRTIO_USE_MSIX; + /* Only 1 MSI vector for bhyve */ pci_emul_add_msicap(vs->vs_pi, 1); + + /* Legacy interrupts are mandatory for virtio devices */ + pci_lintr_request(vs->vs_pi); + return (0); } @@ -188,6 +194,7 @@ vi_vq_init(struct virtio_softc *vs, uint32_t pfn) /* Mark queue as allocated, and start at 0 when we use it. */ vq->vq_flags = VQ_ALLOC; vq->vq_last_avail = 0; + vq->vq_save_used = 0; } /* @@ -247,12 +254,12 @@ _vq_record(int i, volatile struct virtio_desc *vd, struct vmctx *ctx, * that vq_has_descs() does one). */ int -vq_getchain(struct vqueue_info *vq, +vq_getchain(struct vqueue_info *vq, uint16_t *pidx, struct iovec *iov, int n_iov, uint16_t *flags) { int i; u_int ndesc, n_indir; - u_int idx, head, next; + u_int idx, next; volatile struct virtio_desc *vdir, *vindir, *vp; struct vmctx *ctx; struct virtio_softc *vs; @@ -295,8 +302,8 @@ vq_getchain(struct vqueue_info *vq, * index, but we just abort if the count gets excessive. */ ctx = vs->vs_pi->pi_vmctx; - head = vq->vq_avail->va_ring[idx & (vq->vq_qsize - 1)]; - next = head; + *pidx = next = vq->vq_avail->va_ring[idx & (vq->vq_qsize - 1)]; + vq->vq_last_avail++; for (i = 0; i < VQ_MAX_DESCRIPTORS; next = vdir->vd_next) { if (next >= vq->vq_qsize) { fprintf(stderr, @@ -309,7 +316,7 @@ vq_getchain(struct vqueue_info *vq, if ((vdir->vd_flags & VRING_DESC_F_INDIRECT) == 0) { _vq_record(i, vdir, ctx, iov, n_iov, flags); i++; - } else if ((vs->vs_negotiated_caps & + } else if ((vs->vs_vc->vc_hv_caps & VIRTIO_RING_F_INDIRECT_DESC) == 0) { fprintf(stderr, "%s: descriptor has forbidden INDIRECT flag, " @@ -370,16 +377,29 @@ loopy: } /* - * Return the currently-first request chain to the guest, setting - * its I/O length to the provided value. + * Return the currently-first request chain back to the available queue. + * + * (This chain is the one you handled when you called vq_getchain() + * and used its positive return value.) + */ +void +vq_retchain(struct vqueue_info *vq) +{ + + vq->vq_last_avail--; +} + +/* + * Return specified request chain to the guest, setting its I/O length + * to the provided value. * * (This chain is the one you handled when you called vq_getchain() * and used its positive return value.) */ void -vq_relchain(struct vqueue_info *vq, uint32_t iolen) +vq_relchain(struct vqueue_info *vq, uint16_t idx, uint32_t iolen) { - uint16_t head, uidx, mask; + uint16_t uidx, mask; volatile struct vring_used *vuh; volatile struct virtio_used *vue; @@ -395,11 +415,10 @@ vq_relchain(struct vqueue_info *vq, uint32_t iolen) */ mask = vq->vq_qsize - 1; vuh = vq->vq_used; - head = vq->vq_avail->va_ring[vq->vq_last_avail++ & mask]; uidx = vuh->vu_idx; vue = &vuh->vu_ring[uidx++ & mask]; - vue->vu_idx = head; /* ie, vue->id = head */ + vue->vu_idx = idx; vue->vu_tlen = iolen; vuh->vu_idx = uidx; } @@ -436,8 +455,8 @@ vq_endchains(struct vqueue_info *vq, int used_all_avail) * entire avail was processed, we need to interrupt always. */ vs = vq->vq_vs; - new_idx = vq->vq_used->vu_idx; old_idx = vq->vq_save_used; + vq->vq_save_used = new_idx = vq->vq_used->vu_idx; if (used_all_avail && (vs->vs_negotiated_caps & VIRTIO_F_NOTIFY_ON_EMPTY)) intr = 1; diff --git a/usr.sbin/bhyve/virtio.h b/usr.sbin/bhyve/virtio.h index 6f655f3..0e96a1d 100644 --- a/usr.sbin/bhyve/virtio.h +++ b/usr.sbin/bhyve/virtio.h @@ -425,20 +425,6 @@ vq_has_descs(struct vqueue_info *vq) } /* - * Called by virtio driver as it starts processing chains. Each - * completed chain (obtained from vq_getchain()) is released by - * calling vq_relchain(), then when all are done, vq_endchains() - * can tell if / how-many chains were processed and know whether - * and how to generate an interrupt. - */ -static inline void -vq_startchains(struct vqueue_info *vq) -{ - - vq->vq_save_used = vq->vq_used->vu_idx; -} - -/* * Deliver an interrupt to guest on the given virtual queue * (if possible, or a generic MSI interrupt if not using MSI-X). */ @@ -465,9 +451,10 @@ int vi_intr_init(struct virtio_softc *vs, int barnum, int use_msix); void vi_reset_dev(struct virtio_softc *); void vi_set_io_bar(struct virtio_softc *, int); -int vq_getchain(struct vqueue_info *vq, +int vq_getchain(struct vqueue_info *vq, uint16_t *pidx, struct iovec *iov, int n_iov, uint16_t *flags); -void vq_relchain(struct vqueue_info *vq, uint32_t iolen); +void vq_retchain(struct vqueue_info *vq); +void vq_relchain(struct vqueue_info *vq, uint16_t idx, uint32_t iolen); void vq_endchains(struct vqueue_info *vq, int used_all_avail); uint64_t vi_pci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, diff --git a/usr.sbin/bhyve/xmsr.c b/usr.sbin/bhyve/xmsr.c index d50a939..5b7bfbb 100644 --- a/usr.sbin/bhyve/xmsr.c +++ b/usr.sbin/bhyve/xmsr.c @@ -185,6 +185,15 @@ emulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t *val) *val = 0; break; + /* + * OpenBSD guests test bit 0 of this MSR to detect if the + * workaround for erratum 721 is already applied. + * http://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf + */ + case 0xC0011029: + *val = 1; + break; + default: error = -1; break; diff --git a/usr.sbin/bhyvectl/Makefile b/usr.sbin/bhyvectl/Makefile index 5f879fe..dba3f12 100644 --- a/usr.sbin/bhyvectl/Makefile +++ b/usr.sbin/bhyvectl/Makefile @@ -7,8 +7,7 @@ SRCS= bhyvectl.c MAN= -DPADD= ${LIBVMMAPI} ${LIBUTIL} -LDADD= -lvmmapi -lutil +LIBADD= vmmapi WARNS?= 3 diff --git a/usr.sbin/bhyvectl/bhyvectl.c b/usr.sbin/bhyvectl/bhyvectl.c index 0c4457e..7d3017f 100644 --- a/usr.sbin/bhyvectl/bhyvectl.c +++ b/usr.sbin/bhyvectl/bhyvectl.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <fcntl.h> #include <string.h> #include <getopt.h> +#include <time.h> #include <assert.h> #include <machine/cpufunc.h> @@ -157,6 +158,11 @@ usage(bool cpu_intel) " [--inject-nmi]\n" " [--force-reset]\n" " [--force-poweroff]\n" + " [--get-rtc-time]\n" + " [--set-rtc-time=<secs>]\n" + " [--get-rtc-nvram]\n" + " [--set-rtc-nvram=<val>]\n" + " [--rtc-nvram-offset=<offset>]\n" " [--get-active-cpus]\n" " [--get-suspended-cpus]\n" " [--get-intinfo]\n" @@ -220,6 +226,12 @@ usage(bool cpu_intel) exit(1); } +static int get_rtc_time, set_rtc_time; +static int get_rtc_nvram, set_rtc_nvram; +static int rtc_nvram_offset; +static uint8_t rtc_nvram_value; +static time_t rtc_secs; + static int get_stats, getcap, setcap, capval, get_gpa_pmap; static int inject_nmi, assert_lapic_lvt; static int force_reset, force_poweroff; @@ -281,6 +293,7 @@ static int get_guest_pat, get_host_pat; static int get_guest_sysenter, get_vmcs_link; static int get_exit_reason, get_vmcs_exit_qualification; static int get_vmcs_exit_interruption_info, get_vmcs_exit_interruption_error; +static int get_vmcs_exit_inst_length; static uint64_t desc_base; static uint32_t desc_limit, desc_access; @@ -545,6 +558,9 @@ enum { UNASSIGN_PPTDEV, GET_GPA_PMAP, ASSERT_LAPIC_LVT, + SET_RTC_TIME, + SET_RTC_NVRAM, + RTC_NVRAM_OFFSET, }; static void @@ -625,9 +641,9 @@ get_all_registers(struct vmctx *ctx, int vcpu) uint64_t cr0, cr3, cr4, dr7, rsp, rip, rflags, efer; uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp; uint64_t r8, r9, r10, r11, r12, r13, r14, r15; - int error; + int error = 0; - if (get_efer || get_all) { + if (!error && (get_efer || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_EFER, &efer); if (error == 0) printf("efer[%d]\t\t0x%016lx\n", vcpu, efer); @@ -772,10 +788,10 @@ get_all_registers(struct vmctx *ctx, int vcpu) static int get_all_segments(struct vmctx *ctx, int vcpu) { - int error; uint64_t cs, ds, es, fs, gs, ss, tr, ldtr; + int error = 0; - if (get_desc_ds || get_all) { + if (!error && (get_desc_ds || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_DS, &desc_base, &desc_limit, &desc_access); if (error == 0) { @@ -920,9 +936,9 @@ static int get_misc_vmcs(struct vmctx *ctx, int vcpu) { uint64_t ctl, cr0, cr3, cr4, rsp, rip, pat, addr, u64; - int error; - - if (get_cr0_mask || get_all) { + int error = 0; + + if (!error && (get_cr0_mask || get_all)) { uint64_t cr0mask; error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_MASK, &cr0mask); if (error == 0) @@ -1130,7 +1146,15 @@ get_misc_vmcs(struct vmctx *ctx, int vcpu) vcpu, u64); } } - + + if (!error && (get_vmcs_exit_inst_length || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_EXIT_INSTRUCTION_LENGTH, &u64); + if (error == 0) + printf("vmcs_exit_inst_length[%d]\t0x%08x\n", vcpu, + (uint32_t)u64); + } + if (!error && (get_vmcs_exit_qualification || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_QUALIFICATION, &u64); @@ -1146,9 +1170,9 @@ static int get_misc_vmcb(struct vmctx *ctx, int vcpu) { uint64_t ctl, addr; - int error; + int error = 0; - if (get_vmcb_intercept || get_all) { + if (!error && (get_vmcb_intercept || get_all)) { error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_CR_INTERCEPT, 4, &ctl); if (error == 0) @@ -1269,6 +1293,11 @@ setup_options(bool cpu_intel) { "setcap", REQ_ARG, 0, SET_CAP }, { "get-gpa-pmap", REQ_ARG, 0, GET_GPA_PMAP }, { "assert-lapic-lvt", REQ_ARG, 0, ASSERT_LAPIC_LVT }, + { "get-rtc-time", NO_ARG, &get_rtc_time, 1 }, + { "set-rtc-time", REQ_ARG, 0, SET_RTC_TIME }, + { "rtc-nvram-offset", REQ_ARG, 0, RTC_NVRAM_OFFSET }, + { "get-rtc-nvram", NO_ARG, &get_rtc_nvram, 1 }, + { "set-rtc-nvram", REQ_ARG, 0, SET_RTC_NVRAM }, { "getcap", NO_ARG, &getcap, 1 }, { "get-stats", NO_ARG, &get_stats, 1 }, { "get-desc-ds",NO_ARG, &get_desc_ds, 1 }, @@ -1385,6 +1414,8 @@ setup_options(bool cpu_intel) REQ_ARG, 0, SET_VMCS_ENTRY_INTERRUPTION_INFO }, { "get-vmcs-exit-qualification", NO_ARG, &get_vmcs_exit_qualification, 1 }, + { "get-vmcs-exit-inst-length", + NO_ARG, &get_vmcs_exit_inst_length, 1 }, { "get-vmcs-interruptibility", NO_ARG, &get_vmcs_interruptibility, 1 }, { "get-vmcs-exit-interruption-error", @@ -1462,6 +1493,33 @@ setup_options(bool cpu_intel) return (all_opts); } +static const char * +wday_str(int idx) +{ + static const char *weekdays[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + + if (idx >= 0 && idx < 7) + return (weekdays[idx]); + else + return ("UNK"); +} + +static const char * +mon_str(int idx) +{ + static const char *months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + if (idx >= 0 && idx < 12) + return (months[idx]); + else + return ("UNK"); +} + int main(int argc, char *argv[]) { @@ -1477,6 +1535,7 @@ main(int argc, char *argv[]) cpuset_t cpus; bool cpu_intel; uint64_t cs, ds, es, fs, gs, ss, tr, ldtr; + struct tm tm; struct option *opts; cpu_intel = cpu_vendor_intel(); @@ -1594,6 +1653,17 @@ main(int argc, char *argv[]) capval = strtoul(optarg, NULL, 0); setcap = 1; break; + case SET_RTC_TIME: + rtc_secs = strtoul(optarg, NULL, 0); + set_rtc_time = 1; + break; + case SET_RTC_NVRAM: + rtc_nvram_value = (uint8_t)strtoul(optarg, NULL, 0); + set_rtc_nvram = 1; + break; + case RTC_NVRAM_OFFSET: + rtc_nvram_offset = strtoul(optarg, NULL, 0); + break; case GET_GPA_PMAP: gpa_pmap = strtoul(optarg, NULL, 0); get_gpa_pmap = 1; @@ -1971,6 +2041,31 @@ main(int argc, char *argv[]) } } + if (!error && set_rtc_nvram) + error = vm_rtc_write(ctx, rtc_nvram_offset, rtc_nvram_value); + + if (!error && (get_rtc_nvram || get_all)) { + error = vm_rtc_read(ctx, rtc_nvram_offset, &rtc_nvram_value); + if (error == 0) { + printf("rtc nvram[%03d]: 0x%02x\n", rtc_nvram_offset, + rtc_nvram_value); + } + } + + if (!error && set_rtc_time) + error = vm_rtc_settime(ctx, rtc_secs); + + if (!error && (get_rtc_time || get_all)) { + error = vm_rtc_gettime(ctx, &rtc_secs); + if (error == 0) { + gmtime_r(&rtc_secs, &tm); + printf("rtc time %#lx: %s %s %02d %02d:%02d:%02d %d\n", + rtc_secs, wday_str(tm.tm_wday), mon_str(tm.tm_mon), + tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, + 1900 + tm.tm_year); + } + } + if (!error && (getcap || get_all)) { int captype, val, getcaptype; @@ -2034,10 +2129,7 @@ main(int argc, char *argv[]) } if (!error && run) { - error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip); - assert(error == 0); - - error = vm_run(ctx, vcpu, rip, &vmexit); + error = vm_run(ctx, vcpu, &vmexit); if (error == 0) dump_vm_run_exitcode(&vmexit, vcpu); else diff --git a/usr.sbin/bhyveload/Makefile b/usr.sbin/bhyveload/Makefile index e7b19bd..fce0c1b 100644 --- a/usr.sbin/bhyveload/Makefile +++ b/usr.sbin/bhyveload/Makefile @@ -4,8 +4,7 @@ PROG= bhyveload SRCS= bhyveload.c MAN= bhyveload.8 -DPADD+= ${LIBVMMAPI} ${LIBUTIL} -LDADD+= -lvmmapi -lutil +LIBADD= vmmapi WARNS?= 3 diff --git a/usr.sbin/bhyveload/bhyveload.c b/usr.sbin/bhyveload/bhyveload.c index eaf71a8..8ebf116 100644 --- a/usr.sbin/bhyveload/bhyveload.c +++ b/usr.sbin/bhyveload/bhyveload.c @@ -609,7 +609,7 @@ disk_open(char *path) { int err, fd; - if (ndisks > NDISKS) + if (ndisks >= NDISKS) return (ERANGE); err = 0; diff --git a/usr.sbin/binmiscctl/binmiscctl.8 b/usr.sbin/binmiscctl/binmiscctl.8 index 761810e..4bc9986 100644 --- a/usr.sbin/binmiscctl/binmiscctl.8 +++ b/usr.sbin/binmiscctl/binmiscctl.8 @@ -27,7 +27,7 @@ .\" .\" Support for miscellaneous binary image activators .\" -.Dd April 10, 2014 +.Dd December 30, 2014 .Dt BINMISCCTL 8 .Os .Sh NAME @@ -146,46 +146,159 @@ Look up and print out the activator entry identified with Take a snapshot and print all the activator entries currently configured. .El .Sh EXAMPLES +Add an image activator to run the LLVM interpreter (lli) on bitcode +compiled files: .Bd -ragged -offset indent # binmiscctl add llvmbc --interpreter ''/usr/bin/lli --fake-argv0=#a'' --magic ''BC\\xc0\\xde'' --size 4 --set-enabled .Ed .Pp -Add an image activator to run the LLVM interpreter (lli) on bitcode -compiled files. .Ar #a -gets replaced with the old +is replaced with the old .Dv argv0 value so that 'lli' can fake its .Dv argv0 . Set its state to enabled. .Pp +Set the state of the +.Ar llvmbc +image activator to disabled: .Dl # binmiscctl disable llvmbc .Pp Set the state of the .Ar llvmbc -image activator to disabled. -.Pp +image activator to enabled: .Dl # binmiscctl enable llvmbc .Pp -Set the state of the +Delete the .Ar llvmbc -image activator to enabled. -.Pp +image activator: .Dl # binmiscctl remove llvmbc .Pp -Delete the +Look up and list the record for the .Ar llvmbc -image activator. -.Pp +image activator: .Dl # binmiscctl lookup llvmbc .Pp -Look up and list the record for the -.Ar llvmbc -image activator. +Add QEMU bsd-user program as an image activator for ARM AARCH64 binaries: +.Bd -literal -offset indent +# binmiscctl add arm64 \e + --interpreter "/usr/local/bin/qemu-aarch64-static" \e + --magic "\ex7f\ex45\ex4c\ex46\ex02\ex01\ex01\ex00\ex00\ex00\e + \ex00\ex00\ex00\ex00\ex00\ex00\ex02\ex00\exb7\ex00" \e + --mask "\exff\exff\exff\exff\exff\exff\exff\ex00\exff\exff\e + \exff\exff\exff\exff\exff\exff\exfe\exff\exff\exff" \e + --size 20 --set-enabled +.Ed +.Pp +Add QEMU bsd-user program as an image activator for ARM little-endian binaries: +.Bd -literal -offset indent +# binmiscctl add armelf \e + --interpreter "/usr/local/bin/qemu-arm-static" \e + --magic "\ex7f\ex45\ex4c\ex46\ex01\ex01\ex01\ex00\ex00\ex00\e + \ex00\ex00\ex00\ex00\ex00\ex00\ex02\ex00\ex28\ex00" \e + --mask "\exff\exff\exff\exff\exff\exff\exff\ex00\exff\exff\e + \exff\exff\exff\exff\exff\exff\exfe\exff\exff\exff" \e + --size 20 --set-enabled +.Ed +.Pp +Add QEMU bsd-user program as an image activator for ARM big-endian binaries: +.Bd -literal -offset indent +# binmiscctl add armebelf \e + --interpreter "/usr/local/bin/qemu-arm-static" \e + --magic "\ex7f\ex45\ex4c\ex46\ex01\ex02\ex01\ex00\ex00\ex00\e + \ex00\ex00\ex00\ex00\ex00\ex00\ex00\ex02\ex00\ex28" \e + --mask "\exff\exff\exff\exff\exff\exff\exff\ex00\exff\exff\e + \exff\exff\exff\exff\exff\exff\exff\exfe\exff\exff" \e + --size 20 --set-enabled +.Ed +.Pp +Add QEMU bsd-user program as an image activator for MIPS32 binaries: +.Bd -literal -offset indent +# binmiscctl add mips32 \e + --interpreter "/usr/local/bin/qemu-mips-static" \e + --magic "\ex7f\ex45\ex4c\ex46\ex01\ex02\ex01\ex00\ex00\ex00\e + \ex00\ex00\ex00\ex00\ex00\ex00\ex00\ex02\ex00\ex08" \e + --mask "\exff\exff\exff\exff\exff\exff\exff\ex00\exff\exff\e + \exff\exff\exff\exff\exff\exff\exff\exfe\exff\exff" \e + --size 20 --set-enabled +.Ed +.Pp +Add QEMU bsd-user program as an image activator for MIPS64 binaries: +.Bd -literal -offset indent +# binmiscctl add mips64 \e + --interpreter "/usr/local/bin/qemu-mips64-static" \e + --magic "\ex7f\ex45\ex4c\ex46\ex02\ex02\ex01\ex00\ex00\ex00\e + \ex00\ex00\ex00\ex00\ex00\ex00\ex00\ex02\ex00\ex08" \e + --mask "\exff\exff\exff\exff\exff\exff\exff\ex00\exff\exff\e + \exff\exff\exff\exff\exff\exff\exff\exfe\exff\exff" \e + --size 20 --set-enabled +.Ed +.Pp +Add QEMU bsd-user program as an image activator for PowerPC binaries: +.Bd -literal -offset indent +# binmiscctl add powerpc \e + --interpreter "/usr/local/bin/qemu-ppc-static" \e + --magic "\ex7f\ex45\ex4c\ex46\ex01\ex02\ex01\ex00\ex00\ex00\e + \ex00\ex00\ex00\ex00\ex00\ex00\ex00\ex02\ex00\ex14" \e + --mask "\exff\exff\exff\exff\exff\exff\exff\ex00\exff\exff\e + \exff\exff\exff\exff\exff\exff\exff\exfe\exff\exff" \e + --size 20 --set-enabled +.Ed +.Pp +Add QEMU bsd-user program as an image activator for PowerPC64 binaries: +.Bd -literal -offset indent +# binmiscctl add powerpc64 \e + --interpreter "/usr/local/bin/qemu-ppc64-static" \e + --magic "\ex7f\ex45\ex4c\ex46\ex01\ex02\ex01\ex00\ex00\ex00\e + \ex00\ex00\ex00\ex00\ex00\ex00\ex00\ex02\ex00\ex15" \e + --mask "\exff\exff\exff\exff\exff\exff\exff\ex00\exff\exff\e + \exff\exff\exff\exff\exff\exff\exff\exfe\exff\exff" \e + --size 20 --set-enabled +.Ed +.Pp +Add QEMU bsd-user program as an image activator for SPARC64 binaries: +.Bd -literal -offset indent +# binmiscctl add sparc64 \e + --interpreter "/usr/local/bin/qemu-sparc64-static" \e + --magic "\ex7f\ex45\ex4c\ex46\ex02\ex02\ex01\ex00\ex00\ex00\e + \ex00\ex00\ex00\ex00\ex00\ex00\ex00\ex02\ex00\ex2b" \e + --mask "\exff\exff\exff\exff\exff\exff\exff\ex00\exff\exff\e + \exff\exff\exff\exff\exff\exff\exff\exfe\exff\exff" \e + --size 20 --set-enabled +.Ed +.Pp +.Ss "Create and use an ARMv6 chroot on an AMD64 host" +Use an existing source tree to build a chroot host with architecture +overrides: +.Bd -literal +D=/path/to/chroot +cd /usr/src +mkdir -p $D +make world TARGET=arm TARGET_ARCH=armv6 DESTDIR=$D +make distribution TARGET=arm TARGET_ARCH=armv6 DESTDIR=$D +.Ed +.Pp +With +.Pa emulators/qemu-user-static +from the +.Fx +Ports Collection, the emulator must be copied into the jail path +specified in the binmiscctl command. +Using the example above: +.Bd -literal +mkdir $D/usr/local/bin +cp /usr/local/bin/qemu-arm-static $D/usr/local/bin +.Ed +.Pp +Now the user can chroot into the environment normally, as root: +.Bd -literal +chroot $D +.Ed .Sh SEE ALSO .Xr lli 1 , -.Xr execve 2 +.Xr execve 2 , +.Xr jail 8 .Sh HISTORY The .Cm binmiscctl diff --git a/usr.sbin/binmiscctl/binmiscctl.c b/usr.sbin/binmiscctl/binmiscctl.c index 436e761..5ab82e4 100644 --- a/usr.sbin/binmiscctl/binmiscctl.c +++ b/usr.sbin/binmiscctl/binmiscctl.c @@ -363,7 +363,7 @@ add_cmd(__unused int argc, char *argv[], ximgact_binmisc_entry_t *xbe) usage("Error: Missing magic argument"); } - if (!xbe->xbe_interpreter) { + if (!strnlen(xbe->xbe_interpreter, IBE_INTERP_LEN_MAX)) { usage("Error: Missing 'interpreter' argument"); } @@ -371,8 +371,10 @@ add_cmd(__unused int argc, char *argv[], ximgact_binmisc_entry_t *xbe) } int -name_cmd(__unused int argc, char *argv[], ximgact_binmisc_entry_t *xbe) +name_cmd(int argc, char *argv[], ximgact_binmisc_entry_t *xbe) { + if (argc == 0) + usage("Required argument missing\n"); if (strlen(argv[0]) > IBE_NAME_MAX) usage("'%s' string length longer than IBE_NAME_MAX (%d)", IBE_NAME_MAX); diff --git a/usr.sbin/bluetooth/Makefile b/usr.sbin/bluetooth/Makefile index 594b440..1737107 100644 --- a/usr.sbin/bluetooth/Makefile +++ b/usr.sbin/bluetooth/Makefile @@ -1,12 +1,10 @@ # $Id: Makefile,v 1.5 2003/09/08 02:28:35 max Exp $ # $FreeBSD$ +.include <src.opts.mk> + SUBDIR= \ - ath3kfw \ - bcmfw \ bt3cfw \ - bthidcontrol \ - bthidd \ btpand \ hccontrol \ hcsecd \ @@ -17,5 +15,12 @@ SUBDIR= \ sdpcontrol \ sdpd +.if ${MK_USB} != "no" +SUBDIR+= ath3kfw +SUBDIR+= bcmfw +SUBDIR+= bthidcontrol +SUBDIR+= bthidd +.endif + .include <bsd.subdir.mk> diff --git a/usr.sbin/bluetooth/ath3kfw/Makefile b/usr.sbin/bluetooth/ath3kfw/Makefile index 373655b..26ce06e 100644 --- a/usr.sbin/bluetooth/ath3kfw/Makefile +++ b/usr.sbin/bluetooth/ath3kfw/Makefile @@ -2,7 +2,6 @@ PROG= ath3kfw MAN= ath3kfw.8 -DPADD+= ${LIBUSB} -LDADD+= -lusb +LIBADD+= usb .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/bt3cfw/Makefile b/usr.sbin/bluetooth/bt3cfw/Makefile index 90bf751..f9da6ca 100644 --- a/usr.sbin/bluetooth/bt3cfw/Makefile +++ b/usr.sbin/bluetooth/bt3cfw/Makefile @@ -5,7 +5,6 @@ PROG= bt3cfw MAN= bt3cfw.8 WARNS?= 2 -DPADD= ${LIBNETGRAPH} -LDADD= -lnetgraph +LIBADD+= netgraph .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/bthidcontrol/Makefile b/usr.sbin/bluetooth/bthidcontrol/Makefile index 6c9eafb..09128d6 100644 --- a/usr.sbin/bluetooth/bthidcontrol/Makefile +++ b/usr.sbin/bluetooth/bthidcontrol/Makefile @@ -9,7 +9,6 @@ SRCS= bthidcontrol.c hid.c lexer.l parser.y sdp.c WARNS?= 1 CFLAGS+= -DBTHIDCONTROL=1 -I${.CURDIR}/../bthidd -DPADD= ${LIBBLUETOOTH} ${LIBSDP} ${LIBUSBHID} -LDADD= -lbluetooth -lsdp -lusbhid +LIBADD+= bluetooth sdp usbhid .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/bthidcontrol/Makefile.depend b/usr.sbin/bluetooth/bthidcontrol/Makefile.depend index 7ce677b..0bcf768 100644 --- a/usr.sbin/bluetooth/bthidcontrol/Makefile.depend +++ b/usr.sbin/bluetooth/bthidcontrol/Makefile.depend @@ -13,6 +13,7 @@ DIRDEPS = \ lib/libcompiler_rt \ lib/libsdp \ lib/libusbhid \ + usr.bin/yacc.host \ .include <dirdeps.mk> diff --git a/usr.sbin/bluetooth/bthidcontrol/bthidcontrol.c b/usr.sbin/bluetooth/bthidcontrol/bthidcontrol.c index 900bda5..0f795dd 100644 --- a/usr.sbin/bluetooth/bthidcontrol/bthidcontrol.c +++ b/usr.sbin/bluetooth/bthidcontrol/bthidcontrol.c @@ -31,6 +31,7 @@ #include <sys/queue.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <err.h> #include <errno.h> diff --git a/usr.sbin/bluetooth/bthidcontrol/hid.c b/usr.sbin/bluetooth/bthidcontrol/hid.c index 9fb6220..e43ef6a 100644 --- a/usr.sbin/bluetooth/bthidcontrol/hid.c +++ b/usr.sbin/bluetooth/bthidcontrol/hid.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <dev/usb/usb.h> #include <dev/usb/usbhid.h> diff --git a/usr.sbin/bluetooth/bthidcontrol/sdp.c b/usr.sbin/bluetooth/bthidcontrol/sdp.c index a0b4534..3beabc1 100644 --- a/usr.sbin/bluetooth/bthidcontrol/sdp.c +++ b/usr.sbin/bluetooth/bthidcontrol/sdp.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <dev/usb/usb.h> #include <dev/usb/usbhid.h> diff --git a/usr.sbin/bluetooth/bthidd/Makefile b/usr.sbin/bluetooth/bthidd/Makefile index fe6ef33..f36d216 100644 --- a/usr.sbin/bluetooth/bthidd/Makefile +++ b/usr.sbin/bluetooth/bthidd/Makefile @@ -8,10 +8,8 @@ SRCS= bthidd.c client.c hid.c kbd.c lexer.l parser.y server.c \ session.c CFLAGS+= -I${.CURDIR} -DEBUG_FLAGS= -g -DPADD= ${LIBBLUETOOTH} ${LIBUSBHID} -LDADD= -lbluetooth -lusbhid +LIBADD+= bluetooth usbhid NO_WMISSING_VARIABLE_DECLARATIONS= diff --git a/usr.sbin/bluetooth/bthidd/Makefile.depend b/usr.sbin/bluetooth/bthidd/Makefile.depend index c4c93a2..dedd944 100644 --- a/usr.sbin/bluetooth/bthidd/Makefile.depend +++ b/usr.sbin/bluetooth/bthidd/Makefile.depend @@ -12,6 +12,7 @@ DIRDEPS = \ lib/libc \ lib/libcompiler_rt \ lib/libusbhid \ + usr.bin/yacc.host \ .include <dirdeps.mk> diff --git a/usr.sbin/bluetooth/bthidd/bthidd.c b/usr.sbin/bluetooth/bthidd/bthidd.c index b93fd3d..7e988fc 100644 --- a/usr.sbin/bluetooth/bthidd/bthidd.c +++ b/usr.sbin/bluetooth/bthidd/bthidd.c @@ -34,6 +34,7 @@ #include <sys/time.h> #include <sys/queue.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <err.h> #include <errno.h> diff --git a/usr.sbin/bluetooth/bthidd/client.c b/usr.sbin/bluetooth/bthidd/client.c index 59f0d19..5f01133 100644 --- a/usr.sbin/bluetooth/bthidd/client.c +++ b/usr.sbin/bluetooth/bthidd/client.c @@ -33,6 +33,7 @@ #include <sys/queue.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <fcntl.h> @@ -236,7 +237,9 @@ client_socket(bdaddr_p bdaddr, uint16_t psm) l2addr.l2cap_family = AF_BLUETOOTH; memset(&l2addr.l2cap_bdaddr, 0, sizeof(l2addr.l2cap_bdaddr)); l2addr.l2cap_psm = 0; - + l2addr.l2cap_bdaddr_type = BDADDR_BREDR; + l2addr.l2cap_cid = 0; + if (bind(s, (struct sockaddr *) &l2addr, sizeof(l2addr)) < 0) { close(s); return (-1); diff --git a/usr.sbin/bluetooth/bthidd/hid.c b/usr.sbin/bluetooth/bthidd/hid.c index c68865b..69a6fdc 100644 --- a/usr.sbin/bluetooth/bthidd/hid.c +++ b/usr.sbin/bluetooth/bthidd/hid.c @@ -35,6 +35,7 @@ #include <sys/mouse.h> #include <sys/queue.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <dev/usb/usb.h> #include <dev/usb/usbhid.h> @@ -48,12 +49,6 @@ #include "bthidd.h" #include "kbd.h" -#undef min -#define min(x, y) (((x) < (y))? (x) : (y)) - -#undef ASIZE -#define ASIZE(a) (sizeof(a)/sizeof(a[0])) - /* * Process data from control channel */ @@ -165,9 +160,21 @@ hid_interrupt(bthid_session_p s, uint8_t *data, int32_t len) continue; page = HID_PAGE(h.usage); - usage = HID_USAGE(h.usage); val = hid_get_data(data, &h); + /* + * When the input field is an array and the usage is specified + * with a range instead of an ID, we have to derive the actual + * usage by using the item value as an index in the usage range + * list. + */ + if ((h.flags & HIO_VARIABLE)) { + usage = HID_USAGE(h.usage); + } else { + const uint32_t usage_offset = val - h.logical_minimum; + usage = HID_USAGE(h.usage_minimum + usage_offset); + } + switch (page) { case HUP_GENERIC_DESKTOP: switch (usage) { diff --git a/usr.sbin/bluetooth/bthidd/kbd.c b/usr.sbin/bluetooth/bthidd/kbd.c index b5bdfe1..e570b80 100644 --- a/usr.sbin/bluetooth/bthidd/kbd.c +++ b/usr.sbin/bluetooth/bthidd/kbd.c @@ -37,6 +37,7 @@ #include <sys/queue.h> #include <sys/wait.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <dev/usb/usb.h> #include <dev/usb/usbhid.h> @@ -225,8 +226,8 @@ static int32_t const x[] = /* Keyboard Int'l 7 8D */ -1, /* Unassigned */ /* Keyboard Int'l 8 8E */ -1, /* Unassigned */ /* Keyboard Int'l 9 8F */ -1, /* Unassigned */ -/* Keyboard Lang 1 90 */ NOBREAK|0xF2, /* None */ -/* Keyboard Lang 2 91 */ NOBREAK|0xF1, /* None */ +/* Keyboard Lang 1 90 */ 0x71, /* eisu */ +/* Keyboard Lang 2 91 */ 0x72, /* kana */ /* Keyboard Lang 3 92 */ 0x78, /* F8 */ /* Keyboard Lang 4 93 */ 0x77, /* F7 */ /* Keyboard Lang 5 94 */ 0x76, /* F6 */ diff --git a/usr.sbin/bluetooth/bthidd/lexer.l b/usr.sbin/bluetooth/bthidd/lexer.l index b9f62a1..6d913ee 100644 --- a/usr.sbin/bluetooth/bthidd/lexer.l +++ b/usr.sbin/bluetooth/bthidd/lexer.l @@ -31,7 +31,7 @@ * $Id: lexer.l,v 1.3 2006/09/07 21:06:53 max Exp $ * $FreeBSD$ */ - +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <stdlib.h> #include "parser.h" diff --git a/usr.sbin/bluetooth/bthidd/parser.y b/usr.sbin/bluetooth/bthidd/parser.y index 50468f4..dbb2763 100644 --- a/usr.sbin/bluetooth/bthidd/parser.y +++ b/usr.sbin/bluetooth/bthidd/parser.y @@ -33,6 +33,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <dev/usb/usb.h> #include <dev/usb/usbhid.h> diff --git a/usr.sbin/bluetooth/bthidd/server.c b/usr.sbin/bluetooth/bthidd/server.c index d76bd62..26aeb4a 100644 --- a/usr.sbin/bluetooth/bthidd/server.c +++ b/usr.sbin/bluetooth/bthidd/server.c @@ -33,6 +33,7 @@ #include <sys/queue.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <dev/vkbd/vkbd_var.h> #include <errno.h> @@ -90,7 +91,9 @@ server_init(bthid_server_p srv) l2addr.l2cap_family = AF_BLUETOOTH; memcpy(&l2addr.l2cap_bdaddr, &srv->bdaddr, sizeof(l2addr.l2cap_bdaddr)); l2addr.l2cap_psm = htole16(0x11); - + l2addr.l2cap_bdaddr_type = BDADDR_BREDR; + l2addr.l2cap_cid = 0; + if (bind(srv->ctrl, (struct sockaddr *) &l2addr, sizeof(l2addr)) < 0) { syslog(LOG_ERR, "Could not bind control L2CAP socket. " \ "%s (%d)", strerror(errno), errno); diff --git a/usr.sbin/bluetooth/bthidd/session.c b/usr.sbin/bluetooth/bthidd/session.c index b9f331b..260cb86 100644 --- a/usr.sbin/bluetooth/bthidd/session.c +++ b/usr.sbin/bluetooth/bthidd/session.c @@ -33,6 +33,7 @@ #include <sys/queue.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <fcntl.h> diff --git a/usr.sbin/bluetooth/btpand/Makefile b/usr.sbin/bluetooth/btpand/Makefile index 5e4bb0b..0689d17 100644 --- a/usr.sbin/bluetooth/btpand/Makefile +++ b/usr.sbin/bluetooth/btpand/Makefile @@ -7,7 +7,6 @@ SRCS= btpand.c bnep.c channel.c client.c event.c packet.c server.c sdp.c tap.c WARNS?= 3 -DPADD+= ${LIBBLUETOOTH} ${LIBSDP} ${LIBUTIL} -LDADD+= -lbluetooth -lsdp -lutil +LIBADD= bluetooth sdp util .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/btpand/bnep.c b/usr.sbin/bluetooth/btpand/bnep.c index 200a723..4065b1b 100644 --- a/usr.sbin/bluetooth/btpand/bnep.c +++ b/usr.sbin/bluetooth/btpand/bnep.c @@ -31,6 +31,7 @@ __RCSID("$NetBSD: bnep.c,v 1.1 2008/08/17 13:20:57 plunky Exp $"); #include <sys/uio.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <stdarg.h> diff --git a/usr.sbin/bluetooth/btpand/btpand.8 b/usr.sbin/bluetooth/btpand/btpand.8 index b89bf95..4f6ede6 100644 --- a/usr.sbin/bluetooth/btpand/btpand.8 +++ b/usr.sbin/bluetooth/btpand/btpand.8 @@ -206,10 +206,10 @@ Will create a Group Network and register the GN service with the local SDP server. .Sh SEE ALSO .Xr bluetooth 3 , -.Xr tap 4 , .Xr bridge 4 , -.Xr hccontrol 8 , +.Xr tap 4 , .Xr dhclient 8 , +.Xr hccontrol 8 , .Xr ifconfig 8 , .Xr sdpd 8 .Pp diff --git a/usr.sbin/bluetooth/btpand/btpand.c b/usr.sbin/bluetooth/btpand/btpand.c index 9387444..243fcf5 100644 --- a/usr.sbin/bluetooth/btpand/btpand.c +++ b/usr.sbin/bluetooth/btpand/btpand.c @@ -33,6 +33,7 @@ __RCSID("$NetBSD: btpand.c,v 1.1 2008/08/17 13:20:57 plunky Exp $"); #include <sys/wait.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <err.h> #include <fcntl.h> diff --git a/usr.sbin/bluetooth/btpand/channel.c b/usr.sbin/bluetooth/btpand/channel.c index b4eb4ab..32f2487 100644 --- a/usr.sbin/bluetooth/btpand/channel.c +++ b/usr.sbin/bluetooth/btpand/channel.c @@ -35,7 +35,7 @@ __RCSID("$NetBSD: channel.c,v 1.1 2008/08/17 13:20:57 plunky Exp $"); #include <libutil.h> #include <unistd.h> - +#define L2CAP_SOCKET_CHECKED #include "btpand.h" static struct chlist channel_list; diff --git a/usr.sbin/bluetooth/btpand/client.c b/usr.sbin/bluetooth/btpand/client.c index 2cc9089..f88dc6e 100644 --- a/usr.sbin/bluetooth/btpand/client.c +++ b/usr.sbin/bluetooth/btpand/client.c @@ -30,6 +30,7 @@ #include <sys/cdefs.h> __RCSID("$NetBSD: client.c,v 1.2 2008/12/06 20:01:14 plunky Exp $"); +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <sdp.h> @@ -65,6 +66,9 @@ client_init(void) memset(&sa, 0, sizeof(sa)); sa.l2cap_family = AF_BLUETOOTH; sa.l2cap_len = sizeof(sa); + sa.l2cap_bdaddr_type = BDADDR_BREDR; + sa.l2cap_cid = 0; + bdaddr_copy(&sa.l2cap_bdaddr, &local_bdaddr); if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { log_err("Could not bind client socket: %m"); diff --git a/usr.sbin/bluetooth/btpand/event.c b/usr.sbin/bluetooth/btpand/event.c index 159f90c..ac51f57 100644 --- a/usr.sbin/bluetooth/btpand/event.c +++ b/usr.sbin/bluetooth/btpand/event.c @@ -45,6 +45,7 @@ #include <syslog.h> #include "event.h" +#define L2CAP_SOCKET_CHECKED #include "btpand.h" #define __event_link(ev) \ diff --git a/usr.sbin/bluetooth/btpand/packet.c b/usr.sbin/bluetooth/btpand/packet.c index e42e5c5..21a563c 100644 --- a/usr.sbin/bluetooth/btpand/packet.c +++ b/usr.sbin/bluetooth/btpand/packet.c @@ -30,6 +30,7 @@ #include <sys/cdefs.h> __RCSID("$NetBSD: packet.c,v 1.1 2008/08/17 13:20:57 plunky Exp $"); +#define L2CAP_SOCKET_CHECKED #include "btpand.h" packet_t * diff --git a/usr.sbin/bluetooth/btpand/sdp.c b/usr.sbin/bluetooth/btpand/sdp.c index e5aec1c..3cad3f8 100644 --- a/usr.sbin/bluetooth/btpand/sdp.c +++ b/usr.sbin/bluetooth/btpand/sdp.c @@ -32,6 +32,7 @@ __RCSID("$NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $"); #include <string.h> +#define L2CAP_SOCKET_CHECKED #include "sdp.h" /* diff --git a/usr.sbin/bluetooth/btpand/server.c b/usr.sbin/bluetooth/btpand/server.c index b24d416..b72b032 100644 --- a/usr.sbin/bluetooth/btpand/server.c +++ b/usr.sbin/bluetooth/btpand/server.c @@ -32,6 +32,7 @@ __RCSID("$NetBSD: server.c,v 1.2 2009/01/24 17:29:28 plunky Exp $"); #include <sys/ioctl.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <inttypes.h> #include <errno.h> @@ -103,6 +104,9 @@ server_open(void) sa.l2cap_family = AF_BLUETOOTH; sa.l2cap_len = sizeof(sa); sa.l2cap_psm = htole16(l2cap_psm); + sa.l2cap_bdaddr_type = BDADDR_BREDR; + sa.l2cap_cid = 0; + bdaddr_copy(&sa.l2cap_bdaddr, &local_bdaddr); if (bind(server_fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { log_err("Could not bind server socket: %m"); diff --git a/usr.sbin/bluetooth/btpand/tap.c b/usr.sbin/bluetooth/btpand/tap.c index c965633..644bf02 100644 --- a/usr.sbin/bluetooth/btpand/tap.c +++ b/usr.sbin/bluetooth/btpand/tap.c @@ -43,6 +43,7 @@ __RCSID("$NetBSD: tap.c,v 1.1 2008/08/17 13:20:57 plunky Exp $"); #include <stdio.h> #include <unistd.h> +#define L2CAP_SOCKET_CHECKED #include "btpand.h" static bool tap_send(channel_t *, packet_t *); diff --git a/usr.sbin/bluetooth/hccontrol/Makefile b/usr.sbin/bluetooth/hccontrol/Makefile index 592247e..a81fda4 100644 --- a/usr.sbin/bluetooth/hccontrol/Makefile +++ b/usr.sbin/bluetooth/hccontrol/Makefile @@ -3,12 +3,11 @@ PROG= hccontrol MAN= hccontrol.8 -SRCS= send_recv.c link_policy.c link_control.c \ +SRCS= send_recv.c link_policy.c link_control.c le.c\ host_controller_baseband.c info.c status.c node.c hccontrol.c \ util.c WARNS?= 2 -DPADD= ${LIBBLUETOOTH} -LDADD= -lbluetooth +LIBADD= bluetooth .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/hccontrol/hccontrol.8 b/usr.sbin/bluetooth/hccontrol/hccontrol.8 index af0a67f..d8c5263 100644 --- a/usr.sbin/bluetooth/hccontrol/hccontrol.8 +++ b/usr.sbin/bluetooth/hccontrol/hccontrol.8 @@ -25,12 +25,12 @@ .\" $Id: hccontrol.8,v 1.6 2003/08/06 21:26:38 max Exp $ .\" $FreeBSD$ .\" -.Dd June 14, 2002 +.Dd February 7, 2015 .Dt HCCONTROL 8 .Os .Sh NAME .Nm hccontrol -.Nd HCI configuration utility +.Nd Bluetooth HCI configuration utility .Sh SYNOPSIS .Nm .Op Fl hN diff --git a/usr.sbin/bluetooth/hccontrol/hccontrol.c b/usr.sbin/bluetooth/hccontrol/hccontrol.c index 089869b..b72854f 100644 --- a/usr.sbin/bluetooth/hccontrol/hccontrol.c +++ b/usr.sbin/bluetooth/hccontrol/hccontrol.c @@ -29,6 +29,7 @@ * $FreeBSD$ */ +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sys/ioctl.h> #include <sys/sysctl.h> @@ -143,6 +144,7 @@ socket_open(char const *node) bit_set(filter.event_mask, NG_HCI_EVENT_READ_CLOCK_OFFSET_COMPL - 1); bit_set(filter.event_mask, NG_HCI_EVENT_CON_PKT_TYPE_CHANGED - 1); bit_set(filter.event_mask, NG_HCI_EVENT_ROLE_CHANGE - 1); + bit_set(filter.event_mask, NG_HCI_EVENT_LE -1); if (setsockopt(s, SOL_HCI_RAW, SO_HCI_RAW_FILTER, (void * const) &filter, sizeof(filter)) < 0) @@ -181,6 +183,7 @@ do_hci_command(char const *node, int argc, char **argv) print_hci_command(host_controller_baseband_commands); print_hci_command(info_commands); print_hci_command(status_commands); + print_hci_command(le_commands); print_hci_command(node_commands); fprintf(stdout, "\nFor more information use " \ "'help command'\n"); @@ -212,6 +215,11 @@ do_hci_command(char const *node, int argc, char **argv) if (c != NULL) goto execute; + c = find_hci_command(cmd, le_commands); + if (c != NULL) + goto execute; + + c = find_hci_command(cmd, node_commands); if (c == NULL) { fprintf(stdout, "Unknown command: \"%s\"\n", cmd); diff --git a/usr.sbin/bluetooth/hccontrol/hccontrol.h b/usr.sbin/bluetooth/hccontrol/hccontrol.h index cd56ebf..c96aab0 100644 --- a/usr.sbin/bluetooth/hccontrol/hccontrol.h +++ b/usr.sbin/bluetooth/hccontrol/hccontrol.h @@ -53,6 +53,7 @@ extern struct hci_command host_controller_baseband_commands[]; extern struct hci_command info_commands[]; extern struct hci_command status_commands[]; extern struct hci_command node_commands[]; +extern struct hci_command le_commands[]; int hci_request (int, int, char const *, int, char *, int *); int hci_simple_request (int, int, char *, int *); diff --git a/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c b/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c index aae5dd1..532ca1c 100644 --- a/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c +++ b/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c @@ -29,6 +29,7 @@ * $FreeBSD$ */ +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <stdio.h> @@ -1487,6 +1488,78 @@ hci_write_page_scan_mode(int s, int argc, char **argv) return (OK); } /* hci_write_page_scan_mode */ +static int +hci_read_le_host_supported_command(int s, int argc, char **argv) +{ + ng_hci_read_le_host_supported_rp rp; + int n; + n = sizeof(rp); + if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, + NG_HCI_OCF_READ_LE_HOST_SUPPORTED), + (char *) &rp, &n) == ERROR) + return (ERROR); + + if (rp.status != 0x00) { + fprintf(stdout, "Status: %s [%#02x]\n", + hci_status2str(rp.status), rp.status); + return (FAILED); + } + + fprintf(stdout, "LE Host support: %#02x\n", rp.le_supported_host); + fprintf(stdout, "Simulateneouse LE Host : %#02x\n", rp.simultaneous_le_host); + + return (OK); + +} +static int +hci_write_le_host_supported_command(int s, int argc, char **argv) +{ + ng_hci_write_le_host_supported_cp cp; + ng_hci_write_le_host_supported_rp rp; + + int n; + + cp.le_supported_host = 0; + cp.simultaneous_le_host = 0; + switch (argc) { + case 2: + if (sscanf(argv[1], "%d", &n) != 1 || (n != 0 && n != 1)){ + printf("ARGC2: %d\n", n); + return (USAGE); + } + cp.simultaneous_le_host = (n &1); + + case 1: + if (sscanf(argv[0], "%d", &n) != 1 || (n != 0 && n != 1)){ + printf("ARGC1: %d\n", n); + return (USAGE); + } + + cp.le_supported_host = (n &1); + break; + + default: + return (USAGE); + } + + + /* send command */ + n = sizeof(rp); + if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, + NG_HCI_OCF_WRITE_LE_HOST_SUPPORTED), + (char const *) &cp, sizeof(cp), + (char *) &rp, &n) == ERROR) + return (ERROR); + + if (rp.status != 0x00) { + fprintf(stdout, "Status: %s [%#02x]\n", + hci_status2str(rp.status), rp.status); + return (FAILED); + } + + return (OK); +} + struct hci_command host_controller_baseband_commands[] = { { "reset", @@ -1872,6 +1945,17 @@ struct hci_command host_controller_baseband_commands[] = { "\t0x03 - Optional Page Scan Mode III", &hci_write_page_scan_mode }, +{ +"read_le_host_supported_command", \ +"Read if this host is in le supported mode and stimulatenouse le supported mode", +&hci_read_le_host_supported_command, +}, +{ +"write_le_host_supported_command", \ +"write_le_host_supported_command le_host[0|1] stimultajeous_le[0|1]", +&hci_write_le_host_supported_command, +}, + { NULL, } }; diff --git a/usr.sbin/bluetooth/hccontrol/info.c b/usr.sbin/bluetooth/hccontrol/info.c index d7bad36..ee9d1a1 100644 --- a/usr.sbin/bluetooth/hccontrol/info.c +++ b/usr.sbin/bluetooth/hccontrol/info.c @@ -29,6 +29,7 @@ * $FreeBSD$ */ +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <stdio.h> diff --git a/usr.sbin/bluetooth/hccontrol/le.c b/usr.sbin/bluetooth/hccontrol/le.c new file mode 100644 index 0000000..afb151e --- /dev/null +++ b/usr.sbin/bluetooth/hccontrol/le.c @@ -0,0 +1,356 @@ +/* + * le.c + * + * Copyright (c) 2015 Takanori Watanabe <takawata@freebsd.org> + * 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. + * + * $Id: hccontrol.c,v 1.5 2003/09/05 00:38:24 max Exp $ + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/sysctl.h> +#include <sys/bitstring.h> +#include <sys/select.h> +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <netgraph/ng_message.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <stdint.h> +#define L2CAP_SOCKET_CHECKED +#include <bluetooth.h> +#include "hccontrol.h" + +static int le_set_scan_param(int s, int argc, char *argv[]); +static int le_set_scan_enable(int s, int argc, char *argv[]); +static int parse_param(int argc, char *argv[], char *buf, int *len); +static int le_set_scan_response(int s, int argc, char *argv[]); +static int le_read_supported_status(int s, int argc, char *argv[]); +static int le_read_local_supported_features(int s, int argc ,char *argv[]); +static int set_le_event_mask(int s, uint64_t mask); +static int set_event_mask(int s, uint64_t mask); +static int le_enable(int s, int argc, char *argv[]); + +static int +le_set_scan_param(int s, int argc, char *argv[]) +{ + int type; + int interval; + int window; + int adrtype; + int policy; + int e, n; + + ng_hci_le_set_scan_parameters_cp cp; + ng_hci_le_set_scan_parameters_rp rp; + + if (argc != 5) + return USAGE; + + if (strcmp(argv[0], "active") == 0) + type = 1; + else if (strcmp(argv[0], "passive") == 0) + type = 0; + else + return USAGE; + + interval = (int)(atof(argv[1])/0.625); + interval = (interval < 4)? 4: interval; + window = (int)(atof(argv[2])/0.625); + window = (window < 4) ? 4 : interval; + + if (strcmp(argv[3], "public") == 0) + adrtype = 0; + else if (strcmp(argv[0], "random") == 0) + adrtype = 1; + else + return USAGE; + + if (strcmp(argv[4], "all") == 0) + policy = 0; + else if (strcmp(argv[4], "whitelist") == 0) + policy = 1; + else + return USAGE; + + cp.le_scan_type = type; + cp.le_scan_interval = interval; + cp.own_address_type = adrtype; + cp.le_scan_window = window; + cp.scanning_filter_policy = policy; + n = sizeof(rp); + e = hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, + NG_HCI_OCF_LE_SET_SCAN_PARAMETERS), + (void *)&cp, sizeof(cp), (void *)&rp, &n); + + return 0; +} + +static int +le_set_scan_enable(int s, int argc, char *argv[]) +{ + ng_hci_le_set_scan_enable_cp cp; + ng_hci_le_set_scan_enable_rp rp; + int e, n, enable = 0; + + if (argc != 1) + return USAGE; + + if (strcmp(argv[0], "enable") == 0) + enable = 1; + else if (strcmp(argv[0], "disable") != 0) + return USAGE; + + n = sizeof(rp); + cp.le_scan_enable = enable; + cp.filter_duplicates = 0; + e = hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, + NG_HCI_OCF_LE_SET_SCAN_ENABLE), + (void *)&cp, sizeof(cp), (void *)&rp, &n); + + if (e != 0 || rp.status != 0) + return ERROR; + + return OK; +} + +static int +parse_param(int argc, char *argv[], char *buf, int *len) +{ + char *buflast = buf + (*len); + char *curbuf = buf; + char *token,*lenpos; + int ch; + int datalen; + uint16_t value; + optreset = 1; + optind = 0; + while ((ch = getopt(argc, argv , "n:f:u:")) != -1) { + switch(ch){ + case 'n': + datalen = strlen(optarg); + if ((curbuf + datalen + 2) >= buflast) + goto done; + curbuf[0] = datalen + 1; + curbuf[1] = 8; + curbuf += 2; + memcpy(curbuf, optarg, datalen); + curbuf += datalen; + break; + case 'f': + if (curbuf+3 > buflast) + goto done; + curbuf[0] = 2; + curbuf[1] = 1; + curbuf[2] = atoi(optarg); + curbuf += 3; + break; + case 'u': + lenpos = buf; + if ((buf+2) >= buflast) + goto done; + curbuf[1] = 2; + *lenpos = 1; + curbuf += 2; + while ((token = strsep(&optarg, ",")) != NULL) { + value = strtol(token, NULL, 16); + if ((curbuf+2) >= buflast) + break; + curbuf[0] = value &0xff; + curbuf[1] = (value>>8)&0xff; + curbuf += 2; + } + + } + } +done: + *len = curbuf - buf; + + return OK; +} + +static int +le_set_scan_response(int s, int argc, char *argv[]) +{ + ng_hci_le_set_scan_response_data_cp cp; + ng_hci_le_set_scan_response_data_rp rp; + int n; + int e; + int len; + char buf[NG_HCI_ADVERTISING_DATA_SIZE]; + + len = sizeof(buf); + parse_param(argc, argv, buf, &len); + memset(cp.scan_response_data, 0, sizeof(cp.scan_response_data)); + cp.scan_response_data_length = len; + memcpy(cp.scan_response_data, buf, len); + n = sizeof(rp); + e = hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, + NG_HCI_OCF_LE_SET_SCAN_RESPONSE_DATA), + (void *)&cp, sizeof(cp), (void *)&rp, &n); + + printf("SET SCAN RESPONSE %d %d %d\n", e, rp.status, n); + + return OK; +} + +static int +le_read_local_supported_features(int s, int argc ,char *argv[]) +{ + ng_hci_le_read_local_supported_features_rp rp; + int e; + int n = sizeof(rp); + + e = hci_simple_request(s, + NG_HCI_OPCODE(NG_HCI_OGF_LE, + NG_HCI_OCF_LE_READ_LOCAL_SUPPORTED_FEATURES), + (void *)&rp, &n); + + printf("LOCAL SUPPORTED: %d %d %jx\n", e, rp.status, + (uintmax_t) rp.le_features); + + return 0; +} + +static int +le_read_supported_status(int s, int argc, char *argv[]) +{ + ng_hci_le_read_supported_status_rp rp; + int e; + int n = sizeof(rp); + + e = hci_simple_request(s, NG_HCI_OPCODE( + NG_HCI_OGF_LE, + NG_HCI_OCF_LE_READ_SUPPORTED_STATUS), + (void *)&rp, &n); + + printf("LE_STATUS: %d %d %jx\n", e, rp.status, (uintmax_t)rp.le_status); + + return 0; +} + +static int +set_le_event_mask(int s, uint64_t mask) +{ + ng_hci_le_set_event_mask_cp semc; + ng_hci_le_set_event_mask_rp rp; + int i, n ,e; + + n = sizeof(rp); + + for (i=0; i < NG_HCI_LE_EVENT_MASK_SIZE; i++) { + semc.event_mask[i] = mask&0xff; + mask >>= 8; + } + e = hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, + NG_HCI_OCF_LE_SET_EVENT_MASK), + (void *)&semc, sizeof(semc), (void *)&rp, &n); + + return 0; +} + +static int +set_event_mask(int s, uint64_t mask) +{ + ng_hci_set_event_mask_cp semc; + ng_hci_set_event_mask_rp rp; + int i, n, e; + + n = sizeof(rp); + + for (i=0; i < NG_HCI_EVENT_MASK_SIZE; i++) { + semc.event_mask[i] = mask&0xff; + mask >>= 8; + } + e = hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, + NG_HCI_OCF_SET_EVENT_MASK), + (void *)&semc, sizeof(semc), (void *)&rp, &n); + + return 0; +} + +static +int le_enable(int s, int argc, char *argv[]) +{ + if (argc != 1) + return USAGE; + + if (strcasecmp(argv[0], "enable") == 0) { + set_event_mask(s, NG_HCI_EVENT_MASK_DEFAULT | + NG_HCI_EVENT_MASK_LE); + set_le_event_mask(s, NG_HCI_LE_EVENT_MASK_ALL); + } else if (strcasecmp(argv[0], "disble") == 0) + set_event_mask(s, NG_HCI_EVENT_MASK_DEFAULT); + else + return USAGE; + + return OK; +} + +struct hci_command le_commands[] = { +{ + "le_enable", + "le_enable [enable|disable] \n" + "Enable LE event ", + &le_enable, +}, + { + "le_read_local_supported_features", + "le_read_local_supported_features\n" + "read local supported features mask", + &le_read_local_supported_features, + }, + { + "le_read_supported_status", + "le_read_supported_status\n" + "read supported status" + , + &le_read_supported_status, + }, + { + "le_set_scan_response", + "le_set_scan_response -n $name -f $flag -u $uuid16,$uuid16 \n" + "set LE scan response data" + , + &le_set_scan_response, + }, + { + "le_set_scan_enable", + "le_set_scan_enable [enable|disable] \n" + "enable or disable LE device scan", + &le_set_scan_enable + }, + { + "le_set_scan_param", + "le_set_scan_param [active|passive] interval(ms) window(ms) [public|random] [all|whitelist] \n" + "set LE device scan parameter", + &le_set_scan_param + }, +}; diff --git a/usr.sbin/bluetooth/hccontrol/link_control.c b/usr.sbin/bluetooth/hccontrol/link_control.c index 536520a..a55426c 100644 --- a/usr.sbin/bluetooth/hccontrol/link_control.c +++ b/usr.sbin/bluetooth/hccontrol/link_control.c @@ -29,6 +29,7 @@ * $FreeBSD$ */ +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <stdio.h> diff --git a/usr.sbin/bluetooth/hccontrol/link_policy.c b/usr.sbin/bluetooth/hccontrol/link_policy.c index 67b32d5..8142b23 100644 --- a/usr.sbin/bluetooth/hccontrol/link_policy.c +++ b/usr.sbin/bluetooth/hccontrol/link_policy.c @@ -29,6 +29,7 @@ * $FreeBSD$ */ +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <stdio.h> diff --git a/usr.sbin/bluetooth/hccontrol/node.c b/usr.sbin/bluetooth/hccontrol/node.c index ede2153..fb6fd19 100644 --- a/usr.sbin/bluetooth/hccontrol/node.c +++ b/usr.sbin/bluetooth/hccontrol/node.c @@ -30,6 +30,7 @@ */ #include <sys/ioctl.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <netgraph/ng_message.h> diff --git a/usr.sbin/bluetooth/hccontrol/util.c b/usr.sbin/bluetooth/hccontrol/util.c index 4bb5000..1b05170 100644 --- a/usr.sbin/bluetooth/hccontrol/util.c +++ b/usr.sbin/bluetooth/hccontrol/util.c @@ -30,6 +30,7 @@ */ #include <sys/param.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <stdio.h> #include <string.h> @@ -151,7 +152,12 @@ hci_ver2str(int ver) /* 0x00 */ "Bluetooth HCI Specification 1.0B", /* 0x01 */ "Bluetooth HCI Specification 1.1", /* 0x02 */ "Bluetooth HCI Specification 1.2", - /* 0x03 */ "Bluetooth HCI Specification 2.0" + /* 0x03 */ "Bluetooth HCI Specification 2.0", + /* 0x04 */ "Bluetooth HCI Specification 2.1", + /* 0x05 */ "Bluetooth HCI Specification 3.0", + /* 0x06 */ "Bluetooth HCI Specification 4.0", + /* 0x07 */ "Bluetooth HCI Specification 4.1", + /* 0x08 */ "Bluetooth HCI Specification 4.2" }; return (ver >= SIZE(t)? "?" : t[ver]); @@ -164,7 +170,12 @@ hci_lmpver2str(int ver) /* 0x00 */ "Bluetooth LMP 1.0", /* 0x01 */ "Bluetooth LMP 1.1", /* 0x02 */ "Bluetooth LMP 1.2", - /* 0x03 */ "Bluetooth LMP 2.0" + /* 0x03 */ "Bluetooth LMP 2.0", + /* 0x04 */ "Bluetooth LMP 2.1", + /* 0x04 */ "Bluetooth LMP 3.0", + /* 0x04 */ "Bluetooth LMP 4.0", + /* 0x04 */ "Bluetooth LMP 4.1", + /* 0x04 */ "Bluetooth LMP 4.2" }; return (ver >= SIZE(t)? "?" : t[ver]); diff --git a/usr.sbin/bluetooth/hcsecd/Makefile b/usr.sbin/bluetooth/hcsecd/Makefile index e544ed4..684243d 100644 --- a/usr.sbin/bluetooth/hcsecd/Makefile +++ b/usr.sbin/bluetooth/hcsecd/Makefile @@ -7,7 +7,6 @@ SRCS= hcsecd.c lexer.l parser.y WARNS?= 2 CFLAGS+= -I${.CURDIR} -DPADD= ${LIBBLUETOOTH} -LDADD= -lbluetooth +LIBADD= bluetooth .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/hcsecd/Makefile.depend b/usr.sbin/bluetooth/hcsecd/Makefile.depend index cba7fb1..cd6c344 100644 --- a/usr.sbin/bluetooth/hcsecd/Makefile.depend +++ b/usr.sbin/bluetooth/hcsecd/Makefile.depend @@ -11,6 +11,7 @@ DIRDEPS = \ lib/libbluetooth \ lib/libc \ lib/libcompiler_rt \ + usr.bin/yacc.host \ .include <dirdeps.mk> diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.c b/usr.sbin/bluetooth/hcsecd/hcsecd.c index 72f9c8c..15b5ca4 100644 --- a/usr.sbin/bluetooth/hcsecd/hcsecd.c +++ b/usr.sbin/bluetooth/hcsecd/hcsecd.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <err.h> #include <errno.h> diff --git a/usr.sbin/bluetooth/hcsecd/parser.y b/usr.sbin/bluetooth/hcsecd/parser.y index ec91c48..cfaeb02 100644 --- a/usr.sbin/bluetooth/hcsecd/parser.y +++ b/usr.sbin/bluetooth/hcsecd/parser.y @@ -32,6 +32,7 @@ #include <sys/fcntl.h> #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <limits.h> diff --git a/usr.sbin/bluetooth/hcseriald/Makefile b/usr.sbin/bluetooth/hcseriald/Makefile index ed0bf32..e02e1ae 100644 --- a/usr.sbin/bluetooth/hcseriald/Makefile +++ b/usr.sbin/bluetooth/hcseriald/Makefile @@ -5,7 +5,6 @@ PROG= hcseriald MAN= hcseriald.8 WARNS?= 2 -DPADD= ${LIBNETGRAPH} -LDADD= -lnetgraph +LIBADD= netgraph .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/l2control/Makefile b/usr.sbin/bluetooth/l2control/Makefile index 847ff4b..8f17e02 100644 --- a/usr.sbin/bluetooth/l2control/Makefile +++ b/usr.sbin/bluetooth/l2control/Makefile @@ -6,7 +6,6 @@ MAN= l2control.8 SRCS= l2cap.c l2control.c WARNS?= 2 -DPADD= ${LIBBLUETOOTH} -LDADD= -lbluetooth +LIBADD= bluetooth .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/l2control/l2cap.c b/usr.sbin/bluetooth/l2control/l2cap.c index c23106c..44009ef 100644 --- a/usr.sbin/bluetooth/l2control/l2cap.c +++ b/usr.sbin/bluetooth/l2control/l2cap.c @@ -30,6 +30,7 @@ */ #include <sys/ioctl.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <stdio.h> diff --git a/usr.sbin/bluetooth/l2control/l2control.c b/usr.sbin/bluetooth/l2control/l2control.c index fdbf2f5b..87ec237 100644 --- a/usr.sbin/bluetooth/l2control/l2control.c +++ b/usr.sbin/bluetooth/l2control/l2control.c @@ -30,6 +30,7 @@ */ #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <err.h> #include <errno.h> diff --git a/usr.sbin/bluetooth/l2ping/Makefile b/usr.sbin/bluetooth/l2ping/Makefile index bc130e3..572366a 100644 --- a/usr.sbin/bluetooth/l2ping/Makefile +++ b/usr.sbin/bluetooth/l2ping/Makefile @@ -5,7 +5,6 @@ PROG= l2ping MAN= l2ping.8 WARNS?= 2 -DPADD= ${LIBBLUETOOTH} -LDADD= -lbluetooth +LIBADD= bluetooth .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/l2ping/l2ping.c b/usr.sbin/bluetooth/l2ping/l2ping.c index 4baa354..92e7a0a 100644 --- a/usr.sbin/bluetooth/l2ping/l2ping.c +++ b/usr.sbin/bluetooth/l2ping/l2ping.c @@ -34,6 +34,7 @@ #include <arpa/inet.h> #include <netinet/in.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <err.h> #include <errno.h> diff --git a/usr.sbin/bluetooth/rfcomm_pppd/Makefile b/usr.sbin/bluetooth/rfcomm_pppd/Makefile index adac64e..f31e1e5 100644 --- a/usr.sbin/bluetooth/rfcomm_pppd/Makefile +++ b/usr.sbin/bluetooth/rfcomm_pppd/Makefile @@ -8,7 +8,6 @@ MAN= rfcomm_pppd.8 SRCS= rfcomm_pppd.c rfcomm_sdp.c WARNS?= 2 -DPADD= ${LIBBLUETOOTH} ${LIBSDP} -LDADD= -lbluetooth -lsdp +LIBADD= bluetooth sdp .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c index 956dc4d..e970fb0 100644 --- a/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c +++ b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c @@ -30,7 +30,7 @@ * $Id: rfcomm_pppd.c,v 1.5 2003/09/07 18:32:11 max Exp $ * $FreeBSD$ */ - +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <ctype.h> #include <err.h> diff --git a/usr.sbin/bluetooth/sdpcontrol/Makefile b/usr.sbin/bluetooth/sdpcontrol/Makefile index c0ec8d4..e3ebcd8 100644 --- a/usr.sbin/bluetooth/sdpcontrol/Makefile +++ b/usr.sbin/bluetooth/sdpcontrol/Makefile @@ -6,7 +6,6 @@ MAN= sdpcontrol.8 SRCS= sdpcontrol.c search.c WARNS?= 2 -DPADD= ${LIBBLUETOOTH} ${LIBSDP} -LDADD= -lbluetooth -lsdp +LIBADD= bluetooth sdp .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.8 b/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.8 index 89db90b..82aafad 100644 --- a/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.8 +++ b/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.8 @@ -25,12 +25,12 @@ .\" $Id: sdpcontrol.8,v 1.1 2003/09/08 02:27:27 max Exp $ .\" $FreeBSD$ .\" -.Dd September 7, 2003 +.Dd February 7, 2015 .Dt SDPCONTROL 8 .Os .Sh NAME .Nm sdpcontrol -.Nd SDP query utility +.Nd Bluetooth Service Discovery Protocol query utility .Sh SYNOPSIS .Nm .Fl h diff --git a/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.c b/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.c index fca2015..65ee3d0 100644 --- a/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.c +++ b/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.c @@ -30,6 +30,7 @@ */ #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <err.h> #include <errno.h> diff --git a/usr.sbin/bluetooth/sdpcontrol/search.c b/usr.sbin/bluetooth/sdpcontrol/search.c index e7d8244..acc8c16 100644 --- a/usr.sbin/bluetooth/sdpcontrol/search.c +++ b/usr.sbin/bluetooth/sdpcontrol/search.c @@ -30,6 +30,7 @@ */ #include <netinet/in.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <ctype.h> #include <sdp.h> diff --git a/usr.sbin/bluetooth/sdpd/bgd.c b/usr.sbin/bluetooth/sdpd/bgd.c index 70dda89..2c4e4d9 100644 --- a/usr.sbin/bluetooth/sdpd/bgd.c +++ b/usr.sbin/bluetooth/sdpd/bgd.c @@ -28,7 +28,7 @@ * $Id: bgd.c,v 1.4 2004/01/13 01:54:39 max Exp $ * $FreeBSD$ */ - +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/dun.c b/usr.sbin/bluetooth/sdpd/dun.c index e7aeb78..1496285 100644 --- a/usr.sbin/bluetooth/sdpd/dun.c +++ b/usr.sbin/bluetooth/sdpd/dun.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/ftrn.c b/usr.sbin/bluetooth/sdpd/ftrn.c index bcebfc7..bc1095e 100644 --- a/usr.sbin/bluetooth/sdpd/ftrn.c +++ b/usr.sbin/bluetooth/sdpd/ftrn.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/gn.c b/usr.sbin/bluetooth/sdpd/gn.c index d35c0ee..c2bea48 100644 --- a/usr.sbin/bluetooth/sdpd/gn.c +++ b/usr.sbin/bluetooth/sdpd/gn.c @@ -32,6 +32,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/irmc.c b/usr.sbin/bluetooth/sdpd/irmc.c index d28a120..2b8f317 100644 --- a/usr.sbin/bluetooth/sdpd/irmc.c +++ b/usr.sbin/bluetooth/sdpd/irmc.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/irmc_command.c b/usr.sbin/bluetooth/sdpd/irmc_command.c index 10dafe0..a55e133 100644 --- a/usr.sbin/bluetooth/sdpd/irmc_command.c +++ b/usr.sbin/bluetooth/sdpd/irmc_command.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/lan.c b/usr.sbin/bluetooth/sdpd/lan.c index 2425a89..3ed2b12 100644 --- a/usr.sbin/bluetooth/sdpd/lan.c +++ b/usr.sbin/bluetooth/sdpd/lan.c @@ -31,6 +31,7 @@ #include <arpa/inet.h> #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <stdio.h> diff --git a/usr.sbin/bluetooth/sdpd/main.c b/usr.sbin/bluetooth/sdpd/main.c index 1df3bf0..a287b9b 100644 --- a/usr.sbin/bluetooth/sdpd/main.c +++ b/usr.sbin/bluetooth/sdpd/main.c @@ -30,6 +30,7 @@ */ #include <sys/select.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <grp.h> diff --git a/usr.sbin/bluetooth/sdpd/nap.c b/usr.sbin/bluetooth/sdpd/nap.c index 5a857d8..c034ee6 100644 --- a/usr.sbin/bluetooth/sdpd/nap.c +++ b/usr.sbin/bluetooth/sdpd/nap.c @@ -32,6 +32,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/opush.c b/usr.sbin/bluetooth/sdpd/opush.c index 36359da..bcdfda2 100644 --- a/usr.sbin/bluetooth/sdpd/opush.c +++ b/usr.sbin/bluetooth/sdpd/opush.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/panu.c b/usr.sbin/bluetooth/sdpd/panu.c index e00f650..5b2773e 100644 --- a/usr.sbin/bluetooth/sdpd/panu.c +++ b/usr.sbin/bluetooth/sdpd/panu.c @@ -32,6 +32,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/profile.c b/usr.sbin/bluetooth/sdpd/profile.c index f3dfaa7..5c25d03 100644 --- a/usr.sbin/bluetooth/sdpd/profile.c +++ b/usr.sbin/bluetooth/sdpd/profile.c @@ -32,6 +32,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/provider.c b/usr.sbin/bluetooth/sdpd/provider.c index b0f5347..0243305 100644 --- a/usr.sbin/bluetooth/sdpd/provider.c +++ b/usr.sbin/bluetooth/sdpd/provider.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <string.h> #include <stdlib.h> diff --git a/usr.sbin/bluetooth/sdpd/sar.c b/usr.sbin/bluetooth/sdpd/sar.c index 4fc25d9..705f716 100644 --- a/usr.sbin/bluetooth/sdpd/sar.c +++ b/usr.sbin/bluetooth/sdpd/sar.c @@ -34,6 +34,7 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <sdp.h> diff --git a/usr.sbin/bluetooth/sdpd/scr.c b/usr.sbin/bluetooth/sdpd/scr.c index d0c9ec5..1df72d1 100644 --- a/usr.sbin/bluetooth/sdpd/scr.c +++ b/usr.sbin/bluetooth/sdpd/scr.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <sdp.h> diff --git a/usr.sbin/bluetooth/sdpd/sd.c b/usr.sbin/bluetooth/sdpd/sd.c index 1743ea7..c5397ce 100644 --- a/usr.sbin/bluetooth/sdpd/sd.c +++ b/usr.sbin/bluetooth/sdpd/sd.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/server.c b/usr.sbin/bluetooth/sdpd/server.c index 4ef153b..abd1815 100644 --- a/usr.sbin/bluetooth/sdpd/server.c +++ b/usr.sbin/bluetooth/sdpd/server.c @@ -38,6 +38,7 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <pwd.h> diff --git a/usr.sbin/bluetooth/sdpd/sp.c b/usr.sbin/bluetooth/sdpd/sp.c index 31a9585a..48edc77 100644 --- a/usr.sbin/bluetooth/sdpd/sp.c +++ b/usr.sbin/bluetooth/sdpd/sp.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/srr.c b/usr.sbin/bluetooth/sdpd/srr.c index fd636d5..60f48ca 100644 --- a/usr.sbin/bluetooth/sdpd/srr.c +++ b/usr.sbin/bluetooth/sdpd/srr.c @@ -34,6 +34,7 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <sdp.h> diff --git a/usr.sbin/bluetooth/sdpd/ssar.c b/usr.sbin/bluetooth/sdpd/ssar.c index eac9235..5e52e80 100644 --- a/usr.sbin/bluetooth/sdpd/ssar.c +++ b/usr.sbin/bluetooth/sdpd/ssar.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <string.h> diff --git a/usr.sbin/bluetooth/sdpd/ssr.c b/usr.sbin/bluetooth/sdpd/ssr.c index ac27548..785c8ca 100644 --- a/usr.sbin/bluetooth/sdpd/ssr.c +++ b/usr.sbin/bluetooth/sdpd/ssr.c @@ -34,6 +34,7 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <sdp.h> diff --git a/usr.sbin/bluetooth/sdpd/sur.c b/usr.sbin/bluetooth/sdpd/sur.c index 143eaf3..581b593 100644 --- a/usr.sbin/bluetooth/sdpd/sur.c +++ b/usr.sbin/bluetooth/sdpd/sur.c @@ -30,6 +30,7 @@ */ #include <sys/queue.h> +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <errno.h> #include <sdp.h> diff --git a/usr.sbin/bluetooth/sdpd/uuid.c b/usr.sbin/bluetooth/sdpd/uuid.c index 1989bc5..dff8d2c 100644 --- a/usr.sbin/bluetooth/sdpd/uuid.c +++ b/usr.sbin/bluetooth/sdpd/uuid.c @@ -28,7 +28,7 @@ * $Id: uuid.c,v 1.1 2004/12/09 18:20:26 max Exp $ * $FreeBSD$ */ - +#define L2CAP_SOCKET_CHECKED #include <bluetooth.h> #include <sdp.h> #include <uuid.h> diff --git a/usr.sbin/boot0cfg/Makefile b/usr.sbin/boot0cfg/Makefile index bb7fe07..d41945a 100644 --- a/usr.sbin/boot0cfg/Makefile +++ b/usr.sbin/boot0cfg/Makefile @@ -3,8 +3,7 @@ PROG= boot0cfg MAN= boot0cfg.8 -DPADD= ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} -LDADD= -lgeom -lbsdxml -lsbuf +LIBADD= geom NO_WCAST_ALIGN= diff --git a/usr.sbin/boot98cfg/Makefile b/usr.sbin/boot98cfg/Makefile index 9b0e703..57dfe94 100644 --- a/usr.sbin/boot98cfg/Makefile +++ b/usr.sbin/boot98cfg/Makefile @@ -5,7 +5,6 @@ MAN= boot98cfg.8 WARNS?= 2 -DPADD= ${LIBGEOM} -LDADD= -lgeom +LIBADD= geom .include <bsd.prog.mk> diff --git a/usr.sbin/bsdconfig/console/INDEX b/usr.sbin/bsdconfig/console/INDEX index 18763fd..e298f34 100644 --- a/usr.sbin/bsdconfig/console/INDEX +++ b/usr.sbin/bsdconfig/console/INDEX @@ -1,5 +1,5 @@ # Copyright (c) 2012 Ron McDowell -# Copyright (c) 2012 Devin Teske +# Copyright (c) 2012-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,13 @@ menu_help="Customize system console behavior" # can be i18n'ed but `command' is the name of a script. # menu_selection="console|console" +menu_selection="vt_font|font" +menu_selection="vt_keymap|keymap" +menu_selection="vt_repeat|repeat" +menu_selection="vt_saver|saver" +menu_selection="vt_screenmap|screenmap" +menu_selection="vt_ttys|ttys" +# For backward compatibility menu_selection="syscons_font|font" menu_selection="syscons_keymap|keymap" menu_selection="syscons_repeat|repeat" diff --git a/usr.sbin/bsdconfig/include/messages.subr b/usr.sbin/bsdconfig/include/messages.subr index 3d6aad0..04f4485 100644 --- a/usr.sbin/bsdconfig/include/messages.subr +++ b/usr.sbin/bsdconfig/include/messages.subr @@ -138,7 +138,6 @@ msg_ftp="FTP" msg_ftp_desc="FTP client and server utilities." msg_ftp_passive="FTP Passive" msg_ftp_username="FTP username" -msg_games_desc="Various games and sundry amusements." msg_generating_index_from_pkg_database="Generating INDEX from pkg(8) database\n(this can take a while)..." msg_geography_desc="Geography-related software." msg_german_desc="Ported software for Germanic countries." diff --git a/usr.sbin/bsdconfig/includes/INDEX b/usr.sbin/bsdconfig/includes/INDEX index 6e829be..a6a6c49 100644 --- a/usr.sbin/bsdconfig/includes/INDEX +++ b/usr.sbin/bsdconfig/includes/INDEX @@ -1,4 +1,4 @@ -# Copyright (c) 2013 Devin Teske +# Copyright (c) 2013-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -45,6 +45,7 @@ menu_help="" # can be i18n'ed but `command' is the name of a script. # menu_selection="includes|includes" +menu_selection="api|includes" # # ------------ Items below this line do NOT need i18n translation ------------ diff --git a/usr.sbin/bsdconfig/networking/share/device.subr b/usr.sbin/bsdconfig/networking/share/device.subr index bb41be3..14758e6 100644 --- a/usr.sbin/bsdconfig/networking/share/device.subr +++ b/usr.sbin/bsdconfig/networking/share/device.subr @@ -1,6 +1,6 @@ if [ ! "$_NETWORKING_DEVICE_SUBR" ]; then _NETWORKING_DEVICE_SUBR=1 # -# Copyright (c) 2006-2013 Devin Teske +# Copyright (c) 2006-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -207,7 +207,7 @@ f_dialog_menu_netdev_edit() '3 $msg_ipaddr4' '$ipaddr' '4 $msg_netmask' '$netmask' '5 $msg_options' '$options' - " + " # END-QUOTE eval f_dialog_menu_size height width rows \ \"\$DIALOG_TITLE\" \ \"\$DIALOG_BACKTITLE\" \ diff --git a/usr.sbin/bsdconfig/share/dialog.subr b/usr.sbin/bsdconfig/share/dialog.subr index db99a70..d7c2d2c 100644 --- a/usr.sbin/bsdconfig/share/dialog.subr +++ b/usr.sbin/bsdconfig/share/dialog.subr @@ -1,6 +1,6 @@ if [ ! "$_DIALOG_SUBR" ]; then _DIALOG_SUBR=1 # -# Copyright (c) 2006-2014 Devin Teske +# Copyright (c) 2006-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -1580,6 +1580,56 @@ f_xdialog_info() -1 # timeout of -1 means abort when EOF on stdin } +############################################################ PAUSE FUNCTIONS + +# f_dialog_pause $msg_text $duration [$hline] +# +# Display a message in a widget with a progress bar that runs backward for +# $duration seconds. +# +f_dialog_pause() +{ + local pause_text="$1" duration="$2" hline="$3" height width + f_isinteger "$duration" || return $FAILURE + f_dialog_buttonbox_size height width \ + "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$pause_text" "$hline" + if [ "$USE_XDIALOG" ]; then + $DIALOG \ + --title "$DIALOG_TITLE" \ + --backtitle "$DIALOG_BACKTITLE" \ + --ok-label "$msg_skip" \ + --cancel-label "$msg_cancel" \ + ${noCancel:+--no-cancel} \ + --timeout "$duration" \ + --yesno "$pause_text" \ + $height $width + else + [ $duration -gt 0 ] && duration=$(( $duration - 1 )) + [ $duration -gt 1 ] && duration=$(( $duration - 1 )) + height=$(( $height + 3 )) # Add height for progress bar + $DIALOG \ + --title "$DIALOG_TITLE" \ + --backtitle "$DIALOG_BACKTITLE" \ + --hline "$hline" \ + --ok-label "$msg_skip" \ + --cancel-label "$msg_cancel" \ + ${noCancel:+--no-cancel} \ + --pause "$pause_text" \ + $height $width "$duration" + fi +} + +# f_dialog_pause_no_cancel $msg_text $duration [$hline] +# +# Display a message in a widget with a progress bar that runs backward for +# $duration seconds. No cancel button is provided. Always returns success. +# +f_dialog_pause_no_cancel() +{ + noCancel=1 f_dialog_pause "$@" + return $SUCCESS +} + ############################################################ MSGBOX FUNCTIONS # f_dialog_msgbox $msg_text [$hline] @@ -2066,6 +2116,39 @@ f_dialog_menutag2index_with_help() return $FAILURE } +# f_dialog_menutag2help $tag_chosen $tag1 $item1 $help1 $tag2 $item2 $help2 ... +# +# To use the `--menu' option of dialog(1) with the `--item-help' option, you +# must pass an ordered list of tag/item/help triplets on the command-line. When +# the user selects a menu option the tag for that item is printed to stderr. +# +# This function allows you to dereference the tag chosen by the user back into +# the help associated with said tag (item is discarded/ignored). +# +# Pass the tag chosen by the user as the first argument, followed by the +# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list +# as was passed to dialog(1) for consistency). +# +# If the tag cannot be found, NULL is returned. +# +f_dialog_menutag2help() +{ + local tag="$1" tagn help + shift 1 # tag + + while [ $# -gt 0 ]; do + tagn="$1" + help="$3" + shift 3 # tagn/item/help + + if [ "$tag" = "$tagn" ]; then + echo "$help" + return $SUCCESS + fi + done + return $FAILURE +} + ############################################################ INIT FUNCTIONS # f_dialog_init diff --git a/usr.sbin/bsdconfig/share/geom.subr b/usr.sbin/bsdconfig/share/geom.subr index 19ed784..912a5c7 100644 --- a/usr.sbin/bsdconfig/share/geom.subr +++ b/usr.sbin/bsdconfig/share/geom.subr @@ -409,7 +409,7 @@ f_geom_parent() ############################################################ MAIN # -# Parse GEOM configuration unless requeted otherwise +# Parse GEOM configuration unless requested otherwise # f_dprintf "%s: GEOM_SELF_SCAN_ALL=[%s]" geom.subr "$GEOM_SELF_SCAN_ALL" case "$GEOM_SELF_SCAN_ALL" in diff --git a/usr.sbin/bsdconfig/share/keymap.subr b/usr.sbin/bsdconfig/share/keymap.subr index d4f391c..7f2f87c 100644 --- a/usr.sbin/bsdconfig/share/keymap.subr +++ b/usr.sbin/bsdconfig/share/keymap.subr @@ -1,6 +1,6 @@ if [ ! "$_KEYMAP_SUBR" ]; then _KEYMAP_SUBR=1 # -# Copyright (c) 2013 Devin Teske +# Copyright (c) 2013-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -219,7 +219,7 @@ f_keymap_get_all() echo -n "$k " # NOTE: Translate '8x8' to '8x08' before sending to # sort(1) so that things work out as we might expect. - debug= keymap_$k get desc | sed -e 's/8x8/8x08/g' + debug= keymap_$k get desc | awk 'gsub(/8x8/,"8x08")||1' done | sort -k2 | awk '{ printf "%s%s", (started ? " " : ""), $1; started = 1 }' diff --git a/usr.sbin/bsdconfig/timezone/share/continents.subr b/usr.sbin/bsdconfig/timezone/share/continents.subr index 02c4071..764f33f 100644 --- a/usr.sbin/bsdconfig/timezone/share/continents.subr +++ b/usr.sbin/bsdconfig/timezone/share/continents.subr @@ -1,6 +1,6 @@ if [ ! "$_TIMEZONE_CONTINENTS_SUBR" ]; then _TIMEZONE_CONTINENTS_SUBR=1 # -# Copyright (c) 2011-2012 Devin Teske +# Copyright (c) 2011-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -87,7 +87,7 @@ export continent_utc_title ############################################################ FUNCTIONS -# f_continent $cont $property +# f_continent $cont $property [$var_to_set] # # Returns a single property of a given continent. Available properties are: # @@ -102,37 +102,60 @@ export continent_utc_title # (which appears after continent selection). # menu_list Menu-list of regions for this continent. # +# If $var_to_set is missing or NULL, the value of $var_to_get is printed to +# standard output for capturing in a sub-shell (which is less-recommended +# because of performance degredation; for example, when called in a loop). +# f_continent() { - local cont="$1" property="$2" - eval echo \"\${continent_${cont}_$property}\" + f_getvar "continent_${1}_$2" $3 } -# f_find_continent $title +# f_find_continent $title [$var_to_set] # # Returns continent identifier given continent title. # +# If $var_to_set is missing or NULL, the value of $var_to_get is printed to +# standard output for capturing in a sub-shell (which is less-recommended +# because of performance degredation; for example, when called in a loop). +# f_find_continent() { - local cont - for cont in $CONTINENTS; do - if [ "$1" = "$( f_continent $cont title )" ]; then - echo "$cont" + local __cont __title + for __cont in $CONTINENTS; do + f_continent $__cont title __title + if [ "$1" = "$__title" ]; then + if [ "$2" ]; then + setvar "$2" $__cont + else + echo "$__cont" + fi return $SUCCESS fi done return $FAILURE } -# f_OCEANP $cont +# f_OCEANP $cont [$var_to_set] # # Returns "1" if the first argument is an ocean, otherwise NULL. # +# If $var_to_set is missing or NULL, the value of $var_to_get is printed to +# standard output for capturing in a sub-shell (which is less-recommended +# because of performance degredation; for example, when called in a loop). +# f_OCEANP() { case "$1" in arctic|atlantic|indian|pacific) - echo 1 + if [ "$2" ]; then + setvar "$2" 1 + else + echo 1 + fi + ;; + *) + [ "$2" ] && setvar "$2" "" esac } diff --git a/usr.sbin/bsdconfig/timezone/share/countries.subr b/usr.sbin/bsdconfig/timezone/share/countries.subr index ff05766..8958e87 100644 --- a/usr.sbin/bsdconfig/timezone/share/countries.subr +++ b/usr.sbin/bsdconfig/timezone/share/countries.subr @@ -1,6 +1,6 @@ if [ ! "$_TIMEZONE_COUNTRIES_SUBR" ]; then _TIMEZONE_COUNTRIES_SUBR=1 # -# Copyright (c) 2011-2012 Devin Teske +# Copyright (c) 2011-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -25,8 +25,10 @@ if [ ! "$_TIMEZONE_COUNTRIES_SUBR" ]; then _TIMEZONE_COUNTRIES_SUBR=1 # SUCH DAMAGE. # # $FreeBSD$ +# +############################################################ FUNCTIONS -# f_country $code $property +# f_country $code $property [$var_to_set] # # Returns a single property of a given country. Available properties are: # @@ -44,10 +46,13 @@ if [ ! "$_TIMEZONE_COUNTRIES_SUBR" ]; then _TIMEZONE_COUNTRIES_SUBR=1 # descr_N Like name, but for the Nth zone when the country has # multiple zones (nzones > 0) # +# If $var_to_set is missing or NULL, the value of $var_to_get is printed to +# standard output for capturing in a sub-shell (which is less-recommended +# because of performance degredation; for example, when called in a loop). +# f_country() { - local code="$1" property="$2" - eval echo \"\${country_${code}_$property}\" + f_getvar "country_${1}_$2" $3 } # f_sort_countries @@ -59,22 +64,42 @@ f_country() # afterward is the sh(1) function which utilizes the below awk script. # f_sort_countries_awk=' +function _asorti(src, dest) { - split($0, array, /[[:space:]]+/) + k = nitems = 0 + for (i in src) dest[++nitems] = i + for (i = 1; i <= nitems; k = i++) { + idx = dest[i] + while ((k > 0) && (dest[k] > idx)) { + dest[k+1] = dest[k]; k-- + } + dest[k+1] = idx + } + return nitems +} +BEGIN { + split(ENVIRON["COUNTRIES"], array, /[[:space:]]+/) for (item in array) { tlc = array[item] - print ENVIRON["country_" tlc "_name"] " " tlc + name = ENVIRON["country_" tlc "_name"] + countries[name] = tlc } + n = _asorti(countries, sorted_countries) + for (i = 1; i <= n; i++) + print countries[sorted_countries[i]] + exit } ' f_sort_countries() { - COUNTRIES=$( echo "$COUNTRIES" | awk "$f_sort_countries_awk" | - sort | awk '{print $NF}' ) - export COUNTRIES + export COUNTRIES # for awk(1) ENVIRON[] visibility + COUNTRIES=$( awk "$f_sort_countries_awk" ) + export COUNTRIES # Pedantic } +############################################################ MAIN + f_dprintf "%s: Successfully loaded." timezone/countries.subr fi # ! $_TIMEZONE_COUNTRIES_SUBR diff --git a/usr.sbin/bsdconfig/timezone/timezone b/usr.sbin/bsdconfig/timezone/timezone index 66f2d78..a291442 100755 --- a/usr.sbin/bsdconfig/timezone/timezone +++ b/usr.sbin/bsdconfig/timezone/timezone @@ -1,6 +1,6 @@ #!/bin/sh #- -# Copyright (c) 2011-2013 Devin Teske +# Copyright (c) 2011-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -280,8 +280,8 @@ f_make_menus # creates $continent_menu_list and $continent_*_menu_list # # Launch application main menu # -defaultctry="" -defaultzone="" +defaultctry= +defaultzone= NEED_CONTINENT=1 NEED_COUNTRY=1 while :; do @@ -299,10 +299,10 @@ while :; do continent=$( eval f_dialog_menutag2item \"\$mtag\" \ $continent_menu_list ) - cont=$( f_find_continent "$continent" ) - cont_title=$( f_continent $cont title ) - nitems=$( f_continent $cont nitems ) - isocean=$( f_OCEANP $cont ) + f_find_continent "$continent" cont + f_continent $cont title cont_title + f_continent $cont nitems nitems + f_OCEANP $cont isocean fi if [ "$NEED_COUNTRY" ]; then @@ -345,7 +345,7 @@ while :; do # # Calculate size of menu # - menu_list=$( f_continent $cont menu_list ) + f_continent $cont menu_list menu_list eval f_dialog_menu_size height width rows \ \"\$title\" \ \"\$btitle\" \ @@ -378,7 +378,7 @@ while :; do fi # Get the country code from the user's selection - tlc=$( f_continent $cont tlc_$tag ) + f_continent $cont tlc_$tag tlc NEED_COUNTRY= fi @@ -387,12 +387,12 @@ while :; do # If the selection has only one zone (nzones == -1), # just set it. # - nzones=$( f_country $tlc nzones ) + f_country $tlc nzones nzones if [ $nzones -lt 0 ]; then - real_cont=$( f_country $tlc cont ) - real_continent=$( f_continent $real_cont name ) - name=$( f_country $tlc name ) - filename=$( f_country $tlc filename ) + f_country $tlc cont real_cont + f_continent $real_cont name real_continent + f_country $tlc name name + f_country $tlc filename filename if ! f_confirm_zone "$real_continent/$filename"; then [ $nitems -eq 1 ] && NEED_CONTINENT=1 @@ -400,13 +400,13 @@ while :; do continue fi else - f_sprintf title "$msg_country_time_zones" \ - "$( f_country $tlc name )" + f_country $tlc name name + f_sprintf title "$msg_country_time_zones" "$name" f_dialog_title "$title" title="$DIALOG_TITLE" btitle="$DIALOG_BACKTITLE" f_dialog_title_restore prompt="$msg_select_zone" - menu_list=$( f_country $tlc menu_list ) + f_country $tlc menu_list menu_list eval f_dialog_menu_size height width rows \ \"\$title\" \"\$btitle\" \"\$prompt\" \"\" $menu_list @@ -435,10 +435,10 @@ while :; do continue fi - real_cont=$( f_country $tlc cont_$n ) - real_continent=$( f_continent $real_cont name ) - name=$( f_country $tlc name ) - filename=$( f_country $tlc filename_$n ) + f_country $tlc cont_$n real_cont + f_continent $real_cont name real_continent + f_country $tlc name name + f_country $tlc filename_$n filename f_confirm_zone "$real_continent/$filename" || continue fi diff --git a/usr.sbin/bsdconfig/usermgmt/share/user.subr b/usr.sbin/bsdconfig/usermgmt/share/user.subr index 5fd65fb..d0e3887 100644 --- a/usr.sbin/bsdconfig/usermgmt/share/user.subr +++ b/usr.sbin/bsdconfig/usermgmt/share/user.subr @@ -1,7 +1,7 @@ if [ ! "$_USERMGMT_USER_SUBR" ]; then _USERMGMT_USER_SUBR=1 # # Copyright (c) 2012 Ron McDowell -# Copyright (c) 2012-2014 Devin Teske +# Copyright (c) 2012-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -830,8 +830,7 @@ f_user_delete() f_eval_catch $funcname \ pw '%s -H 0' "$cmd" else - f_eval_catch $funcname \ - pw '%s -h -' "$cmd" + f_eval_catch $funcname pw '%s -h -' "$cmd" fi fi fi diff --git a/usr.sbin/bsdinstall/bsdinstall.8 b/usr.sbin/bsdinstall/bsdinstall.8 index f3d06fa..a08eff9 100644 --- a/usr.sbin/bsdinstall/bsdinstall.8 +++ b/usr.sbin/bsdinstall/bsdinstall.8 @@ -129,7 +129,7 @@ with separate datasets for and .Pa /var . Optionally can set up -.Xr geli 8 +.Xr geli 8 to encrypt the disk. .It Cm partedit Provides the installer's interactive manual disk partitioner with an interface @@ -354,7 +354,7 @@ instead of .Cm partedit , the preamble can contain the variable .Ev ZFSBOOT_DATASETS -instead of +instead of .Ev PARTITIONS . .Ss SETUP SCRIPT Following the preamble is an optional shell script, beginning with a #! diff --git a/usr.sbin/bsdinstall/distextract/Makefile b/usr.sbin/bsdinstall/distextract/Makefile index f84c4d7..313ec00 100644 --- a/usr.sbin/bsdinstall/distextract/Makefile +++ b/usr.sbin/bsdinstall/distextract/Makefile @@ -2,8 +2,7 @@ BINDIR= /usr/libexec/bsdinstall PROG= distextract -DPADD= ${LIBARCHIVE} ${LIBNCURSESW} ${LIBDIALOG} ${LIBM} -LDADD= -larchive -lncursesw -ldialog -lm +LIBADD= archive dpv figpar ncursesw dialog m WARNS?= 6 MAN= diff --git a/usr.sbin/bsdinstall/distextract/Makefile.depend b/usr.sbin/bsdinstall/distextract/Makefile.depend index 2a012b9..3d6ca5a 100644 --- a/usr.sbin/bsdinstall/distextract/Makefile.depend +++ b/usr.sbin/bsdinstall/distextract/Makefile.depend @@ -13,8 +13,12 @@ DIRDEPS = \ lib/libbz2 \ lib/libc \ lib/libcompiler_rt \ + lib/libdpv \ lib/libexpat \ + lib/libfigpar \ lib/liblzma \ + lib/libthr \ + lib/libutil \ lib/libz \ lib/msun \ lib/ncurses/ncursesw \ diff --git a/usr.sbin/bsdinstall/distextract/distextract.c b/usr.sbin/bsdinstall/distextract/distextract.c index 54e0171..94536bc 100644 --- a/usr.sbin/bsdinstall/distextract/distextract.c +++ b/usr.sbin/bsdinstall/distextract/distextract.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include <archive.h> #include <ctype.h> #include <dialog.h> +#include <dpv.h> #include <err.h> #include <errno.h> #include <limits.h> @@ -42,17 +43,13 @@ __FBSDID("$FreeBSD$"); /* Data to process */ static char *distdir = NULL; -struct file_node { - char *path; - char *name; - int length; - struct file_node *next; -}; -static struct file_node *dists = NULL; +static struct archive *archive = NULL; +static struct dpv_file_node *dists = NULL; /* Function prototypes */ +static void sig_int(int sig); static int count_files(const char *file); -static int extract_files(int nfiles, struct file_node *files); +static int extract_files(struct dpv_file_node *file, int out); #if __FreeBSD_version <= 1000008 /* r232154: bump for libarchive update */ #define archive_read_support_filter_all(x) \ @@ -66,11 +63,17 @@ main(void) { char *chrootdir; char *distributions; - int ndists = 0; int retval; - size_t file_node_size = sizeof(struct file_node); + size_t config_size = sizeof(struct dpv_config); + size_t file_node_size = sizeof(struct dpv_file_node); size_t span; - struct file_node *dist = dists; + struct dpv_config *config; + struct dpv_file_node *dist = dists; + static char backtitle[] = "FreeBSD Installer"; + static char title[] = "Archive Extraction"; + static char aprompt[] = "\n Overall Progress:"; + static char pprompt[] = "Extracting distribution files...\n"; + struct sigaction act; char error[PATH_MAX + 512]; if ((distributions = getenv("DISTRIBUTIONS")) == NULL) @@ -80,14 +83,14 @@ main(void) /* Initialize dialog(3) */ init_dialog(stdin, stdout); - dialog_vars.backtitle = __DECONST(char *, "FreeBSD Installer"); + dialog_vars.backtitle = backtitle; dlg_put_backtitle(); dialog_msgbox("", "Checking distribution archives.\nPlease wait...", 4, 35, FALSE); /* - * Parse $DISTRIBUTIONS into linked-list + * Parse $DISTRIBUTIONS into dpv(3) linked-list */ while (*distributions != '\0') { span = strcspn(distributions, "\t\n\v\f\r "); @@ -95,7 +98,6 @@ main(void) distributions++; continue; } - ndists++; /* Allocate a new struct for the distribution */ if (dist == NULL) { @@ -141,10 +143,30 @@ main(void) return (EXIT_FAILURE); } - retval = extract_files(ndists, dists); + /* Set cleanup routine for Ctrl-C action */ + act.sa_handler = sig_int; + sigaction(SIGINT, &act, 0); + /* + * Hand off to dpv(3) + */ + if ((config = calloc(1, config_size)) == NULL) + _errx(EXIT_FAILURE, "Out of memory!"); + config->backtitle = backtitle; + config->title = title; + config->pprompt = pprompt; + config->aprompt = aprompt; + config->options |= DPV_WIDE_MODE; + config->label_size = -1; + config->action = extract_files; + config->status_solo = + "%10lli files read @ %'9.1f files/sec."; + config->status_many = + "%10lli files read @ %'9.1f files/sec. [%i/%i busy/wait]"; end_dialog(); + retval = dpv(config, dists); + dpv_free(); while ((dist = dists) != NULL) { dists = dist->next; if (dist->path != NULL) @@ -155,6 +177,12 @@ main(void) return (retval); } +static void +sig_int(int sig __unused) +{ + dpv_interrupt = TRUE; +} + /* * Returns number of files in archive file. Parses $BSDINSTALL_DISTDIR/MANIFEST * if it exists, otherwise uses archive(3) to read the archive file. @@ -167,7 +195,6 @@ count_files(const char *file) int file_count; int retval; size_t span; - struct archive *archive; struct archive_entry *entry; char line[512]; char path[PATH_MAX]; @@ -220,6 +247,7 @@ count_files(const char *file) "Error while extracting %s: %s\n", file, archive_error_string(archive)); dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + archive = NULL; return (-1); } @@ -227,49 +255,27 @@ count_files(const char *file) while (archive_read_next_header(archive, &entry) == ARCHIVE_OK) file_count++; archive_read_free(archive); + archive = NULL; return (file_count); } static int -extract_files(int nfiles, struct file_node *files) +extract_files(struct dpv_file_node *file, int out __unused) { - int archive_file; - int archive_files[nfiles]; - int current_files = 0; - int i; - int last_progress; - int progress = 0; int retval; - int total_files = 0; - struct archive *archive; struct archive_entry *entry; - struct file_node *file; - char status[8]; - static char title[] = "Archive Extraction"; - static char pprompt[] = "Extracting distribution files...\n"; char path[PATH_MAX]; char errormsg[PATH_MAX + 512]; - const char *items[nfiles*2]; - /* Make the transfer list for dialog */ - i = 0; - for (file = files; file != NULL; file = file->next) { - items[i*2] = file->name; - items[i*2 + 1] = "Pending"; - archive_files[i] = file->length; - - total_files += file->length; - i++; - } - - i = 0; - for (file = files; file != NULL; file = file->next) { + /* Open the archive if necessary */ + if (archive == NULL) { if ((archive = archive_read_new()) == NULL) { snprintf(errormsg, sizeof(errormsg), "Error: %s\n", archive_error_string(NULL)); dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); - return (EXIT_FAILURE); + dpv_abort = 1; + return (-1); } archive_read_support_format_all(archive); archive_read_support_filter_all(archive); @@ -280,59 +286,44 @@ extract_files(int nfiles, struct file_node *files) "Error opening %s: %s\n", file->name, archive_error_string(archive)); dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); - return (EXIT_FAILURE); + file->status = DPV_STATUS_FAILED; + dpv_abort = 1; + return (-1); } + } - items[i*2 + 1] = "In Progress"; - archive_file = 0; - - dialog_mixedgauge(title, pprompt, 0, 0, progress, nfiles, - __DECONST(char **, items)); - - while ((retval = archive_read_next_header(archive, &entry)) == - ARCHIVE_OK) { - last_progress = progress; - progress = (current_files*100)/total_files; - - snprintf(status, sizeof(status), "-%d", - (archive_file*100)/archive_files[i]); - items[i*2 + 1] = status; - - if (progress > last_progress) - dialog_mixedgauge(title, pprompt, 0, 0, - progress, nfiles, - __DECONST(char **, items)); - - retval = archive_read_extract(archive, entry, - ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_OWNER | - ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | - ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_FFLAGS); - - if (retval != ARCHIVE_OK) - break; - - archive_file++; - current_files++; - } + /* Read the next archive header */ + retval = archive_read_next_header(archive, &entry); - items[i*2 + 1] = "Done"; - - if (retval != ARCHIVE_EOF) { - snprintf(errormsg, sizeof(errormsg), - "Error while extracting %s: %s\n", items[i*2], - archive_error_string(archive)); - items[i*2 + 1] = "Failed"; - dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); - return (retval); - } - - progress = (current_files*100)/total_files; - dialog_mixedgauge(title, pprompt, 0, 0, progress, nfiles, - __DECONST(char **, items)); + /* If that went well, perform the extraction */ + if (retval == ARCHIVE_OK) + retval = archive_read_extract(archive, entry, + ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_OWNER | + ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | + ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_FFLAGS); + /* Test for either EOF or error */ + if (retval == ARCHIVE_EOF) { archive_read_free(archive); - i++; + archive = NULL; + file->status = DPV_STATUS_DONE; + return (100); + } else if (retval != ARCHIVE_OK) { + snprintf(errormsg, sizeof(errormsg), + "Error while extracting %s: %s\n", file->name, + archive_error_string(archive)); + dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + file->status = DPV_STATUS_FAILED; + dpv_abort = 1; + return (-1); } - return (EXIT_SUCCESS); + dpv_overall_read++; + file->read++; + + /* Calculate [overall] percentage of completion (if possible) */ + if (file->length >= 0) + return (file->read * 100 / file->length); + else + return (-1); } diff --git a/usr.sbin/bsdinstall/distfetch/Makefile b/usr.sbin/bsdinstall/distfetch/Makefile index ed1f599..5c0f6e8 100644 --- a/usr.sbin/bsdinstall/distfetch/Makefile +++ b/usr.sbin/bsdinstall/distfetch/Makefile @@ -2,8 +2,7 @@ BINDIR= /usr/libexec/bsdinstall PROG= distfetch -DPADD= ${LIBFETCH} ${LIBNCURSESW} ${LIBDIALOG} ${LIBM} -LDADD= -lfetch -lncursesw -ldialog -lm +LIBADD= fetch ncursesw dialog m WARNS?= 6 MAN= diff --git a/usr.sbin/bsdinstall/partedit/Makefile b/usr.sbin/bsdinstall/partedit/Makefile index fb75888..d48f777 100644 --- a/usr.sbin/bsdinstall/partedit/Makefile +++ b/usr.sbin/bsdinstall/partedit/Makefile @@ -5,8 +5,7 @@ PROG= partedit LINKS= ${BINDIR}/partedit ${BINDIR}/autopart \ ${BINDIR}/partedit ${BINDIR}/scriptedpart SYMLINKS= ${BINDIR}/partedit /usr/sbin/sade -DPADD= ${LIBGEOM} ${LIBNCURSESW} ${LIBUTIL} ${LIBDIALOG} ${LIBM} -LDADD= -lgeom -lncursesw -lutil -ldialog -lm +LIBADD+= geom ncursesw util dialog m PARTEDIT_ARCH= ${MACHINE} .if ${MACHINE} == "i386" || ${MACHINE} == "amd64" diff --git a/usr.sbin/bsdinstall/partedit/partedit_x86.c b/usr.sbin/bsdinstall/partedit/partedit_x86.c index cc6a571..6a60678 100644 --- a/usr.sbin/bsdinstall/partedit/partedit_x86.c +++ b/usr.sbin/bsdinstall/partedit/partedit_x86.c @@ -51,7 +51,10 @@ x86_bootmethod(void) const char * default_scheme(void) { - return ("GPT"); + if (strcmp(x86_bootmethod(), "UEFI") == 0) + return ("GPT"); + else + return ("MBR"); } int diff --git a/usr.sbin/bsdinstall/scripts/docsinstall b/usr.sbin/bsdinstall/scripts/docsinstall index f0bc8f5..4836507 100755 --- a/usr.sbin/bsdinstall/scripts/docsinstall +++ b/usr.sbin/bsdinstall/scripts/docsinstall @@ -154,10 +154,13 @@ f_quietly cp -f $BSDINSTALL_TMPETC/resolv.conf $BSDINSTALL_CHROOT/etc/ # # Install each of the selected packages # +docsets="" for lang in $selected; do - f_package_add $lang-freebsd-doc || return $FAILURE + docsets="$docsets $lang-freebsd-doc" done +ASSUME_ALWAYS_YES=YES chroot $BSDINSTALL_CHROOT pkg install $docsets || return $FAILURE + ################################################################################ # END ################################################################################ diff --git a/usr.sbin/bsdinstall/scripts/zfsboot b/usr.sbin/bsdinstall/scripts/zfsboot index 2b01dea..c759e85 100755 --- a/usr.sbin/bsdinstall/scripts/zfsboot +++ b/usr.sbin/bsdinstall/scripts/zfsboot @@ -1,7 +1,7 @@ #!/bin/sh #- -# Copyright (c) 2013 Allan Jude -# Copyright (c) 2013 Devin Teske +# Copyright (c) 2013-2014 Allan Jude +# Copyright (c) 2013-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -65,9 +65,9 @@ f_include $BSDCFG_SHARE/variable.subr : ${ZFSBOOT_VDEV_TYPE:=stripe} # -# Should we use gnop(8) to configure a transparent mapping to 4K sectors? +# Should we use sysctl(8) vfs.zfs.min_auto_ashift=12 to force 4K sectors? # -: ${ZFSBOOT_GNOP_4K_FORCE_ALIGN:=1} +: ${ZFSBOOT_FORCE_4K_SECTORS:=1} # # Should we use geli(8) to encrypt the drives? @@ -185,8 +185,6 @@ ECHO_APPEND='echo "%s" >> "%s"' GELI_ATTACH='geli attach -j - -k "%s" "%s"' GELI_DETACH_F='geli detach -f "%s"' GELI_PASSWORD_INIT='geli init -b -B "%s" -e %s -J - -K "%s" -l 256 -s 4096 "%s"' -GNOP_CREATE='gnop create -S 4096 "%s"' -GNOP_DESTROY='gnop destroy "%s"' GPART_ADD='gpart add -t %s "%s"' GPART_ADD_INDEX='gpart add -i %s -t %s "%s"' GPART_ADD_INDEX_WITH_SIZE='gpart add -i %s -t %s -s %s "%s"' @@ -205,6 +203,7 @@ PRINTF_CONF="printf '%s=\"%%s\"\\\n' %s >> \"%s\"" PRINTF_FSTAB='printf "$FSTAB_FMT" "%s" "%s" "%s" "%s" "%s" "%s" >> "%s"' SHELL_TRUNCATE=':> "%s"' SWAP_GMIRROR_LABEL='gmirror label swap %s' +SYSCTL_ZFS_MIN_ASHIFT_12='sysctl vfs.zfs.min_auto_ashift=12' UMOUNT='umount "%s"' ZFS_CREATE_WITH_OPTIONS='zfs create %s "%s"' ZFS_SET='zfs set "%s" "%s"' @@ -236,7 +235,7 @@ msg_encrypt_disks="Encrypt Disks?" msg_encrypt_disks_help="Use geli(8) to encrypt all data partitions" msg_error="Error" msg_force_4k_sectors="Force 4K Sectors?" -msg_force_4k_sectors_help="Use gnop(8) to configure forced 4K sector alignment" +msg_force_4k_sectors_help="Use sysctl(8) vfs.zfs.min_auto_ashift=12 to force 4K sectors" msg_freebsd_installer="FreeBSD Installer" msg_geli_password="Enter a strong passphrase, used to protect your encryption keys. You will be required to enter this passphrase each time the system is booted" msg_geli_setup="Initializing encryption on selected disks,\n this will take several seconds per disk" @@ -288,10 +287,12 @@ msg_stripe_desc="Stripe - No Redundancy" msg_stripe_help="[1+ Disks] Striping provides maximum storage but no redundancy" msg_swap_encrypt="Encrypt Swap?" msg_swap_encrypt_help="Encrypt swap partitions with temporary keys, discarded on reboot" +msg_swap_invalid="The selected swap size (%s) is invalid. Enter a number optionally followed by units. Example: 2G" msg_swap_mirror="Mirror Swap?" msg_swap_mirror_help="Mirror swap partitions for redundancy, breaks crash dumps" msg_swap_size="Swap Size" msg_swap_size_help="Customize how much swap space is allocated to each selected disk" +msg_swap_toosmall="The selected swap size (%s) is to small. Please enter a value greater than 100MB or enter 0 for no swap" msg_these_disks_are_too_small="These disks are too small given the amount of requested\nswap (%s) and/or geli(8) (%s) partitions, which would\ntake 50%% or more of each of the following selected disk\ndevices (not recommended):\n\n %s\n\nRecommend changing partition size(s) and/or selecting a\ndifferent set of devices." msg_uefi_not_supported="The FreeBSD UEFI loader does not currently support booting root-on-ZFS. Your system will need to boot in legacy (CSM) mode.\nDo you want to continue?" msg_unable_to_get_disk_capacity="Unable to get disk capacity of \`%s'" @@ -315,37 +316,40 @@ dialog_menu_main() local usegeli="$msg_no" local swapgeli="$msg_no" local swapmirror="$msg_no" - [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ] && force4k="$msg_yes" + [ "$ZFSBOOT_FORCE_4K_SECTORS" ] && force4k="$msg_yes" [ "$ZFSBOOT_GELI_ENCRYPTION" ] && usegeli="$msg_yes" [ "$ZFSBOOT_SWAP_ENCRYPTION" ] && swapgeli="$msg_yes" [ "$ZFSBOOT_SWAP_MIRROR" ] && swapmirror="$msg_yes" local disks n disks_grammar f_count n $ZFSBOOT_DISKS - { [ $n -eq 1 ] && disks_grammar=$msg_disk_singular; } || + { [ $n -eq 1 ] && disks_grammar=$msg_disk_singular; } || disks_grammar=$msg_disk_plural # grammar local menu_list=" - '>>> $msg_install' '$msg_install_desc' - '$msg_install_help' - 'T $msg_pool_type_disks' '$ZFSBOOT_VDEV_TYPE: $n $disks_grammar' - '$msg_pool_type_disks_help' - '- $msg_rescan_devices' '*' - '$msg_rescan_devices_help' - '- $msg_disk_info' '*' - '$msg_disk_info_help' - 'N $msg_pool_name' '$ZFSBOOT_POOL_NAME' - '$msg_pool_name_help' - '4 $msg_force_4k_sectors' '$force4k' - '$msg_force_4k_sectors_help' - 'E $msg_encrypt_disks' '$usegeli' - '$msg_encrypt_disks_help' - 'P $msg_partition_scheme' '$ZFSBOOT_PARTITION_SCHEME' - '$msg_partition_scheme_help' - 'S $msg_swap_size' '$ZFSBOOT_SWAP_SIZE' - '$msg_swap_size_help' - 'M $msg_swap_mirror' '$swapmirror' - '$msg_swap_mirror_help' - 'W $msg_swap_encrypt' '$swapgeli' - '$msg_swap_encrypt_help' + '>>> $msg_install' '$msg_install_desc' + '$msg_install_help' + 'T $msg_pool_type_disks' + '$ZFSBOOT_VDEV_TYPE: $n $disks_grammar' + '$msg_pool_type_disks_help' + '- $msg_rescan_devices' '*' + '$msg_rescan_devices_help' + '- $msg_disk_info' '*' + '$msg_disk_info_help' + 'N $msg_pool_name' '$ZFSBOOT_POOL_NAME' + '$msg_pool_name_help' + '4 $msg_force_4k_sectors' + '$force4k' + '$msg_force_4k_sectors_help' + 'E $msg_encrypt_disks' '$usegeli' + '$msg_encrypt_disks_help' + 'P $msg_partition_scheme' + '$ZFSBOOT_PARTITION_SCHEME' + '$msg_partition_scheme_help' + 'S $msg_swap_size' '$ZFSBOOT_SWAP_SIZE' + '$msg_swap_size_help' + 'M $msg_swap_mirror' '$swapmirror' + '$msg_swap_mirror_help' + 'W $msg_swap_encrypt' '$swapgeli' + '$msg_swap_encrypt_help' " # END-QUOTE local defaultitem= # Calculated below local hline="$hline_alnum_arrows_punc_tab_enter" @@ -938,17 +942,19 @@ zfs_create_diskpart() # 5. Add freebsd-zfs partition for zroot # f_eval_catch $funcname gpart "$GPART_ADD_INDEX" \ - $mbrindex freebsd-zfs ${disk}s1 || return $FAILURE + $mbrindex freebsd-zfs ${disk}s1 || return $FAILURE f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \ - /dev/$disk$targetpart # Pedantic + /dev/$disk$targetpart # Pedantic f_eval_catch $funcname dd "$DD_WITH_OPTIONS" \ - /boot/zfsboot /dev/${disk}s1 count=1 || - return $FAILURE + /boot/zfsboot /dev/${disk}s1 count=1 || + return $FAILURE ;; esac # $ZFSBOOT_PARTITION_SCHEME # Update fstab(5) + local swapsize + f_expand_number "$ZFSBOOT_SWAP_SIZE" swapsize if [ "$isswapmirror" ]; then # This is not the first disk in the mirror, do nothing elif [ "$ZFSBOOT_SWAP_ENCRYPTION" -a "$ZFSBOOT_SWAP_MIRROR" ]; then @@ -968,6 +974,8 @@ zfs_create_diskpart() /dev/$disk${swappart}.eli none swap sw 0 0 \ $BSDINSTALL_TMPETC/fstab || return $FAILURE + elif [ ${swapsize:-0} -eq 0 ]; then + # If swap is 0 sized, don't add it to fstab else f_eval_catch $funcname printf "$PRINTF_FSTAB" \ /dev/$disk$swappart none swap sw 0 0 \ @@ -1062,35 +1070,24 @@ zfs_create_boot() # Prepare the disks and build pool device list(s) # f_dprintf "$funcname: Preparing disk partitions for ZFS pool..." - [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ] && - f_dprintf "$funcname: With 4k alignment using gnop(8)..." + + # Force 4K sectors using vfs.zfs.min_auto_ashift=12 + if [ "$ZFSBOOT_FORCE_4K_SECTORS" ]; then + f_dprintf "$funcname: With 4K sectors..." + f_eval_catch $funcname sysctl "$SYSCTL_ZFS_MIN_ASHIFT_12" \ + || return $FAILURE + fi local n=0 for disk in $disks; do zfs_create_diskpart $disk $n || return $FAILURE # Now $bootpart, $targetpart, and $swappart are set (suffix # for $disk) - - # Forced 4k alignment support using Geom NOP (see gnop(8)) - if [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ]; then - if [ "$ZFSBOOT_BOOT_POOL" ]; then - boot_vdevs="$boot_vdevs $disk$bootpart.nop" - f_eval_catch $funcname gnop "$GNOP_CREATE" \ - $disk$bootpart || return $FAILURE - fi - # Don't gnop encrypted partition - if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then - zroot_vdevs="$zroot_vdevs $disk$targetpart.eli" - else - zroot_vdevs="$zroot_vdevs $disk$targetpart.nop" - f_eval_catch $funcname gnop "$GNOP_CREATE" \ - $disk$targetpart || - return $FAILURE - fi - else - if [ "$ZFSBOOT_BOOT_POOL" ]; then - boot_vdevs="$boot_vdevs $disk$bootpart" - fi - zroot_vdevs="$zroot_vdevs $disk$targetpart" + if [ "$ZFSBOOT_BOOT_POOL" ]; then + boot_vdevs="$boot_vdevs $disk$bootpart" + fi + zroot_vdevs="$zroot_vdevs $disk$targetpart" + if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then + zroot_vdevs="$zroot_vdevs.eli" fi n=$(( $n + 1 )) @@ -1135,8 +1132,11 @@ zfs_create_boot() if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then # Generate an encryption key using random(4) f_eval_catch $funcname dd "$DD_WITH_OPTIONS" \ - /dev/random "$bootpool/$zroot_key" \ + /dev/random "$bootpool/$zroot_key" \ "bs=4096 count=1" || return $FAILURE + f_eval_catch $funcname chmod "$CHMOD_MODE" \ + go-wrx "$bootpool/$zroot_key" || + return $FAILURE else # Clean up f_eval_catch $funcname zfs "$ZFS_UNMOUNT" \ @@ -1189,6 +1189,7 @@ zfs_create_boot() return $FAILURE f_eval_catch -d $funcname umount "$UMOUNT" /mnt # tmpfs fi + # # Create the gmirror(8) GEOMS for swap # @@ -1266,22 +1267,10 @@ zfs_create_boot() "$bootpool_name" || return $FAILURE fi - # Destroy the gnop devices (if enabled) - for disk in ${ZFSBOOT_GNOP_4K_FORCE_ALIGN:+$disks}; do - if [ "$ZFSBOOT_BOOT_POOL" ]; then - f_eval_catch -d $funcname gnop "$GNOP_DESTROY" \ - $disk$bootpart.nop - fi - if [ ! "$ZFSBOOT_GELI_ENCRYPTION" ]; then - f_eval_catch -d $funcname gnop "$GNOP_DESTROY" \ - $disk$targetpart.nop - fi - done - # MBR boot loader touch-up if [ "$ZFSBOOT_PARTITION_SCHEME" = "MBR" ]; then f_dprintf "$funcname: Updating MBR boot loader on disks..." - # Stick the ZFS boot loader in the "convienient hole" after + # Stick the ZFS boot loader in the "convienient hole" after # the ZFS internal metadata for disk in $disks; do f_eval_catch $funcname dd "$DD_WITH_OPTIONS" \ @@ -1323,8 +1312,10 @@ zfs_create_boot() $BSDINSTALL_TMPBOOT/loader.conf.zfs || return $FAILURE if [ "$ZFSBOOT_SWAP_MIRROR" ]; then - f_eval_catch $funcname echo "$ECHO_APPEND" 'geom_mirror_load=\"YES\"' \ - $BSDINSTALL_TMPBOOT/loader.conf.gmirror || return $FAILURE + f_eval_catch $funcname echo "$ECHO_APPEND" \ + 'geom_mirror_load=\"YES\"' \ + $BSDINSTALL_TMPBOOT/loader.conf.gmirror || + return $FAILURE fi # We're all done unless we should go on for boot pool @@ -1347,8 +1338,8 @@ zfs_create_boot() return $FAILURE done f_eval_catch $funcname printf "$PRINTF_CONF" vfs.root.mountfrom \ - "\"zfs:$zroot_name/$zroot_bootfs\"" \ - $BSDINSTALL_TMPBOOT/loader.conf.root || return $FAILURE + "\"zfs:$zroot_name/$zroot_bootfs\"" \ + $BSDINSTALL_TMPBOOT/loader.conf.root || return $FAILURE # We're all done unless we should go on to do encryption [ "$ZFSBOOT_GELI_ENCRYPTION" ] || return $SUCCESS @@ -1358,9 +1349,12 @@ zfs_create_boot() # f_dprintf "$funcname: Configuring disk encryption..." f_eval_catch $funcname echo "$ECHO_APPEND" 'aesni_load=\"YES\"' \ - $BSDINSTALL_TMPBOOT/loader.conf.aesni || return $FAILURE + $BSDINSTALL_TMPBOOT/loader.conf.aesni || return $FAILURE f_eval_catch $funcname echo "$ECHO_APPEND" 'geom_eli_load=\"YES\"' \ - $BSDINSTALL_TMPBOOT/loader.conf.geli || return $FAILURE + $BSDINSTALL_TMPBOOT/loader.conf.geli || return $FAILURE + f_eval_catch $funcname echo "$ECHO_APPEND" \ + 'geom_eli_passphrase_prompt=\"YES\"' \ + $BSDINSTALL_TMPBOOT/loader.conf.geli || return $FAILURE for disk in $disks; do f_eval_catch $funcname printf "$PRINTF_CONF" \ geli_%s_keyfile0_load "$disk$targetpart YES" \ @@ -1431,14 +1425,14 @@ f_dprintf "FSTAB_FMT=[%s]" "$FSTAB_FMT" # ZFS with UEFI yet # if f_interactive; then - bootmethod=$(sysctl -n machdep.bootmethod) - f_dprintf "machdep.bootmethod=[%s]" "$bootmethod" - if [ "$bootmethod" != "BIOS" ]; then - dialog_uefi_prompt - retval=$? - f_dprintf "uefi_prompt=[%s]" "$retval" - [ $retval -eq $DIALOG_OK ] || f_die - fi + bootmethod=$( sysctl -n machdep.bootmethod ) + f_dprintf "machdep.bootmethod=[%s]" "$bootmethod" + if [ "$bootmethod" != "BIOS" ]; then + dialog_uefi_prompt + retval=$? + f_dprintf "uefi_prompt=[%s]" "$retval" + [ $retval -eq $DIALOG_OK ] || f_die + fi fi # @@ -1544,10 +1538,10 @@ while :; do ;; ?" $msg_force_4k_sectors") # Toggle the variable referenced both by the menu and later - if [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ]; then - ZFSBOOT_GNOP_4K_FORCE_ALIGN= + if [ "$ZFSBOOT_FORCE_4K_SECTORS" ]; then + ZFSBOOT_FORCE_4K_SECTORS= else - ZFSBOOT_GNOP_4K_FORCE_ALIGN=1 + ZFSBOOT_FORCE_4K_SECTORS=1 fi ;; ?" $msg_encrypt_disks") @@ -1555,7 +1549,7 @@ while :; do if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then ZFSBOOT_GELI_ENCRYPTION= else - ZFSBOOT_GNOP_4K_FORCE_ALIGN=1 + ZFSBOOT_FORCE_4K_SECTORS=1 ZFSBOOT_GELI_ENCRYPTION=1 fi ;; @@ -1569,10 +1563,26 @@ while :; do ;; ?" $msg_swap_size") # Prompt the user to input/change the swap size for each disk - f_dialog_input input \ - "$msg_please_enter_amount_of_swap_space" \ - "$ZFSBOOT_SWAP_SIZE" && - ZFSBOOT_SWAP_SIZE="${input:-0}" + while :; do + f_dialog_input input \ + "$msg_please_enter_amount_of_swap_space" \ + "$ZFSBOOT_SWAP_SIZE" && + ZFSBOOT_SWAP_SIZE="${input:-0}" + if f_expand_number "$ZFSBOOT_SWAP_SIZE" swapsize + then + if [ $swapsize -ne 0 -a $swapsize -lt 104857600 ]; then + f_show_err "$msg_swap_toosmall" \ + "$ZFSBOOT_SWAP_SIZE" + continue; + else + break; + fi + else + f_show_err "$msg_swap_invalid" \ + "$ZFSBOOT_SWAP_SIZE" + continue; + fi + done ;; ?" $msg_swap_mirror") # Toggle the variable referenced both by the menu and later diff --git a/usr.sbin/bsnmpd/bsnmpd/Makefile b/usr.sbin/bsnmpd/bsnmpd/Makefile index b20ba31..a426345 100644 --- a/usr.sbin/bsnmpd/bsnmpd/Makefile +++ b/usr.sbin/bsnmpd/bsnmpd/Makefile @@ -29,8 +29,7 @@ CFLAGS+= -DSNMPTREE_TYPES CFLAGS+= -I${CONTRIB}/lib -I${CONTRIB}/snmpd -I. -DUSE_LIBBEGEMOT CFLAGS+= -DUSE_TCPWRAPPERS -DQUADFMT='"llu"' -DQUADXFMT='"llx"' CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DHAVE_ERR_H -DHAVE_STRLCPY -DPADD= ${LIBBEGEMOT} ${LIBBSNMP} ${LIBWRAP} -LDADD= -lbegemot -lbsnmp -lwrap +LIBADD= begemot bsnmp wrap LDFLAGS= -Wl,-export-dynamic diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 index 677a276..09484cf 100644 --- a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 +++ b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 @@ -112,8 +112,8 @@ This is the private BEGEMOT-BRIDGE-MIB that is implemented by this module. .Sh SEE ALSO .Xr bsnmpd 1 , .Xr gensnmptree 1 , +.Xr snmpmod 3 , .Xr if_bridge 4 , -.Xr ifconfig 8 , -.Xr snmpmod 3 +.Xr ifconfig 8 .Sh AUTHORS .An Shteryana Shopova Aq Mt syrinx@FreeBSD.org diff --git a/usr.sbin/bsnmpd/modules/snmp_hast/Makefile b/usr.sbin/bsnmpd/modules/snmp_hast/Makefile index e05ce31..d0c3a48 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hast/Makefile +++ b/usr.sbin/bsnmpd/modules/snmp_hast/Makefile @@ -29,8 +29,7 @@ CFLAGS+=-DYY_NO_UNPUT CFLAGS+=-DYY_NO_INPUT CFLAGS+= -DSNMPTREE_TYPES -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util XSYM= begemotHast DEFS= ${MOD}_tree.def diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile index 2922f45..57f3eab 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile @@ -69,8 +69,7 @@ MAN= snmp_hostres.3 DEFS= ${MOD}_tree.def BMIBS= BEGEMOT-HOSTRES-MIB.txt -DPADD= ${LIBKVM} ${LIBDEVINFO} ${LIBM} ${LIBGEOM} ${LIBMEMSTAT} -LDADD= -lkvm -ldevinfo -lm -lgeom -lmemstat +LIBADD= kvm devinfo m geom memstat .include <bsd.snmpmod.mk> diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c index c2a06db..26bd919 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c @@ -201,8 +201,8 @@ make_date_time(u_char *str, const struct tm *tm, u_int decisecs) else str[8] = '+'; - str[9] = (u_char)(abs(tm->tm_gmtoff) / 3600); - str[10] = (u_char)((abs(tm->tm_gmtoff) % 3600) / 60); + str[9] = (u_char)(labs(tm->tm_gmtoff) / 3600); + str[10] = (u_char)((labs(tm->tm_gmtoff) % 3600) / 60); return (11); } diff --git a/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile b/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile index 7caf7e4..85057c9 100644 --- a/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile +++ b/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile @@ -11,7 +11,6 @@ BMIBS= BEGEMOT-NETGRAPH.txt DEFS= ${MOD}_tree.def INCS= snmp_${MOD}.h -DPADD= ${LIBNETGRAPH} -LDADD= -lnetgraph +LIBADD= netgraph .include <bsd.snmpmod.mk> diff --git a/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 b/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 index 205f11f..d695eee 100644 --- a/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 +++ b/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 @@ -151,10 +151,10 @@ The private BEGEMOT-WIRELESS-MIB that is implemented by this module. .Sh SEE ALSO .Xr bsnmpd 1 , .Xr gensnmptree 1 , +.Xr snmpmod 3 , .Xr wlan 4 , .Xr wlan_acl 4 , .Xr wlan_wep 4 , -.Xr ifconfig 8 , -.Xr snmpmod 3 +.Xr ifconfig 8 .Sh AUTHORS .An Shteryana Shopova Aq Mt syrinx@FreeBSD.org diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/Makefile b/usr.sbin/bsnmpd/tools/bsnmptools/Makefile index 3310420..f63975b 100644 --- a/usr.sbin/bsnmpd/tools/bsnmptools/Makefile +++ b/usr.sbin/bsnmpd/tools/bsnmptools/Makefile @@ -7,15 +7,8 @@ PROG= bsnmpget -DPADD+= ${LIBBSNMP} ${LIBBSNMPTOOLS} -LDADD+= -lbsnmp -lbsnmptools +LIBADD= bsnmp bsnmptools CFLAGS+= -I${.CURDIR}/../libbsnmptools -LDFLAGS+= -L${LIBBSNMPTOOLSDIR} - -.if ${MK_OPENSSL} != "no" -DPADD+= ${LIBCRYPTO} -LDADD+= -lcrypto -.endif LINKS= ${BINDIR}/bsnmpget ${BINDIR}/bsnmpwalk LINKS+= ${BINDIR}/bsnmpget ${BINDIR}/bsnmpset diff --git a/usr.sbin/cdcontrol/Makefile b/usr.sbin/cdcontrol/Makefile index fa0dc2c..de95606 100644 --- a/usr.sbin/cdcontrol/Makefile +++ b/usr.sbin/cdcontrol/Makefile @@ -2,7 +2,6 @@ PROG= cdcontrol -DPADD= ${LIBEDIT} ${LIBTERMCAPW} -LDADD= -ledit -ltermcapw +LIBADD= edit .include <bsd.prog.mk> diff --git a/usr.sbin/chkgrp/chkgrp.c b/usr.sbin/chkgrp/chkgrp.c index c9515b5..d7c1506 100644 --- a/usr.sbin/chkgrp/chkgrp.c +++ b/usr.sbin/chkgrp/chkgrp.c @@ -40,154 +40,152 @@ __FBSDID("$FreeBSD$"); #include <unistd.h> #include <sysexits.h> -static char empty[] = { 0 }; - static void __dead2 usage(void) { - fprintf(stderr, "usage: chkgrp [groupfile]\n"); - exit(EX_USAGE); + + fprintf(stderr, "usage: chkgrp [-q] [groupfile]\n"); + exit(EX_USAGE); } int main(int argc, char *argv[]) { - unsigned int i; - size_t len; - int quiet; - int ch; - int n = 0, k, e = 0; - char *line, *f[4], *p; - const char *cp, *gfn; - FILE *gf; - - quiet = 0; - while ((ch = getopt(argc, argv, "q")) != -1) { - switch (ch) { + FILE *gf; + unsigned long gid; + unsigned int i; + size_t len; + int opt, quiet; + int n = 0, k, e = 0; + const char *cp, *f[4], *gfn, *p; + char *line; + + quiet = 0; + while ((opt = getopt(argc, argv, "q")) != -1) { + switch (opt) { case 'q': quiet = 1; break; - case '?': default: usage(); - } - } - - if (optind == argc) - gfn = "/etc/group"; - else if (optind == argc - 1) - gfn = argv[optind]; - else - usage(); - - /* open group file */ - if ((gf = fopen(gfn, "r")) == NULL) - err(EX_NOINPUT, "%s", gfn); - - /* check line by line */ - while (++n) { - if ((line = fgetln(gf, &len)) == NULL) - break; - if (len > 0 && line[len - 1] != '\n') { - warnx("%s: line %d: no newline character", gfn, n); - e = 1; - } - while (len && isspace(line[len-1])) - len--; - - /* ignore blank lines and comments */ - for (p = line; p < (line + len); p++) - if (!isspace(*p)) break; - if (!len || (*p == '#')) { -#if 0 - /* entry is correct, so print it */ - printf("%*.*s\n", len, len, line); -#endif - continue; - } - - /* - * A correct group entry has four colon-separated fields, the third - * of which must be entirely numeric and the fourth of which may - * be empty. - */ - for (i = k = 0; k < 4; k++) { - for (f[k] = line+i; (i < len) && (line[i] != ':'); i++) - /* nothing */ ; - if ((k < 3) && (line[i] != ':')) - break; - line[i++] = 0; + } } - if (k < 4) { - warnx("%s: line %d: missing field(s)", gfn, n); - for ( ; k < 4; k++) - f[k] = empty; - e = 1; - } - - for (cp = f[0] ; *cp ; cp++) { - if (!isalnum(*cp) && *cp != '.' && *cp != '_' && *cp != '-' && - (cp > f[0] || *cp != '+')) { - warnx("%s: line %d: '%c' invalid character", gfn, n, *cp); - e = 1; - } - } + argc -= optind; + argv += optind; - for (cp = f[3] ; *cp ; cp++) { - if (!isalnum(*cp) && *cp != '.' && *cp != '_' && *cp != '-' && - *cp != ',') { - warnx("%s: line %d: '%c' invalid character", gfn, n, *cp); - e = 1; - } - } + if (argc == 0) + gfn = "/etc/group"; + else if (argc == 1) + gfn = argv[0]; + else + usage(); - /* check if fourth field ended with a colon */ - if (i < len) { - warnx("%s: line %d: too many fields", gfn, n); - e = 1; - } + /* open group file */ + if ((gf = fopen(gfn, "r")) == NULL) + err(EX_NOINPUT, "%s", gfn); + + /* check line by line */ + while (++n) { + if ((line = fgetln(gf, &len)) == NULL) + break; + if (len > 0 && line[len - 1] != '\n') { + warnx("%s: line %d: no newline character", gfn, n); + e = 1; + } + while (len && isspace(line[len-1])) + len--; + + /* ignore blank lines and comments */ + for (p = line; p < line + len; p++) + if (!isspace(*p)) break; + if (!len || *p == '#') + continue; + + /* + * Hack: special case for + line + */ + if (strncmp(line, "+:::", len) == 0) + continue; + + /* + * A correct group entry has four colon-separated fields, + * the third of which must be entirely numeric and the + * fourth of which may be empty. + */ + for (i = k = 0; k < 4; k++) { + for (f[k] = line + i; i < len && line[i] != ':'; i++) + /* nothing */ ; + if (k < 3 && line[i] != ':') + break; + line[i++] = 0; + } + + if (k < 4) { + warnx("%s: line %d: missing field(s)", gfn, n); + while (k < 4) + f[k++] = ""; + e = 1; + } + + for (cp = f[0] ; *cp ; cp++) { + if (!isalnum(*cp) && *cp != '.' && *cp != '_' && + *cp != '-' && (cp > f[0] || *cp != '+')) { + warnx("%s: line %d: '%c' invalid character", + gfn, n, *cp); + e = 1; + } + } + + for (cp = f[3] ; *cp ; cp++) { + if (!isalnum(*cp) && *cp != '.' && *cp != '_' && + *cp != '-' && *cp != ',') { + warnx("%s: line %d: '%c' invalid character", + gfn, n, *cp); + e = 1; + } + } + + /* check if fourth field ended with a colon */ + if (i < len) { + warnx("%s: line %d: too many fields", gfn, n); + e = 1; + } - /* check that none of the fields contain whitespace */ - for (k = 0; k < 4; k++) { - if (strcspn(f[k], " \t") != strlen(f[k])) { - warnx("%s: line %d: field %d contains whitespace", - gfn, n, k+1); - e = 1; - } + /* check that none of the fields contain whitespace */ + for (k = 0; k < 4; k++) { + if (strcspn(f[k], " \t") != strlen(f[k])) { + warnx("%s: line %d: field %d contains whitespace", + gfn, n, k+1); + e = 1; + } + } + + /* check that the GID is numeric */ + if (strspn(f[2], "0123456789") != strlen(f[2])) { + warnx("%s: line %d: group id is not numeric", gfn, n); + e = 1; + } + + /* check the range of the group id */ + errno = 0; + gid = strtoul(f[2], NULL, 10); + if (errno != 0) { + warnx("%s: line %d: strtoul failed", gfn, n); + } else if (gid > GID_MAX) { + warnx("%s: line %d: group id is too large (%ju > %ju)", + gfn, n, (uintmax_t)gid, (uintmax_t)GID_MAX); + e = 1; + } } - /* check that the GID is numeric */ - if (strspn(f[2], "0123456789") != strlen(f[2])) { - warnx("%s: line %d: GID is not numeric", gfn, n); - e = 1; - } + /* check what broke the loop */ + if (ferror(gf)) + err(EX_IOERR, "%s: line %d", gfn, n); - /* check the range of the group id */ - errno = 0; - unsigned long groupid = strtoul(f[2], NULL, 10); - if (errno != 0) { - warnx("%s: line %d: strtoul failed", gfn, n); - } - else if (groupid > GID_MAX) { - warnx("%s: line %d: group id is too large (> %ju)", - gfn, n, (uintmax_t)GID_MAX); - e = 1; - } - -#if 0 - /* entry is correct, so print it */ - printf("%s:%s:%s:%s\n", f[0], f[1], f[2], f[3]); -#endif - } - - /* check what broke the loop */ - if (ferror(gf)) - err(EX_IOERR, "%s: line %d", gfn, n); - - /* done */ - fclose(gf); - if (e == 0 && quiet == 0) - printf("%s is fine\n", gfn); - exit(e ? EX_DATAERR : EX_OK); + /* done */ + fclose(gf); + if (e == 0 && quiet == 0) + printf("%s is fine\n", gfn); + exit(e ? EX_DATAERR : EX_OK); } diff --git a/usr.sbin/chown/chgrp.1 b/usr.sbin/chown/chgrp.1 index 8a4c271..6fb0a31 100644 --- a/usr.sbin/chown/chgrp.1 +++ b/usr.sbin/chown/chgrp.1 @@ -31,7 +31,7 @@ .\" @(#)chgrp.1 8.3 (Berkeley) 3/31/94 .\" $FreeBSD$ .\" -.Dd February 21, 2010 +.Dd April 20, 2015 .Dt CHGRP 1 .Os .Sh NAME @@ -60,8 +60,9 @@ The following options are available: .It Fl H If the .Fl R -option is specified, symbolic links on the command line are followed. -(Symbolic links encountered in the tree traversal are not followed.) +option is specified, symbolic links on the command line are followed +and hence unaffected by the command. +(Symbolic links encountered during traversal are not followed.) .It Fl L If the .Fl R @@ -72,8 +73,12 @@ If the option is specified, no symbolic links are followed. This is the default. .It Fl R -Change the group ID for the file hierarchies rooted -in the files instead of just the files themselves. +Change the group ID of the file hierarchies rooted in the files, +instead of just the files themselves. +Beware of unintentionally matching the +.Dq Pa ".." +hard link to the parent directory when using wildcards like +.Dq Li ".*" . .It Fl f The force option ignores errors, except for usage errors and does not query about strange modes (unless the user does not have proper permissions). diff --git a/usr.sbin/chown/chown.8 b/usr.sbin/chown/chown.8 index b5882a3..6b82728 100644 --- a/usr.sbin/chown/chown.8 +++ b/usr.sbin/chown/chown.8 @@ -28,7 +28,7 @@ .\" @(#)chown.8 8.3 (Berkeley) 3/31/94 .\" $FreeBSD$ .\" -.Dd February 21, 2010 +.Dd April 20, 2015 .Dt CHOWN 8 .Os .Sh NAME @@ -64,8 +64,9 @@ The options are as follows: .It Fl H If the .Fl R -option is specified, symbolic links on the command line are followed. -(Symbolic links encountered in the tree traversal are not followed.) +option is specified, symbolic links on the command line are followed +and hence unaffected by the command. +(Symbolic links encountered during traversal are not followed.) .It Fl L If the .Fl R @@ -76,8 +77,8 @@ If the option is specified, no symbolic links are followed. This is the default. .It Fl R -Change the user ID and/or the group ID of the specified directory trees -(recursively, including their contents) and files. +Change the user ID and/or the group ID of the file hierarchies rooted +in the files, instead of just the files themselves. Beware of unintentionally matching the .Dq Pa ".." hard link to the parent directory when using wildcards like diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c index 9780f02..457068a 100644 --- a/usr.sbin/chown/chown.c +++ b/usr.sbin/chown/chown.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <errno.h> +#include <fcntl.h> #include <fts.h> #include <grp.h> #include <libgen.h> @@ -119,18 +120,24 @@ main(int argc, char **argv) usage(); if (Rflag) { - fts_options = FTS_PHYSICAL; if (hflag && (Hflag || Lflag)) errx(1, "the -R%c and -h options may not be " "specified together", Hflag ? 'H' : 'L'); - if (Hflag) - fts_options |= FTS_COMFOLLOW; - else if (Lflag) { - fts_options &= ~FTS_PHYSICAL; - fts_options |= FTS_LOGICAL; + if (Lflag) { + fts_options = FTS_LOGICAL; + } else { + fts_options = FTS_PHYSICAL; + + if (Hflag) { + fts_options |= FTS_COMFOLLOW; + } } - } else - fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL; + } else if (hflag) { + fts_options = FTS_PHYSICAL; + } else { + fts_options = FTS_LOGICAL; + } + if (xflag) fts_options |= FTS_XDEV; @@ -156,6 +163,15 @@ main(int argc, char **argv) err(1, NULL); for (rval = 0; (p = fts_read(ftsp)) != NULL;) { + int atflag; + + if ((fts_options & FTS_LOGICAL) || + ((fts_options & FTS_COMFOLLOW) && + p->fts_level == FTS_ROOTLEVEL)) + atflag = 0; + else + atflag = AT_SYMLINK_NOFOLLOW; + switch (p->fts_info) { case FTS_D: /* Change it at FTS_DP. */ if (!Rflag) @@ -170,58 +186,44 @@ main(int argc, char **argv) warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; continue; - case FTS_SL: - case FTS_SLNONE: - /* - * The only symlinks that end up here are ones that - * don't point to anything and ones that we found - * doing a physical walk. - */ - if (hflag) - break; - else - continue; default: break; } if ((uid == (uid_t)-1 || uid == p->fts_statp->st_uid) && (gid == (gid_t)-1 || gid == p->fts_statp->st_gid)) continue; - if ((hflag ? lchown : chown)(p->fts_accpath, uid, gid) == -1) { - if (!fflag) { - chownerr(p->fts_path); - rval = 1; - } - } else { - if (vflag) { - printf("%s", p->fts_path); - if (vflag > 1) { - if (ischown) { - printf(": %ju:%ju -> %ju:%ju", - (uintmax_t) - p->fts_statp->st_uid, - (uintmax_t) - p->fts_statp->st_gid, - (uid == (uid_t)-1) ? - (uintmax_t) - p->fts_statp->st_uid : - (uintmax_t)uid, - (gid == (gid_t)-1) ? - (uintmax_t) - p->fts_statp->st_gid : - (uintmax_t)gid); - } else { - printf(": %ju -> %ju", - (uintmax_t) - p->fts_statp->st_gid, - (gid == (gid_t)-1) ? - (uintmax_t) - p->fts_statp->st_gid : - (uintmax_t)gid); - } + if (fchownat(AT_FDCWD, p->fts_accpath, uid, gid, atflag) + == -1 && !fflag) { + chownerr(p->fts_path); + rval = 1; + } else if (vflag) { + printf("%s", p->fts_path); + if (vflag > 1) { + if (ischown) { + printf(": %ju:%ju -> %ju:%ju", + (uintmax_t) + p->fts_statp->st_uid, + (uintmax_t) + p->fts_statp->st_gid, + (uid == (uid_t)-1) ? + (uintmax_t) + p->fts_statp->st_uid : + (uintmax_t)uid, + (gid == (gid_t)-1) ? + (uintmax_t) + p->fts_statp->st_gid : + (uintmax_t)gid); + } else { + printf(": %ju -> %ju", + (uintmax_t) + p->fts_statp->st_gid, + (gid == (gid_t)-1) ? + (uintmax_t) + p->fts_statp->st_gid : + (uintmax_t)gid); } - printf("\n"); } + printf("\n"); } } if (errno) diff --git a/usr.sbin/ckdist/Makefile b/usr.sbin/ckdist/Makefile index 23430a8..4d35763 100644 --- a/usr.sbin/ckdist/Makefile +++ b/usr.sbin/ckdist/Makefile @@ -5,7 +5,6 @@ PROG= ckdist SRCS= ckdist.c crc.c -DPADD= ${LIBMD} -LDADD= -lmd +LIBADD= md .include <bsd.prog.mk> diff --git a/usr.sbin/clear_locks/Makefile b/usr.sbin/clear_locks/Makefile index 00ff3ce..6906bf0 100644 --- a/usr.sbin/clear_locks/Makefile +++ b/usr.sbin/clear_locks/Makefile @@ -2,7 +2,6 @@ PROG= clear_locks MAN= clear_locks.8 -DPADD= ${LIBRPCSVC} -LDADD= -lrpcsvc +LIBADD= rpcsvc .include <bsd.prog.mk> diff --git a/usr.sbin/config/Makefile b/usr.sbin/config/Makefile index 6561989..76712d2 100644 --- a/usr.sbin/config/Makefile +++ b/usr.sbin/config/Makefile @@ -13,8 +13,7 @@ CFLAGS+= -I. -I${.CURDIR} NO_WMISSING_VARIABLE_DECLARATIONS= -DPADD= ${LIBL} ${LIBSBUF} -LDADD= -ll -lsbuf +LIBADD= l sbuf CLEANFILES+= kernconf.c diff --git a/usr.sbin/config/Makefile.depend b/usr.sbin/config/Makefile.depend index 6f629ac..ee946e4 100644 --- a/usr.sbin/config/Makefile.depend +++ b/usr.sbin/config/Makefile.depend @@ -12,6 +12,7 @@ DIRDEPS = \ lib/libcompiler_rt \ lib/libsbuf \ usr.bin/lex/lib \ + usr.bin/yacc.host \ .include <dirdeps.mk> diff --git a/usr.sbin/config/config.8 b/usr.sbin/config/config.8 index bfaded9..dcfbc62 100644 --- a/usr.sbin/config/config.8 +++ b/usr.sbin/config/config.8 @@ -39,6 +39,7 @@ .Op Fl CVgp .Op Fl I Ar path .Op Fl d Ar destdir +.Op Fl s Ar srcdir .Ar SYSTEM_NAME .Nm .Op Fl x Ar kernel @@ -85,6 +86,10 @@ Note that does not append .Ar SYSTEM_NAME to the directory given. +.It Fl s Ar srcdir +Use +.Ar srcdir +as the source directory, instead of the default one. .It Fl m Print the MACHINE and MACHINE_ARCH values for this kernel and exit. @@ -143,6 +148,14 @@ header files, definitions of the number of various devices that will be compiled into the system. .Pp +The +.Nm +utility looks for kernel sources in the directory +.Pa ../.. +or the one given with the +.Fl s +option. +.Pp After running .Nm , it is necessary to run diff --git a/usr.sbin/config/config.y b/usr.sbin/config/config.y index 81329d9..c7198a0 100644 --- a/usr.sbin/config/config.y +++ b/usr.sbin/config/config.y @@ -178,7 +178,7 @@ Config_spec: } | OPTIONS Opt_list | - NOOPTION Save_id { rmopt_schedule(&opt, $2); } | + NOOPTION NoOpt_list | MAKEOPTIONS Mkopt_list | NOMAKEOPTION Save_id { rmopt_schedule(&mkopt, $2); } | @@ -225,6 +225,11 @@ Opt_list: Option ; +NoOpt_list: + NoOpt_list COMMA NoOption + | + NoOption + ; Option: Save_id { newopt(&opt, $1, NULL, 0); @@ -236,6 +241,11 @@ Option: newopt(&opt, $1, $3, 0); } ; +NoOption: + Save_id { + rmopt_schedule(&opt, $1); + }; + Opt_value: ID { $$ = $1; } | NUMBER { diff --git a/usr.sbin/config/configvers.h b/usr.sbin/config/configvers.h index 56ca85c..5c29373 100644 --- a/usr.sbin/config/configvers.h +++ b/usr.sbin/config/configvers.h @@ -49,5 +49,5 @@ * * $FreeBSD$ */ -#define CONFIGVERS 600013 +#define CONFIGVERS 600014 #define MAJOR_VERS(x) ((x) / 100000) diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c index 86ecfa6..f2d2a70 100644 --- a/usr.sbin/config/main.c +++ b/usr.sbin/config/main.c @@ -116,7 +116,7 @@ main(int argc, char **argv) printmachine = 0; kernfile = NULL; SLIST_INIT(&includepath); - while ((ch = getopt(argc, argv, "CI:d:gmpVx:")) != -1) + while ((ch = getopt(argc, argv, "CI:d:gmpsVx:")) != -1) switch (ch) { case 'C': filebased = 1; @@ -144,6 +144,12 @@ main(int argc, char **argv) case 'p': profiling++; break; + case 's': + if (*srcdir == '\0') + strlcpy(srcdir, optarg, sizeof(srcdir)); + else + errx(EXIT_FAILURE, "src directory already set"); + break; case 'V': printf("%d\n", CONFIGVERS); exit(0); @@ -180,7 +186,8 @@ main(int argc, char **argv) len = strlen(destdir); while (len > 1 && destdir[len - 1] == '/') destdir[--len] = '\0'; - get_srcdir(); + if (*srcdir == '\0') + get_srcdir(); } else { strlcpy(destdir, CDIR, sizeof(destdir)); strlcat(destdir, PREFIX, sizeof(destdir)); @@ -275,7 +282,8 @@ static void usage(void) { - fprintf(stderr, "usage: config [-CgmpV] [-d destdir] sysname\n"); + fprintf(stderr, + "usage: config [-CgmpV] [-d destdir] [-s srcdir] sysname\n"); fprintf(stderr, " config -x kernel\n"); exit(EX_USAGE); } @@ -314,6 +322,11 @@ begin: } cp = line; *cp++ = ch; + /* Negation operator is a word by itself. */ + if (ch == '!') { + *cp = 0; + return (line); + } while ((ch = getc(fp)) != EOF) { if (isspace(ch)) break; @@ -673,7 +686,7 @@ kernconfdump(const char *file) { struct stat st; FILE *fp, *pp; - int error, len, osz, r; + int error, osz, r; unsigned int i, off, size, t1, t2, align; char *cmd, *o; @@ -701,7 +714,7 @@ kernconfdump(const char *file) if (pp == NULL) errx(EXIT_FAILURE, "popen() failed"); free(cmd); - len = fread(o, osz, 1, pp); + fread(o, osz, 1, pp); pclose(pp); r = sscanf(o, "%d%d%d%d%d", &off, &size, &t1, &t2, &align); free(o); diff --git a/usr.sbin/config/mkmakefile.c b/usr.sbin/config/mkmakefile.c index cae2efc..0f873c4 100644 --- a/usr.sbin/config/mkmakefile.c +++ b/usr.sbin/config/mkmakefile.c @@ -386,13 +386,9 @@ next: if (nreqs == 0) errout("%s: syntax error describing %s\n", fname, this); - if (not) - compile += !match; - else - compile += match; + compile += match; match = 1; nreqs = 0; - not = 0; continue; } if (eq(wd, "no-obj")) { @@ -474,19 +470,23 @@ next: this, wd); STAILQ_FOREACH(dp, &dtab, d_next) if (eq(dp->d_name, wd)) { - dp->d_done |= DEVDONE; + if (not) + match = 0; + else + dp->d_done |= DEVDONE; goto nextparam; } SLIST_FOREACH(op, &opt, op_next) - if (op->op_value == 0 && opteq(op->op_name, wd)) + if (op->op_value == 0 && opteq(op->op_name, wd)) { + if (not) + match = 0; goto nextparam; - match = 0; + } + match &= not; nextparam:; + not = 0; } - if (not) - compile += !match; - else - compile += match; + compile += match; if (compile && tp == NULL) { if (std == 0 && nreqs == 0) errout("%s: what is %s optional on?\n", diff --git a/usr.sbin/crashinfo/crashinfo.sh b/usr.sbin/crashinfo/crashinfo.sh index 557d810..3a55e5d 100755 --- a/usr.sbin/crashinfo/crashinfo.sh +++ b/usr.sbin/crashinfo/crashinfo.sh @@ -268,12 +268,6 @@ netstat -M $VMCORE -N $KERNEL -m echo echo "------------------------------------------------------------------------" -echo "netstat -anr" -echo -netstat -M $VMCORE -N $KERNEL -anr -echo - -echo "------------------------------------------------------------------------" echo "netstat -anA" echo netstat -M $VMCORE -N $KERNEL -anA diff --git a/usr.sbin/cron/Makefile.inc b/usr.sbin/cron/Makefile.inc index 900730b..265f86d 100644 --- a/usr.sbin/cron/Makefile.inc +++ b/usr.sbin/cron/Makefile.inc @@ -1,5 +1,3 @@ # $FreeBSD$ -LIBCRON= ${.OBJDIR}/../lib/libcron.a - .include "../Makefile.inc" diff --git a/usr.sbin/cron/cron/Makefile b/usr.sbin/cron/cron/Makefile index d9a1d24..0aa84d8 100644 --- a/usr.sbin/cron/cron/Makefile +++ b/usr.sbin/cron/cron/Makefile @@ -6,8 +6,7 @@ SRCS= cron.c database.c do_command.c job.c user.c popen.c CFLAGS+= -DLOGIN_CAP -DPAM -DPADD= ${LIBCRON} ${LIBPAM} ${LIBUTIL} -LDADD= ${LIBCRON} ${MINUSLPAM} -lutil +LIBADD= cron pam util WARNS?= 2 diff --git a/usr.sbin/cron/crontab/Makefile b/usr.sbin/cron/crontab/Makefile index 829128e..9f43112 100644 --- a/usr.sbin/cron/crontab/Makefile +++ b/usr.sbin/cron/crontab/Makefile @@ -12,7 +12,6 @@ WARNS?= 3 CFLAGS+= -I${.CURDIR}/../cron -DPADD= ${LIBCRON} ${LIBMD} ${LIBUTIL} -LDADD= ${LIBCRON} -lmd -lutil +LIBADD= cron md util .include <bsd.prog.mk> diff --git a/usr.sbin/crunch/crunchide/Makefile b/usr.sbin/crunch/crunchide/Makefile index ab8b902..467b0b6 100644 --- a/usr.sbin/crunch/crunchide/Makefile +++ b/usr.sbin/crunch/crunchide/Makefile @@ -1,23 +1,9 @@ # $FreeBSD$ PROG= crunchide -SRCS= crunchide.c +SRCS= crunchide.c exec_elf32.c exec_elf64.c -TARGET_ARCH?= ${MACHINE_ARCH} - -.if ${TARGET_ARCH} == i386 && ${MACHINE_ARCH} == i386 -CFLAGS+=-DNLIST_AOUT -SRCS+= exec_aout.c -.endif - -.if ${TARGET_ARCH} == amd64 || ${TARGET_ARCH} == powerpc64 || \ - ${TARGET_ARCH} == sparc64 || ${TARGET_ARCH:Mmips64*} -CFLAGS+=-DNLIST_ELF64 -SRCS+= exec_elf64.c +CFLAGS+=-DNLIST_ELF32 -DNLIST_ELF64 exec_elf64.o: exec_elf32.c -.else -CFLAGS+=-DNLIST_ELF32 -SRCS+= exec_elf32.c -.endif .include <bsd.prog.mk> diff --git a/usr.sbin/crunch/crunchide/crunchide.c b/usr.sbin/crunch/crunchide/crunchide.c index d2b1123..8665a14 100644 --- a/usr.sbin/crunch/crunchide/crunchide.c +++ b/usr.sbin/crunch/crunchide/crunchide.c @@ -212,12 +212,6 @@ struct { int (*check)(int, const char *); /* 1 if match, zero if not */ int (*hide)(int, const char *); /* non-zero if error */ } exec_formats[] = { -#ifdef NLIST_AOUT - { "a.out", check_aout, hide_aout, }, -#endif -#ifdef NLIST_ECOFF - { "ECOFF", check_elf64, hide_elf64, }, -#endif #ifdef NLIST_ELF32 { "ELF32", check_elf32, hide_elf32, }, #endif diff --git a/usr.sbin/crunch/crunchide/exec_aout.c b/usr.sbin/crunch/crunchide/exec_aout.c deleted file mode 100644 index a608c23..0000000 --- a/usr.sbin/crunch/crunchide/exec_aout.c +++ /dev/null @@ -1,198 +0,0 @@ -/* $NetBSD: exec_aout.c,v 1.6 1997/08/02 21:30:17 perry Exp $ */ -/* - * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. - * Copyright (c) 1994 University of Maryland - * All Rights Reserved. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of U.M. not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. U.M. makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: James da Silva, Systems Design and Analysis Group - * Computer Science Department - * University of Maryland at College Park - */ -#include <sys/cdefs.h> -#ifndef lint -__RCSID("$NetBSD: exec_aout.c,v 1.6 1997/08/02 21:30:17 perry Exp $"); -__FBSDID("$FreeBSD$"); -#endif - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <a.out.h> -#include <sys/types.h> -#include <sys/endian.h> -#include <sys/stat.h> -#include <sys/errno.h> -#include <netinet/in.h> - -#include "extern.h" - -#if defined(NLIST_AOUT) - -int nsyms, ntextrel, ndatarel; -struct exec *hdrp; -char *aoutdata, *strbase; -struct relocation_info *textrel, *datarel; -struct nlist *symbase; - - -#define SYMSTR(sp) (&strbase[(sp)->n_un.n_strx]) - -/* is the symbol a global symbol defined in the current file? */ -#define IS_GLOBAL_DEFINED(sp) \ - (((sp)->n_type & N_EXT) && ((sp)->n_type & N_TYPE) != N_UNDF) - -/* is the relocation entry dependent on a symbol? */ -#define IS_SYMBOL_RELOC(rp) \ - ((rp)->r_extern||(rp)->r_baserel||(rp)->r_jmptable) - -static void check_reloc(const char *filename, struct relocation_info *relp); - -int check_aout(int inf, const char *filename) -{ - struct stat infstat; - struct exec eh; - - /* - * check the header to make sure it's an a.out-format file. - */ - - if(fstat(inf, &infstat) == -1) - return 0; - if(infstat.st_size < sizeof eh) - return 0; - if(read(inf, &eh, sizeof eh) != sizeof eh) - return 0; - - if(N_BADMAG(eh)) - return 0; - - return 1; -} - -int hide_aout(int inf, const char *filename) -{ - struct stat infstat; - struct relocation_info *relp; - struct nlist *symp; - int rc; - - /* - * do some error checking. - */ - - if(fstat(inf, &infstat) == -1) { - perror(filename); - return 1; - } - - /* - * Read the entire file into memory. XXX - Really, we only need to - * read the header and from TRELOFF to the end of the file. - */ - - if((aoutdata = (char *) malloc(infstat.st_size)) == NULL) { - fprintf(stderr, "%s: too big to read into memory\n", filename); - return 1; - } - - if((rc = read(inf, aoutdata, infstat.st_size)) < infstat.st_size) { - fprintf(stderr, "%s: read error: %s\n", filename, - rc == -1? strerror(errno) : "short read"); - return 1; - } - - /* - * Calculate offsets and sizes from the header. - */ - - hdrp = (struct exec *) aoutdata; - -#ifdef __FreeBSD__ - textrel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp)); - datarel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp) + - hdrp->a_trsize); -#else - textrel = (struct relocation_info *) (aoutdata + N_TRELOFF(*hdrp)); - datarel = (struct relocation_info *) (aoutdata + N_DRELOFF(*hdrp)); -#endif - symbase = (struct nlist *) (aoutdata + N_SYMOFF(*hdrp)); - strbase = (char *) (aoutdata + N_STROFF(*hdrp)); - - ntextrel = hdrp->a_trsize / sizeof(struct relocation_info); - ndatarel = hdrp->a_drsize / sizeof(struct relocation_info); - nsyms = hdrp->a_syms / sizeof(struct nlist); - - /* - * Zap the type field of all globally-defined symbols. The linker will - * subsequently ignore these entries. Don't zap any symbols in the - * keep list. - */ - - for(symp = symbase; symp < symbase + nsyms; symp++) { - if(!IS_GLOBAL_DEFINED(symp)) /* keep undefined syms */ - continue; - - /* keep (C) symbols which are on the keep list */ - if(SYMSTR(symp)[0] == '_' && in_keep_list(SYMSTR(symp) + 1)) - continue; - - symp->n_type = 0; - } - - /* - * Check whether the relocation entries reference any symbols that we - * just zapped. I don't know whether ld can handle this case, but I - * haven't encountered it yet. These checks are here so that the program - * doesn't fail silently should such symbols be encountered. - */ - - for(relp = textrel; relp < textrel + ntextrel; relp++) - check_reloc(filename, relp); - for(relp = datarel; relp < datarel + ndatarel; relp++) - check_reloc(filename, relp); - - /* - * Write the .o file back out to disk. XXX - Really, we only need to - * write the symbol table entries back out. - */ - lseek(inf, 0, SEEK_SET); - if((rc = write(inf, aoutdata, infstat.st_size)) < infstat.st_size) { - fprintf(stderr, "%s: write error: %s\n", filename, - rc == -1? strerror(errno) : "short write"); - return 1; - } - - return 0; -} - - -static void check_reloc(const char *filename, struct relocation_info *relp) -{ - /* bail out if we zapped a symbol that is needed */ - if(IS_SYMBOL_RELOC(relp) && symbase[relp->r_symbolnum].n_type == 0) { - fprintf(stderr, - "%s: oops, have hanging relocation for %s: bailing out!\n", - filename, SYMSTR(&symbase[relp->r_symbolnum])); - exit(1); - } -} - -#endif /* defined(NLIST_AOUT) */ diff --git a/usr.sbin/crunch/crunchide/exec_elf32.c b/usr.sbin/crunch/crunchide/exec_elf32.c index e9bc227..fc9a959 100644 --- a/usr.sbin/crunch/crunchide/exec_elf32.c +++ b/usr.sbin/crunch/crunchide/exec_elf32.c @@ -35,7 +35,7 @@ __RCSID("$NetBSD: exec_elf32.c,v 1.6 1999/09/20 04:12:16 christos Exp $"); #endif #endif __FBSDID("$FreeBSD$"); - + #ifndef ELFSIZE #define ELFSIZE 32 #endif @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <limits.h> +#include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -78,6 +79,9 @@ __FBSDID("$FreeBSD$"); #define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y)))) #define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE)) #define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x))) +#ifndef ELFCLASS +#define ELFCLASS CONCAT(ELFCLASS,ELFSIZE) +#endif #define xe16toh(x) ((data == ELFDATA2MSB) ? be16toh(x) : le16toh(x)) #define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) @@ -138,7 +142,7 @@ static void * xrealloc(void *ptr, size_t size, const char *fn, const char *use) { void *rv; - + rv = realloc(ptr, size); if (rv == NULL) { free(ptr); @@ -146,7 +150,7 @@ xrealloc(void *ptr, size_t size, const char *fn, const char *use) fn, use); } return (rv); -} +} int ELFNAMEEND(check)(int fd, const char *fn) @@ -166,7 +170,7 @@ ELFNAMEEND(check)(int fd, const char *fn) if (read(fd, &eh, sizeof eh) != sizeof eh) return 0; - if (IS_ELF(eh) == 0) + if (IS_ELF(eh) == 0 || eh.e_ident[EI_CLASS] != ELFCLASS) return 0; data = eh.e_ident[EI_DATA]; @@ -174,33 +178,16 @@ ELFNAMEEND(check)(int fd, const char *fn) switch (xe16toh(eh.e_machine)) { case EM_386: break; case EM_ALPHA: break; -#ifndef EM_ARM -#define EM_ARM 40 +#ifndef EM_AARCH64 +#define EM_AARCH64 183 #endif + case EM_AARCH64: break; case EM_ARM: break; -#ifndef EM_MIPS -#define EM_MIPS 8 -#endif -#ifndef EM_MIPS_RS4_BE /* same as EM_MIPS_RS3_LE */ -#define EM_MIPS_RS4_BE 10 -#endif case EM_MIPS: break; case /* EM_MIPS_RS3_LE */ EM_MIPS_RS4_BE: break; -#ifndef EM_PPC -#define EM_PPC 20 -#endif case EM_PPC: break; -#ifndef EM_PPC64 -#define EM_PPC64 21 -#endif case EM_PPC64: break; -#ifndef EM_SPARCV9 -#define EM_SPARCV9 43 -#endif case EM_SPARCV9: break; -#ifndef EM_X86_64 -#define EM_X86_64 62 -#endif case EM_X86_64: break; /* ELFDEFNNAME(MACHDEP_ID_CASES) */ @@ -337,11 +324,14 @@ ELFNAMEEND(hide)(int fd, const char *fn) */ /* load section string table for debug use */ - if ((shstrtabp = xmalloc(xewtoh(shstrtabshdr->sh_size), fn, - "section string table")) == NULL) + if ((size = xewtoh(shstrtabshdr->sh_size)) == 0) + goto bad; + if ((shstrtabp = xmalloc(size, fn, "section string table")) == NULL) goto bad; if ((size_t)xreadatoff(fd, shstrtabp, xewtoh(shstrtabshdr->sh_offset), - xewtoh(shstrtabshdr->sh_size), fn) != xewtoh(shstrtabshdr->sh_size)) + size, fn) != size) + goto bad; + if (shstrtabp[size - 1] != '\0') goto bad; /* we need symtab, strtab, and everything behind strtab */ @@ -362,7 +352,8 @@ ELFNAMEEND(hide)(int fd, const char *fn) strtabidx = i; if (layoutp[i].shdr == symtabshdr || i >= strtabidx) { off = xewtoh(layoutp[i].shdr->sh_offset); - size = xewtoh(layoutp[i].shdr->sh_size); + if ((size = xewtoh(layoutp[i].shdr->sh_size)) == 0) + goto bad; layoutp[i].bufp = xmalloc(size, fn, shstrtabp + xewtoh(layoutp[i].shdr->sh_name)); if (layoutp[i].bufp == NULL) @@ -372,10 +363,13 @@ ELFNAMEEND(hide)(int fd, const char *fn) goto bad; /* set symbol table and string table */ - if (layoutp[i].shdr == symtabshdr) + if (layoutp[i].shdr == symtabshdr) { symtabp = layoutp[i].bufp; - else if (layoutp[i].shdr == strtabshdr) + } else if (layoutp[i].shdr == strtabshdr) { strtabp = layoutp[i].bufp; + if (strtabp[size - 1] != '\0') + goto bad; + } } } @@ -460,7 +454,7 @@ ELFNAMEEND(hide)(int fd, const char *fn) if (layoutp[i].shdr == &shdrshdr && ehdr.e_shoff != shdrshdr.sh_offset) { ehdr.e_shoff = shdrshdr.sh_offset; - off = (ELFSIZE == 32) ? 32 : 44; + off = offsetof(Elf_Ehdr, e_shoff); size = sizeof(Elf_Off); if ((size_t)xwriteatoff(fd, &ehdr.e_shoff, off, size, fn) != size) diff --git a/usr.sbin/crunch/crunchide/extern.h b/usr.sbin/crunch/crunchide/extern.h index 4200bc3..1e7809a 100644 --- a/usr.sbin/crunch/crunchide/extern.h +++ b/usr.sbin/crunch/crunchide/extern.h @@ -31,14 +31,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef NLIST_AOUT -int check_aout(int, const char *); -int hide_aout(int, const char *); -#endif -#ifdef NLIST_ECOFF -int check_ecoff(int, const char *); -int hide_ecoff(int, const char *); -#endif #ifdef NLIST_ELF32 int check_elf32(int, const char *); int hide_elf32(int, const char *); diff --git a/usr.sbin/ctladm/Makefile b/usr.sbin/ctladm/Makefile index a9f6bfd..fd9e606 100644 --- a/usr.sbin/ctladm/Makefile +++ b/usr.sbin/ctladm/Makefile @@ -14,8 +14,7 @@ CFLAGS+= -I${SDIR} WARNS?= 3 .endif -DPADD= ${LIBCAM} ${LIBSBUF} ${LIBBSDXML} ${LIBUTIL} -LDADD= -lcam -lsbuf -lbsdxml -lutil +LIBADD= cam sbuf bsdxml util MAN= ctladm.8 .include <bsd.prog.mk> diff --git a/usr.sbin/ctladm/ctladm.8 b/usr.sbin/ctladm/ctladm.8 index 23f63d4..c4508cc 100644 --- a/usr.sbin/ctladm/ctladm.8 +++ b/usr.sbin/ctladm/ctladm.8 @@ -34,7 +34,7 @@ .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $ .\" $FreeBSD$ .\" -.Dd November 5, 2014 +.Dd May 22, 2015 .Dt CTLADM 8 .Os .Sh NAME @@ -196,11 +196,17 @@ .Ic portlist .Op Fl f Ar frontend .Op Fl i +.Op Fl l .Op Fl p Ar targ_port .Op Fl q .Op Fl v .Op Fl x .Nm +.Ic lunmap +.Aq Fl p Ar targ_port +.Op Fl l Ar pLUN +.Op Fl L Ar cLUN +.Nm .Ic dumpooa .Nm .Ic dumpstructs @@ -782,7 +788,9 @@ List CTL frontend ports. .It Fl f Ar frontend Specify the frontend type. .It Fl i -Report target and connected initiators addresses +Report target and connected initiators addresses. +.It Fl l +Report LUN mapping. .It Fl p Ar targ_port Specify the frontend port number. .It Fl q @@ -792,6 +800,31 @@ Enable verbose output (report all port options). .It Fl x Output the port list in XML format. .El +.It Ic lunmap +Change LUN mapping for specified port. +If both +.Ar pLUN +and +.Ar cLUN +are specified -- LUN will be mapped. +If +.Ar pLUN +is specified, but +.Ar cLUN +is not -- LUN will be unmapped. +If neither +.Ar pLUN +nor +.Ar cLUN +are specified -- LUN mapping will be disabled, exposing all CTL LUNs. +.Bl -tag -width 12n +.It Fl p Ar targ_port +Specify the frontend port number. +.It Fl l Ar pLUN +LUN number visible by specified port. +.It Fl L Ar cLUN +CTL LUN number. +.El .It Ic dumpooa Dump the OOA (Order Of Arrival) queue for each LUN registered with CTL. .It Ic dumpstructs @@ -995,6 +1028,20 @@ command sequence order shall be explicitly handled by the application client through the selection of appropriate commands and task attributes. The default value is "restricted". It improves data integrity, but may introduce some additional delays. +.It Va serseq +Set to "on" to serialize conseсutive reads/writes. +Set to "read" to serialize conseсutive reads. +Set to "off" to allow them be issued in parallel. +Parallel issue of consecutive operations may confuse logic of the +backing file system, hurting performance; but it may improve performance +of backing stores without prefetch/write-back. +.It Va pblocksize +.It Va pblockoffset +Specify physical block size and offset of the device. +.It Va ublocksize +.It Va ublockoffset +Specify UNMAP block size and offset of the device. +.It Va rpm .It Va rpm Specifies medium rotation rate of the device: 0 -- not reported, 1 -- non-rotating (SSD), >1024 -- value in revolutions per minute. @@ -1007,10 +1054,11 @@ Set to "on", enables UNMAP support for the LUN, if supported by the backend. .It Va used-threshold .It Va pool-avail-threshold .It Va pool-used-threshold -Set per-LUN/-pool thin provisioning soft thresholds for ZVOL-backed LUNs. +Set per-LUN/-pool thin provisioning soft thresholds. LUN will establish UNIT ATTENTION condition if its or pool available space get below configured avail values, or its or pool used space get above configured used values. +Pool thresholds are working only for ZVOL-backed LUNs. .It Va writecache Set to "off", disables write caching for the LUN, if supported by the backend. .El @@ -1112,7 +1160,8 @@ This will result in a sense key of NOT READY (0x02), and an ASC/ASCQ of .Xr ctl 4 , .Xr xpt 4 , .Xr camcontrol 8 , -.Xr ctld 8 +.Xr ctld 8 , +.Xr ctlstat 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/ctladm/ctladm.c b/usr.sbin/ctladm/ctladm.c index 03f46c9..aefba04 100644 --- a/usr.sbin/ctladm/ctladm.c +++ b/usr.sbin/ctladm/ctladm.c @@ -121,7 +121,8 @@ typedef enum { CTLADM_CMD_MODIFY, CTLADM_CMD_ISLIST, CTLADM_CMD_ISLOGOUT, - CTLADM_CMD_ISTERMINATE + CTLADM_CMD_ISTERMINATE, + CTLADM_CMD_LUNMAP } ctladm_cmdfunction; typedef enum { @@ -188,10 +189,11 @@ static struct ctladm_opts option_table[] = { {"islogout", CTLADM_CMD_ISLOGOUT, CTLADM_ARG_NONE, "ac:i:p:"}, {"isterminate", CTLADM_CMD_ISTERMINATE, CTLADM_ARG_NONE, "ac:i:p:"}, {"lunlist", CTLADM_CMD_LUNLIST, CTLADM_ARG_NONE, NULL}, + {"lunmap", CTLADM_CMD_LUNMAP, CTLADM_ARG_NONE, "p:l:L:"}, {"modesense", CTLADM_CMD_MODESENSE, CTLADM_ARG_NEED_TL, "P:S:dlm:c:"}, {"modify", CTLADM_CMD_MODIFY, CTLADM_ARG_NONE, "b:l:s:"}, {"port", CTLADM_CMD_PORT, CTLADM_ARG_NONE, "lo:p:qt:w:W:x"}, - {"portlist", CTLADM_CMD_PORTLIST, CTLADM_ARG_NONE, "f:ip:qvx"}, + {"portlist", CTLADM_CMD_PORTLIST, CTLADM_ARG_NONE, "f:ilp:qvx"}, {"prin", CTLADM_CMD_PRES_IN, CTLADM_ARG_NEED_TL, "a:"}, {"prout", CTLADM_CMD_PRES_OUT, CTLADM_ARG_NEED_TL, "a:k:r:s:"}, {"read", CTLADM_CMD_READ, CTLADM_ARG_NEED_TL, rw_opts}, @@ -3437,6 +3439,7 @@ struct cctl_islist_conn { char *header_digest; char *data_digest; char *max_data_segment_length;; + char *offload;; int immediate_data; int iser; STAILQ_ENTRY(cctl_islist_conn) links; @@ -3540,6 +3543,7 @@ cctl_islist_end_element(void *user_data, const char *name) } else if (strcmp(name, "target_alias") == 0) { cur_conn->target_alias = str; str = NULL; + } else if (strcmp(name, "target_portal_group_tag") == 0) { } else if (strcmp(name, "header_digest") == 0) { cur_conn->header_digest = str; str = NULL; @@ -3549,6 +3553,9 @@ cctl_islist_end_element(void *user_data, const char *name) } else if (strcmp(name, "max_data_segment_length") == 0) { cur_conn->max_data_segment_length = str; str = NULL; + } else if (strcmp(name, "offload") == 0) { + cur_conn->offload = str; + str = NULL; } else if (strcmp(name, "immediate_data") == 0) { cur_conn->immediate_data = atoi(str); } else if (strcmp(name, "iser") == 0) { @@ -3556,8 +3563,12 @@ cctl_islist_end_element(void *user_data, const char *name) } else if (strcmp(name, "connection") == 0) { islist->cur_conn = NULL; } else if (strcmp(name, "ctlislist") == 0) { - } else - errx(1, "unknown element %s", name); + /* Nothing. */ + } else { + /* + * Unknown element; ignore it for forward compatiblity. + */ + } free(str); } @@ -3643,11 +3654,14 @@ retry: XML_SetCharacterDataHandler(parser, cctl_islist_char_handler); retval = XML_Parse(parser, conn_str, strlen(conn_str), 1); - XML_ParserFree(parser); if (retval != 1) { + warnx("%s: Unable to parse XML: Error %d", __func__, + XML_GetErrorCode(parser)); + XML_ParserFree(parser); retval = 1; goto bailout; } + XML_ParserFree(parser); if (verbose != 0) { STAILQ_FOREACH(conn, &islist.conn_list, links) { @@ -3662,6 +3676,7 @@ retry: printf("DataSegmentLen: %s\n", conn->max_data_segment_length); printf("ImmediateData: %s\n", conn->immediate_data ? "Yes" : "No"); printf("iSER (RDMA): %s\n", conn->iser ? "Yes" : "No"); + printf("Offload driver: %s\n", conn->offload); printf("\n"); } } else { @@ -4058,11 +4073,14 @@ retry: XML_SetCharacterDataHandler(parser, cctl_char_handler); retval = XML_Parse(parser, lun_str, strlen(lun_str), 1); - XML_ParserFree(parser); if (retval != 1) { + warnx("%s: Unable to parse XML: Error %d", __func__, + XML_GetErrorCode(parser)); + XML_ParserFree(parser); retval = 1; goto bailout; } + XML_ParserFree(parser); printf("LUN Backend %18s %4s %-16s %-16s\n", "Size (Blocks)", "BS", "Serial Number", "Device ID"); @@ -4100,8 +4118,9 @@ struct cctl_port { char *frontend_type; char *name; int pp, vp; - char *target, *port; + char *target, *port, *lun_map; STAILQ_HEAD(,cctl_lun_nv) init_list; + STAILQ_HEAD(,cctl_lun_nv) lun_list; STAILQ_HEAD(,cctl_lun_nv) attr_list; STAILQ_ENTRY(cctl_port) links; }; @@ -4111,6 +4130,7 @@ struct cctl_portlist_data { STAILQ_HEAD(,cctl_port) port_list; struct cctl_port *cur_port; int level; + uint64_t cur_id; struct sbuf *cur_sb[32]; }; @@ -4133,6 +4153,14 @@ cctl_start_pelement(void *user_data, const char *name, const char **attr) if (portlist->cur_sb[portlist->level] == NULL) err(1, "%s: Unable to allocate sbuf", __func__); + portlist->cur_id = 0; + for (i = 0; attr[i] != NULL; i += 2) { + if (strcmp(attr[i], "id") == 0) { + portlist->cur_id = strtoull(attr[i+1], NULL, 0); + break; + } + } + if (strcmp(name, "targ_port") == 0) { if (cur_port != NULL) errx(1, "%s: improper port element nesting", __func__); @@ -4146,17 +4174,10 @@ cctl_start_pelement(void *user_data, const char *name, const char **attr) portlist->cur_port = cur_port; STAILQ_INIT(&cur_port->init_list); + STAILQ_INIT(&cur_port->lun_list); STAILQ_INIT(&cur_port->attr_list); + cur_port->port_id = portlist->cur_id; STAILQ_INSERT_TAIL(&portlist->port_list, cur_port, links); - - for (i = 0; attr[i] != NULL; i += 2) { - if (strcmp(attr[i], "id") == 0) { - cur_port->port_id = strtoull(attr[i+1], NULL, 0); - } else { - errx(1, "%s: invalid LUN attribute %s = %s", - __func__, attr[i], attr[i+1]); - } - } } } @@ -4213,6 +4234,9 @@ cctl_end_pelement(void *user_data, const char *name) } else if (strcmp(name, "port") == 0) { cur_port->port = str; str = NULL; + } else if (strcmp(name, "lun_map") == 0) { + cur_port->lun_map = str; + str = NULL; } else if (strcmp(name, "targ_port") == 0) { portlist->cur_port = NULL; } else if (strcmp(name, "ctlportlist") == 0) { @@ -4225,7 +4249,11 @@ cctl_end_pelement(void *user_data, const char *name) err(1, "%s: can't allocate %zd bytes for nv pair", __func__, sizeof(*nv)); - nv->name = strdup(name); + if (strcmp(name, "initiator") == 0 || + strcmp(name, "lun") == 0) + asprintf(&nv->name, "%ju", portlist->cur_id); + else + nv->name = strdup(name); if (nv->name == NULL) err(1, "%s: can't allocated %zd bytes for string", __func__, strlen(name)); @@ -4234,6 +4262,8 @@ cctl_end_pelement(void *user_data, const char *name) str = NULL; if (strcmp(name, "initiator") == 0) STAILQ_INSERT_TAIL(&cur_port->init_list, nv, links); + else if (strcmp(name, "lun") == 0) + STAILQ_INSERT_TAIL(&cur_port->lun_list, nv, links); else STAILQ_INSERT_TAIL(&cur_port->attr_list, nv, links); } @@ -4264,7 +4294,7 @@ cctl_portlist(int fd, int argc, char **argv, char *combinedopt) int retval, c; char *frontend = NULL; uint64_t portarg = UINT64_MAX; - int verbose = 0, init = 0, quiet = 0; + int verbose = 0, init = 0, lun = 0, quiet = 0; retval = 0; port_len = 4096; @@ -4280,6 +4310,9 @@ cctl_portlist(int fd, int argc, char **argv, char *combinedopt) case 'i': init++; break; + case 'l': + lun++; + break; case 'p': portarg = strtoll(optarg, NULL, 0); break; @@ -4336,11 +4369,14 @@ retry: XML_SetCharacterDataHandler(parser, cctl_char_phandler); retval = XML_Parse(parser, port_str, strlen(port_str), 1); - XML_ParserFree(parser); if (retval != 1) { + warnx("%s: Unable to parse XML: Error %d", __func__, + XML_GetErrorCode(parser)); + XML_ParserFree(parser); retval = 1; goto bailout; } + XML_ParserFree(parser); if (quiet == 0) printf("Port Online Frontend Name pp vp\n"); @@ -4363,10 +4399,22 @@ retry: if (port->target) printf(" Target: %s\n", port->target); STAILQ_FOREACH(nv, &port->init_list, links) { - printf(" Initiator: %s\n", nv->value); + printf(" Initiator %s: %s\n", + nv->name, nv->value); } } + if (lun || verbose) { + if (port->lun_map) { + STAILQ_FOREACH(nv, &port->lun_list, links) + printf(" LUN %s: %s\n", + nv->name, nv->value); + if (STAILQ_EMPTY(&port->lun_list)) + printf(" No LUNs mapped\n"); + } else + printf(" All LUNs mapped\n"); + } + if (verbose) { STAILQ_FOREACH(nv, &port->attr_list, links) { printf(" %s=%s\n", nv->name, nv->value); @@ -4379,6 +4427,41 @@ bailout: return (retval); } +static int +cctl_lunmap(int fd, int argc, char **argv, char *combinedopt) +{ + struct ctl_lun_map lm; + int retval = 0, c; + + retval = 0; + lm.port = UINT32_MAX; + lm.plun = UINT32_MAX; + lm.lun = UINT32_MAX; + + while ((c = getopt(argc, argv, combinedopt)) != -1) { + switch (c) { + case 'p': + lm.port = strtoll(optarg, NULL, 0); + break; + case 'l': + lm.plun = strtoll(optarg, NULL, 0); + break; + case 'L': + lm.lun = strtoll(optarg, NULL, 0); + break; + default: + break; + } + } + + if (ioctl(fd, CTL_LUN_MAP, &lm) == -1) { + warn("%s: error issuing CTL_LUN_MAP ioctl", __func__); + retval = 1; + } + + return (retval); +} + void usage(int error) { @@ -4416,6 +4499,7 @@ usage(int error) " ctladm hardstop\n" " ctladm hardstart\n" " ctladm lunlist\n" +" ctladm lunmap -p targ_port [-l pLUN] [-L cLUN]\n" " ctladm bbrread [dev_id] <-l lba> <-d datalen>\n" " ctladm delay [dev_id] <-l datamove|done> [-T oneshot|cont]\n" " [-t secs]\n" @@ -4515,10 +4599,15 @@ usage(int error) "portlist options:\n" "-f fronetnd : specify frontend type\n" "-i : report target and initiators addresses\n" +"-l : report LUN mapping\n" "-p targ_port : specify target port number\n" "-q : omit header in list output\n" "-v : verbose output (report all port options)\n" "-x : output port list in XML format\n" +"lunmap options:\n" +"-p targ_port : specify target port number\n" +"-L pLUN : specify port-visible LUN\n" +"-L cLUN : specify CTL LUN\n" "bbrread options:\n" "-l lba : starting LBA\n" "-d datalen : length, in bytes, to read\n", @@ -4746,6 +4835,9 @@ main(int argc, char **argv) case CTLADM_CMD_PORTLIST: retval = cctl_portlist(fd, argc, argv, combinedopt); break; + case CTLADM_CMD_LUNMAP: + retval = cctl_lunmap(fd, argc, argv, combinedopt); + break; case CTLADM_CMD_READCAPACITY: retval = cctl_read_capacity(fd, target, lun, initid, retries, argc, argv, combinedopt); diff --git a/usr.sbin/ctld/Makefile b/usr.sbin/ctld/Makefile index 149ae39..bd3fb94 100644 --- a/usr.sbin/ctld/Makefile +++ b/usr.sbin/ctld/Makefile @@ -10,8 +10,7 @@ CFLAGS+= -I${.CURDIR}/../../sys/dev/iscsi #CFLAGS+= -DICL_KERNEL_PROXY MAN= ctld.8 ctl.conf.5 -DPADD= ${LIBBSDXML} ${LIBCRYPTO} ${LIBL} ${LIBSBUF} ${LIBUTIL} -LDADD= -lbsdxml -lcrypto -ll -lsbuf -lutil +LIBADD= bsdxml crypto l sbuf util YFLAGS+= -v CLEANFILES= y.tab.c y.tab.h y.output diff --git a/usr.sbin/ctld/ctl.conf.5 b/usr.sbin/ctld/ctl.conf.5 index 8e427b1..eb65fa1 100644 --- a/usr.sbin/ctld/ctl.conf.5 +++ b/usr.sbin/ctld/ctl.conf.5 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 9, 2014 +.Dd April 19, 2015 .Dt CTL.CONF 5 .Os .Sh NAME @@ -60,9 +60,15 @@ file is: .Dl ... } +.No lun Ar name No { +.Dl path Ar path +} + .No target Ar name { .Dl auth-group Ar name -.Dl portal-group Ar name +.Dl portal-group Ar name Op Ar agname +.Dl port Ar name +.Dl lun Ar number Ar name .Dl lun Ar number No { .Dl path Ar path .Dl } @@ -95,6 +101,10 @@ Create a configuration context, defining a new portal-group, which can then be assigned to any number of targets. +.It Ic lun Ar name +Create a +.Sy lun +configuration context, defining a LUN to be exported by some target(s). .It Ic target Ar name Create a .Sy target @@ -218,7 +228,10 @@ An IPv4 or IPv6 address and port to listen on for incoming connections. .\".It Ic listen-iser Ar address .\"An IPv4 or IPv6 address and port to listen on for incoming connections .\"using iSER (iSCSI over RDMA) protocol. -.It Ic redirect Aq Ar address +.It Ic offload Ar driver +Define iSCSI hardware offload driver to use for this +.Sy portal-group . +.It Ic redirect Ar address IPv4 or IPv6 address to redirect initiators to. When configured, all initiators attempting to connect to portal belonging to this @@ -301,17 +314,28 @@ This clause is mutually exclusive with .Sy auth-group ; one cannot use both in a single target. -.It Ic portal-group Ar name +.It Ic portal-group Ar name Op Ar agname Assign a previously defined portal group to the target. The default portal group is .Qq Ar default , which makes the target available on TCP port 3260 on all configured IPv4 and IPv6 addresses. -.It Ic redirect Aq Ar address +Optional second argument specifies auth group name for connections +to this specific portal group. +If second argument is not specified, target auth group is used. +.It Ic port Ar name +Assign specified CTL port (such as "isp0") to the target. +On startup ctld configures LUN mapping and enables all assigned ports. +Each port can be assigned to only one target. +.It Ic redirect Ar address IPv4 or IPv6 address to redirect initiators to. When configured, all initiators attempting to connect to this target will get redirected using "Target moved temporarily" login response. Redirection happens after successful authentication. +.It Ic lun Ar number Ar name +Export previously defined +.Sy lun +by the parent target. .It Ic lun Ar number Create a .Sy lun @@ -341,7 +365,12 @@ All CTL-specific options are documented in the section of .Xr ctladm 8 . .It Ic path Ar path -The path to the file or device node used to back the LUN. +The path to the file, device node, or +.Xr zfs 8 +volume used to back the LUN. +For optimal performance, create the volume with the +.Qq Ar volmode=dev +property set. .It Ic serial Ar string The SCSI serial number presented to the initiator. .It Ic size Ar size @@ -356,8 +385,6 @@ configuration file. .El .Sh EXAMPLES .Bd -literal -pidfile /var/run/ctld.pid - auth-group ag0 { chap-mutual "user" "secret" "mutualuser" "mutualsecret" chap-mutual "user2" "secret2" "mutualuser" "mutualsecret" @@ -389,29 +416,32 @@ target iqn.2012-06.com.example:target0 { } } -target iqn.2012-06.com.example:target1 { - chap chapuser chapsecret - lun 0 { - path /dev/zvol/tank/example_1 - } +lun example_1 { + path /dev/zvol/tank/example_1 + option naa 0x50015178f369f093 } -target iqn.2012-06.com.example:target2 { +target iqn.2012-06.com.example:target1 { auth-group ag0 portal-group pg0 - lun 0 { - path /dev/zvol/tank/example2_0 - } + lun 0 example_1 lun 1 { - path /dev/zvol/tank/example2_1 + path /dev/zvol/tank/example_2 option foo bar } } + +target naa.50015178f369f092 { + port isp0 + port isp1 + lun 0 example_1 +} .Ed .Sh SEE ALSO .Xr ctl 4 , .Xr ctladm 8 , -.Xr ctld 8 +.Xr ctld 8 , +.Xr zfs 8 .Sh AUTHORS The .Nm diff --git a/usr.sbin/ctld/ctld.8 b/usr.sbin/ctld/ctld.8 index aa9a414..b3bea16 100644 --- a/usr.sbin/ctld/ctld.8 +++ b/usr.sbin/ctld/ctld.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 9, 2014 +.Dd May 22, 2015 .Dt CTLD 8 .Os .Sh NAME @@ -104,7 +104,8 @@ utility exits 0 on success, and >0 if an error occurs. .Sh SEE ALSO .Xr ctl 4 , .Xr ctl.conf 5 , -.Xr ctladm 8 +.Xr ctladm 8 , +.Xr ctlstat 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c index bbf8e7d..6f0c63b 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -59,6 +59,7 @@ static volatile bool sigterm_received = false; static volatile bool sigalrm_received = false; static int nchildren = 0; +static uint16_t last_portal_group_tag = 0; static void usage(void) @@ -87,9 +88,12 @@ conf_new(void) conf = calloc(1, sizeof(*conf)); if (conf == NULL) log_err(1, "calloc"); + TAILQ_INIT(&conf->conf_luns); TAILQ_INIT(&conf->conf_targets); TAILQ_INIT(&conf->conf_auth_groups); + TAILQ_INIT(&conf->conf_ports); TAILQ_INIT(&conf->conf_portal_groups); + TAILQ_INIT(&conf->conf_pports); TAILQ_INIT(&conf->conf_isns); conf->conf_isns_period = 900; @@ -104,21 +108,28 @@ conf_new(void) void conf_delete(struct conf *conf) { + struct lun *lun, *ltmp; struct target *targ, *tmp; struct auth_group *ag, *cagtmp; struct portal_group *pg, *cpgtmp; + struct pport *pp, *pptmp; struct isns *is, *istmp; assert(conf->conf_pidfh == NULL); + TAILQ_FOREACH_SAFE(lun, &conf->conf_luns, l_next, ltmp) + lun_delete(lun); TAILQ_FOREACH_SAFE(targ, &conf->conf_targets, t_next, tmp) target_delete(targ); TAILQ_FOREACH_SAFE(ag, &conf->conf_auth_groups, ag_next, cagtmp) auth_group_delete(ag); TAILQ_FOREACH_SAFE(pg, &conf->conf_portal_groups, pg_next, cpgtmp) portal_group_delete(pg); + TAILQ_FOREACH_SAFE(pp, &conf->conf_pports, pp_next, pptmp) + pport_delete(pp); TAILQ_FOREACH_SAFE(is, &conf->conf_isns, i_next, istmp) isns_delete(is); + assert(TAILQ_EMPTY(&conf->conf_ports)); free(conf->conf_pidfile_path); free(conf); } @@ -192,7 +203,7 @@ auth_check_secret_length(struct auth *auth) } if (auth->a_mutual_secret != NULL) { - len = strlen(auth->a_secret); + len = strlen(auth->a_mutual_secret); if (len > 16) { if (auth->a_auth_group->ag_name != NULL) log_warnx("mutual secret for user \"%s\", " @@ -389,6 +400,7 @@ auth_portal_new(struct auth_group *ag, const char *portal) return (ap); error: + free(ap); log_errx(1, "Incorrect initiator portal '%s'", portal); return (NULL); } @@ -604,9 +616,9 @@ portal_group_new(struct conf *conf, const char *name) log_err(1, "calloc"); pg->pg_name = checked_strdup(name); TAILQ_INIT(&pg->pg_portals); + TAILQ_INIT(&pg->pg_ports); pg->pg_conf = conf; - conf->conf_last_portal_group_tag++; - pg->pg_tag = conf->conf_last_portal_group_tag; + pg->pg_tag = 0; /* Assigned later in conf_apply(). */ TAILQ_INSERT_TAIL(&conf->conf_portal_groups, pg, pg_next); return (pg); @@ -616,12 +628,16 @@ void portal_group_delete(struct portal_group *pg) { struct portal *portal, *tmp; + struct port *port, *tport; + TAILQ_FOREACH_SAFE(port, &pg->pg_ports, p_pgs, tport) + port_delete(port); TAILQ_REMOVE(&pg->pg_conf->conf_portal_groups, pg, pg_next); TAILQ_FOREACH_SAFE(portal, &pg->pg_portals, p_next, tmp) portal_delete(portal); free(pg->pg_name); + free(pg->pg_offload); free(pg->pg_redirection); free(pg); } @@ -643,10 +659,11 @@ static int parse_addr_port(char *arg, const char *def_port, struct addrinfo **ai) { struct addrinfo hints; - char *addr, *ch; + char *str, *addr, *ch; const char *port; int error, colons = 0; + str = arg = strdup(arg); if (arg[0] == '[') { /* * IPv6 address in square brackets, perhaps with port. @@ -659,8 +676,10 @@ parse_addr_port(char *arg, const char *def_port, struct addrinfo **ai) port = def_port; } else if (arg[0] == ':') { port = arg + 1; - } else + } else { + free(str); return (1); + } } else { /* * Either IPv6 address without brackets - and without @@ -687,9 +706,8 @@ parse_addr_port(char *arg, const char *def_port, struct addrinfo **ai) hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; error = getaddrinfo(addr, port, &hints, ai); - if (error != 0) - return (1); - return (0); + free(str); + return ((error != 0) ? 1 : 0); } int @@ -778,6 +796,7 @@ isns_do_register(struct isns *isns, int s, const char *hostname) struct target *target; struct portal *portal; struct portal_group *pg; + struct port *port; struct isns_req *req; int res = 0; uint32_t error; @@ -801,11 +820,14 @@ isns_do_register(struct isns *isns, int s, const char *hostname) isns_req_add_32(req, 33, 1); /* 1 -- Target*/ if (target->t_alias != NULL) isns_req_add_str(req, 34, target->t_alias); - pg = target->t_portal_group; - isns_req_add_32(req, 51, pg->pg_tag); - TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { - isns_req_add_addr(req, 49, portal->p_ai); - isns_req_add_port(req, 50, portal->p_ai); + TAILQ_FOREACH(port, &target->t_ports, p_ts) { + if ((pg = port->p_portal_group) == NULL) + continue; + isns_req_add_32(req, 51, pg->pg_tag); + TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { + isns_req_add_addr(req, 49, portal->p_ai); + isns_req_add_port(req, 50, portal->p_ai); + } } } res = isns_req_send(s, req); @@ -1002,6 +1024,22 @@ portal_group_set_filter(struct portal_group *pg, const char *str) } int +portal_group_set_offload(struct portal_group *pg, const char *offload) +{ + + if (pg->pg_offload != NULL) { + log_warnx("cannot set offload to \"%s\" for " + "portal-group \"%s\"; already defined", + offload, pg->pg_name); + return (1); + } + + pg->pg_offload = checked_strdup(offload); + + return (0); +} + +int portal_group_set_redirection(struct portal_group *pg, const char *addr) { @@ -1117,6 +1155,152 @@ valid_iscsi_name(const char *name) return (true); } +struct pport * +pport_new(struct conf *conf, const char *name, uint32_t ctl_port) +{ + struct pport *pp; + + pp = calloc(1, sizeof(*pp)); + if (pp == NULL) + log_err(1, "calloc"); + pp->pp_conf = conf; + pp->pp_name = checked_strdup(name); + pp->pp_ctl_port = ctl_port; + TAILQ_INIT(&pp->pp_ports); + TAILQ_INSERT_TAIL(&conf->conf_pports, pp, pp_next); + return (pp); +} + +struct pport * +pport_find(const struct conf *conf, const char *name) +{ + struct pport *pp; + + TAILQ_FOREACH(pp, &conf->conf_pports, pp_next) { + if (strcasecmp(pp->pp_name, name) == 0) + return (pp); + } + return (NULL); +} + +struct pport * +pport_copy(struct pport *pp, struct conf *conf) +{ + struct pport *ppnew; + + ppnew = pport_new(conf, pp->pp_name, pp->pp_ctl_port); + return (ppnew); +} + +void +pport_delete(struct pport *pp) +{ + struct port *port, *tport; + + TAILQ_FOREACH_SAFE(port, &pp->pp_ports, p_ts, tport) + port_delete(port); + TAILQ_REMOVE(&pp->pp_conf->conf_pports, pp, pp_next); + free(pp->pp_name); + free(pp); +} + +struct port * +port_new(struct conf *conf, struct target *target, struct portal_group *pg) +{ + struct port *port; + char *name; + int ret; + + ret = asprintf(&name, "%s-%s", pg->pg_name, target->t_name); + if (ret <= 0) + log_err(1, "asprintf"); + if (port_find(conf, name) != NULL) { + log_warnx("duplicate port \"%s\"", name); + free(name); + return (NULL); + } + port = calloc(1, sizeof(*port)); + if (port == NULL) + log_err(1, "calloc"); + port->p_conf = conf; + port->p_name = name; + TAILQ_INSERT_TAIL(&conf->conf_ports, port, p_next); + TAILQ_INSERT_TAIL(&target->t_ports, port, p_ts); + port->p_target = target; + TAILQ_INSERT_TAIL(&pg->pg_ports, port, p_pgs); + port->p_portal_group = pg; + return (port); +} + +struct port * +port_new_pp(struct conf *conf, struct target *target, struct pport *pp) +{ + struct port *port; + char *name; + int ret; + + ret = asprintf(&name, "%s-%s", pp->pp_name, target->t_name); + if (ret <= 0) + log_err(1, "asprintf"); + if (port_find(conf, name) != NULL) { + log_warnx("duplicate port \"%s\"", name); + free(name); + return (NULL); + } + port = calloc(1, sizeof(*port)); + if (port == NULL) + log_err(1, "calloc"); + port->p_conf = conf; + port->p_name = name; + TAILQ_INSERT_TAIL(&conf->conf_ports, port, p_next); + TAILQ_INSERT_TAIL(&target->t_ports, port, p_ts); + port->p_target = target; + TAILQ_INSERT_TAIL(&pp->pp_ports, port, p_pps); + port->p_pport = pp; + return (port); +} + +struct port * +port_find(const struct conf *conf, const char *name) +{ + struct port *port; + + TAILQ_FOREACH(port, &conf->conf_ports, p_next) { + if (strcasecmp(port->p_name, name) == 0) + return (port); + } + + return (NULL); +} + +struct port * +port_find_in_pg(const struct portal_group *pg, const char *target) +{ + struct port *port; + + TAILQ_FOREACH(port, &pg->pg_ports, p_pgs) { + if (strcasecmp(port->p_target->t_name, target) == 0) + return (port); + } + + return (NULL); +} + +void +port_delete(struct port *port) +{ + + if (port->p_portal_group) + TAILQ_REMOVE(&port->p_portal_group->pg_ports, port, p_pgs); + if (port->p_pport) + TAILQ_REMOVE(&port->p_pport->pp_ports, port, p_pps); + if (port->p_target) + TAILQ_REMOVE(&port->p_target->t_ports, port, p_ts); + TAILQ_REMOVE(&port->p_conf->conf_ports, port, p_next); + free(port->p_name); + free(port); +} + struct target * target_new(struct conf *conf, const char *name) { @@ -1144,8 +1328,8 @@ target_new(struct conf *conf, const char *name) for (i = 0; i < len; i++) targ->t_name[i] = tolower(targ->t_name[i]); - TAILQ_INIT(&targ->t_luns); targ->t_conf = conf; + TAILQ_INIT(&targ->t_ports); TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next); return (targ); @@ -1154,12 +1338,12 @@ target_new(struct conf *conf, const char *name) void target_delete(struct target *targ) { - struct lun *lun, *tmp; + struct port *port, *tport; + TAILQ_FOREACH_SAFE(port, &targ->t_ports, p_ts, tport) + port_delete(port); TAILQ_REMOVE(&targ->t_conf->conf_targets, targ, t_next); - TAILQ_FOREACH_SAFE(lun, &targ->t_luns, l_next, tmp) - lun_delete(lun); free(targ->t_name); free(targ->t_redirection); free(targ); @@ -1195,24 +1379,23 @@ target_set_redirection(struct target *target, const char *addr) } struct lun * -lun_new(struct target *targ, int lun_id) +lun_new(struct conf *conf, const char *name) { struct lun *lun; - lun = lun_find(targ, lun_id); + lun = lun_find(conf, name); if (lun != NULL) { - log_warnx("duplicated lun %d for target \"%s\"", - lun_id, targ->t_name); + log_warnx("duplicated lun \"%s\"", name); return (NULL); } lun = calloc(1, sizeof(*lun)); if (lun == NULL) log_err(1, "calloc"); - lun->l_lun = lun_id; + lun->l_conf = conf; + lun->l_name = checked_strdup(name); TAILQ_INIT(&lun->l_options); - lun->l_target = targ; - TAILQ_INSERT_TAIL(&targ->t_luns, lun, l_next); + TAILQ_INSERT_TAIL(&conf->conf_luns, lun, l_next); return (lun); } @@ -1220,26 +1403,36 @@ lun_new(struct target *targ, int lun_id) void lun_delete(struct lun *lun) { + struct target *targ; struct lun_option *lo, *tmp; + int i; - TAILQ_REMOVE(&lun->l_target->t_luns, lun, l_next); + TAILQ_FOREACH(targ, &lun->l_conf->conf_targets, t_next) { + for (i = 0; i < MAX_LUNS; i++) { + if (targ->t_luns[i] == lun) + targ->t_luns[i] = NULL; + } + } + TAILQ_REMOVE(&lun->l_conf->conf_luns, lun, l_next); TAILQ_FOREACH_SAFE(lo, &lun->l_options, lo_next, tmp) lun_option_delete(lo); + free(lun->l_name); free(lun->l_backend); free(lun->l_device_id); free(lun->l_path); + free(lun->l_scsiname); free(lun->l_serial); free(lun); } struct lun * -lun_find(const struct target *targ, int lun_id) +lun_find(const struct conf *conf, const char *name) { struct lun *lun; - TAILQ_FOREACH(lun, &targ->t_luns, l_next) { - if (lun->l_lun == lun_id) + TAILQ_FOREACH(lun, &conf->conf_luns, l_next) { + if (strcmp(lun->l_name, name) == 0) return (lun); } @@ -1275,6 +1468,13 @@ lun_set_path(struct lun *lun, const char *value) } void +lun_set_scsiname(struct lun *lun, const char *value) +{ + free(lun->l_scsiname); + lun->l_scsiname = checked_strdup(value); +} + +void lun_set_serial(struct lun *lun, const char *value) { free(lun->l_serial); @@ -1302,8 +1502,8 @@ lun_option_new(struct lun *lun, const char *name, const char *value) lo = lun_option_find(lun, name); if (lo != NULL) { - log_warnx("duplicated lun option %s for lun %d, target \"%s\"", - name, lun->l_lun, lun->l_target->t_name); + log_warnx("duplicated lun option \"%s\" for lun \"%s\"", + name, lun->l_name); return (NULL); } @@ -1408,18 +1608,18 @@ conf_print(struct conf *conf) fprintf(stderr, "\t listen %s\n", portal->p_listen); fprintf(stderr, "}\n"); } + TAILQ_FOREACH(lun, &conf->conf_luns, l_next) { + fprintf(stderr, "\tlun %s {\n", lun->l_name); + fprintf(stderr, "\t\tpath %s\n", lun->l_path); + TAILQ_FOREACH(lo, &lun->l_options, lo_next) + fprintf(stderr, "\t\toption %s %s\n", + lo->lo_name, lo->lo_value); + fprintf(stderr, "\t}\n"); + } TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { fprintf(stderr, "target %s {\n", targ->t_name); if (targ->t_alias != NULL) fprintf(stderr, "\t alias %s\n", targ->t_alias); - TAILQ_FOREACH(lun, &targ->t_luns, l_next) { - fprintf(stderr, "\tlun %d {\n", lun->l_lun); - fprintf(stderr, "\t\tpath %s\n", lun->l_path); - TAILQ_FOREACH(lo, &lun->l_options, lo_next) - fprintf(stderr, "\t\toption %s %s\n", - lo->lo_name, lo->lo_value); - fprintf(stderr, "\t}\n"); - } fprintf(stderr, "}\n"); } } @@ -1429,60 +1629,49 @@ static int conf_verify_lun(struct lun *lun) { const struct lun *lun2; - const struct target *targ2; if (lun->l_backend == NULL) lun_set_backend(lun, "block"); if (strcmp(lun->l_backend, "block") == 0) { if (lun->l_path == NULL) { - log_warnx("missing path for lun %d, target \"%s\"", - lun->l_lun, lun->l_target->t_name); + log_warnx("missing path for lun \"%s\"", + lun->l_name); return (1); } } else if (strcmp(lun->l_backend, "ramdisk") == 0) { if (lun->l_size == 0) { - log_warnx("missing size for ramdisk-backed lun %d, " - "target \"%s\"", lun->l_lun, lun->l_target->t_name); + log_warnx("missing size for ramdisk-backed lun \"%s\"", + lun->l_name); return (1); } if (lun->l_path != NULL) { log_warnx("path must not be specified " - "for ramdisk-backed lun %d, target \"%s\"", - lun->l_lun, lun->l_target->t_name); + "for ramdisk-backed lun \"%s\"", + lun->l_name); return (1); } } - if (lun->l_lun < 0 || lun->l_lun > 255) { - log_warnx("invalid lun number for lun %d, target \"%s\"; " - "must be between 0 and 255", lun->l_lun, - lun->l_target->t_name); - return (1); - } if (lun->l_blocksize == 0) { lun_set_blocksize(lun, DEFAULT_BLOCKSIZE); } else if (lun->l_blocksize < 0) { - log_warnx("invalid blocksize for lun %d, target \"%s\"; " - "must be larger than 0", lun->l_lun, lun->l_target->t_name); + log_warnx("invalid blocksize for lun \"%s\"; " + "must be larger than 0", lun->l_name); return (1); } if (lun->l_size != 0 && lun->l_size % lun->l_blocksize != 0) { - log_warnx("invalid size for lun %d, target \"%s\"; " - "must be multiple of blocksize", lun->l_lun, - lun->l_target->t_name); + log_warnx("invalid size for lun \"%s\"; " + "must be multiple of blocksize", lun->l_name); return (1); } - TAILQ_FOREACH(targ2, &lun->l_target->t_conf->conf_targets, t_next) { - TAILQ_FOREACH(lun2, &targ2->t_luns, l_next) { - if (lun == lun2) - continue; - if (lun->l_path != NULL && lun2->l_path != NULL && - strcmp(lun->l_path, lun2->l_path) == 0) { - log_debugx("WARNING: path \"%s\" duplicated " - "between lun %d, target \"%s\", and " - "lun %d, target \"%s\"", lun->l_path, - lun->l_lun, lun->l_target->t_name, - lun2->l_lun, lun2->l_target->t_name); - } + TAILQ_FOREACH(lun2, &lun->l_conf->conf_luns, l_next) { + if (lun == lun2) + continue; + if (lun->l_path != NULL && lun2->l_path != NULL && + strcmp(lun->l_path, lun2->l_path) == 0) { + log_debugx("WARNING: path \"%s\" duplicated " + "between lun \"%s\", and " + "lun \"%s\"", lun->l_path, + lun->l_name, lun2->l_name); } } @@ -1494,31 +1683,35 @@ conf_verify(struct conf *conf) { struct auth_group *ag; struct portal_group *pg; + struct port *port; struct target *targ; struct lun *lun; bool found; - int error; + int error, i; if (conf->conf_pidfile_path == NULL) conf->conf_pidfile_path = checked_strdup(DEFAULT_PIDFILE); + TAILQ_FOREACH(lun, &conf->conf_luns, l_next) { + error = conf_verify_lun(lun); + if (error != 0) + return (error); + } TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { if (targ->t_auth_group == NULL) { targ->t_auth_group = auth_group_find(conf, "default"); assert(targ->t_auth_group != NULL); } - if (targ->t_portal_group == NULL) { - targ->t_portal_group = portal_group_find(conf, - "default"); - assert(targ->t_portal_group != NULL); + if (TAILQ_EMPTY(&targ->t_ports)) { + pg = portal_group_find(conf, "default"); + assert(pg != NULL); + port_new(conf, targ, pg); } found = false; - TAILQ_FOREACH(lun, &targ->t_luns, l_next) { - error = conf_verify_lun(lun); - if (error != 0) - return (error); - found = true; + for (i = 0; i < MAX_LUNS; i++) { + if (targ->t_luns[i] != NULL) + found = true; } if (!found && targ->t_redirection == NULL) { log_warnx("no LUNs defined for target \"%s\"", @@ -1541,20 +1734,14 @@ conf_verify(struct conf *conf) if (pg->pg_discovery_filter == PG_FILTER_UNKNOWN) pg->pg_discovery_filter = PG_FILTER_NONE; - TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { - if (targ->t_portal_group == pg) - break; - } - if (pg->pg_redirection != NULL) { - if (targ != NULL) { + if (!TAILQ_EMPTY(&pg->pg_ports)) { + if (pg->pg_redirection != NULL) { log_debugx("portal-group \"%s\" assigned " - "to target \"%s\", but configured " + "to target, but configured " "for redirection", - pg->pg_name, targ->t_name); + pg->pg_name); } pg->pg_unassigned = false; - } else if (targ != NULL) { - pg->pg_unassigned = false; } else { if (strcmp(pg->pg_name, "default") != 0) log_warnx("portal-group \"%s\" not assigned " @@ -1575,6 +1762,12 @@ conf_verify(struct conf *conf) break; } } + TAILQ_FOREACH(port, &conf->conf_ports, p_next) { + if (port->p_auth_group == ag) { + found = true; + break; + } + } TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { if (pg->pg_discovery_auth_group == ag) { found = true; @@ -1596,13 +1789,13 @@ conf_verify(struct conf *conf) static int conf_apply(struct conf *oldconf, struct conf *newconf) { - struct target *oldtarg, *newtarg, *tmptarg; struct lun *oldlun, *newlun, *tmplun; struct portal_group *oldpg, *newpg; struct portal *oldp, *newp; + struct port *oldport, *newport, *tmpport; struct isns *oldns, *newns; pid_t otherpid; - int changed, cumulated_error = 0, error; + int changed, cumulated_error = 0, error, sockbuf; int one = 1; if (oldconf->conf_debug != newconf->conf_debug) { @@ -1638,6 +1831,17 @@ conf_apply(struct conf *oldconf, struct conf *newconf) } } + /* + * Go through the new portal groups, assigning tags or preserving old. + */ + TAILQ_FOREACH(newpg, &newconf->conf_portal_groups, pg_next) { + oldpg = portal_group_find(oldconf, newpg->pg_name); + if (oldpg != NULL) + newpg->pg_tag = oldpg->pg_tag; + else + newpg->pg_tag = ++last_portal_group_tag; + } + /* Deregister on removed iSNS servers. */ TAILQ_FOREACH(oldns, &oldconf->conf_isns, i_next) { TAILQ_FOREACH(newns, &newconf->conf_isns, i_next) { @@ -1655,165 +1859,156 @@ conf_apply(struct conf *oldconf, struct conf *newconf) * be somewhat hairy, though, and lun deletion failures don't * really happen, so leave it as it is for now. */ - TAILQ_FOREACH_SAFE(oldtarg, &oldconf->conf_targets, t_next, tmptarg) { - /* - * First, remove any targets present in the old configuration - * and missing in the new one. - */ - newtarg = target_find(newconf, oldtarg->t_name); - if (newtarg == NULL) { - TAILQ_FOREACH_SAFE(oldlun, &oldtarg->t_luns, l_next, - tmplun) { - log_debugx("target %s not found in new " - "configuration; removing its lun %d, " - "backed by CTL lun %d", - oldtarg->t_name, oldlun->l_lun, - oldlun->l_ctl_lun); - error = kernel_lun_remove(oldlun); - if (error != 0) { - log_warnx("failed to remove lun %d, " - "target %s, CTL lun %d", - oldlun->l_lun, oldtarg->t_name, - oldlun->l_ctl_lun); - cumulated_error++; - } + /* + * First, remove any ports present in the old configuration + * and missing in the new one. + */ + TAILQ_FOREACH_SAFE(oldport, &oldconf->conf_ports, p_next, tmpport) { + newport = port_find(newconf, oldport->p_name); + if (newport != NULL) + continue; + log_debugx("removing port \"%s\"", oldport->p_name); + error = kernel_port_remove(oldport); + if (error != 0) { + log_warnx("failed to remove port %s", + oldport->p_name); + /* + * XXX: Uncomment after fixing the root cause. + * + * cumulated_error++; + */ + } + } + + /* + * Second, remove any LUNs present in the old configuration + * and missing in the new one. + */ + TAILQ_FOREACH_SAFE(oldlun, &oldconf->conf_luns, l_next, tmplun) { + newlun = lun_find(newconf, oldlun->l_name); + if (newlun == NULL) { + log_debugx("lun \"%s\", CTL lun %d " + "not found in new configuration; " + "removing", oldlun->l_name, oldlun->l_ctl_lun); + error = kernel_lun_remove(oldlun); + if (error != 0) { + log_warnx("failed to remove lun \"%s\", " + "CTL lun %d", + oldlun->l_name, oldlun->l_ctl_lun); + cumulated_error++; } - kernel_port_remove(oldtarg); continue; } /* - * Second, remove any LUNs present in the old target - * and missing in the new one. + * Also remove the LUNs changed by more than size. */ - TAILQ_FOREACH_SAFE(oldlun, &oldtarg->t_luns, l_next, tmplun) { - newlun = lun_find(newtarg, oldlun->l_lun); - if (newlun == NULL) { - log_debugx("lun %d, target %s, CTL lun %d " - "not found in new configuration; " - "removing", oldlun->l_lun, oldtarg->t_name, - oldlun->l_ctl_lun); - error = kernel_lun_remove(oldlun); - if (error != 0) { - log_warnx("failed to remove lun %d, " - "target %s, CTL lun %d", - oldlun->l_lun, oldtarg->t_name, - oldlun->l_ctl_lun); - cumulated_error++; - } - continue; + changed = 0; + assert(oldlun->l_backend != NULL); + assert(newlun->l_backend != NULL); + if (strcmp(newlun->l_backend, oldlun->l_backend) != 0) { + log_debugx("backend for lun \"%s\", " + "CTL lun %d changed; removing", + oldlun->l_name, oldlun->l_ctl_lun); + changed = 1; + } + if (oldlun->l_blocksize != newlun->l_blocksize) { + log_debugx("blocksize for lun \"%s\", " + "CTL lun %d changed; removing", + oldlun->l_name, oldlun->l_ctl_lun); + changed = 1; + } + if (newlun->l_device_id != NULL && + (oldlun->l_device_id == NULL || + strcmp(oldlun->l_device_id, newlun->l_device_id) != + 0)) { + log_debugx("device-id for lun \"%s\", " + "CTL lun %d changed; removing", + oldlun->l_name, oldlun->l_ctl_lun); + changed = 1; + } + if (newlun->l_path != NULL && + (oldlun->l_path == NULL || + strcmp(oldlun->l_path, newlun->l_path) != 0)) { + log_debugx("path for lun \"%s\", " + "CTL lun %d, changed; removing", + oldlun->l_name, oldlun->l_ctl_lun); + changed = 1; + } + if (newlun->l_serial != NULL && + (oldlun->l_serial == NULL || + strcmp(oldlun->l_serial, newlun->l_serial) != 0)) { + log_debugx("serial for lun \"%s\", " + "CTL lun %d changed; removing", + oldlun->l_name, oldlun->l_ctl_lun); + changed = 1; + } + if (changed) { + error = kernel_lun_remove(oldlun); + if (error != 0) { + log_warnx("failed to remove lun \"%s\", " + "CTL lun %d", + oldlun->l_name, oldlun->l_ctl_lun); + cumulated_error++; } + lun_delete(oldlun); + continue; + } - /* - * Also remove the LUNs changed by more than size. - */ - changed = 0; - assert(oldlun->l_backend != NULL); - assert(newlun->l_backend != NULL); - if (strcmp(newlun->l_backend, oldlun->l_backend) != 0) { - log_debugx("backend for lun %d, target %s, " - "CTL lun %d changed; removing", - oldlun->l_lun, oldtarg->t_name, - oldlun->l_ctl_lun); - changed = 1; - } - if (oldlun->l_blocksize != newlun->l_blocksize) { - log_debugx("blocksize for lun %d, target %s, " - "CTL lun %d changed; removing", - oldlun->l_lun, oldtarg->t_name, - oldlun->l_ctl_lun); - changed = 1; - } - if (newlun->l_device_id != NULL && - (oldlun->l_device_id == NULL || - strcmp(oldlun->l_device_id, newlun->l_device_id) != - 0)) { - log_debugx("device-id for lun %d, target %s, " - "CTL lun %d changed; removing", - oldlun->l_lun, oldtarg->t_name, - oldlun->l_ctl_lun); - changed = 1; - } - if (newlun->l_path != NULL && - (oldlun->l_path == NULL || - strcmp(oldlun->l_path, newlun->l_path) != 0)) { - log_debugx("path for lun %d, target %s, " - "CTL lun %d, changed; removing", - oldlun->l_lun, oldtarg->t_name, - oldlun->l_ctl_lun); - changed = 1; - } - if (newlun->l_serial != NULL && - (oldlun->l_serial == NULL || - strcmp(oldlun->l_serial, newlun->l_serial) != 0)) { - log_debugx("serial for lun %d, target %s, " - "CTL lun %d changed; removing", - oldlun->l_lun, oldtarg->t_name, - oldlun->l_ctl_lun); - changed = 1; - } - if (changed) { - error = kernel_lun_remove(oldlun); + lun_set_ctl_lun(newlun, oldlun->l_ctl_lun); + } + + TAILQ_FOREACH_SAFE(newlun, &newconf->conf_luns, l_next, tmplun) { + oldlun = lun_find(oldconf, newlun->l_name); + if (oldlun != NULL) { + if (newlun->l_size != oldlun->l_size || + newlun->l_size == 0) { + log_debugx("resizing lun \"%s\", CTL lun %d", + newlun->l_name, newlun->l_ctl_lun); + error = kernel_lun_resize(newlun); if (error != 0) { - log_warnx("failed to remove lun %d, " - "target %s, CTL lun %d", - oldlun->l_lun, oldtarg->t_name, - oldlun->l_ctl_lun); + log_warnx("failed to " + "resize lun \"%s\", CTL lun %d", + newlun->l_name, + newlun->l_ctl_lun); cumulated_error++; } - lun_delete(oldlun); - continue; } - - lun_set_ctl_lun(newlun, oldlun->l_ctl_lun); + continue; + } + log_debugx("adding lun \"%s\"", newlun->l_name); + error = kernel_lun_add(newlun); + if (error != 0) { + log_warnx("failed to add lun \"%s\"", newlun->l_name); + lun_delete(newlun); + cumulated_error++; } } /* - * Now add new targets or modify existing ones. + * Now add new ports or modify existing ones. */ - TAILQ_FOREACH(newtarg, &newconf->conf_targets, t_next) { - oldtarg = target_find(oldconf, newtarg->t_name); - - TAILQ_FOREACH_SAFE(newlun, &newtarg->t_luns, l_next, tmplun) { - if (oldtarg != NULL) { - oldlun = lun_find(oldtarg, newlun->l_lun); - if (oldlun != NULL) { - if (newlun->l_size != oldlun->l_size || - newlun->l_size == 0) { - log_debugx("resizing lun %d, " - "target %s, CTL lun %d", - newlun->l_lun, - newtarg->t_name, - newlun->l_ctl_lun); - error = - kernel_lun_resize(newlun); - if (error != 0) { - log_warnx("failed to " - "resize lun %d, " - "target %s, " - "CTL lun %d", - newlun->l_lun, - newtarg->t_name, - newlun->l_lun); - cumulated_error++; - } - } - continue; - } - } - log_debugx("adding lun %d, target %s", - newlun->l_lun, newtarg->t_name); - error = kernel_lun_add(newlun); - if (error != 0) { - log_warnx("failed to add lun %d, target %s", - newlun->l_lun, newtarg->t_name); - lun_delete(newlun); - cumulated_error++; - } + TAILQ_FOREACH(newport, &newconf->conf_ports, p_next) { + oldport = port_find(oldconf, newport->p_name); + + if (oldport == NULL) { + log_debugx("adding port \"%s\"", newport->p_name); + error = kernel_port_add(newport); + } else { + log_debugx("updating port \"%s\"", newport->p_name); + newport->p_ctl_port = oldport->p_ctl_port; + error = kernel_port_update(newport); + } + if (error != 0) { + log_warnx("failed to %s port %s", + (oldport == NULL) ? "add" : "update", + newport->p_name); + /* + * XXX: Uncomment after fixing the root cause. + * + * cumulated_error++; + */ } - if (oldtarg == NULL) - kernel_port_add(newtarg); } /* @@ -1880,6 +2075,16 @@ conf_apply(struct conf *oldconf, struct conf *newconf) cumulated_error++; continue; } + sockbuf = SOCKBUF_SIZE; + if (setsockopt(newp->p_socket, SOL_SOCKET, SO_RCVBUF, + &sockbuf, sizeof(sockbuf)) == -1) + log_warn("setsockopt(SO_RCVBUF) failed " + "for %s", newp->p_listen); + sockbuf = SOCKBUF_SIZE; + if (setsockopt(newp->p_socket, SOL_SOCKET, SO_SNDBUF, + &sockbuf, sizeof(sockbuf)) == -1) + log_warn("setsockopt(SO_SNDBUF) failed " + "for %s", newp->p_listen); error = setsockopt(newp->p_socket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if (error != 0) { @@ -2194,8 +2399,11 @@ found: client_fd = accept(portal->p_socket, (struct sockaddr *)&client_sa, &client_salen); - if (client_fd < 0) + if (client_fd < 0) { + if (errno == ECONNABORTED) + continue; log_err(1, "accept"); + } assert(client_salen >= client_sa.ss_len); handle_connection(portal, client_fd, @@ -2302,7 +2510,7 @@ main(int argc, char **argv) kernel_init(); oldconf = conf_new_from_kernel(); - newconf = conf_new_from_file(config_path); + newconf = conf_new_from_file(config_path, oldconf); if (newconf == NULL) log_errx(1, "configuration error; exiting"); if (debug > 0) { @@ -2337,7 +2545,7 @@ main(int argc, char **argv) if (sighup_received) { sighup_received = false; log_debugx("received SIGHUP, reloading configuration"); - tmpconf = conf_new_from_file(config_path); + tmpconf = conf_new_from_file(config_path, newconf); if (tmpconf == NULL) { log_warnx("configuration error, " "continuing with old configuration"); @@ -2357,7 +2565,7 @@ main(int argc, char **argv) log_debugx("exiting on signal; " "reloading empty configuration"); - log_debugx("disabling CTL iSCSI port " + log_debugx("removing CTL iSCSI ports " "and terminating all connections"); oldconf = newconf; diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h index 600bd30..52ffad0 100644 --- a/usr.sbin/ctld/ctld.h +++ b/usr.sbin/ctld/ctld.h @@ -45,9 +45,11 @@ #define DEFAULT_PIDFILE "/var/run/ctld.pid" #define DEFAULT_BLOCKSIZE 512 +#define MAX_LUNS 1024 #define MAX_NAME_LEN 223 #define MAX_DATA_SEGMENT_LENGTH (128 * 1024) #define MAX_BURST_LENGTH 16776192 +#define SOCKBUF_SIZE 1048576 struct auth { TAILQ_ENTRY(auth) a_next; @@ -117,11 +119,37 @@ struct portal_group { int pg_discovery_filter; bool pg_unassigned; TAILQ_HEAD(, portal) pg_portals; + TAILQ_HEAD(, port) pg_ports; + char *pg_offload; char *pg_redirection; uint16_t pg_tag; }; +struct pport { + TAILQ_ENTRY(pport) pp_next; + TAILQ_HEAD(, port) pp_ports; + struct conf *pp_conf; + char *pp_name; + + uint32_t pp_ctl_port; +}; + +struct port { + TAILQ_ENTRY(port) p_next; + TAILQ_ENTRY(port) p_pgs; + TAILQ_ENTRY(port) p_pps; + TAILQ_ENTRY(port) p_ts; + struct conf *p_conf; + char *p_name; + struct auth_group *p_auth_group; + struct portal_group *p_portal_group; + struct pport *p_pport; + struct target *p_target; + + uint32_t p_ctl_port; +}; + struct lun_option { TAILQ_ENTRY(lun_option) lo_next; struct lun *lo_lun; @@ -131,13 +159,14 @@ struct lun_option { struct lun { TAILQ_ENTRY(lun) l_next; + struct conf *l_conf; TAILQ_HEAD(, lun_option) l_options; - struct target *l_target; - int l_lun; + char *l_name; char *l_backend; int l_blocksize; char *l_device_id; char *l_path; + char *l_scsiname; char *l_serial; int64_t l_size; @@ -146,10 +175,10 @@ struct lun { struct target { TAILQ_ENTRY(target) t_next; - TAILQ_HEAD(, lun) t_luns; struct conf *t_conf; + struct lun *t_luns[MAX_LUNS]; struct auth_group *t_auth_group; - struct portal_group *t_portal_group; + TAILQ_HEAD(, port) t_ports; char *t_name; char *t_alias; char *t_redirection; @@ -164,9 +193,12 @@ struct isns { struct conf { char *conf_pidfile_path; + TAILQ_HEAD(, lun) conf_luns; TAILQ_HEAD(, target) conf_targets; TAILQ_HEAD(, auth_group) conf_auth_groups; + TAILQ_HEAD(, port) conf_ports; TAILQ_HEAD(, portal_group) conf_portal_groups; + TAILQ_HEAD(, pport) conf_pports; TAILQ_HEAD(, isns) conf_isns; int conf_isns_period; int conf_isns_timeout; @@ -174,7 +206,6 @@ struct conf { int conf_timeout; int conf_maxproc; - uint16_t conf_last_portal_group_tag; #ifdef ICL_KERNEL_PROXY int conf_portal_id; #endif @@ -194,6 +225,7 @@ struct conf { struct connection { struct portal *conn_portal; + struct port *conn_port; struct target *conn_target; int conn_socket; int conn_session_type; @@ -204,6 +236,7 @@ struct connection { struct sockaddr_storage conn_initiator_sa; uint32_t conn_cmdsn; uint32_t conn_statsn; + size_t conn_data_segment_limit; size_t conn_max_data_segment_length; size_t conn_max_burst_length; int conn_immediate_data; @@ -259,7 +292,7 @@ char *rchap_get_response(struct rchap *rchap); void rchap_delete(struct rchap *rchap); struct conf *conf_new(void); -struct conf *conf_new_from_file(const char *path); +struct conf *conf_new_from_file(const char *path, struct conf *old); struct conf *conf_new_from_kernel(void); void conf_delete(struct conf *conf); int conf_verify(struct conf *conf); @@ -303,6 +336,8 @@ int portal_group_add_listen(struct portal_group *pg, const char *listen, bool iser); int portal_group_set_filter(struct portal_group *pg, const char *filter); +int portal_group_set_offload(struct portal_group *pg, + const char *offload); int portal_group_set_redirection(struct portal_group *pg, const char *addr); @@ -312,6 +347,21 @@ void isns_register(struct isns *isns, struct isns *oldisns); void isns_check(struct isns *isns); void isns_deregister(struct isns *isns); +struct pport *pport_new(struct conf *conf, const char *name, + uint32_t ctl_port); +struct pport *pport_find(const struct conf *conf, const char *name); +struct pport *pport_copy(struct pport *pport, struct conf *conf); +void pport_delete(struct pport *pport); + +struct port *port_new(struct conf *conf, struct target *target, + struct portal_group *pg); +struct port *port_new_pp(struct conf *conf, struct target *target, + struct pport *pp); +struct port *port_find(const struct conf *conf, const char *name); +struct port *port_find_in_pg(const struct portal_group *pg, + const char *target); +void port_delete(struct port *port); + struct target *target_new(struct conf *conf, const char *name); void target_delete(struct target *target); struct target *target_find(struct conf *conf, @@ -319,13 +369,14 @@ struct target *target_find(struct conf *conf, int target_set_redirection(struct target *target, const char *addr); -struct lun *lun_new(struct target *target, int lun_id); +struct lun *lun_new(struct conf *conf, const char *name); void lun_delete(struct lun *lun); -struct lun *lun_find(const struct target *target, int lun_id); +struct lun *lun_find(const struct conf *conf, const char *name); void lun_set_backend(struct lun *lun, const char *value); void lun_set_blocksize(struct lun *lun, size_t value); void lun_set_device_id(struct lun *lun, const char *value); void lun_set_path(struct lun *lun, const char *value); +void lun_set_scsiname(struct lun *lun, const char *value); void lun_set_serial(struct lun *lun, const char *value); void lun_set_size(struct lun *lun, size_t value); void lun_set_ctl_lun(struct lun *lun, uint32_t value); @@ -343,8 +394,11 @@ int kernel_lun_add(struct lun *lun); int kernel_lun_resize(struct lun *lun); int kernel_lun_remove(struct lun *lun); void kernel_handoff(struct connection *conn); -int kernel_port_add(struct target *targ); -int kernel_port_remove(struct target *targ); +void kernel_limits(const char *offload, + size_t *max_data_segment_length); +int kernel_port_add(struct port *port); +int kernel_port_update(struct port *port); +int kernel_port_remove(struct port *port); void kernel_capsicate(void); #ifdef ICL_KERNEL_PROXY @@ -362,7 +416,6 @@ void keys_delete(struct keys *keys); void keys_load(struct keys *keys, const struct pdu *pdu); void keys_save(struct keys *keys, struct pdu *pdu); const char *keys_find(struct keys *keys, const char *name); -int keys_find_int(struct keys *keys, const char *name); void keys_add(struct keys *keys, const char *name, const char *value); void keys_add_int(struct keys *keys, diff --git a/usr.sbin/ctld/discovery.c b/usr.sbin/ctld/discovery.c index 01c9913..d7d843e 100644 --- a/usr.sbin/ctld/discovery.c +++ b/usr.sbin/ctld/discovery.c @@ -32,7 +32,6 @@ __FBSDID("$FreeBSD$"); #include <assert.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -65,16 +64,18 @@ text_receive(struct connection *conn) */ if ((bhstr->bhstr_flags & BHSTR_FLAGS_CONTINUE) != 0) log_errx(1, "received Text PDU with unsupported \"C\" flag"); - if (ntohl(bhstr->bhstr_cmdsn) < conn->conn_cmdsn) { + if (ISCSI_SNLT(ntohl(bhstr->bhstr_cmdsn), conn->conn_cmdsn)) { log_errx(1, "received Text PDU with decreasing CmdSN: " - "was %d, is %d", conn->conn_cmdsn, ntohl(bhstr->bhstr_cmdsn)); + "was %u, is %u", conn->conn_cmdsn, ntohl(bhstr->bhstr_cmdsn)); } if (ntohl(bhstr->bhstr_expstatsn) != conn->conn_statsn) { log_errx(1, "received Text PDU with wrong StatSN: " - "is %d, should be %d", ntohl(bhstr->bhstr_expstatsn), + "is %u, should be %u", ntohl(bhstr->bhstr_expstatsn), conn->conn_statsn); } conn->conn_cmdsn = ntohl(bhstr->bhstr_cmdsn); + if ((bhstr->bhstr_opcode & ISCSI_BHS_OPCODE_IMMEDIATE) == 0) + conn->conn_cmdsn++; return (request); } @@ -120,17 +121,19 @@ logout_receive(struct connection *conn) if ((bhslr->bhslr_reason & 0x7f) != BHSLR_REASON_CLOSE_SESSION) log_debugx("received Logout PDU with invalid reason 0x%x; " "continuing anyway", bhslr->bhslr_reason & 0x7f); - if (ntohl(bhslr->bhslr_cmdsn) < conn->conn_cmdsn) { + if (ISCSI_SNLT(ntohl(bhslr->bhslr_cmdsn), conn->conn_cmdsn)) { log_errx(1, "received Logout PDU with decreasing CmdSN: " - "was %d, is %d", conn->conn_cmdsn, + "was %u, is %u", conn->conn_cmdsn, ntohl(bhslr->bhslr_cmdsn)); } if (ntohl(bhslr->bhslr_expstatsn) != conn->conn_statsn) { log_errx(1, "received Logout PDU with wrong StatSN: " - "is %d, should be %d", ntohl(bhslr->bhslr_expstatsn), + "is %u, should be %u", ntohl(bhslr->bhslr_expstatsn), conn->conn_statsn); } conn->conn_cmdsn = ntohl(bhslr->bhslr_cmdsn); + if ((bhslr->bhslr_opcode & ISCSI_BHS_OPCODE_IMMEDIATE) == 0) + conn->conn_cmdsn++; return (request); } @@ -162,6 +165,7 @@ logout_new_response(struct pdu *request) static void discovery_add_target(struct keys *response_keys, const struct target *targ) { + struct port *port; struct portal *portal; char *buf; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; @@ -169,7 +173,10 @@ discovery_add_target(struct keys *response_keys, const struct target *targ) int ret; keys_add(response_keys, "TargetName", targ->t_name); - TAILQ_FOREACH(portal, &targ->t_portal_group->pg_portals, p_next) { + TAILQ_FOREACH(port, &targ->t_ports, p_ts) { + if (port->p_portal_group == NULL) + continue; + TAILQ_FOREACH(portal, &port->p_portal_group->pg_portals, p_next) { ai = portal->p_ai; ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), @@ -183,13 +190,13 @@ discovery_add_target(struct keys *response_keys, const struct target *targ) if (strcmp(hbuf, "0.0.0.0") == 0) continue; ret = asprintf(&buf, "%s:%s,%d", hbuf, sbuf, - targ->t_portal_group->pg_tag); + port->p_portal_group->pg_tag); break; case AF_INET6: if (strcmp(hbuf, "::") == 0) continue; ret = asprintf(&buf, "[%s]:%s,%d", hbuf, sbuf, - targ->t_portal_group->pg_tag); + port->p_portal_group->pg_tag); break; default: continue; @@ -198,19 +205,24 @@ discovery_add_target(struct keys *response_keys, const struct target *targ) log_err(1, "asprintf"); keys_add(response_keys, "TargetAddress", buf); free(buf); + } } } static bool discovery_target_filtered_out(const struct connection *conn, - const struct target *targ) + const struct port *port) { const struct auth_group *ag; const struct portal_group *pg; + const struct target *targ; const struct auth *auth; int error; - ag = targ->t_auth_group; + targ = port->p_target; + ag = port->p_auth_group; + if (ag == NULL) + ag = targ->t_auth_group; pg = conn->conn_portal->p_portal_group; assert(pg->pg_discovery_auth_group != PG_FILTER_UNKNOWN); @@ -265,8 +277,8 @@ discovery(struct connection *conn) { struct pdu *request, *response; struct keys *request_keys, *response_keys; + const struct port *port; const struct portal_group *pg; - const struct target *targ; const char *send_targets; pg = conn->conn_portal->p_portal_group; @@ -284,29 +296,23 @@ discovery(struct connection *conn) response_keys = keys_new(); if (strcmp(send_targets, "All") == 0) { - TAILQ_FOREACH(targ, &pg->pg_conf->conf_targets, t_next) { - if (targ->t_portal_group != pg) { - log_debugx("not returning target \"%s\"; " - "belongs to a different portal group", - targ->t_name); - continue; - } - if (discovery_target_filtered_out(conn, targ)) { + TAILQ_FOREACH(port, &pg->pg_ports, p_pgs) { + if (discovery_target_filtered_out(conn, port)) { /* Ignore this target. */ continue; } - discovery_add_target(response_keys, targ); + discovery_add_target(response_keys, port->p_target); } } else { - targ = target_find(pg->pg_conf, send_targets); - if (targ == NULL) { + port = port_find_in_pg(pg, send_targets); + if (port == NULL) { log_debugx("initiator requested information on unknown " "target \"%s\"; returning nothing", send_targets); } else { - if (discovery_target_filtered_out(conn, targ)) { + if (discovery_target_filtered_out(conn, port)) { /* Ignore this target. */ } else { - discovery_add_target(response_keys, targ); + discovery_add_target(response_keys, port->p_target); } } } diff --git a/usr.sbin/ctld/isns.c b/usr.sbin/ctld/isns.c index 2a7bd97..f7381a1 100644 --- a/usr.sbin/ctld/isns.c +++ b/usr.sbin/ctld/isns.c @@ -35,14 +35,8 @@ __FBSDID("$FreeBSD$"); #include <sys/endian.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <assert.h> -#include <ctype.h> -#include <errno.h> #include <netdb.h> -#include <signal.h> #include <stdbool.h> -#include <stdio.h> -#include <stdint.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -63,7 +57,7 @@ isns_req_alloc(void) req->ir_buflen = sizeof(struct isns_hdr); req->ir_usedlen = 0; req->ir_buf = calloc(req->ir_buflen, 1); - if (req == NULL) { + if (req->ir_buf == NULL) { free(req); log_err(1, "calloc"); return (NULL); diff --git a/usr.sbin/ctld/kernel.c b/usr.sbin/ctld/kernel.c index 219313f..95bc89c 100644 --- a/usr.sbin/ctld/kernel.c +++ b/usr.sbin/ctld/kernel.c @@ -114,17 +114,18 @@ struct cctl_lun { uint32_t blocksize; char *serial_number; char *device_id; - char *cfiscsi_target; - int cfiscsi_lun; + char *ctld_name; STAILQ_HEAD(,cctl_lun_nv) attr_list; STAILQ_ENTRY(cctl_lun) links; }; struct cctl_port { uint32_t port_id; - int cfiscsi_status; + char *port_name; + int cfiscsi_state; char *cfiscsi_target; uint16_t cfiscsi_portal_group_tag; + char *ctld_portal_group_name; STAILQ_HEAD(,cctl_lun_nv) attr_list; STAILQ_ENTRY(cctl_port) links; }; @@ -229,11 +230,9 @@ cctl_end_element(void *user_data, const char *name) } else if (strcmp(name, "device_id") == 0) { cur_lun->device_id = str; str = NULL; - } else if (strcmp(name, "cfiscsi_target") == 0) { - cur_lun->cfiscsi_target = str; + } else if (strcmp(name, "ctld_name") == 0) { + cur_lun->ctld_name = str; str = NULL; - } else if (strcmp(name, "cfiscsi_lun") == 0) { - cur_lun->cfiscsi_lun = strtoul(str, NULL, 0); } else if (strcmp(name, "lun") == 0) { devlist->cur_lun = NULL; } else if (strcmp(name, "ctllunlist") == 0) { @@ -332,13 +331,19 @@ cctl_end_pelement(void *user_data, const char *name) devlist->cur_sb[devlist->level] = NULL; devlist->level--; - if (strcmp(name, "cfiscsi_target") == 0) { + if (strcmp(name, "port_name") == 0) { + cur_port->port_name = str; + str = NULL; + } else if (strcmp(name, "cfiscsi_target") == 0) { cur_port->cfiscsi_target = str; str = NULL; - } else if (strcmp(name, "cfiscsi_status") == 0) { - cur_port->cfiscsi_status = strtoul(str, NULL, 0); + } else if (strcmp(name, "cfiscsi_state") == 0) { + cur_port->cfiscsi_state = strtoul(str, NULL, 0); } else if (strcmp(name, "cfiscsi_portal_group_tag") == 0) { cur_port->cfiscsi_portal_group_tag = strtoul(str, NULL, 0); + } else if (strcmp(name, "ctld_portal_group_name") == 0) { + cur_port->ctld_portal_group_name = str; + str = NULL; } else if (strcmp(name, "targ_port") == 0) { devlist->cur_port = NULL; } else if (strcmp(name, "ctlportlist") == 0) { @@ -376,6 +381,9 @@ conf_new_from_kernel(void) { struct conf *conf = NULL; struct target *targ; + struct portal_group *pg; + struct pport *pp; + struct port *cp; struct lun *cl; struct lun_option *lo; struct ctl_lun_list list; @@ -495,13 +503,25 @@ retry_port: STAILQ_FOREACH(port, &devlist.port_list, links) { if (port->cfiscsi_target == NULL) { - log_debugx("CTL port %ju wasn't managed by ctld; " - "ignoring", (uintmax_t)port->port_id); + log_debugx("CTL port %u \"%s\" wasn't managed by ctld; ", + port->port_id, port->port_name); + pp = pport_find(conf, port->port_name); + if (pp == NULL) { +#if 0 + log_debugx("found new kernel port %u \"%s\"", + port->port_id, port->port_name); +#endif + pp = pport_new(conf, port->port_name, port->port_id); + if (pp == NULL) { + log_warnx("pport_new failed"); + continue; + } + } continue; } - if (port->cfiscsi_status != 1) { + if (port->cfiscsi_state != 1) { log_debugx("CTL port %ju is not active (%d); ignoring", - (uintmax_t)port->port_id, port->cfiscsi_status); + (uintmax_t)port->port_id, port->cfiscsi_state); continue; } @@ -517,43 +537,52 @@ retry_port: continue; } } + + if (port->ctld_portal_group_name == NULL) + continue; + pg = portal_group_find(conf, port->ctld_portal_group_name); + if (pg == NULL) { +#if 0 + log_debugx("found new kernel portal group %s for CTL port %ld", + port->ctld_portal_group_name, port->port_id); +#endif + pg = portal_group_new(conf, port->ctld_portal_group_name); + if (pg == NULL) { + log_warnx("portal_group_new failed"); + continue; + } + } + pg->pg_tag = port->cfiscsi_portal_group_tag; + cp = port_new(conf, targ, pg); + if (cp == NULL) { + log_warnx("port_new failed"); + continue; + } + cp->p_ctl_port = port->port_id; } STAILQ_FOREACH(lun, &devlist.lun_list, links) { struct cctl_lun_nv *nv; - if (lun->cfiscsi_target == NULL) { + if (lun->ctld_name == NULL) { log_debugx("CTL lun %ju wasn't managed by ctld; " "ignoring", (uintmax_t)lun->lun_id); continue; } - targ = target_find(conf, lun->cfiscsi_target); - if (targ == NULL) { -#if 0 - log_debugx("found new kernel target %s for CTL lun %ld", - lun->cfiscsi_target, lun->lun_id); -#endif - targ = target_new(conf, lun->cfiscsi_target); - if (targ == NULL) { - log_warnx("target_new failed"); - continue; - } - } - - cl = lun_find(targ, lun->cfiscsi_lun); + cl = lun_find(conf, lun->ctld_name); if (cl != NULL) { - log_warnx("found CTL lun %ju, backing lun %d, target " - "%s, also backed by CTL lun %d; ignoring", - (uintmax_t) lun->lun_id, cl->l_lun, - cl->l_target->t_name, cl->l_ctl_lun); + log_warnx("found CTL lun %ju \"%s\", " + "also backed by CTL lun %d; ignoring", + (uintmax_t)lun->lun_id, lun->ctld_name, + cl->l_ctl_lun); continue; } - log_debugx("found CTL lun %ju, backing lun %d, target %s", - (uintmax_t)lun->lun_id, lun->cfiscsi_lun, lun->cfiscsi_target); + log_debugx("found CTL lun %ju \"%s\"", + (uintmax_t)lun->lun_id, lun->ctld_name); - cl = lun_new(targ, lun->cfiscsi_lun); + cl = lun_new(conf, lun->ctld_name); if (cl == NULL) { log_warnx("lun_new failed"); continue; @@ -574,9 +603,9 @@ retry_port: lo = lun_option_new(cl, nv->name, nv->value); if (lo == NULL) log_warnx("unable to add CTL lun option %s " - "for CTL lun %ju for lun %d, target %s", + "for CTL lun %ju \"%s\"", nv->name, (uintmax_t) lun->lun_id, - cl->l_lun, cl->l_target->t_name); + cl->l_name); } } @@ -599,7 +628,6 @@ kernel_lun_add(struct lun *lun) { struct lun_option *lo; struct ctl_lun_req req; - char *tmp; int error, i, num_options; bzero(&req, sizeof(req)); @@ -637,38 +665,17 @@ kernel_lun_add(struct lun *lun) } } - lo = lun_option_find(lun, "cfiscsi_target"); + lo = lun_option_find(lun, "ctld_name"); if (lo != NULL) { - lun_option_set(lo, lun->l_target->t_name); + lun_option_set(lo, lun->l_name); } else { - lo = lun_option_new(lun, "cfiscsi_target", - lun->l_target->t_name); + lo = lun_option_new(lun, "ctld_name", lun->l_name); assert(lo != NULL); } - asprintf(&tmp, "%d", lun->l_lun); - if (tmp == NULL) - log_errx(1, "asprintf"); - lo = lun_option_find(lun, "cfiscsi_lun"); - if (lo != NULL) { - lun_option_set(lo, tmp); - free(tmp); - } else { - lo = lun_option_new(lun, "cfiscsi_lun", tmp); - free(tmp); - assert(lo != NULL); - } - - asprintf(&tmp, "%s,lun,%d", lun->l_target->t_name, lun->l_lun); - if (tmp == NULL) - log_errx(1, "asprintf"); lo = lun_option_find(lun, "scsiname"); - if (lo != NULL) { - lun_option_set(lo, tmp); - free(tmp); - } else { - lo = lun_option_new(lun, "scsiname", tmp); - free(tmp); + if (lo == NULL && lun->l_scsiname != NULL) { + lo = lun_option_new(lun, "scsiname", lun->l_scsiname); assert(lo != NULL); } @@ -809,6 +816,11 @@ kernel_handoff(struct connection *conn) sizeof(req.data.handoff.initiator_isid)); strlcpy(req.data.handoff.target_name, conn->conn_target->t_name, sizeof(req.data.handoff.target_name)); + if (conn->conn_portal->p_portal_group->pg_offload != NULL) { + strlcpy(req.data.handoff.offload, + conn->conn_portal->p_portal_group->pg_offload, + sizeof(req.data.handoff.offload)); + } #ifdef ICL_KERNEL_PROXY if (proxy_mode) req.data.handoff.connection_id = conn->conn_socket; @@ -841,55 +853,126 @@ kernel_handoff(struct connection *conn) } } -int -kernel_port_add(struct target *targ) +void +kernel_limits(const char *offload, size_t *max_data_segment_length) { - struct ctl_port_entry entry; - struct ctl_req req; - char tagstr[16]; - int error; - uint32_t port_id = -1; + struct ctl_iscsi req; bzero(&req, sizeof(req)); - strlcpy(req.driver, "iscsi", sizeof(req.driver)); - req.reqtype = CTL_REQ_CREATE; - req.num_args = 4; - req.args = malloc(req.num_args * sizeof(*req.args)); - req.args[0].namelen = sizeof("port_id"); - req.args[0].name = __DECONST(char *, "port_id"); - req.args[0].vallen = sizeof(port_id); - req.args[0].value = &port_id; - req.args[0].flags = CTL_BEARG_WR; - str_arg(&req.args[1], "cfiscsi_target", targ->t_name); - snprintf(tagstr, sizeof(tagstr), "%d", targ->t_portal_group->pg_tag); - str_arg(&req.args[2], "cfiscsi_portal_group_tag", tagstr); - if (targ->t_alias) - str_arg(&req.args[3], "cfiscsi_target_alias", targ->t_alias); - else - req.num_args--; - error = ioctl(ctl_fd, CTL_PORT_REQ, &req); - free(req.args); - if (error != 0) { - log_warn("error issuing CTL_PORT_REQ ioctl"); - return (1); + req.type = CTL_ISCSI_LIMITS; + if (offload != NULL) { + strlcpy(req.data.limits.offload, offload, + sizeof(req.data.limits.offload)); } - if (req.status == CTL_LUN_ERROR) { - log_warnx("error returned from port creation request: %s", - req.error_str); - return (1); + if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) { + log_err(1, "error issuing CTL_ISCSI ioctl; " + "dropping connection"); } - if (req.status != CTL_LUN_OK) { - log_warnx("unknown port creation request status %d", - req.status); - return (1); + if (req.status != CTL_ISCSI_OK) { + log_errx(1, "error returned from CTL iSCSI limits request: " + "%s; dropping connection", req.error_str); } - bzero(&entry, sizeof(entry)); - entry.targ_port = port_id; + *max_data_segment_length = req.data.limits.data_segment_limit; + if (offload != NULL) { + log_debugx("MaxRecvDataSegment kernel limit for offload " + "\"%s\" is %zd", offload, *max_data_segment_length); + } else { + log_debugx("MaxRecvDataSegment kernel limit is %zd", + *max_data_segment_length); + } +} + +int +kernel_port_add(struct port *port) +{ + struct ctl_port_entry entry; + struct ctl_req req; + struct ctl_lun_map lm; + struct target *targ = port->p_target; + struct portal_group *pg = port->p_portal_group; + char tagstr[16]; + int error, i, n; + + /* Create iSCSI port. */ + if (port->p_portal_group) { + bzero(&req, sizeof(req)); + strlcpy(req.driver, "iscsi", sizeof(req.driver)); + req.reqtype = CTL_REQ_CREATE; + req.num_args = 5; + req.args = malloc(req.num_args * sizeof(*req.args)); + if (req.args == NULL) + log_err(1, "malloc"); + n = 0; + req.args[n].namelen = sizeof("port_id"); + req.args[n].name = __DECONST(char *, "port_id"); + req.args[n].vallen = sizeof(port->p_ctl_port); + req.args[n].value = &port->p_ctl_port; + req.args[n++].flags = CTL_BEARG_WR; + str_arg(&req.args[n++], "cfiscsi_target", targ->t_name); + snprintf(tagstr, sizeof(tagstr), "%d", pg->pg_tag); + str_arg(&req.args[n++], "cfiscsi_portal_group_tag", tagstr); + if (targ->t_alias) + str_arg(&req.args[n++], "cfiscsi_target_alias", targ->t_alias); + str_arg(&req.args[n++], "ctld_portal_group_name", pg->pg_name); + req.num_args = n; + error = ioctl(ctl_fd, CTL_PORT_REQ, &req); + free(req.args); + if (error != 0) { + log_warn("error issuing CTL_PORT_REQ ioctl"); + return (1); + } + if (req.status == CTL_LUN_ERROR) { + log_warnx("error returned from port creation request: %s", + req.error_str); + return (1); + } + if (req.status != CTL_LUN_OK) { + log_warnx("unknown port creation request status %d", + req.status); + return (1); + } + } else if (port->p_pport) { + port->p_ctl_port = port->p_pport->pp_ctl_port; + + if (strncmp(targ->t_name, "naa.", 4) == 0 && + strlen(targ->t_name) == 20) { + bzero(&entry, sizeof(entry)); + entry.port_type = CTL_PORT_NONE; + entry.targ_port = port->p_ctl_port; + entry.flags |= CTL_PORT_WWNN_VALID; + entry.wwnn = strtoull(targ->t_name + 4, NULL, 16); + if (ioctl(ctl_fd, CTL_SET_PORT_WWNS, &entry) == -1) + log_warn("CTL_SET_PORT_WWNS ioctl failed"); + } + } + /* Explicitly enable mapping to block any access except allowed. */ + lm.port = port->p_ctl_port; + lm.plun = UINT32_MAX; + lm.lun = 0; + error = ioctl(ctl_fd, CTL_LUN_MAP, &lm); + if (error != 0) + log_warn("CTL_LUN_MAP ioctl failed"); + + /* Map configured LUNs */ + for (i = 0; i < MAX_LUNS; i++) { + if (targ->t_luns[i] == NULL) + continue; + lm.port = port->p_ctl_port; + lm.plun = i; + lm.lun = targ->t_luns[i]->l_ctl_lun; + error = ioctl(ctl_fd, CTL_LUN_MAP, &lm); + if (error != 0) + log_warn("CTL_LUN_MAP ioctl failed"); + } + + /* Enable port */ + bzero(&entry, sizeof(entry)); + entry.targ_port = port->p_ctl_port; error = ioctl(ctl_fd, CTL_ENABLE_PORT, &entry); if (error != 0) { log_warn("CTL_ENABLE_PORT ioctl failed"); @@ -900,44 +983,84 @@ kernel_port_add(struct target *targ) } int -kernel_port_remove(struct target *targ) +kernel_port_update(struct port *port) +{ + struct ctl_lun_map lm; + struct target *targ = port->p_target; + int error, i; + + /* Map configured LUNs and unmap others */ + for (i = 0; i < MAX_LUNS; i++) { + lm.port = port->p_ctl_port; + lm.plun = i; + if (targ->t_luns[i] == NULL) + lm.lun = UINT32_MAX; + else + lm.lun = targ->t_luns[i]->l_ctl_lun; + error = ioctl(ctl_fd, CTL_LUN_MAP, &lm); + if (error != 0) + log_warn("CTL_LUN_MAP ioctl failed"); + } + return (0); +} + +int +kernel_port_remove(struct port *port) { + struct ctl_port_entry entry; + struct ctl_lun_map lm; struct ctl_req req; char tagstr[16]; + struct target *targ = port->p_target; + struct portal_group *pg = port->p_portal_group; int error; - bzero(&req, sizeof(req)); - strlcpy(req.driver, "iscsi", sizeof(req.driver)); - req.reqtype = CTL_REQ_REMOVE; - req.num_args = 2; - req.args = malloc(req.num_args * sizeof(*req.args)); - str_arg(&req.args[0], "cfiscsi_target", targ->t_name); - if (targ->t_portal_group) { - snprintf(tagstr, sizeof(tagstr), "%d", - targ->t_portal_group->pg_tag); - str_arg(&req.args[1], "cfiscsi_portal_group_tag", tagstr); - } else - req.num_args--; - - error = ioctl(ctl_fd, CTL_PORT_REQ, &req); - free(req.args); + /* Disable port */ + bzero(&entry, sizeof(entry)); + entry.targ_port = port->p_ctl_port; + error = ioctl(ctl_fd, CTL_DISABLE_PORT, &entry); if (error != 0) { - log_warn("error issuing CTL_PORT_REQ ioctl"); - return (1); - } - - if (req.status == CTL_LUN_ERROR) { - log_warnx("error returned from port removal request: %s", - req.error_str); - return (1); + log_warn("CTL_DISABLE_PORT ioctl failed"); + return (-1); } - if (req.status != CTL_LUN_OK) { - log_warnx("unknown port removal request status %d", - req.status); - return (1); + /* Remove iSCSI port. */ + if (port->p_portal_group) { + bzero(&req, sizeof(req)); + strlcpy(req.driver, "iscsi", sizeof(req.driver)); + req.reqtype = CTL_REQ_REMOVE; + req.num_args = 2; + req.args = malloc(req.num_args * sizeof(*req.args)); + if (req.args == NULL) + log_err(1, "malloc"); + str_arg(&req.args[0], "cfiscsi_target", targ->t_name); + snprintf(tagstr, sizeof(tagstr), "%d", pg->pg_tag); + str_arg(&req.args[1], "cfiscsi_portal_group_tag", tagstr); + error = ioctl(ctl_fd, CTL_PORT_REQ, &req); + free(req.args); + if (error != 0) { + log_warn("error issuing CTL_PORT_REQ ioctl"); + return (1); + } + if (req.status == CTL_LUN_ERROR) { + log_warnx("error returned from port removal request: %s", + req.error_str); + return (1); + } + if (req.status != CTL_LUN_OK) { + log_warnx("unknown port removal request status %d", + req.status); + return (1); + } + } else { + /* Disable LUN mapping. */ + lm.port = port->p_ctl_port; + lm.plun = UINT32_MAX; + lm.lun = UINT32_MAX; + error = ioctl(ctl_fd, CTL_LUN_MAP, &lm); + if (error != 0) + log_warn("CTL_LUN_MAP ioctl failed"); } - return (0); } diff --git a/usr.sbin/ctld/keys.c b/usr.sbin/ctld/keys.c index 6a9ad02..f339a10 100644 --- a/usr.sbin/ctld/keys.c +++ b/usr.sbin/ctld/keys.c @@ -32,7 +32,6 @@ __FBSDID("$FreeBSD$"); #include <assert.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -161,26 +160,6 @@ keys_find(struct keys *keys, const char *name) return (NULL); } -int -keys_find_int(struct keys *keys, const char *name) -{ - const char *str; - char *endptr; - int num; - - str = keys_find(keys, name); - if (str == NULL) - return (-1); - - num = strtoul(str, &endptr, 10); - if (*endptr != '\0') { - log_debugx("invalid numeric value \"%s\"", str); - return (-1); - } - - return (num); -} - void keys_add(struct keys *keys, const char *name, const char *value) { diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c index fc41f51..c6b83d9 100644 --- a/usr.sbin/ctld/login.c +++ b/usr.sbin/ctld/login.c @@ -33,8 +33,6 @@ __FBSDID("$FreeBSD$"); #include <assert.h> #include <stdbool.h> -#include <stdint.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -127,17 +125,17 @@ login_receive(struct connection *conn, bool initial) log_errx(1, "received Login PDU with unsupported " "Version-min 0x%x", bhslr->bhslr_version_min); } - if (ntohl(bhslr->bhslr_cmdsn) < conn->conn_cmdsn) { + if (ISCSI_SNLT(ntohl(bhslr->bhslr_cmdsn), conn->conn_cmdsn)) { login_send_error(request, 0x02, 0x05); log_errx(1, "received Login PDU with decreasing CmdSN: " - "was %d, is %d", conn->conn_cmdsn, + "was %u, is %u", conn->conn_cmdsn, ntohl(bhslr->bhslr_cmdsn)); } if (initial == false && ntohl(bhslr->bhslr_expstatsn) != conn->conn_statsn) { login_send_error(request, 0x02, 0x05); log_errx(1, "received Login PDU with wrong ExpStatSN: " - "is %d, should be %d", ntohl(bhslr->bhslr_expstatsn), + "is %u, should be %u", ntohl(bhslr->bhslr_expstatsn), conn->conn_statsn); } conn->conn_cmdsn = ntohl(bhslr->bhslr_cmdsn); @@ -453,7 +451,8 @@ static void login_negotiate_key(struct pdu *request, const char *name, const char *value, bool skipped_security, struct keys *response_keys) { - int which, tmp; + int which; + size_t tmp; struct connection *conn; conn = request->pdu_connection; @@ -552,10 +551,10 @@ login_negotiate_key(struct pdu *request, const char *name, log_errx(1, "received invalid " "MaxRecvDataSegmentLength"); } - if (tmp > MAX_DATA_SEGMENT_LENGTH) { + if (tmp > conn->conn_data_segment_limit) { log_debugx("capping MaxRecvDataSegmentLength " - "from %d to %d", tmp, MAX_DATA_SEGMENT_LENGTH); - tmp = MAX_DATA_SEGMENT_LENGTH; + "from %zd to %zd", tmp, conn->conn_data_segment_limit); + tmp = conn->conn_data_segment_limit; } conn->conn_max_data_segment_length = tmp; keys_add_int(response_keys, name, tmp); @@ -566,7 +565,7 @@ login_negotiate_key(struct pdu *request, const char *name, log_errx(1, "received invalid MaxBurstLength"); } if (tmp > MAX_BURST_LENGTH) { - log_debugx("capping MaxBurstLength from %d to %d", + log_debugx("capping MaxBurstLength from %zd to %d", tmp, MAX_BURST_LENGTH); tmp = MAX_BURST_LENGTH; } @@ -579,10 +578,10 @@ login_negotiate_key(struct pdu *request, const char *name, log_errx(1, "received invalid " "FirstBurstLength"); } - if (tmp > MAX_DATA_SEGMENT_LENGTH) { - log_debugx("capping FirstBurstLength from %d to %d", - tmp, MAX_DATA_SEGMENT_LENGTH); - tmp = MAX_DATA_SEGMENT_LENGTH; + if (tmp > conn->conn_data_segment_limit) { + log_debugx("capping FirstBurstLength from %zd to %zd", + tmp, conn->conn_data_segment_limit); + tmp = conn->conn_data_segment_limit; } /* * We don't pass the value to the kernel; it only enforces @@ -680,6 +679,18 @@ login_negotiate(struct connection *conn, struct pdu *request) int i; bool redirected, skipped_security; + if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) { + /* + * Query the kernel for MaxDataSegmentLength it can handle. + * In case of offload, it depends on hardware capabilities. + */ + assert(conn->conn_target != NULL); + kernel_limits(conn->conn_portal->p_portal_group->pg_offload, + &conn->conn_data_segment_limit); + } else { + conn->conn_data_segment_limit = MAX_DATA_SEGMENT_LENGTH; + } + if (request == NULL) { log_debugx("beginning operational parameter negotiation; " "waiting for Login PDU"); @@ -789,9 +800,6 @@ login(struct connection *conn) } conn->conn_initiator_name = checked_strdup(initiator_name); log_set_peer_name(conn->conn_initiator_name); - /* - * XXX: This doesn't work (does nothing) because of Capsicum. - */ setproctitle("%s (%s)", conn->conn_initiator_addr, conn->conn_initiator_name); redirected = login_portal_redirect(conn, request); @@ -827,19 +835,22 @@ login(struct connection *conn) log_errx(1, "received Login PDU without TargetName"); } - conn->conn_target = target_find(pg->pg_conf, target_name); - if (conn->conn_target == NULL) { + conn->conn_port = port_find_in_pg(pg, target_name); + if (conn->conn_port == NULL) { login_send_error(request, 0x02, 0x03); log_errx(1, "requested target \"%s\" not found", target_name); } + conn->conn_target = conn->conn_port->p_target; } /* * At this point we know what kind of authentication we need. */ if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) { - ag = conn->conn_target->t_auth_group; + ag = conn->conn_port->p_auth_group; + if (ag == NULL) + ag = conn->conn_target->t_auth_group; if (ag->ag_name != NULL) { log_debugx("initiator requests to connect " "to target \"%s\"; auth-group \"%s\"", diff --git a/usr.sbin/ctld/parse.y b/usr.sbin/ctld/parse.y index a6519dd..cfc202c 100644 --- a/usr.sbin/ctld/parse.y +++ b/usr.sbin/ctld/parse.y @@ -35,7 +35,6 @@ #include <sys/stat.h> #include <assert.h> #include <stdio.h> -#include <stdint.h> #include <stdlib.h> #include <string.h> @@ -60,8 +59,8 @@ extern void yyrestart(FILE *); %token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL %token CLOSING_BRACKET DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP DISCOVERY_FILTER %token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT -%token LISTEN LISTEN_ISER LUN MAXPROC OPENING_BRACKET OPTION -%token PATH PIDFILE PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR +%token LISTEN LISTEN_ISER LUN MAXPROC OFFLOAD OPENING_BRACKET OPTION +%token PATH PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR %token TARGET TIMEOUT %union @@ -99,6 +98,8 @@ statement: | portal_group | + lun + | target ; @@ -340,6 +341,8 @@ portal_group_entry: | portal_group_listen_iser | + portal_group_offload + | portal_group_redirect ; @@ -396,6 +399,17 @@ portal_group_listen_iser: LISTEN_ISER STR } ; +portal_group_offload: OFFLOAD STR + { + int error; + + error = portal_group_set_offload(portal_group, $2); + free($2); + if (error != 0) + return (1); + } + ; + portal_group_redirect: REDIRECT STR { int error; @@ -407,6 +421,22 @@ portal_group_redirect: REDIRECT STR } ; +lun: LUN lun_name + OPENING_BRACKET lun_entries CLOSING_BRACKET + { + lun = NULL; + } + ; + +lun_name: STR + { + lun = lun_new(conf, $1); + free($1); + if (lun == NULL) + return (1); + } + ; + target: TARGET target_name OPENING_BRACKET target_entries CLOSING_BRACKET { @@ -447,9 +477,13 @@ target_entry: | target_portal_group | + target_port + | target_redirect | target_lun + | + target_lun_ref ; target_alias: ALIAS STR @@ -632,21 +666,88 @@ target_initiator_portal: INITIATOR_PORTAL STR } ; -target_portal_group: PORTAL_GROUP STR +target_portal_group: PORTAL_GROUP STR STR { - if (target->t_portal_group != NULL) { - log_warnx("portal-group for target \"%s\" " - "specified more than once", target->t_name); + struct portal_group *tpg; + struct auth_group *tag; + struct port *tp; + + tpg = portal_group_find(conf, $2); + if (tpg == NULL) { + log_warnx("unknown portal-group \"%s\" for target " + "\"%s\"", $2, target->t_name); + free($2); + free($3); + return (1); + } + tag = auth_group_find(conf, $3); + if (tag == NULL) { + log_warnx("unknown auth-group \"%s\" for target " + "\"%s\"", $3, target->t_name); + free($2); + free($3); + return (1); + } + tp = port_new(conf, target, tpg); + if (tp == NULL) { + log_warnx("can't link portal-group \"%s\" to target " + "\"%s\"", $2, target->t_name); free($2); return (1); } - target->t_portal_group = portal_group_find(conf, $2); - if (target->t_portal_group == NULL) { + tp->p_auth_group = tag; + free($2); + free($3); + } + | PORTAL_GROUP STR + { + struct portal_group *tpg; + struct port *tp; + + tpg = portal_group_find(conf, $2); + if (tpg == NULL) { log_warnx("unknown portal-group \"%s\" for target " "\"%s\"", $2, target->t_name); free($2); return (1); } + tp = port_new(conf, target, tpg); + if (tp == NULL) { + log_warnx("can't link portal-group \"%s\" to target " + "\"%s\"", $2, target->t_name); + free($2); + return (1); + } + free($2); + } + ; + +target_port: PORT STR + { + struct pport *pp; + struct port *tp; + + pp = pport_find(conf, $2); + if (pp == NULL) { + log_warnx("unknown port \"%s\" for target \"%s\"", + $2, target->t_name); + free($2); + return (1); + } + if (!TAILQ_EMPTY(&pp->pp_ports)) { + log_warnx("can't link port \"%s\" to target \"%s\", " + "port already linked to some target", + $2, target->t_name); + free($2); + return (1); + } + tp = port_new_pp(conf, target, pp); + if (tp == NULL) { + log_warnx("can't link port \"%s\" to target \"%s\"", + $2, target->t_name); + free($2); + return (1); + } free($2); } ; @@ -672,6 +773,8 @@ target_lun: LUN lun_number lun_number: STR { uint64_t tmp; + int ret; + char *name; if (expand_number($1, &tmp) != 0) { yyerror("invalid numeric value"); @@ -679,9 +782,36 @@ lun_number: STR return (1); } - lun = lun_new(target, tmp); + ret = asprintf(&name, "%s,lun,%ju", target->t_name, tmp); + if (ret <= 0) + log_err(1, "asprintf"); + lun = lun_new(conf, name); + if (lun == NULL) + return (1); + + lun_set_scsiname(lun, name); + target->t_luns[tmp] = lun; + } + ; + +target_lun_ref: LUN STR STR + { + uint64_t tmp; + + if (expand_number($2, &tmp) != 0) { + yyerror("invalid numeric value"); + free($2); + free($3); + return (1); + } + free($2); + + lun = lun_find(conf, $3); + free($3); if (lun == NULL) return (1); + + target->t_luns[tmp] = lun; } ; @@ -711,9 +841,9 @@ lun_entry: lun_backend: BACKEND STR { if (lun->l_backend != NULL) { - log_warnx("backend for lun %d, target \"%s\" " + log_warnx("backend for lun \"%s\" " "specified more than once", - lun->l_lun, target->t_name); + lun->l_name); free($2); return (1); } @@ -733,9 +863,9 @@ lun_blocksize: BLOCKSIZE STR } if (lun->l_blocksize != 0) { - log_warnx("blocksize for lun %d, target \"%s\" " + log_warnx("blocksize for lun \"%s\" " "specified more than once", - lun->l_lun, target->t_name); + lun->l_name); return (1); } lun_set_blocksize(lun, tmp); @@ -745,9 +875,9 @@ lun_blocksize: BLOCKSIZE STR lun_device_id: DEVICE_ID STR { if (lun->l_device_id != NULL) { - log_warnx("device_id for lun %d, target \"%s\" " + log_warnx("device_id for lun \"%s\" " "specified more than once", - lun->l_lun, target->t_name); + lun->l_name); free($2); return (1); } @@ -771,9 +901,9 @@ lun_option: OPTION STR STR lun_path: PATH STR { if (lun->l_path != NULL) { - log_warnx("path for lun %d, target \"%s\" " + log_warnx("path for lun \"%s\" " "specified more than once", - lun->l_lun, target->t_name); + lun->l_name); free($2); return (1); } @@ -785,9 +915,9 @@ lun_path: PATH STR lun_serial: SERIAL STR { if (lun->l_serial != NULL) { - log_warnx("serial for lun %d, target \"%s\" " + log_warnx("serial for lun \"%s\" " "specified more than once", - lun->l_lun, target->t_name); + lun->l_name); free($2); return (1); } @@ -807,9 +937,9 @@ lun_size: SIZE STR } if (lun->l_size != 0) { - log_warnx("size for lun %d, target \"%s\" " + log_warnx("size for lun \"%s\" " "specified more than once", - lun->l_lun, target->t_name); + lun->l_name); return (1); } lun_set_size(lun, tmp); @@ -854,16 +984,20 @@ check_perms(const char *path) } struct conf * -conf_new_from_file(const char *path) +conf_new_from_file(const char *path, struct conf *oldconf) { struct auth_group *ag; struct portal_group *pg; + struct pport *pp; int error; log_debugx("obtaining configuration from %s", path); conf = conf_new(); + TAILQ_FOREACH(pp, &oldconf->conf_pports, pp_next) + pport_copy(pp, conf); + ag = auth_group_new(conf, "default"); assert(ag != NULL); diff --git a/usr.sbin/ctld/pdu.c b/usr.sbin/ctld/pdu.c index c3181ac..be3598e 100644 --- a/usr.sbin/ctld/pdu.c +++ b/usr.sbin/ctld/pdu.c @@ -34,8 +34,6 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> #include <sys/uio.h> #include <assert.h> -#include <stdint.h> -#include <stdio.h> #include <stdlib.h> #include <unistd.h> diff --git a/usr.sbin/ctld/token.l b/usr.sbin/ctld/token.l index d4bf823..54b803b 100644 --- a/usr.sbin/ctld/token.l +++ b/usr.sbin/ctld/token.l @@ -34,7 +34,6 @@ #include <stdint.h> #include <string.h> -#include "ctld.h" #include "y.tab.h" int lineno; @@ -65,12 +64,14 @@ listen { return LISTEN; } listen-iser { return LISTEN_ISER; } lun { return LUN; } maxproc { return MAXPROC; } +offload { return OFFLOAD; } option { return OPTION; } path { return PATH; } pidfile { return PIDFILE; } isns-server { return ISNS_SERVER; } isns-period { return ISNS_PERIOD; } isns-timeout { return ISNS_TIMEOUT; } +port { return PORT; } portal-group { return PORTAL_GROUP; } redirect { return REDIRECT; } serial { return SERIAL; } diff --git a/usr.sbin/ctm/ctm/Makefile b/usr.sbin/ctm/ctm/Makefile index cc2c9b9..dd27ed2 100644 --- a/usr.sbin/ctm/ctm/Makefile +++ b/usr.sbin/ctm/ctm/Makefile @@ -14,8 +14,7 @@ SRCS= ctm.c ctm_input.c ctm_pass1.c ctm_pass2.c ctm_pass3.c \ NOTYET= ctm_ed.c -LDADD= -lmd -DPADD= ${LIBMD} +LIBADD= md WARNS?= 2 diff --git a/usr.sbin/ctm/mkCTM/Makefile b/usr.sbin/ctm/mkCTM/Makefile index 745956c..8194dd7 100644 --- a/usr.sbin/ctm/mkCTM/Makefile +++ b/usr.sbin/ctm/mkCTM/Makefile @@ -3,8 +3,7 @@ PROG= mkctm MAN= -DPADD= ${LIBMD} -LDADD= -lmd +LIBADD= md test: mkctm rm -f tst.out* diff --git a/usr.sbin/daemon/Makefile b/usr.sbin/daemon/Makefile index 2def803..eb0d502 100644 --- a/usr.sbin/daemon/Makefile +++ b/usr.sbin/daemon/Makefile @@ -3,7 +3,6 @@ PROG= daemon MAN= daemon.8 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/dconschat/Makefile b/usr.sbin/dconschat/Makefile index 2836a66..198c5cc 100644 --- a/usr.sbin/dconschat/Makefile +++ b/usr.sbin/dconschat/Makefile @@ -5,8 +5,7 @@ MAN= dconschat.8 CFLAGS+= -I${.CURDIR}/../../sys -DPADD= ${LIBKVM} -LDADD= -lkvm +LIBADD= kvm WARNS?= 1 diff --git a/usr.sbin/devctl/Makefile b/usr.sbin/devctl/Makefile new file mode 100644 index 0000000..a7deb37 --- /dev/null +++ b/usr.sbin/devctl/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +PROG= devctl +MAN= devctl.8 + +LIBADD= devctl + +.include <bsd.prog.mk> diff --git a/usr.sbin/devctl/devctl.8 b/usr.sbin/devctl/devctl.8 new file mode 100644 index 0000000..77c803a --- /dev/null +++ b/usr.sbin/devctl/devctl.8 @@ -0,0 +1,137 @@ +.\" +.\" Copyright (c) 2015 John Baldwin <jhb@FreeBSD.org> +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd February 5, 2015 +.Dt DEVCTL 8 +.Os +.Sh NAME +.Nm devctl +.Nd device control utility +.Sh SYNOPSIS +.Nm +.Cm attach +.Ar device +.Nm +.Cm detach +.Op Fl f +.Ar device +.Nm +.Cm disable +.Op Fl f +.Ar device +.Nm +.Cm enable +.Ar device +.Nm +.Cm suspend +.Ar device +.Nm +.Cm resume +.Ar device +.Nm +.Cm set driver +.Op Fl f +.Ar device driver +.Sh DESCRIPTION +The +.Nm +utility adjusts the state of individual devices in the kernel's +internal device hierarchy. +Each invocation of +.Nm +consists of a single command followed by command-specific arguments. +Each command operates on a single device specified via the +.Ar device +argument. +The +.Ar device +may be specified either as the name of an existing device or as a +bus-specific address. +More details on supported address formats can be found in +.Xr devctl 3 . +.Pp +The following commands are supported: +.Bl -tag -width indent +.It Cm attach Ar device +Force the kernel to re-probe the device. +If a suitable driver is found, +it is attached to the device. +.It Xo Cm detach +.Op Fl f +.Ar device +.Xc +Detach the device from its current device driver. +If the +.Fl f +flag is specified, +the device driver will be detached even if the device is busy. +.It Xo Cm disable +.Op Fl f +.Ar device +.Xc +Disable a device. +If the device is currently attached to a device driver, +the device driver will be detached from the device, +but the device will retain its current name. +If the +.Fl f +flag is specified, +the device driver will be detached even if the device is busy. +.It Cm enable Ar device +Enable a device. +The device will probe and attach if a suitable device driver is found. +Note that this can re-enable a device disabled at boot time via a +loader tunable. +.It Cm suspend Ar device +Suspend a device. +This may include placing the device in a reduced power state. +.It Cm resume device +Resume a suspended device to a fully working state. +.It Xo Cm set driver +.Op Fl f +.Ar device driver +.Xc +Force the device to use a device driver named +.Ar driver . +If the device is already attached to a device driver and the +.Fl f +flag is specified, +the device will be detached from its current device driver before it is +attached to the new device driver. +If the device is already attached to a device driver and the +.Fl f +flag is not specified, +the device will not be changed. +.El +.Sh SEE ALSO +.Xr devctl 3 , +.Xr devinfo 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 11.0 . diff --git a/usr.sbin/devctl/devctl.c b/usr.sbin/devctl/devctl.c new file mode 100644 index 0000000..076c650 --- /dev/null +++ b/usr.sbin/devctl/devctl.c @@ -0,0 +1,282 @@ +/*- + * Copyright (c) 2014 John Baldwin <jhb@FreeBSD.org> + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/linker_set.h> +#include <devctl.h> +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> + +struct devctl_command { + const char *name; + int (*handler)(int ac, char **av); +}; + +#define DEVCTL_DATASET(name) devctl_ ## name ## _table + +#define DEVCTL_COMMAND(set, name, function) \ + static struct devctl_command function ## _devctl_command = \ + { #name, function }; \ + DATA_SET(DEVCTL_DATASET(set), function ## _devctl_command) + +#define DEVCTL_TABLE(set, name) \ + SET_DECLARE(DEVCTL_DATASET(name), struct devctl_command); \ + \ + static int \ + devctl_ ## name ## _table_handler(int ac, char **av) \ + { \ + return (devctl_table_handler(SET_BEGIN(DEVCTL_DATASET(name)), \ + SET_LIMIT(DEVCTL_DATASET(name)), ac, av)); \ + } \ + DEVCTL_COMMAND(set, name, devctl_ ## name ## _table_handler) + +static int devctl_table_handler(struct devctl_command **start, + struct devctl_command **end, int ac, char **av); + +SET_DECLARE(DEVCTL_DATASET(top), struct devctl_command); + +DEVCTL_TABLE(top, set); + +static void +usage(void) +{ + fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", + "usage: devctl attach device", + " devctl detach [-f] device", + " devctl disable [-f] device", + " devctl enable device", + " devctl suspend device", + " devctl resume device", + " devctl set driver [-f] device driver"); + exit(1); +} + +static int +devctl_table_handler(struct devctl_command **start, + struct devctl_command **end, int ac, char **av) +{ + struct devctl_command **cmd; + + if (ac < 2) { + warnx("The %s command requires a sub-command.", av[0]); + return (EINVAL); + } + for (cmd = start; cmd < end; cmd++) { + if (strcmp((*cmd)->name, av[1]) == 0) + return ((*cmd)->handler(ac - 1, av + 1)); + } + + warnx("%s is not a valid sub-command of %s.", av[1], av[0]); + return (ENOENT); +} + +static int +help(int ac __unused, char **av __unused) +{ + + usage(); + return (0); +} +DEVCTL_COMMAND(top, help, help); + +static int +attach(int ac, char **av) +{ + + if (ac != 2) + usage(); + if (devctl_attach(av[1]) < 0) + err(1, "Failed to attach %s", av[1]); + return (0); +} +DEVCTL_COMMAND(top, attach, attach); + +static void +detach_usage(void) +{ + + fprintf(stderr, "usage: devctl detach [-f] device\n"); + exit(1); +} + +static int +detach(int ac, char **av) +{ + bool force; + int ch; + + force = false; + while ((ch = getopt(ac, av, "f")) != -1) + switch (ch) { + case 'f': + force = true; + break; + default: + detach_usage(); + } + ac -= optind; + av += optind; + + if (ac != 1) + detach_usage(); + if (devctl_detach(av[0], force) < 0) + err(1, "Failed to detach %s", av[0]); + return (0); +} +DEVCTL_COMMAND(top, detach, detach); + +static void +disable_usage(void) +{ + + fprintf(stderr, "usage: devctl disable [-f] device\n"); + exit(1); +} + +static int +disable(int ac, char **av) +{ + bool force; + int ch; + + force = false; + while ((ch = getopt(ac, av, "f")) != -1) + switch (ch) { + case 'f': + force = true; + break; + default: + disable_usage(); + } + ac -= optind; + av += optind; + + if (ac != 1) + disable_usage(); + if (devctl_disable(av[0], force) < 0) + err(1, "Failed to disable %s", av[0]); + return (0); +} +DEVCTL_COMMAND(top, disable, disable); + +static int +enable(int ac, char **av) +{ + + if (ac != 2) + usage(); + if (devctl_enable(av[1]) < 0) + err(1, "Failed to enable %s", av[1]); + return (0); +} +DEVCTL_COMMAND(top, enable, enable); + +static int +suspend(int ac, char **av) +{ + + if (ac != 2) + usage(); + if (devctl_suspend(av[1]) < 0) + err(1, "Failed to suspend %s", av[1]); + return (0); +} +DEVCTL_COMMAND(top, suspend, suspend); + +static int +resume(int ac, char **av) +{ + + if (ac != 2) + usage(); + if (devctl_resume(av[1]) < 0) + err(1, "Failed to resume %s", av[1]); + return (0); +} +DEVCTL_COMMAND(top, resume, resume); + +static void +set_driver_usage(void) +{ + + fprintf(stderr, "usage: devctl set driver [-f] device driver\n"); + exit(1); +} + +static int +set_driver(int ac, char **av) +{ + bool force; + int ch; + + force = false; + while ((ch = getopt(ac, av, "f")) != -1) + switch (ch) { + case 'f': + force = true; + break; + default: + set_driver_usage(); + } + ac -= optind; + av += optind; + + if (ac != 2) + set_driver_usage(); + if (devctl_set_driver(av[0], av[1], force) < 0) + err(1, "Failed to set %s driver to %s", av[0], av[1]); + return (0); +} +DEVCTL_COMMAND(set, driver, set_driver); + +int +main(int ac, char *av[]) +{ + struct devctl_command **cmd; + + if (ac == 1) + usage(); + ac--; + av++; + + SET_FOREACH(cmd, DEVCTL_DATASET(top)) { + if (strcmp((*cmd)->name, av[0]) == 0) { + if ((*cmd)->handler(ac, av) != 0) + return (1); + else + return (0); + } + } + warnx("Unknown command %s.", av[0]); + return (1); +} diff --git a/usr.sbin/devinfo/Makefile b/usr.sbin/devinfo/Makefile index 2a2301b..681c819 100644 --- a/usr.sbin/devinfo/Makefile +++ b/usr.sbin/devinfo/Makefile @@ -3,7 +3,6 @@ PROG= devinfo MAN= devinfo.8 -DPADD= ${LIBDEVINFO} -LDADD= -ldevinfo +LIBADD= devinfo .include <bsd.prog.mk> diff --git a/usr.sbin/devinfo/devinfo.c b/usr.sbin/devinfo/devinfo.c index 32d2932..40f2b0b 100644 --- a/usr.sbin/devinfo/devinfo.c +++ b/usr.sbin/devinfo/devinfo.c @@ -146,6 +146,10 @@ print_device(struct devinfo_dev *dev, void *arg) printf(" pnpinfo %s", dev->dd_pnpinfo); if (vflag && *dev->dd_location) printf(" at %s", dev->dd_location); + if (!(dev->dd_flags & DF_ENABLED)) + printf(" (disabled)"); + else if (dev->dd_flags & DF_SUSPENDED) + printf(" (suspended)"); printf("\n"); if (rflag) { ia.indent = indent + 4; diff --git a/usr.sbin/diskinfo/Makefile b/usr.sbin/diskinfo/Makefile index b16b933..41c52da 100644 --- a/usr.sbin/diskinfo/Makefile +++ b/usr.sbin/diskinfo/Makefile @@ -3,8 +3,7 @@ PROG= diskinfo MAN= diskinfo.8 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/editmap/Makefile b/usr.sbin/editmap/Makefile index 92d8392..20d86ab 100644 --- a/usr.sbin/editmap/Makefile +++ b/usr.sbin/editmap/Makefile @@ -12,17 +12,7 @@ CFLAGS+= -DNEWDB -DNOT_SENDMAIL WARNS?= 2 -LIBSMDIR= ${.OBJDIR}/../../lib/libsm -LIBSM= ${LIBSMDIR}/libsm.a - -LIBSMDBDIR= ${.OBJDIR}/../../lib/libsmdb -LIBSMDB= ${LIBSMDBDIR}/libsmdb.a - -LIBSMUTILDIR= ${.OBJDIR}/../../lib/libsmutil -LIBSMUTIL= ${LIBSMUTILDIR}/libsmutil.a - -DPADD= ${LIBSMDB} ${LIBSMUTIL} ${LIBSM} -LDADD= ${LIBSMDB} ${LIBSMUTIL} ${LIBSM} +LIBADD= smdb smutil sm SRCS+= sm_os.h CLEANFILES+=sm_os.h diff --git a/usr.sbin/edquota/Makefile b/usr.sbin/edquota/Makefile index 1196e47..83f06d0 100644 --- a/usr.sbin/edquota/Makefile +++ b/usr.sbin/edquota/Makefile @@ -7,7 +7,6 @@ MAN= edquota.8 CSTD= gnu99 WARNS?= 4 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/etcupdate/etcupdate.8 b/usr.sbin/etcupdate/etcupdate.8 index 1966179..c5a74f3 100644 --- a/usr.sbin/etcupdate/etcupdate.8 +++ b/usr.sbin/etcupdate/etcupdate.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2010-2013 Advanced Computing Technologies LLC +.\" Copyright (c) 2010-2013 Hudson River Trading LLC .\" Written by: John H. Baldwin <jhb@FreeBSD.org> .\" All rights reserved. .\" diff --git a/usr.sbin/etcupdate/etcupdate.sh b/usr.sbin/etcupdate/etcupdate.sh index a4728fa..6be57b6 100755 --- a/usr.sbin/etcupdate/etcupdate.sh +++ b/usr.sbin/etcupdate/etcupdate.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2010-2013 Advanced Computing Technologies LLC +# Copyright (c) 2010-2013 Hudson River Trading LLC # Written by: John H. Baldwin <jhb@FreeBSD.org> # All rights reserved. # diff --git a/usr.sbin/etcupdate/tests/always_test.sh b/usr.sbin/etcupdate/tests/always_test.sh index 514481e..2055bb6 100644 --- a/usr.sbin/etcupdate/tests/always_test.sh +++ b/usr.sbin/etcupdate/tests/always_test.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2010 Advanced Computing Technologies LLC +# Copyright (c) 2010 Hudson River Trading LLC # Written by: John H. Baldwin <jhb@FreeBSD.org> # All rights reserved. # diff --git a/usr.sbin/etcupdate/tests/conflicts_test.sh b/usr.sbin/etcupdate/tests/conflicts_test.sh index 816c180..71f16fa 100644 --- a/usr.sbin/etcupdate/tests/conflicts_test.sh +++ b/usr.sbin/etcupdate/tests/conflicts_test.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2010 Advanced Computing Technologies LLC +# Copyright (c) 2010 Hudson River Trading LLC # Written by: John H. Baldwin <jhb@FreeBSD.org> # All rights reserved. # diff --git a/usr.sbin/etcupdate/tests/fbsdid_test.sh b/usr.sbin/etcupdate/tests/fbsdid_test.sh index c062c06..d8d5cce 100644 --- a/usr.sbin/etcupdate/tests/fbsdid_test.sh +++ b/usr.sbin/etcupdate/tests/fbsdid_test.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2010 Advanced Computing Technologies LLC +# Copyright (c) 2010 Hudson River Trading LLC # Written by: John H. Baldwin <jhb@FreeBSD.org> # All rights reserved. # diff --git a/usr.sbin/etcupdate/tests/ignore_test.sh b/usr.sbin/etcupdate/tests/ignore_test.sh index 2d3d2f5..571dd24 100644 --- a/usr.sbin/etcupdate/tests/ignore_test.sh +++ b/usr.sbin/etcupdate/tests/ignore_test.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2010 Advanced Computing Technologies LLC +# Copyright (c) 2010 Hudson River Trading LLC # Written by: John H. Baldwin <jhb@FreeBSD.org> # All rights reserved. # diff --git a/usr.sbin/etcupdate/tests/preworld_test.sh b/usr.sbin/etcupdate/tests/preworld_test.sh index c731293..b724154 100644 --- a/usr.sbin/etcupdate/tests/preworld_test.sh +++ b/usr.sbin/etcupdate/tests/preworld_test.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2013 Advanced Computing Technologies LLC +# Copyright (c) 2013 Hudson River Trading LLC # Written by: John H. Baldwin <jhb@FreeBSD.org> # All rights reserved. # diff --git a/usr.sbin/etcupdate/tests/tests_test.sh b/usr.sbin/etcupdate/tests/tests_test.sh index b99bbef..5382de3 100644 --- a/usr.sbin/etcupdate/tests/tests_test.sh +++ b/usr.sbin/etcupdate/tests/tests_test.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2010 Advanced Computing Technologies LLC +# Copyright (c) 2010 Hudson River Trading LLC # Written by: John H. Baldwin <jhb@FreeBSD.org> # All rights reserved. # diff --git a/usr.sbin/etcupdate/tests/tzsetup_test.sh b/usr.sbin/etcupdate/tests/tzsetup_test.sh index b102938..dbdcc0e 100644 --- a/usr.sbin/etcupdate/tests/tzsetup_test.sh +++ b/usr.sbin/etcupdate/tests/tzsetup_test.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2013 Advanced Computing Technologies LLC +# Copyright (c) 2013 Hudson River Trading LLC # Written by: John H. Baldwin <jhb@FreeBSD.org> # All rights reserved. # diff --git a/usr.sbin/fifolog/Makefile.inc b/usr.sbin/fifolog/Makefile.inc index 5ec27dd..265f86d 100644 --- a/usr.sbin/fifolog/Makefile.inc +++ b/usr.sbin/fifolog/Makefile.inc @@ -1,8 +1,3 @@ # $FreeBSD$ -LIBFIFOLOG= ${.OBJDIR}/../lib/libfifolog.a - -#LINT= flint -#LINTFLAGS= ${.CURDIR}/../flint.lnt -I/usr/include - .include "../Makefile.inc" diff --git a/usr.sbin/fifolog/fifolog_create/Makefile b/usr.sbin/fifolog/fifolog_create/Makefile index 8b59b25..4a83b5b 100644 --- a/usr.sbin/fifolog/fifolog_create/Makefile +++ b/usr.sbin/fifolog/fifolog_create/Makefile @@ -4,8 +4,7 @@ PROG= fifolog_create CFLAGS+= -I${.CURDIR}/../lib -DPADD= ${LIBFIFOLOG} ${LIBUTIL} -LDADD= ${LIBFIFOLOG} -lutil +LIBADD= util fifolog MAN= fifolog.1 MLINKS= fifolog.1 fifolog_create.1 \ diff --git a/usr.sbin/fifolog/fifolog_create/Makefile.depend b/usr.sbin/fifolog/fifolog_create/Makefile.depend index 793b497..e6e291a 100644 --- a/usr.sbin/fifolog/fifolog_create/Makefile.depend +++ b/usr.sbin/fifolog/fifolog_create/Makefile.depend @@ -10,6 +10,7 @@ DIRDEPS = \ lib/libc \ lib/libcompiler_rt \ lib/libutil \ + lib/libz \ usr.sbin/fifolog/lib \ diff --git a/usr.sbin/fifolog/fifolog_reader/Makefile b/usr.sbin/fifolog/fifolog_reader/Makefile index 50575a9..ae5f9e7 100644 --- a/usr.sbin/fifolog/fifolog_reader/Makefile +++ b/usr.sbin/fifolog/fifolog_reader/Makefile @@ -6,8 +6,7 @@ CFLAGS+= -I${.CURDIR}/../lib MAN= -DPADD= ${LIBFIFOLOG} ${LIBZ} -LDADD= ${LIBFIFOLOG} -lz +LIBADD= fifolog regress: ./${PROG} /tmp/fifolog.0 diff --git a/usr.sbin/fifolog/fifolog_writer/Makefile b/usr.sbin/fifolog/fifolog_writer/Makefile index 9806ec7..7a9316d 100644 --- a/usr.sbin/fifolog/fifolog_writer/Makefile +++ b/usr.sbin/fifolog/fifolog_writer/Makefile @@ -6,8 +6,7 @@ CFLAGS+= -I${.CURDIR}/../lib MAN= -DPADD= ${LIBFIFOLOG} ${LIBZ} -LDADD= ${LIBFIFOLOG} -lz +LIBADD= fifolog regress: date | ./${PROG} -z 0 /tmp/fifolog.0 diff --git a/usr.sbin/fifolog/lib/Makefile.depend b/usr.sbin/fifolog/lib/Makefile.depend index 7a06d24..bcbc78b 100644 --- a/usr.sbin/fifolog/lib/Makefile.depend +++ b/usr.sbin/fifolog/lib/Makefile.depend @@ -6,6 +6,7 @@ DIRDEPS = \ include \ include/xlocale \ lib/libz \ + usr.bin/yacc.host \ .include <dirdeps.mk> diff --git a/usr.sbin/flowctl/Makefile b/usr.sbin/flowctl/Makefile index acee16b..8bd6389 100644 --- a/usr.sbin/flowctl/Makefile +++ b/usr.sbin/flowctl/Makefile @@ -8,8 +8,7 @@ PROG= flowctl MAN= flowctl.8 WARNS?= 2 -DPADD= ${LIBNETGRAPH} -LDADD= -lnetgraph +LIBADD= netgraph .if ${MK_INET6_SUPPORT} != "no" CFLAGS+= -DINET6 diff --git a/usr.sbin/flowctl/flowctl.c b/usr.sbin/flowctl/flowctl.c index 47ddadf..0c7539a 100644 --- a/usr.sbin/flowctl/flowctl.c +++ b/usr.sbin/flowctl/flowctl.c @@ -222,12 +222,12 @@ ctl_show(int argc, char **argv) static void do_show(int version, void (*func)(struct ngnf_show_header *)) { + char buf[SORCVBUF_SIZE]; struct ng_mesg *ng_mesg; struct ngnf_show_header req, *resp; int token, nread; - ng_mesg = alloca(SORCVBUF_SIZE); - + ng_mesg = (struct ng_mesg *)buf; req.version = version; req.hash_id = req.list_id = 0; diff --git a/usr.sbin/freebsd-update/freebsd-update.8 b/usr.sbin/freebsd-update/freebsd-update.8 index b85a4e4..dcba710 100644 --- a/usr.sbin/freebsd-update/freebsd-update.8 +++ b/usr.sbin/freebsd-update/freebsd-update.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 14, 2010 +.Dd March 2, 2015 .Dt FREEBSD-UPDATE 8 .Os FreeBSD .Sh NAME @@ -36,10 +36,12 @@ .Op Fl b Ar basedir .Op Fl d Ar workdir .Op Fl f Ar conffile +.Op Fl F .Op Fl k Ar KEY .Op Fl r Ar newrelease .Op Fl s Ar server .Op Fl t Ar address +.Op Fl -not-running-from-cron .Cm command ... .Sh DESCRIPTION The @@ -54,16 +56,16 @@ by the .Fx Release Engineering Team, e.g., .Fx -7.3-RELEASE and +9.3-RELEASE and .Fx -8.0-RELEASE, but not +10.1-RELEASE, but not .Fx -6.3-STABLE or +9.3-STABLE or .Fx -9.0-CURRENT. +11-CURRENT. .Sh OPTIONS The following options are supported: -.Bl -tag -width "-f conffile" +.Bl -tag -width "-r newrelease" .It Fl b Ar basedir Operate on a system mounted at .Ar basedir . @@ -81,6 +83,10 @@ Read configuration options from .Ar conffile . (default: .Pa /etc/freebsd-update.conf ) +.It Fl F +Force +.Nm Cm fetch +to proceed where it normally would not, such as an unfinished upgrade .It Fl k Ar KEY Trust an RSA key with SHA256 of .Ar KEY . @@ -98,12 +104,21 @@ Mail output of command, if any, to .Ar address . (default: root, or as given in the configuration file.) +.It Fl -not-running-from-cron +Force +.Nm Cm fetch +to proceed when there is no controlling tty. +This is for use by automated scripts and orchestration tools. +Please do not run +.Nm Cm fetch +from crontab or similar using this flag, see: +.Nm Cm cron .El .Sh COMMANDS The .Cm command can be any one of the following: -.Bl -tag -width "-f conffile" +.Bl -tag -width "rollback" .It Cm fetch Based on the currently installed world and the configuration options set, fetch all available binary updates. diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index f586909..fda1d90 100644 --- a/usr.sbin/freebsd-update/freebsd-update.sh +++ b/usr.sbin/freebsd-update/freebsd-update.sh @@ -43,12 +43,15 @@ Options: (default: /var/db/freebsd-update/) -f conffile -- Read configuration options from conffile (default: /etc/freebsd-update.conf) + -F -- Force a fetch operation to proceed -k KEY -- Trust an RSA key with SHA256 hash of KEY -r release -- Target for upgrade (e.g., 6.2-RELEASE) -s server -- Server from which to fetch updates (default: update.FreeBSD.org) -t address -- Mail output of cron command, if any, to address (default: root) + --not-running-from-cron + -- Run without a tty, for use by automated tools Commands: fetch -- Fetch updates from server cron -- Sleep rand(3600) seconds, fetch updates, and send an @@ -399,6 +402,12 @@ init_params () { # No commands specified yet COMMANDS="" + + # Force fetch to proceed + FORCEFETCH=0 + + # Run without a TTY + NOTTYOK=0 } # Parse the command line @@ -411,6 +420,12 @@ parse_cmdline () { if [ ! -z "${CONFFILE}" ]; then usage; fi shift; CONFFILE="$1" ;; + -F) + FORCEFETCH=1 + ;; + --not-running-from-cron) + NOTTYOK=1 + ;; # Configuration file equivalents -b) @@ -673,6 +688,14 @@ fetch_check_params () { echo "(Did you mean 'upgrade' instead?)" exit 1 fi + + # Check that we have updates ready to install + if [ -f ${BDHASH}-install/kerneldone -a $FORCEFETCH -eq 0 ]; then + echo "You have a partially completed upgrade pending" + echo "Run '$0 install' first." + echo "Run '$0 fetch -F' to proceed anyway." + exit 1 + fi } # Perform sanity checks etc. before fetching upgrades. @@ -1208,7 +1231,7 @@ fetch_metadata_sanity () { # Some aliases to save space later: ${P} is a character which can # appear in a path; ${M} is the four numeric metadata fields; and # ${H} is a sha256 hash. - P="[-+./:=%@_[~[:alnum:]]" + P="[-+./:=,%@_[~[:alnum:]]" M="[0-9]+\|[0-9]+\|[0-9]+\|[0-9]+" H="[0-9a-f]{64}" @@ -1395,6 +1418,7 @@ fetch_filter_metadata () { # matter, since we add a leading "/" when we use paths later. cut -f 3- -d '|' $1 | sed -e 's,/|d|,|d|,' | + sed -e 's,/|-|,|-|,' | sort -u > $1.tmp # Figure out which lines to ignore and remove them. @@ -2263,7 +2287,7 @@ upgrade_oldall_to_oldnew () { } # Helper for upgrade_merge: Return zero true iff the two files differ only -# in the contents of their $FreeBSD$ tags. +# in the contents of their RCS tags. samef () { X=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $1 | ${SHA256}` Y=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $2 | ${SHA256}` @@ -2359,7 +2383,7 @@ upgrade_merge () { # Ask the user to handle any files which didn't merge. while read F; do # If the installed file differs from the version in - # the old release only due to $FreeBSD$ tag expansion + # the old release only due to RCS tag expansion # then just use the version in the new release. if samef merge/old/${F} merge/${OLDRELNUM}/${F}; then cp merge/${RELNUM}/${F} merge/new/${F} @@ -2381,14 +2405,14 @@ manually... # of merging files. while read F; do # Skip files which haven't changed except possibly - # in their $FreeBSD$ tags. + # in their RCS tags. if [ -f merge/old/${F} ] && [ -f merge/new/${F} ] && samef merge/old/${F} merge/new/${F}; then continue fi # Skip files where the installed file differs from - # the old file only due to $FreeBSD$ tags. + # the old file only due to RCS tags. if [ -f merge/old/${F} ] && [ -f merge/${OLDRELNUM}/${F} ] && samef merge/old/${F} merge/${OLDRELNUM}/${F}; then @@ -2633,14 +2657,14 @@ backup_kernel_finddir () { while true ; do # Pathname does not exist, so it is OK use that name # for backup directory. - if [ ! -e $BACKUPKERNELDIR ]; then + if [ ! -e $BASEDIR/$BACKUPKERNELDIR ]; then return 0 fi # If directory do exist, we only use if it has our # marker file. - if [ -d $BACKUPKERNELDIR -a \ - -e $BACKUPKERNELDIR/.freebsd-update ]; then + if [ -d $BASEDIR/$BACKUPKERNELDIR -a \ + -e $BASEDIR/$BACKUPKERNELDIR/.freebsd-update ]; then return 0 fi @@ -2648,7 +2672,7 @@ backup_kernel_finddir () { # the end and try again. CNT=$((CNT + 1)) if [ $CNT -gt 9 ]; then - echo "Could not find valid backup dir ($BACKUPKERNELDIR)" + echo "Could not find valid backup dir ($BASEDIR/$BACKUPKERNELDIR)" exit 1 fi BACKUPKERNELDIR="`echo $BACKUPKERNELDIR | sed -Ee 's/[0-9]\$//'`" @@ -2675,17 +2699,17 @@ backup_kernel () { # Remove old kernel backup files. If $BACKUPKERNELDIR was # "not ours", backup_kernel_finddir would have exited, so # deleting the directory content is as safe as we can make it. - if [ -d $BACKUPKERNELDIR ]; then - rm -fr $BACKUPKERNELDIR + if [ -d $BASEDIR/$BACKUPKERNELDIR ]; then + rm -fr $BASEDIR/$BACKUPKERNELDIR fi # Create directories for backup. - mkdir -p $BACKUPKERNELDIR - mtree -cdn -p "${KERNELDIR}" | \ - mtree -Ue -p "${BACKUPKERNELDIR}" > /dev/null + mkdir -p $BASEDIR/$BACKUPKERNELDIR + mtree -cdn -p "${BASEDIR}/${KERNELDIR}" | \ + mtree -Ue -p "${BASEDIR}/${BACKUPKERNELDIR}" > /dev/null # Mark the directory as having been created by freebsd-update. - touch $BACKUPKERNELDIR/.freebsd-update + touch $BASEDIR/$BACKUPKERNELDIR/.freebsd-update if [ $? -ne 0 ]; then echo "Could not create kernel backup directory" exit 1 @@ -2703,8 +2727,8 @@ backup_kernel () { fi # Backup all the kernel files using hardlinks. - (cd $KERNELDIR && find . -type f $FINDFILTER -exec \ - cp -pl '{}' ${BACKUPKERNELDIR}/'{}' \;) + (cd ${BASEDIR}/${KERNELDIR} && find . -type f $FINDFILTER -exec \ + cp -pl '{}' ${BASEDIR}/${BACKUPKERNELDIR}/'{}' \;) # Re-enable patchname expansion. set +f @@ -2802,7 +2826,7 @@ install_files () { # Update linker.hints if necessary if [ -s INDEX-OLD -o -s INDEX-NEW ]; then - kldxref -R /boot/ 2>/dev/null + kldxref -R ${BASEDIR}/boot/ 2>/dev/null fi # We've finished updating the kernel. @@ -2827,31 +2851,40 @@ Kernel updates have been installed. Please reboot and run grep -E '^[^|]+\|d\|' > INDEX-NEW install_from_index INDEX-NEW || return 1 + # Install new runtime linker + grep -vE '^/boot/' $1/INDEX-NEW | + grep -vE '^[^|]+\|d\|' | + grep -E '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' > INDEX-NEW + install_from_index INDEX-NEW || return 1 + # Install new shared libraries next grep -vE '^/boot/' $1/INDEX-NEW | grep -vE '^[^|]+\|d\|' | + grep -vE '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' | grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-NEW install_from_index INDEX-NEW || return 1 # Deal with everything else grep -vE '^/boot/' $1/INDEX-OLD | grep -vE '^[^|]+\|d\|' | + grep -vE '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' | grep -vE '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-OLD grep -vE '^/boot/' $1/INDEX-NEW | grep -vE '^[^|]+\|d\|' | + grep -vE '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' | grep -vE '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-NEW install_from_index INDEX-NEW || return 1 install_delete INDEX-OLD INDEX-NEW || return 1 # Rebuild /etc/spwd.db and /etc/pwd.db if necessary. - if [ /etc/master.passwd -nt /etc/spwd.db ] || - [ /etc/master.passwd -nt /etc/pwd.db ]; then - pwd_mkdb /etc/master.passwd + if [ ${BASEDIR}/etc/master.passwd -nt ${BASEDIR}/etc/spwd.db ] || + [ ${BASEDIR}/etc/master.passwd -nt ${BASEDIR}/etc/pwd.db ]; then + pwd_mkdb -d ${BASEDIR}/etc ${BASEDIR}/etc/master.passwd fi # Rebuild /etc/login.conf.db if necessary. - if [ /etc/login.conf -nt /etc/login.conf.db ]; then - cap_mkdb /etc/login.conf + if [ ${BASEDIR}/etc/login.conf -nt ${BASEDIR}/etc/login.conf.db ]; then + cap_mkdb ${BASEDIR}/etc/login.conf fi # We've finished installing the world and deleting old files @@ -3187,7 +3220,7 @@ get_params () { # Fetch command. Make sure that we're being called # interactively, then run fetch_check_params and fetch_run cmd_fetch () { - if [ ! -t 0 ]; then + if [ ! -t 0 -a $NOTTYOK -eq 0 ]; then echo -n "`basename $0` fetch should not " echo "be run non-interactively." echo "Run `basename $0` cron instead." diff --git a/usr.sbin/fstyp/Makefile b/usr.sbin/fstyp/Makefile new file mode 100644 index 0000000..d0b14d1 --- /dev/null +++ b/usr.sbin/fstyp/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD$ + +PROG= fstyp +SRCS= fstyp.c ext2fs.c cd9660.c msdosfs.c ntfs.c ufs.c +MAN= fstyp.8 + +WARNS= 6 + +.include <bsd.prog.mk> diff --git a/usr.sbin/fstyp/cd9660.c b/usr.sbin/fstyp/cd9660.c new file mode 100644 index 0000000..ee6af11 --- /dev/null +++ b/usr.sbin/fstyp/cd9660.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org> + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "fstyp.h" + +#define ISO9660_MAGIC "\x01" "CD001" "\x01\x00" +#define ISO9660_OFFSET 0x8000 +#define VOLUME_LEN 32 + +int +fstyp_cd9660(FILE *fp, char *label, size_t size) +{ + char *sector, *volume; + int i; + + sector = read_buf(fp, ISO9660_OFFSET, 512); + if (sector == NULL) + return (1); + if (bcmp(sector, ISO9660_MAGIC, sizeof(ISO9660_MAGIC) - 1) != 0) { + free(sector); + return (1); + } + volume = sector + 0x28; + bzero(label, size); + strlcpy(label, volume, MIN(size, VOLUME_LEN)); + free(sector); + for (i = size - 1; i > 0; i--) { + if (label[i] == '\0') + continue; + else if (label[i] == ' ') + label[i] = '\0'; + else + break; + } + return (0); +} diff --git a/usr.sbin/fstyp/ext2fs.c b/usr.sbin/fstyp/ext2fs.c new file mode 100644 index 0000000..79a4e3a --- /dev/null +++ b/usr.sbin/fstyp/ext2fs.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2005 Stanislav Sedov + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "fstyp.h" + +#define EXT2FS_SB_OFFSET 1024 +#define EXT2_SUPER_MAGIC 0xef53 +#define EXT2_DYNAMIC_REV 1 + +typedef struct e2sb { + uint8_t fake1[56]; + uint16_t s_magic; + uint8_t fake2[18]; + uint32_t s_rev_level; + uint8_t fake3[40]; + char s_volume_name[16]; +} e2sb_t; + +int +fstyp_ext2fs(FILE *fp, char *label, size_t size) +{ + e2sb_t *fs; + char *s_volume_name; + + fs = (e2sb_t *)read_buf(fp, EXT2FS_SB_OFFSET, 512); + if (fs == NULL) + return (1); + + /* Check for magic and versio n*/ + if (fs->s_magic == EXT2_SUPER_MAGIC && + fs->s_rev_level == EXT2_DYNAMIC_REV) { + //G_LABEL_DEBUG(1, "ext2fs file system detected on %s.", + // pp->name); + } else { + free(fs); + return (1); + } + + s_volume_name = fs->s_volume_name; + /* Terminate label */ + s_volume_name[sizeof(fs->s_volume_name) - 1] = '\0'; + + if (s_volume_name[0] == '/') + s_volume_name += 1; + + strlcpy(label, s_volume_name, size); + free(fs); + + return (0); +} diff --git a/usr.sbin/fstyp/fstyp.8 b/usr.sbin/fstyp/fstyp.8 new file mode 100644 index 0000000..5223f81 --- /dev/null +++ b/usr.sbin/fstyp/fstyp.8 @@ -0,0 +1,97 @@ +.\" Copyright (c) 2014 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This software was developed by Edward Tomasz Napierala under sponsorship +.\" from the FreeBSD Foundation. +.\" +.\" 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 AUTHORS 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 AUTHORS 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. +.\" +.\" $FreeBSD$ +.\" +.Dd January 14, 2015 +.Dt FSTYP 8 +.Os +.Sh NAME +.Nm fstyp +.Nd determine filesystem type +.Sh SYNOPSIS +.Nm +.Op Fl l +.Op Fl s +.Ar special +.Sh DESCRIPTION +The +.Nm +utility is used to determine the filesystem type on a given device. +It can recognize ISO-9660, Ext2, FAT, NTFS, and UFS filesystems. +The filesystem name is printed to the standard output +as, respectively, +.Li cd9660 , +.Li ext2fs , +.Li msdosfs , +.Li ntfs , +or +.Li ufs . +.Pp +Because +.Nm +is built specifically to detect filesystem types, it differs from +.Xr file 1 +in several ways. +The output is machine-parsable, filesystem labels are supported, +the utility runs sandboxed using +.Xr capsicum 4 , +and does not try to recognize any file format other than filesystems. +.Pp +These options are available: +.Bl -tag -width ".Fl l" +.It Fl l +In addition to filesystem type, print filesystem label if available. +.It Fl s +Ignore file type. +By default, +.Nm +only works on regular files and disk-like device nodes. +Trying to read other file types might have unexpected consequences or hang +indefinitely. +.El +.Sh EXIT STATUS +The +.Nm +utility exits 0 on success, and >0 if an error occurs or the filesystem +type is not recognized. +.Sh SEE ALSO +.Xr file 1 , +.Xr capsicum 4 , +.Xr glabel 8 , +.Xr mount 8 +.Sh HISTORY +The +.Nm +command appeared in +.Fx 11.0 . +.Sh AUTHORS +The +.Nm +utility was developed by +.An Edward Tomasz Napierala Aq Mt trasz@FreeBSD.org +under sponsorship from the FreeBSD Foundation. diff --git a/usr.sbin/fstyp/fstyp.c b/usr.sbin/fstyp/fstyp.c new file mode 100644 index 0000000..d6a48f6 --- /dev/null +++ b/usr.sbin/fstyp/fstyp.c @@ -0,0 +1,210 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/capsicum.h> +#include <sys/disk.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <err.h> +#include <errno.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <vis.h> + +#include "fstyp.h" + +#define LABEL_LEN 256 + +typedef int (*fstyp_function)(FILE *, char *, size_t); + +static struct { + const char *name; + fstyp_function function; +} fstypes[] = { + { "cd9660", &fstyp_cd9660 }, + { "ext2fs", &fstyp_ext2fs }, + { "msdosfs", &fstyp_msdosfs }, + { "ntfs", &fstyp_ntfs }, + { "ufs", &fstyp_ufs }, + { NULL, NULL } +}; + +void * +read_buf(FILE *fp, off_t off, size_t len) +{ + int error; + size_t nread; + void *buf; + + error = fseek(fp, off, SEEK_SET); + if (error != 0) { + warn("cannot seek to %jd", (uintmax_t)off); + return (NULL); + } + + buf = malloc(len); + if (buf == 0) { + warn("cannot malloc %zd bytes of memory", len); + return (NULL); + } + + nread = fread(buf, len, 1, fp); + if (nread != 1) { + free(buf); + if (feof(fp) == 0) + warn("fread"); + return (NULL); + } + + return (buf); +} + +char * +checked_strdup(const char *s) +{ + char *c; + + c = strdup(s); + if (c == NULL) + err(1, "strdup"); + return (c); +} + +static void +usage(void) +{ + + fprintf(stderr, "usage: fstyp [-l][-s] special\n"); + exit(1); +} + +static void +type_check(const char *path, FILE *fp) +{ + int error, fd; + off_t mediasize; + struct stat sb; + + fd = fileno(fp); + + error = fstat(fd, &sb); + if (error != 0) + err(1, "%s: fstat", path); + + if (S_ISREG(sb.st_mode)) + return; + + error = ioctl(fd, DIOCGMEDIASIZE, &mediasize); + if (error != 0) + errx(1, "%s: not a disk", path); +} + +int +main(int argc, char **argv) +{ + int ch, error, i, nbytes; + bool ignore_type = false, show_label = false; + char label[LABEL_LEN + 1], strvised[LABEL_LEN * 4 + 1]; + char *path; + FILE *fp; + fstyp_function fstyp_f; + + while ((ch = getopt(argc, argv, "ls")) != -1) { + switch (ch) { + case 'l': + show_label = true; + break; + case 's': + ignore_type = true; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + if (argc != 1) + usage(); + + path = argv[0]; + + fp = fopen(path, "r"); + if (fp == NULL) + err(1, "%s", path); + + error = cap_enter(); + if (error != 0 && errno != ENOSYS) + err(1, "cap_enter"); + + if (ignore_type == false) + type_check(path, fp); + + memset(label, '\0', sizeof(label)); + + for (i = 0;; i++) { + fstyp_f = fstypes[i].function; + if (fstyp_f == NULL) + break; + + error = fstyp_f(fp, label, sizeof(label)); + if (error == 0) + break; + } + + if (fstypes[i].name == NULL) { + warnx("%s: filesystem not recognized", path); + return (1); + } + + if (show_label && label[0] != '\0') { + /* + * XXX: I'd prefer VIS_HTTPSTYLE, but it unconditionally + * encodes spaces. + */ + nbytes = strsnvis(strvised, sizeof(strvised), label, + VIS_GLOB | VIS_NL, "\"'$"); + if (nbytes == -1) + err(1, "strsnvis"); + + printf("%s %s\n", fstypes[i].name, strvised); + } else { + printf("%s\n", fstypes[i].name); + } + + return (0); +} diff --git a/usr.sbin/fstyp/fstyp.h b/usr.sbin/fstyp/fstyp.h new file mode 100644 index 0000000..4474ffe --- /dev/null +++ b/usr.sbin/fstyp/fstyp.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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. + * + * $FreeBSD$ + */ + +#ifndef FSTYP_H +#define FSTYP_H + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +void *read_buf(FILE *fp, off_t off, size_t len); +char *checked_strdup(const char *s); + +int fstyp_cd9660(FILE *fp, char *label, size_t size); +int fstyp_ext2fs(FILE *fp, char *label, size_t size); +int fstyp_msdosfs(FILE *fp, char *label, size_t size); +int fstyp_ntfs(FILE *fp, char *label, size_t size); +int fstyp_ufs(FILE *fp, char *label, size_t size); + +#endif /* !FSTYP_H */ diff --git a/usr.sbin/fstyp/msdosfs.c b/usr.sbin/fstyp/msdosfs.c new file mode 100644 index 0000000..b299243 --- /dev/null +++ b/usr.sbin/fstyp/msdosfs.c @@ -0,0 +1,183 @@ +/*- + * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org> + * Copyright (c) 2006 Tobias Reifenberger + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "fstyp.h" +#include "msdosfs.h" + +#define LABEL_NO_NAME "NO NAME " + +int +fstyp_msdosfs(FILE *fp, char *label, size_t size) +{ + FAT_BSBPB *pfat_bsbpb; + FAT32_BSBPB *pfat32_bsbpb; + FAT_DES *pfat_entry; + uint8_t *sector0, *sector; + uint32_t i; + + sector0 = NULL; + sector = NULL; + + /* Load 1st sector with boot sector and boot parameter block. */ + sector0 = (uint8_t *)read_buf(fp, 0, 512); + if (sector0 == NULL) + return (1); + + /* Check for the FAT boot sector signature. */ + if (sector0[510] != 0x55 || sector0[511] != 0xaa) { + goto error; + } + + /* + * Test if this is really a FAT volume and determine the FAT type. + */ + + pfat_bsbpb = (FAT_BSBPB *)sector0; + pfat32_bsbpb = (FAT32_BSBPB *)sector0; + + if (UINT16BYTES(pfat_bsbpb->BPB_FATSz16) != 0) { + /* + * If the BPB_FATSz16 field is not zero and the string "FAT" is + * at the right place, this should be a FAT12 or FAT16 volume. + */ + if (strncmp(pfat_bsbpb->BS_FilSysType, "FAT", 3) != 0) { + goto error; + } + + /* A volume with no name should have "NO NAME " as label. */ + if (strncmp(pfat_bsbpb->BS_VolLab, LABEL_NO_NAME, + sizeof(pfat_bsbpb->BS_VolLab)) == 0) { + goto endofchecks; + } + strlcpy(label, pfat_bsbpb->BS_VolLab, + MIN(size, sizeof(pfat_bsbpb->BS_VolLab) + 1)); + } else if (UINT32BYTES(pfat32_bsbpb->BPB_FATSz32) != 0) { + uint32_t fat_FirstDataSector, fat_BytesPerSector, offset; + + /* + * If the BPB_FATSz32 field is not zero and the string "FAT" is + * at the right place, this should be a FAT32 volume. + */ + if (strncmp(pfat32_bsbpb->BS_FilSysType, "FAT", 3) != 0) { + goto error; + } + + /* + * If the volume label is not "NO NAME " we're done. + */ + if (strncmp(pfat32_bsbpb->BS_VolLab, LABEL_NO_NAME, + sizeof(pfat32_bsbpb->BS_VolLab)) != 0) { + strlcpy(label, pfat32_bsbpb->BS_VolLab, + MIN(size, sizeof(pfat32_bsbpb->BS_VolLab) + 1)); + goto endofchecks; + } + + /* + * If the volume label "NO NAME " is in the boot sector, the + * label of FAT32 volumes may be stored as a special entry in + * the root directory. + */ + fat_FirstDataSector = + UINT16BYTES(pfat32_bsbpb->BPB_RsvdSecCnt) + + (pfat32_bsbpb->BPB_NumFATs * + UINT32BYTES(pfat32_bsbpb->BPB_FATSz32)); + fat_BytesPerSector = UINT16BYTES(pfat32_bsbpb->BPB_BytsPerSec); + + // fat_FirstDataSector, fat_BytesPerSector); + + for (offset = fat_BytesPerSector * fat_FirstDataSector;; + offset += fat_BytesPerSector) { + sector = (uint8_t *)read_buf(fp, offset, fat_BytesPerSector); + if (sector == NULL) + goto error; + + pfat_entry = (FAT_DES *)sector; + do { + /* No more entries available. */ + if (pfat_entry->DIR_Name[0] == 0) { + goto endofchecks; + } + + /* Skip empty or long name entries. */ + if (pfat_entry->DIR_Name[0] == 0xe5 || + (pfat_entry->DIR_Attr & + FAT_DES_ATTR_LONG_NAME) == + FAT_DES_ATTR_LONG_NAME) { + continue; + } + + /* + * The name of the entry is the volume label if + * ATTR_VOLUME_ID is set. + */ + if (pfat_entry->DIR_Attr & + FAT_DES_ATTR_VOLUME_ID) { + strlcpy(label, pfat_entry->DIR_Name, + MIN(size, + sizeof(pfat_entry->DIR_Name) + 1)); + goto endofchecks; + } + } while((uint8_t *)(++pfat_entry) < + (uint8_t *)(sector + fat_BytesPerSector)); + free(sector); + } + } else { + goto error; + } + +endofchecks: + for (i = size - 1; i > 0; i--) { + if (label[i] == '\0') + continue; + else if (label[i] == ' ') + label[i] = '\0'; + else + break; + } + + free(sector0); + free(sector); + + return (0); + +error: + free(sector0); + free(sector); + + return (1); +} diff --git a/usr.sbin/fstyp/msdosfs.h b/usr.sbin/fstyp/msdosfs.h new file mode 100644 index 0000000..a04b87f --- /dev/null +++ b/usr.sbin/fstyp/msdosfs.h @@ -0,0 +1,140 @@ +/*- + * Copyright (c) 2006 Tobias Reifenberger + * 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 AUTHORS 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 AUTHORS 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. + * + * $FreeBSD$ + */ + +#include <sys/types.h> + +/* + * Conversion macros for little endian encoded unsigned integers + * in byte streams to the local unsigned integer format. + */ +#define UINT16BYTES(p) ((uint32_t)((p)[0] + (256*(p)[1]))) +#define UINT32BYTES(p) ((uint32_t)((p)[0] + (256*(p)[1]) + \ + (65536*(p)[2]) + (16777216*(p)[3]))) + +/* + * All following structures are according to: + * + * Microsoft Extensible Firmware Initiative FAT32 File System Specification + * FAT: General Overview of On-Disk Format + * Version 1.03, December 6, 2000 + * Microsoft Corporation + */ + +/* + * FAT boot sector and boot parameter block for + * FAT12 and FAT16 volumes + */ +typedef struct fat_bsbpb { + /* common fields */ + uint8_t BS_jmpBoot[3]; + uint8_t BS_OEMName[8]; + uint8_t BPB_BytsPerSec[2]; + uint8_t BPB_SecPerClus; + uint8_t BPB_RsvdSecCnt[2]; + uint8_t BPB_NumFATs; + uint8_t BPB_RootEntCnt[2]; + uint8_t BPB_TotSec16[2]; + uint8_t BPB_Media; + uint8_t BPB_FATSz16[2]; + uint8_t BPB_SecPerTrack[2]; + uint8_t BPB_NumHeads[2]; + uint8_t BPB_HiddSec[4]; + uint8_t BPB_TotSec32[4]; + /* FAT12/FAT16 only fields */ + uint8_t BS_DrvNum; + uint8_t BS_Reserved1; + uint8_t BS_BootSig; + uint8_t BS_VolID[4]; + uint8_t BS_VolLab[11]; + uint8_t BS_FilSysType[8]; +} FAT_BSBPB; /* 62 bytes */ + +/* + * FAT boot sector and boot parameter block for + * FAT32 volumes + */ +typedef struct fat32_bsbpb { + /* common fields */ + uint8_t BS_jmpBoot[3]; + uint8_t BS_OEMName[8]; + uint8_t BPB_BytsPerSec[2]; + uint8_t BPB_SecPerClus; + uint8_t BPB_RsvdSecCnt[2]; + uint8_t BPB_NumFATs; + uint8_t BPB_RootEntCnt[2]; + uint8_t BPB_TotSec16[2]; + uint8_t BPB_Media; + uint8_t BPB_FATSz16[2]; + uint8_t BPB_SecPerTrack[2]; + uint8_t BPB_NumHeads[2]; + uint8_t BPB_HiddSec[4]; + uint8_t BPB_TotSec32[4]; + /* FAT32 only fields */ + uint8_t BPB_FATSz32[4]; + uint8_t BPB_ExtFlags[2]; + uint8_t BPB_FSVer[2]; + uint8_t BPB_RootClus[4]; + uint8_t BPB_FSInfo[2]; + uint8_t BPB_BkBootSec[2]; + uint8_t BPB_Reserved[12]; + uint8_t BS_DrvNum; + uint8_t BS_Reserved1; + uint8_t BS_BootSig; + uint8_t BS_VolID[4]; + uint8_t BS_VolLab[11]; + uint8_t BS_FilSysType[8]; +} FAT32_BSBPB; /* 90 bytes */ + +/* + * FAT directory entry structure + */ +#define FAT_DES_ATTR_READ_ONLY 0x01 +#define FAT_DES_ATTR_HIDDEN 0x02 +#define FAT_DES_ATTR_SYSTEM 0x04 +#define FAT_DES_ATTR_VOLUME_ID 0x08 +#define FAT_DES_ATTR_DIRECTORY 0x10 +#define FAT_DES_ATTR_ARCHIVE 0x20 +#define FAT_DES_ATTR_LONG_NAME (FAT_DES_ATTR_READ_ONLY | \ + FAT_DES_ATTR_HIDDEN | \ + FAT_DES_ATTR_SYSTEM | \ + FAT_DES_ATTR_VOLUME_ID) + +typedef struct fat_des { + uint8_t DIR_Name[11]; + uint8_t DIR_Attr; + uint8_t DIR_NTRes; + uint8_t DIR_CrtTimeTenth; + uint8_t DIR_CrtTime[2]; + uint8_t DIR_CrtDate[2]; + uint8_t DIR_LstAccDate[2]; + uint8_t DIR_FstClusHI[2]; + uint8_t DIR_WrtTime[2]; + uint8_t DIR_WrtDate[2]; + uint8_t DIR_FstClusLO[2]; + uint8_t DIR_FileSize[4]; +} FAT_DES; diff --git a/usr.sbin/fstyp/ntfs.c b/usr.sbin/fstyp/ntfs.c new file mode 100644 index 0000000..9058410 --- /dev/null +++ b/usr.sbin/fstyp/ntfs.c @@ -0,0 +1,163 @@ +/*- + * Copyright (c) 2005 Takanori Watanabe + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "fstyp.h" + +#define NTFS_A_VOLUMENAME 0x60 +#define NTFS_FILEMAGIC ((uint32_t)(0x454C4946)) +#define NTFS_VOLUMEINO 3 + +struct ntfs_attr { + uint32_t a_type; + uint32_t reclen; + uint8_t a_flag; + uint8_t a_namelen; + uint8_t a_nameoff; + uint8_t reserved1; + uint8_t a_compression; + uint8_t reserved2; + uint16_t a_index; + uint16_t a_datalen; + uint16_t reserved3; + uint16_t a_dataoff; + uint16_t a_indexed; +} __packed; + +struct ntfs_filerec { + uint32_t fr_hdrmagic; + uint16_t fr_hdrfoff; + uint16_t fr_hdrfnum; + uint8_t reserved[8]; + uint16_t fr_seqnum; + uint16_t fr_nlink; + uint16_t fr_attroff; + uint16_t fr_flags; + uint32_t fr_size; + uint32_t fr_allocated; + uint64_t fr_mainrec; + uint16_t fr_attrnum; +} __packed; + +struct ntfs_bootfile { + uint8_t reserved1[3]; + uint8_t bf_sysid[8]; + uint16_t bf_bps; + uint8_t bf_spc; + uint8_t reserved2[7]; + uint8_t bf_media; + uint8_t reserved3[2]; + uint16_t bf_spt; + uint16_t bf_heads; + uint8_t reserver4[12]; + uint64_t bf_spv; + uint64_t bf_mftcn; + uint64_t bf_mftmirrcn; + int8_t bf_mftrecsz; + uint32_t bf_ibsz; + uint32_t bf_volsn; +} __packed; + +int +fstyp_ntfs(FILE *fp, char *label, size_t size) +{ + struct ntfs_bootfile *bf; + struct ntfs_filerec *fr; + struct ntfs_attr *atr; + off_t voloff; + char *filerecp, *ap; + int8_t mftrecsz; + char vnchar; + int recsize, j; + + filerecp = NULL; + + bf = (struct ntfs_bootfile *)read_buf(fp, 0, 512); + if (bf == NULL || strncmp(bf->bf_sysid, "NTFS ", 8) != 0) + goto fail; + + mftrecsz = bf->bf_mftrecsz; + recsize = (mftrecsz > 0) ? (mftrecsz * bf->bf_bps * bf->bf_spc) : (1 << -mftrecsz); + + voloff = bf->bf_mftcn * bf->bf_spc * bf->bf_bps + + recsize * NTFS_VOLUMEINO; + + filerecp = read_buf(fp, voloff, recsize); + if (filerecp == NULL) + goto fail; + fr = (struct ntfs_filerec *)filerecp; + + if (fr->fr_hdrmagic != NTFS_FILEMAGIC) + goto fail; + + for (ap = filerecp + fr->fr_attroff; + atr = (struct ntfs_attr *)ap, (int)atr->a_type != -1; + ap += atr->reclen) { + if (atr->a_type == NTFS_A_VOLUMENAME) { + if(atr->a_datalen >= size *2){ + goto fail; + } + /* + *UNICODE to ASCII. + * Should we need to use iconv(9)? + */ + for (j = 0; j < atr->a_datalen; j++) { + vnchar = *(ap + atr->a_dataoff + j); + if (j & 1) { + if (vnchar) { + goto fail; + } + } else { + label[j / 2] = vnchar; + } + } + label[j / 2] = 0; + break; + } + } + + free(bf); + free(filerecp); + + return (0); + +fail: + free(bf); + free(filerecp); + + return (1); +} diff --git a/usr.sbin/fstyp/ufs.c b/usr.sbin/fstyp/ufs.c new file mode 100644 index 0000000..8b27ca0 --- /dev/null +++ b/usr.sbin/fstyp/ufs.c @@ -0,0 +1,109 @@ +/*- + * Copyright (c) 2002, 2003 Gordon Tetlow + * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org> + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 <sys/types.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <ufs/ufs/dinode.h> +#include <ufs/ffs/fs.h> + +#include "fstyp.h" + +static const int superblocks[] = SBLOCKSEARCH; + +int +fstyp_ufs(FILE *fp, char *label, size_t labelsize) +{ + int sb, superblock; + struct fs *fs; + + /* + * Walk through the standard places that superblocks hide and look + * for UFS magic. If we find magic, then check that the size in the + * superblock corresponds to the size of the underlying provider. + * Finally, look for a volume label and create an appropriate + * provider based on that. + */ + for (sb = 0; (superblock = superblocks[sb]) != -1; sb++) { + fs = (struct fs *)read_buf(fp, superblock, SBLOCKSIZE); + if (fs == NULL) + continue; + /* + * Check for magic. We also need to check if file system size is equal + * to providers size, because sysinstall(8) used to bogusly put first + * partition at offset 0 instead of 16, and glabel/ufs would find file + * system on slice instead of partition. + */ +#ifdef notyet + if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_fsize > 0 && + ((pp->mediasize / fs->fs_fsize == fs->fs_old_size) || + (pp->mediasize / fs->fs_fsize == fs->fs_providersize))) { + /* Valid UFS1. */ + } else if (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_fsize > 0 && + ((pp->mediasize / fs->fs_fsize == fs->fs_size) || + (pp->mediasize / fs->fs_fsize == fs->fs_providersize))) { + /* Valid UFS2. */ + } else { + g_free(fs); + continue; + } +#else + if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_fsize > 0) { + /* Valid UFS1. */ + } else if (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_fsize > 0) { + /* Valid UFS2. */ + } else { + free(fs); + continue; + } +#endif + + if (fs->fs_sblockloc != superblock || fs->fs_ncg < 1 || + fs->fs_bsize < MINBSIZE || + (size_t)fs->fs_bsize < sizeof(struct fs)) { + free(fs); + continue; + } + + strlcpy(label, fs->fs_volname, labelsize); + + free(fs); + return (0); + } + + return (1); +} diff --git a/usr.sbin/ftp-proxy/Makefile b/usr.sbin/ftp-proxy/Makefile index 7a3ef47..103ea86 100644 --- a/usr.sbin/ftp-proxy/Makefile +++ b/usr.sbin/ftp-proxy/Makefile @@ -9,8 +9,7 @@ SRCS= ftp-proxy.c filter.c CFLAGS+=-I${.CURDIR}/../../contrib/pf/libevent -LDADD+= ${LIBEVENT} -DPADD+= ${LIBEVENT} +LIBADD= event WARNS?= 3 diff --git a/usr.sbin/gpioctl/Makefile b/usr.sbin/gpioctl/Makefile index 997f0c7..c0a907b 100644 --- a/usr.sbin/gpioctl/Makefile +++ b/usr.sbin/gpioctl/Makefile @@ -3,4 +3,8 @@ PROG= gpioctl MAN= gpioctl.8 +CFLAGS+= -I${.CURDIR}/../../lib/libgpio + +LIBADD= gpio + .include <bsd.prog.mk> diff --git a/usr.sbin/gpioctl/Makefile.depend b/usr.sbin/gpioctl/Makefile.depend index 96aa2a2..e0158f3 100644 --- a/usr.sbin/gpioctl/Makefile.depend +++ b/usr.sbin/gpioctl/Makefile.depend @@ -10,6 +10,7 @@ DIRDEPS = \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ + lib/libgpio \ .include <dirdeps.mk> diff --git a/usr.sbin/gpioctl/gpioctl.8 b/usr.sbin/gpioctl/gpioctl.8 index 8a43372..dc2a554 100644 --- a/usr.sbin/gpioctl/gpioctl.8 +++ b/usr.sbin/gpioctl/gpioctl.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 7, 2013 +.Dd March 8, 2015 .Dt GPIOCTL 1 .Os .Sh NAME @@ -35,20 +35,25 @@ .Nd GPIO control utility .Sh SYNOPSIS .Nm -.Cm -l .Op Fl f Ar ctldev +.Cm -l .Op Fl v .Nm -.Cm -t .Op Fl f Ar ctldev +.Cm -t .Ar pin .Nm -.Cm -c .Op Fl f Ar ctldev +.Cm -c .Ar pin .Ar flag .Op flag ... .Nm +.Op Fl f Ar ctldev +.Cm -n +.Ar pin +.Ar pin-name +.Nm .Op Cm -f Ar ctldev .Ar pin .Ar [0|1] @@ -60,7 +65,8 @@ utility could be used to manage GPIO pins from userland and list available pins. The options are as follows: .Bl -tag -width ".Fl f Ar ctldev" .It Fl c Ar pin Ar flag Op flag ... -Configure pin by setting provided flags. The following flags are currently defined: +Configure pin by setting provided flags. +The following flags are currently defined: .Bl -tag -offset indent -width ".Cm PULSE" .It Cm IN Input pin @@ -87,6 +93,8 @@ If not specified, defaults to .Pa /dev/gpioc0 .It Fl l list available pins +.It Fl n Ar pin Ar pin-name +set the name used to describe the pin .It Fl t Ar pin toggle value of provided pin number .It Fl v @@ -108,8 +116,8 @@ Configure pin 12 to be input pin gpioctl -f /dev/gpioc0 -c 12 IN .El .Sh SEE ALSO -.Xr gpio 4 -.Xr gpioiic 4 +.Xr gpio 4 , +.Xr gpioiic 4 , .Xr gpioled 4 .Sh HISTORY The diff --git a/usr.sbin/gpioctl/gpioctl.c b/usr.sbin/gpioctl/gpioctl.c index e4708a4..38e53e7 100644 --- a/usr.sbin/gpioctl/gpioctl.c +++ b/usr.sbin/gpioctl/gpioctl.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org> + * Copyright (c) 2014, Rui Paulo <rpaulo@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,7 +38,7 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <unistd.h> -#include <sys/gpio.h> +#include <libgpio.h> struct flag_desc { const char *name; @@ -67,6 +68,7 @@ usage(void) fprintf(stderr, "\tgpioctl [-f ctldev] -l [-v]\n"); fprintf(stderr, "\tgpioctl [-f ctldev] -t pin\n"); fprintf(stderr, "\tgpioctl [-f ctldev] -c pin flag ...\n"); + fprintf(stderr, "\tgpioctl [-f ctldev] -n pin pin-name\n"); fprintf(stderr, "\tgpioctl [-f ctldev] pin [0|1]\n"); exit(1); } @@ -100,7 +102,7 @@ str2cap(const char *str) /* * Our handmade function for converting string to number */ -static int +static int str2int(const char *s, int *ok) { char *endptr; @@ -132,44 +134,36 @@ print_caps(int caps) } static void -dump_pins(int fd, int verbose) +dump_pins(gpio_handle_t handle, int verbose) { - int i, maxpin; - struct gpio_pin pin; - struct gpio_req req; + int i, maxpin, pinv; + gpio_config_t *cfgs; + gpio_config_t *pin; - if (ioctl(fd, GPIOMAXPIN, &maxpin) < 0) { - perror("ioctl(GPIOMAXPIN)"); + maxpin = gpio_pin_list(handle, &cfgs); + if (maxpin < 0) { + perror("gpio_pin_list"); exit(1); } for (i = 0; i <= maxpin; i++) { - pin.gp_pin = i; - if (ioctl(fd, GPIOGETCONFIG, &pin) < 0) - /* For some reason this pin is inaccessible */ - continue; - - req.gp_pin = i; - if (ioctl(fd, GPIOGET, &req) < 0) { - /* Now, that's wrong */ - perror("ioctl(GPIOGET)"); - exit(1); - } + pin = cfgs + i; + pinv = gpio_pin_get(handle, pin->g_pin); + printf("pin %02d:\t%d\t%s", pin->g_pin, pinv, + pin->g_name); - printf("pin %02d:\t%d\t%s", pin.gp_pin, req.gp_value, - pin.gp_name); - - print_caps(pin.gp_flags); + print_caps(pin->g_flags); if (verbose) { printf(", caps:"); - print_caps(pin.gp_caps); + print_caps(pin->g_caps); } printf("\n"); } + free(cfgs); } -static void +static void fail(const char *fmt, ...) { va_list ap; @@ -180,21 +174,20 @@ fail(const char *fmt, ...) exit(1); } -int +int main(int argc, char **argv) { int i; - struct gpio_pin pin; - struct gpio_req req; - char defctlfile[] = _PATH_DEVGPIOC "0"; + gpio_config_t pin; + gpio_handle_t handle; char *ctlfile = NULL; - int pinn, pinv, fd, ch; + int pinn, pinv, ch; int flags, flag, ok; - int config, toggle, verbose, list; + int config, list, name, toggle, verbose; - config = toggle = verbose = list = pinn = 0; + config = toggle = verbose = list = name = pinn = 0; - while ((ch = getopt(argc, argv, "c:f:lt:v")) != -1) { + while ((ch = getopt(argc, argv, "c:f:ln:t:v")) != -1) { switch (ch) { case 'c': config = 1; @@ -208,6 +201,12 @@ main(int argc, char **argv) case 'l': list = 1; break; + case 'n': + name = 1; + pinn = str2int(optarg, &ok); + if (!ok) + fail("Invalid pin number: %s\n", optarg); + break; case 't': toggle = 1; pinn = str2int(optarg, &ok); @@ -224,21 +223,31 @@ main(int argc, char **argv) } argv += optind; argc -= optind; - for (i = 0; i < argc; i++) - printf("%d/%s\n", i, argv[i]); - if (ctlfile == NULL) - ctlfile = defctlfile; - - fd = open(ctlfile, O_RDONLY); - if (fd < 0) { - perror("open"); + handle = gpio_open(0); + else + handle = gpio_open_device(ctlfile); + if (handle == GPIO_INVALID_HANDLE) { + perror("gpio_open"); exit(1); } + /* Set the pin name. */ + if (name) { + if (argc == 0) { + usage(); + exit(1); + } + if (gpio_pin_set_name(handle, pinn, argv[0]) < 0) { + perror("gpio_pin_set_name"); + exit(1); + } + exit(0); + } + if (list) { - dump_pins(fd, verbose); - close(fd); + dump_pins(handle, verbose); + gpio_close(handle); exit(0); } @@ -246,19 +255,16 @@ main(int argc, char **argv) /* * -t pin assumes no additional arguments */ - if(argc > 0) { + if (argc > 0) { usage(); exit(1); } - - req.gp_pin = pinn; - if (ioctl(fd, GPIOTOGGLE, &req) < 0) { - perror("ioctl(GPIOTOGGLE)"); + if (gpio_pin_toggle(handle, pinn) < 0) { + perror("gpio_pin_toggle"); exit(1); } - - close(fd); - exit (0); + gpio_close(handle); + exit(0); } if (config) { @@ -269,14 +275,12 @@ main(int argc, char **argv) fail("Invalid flag: %s\n", argv[i]); flags |= flag; } - - pin.gp_pin = pinn; - pin.gp_flags = flags; - if (ioctl(fd, GPIOSETCONFIG, &pin) < 0) { - perror("ioctl(GPIOSETCONFIG)"); + pin.g_pin = pinn; + pin.g_flags = flags; + if (gpio_pin_set_flags(handle, &pin) < 0) { + perror("gpio_pin_set_flags"); exit(1); } - exit(0); } @@ -296,13 +300,13 @@ main(int argc, char **argv) * Read pin value */ if (argc == 1) { - req.gp_pin = pinn; - if (ioctl(fd, GPIOGET, &req) < 0) { - perror("ioctl(GPIOGET)"); + pinv = gpio_pin_get(handle, pinn); + if (pinv < 0) { + perror("gpio_pin_get"); exit(1); } - printf("%d\n", req.gp_value); - exit (0); + printf("%d\n", pinv); + exit(0); } /* Is it valid number (0 or 1) ? */ @@ -313,13 +317,11 @@ main(int argc, char **argv) /* * Set pin value */ - req.gp_pin = pinn; - req.gp_value = pinv; - if (ioctl(fd, GPIOSET, &req) < 0) { - perror("ioctl(GPIOSET)"); + if (gpio_pin_set(handle, pinn, pinv) < 0) { + perror("gpio_pin_set"); exit(1); } - close(fd); + gpio_close(handle); exit(0); } diff --git a/usr.sbin/gssd/Makefile b/usr.sbin/gssd/Makefile index 9573702..4faaf2d 100644 --- a/usr.sbin/gssd/Makefile +++ b/usr.sbin/gssd/Makefile @@ -9,16 +9,14 @@ SRCS= gssd.c gssd.h gssd_svc.c gssd_xdr.c gssd_prot.c CFLAGS+= -I. WARNS?= 1 -DPADD= ${LIBGSSAPI} -LDADD= -lgssapi +LIBADD= gssapi .if ${MK_KERBEROS_SUPPORT} != "no" -DPADD+= ${LIBKRB5} ${LIBHX509} ${LIBASN1} ${LIBROKEN} ${LIBCOM_ERR} ${LIBCRYPT} ${LIBCRYPTO} -LDADD+= -lkrb5 -lhx509 -lasn1 -lroken -lcom_err -lcrypt -lcrypto +LIBADD+= krb5 roken .else CFLAGS+= -DWITHOUT_KERBEROS .endif -CLEANFILES= gssd_svc.c gssd.h +CLEANFILES= gssd_svc.c gssd_xdr.c gssd.h RPCSRC= ${.CURDIR}/../../sys/kgssapi/gssd.x RPCGEN= RPCGEN_CPP=${CPP:Q} rpcgen -L -C -M diff --git a/usr.sbin/gssd/gssd.8 b/usr.sbin/gssd/gssd.8 index 82611f8..7eaf11a 100644 --- a/usr.sbin/gssd/gssd.8 +++ b/usr.sbin/gssd/gssd.8 @@ -106,8 +106,8 @@ by kernel GSS-API services. .Ex -std .Sh SEE ALSO .Xr gssapi 3 , -.Xr mount_nfs 8 , -.Xr syslog 3 +.Xr syslog 3 , +.Xr mount_nfs 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/gssd/gssd.c b/usr.sbin/gssd/gssd.c index 9548b8c..2540161 100644 --- a/usr.sbin/gssd/gssd.c +++ b/usr.sbin/gssd/gssd.c @@ -193,7 +193,8 @@ main(int argc, char **argv) gssd_load_mech(); if (!debug_level) { - daemon(0, 0); + if (daemon(0, 0) != 0) + err(1, "Can't daemonize"); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGHUP, SIG_IGN); @@ -206,7 +207,7 @@ main(int argc, char **argv) strcpy(sun.sun_path, _PATH_GSSDSOCK); sun.sun_len = SUN_LEN(&sun); fd = socket(AF_LOCAL, SOCK_STREAM, 0); - if (!fd) { + if (fd < 0) { if (debug_level == 0) { syslog(LOG_ERR, "Can't create local gssd socket"); exit(1); diff --git a/usr.sbin/gstat/Makefile b/usr.sbin/gstat/Makefile index 8aceec0..1c71f22 100644 --- a/usr.sbin/gstat/Makefile +++ b/usr.sbin/gstat/Makefile @@ -2,7 +2,6 @@ PROG= gstat MAN= gstat.8 -DPADD= ${LIBDEVSTAT} ${LIBKVM} ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} ${LIBEDIT} ${LIBNCURSESW} -LDADD= -ldevstat -lkvm -lgeom -lbsdxml -lsbuf -ledit -lncursesw +LIBADD= devstat geom edit ncursesw .include <bsd.prog.mk> diff --git a/usr.sbin/ifmcstat/Makefile b/usr.sbin/ifmcstat/Makefile index 5b967c7..adf1304 100644 --- a/usr.sbin/ifmcstat/Makefile +++ b/usr.sbin/ifmcstat/Makefile @@ -15,10 +15,4 @@ WARNS?= 2 CFLAGS+=-DINET6 .endif -.if ${MK_KVM_SUPPORT} != "no" -CFLAGS+=-DWITH_KVM -DPADD= ${LIBKVM} -LDADD= -lkvm -.endif - .include <bsd.prog.mk> diff --git a/usr.sbin/ifmcstat/Makefile.depend b/usr.sbin/ifmcstat/Makefile.depend index 3820cc8..b68b4bb 100644 --- a/usr.sbin/ifmcstat/Makefile.depend +++ b/usr.sbin/ifmcstat/Makefile.depend @@ -11,7 +11,6 @@ DIRDEPS = \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ - lib/libkvm \ .include <dirdeps.mk> diff --git a/usr.sbin/ifmcstat/ifmcstat.c b/usr.sbin/ifmcstat/ifmcstat.c index 9f51877..4f3f444 100644 --- a/usr.sbin/ifmcstat/ifmcstat.c +++ b/usr.sbin/ifmcstat/ifmcstat.c @@ -41,8 +41,6 @@ __FBSDID("$FreeBSD$"); #include <sys/tree.h> #include <net/if.h> -#define _WANT_IFADDR -#include <net/if_var.h> #include <net/if_types.h> #include <net/if_dl.h> #include <net/route.h> @@ -52,20 +50,12 @@ __FBSDID("$FreeBSD$"); #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/igmp.h> -#define KERNEL -# include <netinet/if_ether.h> -#undef KERNEL -#define _KERNEL -#define SYSCTL_DECL(x) -# include <netinet/igmp_var.h> -#undef SYSCTL_DECL -#undef _KERNEL +#include <netinet/if_ether.h> +#include <netinet/igmp_var.h> #ifdef INET6 #include <netinet/icmp6.h> -#define _KERNEL -# include <netinet6/mld6_var.h> -#undef _KERNEL +#include <netinet6/mld6_var.h> #endif /* INET6 */ #include <arpa/inet.h> @@ -82,14 +72,23 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <errno.h> #include <fcntl.h> -#include <kvm.h> #include <limits.h> #include <ifaddrs.h> -#include <nlist.h> #include <sysexits.h> #include <unistd.h> -/* XXX: This file currently assumes INET and KVM support in the base system. */ +#ifdef KVM +/* + * Currently the KVM build is broken. To be fixed it requires uncovering + * large amount of _KERNEL code in include files, and it is also very + * tentative to internal kernel ABI changes. If anyone wishes to restore + * it, please move it out of src/usr.sbin to src/tools/tools. + */ +#include <kvm.h> +#include <nlist.h> +#endif + +/* XXX: This file currently assumes INET support in the base system. */ #ifndef INET #define INET #endif diff --git a/usr.sbin/inetd/Makefile b/usr.sbin/inetd/Makefile index f31027af..6174592 100644 --- a/usr.sbin/inetd/Makefile +++ b/usr.sbin/inetd/Makefile @@ -16,14 +16,12 @@ CFLAGS+= -DLOGIN_CAP CFLAGS+= -DINET6 .endif -DPADD= ${LIBUTIL} ${LIBWRAP} -LDADD= -lutil -lwrap +LIBADD= util wrap # XXX for src/release/picobsd .if !defined(RELEASE_CRUNCH) CFLAGS+= -DIPSEC -DPADD+= ${LIBIPSEC} -LDADD+= -lipsec +LIBADD+= ipsec .endif .include <bsd.prog.mk> diff --git a/usr.sbin/inetd/inetd.c b/usr.sbin/inetd/inetd.c index c48f33c..178cb58 100644 --- a/usr.sbin/inetd/inetd.c +++ b/usr.sbin/inetd/inetd.c @@ -1752,10 +1752,10 @@ more: memmove(sep->se_proto, sep->se_proto + 4, strlen(sep->se_proto) + 1 - 4); sep->se_rpc = 1; - sep->se_rpc_prog = sep->se_rpc_lowvers = - sep->se_rpc_lowvers = 0; memcpy(&sep->se_ctrladdr4, bind_sa4, - sizeof(sep->se_ctrladdr4)); + sizeof(sep->se_ctrladdr4)); + sep->se_rpc_prog = sep->se_rpc_lowvers = + sep->se_rpc_highvers = 0; if ((versp = strrchr(sep->se_service, '/'))) { *versp++ = '\0'; switch (sscanf(versp, "%u-%u", diff --git a/usr.sbin/iostat/Makefile b/usr.sbin/iostat/Makefile index 9fd4809..dfbf69d 100644 --- a/usr.sbin/iostat/Makefile +++ b/usr.sbin/iostat/Makefile @@ -4,8 +4,7 @@ PROG= iostat MAN= iostat.8 -DPADD= ${LIBDEVSTAT} ${LIBKVM} ${LIBM} -LDADD= -ldevstat -lkvm -lm +LIBADD= devstat kvm m WARNS?= 1 diff --git a/usr.sbin/iostat/iostat.8 b/usr.sbin/iostat/iostat.8 index 5223b72..2073679 100644 --- a/usr.sbin/iostat/iostat.8 +++ b/usr.sbin/iostat/iostat.8 @@ -56,7 +56,7 @@ .\" .\" @(#)iostat.8 8.1 (Berkeley) 6/6/93 .\" -.Dd December 15, 2012 +.Dd May 22, 2015 .Dt IOSTAT 8 .Os .Sh NAME @@ -494,6 +494,7 @@ flags are given, the TTY and CPU displays will be displayed. .Xr ps 1 , .Xr systat 1 , .Xr devstat 3 , +.Xr ctlstat 8 , .Xr gstat 8 , .Xr pstat 8 , .Xr vmstat 8 diff --git a/usr.sbin/iostat/iostat.c b/usr.sbin/iostat/iostat.c index f566f39..195e59c 100644 --- a/usr.sbin/iostat/iostat.c +++ b/usr.sbin/iostat/iostat.c @@ -726,15 +726,17 @@ static void devstats(int perf_select, long double etime, int havelast) { int dn; - long double transfers_per_second, transfers_per_second_read, transfers_per_second_write; - long double kb_per_transfer, mb_per_second, mb_per_second_read, mb_per_second_write; + long double transfers_per_second, transfers_per_second_read; + long double transfers_per_second_write; + long double kb_per_transfer, mb_per_second, mb_per_second_read; + long double mb_per_second_write; u_int64_t total_bytes, total_transfers, total_blocks; u_int64_t total_bytes_read, total_transfers_read; u_int64_t total_bytes_write, total_transfers_write; long double busy_pct, busy_time; u_int64_t queue_len; - long double total_mb; - long double blocks_per_second, ms_per_transaction, total_duration; + long double total_mb, blocks_per_second, total_duration; + long double ms_per_other, ms_per_read, ms_per_write, ms_per_transaction; int firstline = 1; char *devname; @@ -746,8 +748,8 @@ devstats(int perf_select, long double etime, int havelast) printf(" cpu "); printf("\n"); if (Iflag == 0) { - printf("device r/s w/s kr/s kw/s qlen " - "svc_t %%b "); + printf("device r/s w/s kr/s kw/s " + " ms/r ms/w ms/o ms/t qlen %%b "); } else { printf("device r/i w/i kr/i" " kw/i qlen tsvc_t/i sb/i "); @@ -786,6 +788,9 @@ devstats(int perf_select, long double etime, int havelast) DSM_MB_PER_SECOND_WRITE, &mb_per_second_write, DSM_BLOCKS_PER_SECOND, &blocks_per_second, DSM_MS_PER_TRANSACTION, &ms_per_transaction, + DSM_MS_PER_TRANSACTION_READ, &ms_per_read, + DSM_MS_PER_TRANSACTION_WRITE, &ms_per_write, + DSM_MS_PER_TRANSACTION_OTHER, &ms_per_other, DSM_BUSY_PCT, &busy_pct, DSM_QUEUE_LENGTH, &queue_len, DSM_TOTAL_DURATION, &total_duration, @@ -820,13 +825,18 @@ devstats(int perf_select, long double etime, int havelast) mb_per_second_write > ((long double).0005)/1024 || busy_pct > 0.5) { if (Iflag == 0) - printf("%-8.8s %5.1Lf %5.1Lf %7.1Lf %7.1Lf %4" PRIu64 " %5.1Lf %3.0Lf ", - devname, transfers_per_second_read, - transfers_per_second_write, + printf("%-8.8s %5d %5d %8.1Lf " + "%8.1Lf %5d %5d %5d %5d " + "%4" PRIu64 " %3.0Lf ", + devname, + (int)transfers_per_second_read, + (int)transfers_per_second_write, mb_per_second_read * 1024, mb_per_second_write * 1024, - queue_len, - ms_per_transaction, busy_pct); + (int)ms_per_read, (int)ms_per_write, + (int)ms_per_other, + (int)ms_per_transaction, + queue_len, busy_pct); else printf("%-8.8s %11.1Lf %11.1Lf " "%12.1Lf %12.1Lf %4" PRIu64 diff --git a/usr.sbin/iovctl/Makefile b/usr.sbin/iovctl/Makefile new file mode 100644 index 0000000..d5b2780 --- /dev/null +++ b/usr.sbin/iovctl/Makefile @@ -0,0 +1,17 @@ +# $FreeBSD$ + +PROG= iovctl +SRCS= iovctl.c parse.c validate.c +LIBADD= nv ucl m + +CFLAGS+=-I${.CURDIR}/../../contrib/libucl/include + +WARNS?=6 + +MAN= \ + iovctl.8 \ + iovctl.conf.5 \ + +.include <bsd.own.mk> +.include <bsd.prog.mk> + diff --git a/usr.sbin/iovctl/iovctl.8 b/usr.sbin/iovctl/iovctl.8 new file mode 100644 index 0000000..b58ee54 --- /dev/null +++ b/usr.sbin/iovctl/iovctl.8 @@ -0,0 +1,123 @@ +.\" +.\" Copyright (c) 2014 Sandvine Inc. +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd May 21, 2014 +.Dt IOVCTL 8 +.Os +.Sh NAME +.Nm iovctl +.Nd "PCI SR-IOV configuration utility" +.Sh SYNOPSIS +.Nm +.Fl C +.Op Fl f Ar config-file +.Op Fl n +.Nm +.Fl D +.Op Fl f Ar config-file | Fl d Ar device +.Op Fl n +.Nm +.Fl S +.Op Fl f Ar config-file | Fl d Ar device +.Sh DESCRIPTION +The +.Nm +utility creates or destroys PCI Single-Root I/O Virtualization +.Pq SR-IOV +Virtual Functions +.Po VFs Pc . +When invoked with the +.Fl C +flag, +.Nm +creates VFs as children of the Physical Function +.Pq PF +configured in the specified configuration file. +When invoked with the +.Fl D +flag, +.Nm +destroys all VFs that are children of the specified device. +Available PF devices can be seen in +.Pa /dev/iov/ . +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl C +Enable SR-IOV on the specified PF device and create VF children. +This operation will fail if the PF already has VF children. +This option must be used in conjunction with the +.Fl f +option. +.It Fl d Ar device +Specify the PF device to use for the given operation. +.Ar device +may either be the name of a PF device, or a full path name to a node in +.Pa /dev/iov/ . +This option may not be used with the +.Fl C +option. +.It Fl D +Delete all VF children of the specified PF device. +This operation will fail if SR-IOV is not currently enabled on the specified +device. +.It Fl f Ar config-file +Specify the pathname of the configuration file. +For the +.Fl C +option, this file will be used to specify all configuration values. +For the +.Fl D +and +.Fl S +options, this file will only be used to specify the name of the PF device. +.Pp +See +.Xr iovctl.conf +for a description of the config file format and documentation of the +configuration parameters that apply to all PF drivers. +See the PF driver manual page for configuration parameters specific to +particular hardware. +.It Fl n +Perform a dry-run. +Perform all validation of the specified action and print what would be done, +but do not perform the actual creation or destruction of VFs. +This option may not be used with the +.Fl S +flag. +.It Fl S +Read the configuration schema from the specified device and print its contents +to stdout. +This action may be used to discover the configuration parameters supported on +a given PF device. +.El +.Sh SEE ALSO +.Xr iovctl.conf 5 , +.Xr rc.conf 5 +.Sh AUTHORS +This manual page was written by +.An Ryan Stone Aq Mt rstone@FreeBSD.org . diff --git a/usr.sbin/iovctl/iovctl.c b/usr.sbin/iovctl/iovctl.c new file mode 100644 index 0000000..dbf29d8 --- /dev/null +++ b/usr.sbin/iovctl/iovctl.c @@ -0,0 +1,403 @@ +/*- + * Copyright (c) 2013-2015 Sandvine Inc. All rights reserved. + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/iov.h> + +#include <dnv.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <nv.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "iovctl.h" + +static void config_action(const char *filename, int dryrun); +static void delete_action(const char *device, int dryrun); +static void print_schema(const char *device); + +/* + * Fetch the config schema from the kernel via ioctl. This function has to + * call the ioctl twice: the first returns the amount of memory that we need + * to allocate for the schema, and the second actually fetches the schema. + */ +static nvlist_t * +get_schema(int fd) +{ + struct pci_iov_schema arg; + nvlist_t *schema; + int error; + + /* Do the ioctl() once to fetch the size of the schema. */ + arg.schema = NULL; + arg.len = 0; + arg.error = 0; + error = ioctl(fd, IOV_GET_SCHEMA, &arg); + if (error != 0) + err(1, "Could not fetch size of config schema"); + + arg.schema = malloc(arg.len); + if (arg.schema == NULL) + err(1, "Could not allocate %zu bytes for schema", + arg.len); + + /* Now do the ioctl() for real to get the schema. */ + error = ioctl(fd, IOV_GET_SCHEMA, &arg); + if (error != 0 || arg.error != 0) { + if (arg.error != 0) + errno = arg.error; + err(1, "Could not fetch config schema"); + } + + schema = nvlist_unpack(arg.schema, arg.len, NV_FLAG_IGNORE_CASE); + if (schema == NULL) + err(1, "Could not unpack schema"); + + free(arg.schema); + return (schema); +} + +/* + * Call the ioctl that activates SR-IOV and creates the VFs. + */ +static void +config_iov(int fd, const char *dev_name, const nvlist_t *config, int dryrun) +{ + struct pci_iov_arg arg; + int error; + + arg.config = nvlist_pack(config, &arg.len); + if (arg.config == NULL) + err(1, "Could not pack configuration"); + + if (dryrun) { + printf("Would enable SR-IOV on device '%s'.\n", dev_name); + printf( + "The following configuration parameters would be used:\n"); + nvlist_fdump(config, stdout); + printf( + "The configuration parameters consume %zu bytes when packed.\n", + arg.len); + } else { + error = ioctl(fd, IOV_CONFIG, &arg); + if (error != 0) + err(1, "Failed to configure SR-IOV"); + } + + free(arg.config); +} + +static int +open_device(const char *dev_name) +{ + char *dev; + int fd; + size_t copied, size; + long path_max; + + path_max = pathconf("/dev", _PC_PATH_MAX); + if (path_max < 0) + err(1, "Could not get maximum path length"); + + size = path_max; + dev = malloc(size); + if (dev == NULL) + err(1, "Could not allocate memory for device path"); + + if (dev_name[0] == '/') + copied = strlcpy(dev, dev_name, size); + else + copied = snprintf(dev, size, "/dev/iov/%s", dev_name); + + /* >= to account for null terminator. */ + if (copied >= size) + errx(1, "Provided file name too long"); + + fd = open(dev, O_RDWR); + if (fd < 0) + err(1, "Could not open device '%s'", dev); + + free(dev); + return (fd); +} + +static void +usage(void) +{ + + warnx("Usage: iovctl -C -f <config file> [-n]"); + warnx(" iovctl -D [-d <PF device> | -f <config file>] [-n]"); + warnx(" iovctl -S [-d <PF device> | -f <config file>]"); + exit(1); + +} + +enum main_action { + NONE, + CONFIG, + DELETE, + PRINT_SCHEMA, +}; + +int +main(int argc, char **argv) +{ + char *device; + const char *filename; + int ch, dryrun; + enum main_action action; + + device = NULL; + filename = NULL; + dryrun = 0; + action = NONE; + + while ((ch = getopt(argc, argv, "Cd:Df:nS")) != -1) { + switch (ch) { + case 'C': + if (action != NONE) { + warnx( + "Only one of -C, -D or -S may be specified"); + usage(); + } + action = CONFIG; + break; + case 'd': + device = strdup(optarg); + break; + case 'D': + if (action != NONE) { + warnx( + "Only one of -C, -D or -S may be specified"); + usage(); + } + action = DELETE; + break; + case 'f': + filename = optarg; + break; + case 'n': + dryrun = 1; + break; + case 'S': + if (action != NONE) { + warnx( + "Only one of -C, -D or -S may be specified"); + usage(); + } + action = PRINT_SCHEMA; + break; + case '?': + warnx("Unrecognized argument '-%c'\n", optopt); + usage(); + break; + } + } + + if (device != NULL && filename != NULL) { + warnx("Only one of the -d and -f flags may be specified"); + usage(); + } + + if (device == NULL && filename == NULL) { + warnx("Either the -d or -f flag must be specified"); + usage(); + } + + switch (action) { + case CONFIG: + if (filename == NULL) { + warnx("-d flag cannot be used with the -C flag"); + usage(); + } + config_action(filename, dryrun); + break; + case DELETE: + if (device == NULL) + device = find_device(filename); + delete_action(device, dryrun); + free(device); + break; + case PRINT_SCHEMA: + if (dryrun) { + warnx("-n flag cannot be used with the -S flag"); + usage(); + } + if (device == NULL) + device = find_device(filename); + print_schema(device); + free(device); + break; + default: + usage(); + break; + } + + exit(0); +} + +static void +config_action(const char *filename, int dryrun) +{ + char *dev; + nvlist_t *schema, *config; + int fd; + + dev = find_device(filename); + fd = open(dev, O_RDWR); + if (fd < 0) + err(1, "Could not open device '%s'", dev); + + schema = get_schema(fd); + config = parse_config_file(filename, schema); + if (config == NULL) + errx(1, "Could not parse config"); + + config_iov(fd, dev, config, dryrun); + + nvlist_destroy(config); + nvlist_destroy(schema); + free(dev); + close(fd); +} + +static void +delete_action(const char *dev_name, int dryrun) +{ + int fd, error; + + fd = open_device(dev_name); + + if (dryrun) + printf("Would attempt to delete all VF children of '%s'\n", + dev_name); + else { + error = ioctl(fd, IOV_DELETE); + if (error != 0) + err(1, "Failed to delete VFs"); + } + + close(fd); +} + +static void +print_default_value(const nvlist_t *parameter, const char *type) +{ + const uint8_t *mac; + size_t size; + + if (strcasecmp(type, "bool") == 0) + printf(" (default = %s)", + nvlist_get_bool(parameter, DEFAULT_SCHEMA_NAME) ? "true" : + "false"); + else if (strcasecmp(type, "string") == 0) + printf(" (default = %s)", + nvlist_get_string(parameter, DEFAULT_SCHEMA_NAME)); + else if (strcasecmp(type, "uint8_t") == 0) + printf(" (default = %ju)", + (uintmax_t)nvlist_get_number(parameter, + DEFAULT_SCHEMA_NAME)); + else if (strcasecmp(type, "uint16_t") == 0) + printf(" (default = %ju)", + (uintmax_t)nvlist_get_number(parameter, + DEFAULT_SCHEMA_NAME)); + else if (strcasecmp(type, "uint32_t") == 0) + printf(" (default = %ju)", + (uintmax_t)nvlist_get_number(parameter, + DEFAULT_SCHEMA_NAME)); + else if (strcasecmp(type, "uint64_t") == 0) + printf(" (default = %ju)", + (uintmax_t)nvlist_get_number(parameter, + DEFAULT_SCHEMA_NAME)); + else if (strcasecmp(type, "unicast-mac") == 0) { + mac = nvlist_get_binary(parameter, DEFAULT_SCHEMA_NAME, &size); + printf(" (default = %02x:%02x:%02x:%02x:%02x:%02x)", mac[0], + mac[1], mac[2], mac[3], mac[4], mac[5]); + } else + errx(1, "Unexpected type in schema: '%s'", type); +} + +static void +print_subsystem_schema(const nvlist_t * subsystem_schema) +{ + const char *name, *type; + const nvlist_t *parameter; + void *it; + int nvtype; + + it = NULL; + while ((name = nvlist_next(subsystem_schema, &nvtype, &it)) != NULL) { + parameter = nvlist_get_nvlist(subsystem_schema, name); + type = nvlist_get_string(parameter, TYPE_SCHEMA_NAME); + + printf("\t%s : %s", name, type); + if (dnvlist_get_bool(parameter, REQUIRED_SCHEMA_NAME, false)) + printf(" (required)"); + else if (nvlist_exists(parameter, DEFAULT_SCHEMA_NAME)) + print_default_value(parameter, type); + else + printf(" (optional)"); + printf("\n"); + } +} + +static void +print_schema(const char *dev_name) +{ + nvlist_t *schema; + const nvlist_t *iov_schema, *driver_schema, *pf_schema, *vf_schema; + int fd; + + fd = open_device(dev_name); + schema = get_schema(fd); + + pf_schema = nvlist_get_nvlist(schema, PF_CONFIG_NAME); + iov_schema = nvlist_get_nvlist(pf_schema, IOV_CONFIG_NAME); + driver_schema = nvlist_get_nvlist(pf_schema, DRIVER_CONFIG_NAME); + printf( +"The following configuration parameters may be configured on the PF:\n"); + print_subsystem_schema(iov_schema); + print_subsystem_schema(driver_schema); + + vf_schema = nvlist_get_nvlist(schema, VF_SCHEMA_NAME); + iov_schema = nvlist_get_nvlist(vf_schema, IOV_CONFIG_NAME); + driver_schema = nvlist_get_nvlist(vf_schema, DRIVER_CONFIG_NAME); + printf( +"\nThe following configuration parameters may be configured on a VF:\n"); + print_subsystem_schema(iov_schema); + print_subsystem_schema(driver_schema); + + nvlist_destroy(schema); + close(fd); +} diff --git a/usr.sbin/iovctl/iovctl.conf.5 b/usr.sbin/iovctl/iovctl.conf.5 new file mode 100644 index 0000000..f7a6052 --- /dev/null +++ b/usr.sbin/iovctl/iovctl.conf.5 @@ -0,0 +1,167 @@ +.\" +.\" Copyright (c) 2014 Sandvine Inc. +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd May 21, 2014 +.Dt IOVCTL.CONF 5 +.Os +.Sh NAME +.Nm iovctl.conf +.Nd IOVCTL configuration file +.Sh DESCRIPTION +The +.Nm +file is the configuration file for the +.Xr iovctl 8 +program. +This file specifies configuration parameters for a single Physical Function +.Pq PF +device. +To configure SR-IOV on multiple PF devices, use one configuration file for each +PF. +The locations of all +.Xr iovctl 9 +configuration files are specified in +.Xr rc.conf 5 . +.Pp +The +.Nm +file uses UCL format. +UCL syntax is documented at the official UCL website: +http://github.com/vstakhov/libucl. +.Pp +There are three types of sections in the +.Nm +file. +A section is a key at the top level of the file with a list as its value. +The list may contain the keys specified in the +.Sx OPTIONS +section of this manual page. +Individual PF driver implementations may specify additional device-specific +configuration keys that they will accept. +The order in which sections appear in +.Nm +is ignored. +No two sections may have the same key. +For example, two sections for VF-1 must not be defined. +.Pp +The first section type is the PF section. +This section always has the key "PF"; therefore, only one such section may be +defined. +This section defines configuration parameters that apply to the PF as a whole. +.Pp +The second section type is the VF section. +This section has the key "VF-" followed by a VF index. +VF indices start at 0 and always increment by 1. +Valid VF indices are in the range of 0 to +.Po num_vfs - 1 Pc . +The VF index must be given as a decimal integer with no leading zeros. +This section defines configuration parameters that apply to a single VF. +.Pp +The third section type is the default section. +This section always has the key "DEFAULT"; therefore, only one such section may +be specified. +This section defines default configuration parameters that apply to all VFs. +All configuration keys that are valid to be applied to a VF are valid in this +section. +An individual VF section may override a default specified in this section by +providing a different value for the configuration parameter. +Note that the default section applies to ALL VFs. +The default section must appear before any VF sections. +The default section may appear before or after the PF section. +.Pp +The following option types are supported: +.Bl -tag -width indent +.It boolean +Accepts a boolean value of true or false. +.It mac-addr +Accepts a unicast MAC address specified as a string of the form +xx:xx:xx:xx:xx:xx, where xx is one or two hexadecimal digits. +.It string +Accepts any string value. +.It uint8_t +Accepts any integer in the range 0-255, inclusive. +.It uint16_t +Accepts any integer in the range 0-65535, inclusive. +.It uint32_t +Accepts any integer in the range 0-2**32, inclusive. +.It uint64_t +Accepts any integer in the range 0-2**64, inclusive. +.El +.Sh OPTIONS +The following parameters are accepted by all PF drivers: +.Bl -tag -width indent +.It device Pq string +This parameter specifies the name of the PF device. +This parameter is required to be specified. +.It num_vfs Pq uint16_t +This parameter specifies the number of VF children to create. +This parameter may not be zero. +The maximum value of this parameter is device-specific. +.El +.Pp +The following parameters are accepted by all VFs: +.Bl -tag -width indent +.It passthrough Pq boolean +This parameter controls whether the VF is reserved for the use of the +.Xr bhyve 8 +hypervisor as a PCI passthrough device. +If this parameter is set to true, then the VF will be reserved as a PCI +passthrough device and it will not be accessible from the host OS. +The default value of this parameter is false. +.El +.Pp +See the PF driver manual page for configuration parameters specific to +particular hardware. +.Sh EXAMPLES +This sample file will create 3 VFs as children of the ix0 device. +VF-1 and VF-2 are set as +.Xr bhyve 8 +passthrough devices through the use of the default section. +VF-0 is not configured as a passthrough device as it explicitly overrides the +default. +VF-0 also sets a device-specific parameter named mac-addr. +.Bd -literal -offset ident +PF { + device : "ix0"; + num_vfs : 3; +} + +DEFAULT { + passthrough : true; +} + +VF-0 { + mac-addr : "02:56:48:7e:d9:f7"; + passthrough : false; +} +.Ed +.Sh SEE ALSO +.Xr rc.conf 5 , +.Xr iovctl 8 +.Sh AUTHORS +This manual page was written by +.An Ryan Stone Aq Mt rstone@FreeBSD.org . diff --git a/usr.sbin/iovctl/iovctl.h b/usr.sbin/iovctl/iovctl.h new file mode 100644 index 0000000..21d7e5c --- /dev/null +++ b/usr.sbin/iovctl/iovctl.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013-2015 Sandvine Inc. All rights reserved. + * 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. + * + * $FreeBSD$ + */ + +#ifndef IOVCTL_H +#define IOVCTL_H + +char * find_device(const char *); +nvlist_t * parse_config_file(const char *, const nvlist_t *); +void validate_config(nvlist_t *, const nvlist_t *, const regex_t *); + +#endif + diff --git a/usr.sbin/iovctl/parse.c b/usr.sbin/iovctl/parse.c new file mode 100644 index 0000000..50e73b1 --- /dev/null +++ b/usr.sbin/iovctl/parse.c @@ -0,0 +1,416 @@ +/*- + * Copyright (c) 2014-2015 Sandvine Inc. All rights reserved. + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/iov.h> +#include <net/ethernet.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <nv.h> +#include <regex.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ucl.h> +#include <unistd.h> + +#include "iovctl.h" + +static void +report_config_error(const char *key, const ucl_object_t *obj, const char *type) +{ + + errx(1, "Value '%s' of key '%s' is not of type %s", + ucl_object_tostring(obj), key, type); +} + +/* + * Verifies that the value specified in the config file is a boolean value, and + * then adds the value to the configuration. + */ +static void +add_bool_config(const char *key, const ucl_object_t *obj, nvlist_t *config) +{ + bool val; + + if (!ucl_object_toboolean_safe(obj, &val)) + report_config_error(key, obj, "bool"); + + nvlist_add_bool(config, key, val); +} + +/* + * Verifies that the value specified in the config file is a string, and then + * adds the value to the configuration. + */ +static void +add_string_config(const char *key, const ucl_object_t *obj, nvlist_t *config) +{ + const char *val; + + if (!ucl_object_tostring_safe(obj, &val)) + report_config_error(key, obj, "string"); + + nvlist_add_string(config, key, val); +} + +/* + * Verifies that the value specified in the config file is a integer value + * within the specified range, and then adds the value to the configuration. + */ +static void +add_uint_config(const char *key, const ucl_object_t *obj, nvlist_t *config, + const char *type, uint64_t max) +{ + int64_t val; + uint64_t uval; + + /* I must use a signed type here as libucl doesn't provide unsigned. */ + if (!ucl_object_toint_safe(obj, &val)) + report_config_error(key, obj, type); + + if (val < 0) + report_config_error(key, obj, type); + + uval = val; + if (uval > max) + report_config_error(key, obj, type); + + nvlist_add_number(config, key, uval); +} + +/* + * Verifies that the value specified in the config file is a unicast MAC + * address, and then adds the value to the configuration. + */ +static void +add_unicast_mac_config(const char *key, const ucl_object_t *obj, nvlist_t *config) +{ + uint8_t mac[ETHER_ADDR_LEN]; + const char *val, *token; + char *parse, *orig_parse, *tokpos, *endpos; + size_t len; + u_long value; + int i; + + if (!ucl_object_tostring_safe(obj, &val)) + report_config_error(key, obj, "unicast-mac"); + + parse = strdup(val); + orig_parse = parse; + + i = 0; + while ((token = strtok_r(parse, ":", &tokpos)) != NULL) { + parse = NULL; + + len = strlen(token); + if (len < 1 || len > 2) + report_config_error(key, obj, "unicast-mac"); + + value = strtoul(token, &endpos, 16); + + if (*endpos != '\0') + report_config_error(key, obj, "unicast-mac"); + + if (value > UINT8_MAX) + report_config_error(key, obj, "unicast-mac"); + + if (i >= ETHER_ADDR_LEN) + report_config_error(key, obj, "unicast-mac"); + + mac[i] = value; + i++; + } + + free(orig_parse); + + if (i != ETHER_ADDR_LEN) + report_config_error(key, obj, "unicast-mac"); + + if (ETHER_IS_MULTICAST(mac)) + errx(1, "Value '%s' of key '%s' is a multicast address", + ucl_object_tostring(obj), key); + + nvlist_add_binary(config, key, mac, ETHER_ADDR_LEN); +} + +/* + * Validates that the given configuation value has the right type as specified + * in the schema, and then adds the value to the configuation node. + */ +static void +add_config(const char *key, const ucl_object_t *obj, nvlist_t *config, + const nvlist_t *schema) +{ + const char *type; + + type = nvlist_get_string(schema, TYPE_SCHEMA_NAME); + + if (strcasecmp(type, "bool") == 0) + add_bool_config(key, obj, config); + else if (strcasecmp(type, "string") == 0) + add_string_config(key, obj, config); + else if (strcasecmp(type, "uint8_t") == 0) + add_uint_config(key, obj, config, type, UINT8_MAX); + else if (strcasecmp(type, "uint16_t") == 0) + add_uint_config(key, obj, config, type, UINT16_MAX); + else if (strcasecmp(type, "uint32_t") == 0) + add_uint_config(key, obj, config, type, UINT32_MAX); + else if (strcasecmp(type, "uint64_t") == 0) + add_uint_config(key, obj, config, type, UINT64_MAX); + else if (strcasecmp(type, "unicast-mac") == 0) + add_unicast_mac_config(key, obj, config); + else + errx(1, "Unexpected type '%s' in schema", type); +} + +/* + * Parses all values specified in a device section in the configuration file, + * validates that the key/value pair is valid in the schema, and then adds + * the key/value pair to the correct subsystem in the config. + */ +static void +parse_device_config(const ucl_object_t *top, nvlist_t *config, + const char *subsystem, const nvlist_t *schema) +{ + ucl_object_iter_t it; + const ucl_object_t *obj; + nvlist_t *subsystem_config, *driver_config, *iov_config; + const nvlist_t *driver_schema, *iov_schema; + const char *key; + + if (nvlist_exists(config, subsystem)) + errx(1, "Multiple definitions of '%s' in config file", + subsystem); + + driver_schema = nvlist_get_nvlist(schema, DRIVER_CONFIG_NAME); + iov_schema = nvlist_get_nvlist(schema, IOV_CONFIG_NAME); + + driver_config = nvlist_create(NV_FLAG_IGNORE_CASE); + if (driver_config == NULL) + err(1, "Could not allocate config nvlist"); + + iov_config = nvlist_create(NV_FLAG_IGNORE_CASE); + if (iov_config == NULL) + err(1, "Could not allocate config nvlist"); + + subsystem_config = nvlist_create(NV_FLAG_IGNORE_CASE); + if (subsystem_config == NULL) + err(1, "Could not allocate config nvlist"); + + it = NULL; + while ((obj = ucl_iterate_object(top, &it, true)) != NULL) { + key = ucl_object_key(obj); + + if (nvlist_exists_nvlist(iov_schema, key)) + add_config(key, obj, iov_config, + nvlist_get_nvlist(iov_schema, key)); + else if (nvlist_exists_nvlist(driver_schema, key)) + add_config(key, obj, driver_config, + nvlist_get_nvlist(driver_schema, key)); + else + errx(1, "%s: Invalid config key '%s'", subsystem, key); + } + + nvlist_move_nvlist(subsystem_config, DRIVER_CONFIG_NAME, driver_config); + nvlist_move_nvlist(subsystem_config, IOV_CONFIG_NAME, iov_config); + nvlist_move_nvlist(config, subsystem, subsystem_config); +} + +/* + * Parses the specified config file using the given schema, and returns an + * nvlist containing the configuration specified by the file. + * + * Exits with a message to stderr and an error if any config validation fails. + */ +nvlist_t * +parse_config_file(const char *filename, const nvlist_t *schema) +{ + ucl_object_iter_t it; + struct ucl_parser *parser; + ucl_object_t *top; + const ucl_object_t *obj; + nvlist_t *config; + const nvlist_t *pf_schema, *vf_schema; + const char *errmsg, *key; + regex_t vf_pat; + int regex_err, processed_vf; + + regex_err = regcomp(&vf_pat, "^"VF_PREFIX"([1-9][0-9]*|0)$", + REG_EXTENDED | REG_ICASE); + if (regex_err != 0) + errx(1, "Could not compile VF regex"); + + parser = ucl_parser_new(0); + if (parser == NULL) + err(1, "Could not allocate parser"); + + if (!ucl_parser_add_file(parser, filename)) + err(1, "Could not open '%s' for reading", filename); + + errmsg = ucl_parser_get_error(parser); + if (errmsg != NULL) + errx(1, "Could not parse '%s': %s", filename, errmsg); + + config = nvlist_create(NV_FLAG_IGNORE_CASE); + if (config == NULL) + err(1, "Could not allocate config nvlist"); + + pf_schema = nvlist_get_nvlist(schema, PF_CONFIG_NAME); + vf_schema = nvlist_get_nvlist(schema, VF_SCHEMA_NAME); + + processed_vf = 0; + top = ucl_parser_get_object(parser); + it = NULL; + while ((obj = ucl_iterate_object(top, &it, true)) != NULL) { + key = ucl_object_key(obj); + + if (strcasecmp(key, PF_CONFIG_NAME) == 0) + parse_device_config(obj, config, key, pf_schema); + else if (strcasecmp(key, DEFAULT_SCHEMA_NAME) == 0) { + /* + * Enforce that the default section must come before all + * VF sections. This will hopefully prevent confusing + * the user by having a default value apply to a VF + * that was declared earlier in the file. + * + * This also gives us the flexibility to extend the file + * format in the future to allow for multiple default + * sections that do only apply to subsequent VF + * sections. + */ + if (processed_vf) + errx(1, + "'default' section must precede all VF sections"); + + parse_device_config(obj, config, key, vf_schema); + } else if (regexec(&vf_pat, key, 0, NULL, 0) == 0) { + processed_vf = 1; + parse_device_config(obj, config, key, vf_schema); + } else + errx(1, "Unexpected top-level node: %s", key); + } + + validate_config(config, schema, &vf_pat); + + ucl_object_unref(top); + ucl_parser_free(parser); + regfree(&vf_pat); + + return (config); +} + +/* + * Parse the PF configuration section for and return the value specified for + * the device parameter, or NULL if the device is not specified. + */ +static const char * +find_pf_device(const ucl_object_t *pf) +{ + ucl_object_iter_t it; + const ucl_object_t *obj; + const char *key, *device; + + it = NULL; + while ((obj = ucl_iterate_object(pf, &it, true)) != NULL) { + key = ucl_object_key(obj); + + if (strcasecmp(key, "device") == 0) { + if (!ucl_object_tostring_safe(obj, &device)) + err(1, + "Config PF.device must be a string"); + + return (device); + } + } + + return (NULL); +} + +/* + * Manually parse the config file looking for the name of the PF device. We + * have to do this separately because we need the config schema to call the + * normal config file parsing code, and we need to know the name of the PF + * device so that we can fetch the schema from it. + * + * This will always exit on failure, so if it returns then it is guaranteed to + * have returned a valid device name. + */ +char * +find_device(const char *filename) +{ + char *device; + const char *deviceName; + ucl_object_iter_t it; + struct ucl_parser *parser; + ucl_object_t *top; + const ucl_object_t *obj; + const char *errmsg, *key; + int error; + + device = NULL; + deviceName = NULL; + + parser = ucl_parser_new(0); + if (parser == NULL) + err(1, "Could not allocate parser"); + + if (!ucl_parser_add_file(parser, filename)) + err(1, "Could not open '%s' for reading", filename); + + errmsg = ucl_parser_get_error(parser); + if (errmsg != NULL) + errx(1, "Could not parse '%s': %s", filename, errmsg); + + top = ucl_parser_get_object (parser); + it = NULL; + while ((obj = ucl_iterate_object(top, &it, true)) != NULL) { + key = ucl_object_key(obj); + + if (strcasecmp(key, PF_CONFIG_NAME) == 0) { + deviceName = find_pf_device(obj); + break; + } + } + + if (deviceName == NULL) + errx(1, "Config file does not specify device"); + + error = asprintf(&device, "/dev/iov/%s", deviceName); + if (error < 0) + err(1, "Could not allocate memory for device"); + + ucl_object_unref(top); + ucl_parser_free(parser); + + return (device); +} diff --git a/usr.sbin/iovctl/validate.c b/usr.sbin/iovctl/validate.c new file mode 100644 index 0000000..0e3eacd --- /dev/null +++ b/usr.sbin/iovctl/validate.c @@ -0,0 +1,274 @@ +/*- + * Copyright (c) 2014-2015 Sandvine Inc. All rights reserved. + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/iov.h> + +#include <dnv.h> +#include <err.h> +#include <nv.h> +#include <regex.h> +#include <stdlib.h> + +#include "iovctl.h" + +/* + * Returns a writeable pointer to the configuration for the given device. + * If no configuration exists, a new nvlist with empty driver and iov + * sections is allocated and returned. + * + * Returning a writeable pointer requires removing the configuration from config + * using nvlist_take. It is the responsibility of the caller to re-insert the + * nvlist in config with nvlist_move_nvlist. + */ +static nvlist_t * +find_config(nvlist_t *config, const char * device) +{ + nvlist_t *subsystem, *empty_driver, *empty_iov; + + subsystem = dnvlist_take_nvlist(config, device, NULL); + + if (subsystem != NULL) + return (subsystem); + + empty_driver = nvlist_create(NV_FLAG_IGNORE_CASE); + if (empty_driver == NULL) + err(1, "Could not allocate config nvlist"); + + empty_iov = nvlist_create(NV_FLAG_IGNORE_CASE); + if (empty_iov == NULL) + err(1, "Could not allocate config nvlist"); + + subsystem = nvlist_create(NV_FLAG_IGNORE_CASE); + if (subsystem == NULL) + err(1, "Could not allocate config nvlist"); + + nvlist_move_nvlist(subsystem, DRIVER_CONFIG_NAME, empty_driver); + nvlist_move_nvlist(subsystem, IOV_CONFIG_NAME, empty_iov); + + return (subsystem); +} + +static uint16_t +parse_vf_num(const char *key, regmatch_t *matches) +{ + u_long vf_num; + + vf_num = strtoul(key + matches[1].rm_so, NULL, 10); + + if (vf_num > UINT16_MAX) + errx(1, "VF number %lu is too large to be valid", + vf_num); + + return (vf_num); +} + +/* + * Apply the default values specified in device_defaults to the specified + * subsystem in the given device_config. + * + * This function assumes that the values specified in device_defaults have + * already been validated. + */ +static void +apply_subsystem_defaults(nvlist_t *device_config, const char *subsystem, + const nvlist_t *device_defaults) +{ + nvlist_t *config; + const nvlist_t *defaults; + const char *name; + void *cookie; + size_t len; + const void *bin; + int type; + + config = nvlist_take_nvlist(device_config, subsystem); + defaults = nvlist_get_nvlist(device_defaults, subsystem); + + cookie = NULL; + while ((name = nvlist_next(defaults, &type, &cookie)) != NULL) { + if (nvlist_exists(config, name)) + continue; + + switch (type) { + case NV_TYPE_BOOL: + nvlist_add_bool(config, name, + nvlist_get_bool(defaults, name)); + break; + case NV_TYPE_NUMBER: + nvlist_add_number(config, name, + nvlist_get_number(defaults, name)); + break; + case NV_TYPE_STRING: + nvlist_add_string(config, name, + nvlist_get_string(defaults, name)); + break; + case NV_TYPE_NVLIST: + nvlist_add_nvlist(config, name, + nvlist_get_nvlist(defaults, name)); + break; + case NV_TYPE_BINARY: + bin = nvlist_get_binary(defaults, name, &len); + nvlist_add_binary(config, name, bin, len); + break; + default: + errx(1, "Unexpected type '%d'", type); + } + } + nvlist_move_nvlist(device_config, subsystem, config); +} + +/* + * Iterate over every subsystem in the given VF device and apply default values + * for parameters that were not configured with a value. + * + * This function assumes that the values specified in defaults have already been + * validated. + */ +static void +apply_defaults(nvlist_t *vf, const nvlist_t *defaults) +{ + + apply_subsystem_defaults(vf, DRIVER_CONFIG_NAME, defaults); + apply_subsystem_defaults(vf, IOV_CONFIG_NAME, defaults); +} + +/* + * Validate that all required parameters have been configured in the specified + * subsystem. + */ +static void +validate_subsystem(const nvlist_t *device, const nvlist_t *device_schema, + const char *subsystem_name, const char *config_name) +{ + const nvlist_t *subsystem, *schema, *config; + const char *name; + void *cookie; + int type; + + subsystem = nvlist_get_nvlist(device, subsystem_name); + schema = nvlist_get_nvlist(device_schema, subsystem_name); + + cookie = NULL; + while ((name = nvlist_next(schema, &type, &cookie)) != NULL) { + config = nvlist_get_nvlist(schema, name); + + if (dnvlist_get_bool(config, REQUIRED_SCHEMA_NAME, false)) { + if (!nvlist_exists(subsystem, name)) + errx(1, + "Required parameter '%s' not found in '%s'", + name, config_name); + } + } +} + +/* + * Validate that all required parameters have been configured in all subsystems + * in the device. + */ +static void +validate_device(const nvlist_t *device, const nvlist_t *schema, + const char *config_name) +{ + + validate_subsystem(device, schema, DRIVER_CONFIG_NAME, config_name); + validate_subsystem(device, schema, IOV_CONFIG_NAME, config_name); +} + +static uint16_t +get_num_vfs(const nvlist_t *pf) +{ + const nvlist_t *iov; + + iov = nvlist_get_nvlist(pf, IOV_CONFIG_NAME); + return (nvlist_get_number(iov, "num_vfs")); +} + +/* + * Validates the configuration that has been parsed into config using the given + * config schema. Note that the parser is required to not insert configuration + * keys that are not valid in the schema, and to not insert configuration values + * that are of the incorrect type. Therefore this function will not validate + * either condition. This function is only responsible for inserting config + * file defaults in individual VF sections and removing the DEFAULT_SCHEMA_NAME + * subsystem from config, validating that all required parameters in the schema + * are present in each PF and VF subsystem, and that there is no VF subsystem + * section whose number exceeds num_vfs. + */ +void +validate_config(nvlist_t *config, const nvlist_t *schema, const regex_t *vf_pat) +{ + char device_name[VF_MAX_NAME]; + regmatch_t matches[2]; + nvlist_t *defaults, *pf, *vf; + const nvlist_t *vf_schema; + const char *key; + void *cookie; + int i, type; + uint16_t vf_num, num_vfs; + + pf = find_config(config, PF_CONFIG_NAME); + validate_device(pf, nvlist_get_nvlist(schema, PF_CONFIG_NAME), + PF_CONFIG_NAME); + nvlist_move_nvlist(config, PF_CONFIG_NAME, pf); + + num_vfs = get_num_vfs(pf); + vf_schema = nvlist_get_nvlist(schema, VF_SCHEMA_NAME); + + if (num_vfs == 0) + errx(1, "PF.num_vfs must be at least 1"); + + defaults = dnvlist_take_nvlist(config, DEFAULT_SCHEMA_NAME, NULL); + + for (i = 0; i < num_vfs; i++) { + snprintf(device_name, sizeof(device_name), VF_PREFIX"%d", + i); + + vf = find_config(config, device_name); + + if (defaults != NULL) + apply_defaults(vf, defaults); + + validate_device(vf, vf_schema, device_name); + nvlist_move_nvlist(config, device_name, vf); + } + nvlist_destroy(defaults); + + cookie = NULL; + while ((key = nvlist_next(config, &type, &cookie)) != NULL) { + if (regexec(vf_pat, key, nitems(matches), matches, 0) == 0) { + vf_num = parse_vf_num(key, matches); + if (vf_num >= num_vfs) + errx(1, + "VF number %d is out of bounds (num_vfs=%d)", + vf_num, num_vfs); + } + } +} + diff --git a/usr.sbin/ip6addrctl/ip6addrctl.c b/usr.sbin/ip6addrctl/ip6addrctl.c index 6a730ff..d9bf89d 100644 --- a/usr.sbin/ip6addrctl/ip6addrctl.c +++ b/usr.sbin/ip6addrctl/ip6addrctl.c @@ -39,7 +39,6 @@ #include <sys/sysctl.h> #include <net/if.h> -#include <net/if_var.h> #include <netinet/in.h> #include <netinet6/in6_var.h> diff --git a/usr.sbin/ipfwpcap/Makefile b/usr.sbin/ipfwpcap/Makefile index d16f888..2fde890 100644 --- a/usr.sbin/ipfwpcap/Makefile +++ b/usr.sbin/ipfwpcap/Makefile @@ -6,8 +6,7 @@ PROG= ipfwpcap -LDADD= -lpcap -DPADD= ${LIBPCAP} +LIBADD= pcap MAN= ipfwpcap.8 diff --git a/usr.sbin/iscsid/Makefile b/usr.sbin/iscsid/Makefile index 784c204..e3c6dd1 100644 --- a/usr.sbin/iscsid/Makefile +++ b/usr.sbin/iscsid/Makefile @@ -8,8 +8,7 @@ CFLAGS+= -I${.CURDIR}/../../sys/dev/iscsi #CFLAGS+= -DICL_KERNEL_PROXY MAN= iscsid.8 -DPADD= ${LIBCRYPTO} ${LIBUTIL} -LDADD= -lcrypto -lutil +LIBADD= crypto util WARNS= 6 diff --git a/usr.sbin/iscsid/discovery.c b/usr.sbin/iscsid/discovery.c index c87d9ff..a8975d7 100644 --- a/usr.sbin/iscsid/discovery.c +++ b/usr.sbin/iscsid/discovery.c @@ -66,7 +66,7 @@ text_receive(struct connection *conn) log_errx(1, "received Text PDU with unsupported \"C\" flag"); if (ntohl(bhstr->bhstr_statsn) != conn->conn_statsn + 1) { log_errx(1, "received Text PDU with wrong StatSN: " - "is %d, should be %d", ntohl(bhstr->bhstr_statsn), + "is %u, should be %u", ntohl(bhstr->bhstr_statsn), conn->conn_statsn + 1); } conn->conn_statsn = ntohl(bhstr->bhstr_statsn); @@ -112,7 +112,7 @@ logout_receive(struct connection *conn) ntohs(bhslr->bhslr_response)); if (ntohl(bhslr->bhslr_statsn) != conn->conn_statsn + 1) { log_errx(1, "received Logout PDU with wrong StatSN: " - "is %d, should be %d", ntohl(bhslr->bhslr_statsn), + "is %u, should be %u", ntohl(bhslr->bhslr_statsn), conn->conn_statsn + 1); } conn->conn_statsn = ntohl(bhslr->bhslr_statsn); diff --git a/usr.sbin/iscsid/iscsid.c b/usr.sbin/iscsid/iscsid.c index a7f489e..c1c8b1b 100644 --- a/usr.sbin/iscsid/iscsid.c +++ b/usr.sbin/iscsid/iscsid.c @@ -151,8 +151,7 @@ resolve_addr(const struct connection *conn, const char *address, } static struct connection * -connection_new(unsigned int session_id, const uint8_t isid[8], uint16_t tsih, - const struct iscsi_session_conf *conf, int iscsi_fd) +connection_new(int iscsi_fd, const struct iscsi_daemon_request *request) { struct connection *conn; struct addrinfo *from_ai, *to_ai; @@ -160,7 +159,7 @@ connection_new(unsigned int session_id, const uint8_t isid[8], uint16_t tsih, #ifdef ICL_KERNEL_PROXY struct iscsi_daemon_connect idc; #endif - int error; + int error, sockbuf; conn = calloc(1, sizeof(*conn)); if (conn == NULL) @@ -176,16 +175,13 @@ connection_new(unsigned int session_id, const uint8_t isid[8], uint16_t tsih, conn->conn_max_data_segment_length = 8192; conn->conn_max_burst_length = 262144; conn->conn_first_burst_length = 65536; - - conn->conn_session_id = session_id; - memcpy(&conn->conn_isid, isid, sizeof(conn->conn_isid)); - conn->conn_tsih = tsih; conn->conn_iscsi_fd = iscsi_fd; - /* - * XXX: Should we sanitize this somehow? - */ - memcpy(&conn->conn_conf, conf, sizeof(conn->conn_conf)); + conn->conn_session_id = request->idr_session_id; + memcpy(&conn->conn_conf, &request->idr_conf, sizeof(conn->conn_conf)); + memcpy(&conn->conn_isid, &request->idr_isid, sizeof(conn->conn_isid)); + conn->conn_tsih = request->idr_tsih; + memcpy(&conn->conn_limits, &request->idr_limits, sizeof(conn->conn_limits)); from_addr = conn->conn_conf.isc_initiator_addr; to_addr = conn->conn_conf.isc_target_addr; @@ -237,6 +233,14 @@ connection_new(unsigned int session_id, const uint8_t isid[8], uint16_t tsih, fail(conn, strerror(errno)); log_err(1, "failed to create socket for %s", from_addr); } + sockbuf = SOCKBUF_SIZE; + if (setsockopt(conn->conn_socket, SOL_SOCKET, SO_RCVBUF, + &sockbuf, sizeof(sockbuf)) == -1) + log_warn("setsockopt(SO_RCVBUF) failed"); + sockbuf = SOCKBUF_SIZE; + if (setsockopt(conn->conn_socket, SOL_SOCKET, SO_SNDBUF, + &sockbuf, sizeof(sockbuf)) == -1) + log_warn("setsockopt(SO_SNDBUF) failed"); if (from_ai != NULL) { error = bind(conn->conn_socket, from_ai->ai_addr, from_ai->ai_addrlen); @@ -434,8 +438,7 @@ handle_request(int iscsi_fd, const struct iscsi_daemon_request *request, int tim setproctitle("%s", request->idr_conf.isc_target_addr); } - conn = connection_new(request->idr_session_id, request->idr_isid, - request->idr_tsih, &request->idr_conf, iscsi_fd); + conn = connection_new(iscsi_fd, request); set_timeout(timeout); capsicate(conn); login(conn); diff --git a/usr.sbin/iscsid/iscsid.h b/usr.sbin/iscsid/iscsid.h index b05c222..946f927 100644 --- a/usr.sbin/iscsid/iscsid.h +++ b/usr.sbin/iscsid/iscsid.h @@ -44,12 +44,14 @@ #define CONN_DIGEST_CRC32C 1 #define CONN_MUTUAL_CHALLENGE_LEN 1024 +#define SOCKBUF_SIZE 1048576 struct connection { int conn_iscsi_fd; int conn_socket; unsigned int conn_session_id; struct iscsi_session_conf conn_conf; + struct iscsi_session_limits conn_limits; char conn_target_alias[ISCSI_ADDR_LEN]; uint8_t conn_isid[6]; uint16_t conn_tsih; @@ -114,7 +116,6 @@ void keys_delete(struct keys *key); void keys_load(struct keys *keys, const struct pdu *pdu); void keys_save(struct keys *keys, struct pdu *pdu); const char *keys_find(struct keys *keys, const char *name); -int keys_find_int(struct keys *keys, const char *name); void keys_add(struct keys *keys, const char *name, const char *value); void keys_add_int(struct keys *keys, diff --git a/usr.sbin/iscsid/keys.c b/usr.sbin/iscsid/keys.c index bab1ac9..c4b478b 100644 --- a/usr.sbin/iscsid/keys.c +++ b/usr.sbin/iscsid/keys.c @@ -162,26 +162,6 @@ keys_find(struct keys *keys, const char *name) return (NULL); } -int -keys_find_int(struct keys *keys, const char *name) -{ - const char *str; - char *endptr; - int num; - - str = keys_find(keys, name); - if (str == NULL) - return (-1); - - num = strtoul(str, &endptr, 10); - if (*endptr != '\0') { - log_debugx("invalid numeric value \"%s\"", str); - return (-1); - } - - return (num); -} - void keys_add(struct keys *keys, const char *name, const char *value) { diff --git a/usr.sbin/iscsid/login.c b/usr.sbin/iscsid/login.c index afe7ebb..ed0b9bf 100644 --- a/usr.sbin/iscsid/login.c +++ b/usr.sbin/iscsid/login.c @@ -257,7 +257,7 @@ login_receive(struct connection *conn) * to be bug in NetBSD iSCSI target. */ log_warnx("received Login PDU with wrong StatSN: " - "is %d, should be %d", ntohl(bhslr->bhslr_statsn), + "is %u, should be %u", ntohl(bhslr->bhslr_statsn), conn->conn_statsn + 1); } conn->conn_tsih = ntohs(bhslr->bhslr_tsih); @@ -388,6 +388,11 @@ login_negotiate_key(struct connection *conn, const char *name, if (tmp <= 0) log_errx(1, "received invalid " "MaxRecvDataSegmentLength"); + if (tmp > ISCSI_MAX_DATA_SEGMENT_LENGTH) { + log_debugx("capping MaxRecvDataSegmentLength " + "from %d to %d", tmp, ISCSI_MAX_DATA_SEGMENT_LENGTH); + tmp = ISCSI_MAX_DATA_SEGMENT_LENGTH; + } conn->conn_max_data_segment_length = tmp; } else if (strcmp(name, "MaxBurstLength") == 0) { if (conn->conn_immediate_data) { @@ -436,6 +441,10 @@ login_negotiate(struct connection *conn) request = login_new_request(conn, BHSLR_STAGE_OPERATIONAL_NEGOTIATION); request_keys = keys_new(); + log_debugx("offload \"%s\" limits MaxRecvDataSegmentLength to %zd", + conn->conn_conf.isc_offload, + conn->conn_limits.isl_max_data_segment_length); + /* * The following keys are irrelevant for discovery sessions. */ @@ -451,21 +460,21 @@ login_negotiate(struct connection *conn) keys_add(request_keys, "ImmediateData", "Yes"); keys_add_int(request_keys, "MaxBurstLength", - ISCSI_MAX_DATA_SEGMENT_LENGTH); + 2 * conn->conn_limits.isl_max_data_segment_length); keys_add_int(request_keys, "FirstBurstLength", - ISCSI_MAX_DATA_SEGMENT_LENGTH); + conn->conn_limits.isl_max_data_segment_length); keys_add(request_keys, "InitialR2T", "Yes"); + keys_add(request_keys, "MaxOutstandingR2T", "1"); } else { keys_add(request_keys, "HeaderDigest", "None"); keys_add(request_keys, "DataDigest", "None"); } keys_add_int(request_keys, "MaxRecvDataSegmentLength", - ISCSI_MAX_DATA_SEGMENT_LENGTH); + conn->conn_limits.isl_max_data_segment_length); keys_add(request_keys, "DefaultTime2Wait", "0"); keys_add(request_keys, "DefaultTime2Retain", "0"); keys_add(request_keys, "ErrorRecoveryLevel", "0"); - keys_add(request_keys, "MaxOutstandingR2T", "1"); keys_save(request_keys, request); keys_delete(request_keys); request_keys = NULL; diff --git a/usr.sbin/jail/Makefile b/usr.sbin/jail/Makefile index 58324ac..9dfdee5 100644 --- a/usr.sbin/jail/Makefile +++ b/usr.sbin/jail/Makefile @@ -6,8 +6,7 @@ PROG= jail MAN= jail.8 jail.conf.5 SRCS= jail.c command.c config.c state.c jailp.h jaillex.l jailparse.y y.tab.h -DPADD= ${LIBJAIL} ${LIBKVM} ${LIBUTIL} ${LIBL} -LDADD= -ljail -lkvm -lutil -ll +LIBADD= jail kvm util l NO_WMISSING_VARIABLE_DECLARATIONS= diff --git a/usr.sbin/jail/Makefile.depend b/usr.sbin/jail/Makefile.depend index 4dabb74..b624768 100644 --- a/usr.sbin/jail/Makefile.depend +++ b/usr.sbin/jail/Makefile.depend @@ -15,6 +15,7 @@ DIRDEPS = \ lib/libkvm \ lib/libutil \ usr.bin/lex/lib \ + usr.bin/yacc.host \ .include <dirdeps.mk> diff --git a/usr.sbin/jail/command.c b/usr.sbin/jail/command.c index 0d1c898..f6f9db3 100644 --- a/usr.sbin/jail/command.c +++ b/usr.sbin/jail/command.c @@ -112,6 +112,12 @@ next_command(struct cfjail *j) if (!bool_param(j->intparams[IP_MOUNT_FDESCFS])) continue; j->comstring = &dummystring; + break; + case IP_MOUNT_PROCFS: + if (!bool_param(j->intparams[IP_MOUNT_PROCFS])) + continue; + j->comstring = &dummystring; + break; case IP__OP: case IP_STOP_TIMEOUT: j->comstring = &dummystring; @@ -260,8 +266,8 @@ run_command(struct cfjail *j) const struct passwd *pwd; const struct cfstring *comstring, *s; login_cap_t *lcap; - char **argv; - char *cs, *comcs, *devpath; + const char **argv; + char *acs, *cs, *comcs, *devpath; const char *jidstr, *conslog, *path, *ruleset, *term, *username; enum intparam comparam; size_t comlen; @@ -332,27 +338,26 @@ run_command(struct cfjail *j) } argv = alloca((8 + argc) * sizeof(char *)); - *(const char **)&argv[0] = _PATH_IFCONFIG; + argv[0] = _PATH_IFCONFIG; if ((cs = strchr(val, '|'))) { - argv[1] = alloca(cs - val + 1); - strlcpy(argv[1], val, cs - val + 1); + argv[1] = acs = alloca(cs - val + 1); + strlcpy(acs, val, cs - val + 1); addr = cs + 1; } else { - *(const char **)&argv[1] = - string_param(j->intparams[IP_INTERFACE]); + argv[1] = string_param(j->intparams[IP_INTERFACE]); addr = val; } - *(const char **)&argv[2] = "inet"; + argv[2] = "inet"; if (!(cs = strchr(addr, '/'))) { argv[3] = addr; - *(const char **)&argv[4] = "netmask"; - *(const char **)&argv[5] = "255.255.255.255"; + argv[4] = "netmask"; + argv[5] = "255.255.255.255"; argc = 6; } else if (strchr(cs + 1, '.')) { - argv[3] = alloca(cs - addr + 1); - strlcpy(argv[3], addr, cs - addr + 1); - *(const char **)&argv[4] = "netmask"; - *(const char **)&argv[5] = cs + 1; + argv[3] = acs = alloca(cs - addr + 1); + strlcpy(acs, addr, cs - addr + 1); + argv[4] = "netmask"; + argv[5] = cs + 1; argc = 6; } else { argv[3] = addr; @@ -360,14 +365,15 @@ run_command(struct cfjail *j) } if (!down) { - for (cs = strtok(extrap, " "); cs; cs = strtok(NULL, " ")) { + for (cs = strtok(extrap, " "); cs; + cs = strtok(NULL, " ")) { size_t len = strlen(cs) + 1; - argv[argc] = alloca(len); - strlcpy(argv[argc++], cs, len); + argv[argc++] = acs = alloca(len); + strlcpy(acs, cs, len); } } - *(const char **)&argv[argc] = down ? "-alias" : "alias"; + argv[argc] = down ? "-alias" : "alias"; argv[argc + 1] = NULL; break; #endif @@ -389,46 +395,45 @@ run_command(struct cfjail *j) } argv = alloca((8 + argc) * sizeof(char *)); - *(const char **)&argv[0] = _PATH_IFCONFIG; + argv[0] = _PATH_IFCONFIG; if ((cs = strchr(val, '|'))) { - argv[1] = alloca(cs - val + 1); - strlcpy(argv[1], val, cs - val + 1); + argv[1] = acs = alloca(cs - val + 1); + strlcpy(acs, val, cs - val + 1); addr = cs + 1; } else { - *(const char **)&argv[1] = - string_param(j->intparams[IP_INTERFACE]); + argv[1] = string_param(j->intparams[IP_INTERFACE]); addr = val; } - *(const char **)&argv[2] = "inet6"; + argv[2] = "inet6"; argv[3] = addr; if (!(cs = strchr(addr, '/'))) { - *(const char **)&argv[4] = "prefixlen"; - *(const char **)&argv[5] = "128"; + argv[4] = "prefixlen"; + argv[5] = "128"; argc = 6; } else argc = 4; if (!down) { - for (cs = strtok(extrap, " "); cs; cs = strtok(NULL, " ")) { + for (cs = strtok(extrap, " "); cs; + cs = strtok(NULL, " ")) { size_t len = strlen(cs) + 1; - argv[argc] = alloca(len); - strlcpy(argv[argc++], cs, len); + argv[argc++] = acs = alloca(len); + strlcpy(acs, cs, len); } } - *(const char **)&argv[argc] = down ? "-alias" : "alias"; + argv[argc] = down ? "-alias" : "alias"; argv[argc + 1] = NULL; break; #endif case IP_VNET_INTERFACE: argv = alloca(5 * sizeof(char *)); - *(const char **)&argv[0] = _PATH_IFCONFIG; + argv[0] = _PATH_IFCONFIG; argv[1] = comstring->s; - *(const char **)&argv[2] = down ? "-vnet" : "vnet"; + argv[2] = down ? "-vnet" : "vnet"; jidstr = string_param(j->intparams[KP_JID]); - *(const char **)&argv[3] = - jidstr ? jidstr : string_param(j->intparams[KP_NAME]); + argv[3] = jidstr ? jidstr : string_param(j->intparams[KP_NAME]); argv[4] = NULL; break; @@ -454,22 +459,22 @@ run_command(struct cfjail *j) if (down) { argv[4] = NULL; argv[3] = argv[1]; - *(const char **)&argv[0] = "/sbin/umount"; + argv[0] = "/sbin/umount"; } else { if (argc == 4) { argv[7] = NULL; argv[6] = argv[1]; argv[5] = argv[0]; argv[4] = argv[3]; - *(const char **)&argv[3] = "-o"; + argv[3] = "-o"; } else { argv[5] = NULL; argv[4] = argv[1]; argv[3] = argv[0]; } - *(const char **)&argv[0] = _PATH_MOUNT; + argv[0] = _PATH_MOUNT; } - *(const char **)&argv[1] = "-t"; + argv[1] = "-t"; break; case IP_MOUNT_DEVFS: @@ -485,19 +490,19 @@ run_command(struct cfjail *j) down ? "devfs" : NULL) < 0) return -1; if (down) { - *(const char **)&argv[0] = "/sbin/umount"; + argv[0] = "/sbin/umount"; argv[1] = devpath; argv[2] = NULL; } else { - *(const char **)&argv[0] = _PATH_MOUNT; - *(const char **)&argv[1] = "-t"; - *(const char **)&argv[2] = "devfs"; + argv[0] = _PATH_MOUNT; + argv[1] = "-t"; + argv[2] = "devfs"; ruleset = string_param(j->intparams[KP_DEVFS_RULESET]); if (!ruleset) ruleset = "4"; /* devfsrules_jail */ - argv[3] = alloca(11 + strlen(ruleset)); - sprintf(argv[3], "-oruleset=%s", ruleset); - *(const char **)&argv[4] = "."; + argv[3] = acs = alloca(11 + strlen(ruleset)); + sprintf(acs, "-oruleset=%s", ruleset); + argv[4] = "."; argv[5] = devpath; argv[6] = NULL; } @@ -516,14 +521,40 @@ run_command(struct cfjail *j) down ? "fdescfs" : NULL) < 0) return -1; if (down) { - *(const char **)&argv[0] = "/sbin/umount"; + argv[0] = "/sbin/umount"; + argv[1] = devpath; + argv[2] = NULL; + } else { + argv[0] = _PATH_MOUNT; + argv[1] = "-t"; + argv[2] = "fdescfs"; + argv[3] = "."; + argv[4] = devpath; + argv[5] = NULL; + } + break; + + case IP_MOUNT_PROCFS: + argv = alloca(7 * sizeof(char *)); + path = string_param(j->intparams[KP_PATH]); + if (path == NULL) { + jail_warnx(j, "mount.procfs: no path"); + return -1; + } + devpath = alloca(strlen(path) + 6); + sprintf(devpath, "%s/proc", path); + if (check_path(j, "mount.procfs", devpath, 0, + down ? "procfs" : NULL) < 0) + return -1; + if (down) { + argv[0] = "/sbin/umount"; argv[1] = devpath; argv[2] = NULL; } else { - *(const char **)&argv[0] = _PATH_MOUNT; - *(const char **)&argv[1] = "-t"; - *(const char **)&argv[2] = "fdescfs"; - *(const char **)&argv[3] = "."; + argv[0] = _PATH_MOUNT; + argv[1] = "-t"; + argv[2] = "procfs"; + argv[3] = "."; argv[4] = devpath; argv[5] = NULL; } @@ -548,8 +579,8 @@ run_command(struct cfjail *j) if ((cs = strpbrk(comstring->s, "!\"$&'()*;<>?[\\]`{|}~")) && !(cs[0] == '&' && cs[1] == '\0')) { argv = alloca(4 * sizeof(char *)); - *(const char **)&argv[0] = _PATH_BSHELL; - *(const char **)&argv[1] = "-c"; + argv[0] = _PATH_BSHELL; + argv[1] = "-c"; argv[2] = comstring->s; argv[3] = NULL; } else { @@ -668,6 +699,11 @@ run_command(struct cfjail *j) if (term != NULL) setenv("TERM", term, 1); } + if (setgid(pwd->pw_gid) < 0) { + jail_warnx(j, "setgid %d: %s", pwd->pw_gid, + strerror(errno)); + exit(1); + } if (setusercontext(lcap, pwd, pwd->pw_uid, username ? LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN : LOGIN_SETPATH | LOGIN_SETENV) < 0) { @@ -693,7 +729,7 @@ run_command(struct cfjail *j) exit(1); } closefrom(3); - execvp(argv[0], argv); + execvp(argv[0], __DECONST(char *const*, argv)); jail_warnx(j, "exec %s: %s", argv[0], strerror(errno)); exit(1); } diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c index cd02a50..5820209 100644 --- a/usr.sbin/jail/config.c +++ b/usr.sbin/jail/config.c @@ -84,6 +84,7 @@ static const struct ipspec intparams[] = { [IP_MOUNT] = {"mount", PF_INTERNAL | PF_REV}, [IP_MOUNT_DEVFS] = {"mount.devfs", PF_INTERNAL | PF_BOOL}, [IP_MOUNT_FDESCFS] = {"mount.fdescfs", PF_INTERNAL | PF_BOOL}, + [IP_MOUNT_PROCFS] = {"mount.procfs", PF_INTERNAL | PF_BOOL}, [IP_MOUNT_FSTAB] = {"mount.fstab", PF_INTERNAL}, [IP_STOP_TIMEOUT] = {"stop.timeout", PF_INTERNAL | PF_INT}, [IP_VNET_INTERFACE] = {"vnet.interface", PF_INTERNAL}, diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8 index 927e2bb..189fa36 100644 --- a/usr.sbin/jail/jail.8 +++ b/usr.sbin/jail/jail.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 4, 2014 +.Dd February 25, 2015 .Dt JAIL 8 .Os .Sh NAME @@ -276,7 +276,7 @@ Then there are pseudo-parameters that are only used by .Nm itself. .Pp -Jails have a set a core parameters, and kernel modules can add their own +Jails have a set of core parameters, and kernel modules can add their own jail parameters. The current set of available parameters can be retrieved via .Dq Nm sysctl Fl d Va security.jail.param . @@ -362,7 +362,7 @@ A set of IPv6 options for the jail, the counterparts to and .Va ip4 above. -.It vnet +.It Va vnet Create the jail with its own virtual network stack, with its own network interfaces, addresses, routing table, etc. The kernel must have been compiled with the @@ -471,6 +471,14 @@ The .Va jid of the parent of this jail, or zero if this is a top-level jail (read-only). +.It Va osrelease +The string for the jail's +.Va kern.osrelease +sysctl and uname -r. +.It Va osreldate +The number for the jail's +.Va kern.osreldate +and uname -K. .It Va allow.* Some restrictions of the jail environment may be set on a per-jail basis. @@ -531,6 +539,14 @@ is set to a value lower than 2. The devfs ruleset should be restricted from the default by using the .Va devfs_ruleset option. +.It Va allow.mount.fdescfs +privileged users inside the jail will be able to mount and unmount the +fdescfs file system. +This permission is effective only together with +.Va allow.mount +and only when +.Va enforce_statfs +is set to a value lower than 2. .It Va allow.mount.nullfs privileged users inside the jail will be able to mount and unmount the nullfs file system. @@ -687,7 +703,7 @@ jail is created, and will be removed from the interface after the jail is removed. .It Va ip4.addr In addition to the IP addresses that are passed to the kernel, an -interface, netmask and additional paramters (as supported by +interface, netmask and additional parameters (as supported by .Xr ifconfig 8 Ns ) may also be specified, in the form .Dq Ar interface Ns | Ns Ar ip-address Ns / Ns Ar netmask param ... . @@ -745,6 +761,12 @@ Mount a filesystem on the chrooted .Pa /dev/fd directory. +.It Va mount.procfs +Mount a +.Xr procfs 5 +filesystem on the chrooted +.Pa /proc +directory. .It Va allow.dying Allow making changes to a .Va dying @@ -1183,7 +1205,6 @@ environment of the first jail. .Xr pkill 1 , .Xr ps 1 , .Xr quota 1 , -.Xr ifconfig 8 , .Xr jail_set 2 , .Xr devfs 5 , .Xr fdescfs 5 , @@ -1194,6 +1215,7 @@ environment of the first jail. .Xr chroot 8 , .Xr devfs 8 , .Xr halt 8 , +.Xr ifconfig 8 , .Xr inetd 8 , .Xr jexec 8 , .Xr jls 8 , diff --git a/usr.sbin/jail/jail.c b/usr.sbin/jail/jail.c index 661c4ad..e42afa4 100644 --- a/usr.sbin/jail/jail.c +++ b/usr.sbin/jail/jail.c @@ -93,6 +93,7 @@ static const enum intparam startcommands[] = { IP__MOUNT_FROM_FSTAB, IP_MOUNT_DEVFS, IP_MOUNT_FDESCFS, + IP_MOUNT_PROCFS, IP_EXEC_PRESTART, IP__OP, IP_VNET_INTERFACE, @@ -109,6 +110,7 @@ static const enum intparam stopcommands[] = { IP_STOP_TIMEOUT, IP__OP, IP_EXEC_POSTSTOP, + IP_MOUNT_PROCFS, IP_MOUNT_FDESCFS, IP_MOUNT_DEVFS, IP__MOUNT_FROM_FSTAB, @@ -656,11 +658,11 @@ create_jail(struct cfjail *j) * The jail already exists, but may be dying. * Make sure it is, in which case an update is appropriate. */ - *(const void **)&jiov[0].iov_base = "jid"; + jiov[0].iov_base = __DECONST(char *, "jid"); jiov[0].iov_len = sizeof("jid"); jiov[1].iov_base = &jid; jiov[1].iov_len = sizeof(jid); - *(const void **)&jiov[2].iov_base = "dying"; + jiov[2].iov_base = __DECONST(char *, "dying"); jiov[2].iov_len = sizeof("dying"); jiov[3].iov_base = &dying; jiov[3].iov_len = sizeof(dying); @@ -721,11 +723,11 @@ clear_persist(struct cfjail *j) if (!(j->flags & JF_PERSIST)) return; j->flags &= ~JF_PERSIST; - *(const void **)&jiov[0].iov_base = "jid"; + jiov[0].iov_base = __DECONST(char *, "jid"); jiov[0].iov_len = sizeof("jid"); jiov[1].iov_base = &j->jid; jiov[1].iov_len = sizeof(j->jid); - *(const void **)&jiov[2].iov_base = "nopersist"; + jiov[2].iov_base = __DECONST(char *, "nopersist"); jiov[2].iov_len = sizeof("nopersist"); jiov[3].iov_base = NULL; jiov[3].iov_len = 0; @@ -849,12 +851,12 @@ running_jid(struct cfjail *j, int dflag) j->jid = -1; return; } - *(const void **)&jiov[0].iov_base = "jid"; + jiov[0].iov_base = __DECONST(char *, "jid"); jiov[0].iov_len = sizeof("jid"); jiov[1].iov_base = &jid; jiov[1].iov_len = sizeof(jid); } else if ((pval = string_param(j->intparams[KP_NAME]))) { - *(const void **)&jiov[0].iov_base = "name"; + jiov[0].iov_base = __DECONST(char *, "name"); jiov[0].iov_len = sizeof("name"); jiov[1].iov_len = strlen(pval) + 1; jiov[1].iov_base = alloca(jiov[1].iov_len); @@ -880,7 +882,7 @@ jail_quoted_warnx(const struct cfjail *j, const char *name_msg, } /* - * Set jail parameters and possible print them out. + * Set jail parameters and possibly print them out. */ static int jailparam_set_note(const struct cfjail *j, struct jailparam *jp, unsigned njp, diff --git a/usr.sbin/jail/jailp.h b/usr.sbin/jail/jailp.h index 3f89392..bfefca5 100644 --- a/usr.sbin/jail/jailp.h +++ b/usr.sbin/jail/jailp.h @@ -96,6 +96,7 @@ enum intparam { IP_MOUNT, /* Mount points in fstab(5) form */ IP_MOUNT_DEVFS, /* Mount /dev under prison root */ IP_MOUNT_FDESCFS, /* Mount /dev/fd under prison root */ + IP_MOUNT_PROCFS, /* Mount /proc under prison root */ IP_MOUNT_FSTAB, /* A standard fstab(5) file */ IP_STOP_TIMEOUT, /* Time to wait after sending SIGTERM */ IP_VNET_INTERFACE, /* Assign interface(s) to vnet jail */ diff --git a/usr.sbin/jail/state.c b/usr.sbin/jail/state.c index 17b2a0c..b3eb942 100644 --- a/usr.sbin/jail/state.c +++ b/usr.sbin/jail/state.c @@ -60,7 +60,7 @@ dep_setup(int docf) const char *cs; char *pname; size_t plen; - int error, deps, ldeps; + int deps, ldeps; if (!docf) { /* @@ -88,7 +88,6 @@ dep_setup(int docf) TAILQ_FOREACH(j, &cfjails, tq) jails_byname[njails++] = j; qsort(jails_byname, njails, sizeof(struct cfjail *), cmp_jailptr); - error = 0; deps = 0; ldeps = 0; plen = 0; @@ -331,15 +330,15 @@ start_state(const char *target, int docf, unsigned state, int running) * -R matches its wildcards against currently running * jails, not against the config file. */ - *(const void **)&jiov[0].iov_base = "lastjid"; + jiov[0].iov_base = __DECONST(char *, "lastjid"); jiov[0].iov_len = sizeof("lastjid"); jiov[1].iov_base = &jid; jiov[1].iov_len = sizeof(jid); - *(const void **)&jiov[2].iov_base = "jid"; + jiov[2].iov_base = __DECONST(char *, "jid"); jiov[2].iov_len = sizeof("jid"); jiov[3].iov_base = &jid; jiov[3].iov_len = sizeof(jid); - *(const void **)&jiov[4].iov_base = "name"; + jiov[4].iov_base = __DECONST(char *, "name"); jiov[4].iov_len = sizeof("name"); jiov[5].iov_base = &namebuf; jiov[5].iov_len = sizeof(namebuf); @@ -454,12 +453,12 @@ running_jid(const char *name, int flags) int jid; if ((jid = strtol(name, &ep, 10)) && !*ep) { - *(const void **)&jiov[0].iov_base = "jid"; + jiov[0].iov_base = __DECONST(char *, "jid"); jiov[0].iov_len = sizeof("jid"); jiov[1].iov_base = &jid; jiov[1].iov_len = sizeof(jid); } else { - *(const void **)&jiov[0].iov_base = "name"; + jiov[0].iov_base = __DECONST(char *, "name"); jiov[0].iov_len = sizeof("name"); jiov[1].iov_len = strlen(name) + 1; jiov[1].iov_base = alloca(jiov[1].iov_len); diff --git a/usr.sbin/jexec/Makefile b/usr.sbin/jexec/Makefile index 7a2e6821..700da97 100644 --- a/usr.sbin/jexec/Makefile +++ b/usr.sbin/jexec/Makefile @@ -2,7 +2,6 @@ PROG= jexec MAN= jexec.8 -DPADD= ${LIBJAIL} ${LIBUTIL} -LDADD= -ljail -lutil +LIBADD= jail util .include <bsd.prog.mk> diff --git a/usr.sbin/jls/Makefile b/usr.sbin/jls/Makefile index 431fd0c..d90d094 100644 --- a/usr.sbin/jls/Makefile +++ b/usr.sbin/jls/Makefile @@ -4,8 +4,7 @@ PROG= jls MAN= jls.8 -DPADD= ${LIBJAIL} -LDADD= -ljail +LIBADD= jail .if ${MK_INET6_SUPPORT} != "no" CFLAGS+= -DINET6 diff --git a/usr.sbin/jls/jls.8 b/usr.sbin/jls/jls.8 index 3137654..15a80d4 100644 --- a/usr.sbin/jls/jls.8 +++ b/usr.sbin/jls/jls.8 @@ -92,7 +92,8 @@ skipping read-only and unused parameters. Implies .Fl nq . .It Fl v -Print a multiple-line summary per jail, with the following parameters: +Extend the standard display with a multiple-line summary per jail, +containing the following parameters: jail identifier (jid), hostname (host.hostname), path (path), jail name (name), jail state (dying), cpuset ID (cpuset), IP address(es) (ip4.addr and ip6.addr). diff --git a/usr.sbin/jls/jls.c b/usr.sbin/jls/jls.c index ce07100..b1e28fb 100644 --- a/usr.sbin/jls/jls.c +++ b/usr.sbin/jls/jls.c @@ -78,7 +78,7 @@ static void quoted_print(char *str); int main(int argc, char **argv) { - char *dot, *ep, *jname; + char *dot, *ep, *jname, *pname; int c, i, jflags, jid, lastjid, pflags, spc; jname = NULL; @@ -166,20 +166,23 @@ main(int argc, char **argv) JP_USER); add_param("path", NULL, (size_t)0, NULL, JP_USER); } - } else + } else { + pflags &= ~PRINT_VERBOSE; while (optind < argc) add_param(argv[optind++], NULL, (size_t)0, NULL, JP_USER); + } if (pflags & PRINT_SKIP) { /* Check for parameters with jailsys parents. */ for (i = 0; i < nparams; i++) { if ((params[i].jp_flags & JP_USER) && (dot = strchr(params[i].jp_name, '.'))) { - *dot = 0; - param_parent[i] = add_param(params[i].jp_name, + pname = alloca((dot - params[i].jp_name) + 1); + strlcpy(pname, params[i].jp_name, + (dot - params[i].jp_name) + 1); + param_parent[i] = add_param(pname, NULL, (size_t)0, NULL, JP_OPT); - *dot = '.'; } } } @@ -291,10 +294,8 @@ add_param(const char *name, void *value, size_t valuelen, param->jp_flags |= flags; return param - params; } - if (jailparam_init(param, name) < 0) - errx(1, "%s", jail_errmsg); - param->jp_flags = flags; - if ((value != NULL ? jailparam_import_raw(param, value, valuelen) + if (jailparam_init(param, name) < 0 || + (value != NULL ? jailparam_import_raw(param, value, valuelen) : jailparam_import(param, value)) < 0) { if (flags & JP_OPT) { nparams--; @@ -302,6 +303,7 @@ add_param(const char *name, void *value, size_t valuelen, } errx(1, "%s", jail_errmsg); } + param->jp_flags = flags; return param - params; } diff --git a/usr.sbin/kbdcontrol/Makefile b/usr.sbin/kbdcontrol/Makefile index ca1b6e6..42fa3e8 100644 --- a/usr.sbin/kbdcontrol/Makefile +++ b/usr.sbin/kbdcontrol/Makefile @@ -8,7 +8,6 @@ SRCS= kbdcontrol.c lex.l WARNS?= 4 CFLAGS+= -I${.CURDIR} -DPADD= ${LIBL} -LDADD= -ll +LIBADD= l .include <bsd.prog.mk> diff --git a/usr.sbin/kbdcontrol/kbdcontrol.1 b/usr.sbin/kbdcontrol/kbdcontrol.1 index cc37309..ea76b53 100644 --- a/usr.sbin/kbdcontrol/kbdcontrol.1 +++ b/usr.sbin/kbdcontrol/kbdcontrol.1 @@ -230,7 +230,7 @@ So long as the keyboard map file resides in (if using .Xr syscons 4 ) or .Pa /usr/share/vt/keymaps -(if using +(if using .Xr vt 4 ) , you may abbreviate the file name as .Pa ru.koi8-r . diff --git a/usr.sbin/kbdmap/kbdmap.c b/usr.sbin/kbdmap/kbdmap.c index bf2aa81..08c0d77 100644 --- a/usr.sbin/kbdmap/kbdmap.c +++ b/usr.sbin/kbdmap/kbdmap.c @@ -571,7 +571,7 @@ menu_read(void) char *p; int mark, num_keymaps, items, i; char buffer[256], filename[PATH_MAX]; - char keym[64], lng[64], desc[64]; + char keym[64], lng[64], desc[256]; char dialect[64], lang_abk[64]; struct keymap *km; struct keymap **km_sorted; @@ -616,7 +616,7 @@ menu_read(void) continue; /* Parse input, removing newline */ - matches = sscanf(p, "%64[^:]:%64[^:]:%64[^:\n]", + matches = sscanf(p, "%64[^:]:%64[^:]:%256[^:\n]", keym, lng, desc); if (matches == 3) { if (strcmp(keym, "FONT") diff --git a/usr.sbin/keyserv/Makefile b/usr.sbin/keyserv/Makefile index 4308b40..db8a832 100644 --- a/usr.sbin/keyserv/Makefile +++ b/usr.sbin/keyserv/Makefile @@ -6,8 +6,7 @@ SRCS= keyserv.c setkey.c crypt_svc.c crypt_server.c crypt.h CFLAGS+= -DKEYSERV_RANDOM -DBROKEN_DES -I. -DPADD= ${LIBMP} ${LIBCRYPTO} ${LIBRPCSVC} -LDADD= -lmp -lcrypto -lrpcsvc +LIBADD= mp rpcsvc WARNS?= 1 diff --git a/usr.sbin/kgmon/Makefile b/usr.sbin/kgmon/Makefile index bf19401..5f6a2a3 100644 --- a/usr.sbin/kgmon/Makefile +++ b/usr.sbin/kgmon/Makefile @@ -11,7 +11,6 @@ WARNS?= 2 #BINOWN=root #BINMODE=4555 -DPADD= ${LIBKVM} -LDADD= -lkvm +LIBADD= kvm .include <bsd.prog.mk> diff --git a/usr.sbin/kldxref/Makefile b/usr.sbin/kldxref/Makefile index 767cc23..75e74ef 100644 --- a/usr.sbin/kldxref/Makefile +++ b/usr.sbin/kldxref/Makefile @@ -5,7 +5,6 @@ MAN= kldxref.8 SRCS= kldxref.c ef.c ef_obj.c WARNS?= 2 -CFLAGS+=-fno-strict-aliasing .if exists(ef_${MACHINE_CPUARCH}.c) && ${MACHINE_ARCH} != "powerpc64" SRCS+= ef_${MACHINE_CPUARCH}.c diff --git a/usr.sbin/kldxref/kldxref.c b/usr.sbin/kldxref/kldxref.c index 9144ba0..c3784ef 100644 --- a/usr.sbin/kldxref/kldxref.c +++ b/usr.sbin/kldxref/kldxref.c @@ -53,7 +53,7 @@ #include "ef.h" -#define MAXRECSIZE 1024 +#define MAXRECSIZE 8192 #define check(val) if ((error = (val)) != 0) break static int dflag; /* do not create a hint file, only write on stdout */ @@ -172,6 +172,10 @@ parse_entry(struct mod_metadata *md, const char *cval, record_string(kldname); } break; + case MDT_PNP_INFO: + if (dflag) { + printf(" pnp info for bus %s\n", cval); + } default: warnx("unknown metadata record %d in file %s", md->md_type, kldname); } diff --git a/usr.sbin/lmcconfig/Makefile b/usr.sbin/lmcconfig/Makefile index 1ff5055..be00544 100644 --- a/usr.sbin/lmcconfig/Makefile +++ b/usr.sbin/lmcconfig/Makefile @@ -3,8 +3,7 @@ PROG= lmcconfig MAN= lmcconfig.8 -DPADD= ${LIBNETGRAPH} -LDADD= -lnetgraph +LIBADD= netgraph WARNS?= 3 diff --git a/usr.sbin/lpr/Makefile.inc b/usr.sbin/lpr/Makefile.inc index 65535e6..59f8ceb 100644 --- a/usr.sbin/lpr/Makefile.inc +++ b/usr.sbin/lpr/Makefile.inc @@ -6,6 +6,4 @@ CFLAGS+= -DINET6 .endif -LIBLPR= ${.OBJDIR}/../common_source/liblpr.a - .include "../Makefile.inc" diff --git a/usr.sbin/lpr/chkprintcap/Makefile b/usr.sbin/lpr/chkprintcap/Makefile index ffffffb..aa08882 100644 --- a/usr.sbin/lpr/chkprintcap/Makefile +++ b/usr.sbin/lpr/chkprintcap/Makefile @@ -8,7 +8,6 @@ SRCS= chkprintcap.c skimprintcap.c CFLAGS+= -I${.CURDIR}/../common_source -DPADD= ${LIBLPR} -LDADD= ${LIBLPR} +LIBADD= lpr .include <bsd.prog.mk> diff --git a/usr.sbin/lpr/lpc/Makefile b/usr.sbin/lpr/lpc/Makefile index 92ca9e8..43f1f7a 100644 --- a/usr.sbin/lpr/lpc/Makefile +++ b/usr.sbin/lpr/lpc/Makefile @@ -5,7 +5,7 @@ PROG= lpc MAN= lpc.8 -SRCS= lpc.c cmds.c cmdtab.c movejobs.c +SRCS= lpc.c cmds.c cmdtab.c movejobs.c BINGRP= daemon BINMODE= 2555 @@ -13,7 +13,6 @@ CFLAGS+= -I${.CURDIR}/../common_source WARNS?= 0 -DPADD= ${LIBLPR} ${LIBEDIT} ${LIBTERMCAPW} -LDADD= ${LIBLPR} -ledit -ltermcapw +LIBADD= lpr edit .include <bsd.prog.mk> diff --git a/usr.sbin/lpr/lpd/Makefile b/usr.sbin/lpr/lpd/Makefile index 0d7d93e..a35212b 100644 --- a/usr.sbin/lpr/lpd/Makefile +++ b/usr.sbin/lpr/lpd/Makefile @@ -9,7 +9,6 @@ CFLAGS+= -I${.CURDIR}/../common_source WARNS?= 1 -DPADD= ${LIBLPR} -LDADD= ${LIBLPR} +LIBADD= lpr .include <bsd.prog.mk> diff --git a/usr.sbin/lpr/lpq/Makefile b/usr.sbin/lpr/lpq/Makefile index 4df437e..7ea22fa 100644 --- a/usr.sbin/lpr/lpq/Makefile +++ b/usr.sbin/lpr/lpq/Makefile @@ -10,7 +10,6 @@ BINMODE= 6555 CFLAGS+= -I${.CURDIR}/../common_source -DPADD= ${LIBLPR} -LDADD= ${LIBLPR} +LIBADD= lpr .include <bsd.prog.mk> diff --git a/usr.sbin/lpr/lpr/Makefile b/usr.sbin/lpr/lpr/Makefile index 1894b00..2841a79 100644 --- a/usr.sbin/lpr/lpr/Makefile +++ b/usr.sbin/lpr/lpr/Makefile @@ -15,7 +15,6 @@ CFLAGS+= -I${.CURDIR}/../common_source WARNS?= 2 -DPADD= ${LIBLPR} -LDADD= ${LIBLPR} +LIBADD= lpr .include <bsd.prog.mk> diff --git a/usr.sbin/lpr/lpr/lpr.c b/usr.sbin/lpr/lpr/lpr.c index 394ccb0..9a4382f 100644 --- a/usr.sbin/lpr/lpr/lpr.c +++ b/usr.sbin/lpr/lpr/lpr.c @@ -387,8 +387,8 @@ main(int argc, char *argv[]) continue; /* file unreasonable */ if (sflag && (cp = linked(arg)) != NULL) { - (void)snprintf(buf, sizeof(buf), "%u %ju", - statb.st_dev, (uintmax_t)statb.st_ino); + (void)snprintf(buf, sizeof(buf), "%ju %ju", + (uintmax_t)statb.st_dev, (uintmax_t)statb.st_ino); card('S', buf); if (format == 'p') card('T', title ? title : arg); diff --git a/usr.sbin/lpr/lprm/Makefile b/usr.sbin/lpr/lprm/Makefile index 44bc93a..5724d53 100644 --- a/usr.sbin/lpr/lprm/Makefile +++ b/usr.sbin/lpr/lprm/Makefile @@ -12,7 +12,6 @@ BINMODE= 6555 CFLAGS+= -I${.CURDIR}/../common_source -DPADD= ${LIBLPR} -LDADD= ${LIBLPR} +LIBADD= lpr .include <bsd.prog.mk> diff --git a/usr.sbin/lpr/pac/Makefile b/usr.sbin/lpr/pac/Makefile index bd895a7..faf8e58 100644 --- a/usr.sbin/lpr/pac/Makefile +++ b/usr.sbin/lpr/pac/Makefile @@ -8,7 +8,6 @@ MAN= pac.8 CFLAGS+= -I${.CURDIR}/../common_source -DPADD= ${LIBLPR} -LDADD= ${LIBLPR} +LIBADD= lpr .include <bsd.prog.mk> diff --git a/usr.sbin/mailstats/Makefile b/usr.sbin/mailstats/Makefile index bd72fc6..a7911a2 100644 --- a/usr.sbin/mailstats/Makefile +++ b/usr.sbin/mailstats/Makefile @@ -13,14 +13,7 @@ CFLAGS+= -DNOT_SENDMAIL WARNS?= 2 -LIBSMDIR= ${.OBJDIR}/../../lib/libsm -LIBSM= ${LIBSMDIR}/libsm.a - -LIBSMUTILDIR= ${.OBJDIR}/../../lib/libsmutil -LIBSMUTIL= ${LIBSMUTILDIR}/libsmutil.a - -DPADD= ${LIBSMUTIL} ${LIBSM} -LDADD= ${LIBSMUTIL} ${LIBSM} +LIBADD= sm smutil SRCS+= sm_os.h CLEANFILES+=sm_os.h diff --git a/usr.sbin/mailwrapper/Makefile b/usr.sbin/mailwrapper/Makefile index 8e49db7..584cab8 100644 --- a/usr.sbin/mailwrapper/Makefile +++ b/usr.sbin/mailwrapper/Makefile @@ -6,8 +6,7 @@ PROG= mailwrapper MAN= mailwrapper.8 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util .endif .if ${MK_MAILWRAPPER} != "no" || ${MK_SENDMAIL} != "no" diff --git a/usr.sbin/makefs/Makefile b/usr.sbin/makefs/Makefile index 6253148..882fe45 100644 --- a/usr.sbin/makefs/Makefile +++ b/usr.sbin/makefs/Makefile @@ -30,12 +30,6 @@ SRCS+= pack_dev.c SRCS+= ffs_tables.c CFLAGS+= -I${.CURDIR}/../../lib/libnetbsd -LIBNETBSDDIR= ${.OBJDIR}/../../lib/libnetbsd -LIBNETBSD= ${LIBNETBSDDIR}/libnetbsd.a -DPADD+= ${LIBNETBSD} -LDADD+= ${LIBNETBSD} - -DPADD+= ${LIBSBUF} ${LIBUTIL} -LDADD+= -lsbuf -lutil +LIBADD= netbsd util sbuf .include <bsd.prog.mk> diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c index 9fd87ae..1647d8f 100644 --- a/usr.sbin/makefs/ffs.c +++ b/usr.sbin/makefs/ffs.c @@ -191,7 +191,7 @@ ffs_parse_opts(const char *option, fsinfo_t *fsopts) "bytes per inode" }, { "minfree", &ffs_opts->minfree, 0, 99, "minfree" }, - { "maxbpf", &ffs_opts->maxbpg, 1, INT_MAX, + { "maxbpg", &ffs_opts->maxbpg, 1, INT_MAX, "max blocks per file in a cg" }, { "avgfilesize", &ffs_opts->avgfilesize,1, INT_MAX, "expected average file size" }, diff --git a/usr.sbin/makemap/Makefile b/usr.sbin/makemap/Makefile index 80cafcb..ceec1b3 100644 --- a/usr.sbin/makemap/Makefile +++ b/usr.sbin/makemap/Makefile @@ -13,17 +13,7 @@ CFLAGS+= -DNEWDB -DNOT_SENDMAIL WARNS?= 2 -LIBSMDIR= ${.OBJDIR}/../../lib/libsm -LIBSM= ${LIBSMDIR}/libsm.a - -LIBSMDBDIR= ${.OBJDIR}/../../lib/libsmdb -LIBSMDB= ${LIBSMDBDIR}/libsmdb.a - -LIBSMUTILDIR= ${.OBJDIR}/../../lib/libsmutil -LIBSMUTIL= ${LIBSMUTILDIR}/libsmutil.a - -DPADD= ${LIBSMDB} ${LIBSMUTIL} ${LIBSM} -LDADD= ${LIBSMDB} ${LIBSMUTIL} ${LIBSM} +LIBADD= sm smdb smutil SRCS+= sm_os.h CLEANFILES+=sm_os.h diff --git a/usr.sbin/mfiutil/Makefile b/usr.sbin/mfiutil/Makefile index 4fe6f03..dc6f3e4 100644 --- a/usr.sbin/mfiutil/Makefile +++ b/usr.sbin/mfiutil/Makefile @@ -8,8 +8,7 @@ MAN8= mfiutil.8 CFLAGS.gcc+= -fno-builtin-strftime -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util # Here be dragons .ifdef DEBUG diff --git a/usr.sbin/mld6query/mld6.c b/usr.sbin/mld6query/mld6.c index 53f38ae..a3c8342 100644 --- a/usr.sbin/mld6query/mld6.c +++ b/usr.sbin/mld6query/mld6.c @@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$"); #include <signal.h> #include <net/if.h> -#include <net/if_var.h> #include <netinet/in.h> #include <netinet/ip6.h> diff --git a/usr.sbin/mount_smbfs/Makefile b/usr.sbin/mount_smbfs/Makefile index bbc084f..c4c2d1c 100644 --- a/usr.sbin/mount_smbfs/Makefile +++ b/usr.sbin/mount_smbfs/Makefile @@ -8,8 +8,7 @@ MOUNTDIR= ${.CURDIR}/../../sbin/mount CONTRIBDIR= ${.CURDIR}/../../contrib/smbfs CFLAGS+= -DSMBFS -I${MOUNTDIR} -I${CONTRIBDIR}/include -LDADD= -lsmb -lkiconv -DPADD= ${LIBSMB} ${LIBKICONV} +LIBADD= smb .PATH: ${CONTRIBDIR}/mount_smbfs .PATH: ${MOUNTDIR} diff --git a/usr.sbin/mountd/Makefile b/usr.sbin/mountd/Makefile index c141d8a..ab32fa3 100644 --- a/usr.sbin/mountd/Makefile +++ b/usr.sbin/mountd/Makefile @@ -11,7 +11,6 @@ WARNS?= 2 .PATH: ${MOUNT} -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/mountd/mountd.8 b/usr.sbin/mountd/mountd.8 index fe73743..4dbf5ff 100644 --- a/usr.sbin/mountd/mountd.8 +++ b/usr.sbin/mountd/mountd.8 @@ -38,7 +38,7 @@ mount requests .Sh SYNOPSIS .Nm -.Op Fl 2delnorS +.Op Fl 2delnrS .Op Fl h Ar bindip .Op Fl p Ar port .Op Ar exportsfile ... @@ -69,8 +69,7 @@ Output debugging information. will not detach from the controlling terminal and will print debugging messages to stderr. .It Fl e -The new NFS server that includes NFSv4 support is now the default, so this -option is now a no-op and should be considered deprecated. +Ignored; included for backward compatibility. .It Fl h Ar bindip Specify specific IP addresses to bind to for TCP and UDP requests. This option may be specified multiple times. @@ -98,9 +97,6 @@ This should only be specified if there are clients such as PC's, that require it. It will automatically clear the vfs.nfsrv.nfs_privport sysctl flag, which controls if the kernel will accept NFS requests from reserved ports only. -.It Fl o -This flag forces the system to run the old NFS server, which does not -have NFSv4 support in it. .It Fl p Ar port Force .Nm diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index 6e4085c..d916577 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -253,7 +253,6 @@ static int have_v6 = 1; int v4root_phase = 0; char v4root_dirpath[PATH_MAX + 1]; -int run_v4server = 1; int has_publicfh = 0; struct pidfh *pfh = NULL; @@ -312,7 +311,7 @@ main(int argc, char **argv) else close(s); - while ((c = getopt(argc, argv, "2deh:lnop:rS")) != -1) + while ((c = getopt(argc, argv, "2deh:lnp:rS")) != -1) switch (c) { case '2': force_v2 = 1; @@ -332,9 +331,6 @@ main(int argc, char **argv) case 'l': dolog = 1; break; - case 'o': - run_v4server = 0; - break; case 'p': endptr = NULL; svcport = (in_port_t)strtoul(optarg, &endptr, 10); @@ -371,19 +367,9 @@ main(int argc, char **argv) usage(); }; - /* - * Unless the "-o" option was specified, try and run "nfsd". - * If "-o" was specified, try and run "nfsserver". - */ - if (run_v4server > 0) { - if (modfind("nfsd") < 0) { - /* Not present in kernel, try loading it */ - if (kldload("nfsd") < 0 || modfind("nfsd") < 0) - errx(1, "NFS server is not available"); - } - } else if (modfind("nfsserver") < 0) { + if (modfind("nfsd") < 0) { /* Not present in kernel, try loading it */ - if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0) + if (kldload("nfsd") < 0 || modfind("nfsd") < 0) errx(1, "NFS server is not available"); } @@ -627,7 +613,6 @@ create_service(struct netconfig *nconf) /* Get mountd's address on this transport */ memset(&hints, 0, sizeof hints); - hints.ai_flags = AI_PASSIVE; hints.ai_family = si.si_af; hints.ai_socktype = si.si_socktype; hints.ai_protocol = si.si_proto; @@ -644,6 +629,8 @@ create_service(struct netconfig *nconf) sock_fd[sock_fdcnt++] = -1; /* Set invalid for now. */ mallocd_res = 0; + hints.ai_flags = AI_PASSIVE; + /* * XXX - using RPC library internal functions. */ @@ -1423,6 +1410,9 @@ get_exportlist_one(void) } if (check_dirpath(cp) && statfs(cp, &fsb) >= 0) { + if ((fsb.f_flags & MNT_AUTOMOUNTED) != 0) + syslog(LOG_ERR, "Warning: exporting of " + "automounted fs %s not supported", cp); if (got_nondir) { syslog(LOG_ERR, "dirs must be first"); getexp_err(ep, tgrp); @@ -1696,8 +1686,7 @@ get_exportlist(void) */ bzero(&eargs, sizeof (eargs)); eargs.export.ex_flags = MNT_DELEXPORT; - if (run_v4server > 0 && - nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&eargs) < 0 && + if (nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&eargs) < 0 && errno != ENOENT) syslog(LOG_ERR, "Can't delete exports for V4:"); @@ -1731,6 +1720,12 @@ get_exportlist(void) } /* + * We do not need to delete "export" flag from + * filesystems that do not have it set. + */ + if (!(fsp->f_flags & MNT_EXPORTED)) + continue; + /* * Do not delete export for network filesystem by * passing "export" arg to nmount(). * It only makes sense to do this for local filesystems. @@ -1746,8 +1741,12 @@ get_exportlist(void) iov[5].iov_len = strlen(fsp->f_mntfromname) + 1; errmsg[0] = '\0'; + /* + * EXDEV is returned when path exists but is not a + * mount point. May happens if raced with unmount. + */ if (nmount(iov, iovlen, fsp->f_flags) < 0 && - errno != ENOENT && errno != ENOTSUP) { + errno != ENOENT && errno != ENOTSUP && errno != EXDEV) { syslog(LOG_ERR, "can't delete exports for %s: %m %s", fsp->f_mntonname, errmsg); @@ -1792,7 +1791,7 @@ get_exportlist(void) /* * If there was no public fh, clear any previous one set. */ - if (run_v4server > 0 && has_publicfh == 0) + if (has_publicfh == 0) (void) nfssvc(NFSSVC_NOPUBLICFH, NULL); /* Resume the nfsd. If they weren't suspended, this is harmless. */ @@ -2389,7 +2388,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp, int exflags, { struct statfs fsb1; struct addrinfo *ai; - struct export_args ea, *eap; + struct export_args *eap; char errmsg[255]; char *cp; int done; @@ -2399,10 +2398,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp, int exflags, int ret; struct nfsex_args nfsea; - if (run_v4server > 0) - eap = &nfsea.export; - else - eap = &ea; + eap = &nfsea.export; cp = NULL; savedc = '\0'; @@ -2482,8 +2478,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp, int exflags, */ if (v4root_phase == 2) { nfsea.fspec = v4root_dirpath; - if (run_v4server > 0 && - nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&nfsea) < 0) { + if (nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&nfsea) < 0) { syslog(LOG_ERR, "Exporting V4: failed"); return (2); } @@ -2572,7 +2567,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp, int exflags, * If this is the public directory, get the file handle * and load it into the kernel via the nfssvc() syscall. */ - if (run_v4server > 0 && (exflags & MNT_EXPUBLIC) != 0) { + if ((exflags & MNT_EXPUBLIC) != 0) { fhandle_t fh; char *public_name; diff --git a/usr.sbin/moused/Makefile b/usr.sbin/moused/Makefile index a313a21..0f9eac5 100644 --- a/usr.sbin/moused/Makefile +++ b/usr.sbin/moused/Makefile @@ -3,8 +3,7 @@ PROG= moused MAN= moused.8 -DPADD= ${LIBUTIL} ${LIBM} -LDADD= -lutil -lm +LIBADD= m util #BINMODE=4555 #PRECIOUSPROG= diff --git a/usr.sbin/mptutil/Makefile b/usr.sbin/mptutil/Makefile index 53d75b3..2054c26 100644 --- a/usr.sbin/mptutil/Makefile +++ b/usr.sbin/mptutil/Makefile @@ -8,8 +8,7 @@ MAN= mptutil.8 WARNS?= 3 -DPADD= ${LIBCAM} ${LIBSBUF} ${LIBUTIL} -LDADD= -lcam -lsbuf -lutil +LIBADD= cam util # Here be dragons .ifdef DEBUG diff --git a/usr.sbin/mtree/Makefile b/usr.sbin/mtree/Makefile index 1ceb52e..6d060e2 100644 --- a/usr.sbin/mtree/Makefile +++ b/usr.sbin/mtree/Makefile @@ -11,12 +11,11 @@ SRCS= compare.c crc.c create.c excludes.c misc.c mtree.c spec.c verify.c SRCS+= specspec.c CFLAGS+= -DMD5 -DSHA1 -DRMD160 -DSHA256 -DPADD= ${LIBMD} -LDADD= -lmd +LIBADD= md CLEANFILES+= fmtree.8 fmtree.8: mtree.8 - cp -f ${.ALLSRC} ${.TARGET} + ${CP} ${.ALLSRC} ${.TARGET} .include <bsd.prog.mk> diff --git a/usr.sbin/mtree/verify.c b/usr.sbin/mtree/verify.c index b7c4fd9..c9291c0 100644 --- a/usr.sbin/mtree/verify.c +++ b/usr.sbin/mtree/verify.c @@ -233,7 +233,7 @@ miss(NODE *p, char *tail) miss(p->child, tp + 1); *tp = '\0'; - if (!create) + if (!create && !uflag) continue; if (chown(path, p->st_uid, p->st_gid) == -1) { serr = errno; diff --git a/usr.sbin/nandsim/nandsim.8 b/usr.sbin/nandsim/nandsim.8 index c7bdb9a..d89767b 100644 --- a/usr.sbin/nandsim/nandsim.8 +++ b/usr.sbin/nandsim/nandsim.8 @@ -217,7 +217,7 @@ All commands issues to any chip on this controller are ignored. .El .Sh SEE ALSO .Xr nand 4 , -.Xr nandsim 4 +.Xr nandsim 4 , .Xr nandsim.conf 5 .Sh HISTORY The diff --git a/usr.sbin/nandtool/Makefile b/usr.sbin/nandtool/Makefile index ae9de2d..c01c2fd 100644 --- a/usr.sbin/nandtool/Makefile +++ b/usr.sbin/nandtool/Makefile @@ -4,8 +4,7 @@ PROG= nandtool SRCS= nandtool.c nand_read.c nand_write.c nand_erase.c nand_info.c SRCS+= nand_readoob.c nand_writeoob.c BINDIR= /usr/sbin -DPADD= ${LIBGEOM} -LDADD= -lgeom +LIBADD= geom MAN= nandtool.8 .include <bsd.prog.mk> diff --git a/usr.sbin/ndiscvt/Makefile b/usr.sbin/ndiscvt/Makefile index b11b4b0..3322a53 100644 --- a/usr.sbin/ndiscvt/Makefile +++ b/usr.sbin/ndiscvt/Makefile @@ -13,8 +13,7 @@ MAN+= ndisgen.8 WARNS?= 4 NO_WCAST_ALIGN= -DPADD= ${LIBL} -LDADD= -ll +LIBADD= l YFLAGS+=-v diff --git a/usr.sbin/ndiscvt/Makefile.depend b/usr.sbin/ndiscvt/Makefile.depend index 35458af..4fe82d8 100644 --- a/usr.sbin/ndiscvt/Makefile.depend +++ b/usr.sbin/ndiscvt/Makefile.depend @@ -11,6 +11,7 @@ DIRDEPS = \ lib/libc \ lib/libcompiler_rt \ usr.bin/lex/lib \ + usr.bin/yacc.host \ .include <dirdeps.mk> diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index e896010..339a4b6 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -83,7 +83,6 @@ #include <sys/queue.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_dl.h> #include <net/if_types.h> #include <net/route.h> diff --git a/usr.sbin/nfsd/nfsd.8 b/usr.sbin/nfsd/nfsd.8 index 660e5e8..d014a01 100644 --- a/usr.sbin/nfsd/nfsd.8 +++ b/usr.sbin/nfsd/nfsd.8 @@ -28,7 +28,7 @@ .\" @(#)nfsd.8 8.4 (Berkeley) 3/29/95 .\" $FreeBSD$ .\" -.Dd August 10, 2014 +.Dd April 25, 2015 .Dt NFSD 8 .Os .Sh NAME @@ -38,11 +38,11 @@ server .Sh SYNOPSIS .Nm -.Op Fl arduteo +.Op Fl ardute .Op Fl n Ar num_servers .Op Fl h Ar bindip -.Op Fl maxthreads Ar max_threads -.Op Fl minthreads Ar min_threads +.Op Fl Fl maxthreads Ar max_threads +.Op Fl Fl minthreads Ar min_threads .Sh DESCRIPTION The .Nm @@ -78,14 +78,14 @@ service with without creating any servers. .It Fl n Ar threads Specifies how many servers to create. This option is equivalent to specifying -.Fl maxthreads +.Fl Fl maxthreads and -.Fl minthreads +.Fl Fl minthreads with their respective arguments to .Ar threads . -.It Fl maxthreads Ar threads +.It Fl Fl maxthreads Ar threads Specifies the maximum servers that will be kept around to service requests. -.It Fl minthreads Ar threads +.It Fl Fl minthreads Ar threads Specifies the minimum servers that will be kept around to service requests. .It Fl h Ar bindip Specifies which IP address or hostname to bind to on the local host. @@ -112,11 +112,7 @@ Serve .Tn UDP NFS clients. .It Fl e -The new NFS server that includes NFSv4 support is now the default, so this -option is now a no-op and should be considered deprecated. -.It Fl o -Forces the use of the old NFS server that does not include NFSv4 support -in it. +Ignored; included for backward compatibility. .El .Pp For example, diff --git a/usr.sbin/nfsd/nfsd.c b/usr.sbin/nfsd/nfsd.c index b114ba6..f58ed30 100644 --- a/usr.sbin/nfsd/nfsd.c +++ b/usr.sbin/nfsd/nfsd.c @@ -87,8 +87,6 @@ static int nfsdcnt; /* number of children */ static int nfsdcnt_set; static int minthreads; static int maxthreads; -static int new_syscall; -static int run_v4server = 1; /* Force running of nfsv4 server */ static int nfssvc_nfsd; /* Set to correct NFSSVC_xxx flag */ static int stablefd = -1; /* Fd for the stable restart file */ static int backupfd; /* Fd for the backup stable restart file */ @@ -156,7 +154,7 @@ main(int argc, char **argv) socklen_t len; int on = 1, unregister, reregister, sock; int tcp6sock, ip6flag, tcpflag, tcpsock; - int udpflag, ecode, error, s, srvcnt; + int udpflag, ecode, error, s; int bindhostc, bindanyflag, rpcbreg, rpcbregcnt; int nfssvc_addsock; int longindex = 0; @@ -167,10 +165,10 @@ main(int argc, char **argv) nfsdcnt = DEFNFSDCNT; unregister = reregister = tcpflag = maxsock = 0; bindanyflag = udpflag = connect_type_cnt = bindhostc = 0; - getopt_shortopts = "ah:n:rdtueo"; + getopt_shortopts = "ah:n:rdtue"; getopt_usage = "usage:\n" - " nfsd [-ardtueo] [-h bindip]\n" + " nfsd [-ardtue] [-h bindip]\n" " [-n numservers] [--minthreads #] [--maxthreads #]\n"; while ((ch = getopt_long(argc, argv, getopt_shortopts, longopts, &longindex)) != -1) @@ -205,9 +203,6 @@ main(int argc, char **argv) case 'e': /* now a no-op, since this is the default */ break; - case 'o': - run_v4server = 0; - break; case 0: lopt = longopts[longindex].name; if (!strcmp(lopt, "minthreads")) { @@ -242,15 +237,9 @@ main(int argc, char **argv) * Unless the "-o" option was specified, try and run "nfsd". * If "-o" was specified, try and run "nfsserver". */ - if (run_v4server > 0) { - if (modfind("nfsd") < 0) { - /* Not present in kernel, try loading it */ - if (kldload("nfsd") < 0 || modfind("nfsd") < 0) - errx(1, "NFS server is not available"); - } - } else if (modfind("nfsserver") < 0) { + if (modfind("nfsd") < 0) { /* Not present in kernel, try loading it */ - if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0) + if (kldload("nfsd") < 0 || modfind("nfsd") < 0) errx(1, "NFS server is not available"); } @@ -392,55 +381,21 @@ main(int argc, char **argv) * level write-back caching. (See SCSI doc for more information * on how to prevent write-back caching on SCSI disks.) */ - if (run_v4server > 0) { - open_stable(&stablefd, &backupfd); - if (stablefd < 0) { - syslog(LOG_ERR, "Can't open %s: %m\n", NFSD_STABLERESTART); - exit(1); - } - /* This system call will fail for old kernels, but that's ok. */ - nfssvc(NFSSVC_BACKUPSTABLE, NULL); - if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) { - syslog(LOG_ERR, "Can't read stable storage file: %m\n"); - exit(1); - } - nfssvc_addsock = NFSSVC_NFSDADDSOCK; - nfssvc_nfsd = NFSSVC_NFSDNFSD; - new_syscall = TRUE; - } else { - nfssvc_addsock = NFSSVC_ADDSOCK; - nfssvc_nfsd = NFSSVC_NFSD; - /* - * Figure out if the kernel supports the new-style - * NFSSVC_NFSD. Old kernels will return ENXIO because they - * don't recognise the flag value, new ones will return EINVAL - * because argp is NULL. - */ - new_syscall = FALSE; - if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL) - new_syscall = TRUE; + open_stable(&stablefd, &backupfd); + if (stablefd < 0) { + syslog(LOG_ERR, "Can't open %s: %m\n", NFSD_STABLERESTART); + exit(1); } + /* This system call will fail for old kernels, but that's ok. */ + nfssvc(NFSSVC_BACKUPSTABLE, NULL); + if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) { + syslog(LOG_ERR, "Can't read stable storage file: %m\n"); + exit(1); + } + nfssvc_addsock = NFSSVC_NFSDADDSOCK; + nfssvc_nfsd = NFSSVC_NFSDNFSD; - if (!new_syscall) { - /* If we use UDP only, we start the last server below. */ - srvcnt = tcpflag ? nfsdcnt : nfsdcnt - 1; - for (i = 0; i < srvcnt; i++) { - switch ((pid = fork())) { - case -1: - syslog(LOG_ERR, "fork: %m"); - nfsd_exit(1); - case 0: - break; - default: - children[i] = pid; - continue; - } - (void)signal(SIGUSR1, child_cleanup); - setproctitle("server"); - - start_server(0); - } - } else if (tcpflag) { + if (tcpflag) { /* * For TCP mode, we fork once to start the first * kernel nfsd thread. The kernel will add more @@ -626,7 +581,7 @@ main(int argc, char **argv) bindhost[i]); nfsd_exit(1); } - if (listen(tcpsock, 5) < 0) { + if (listen(tcpsock, -1) < 0) { syslog(LOG_ERR, "listen failed"); nfsd_exit(1); } @@ -701,7 +656,7 @@ main(int argc, char **argv) bindhost[i]); nfsd_exit(1); } - if (listen(tcp6sock, 5) < 0) { + if (listen(tcp6sock, -1) < 0) { syslog(LOG_ERR, "listen failed"); nfsd_exit(1); } @@ -976,11 +931,6 @@ get_tuned_nfsdcount(void) } else { tuned_nfsdcnt = ncpu * 8; } - if (!new_syscall && tuned_nfsdcnt > MAXNFSDCNT) { - warnx("nfsd count %d; truncated to %d", tuned_nfsdcnt, - MAXNFSDCNT); - tuned_nfsdcnt = MAXNFSDCNT; - } return tuned_nfsdcnt; } @@ -994,55 +944,48 @@ start_server(int master) struct addrinfo *aip, hints; status = 0; - if (new_syscall) { - gethostname(hostname, sizeof (hostname)); - snprintf(principal, sizeof (principal), "nfs@%s", hostname); - if ((cp = strchr(hostname, '.')) == NULL || - *(cp + 1) == '\0') { - /* If not fully qualified, try getaddrinfo() */ - memset((void *)&hints, 0, sizeof (hints)); - hints.ai_flags = AI_CANONNAME; - error = getaddrinfo(hostname, NULL, &hints, &aip); - if (error == 0) { - if (aip->ai_canonname != NULL && - (cp = strchr(aip->ai_canonname, '.')) != - NULL && *(cp + 1) != '\0') - snprintf(principal, sizeof (principal), - "nfs@%s", aip->ai_canonname); - freeaddrinfo(aip); - } + gethostname(hostname, sizeof (hostname)); + snprintf(principal, sizeof (principal), "nfs@%s", hostname); + if ((cp = strchr(hostname, '.')) == NULL || + *(cp + 1) == '\0') { + /* If not fully qualified, try getaddrinfo() */ + memset((void *)&hints, 0, sizeof (hints)); + hints.ai_flags = AI_CANONNAME; + error = getaddrinfo(hostname, NULL, &hints, &aip); + if (error == 0) { + if (aip->ai_canonname != NULL && + (cp = strchr(aip->ai_canonname, '.')) != + NULL && *(cp + 1) != '\0') + snprintf(principal, sizeof (principal), + "nfs@%s", aip->ai_canonname); + freeaddrinfo(aip); } - nfsdargs.principal = principal; + } + nfsdargs.principal = principal; - if (nfsdcnt_set) - nfsdargs.minthreads = nfsdargs.maxthreads = nfsdcnt; - else { - nfsdargs.minthreads = minthreads_set ? minthreads : get_tuned_nfsdcount(); - nfsdargs.maxthreads = maxthreads_set ? maxthreads : nfsdargs.minthreads; - if (nfsdargs.maxthreads < nfsdargs.minthreads) - nfsdargs.maxthreads = nfsdargs.minthreads; - } + if (nfsdcnt_set) + nfsdargs.minthreads = nfsdargs.maxthreads = nfsdcnt; + else { + nfsdargs.minthreads = minthreads_set ? minthreads : get_tuned_nfsdcount(); + nfsdargs.maxthreads = maxthreads_set ? maxthreads : nfsdargs.minthreads; + if (nfsdargs.maxthreads < nfsdargs.minthreads) + nfsdargs.maxthreads = nfsdargs.minthreads; + } + error = nfssvc(nfssvc_nfsd, &nfsdargs); + if (error < 0 && errno == EAUTH) { + /* + * This indicates that it could not register the + * rpcsec_gss credentials, usually because the + * gssd daemon isn't running. + * (only the experimental server with nfsv4) + */ + syslog(LOG_ERR, "No gssd, using AUTH_SYS only"); + principal[0] = '\0'; error = nfssvc(nfssvc_nfsd, &nfsdargs); - if (error < 0 && errno == EAUTH) { - /* - * This indicates that it could not register the - * rpcsec_gss credentials, usually because the - * gssd daemon isn't running. - * (only the experimental server with nfsv4) - */ - syslog(LOG_ERR, "No gssd, using AUTH_SYS only"); - principal[0] = '\0'; - error = nfssvc(nfssvc_nfsd, &nfsdargs); - } - if (error < 0) { - syslog(LOG_ERR, "nfssvc: %m"); - status = 1; - } - } else { - if (nfssvc(NFSSVC_OLDNFSD, NULL) < 0) { - syslog(LOG_ERR, "nfssvc: %m"); - status = 1; - } + } + if (error < 0) { + syslog(LOG_ERR, "nfssvc: %m"); + status = 1; } if (master) nfsd_exit(status); diff --git a/usr.sbin/nfsuserd/nfsuserd.8 b/usr.sbin/nfsuserd/nfsuserd.8 index 04100ea..6e170db 100644 --- a/usr.sbin/nfsuserd/nfsuserd.8 +++ b/usr.sbin/nfsuserd/nfsuserd.8 @@ -89,12 +89,12 @@ performance impact, whereas running too many will only tie up some resources, such as a process table entry and swap space. .El .Sh SEE ALSO -.Xr getpwent 3 , .Xr getgrent 3 , +.Xr getpwent 3 , .Xr nfsv4 4 , .Xr group 5 , .Xr passwd 5 , -.Xr nfsd 8 . +.Xr nfsd 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/ngctl/Makefile b/usr.sbin/ngctl/Makefile index cf72f39..71b5d2b 100644 --- a/usr.sbin/ngctl/Makefile +++ b/usr.sbin/ngctl/Makefile @@ -17,13 +17,11 @@ NGCTL_NO_LIBEDIT= NGCTL_NO_LIBEDIT= .endif -DPADD= ${LIBNETGRAPH} -LDADD= -lnetgraph +LIBADD= netgraph .if !defined(NGCTL_NO_LIBEDIT) CFLAGS+= -DEDITLINE -DPADD+= ${LIBPTHREAD} ${LIBEDIT} ${LIBTERMCAPW} -LDADD+= -lpthread -ledit -ltermcapw +LIBADD+= edit pthread .endif .include <bsd.prog.mk> diff --git a/usr.sbin/ngctl/main.c b/usr.sbin/ngctl/main.c index 3581386..4b1cdab 100644 --- a/usr.sbin/ngctl/main.c +++ b/usr.sbin/ngctl/main.c @@ -324,8 +324,10 @@ DoInteractive(void) history(hist, &hev, H_ENTER, buf); pthread_kill(monitor, SIGUSR1); pthread_mutex_lock(&mutex); - if (DoParseCommand(buf) == CMDRTN_QUIT) + if (DoParseCommand(buf) == CMDRTN_QUIT) { + pthread_mutex_unlock(&mutex); break; + } pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); } diff --git a/usr.sbin/nghook/Makefile b/usr.sbin/nghook/Makefile index e427f26..8a63d82 100644 --- a/usr.sbin/nghook/Makefile +++ b/usr.sbin/nghook/Makefile @@ -5,7 +5,6 @@ PROG= nghook MAN= nghook.8 SRCS= main.c -DPADD= ${LIBNETGRAPH} -LDADD= -lnetgraph +LIBADD= netgraph .include <bsd.prog.mk> diff --git a/usr.sbin/nmtree/Makefile b/usr.sbin/nmtree/Makefile index 5789ad8..03af6d6 100644 --- a/usr.sbin/nmtree/Makefile +++ b/usr.sbin/nmtree/Makefile @@ -8,18 +8,13 @@ PROG= mtree MAN= mtree.5 mtree.8 SRCS= compare.c crc.c create.c excludes.c getid.c misc.c mtree.c \ only.c spec.c specspec.c verify.c -DPADD+= ${LIBMD} ${LIBUTIL} -LDADD+= -lmd -lutil CFLAGS+= -I${.CURDIR}/../../contrib/mknod .PATH: ${.CURDIR}/../../contrib/mknod SRCS+= pack_dev.c CFLAGS+= -I${.CURDIR}/../../lib/libnetbsd -LIBNETBSDDIR= ${.OBJDIR}/../../lib/libnetbsd -LIBNETBSD= ${LIBNETBSDDIR}/libnetbsd.a -DPADD+= ${LIBNETBSD} -LDADD+= ${LIBNETBSD} +LIBADD= netbsd md util LINKS= ${BINDIR}/mtree ${BINDIR}/nmtree MLINKS= mtree.8 nmtree.8 diff --git a/usr.sbin/nscd/Makefile b/usr.sbin/nscd/Makefile index 298e163..96a2e8a 100644 --- a/usr.sbin/nscd/Makefile +++ b/usr.sbin/nscd/Makefile @@ -8,8 +8,8 @@ SRCS= agent.c nscd.c nscdcli.c cachelib.c cacheplcs.c debug.c log.c \ config.c query.c mp_ws_query.c mp_rs_query.c singletons.c protocol.c \ parser.c CFLAGS+= -DCONFIG_PATH="\"${PREFIX}/etc/nscd.conf\"" -DPADD= ${LIBM} ${LIBPTHREAD} ${LIBUTIL} -LDADD= -lm -lpthread -lutil + +LIBADD= util pthread .PATH: ${.CURDIR}/agents .include "${.CURDIR}/agents/Makefile.inc" diff --git a/usr.sbin/ntp/Makefile b/usr.sbin/ntp/Makefile index 31ee564..962e60f 100644 --- a/usr.sbin/ntp/Makefile +++ b/usr.sbin/ntp/Makefile @@ -1,7 +1,7 @@ # Makefile for ntpd. # $FreeBSD$ -SUBDIR= libopts libntp libparse ntpd ntpdc ntpq ntpdate \ +SUBDIR= libopts libntp libntpevent libparse ntpd ntpdc ntpq ntpdate \ ntptime ntp-keygen sntp SUBDIR+= doc diff --git a/usr.sbin/ntp/Makefile.inc b/usr.sbin/ntp/Makefile.inc index cadd4c7..755fbee 100644 --- a/usr.sbin/ntp/Makefile.inc +++ b/usr.sbin/ntp/Makefile.inc @@ -14,10 +14,6 @@ CFLAGS+= ${NTPDEFS} ${DEFS_LOCAL} ${CLOCKDEFS} CFLAGS+= -DOPENSSL .endif -LIBOPTS= ${.OBJDIR}/../libopts/libopts.a -LIBPARSE= ${.OBJDIR}/../libparse/libparse.a -LIBNTP= ${.OBJDIR}/../libntp/libntp.a - WARNS?= 0 .include "../Makefile.inc" diff --git a/usr.sbin/ntp/config.h b/usr.sbin/ntp/config.h index d4b3685..8bcf6e6 100644 --- a/usr.sbin/ntp/config.h +++ b/usr.sbin/ntp/config.h @@ -1,27 +1,30 @@ -/* config.h. Generated by configure. */ +/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* $FreeBSD$ */ +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + /* Is adjtime() accurate? */ /* #undef ADJTIME_IS_ACCURATE */ -/* CHU audio/decoder? */ -/* #undef AUDIO_CHU */ +/* Support NTP Autokey protocol? */ +#define AUTOKEY 1 -/* Declare char *sys_errlist array */ -/* #undef CHAR_SYS_ERRLIST */ +/* why not HAVE_P_S? */ +/* #undef CALL_PTHREAD_SETCONCURRENCY */ /* ACTS modem service */ -/* #undef CLOCK_ACTS */ +#define CLOCK_ACTS 1 /* Arbiter 1088A/B GPS receiver */ -/* #undef CLOCK_ARBITER */ +#define CLOCK_ARBITER 1 /* ARCRON support? */ -/* #undef CLOCK_ARCRON_MSF */ +#define CLOCK_ARCRON_MSF 1 /* Austron 2200A/2201A GPS receiver? */ -/* #undef CLOCK_AS2201 */ +#define CLOCK_AS2201 1 /* PPS interface? */ #define CLOCK_ATOM 1 @@ -30,16 +33,16 @@ /* #undef CLOCK_BANC */ /* Chronolog K-series WWVB receiver? */ -/* #undef CLOCK_CHRONOLOG */ +#define CLOCK_CHRONOLOG 1 /* CHU modem/decoder */ -/* #undef CLOCK_CHU */ +#define CLOCK_CHU 1 /* Diems Computime Radio Clock? */ /* #undef CLOCK_COMPUTIME */ /* Datum Programmable Time System? */ -/* #undef CLOCK_DATUM */ +#define CLOCK_DATUM 1 /* ELV/DCF7000 clock? */ /* #undef CLOCK_DCF7000 */ @@ -48,37 +51,40 @@ #define CLOCK_DUMBCLOCK 1 /* Forum Graphic GPS datating station driver? */ -/* #undef CLOCK_FG */ +#define CLOCK_FG 1 + +/* GPSD JSON receiver */ +#define CLOCK_GPSDJSON 1 /* TrueTime GPS receiver/VME interface? */ /* #undef CLOCK_GPSVME */ /* Heath GC-1000 WWV/WWVH receiver? */ -/* #undef CLOCK_HEATH */ +#define CLOCK_HEATH 1 /* HOPF 6021 clock? */ /* #undef CLOCK_HOPF6021 */ /* HOPF PCI clock device? */ -/* #undef CLOCK_HOPF_PCI */ +#define CLOCK_HOPF_PCI 1 /* HOPF serial clock device? */ -/* #undef CLOCK_HOPF_SERIAL */ +#define CLOCK_HOPF_SERIAL 1 /* HP 58503A GPS receiver? */ -/* #undef CLOCK_HPGPS */ +#define CLOCK_HPGPS 1 /* IRIG audio decoder? */ -/* #undef CLOCK_IRIG */ +#define CLOCK_IRIG 1 /* JJY receiver? */ -/* #undef CLOCK_JJY */ +#define CLOCK_JJY 1 /* Rockwell Jupiter GPS clock? */ -/* #undef CLOCK_JUPITER */ +#define CLOCK_JUPITER 1 /* Leitch CSD 5300 Master Clock System Driver? */ -/* #undef CLOCK_LEITCH */ +#define CLOCK_LEITCH 1 /* local clock reference? */ #define CLOCK_LOCAL 1 @@ -90,7 +96,7 @@ /* #undef CLOCK_MX4200 */ /* NeoClock4X */ -/* #undef CLOCK_NEOCLOCK4X */ +#define CLOCK_NEOCLOCK4X 1 /* NMEA GPS receiver */ #define CLOCK_NMEA 1 @@ -99,22 +105,22 @@ #define CLOCK_ONCORE 1 /* Palisade clock */ -/* #undef CLOCK_PALISADE */ +#define CLOCK_PALISADE 1 /* PARSE driver interface */ #define CLOCK_PARSE 1 /* Conrad parallel port radio clock */ -/* #undef CLOCK_PCF */ +#define CLOCK_PCF 1 /* PCL 720 clock support */ /* #undef CLOCK_PPS720 */ /* PST/Traconex 1020 WWV/WWVH receiver */ -/* #undef CLOCK_PST */ +#define CLOCK_PST 1 /* DCF77 raw time code */ -#define CLOCK_RAWDCF 1 +/* #undef CLOCK_RAWDCF */ /* RCC 8000 clock */ /* #undef CLOCK_RCC8000 */ @@ -125,11 +131,14 @@ /* Schmid DCF77 clock */ /* #undef CLOCK_SCHMID */ +/* SEL240X protocol */ +/* #undef CLOCK_SEL240X */ + /* clock thru shared memory */ -#define CLOCK_SHM +#define CLOCK_SHM 1 /* Spectracom 8170/Netclock/2 WWVB receiver */ -/* #undef CLOCK_SPECTRACOM */ +#define CLOCK_SPECTRACOM 1 /* KSI/Odetics TPRO/S GPS receiver/IRIG interface */ /* #undef CLOCK_TPRO */ @@ -141,28 +150,39 @@ /* #undef CLOCK_TRIMTSIP */ /* Kinemetrics/TrueTime receivers */ -/* #undef CLOCK_TRUETIME */ +#define CLOCK_TRUETIME 1 + +/* Spectracom TSYNC timing board */ +/* #undef CLOCK_TSYNCPCI */ /* TrueTime 560 IRIG-B decoder? */ /* #undef CLOCK_TT560 */ /* Ultralink M320 WWVB receiver? */ -/* #undef CLOCK_ULINK */ +#define CLOCK_ULINK 1 -/* VARITEXT protocol */ +/* VARITEXT clock */ /* #undef CLOCK_VARITEXT */ -/* WHARTON 400A Series protocol */ +/* WHARTON 400A Series clock */ /* #undef CLOCK_WHARTON_400A */ /* WWV audio driver */ -/* #undef CLOCK_WWV */ +#define CLOCK_WWV 1 /* Zyfer GPStarplus */ -/* #undef CLOCK_ZYFER */ +#define CLOCK_ZYFER 1 + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ -/* Enable debugging? */ -/* #undef DEBUG */ +/* Enable debugging code? */ +#define DEBUG 1 /* Enable processing time debugging? */ /* #undef DEBUG_TIMING */ @@ -246,7 +266,7 @@ /* #undef DECL_STRTOL_0 */ /* Declare syscall()? */ -#define DECL_SYSCALL 1 +/* #undef DECL_SYSCALL */ /* Declaration style */ /* #undef DECL_SYSLOG_0 */ @@ -266,17 +286,29 @@ /* What is the fallback value for HZ? */ #define DEFAULT_HZ 100 +/* Default number of megabytes for RLIMIT_MEMLOCK */ +#define DFLT_RLIMIT_MEMLOCK 32 + +/* Default number of 4k pages for RLIMIT_STACK */ +#define DFLT_RLIMIT_STACK 50 + +/* Directory separator character, usually / or \\ */ +#define DIR_SEP '/' + +/* use old autokey session key behavior? */ +/* #undef DISABLE_BUG1243_FIX */ + /* synch TODR hourly? */ /* #undef DOSYNCTODR */ /* The number of minutes in a DST adjustment */ #define DSTMINUTES 60 -/* fopen(3) accepts a 'b' in the mode flag */ -#define FOPEN_BINARY_FLAG "b" +/* number of args to el_init() */ +#define EL_INIT_ARGS 4 -/* fopen(3) accepts a 't' in the mode flag */ -#define FOPEN_TEXT_FLAG "t" +/* nls support in libopts */ +/* #undef ENABLE_NLS */ /* force ntpdate to step the clock if !defined(STEP_SLEW) ? */ /* #undef FORCE_NTPDATE_STEP */ @@ -284,14 +316,27 @@ /* What is getsockname()'s socklen type? */ #define GETSOCKNAME_SOCKLEN_TYPE socklen_t -/* Do we have a routing socket (struct rt_msghdr)? */ +/* Do we have a routing socket (rt_msghdr or rtattr)? */ #define HAS_ROUTING_SOCKET 1 +/* via __adjtimex */ +/* #undef HAVE_ADJTIMEX */ + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). + */ +/* #undef HAVE_ALLOCA_H */ + +/* Define to 1 if you have the `arc4random_buf' function. */ +#define HAVE_ARC4RANDOM_BUF 1 + /* Define to 1 if you have the <arpa/nameser.h> header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Do we have audio support? */ -#define HAVE_AUDIO 1 +#define HAVE_AUDIO /**/ /* Define to 1 if you have the <bstring.h> header file. */ /* #undef HAVE_BSTRING_H */ @@ -299,20 +344,30 @@ /* Define to 1 if you have the `canonicalize_file_name' function. */ /* #undef HAVE_CANONICALIZE_FILE_NAME */ +/* Define to 1 if you have the `chmod' function. */ +#define HAVE_CHMOD 1 + /* Do we have the CIOGETEV ioctl (SunOS, Linux)? */ /* #undef HAVE_CIOGETEV */ +/* Define to 1 if you have the `clock_getres' function. */ +#define HAVE_CLOCK_GETRES 1 + /* Define to 1 if you have the `clock_gettime' function. */ #define HAVE_CLOCK_GETTIME 1 /* Define to 1 if you have the `clock_settime' function. */ #define HAVE_CLOCK_SETTIME 1 +/* Define to 1 if you have the <cthreads.h> header file. */ +/* #undef HAVE_CTHREADS_H */ + /* Define to 1 if you have the `daemon' function. */ #define HAVE_DAEMON 1 -/* Define this if /dev/zero is readable device */ -#define HAVE_DEV_ZERO 1 +/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you + don't. */ +#define HAVE_DECL_STRERROR_R 1 /* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. */ @@ -333,11 +388,8 @@ /* Define to 1 if you have the <errno.h> header file. */ #define HAVE_ERRNO_H 1 -/* Define to 1 if you have the `EVP_md2' function. */ -/* #undef HAVE_EVP_MD2 */ - -/* Define to 1 if you have the `EVP_mdc2' function. */ -/* #undef HAVE_EVP_MDC2 */ +/* Define to 1 if you have the `fchmod' function. */ +#define HAVE_FCHMOD 1 /* Define to 1 if you have the <fcntl.h> header file. */ #define HAVE_FCNTL_H 1 @@ -345,6 +397,18 @@ /* Define to 1 if you have the `finite' function. */ /* #undef HAVE_FINITE */ +/* Define to 1 if you have the `fnmatch' function. */ +#define HAVE_FNMATCH 1 + +/* Define to 1 if you have the <fnmatch.h> header file. */ +#define HAVE_FNMATCH_H 1 + +/* Define to 1 if you have the `fork' function. */ +#define HAVE_FORK 1 + +/* Define to 1 if you have the `fstat' function. */ +#define HAVE_FSTAT 1 + /* Define to 1 if you have the `getbootfile' function. */ #define HAVE_GETBOOTFILE 1 @@ -357,33 +421,57 @@ /* Define to 1 if you have the `getifaddrs' function. */ #define HAVE_GETIFADDRS 1 +/* Define to 1 if you have the `getpassphrase' function. */ +/* #undef HAVE_GETPASSPHRASE */ + /* Define to 1 if you have the `getrusage' function. */ #define HAVE_GETRUSAGE 1 /* Define to 1 if you have the `getuid' function. */ #define HAVE_GETUID 1 -/* Define to 1 if you have the `hstrerror' function. */ -#define HAVE_HSTRERROR 1 +/* if you have GNU Pth */ +/* #undef HAVE_GNU_PTH */ -/* Obvious... */ +/* Define to 1 if you have the <histedit.h> header file. */ +#define HAVE_HISTEDIT_H 1 + +/* Define to 1 if you have the <history.h> header file. */ +/* #undef HAVE_HISTORY_H */ + +/* Obvious */ #define HAVE_HZ_IN_STRUCT_CLOCKINFO 1 /* Define to 1 if you have the <ieeefp.h> header file. */ #define HAVE_IEEEFP_H 1 -/* ISC: Use iflist_sysctl? */ +/* have iflist_sysctl? */ #define HAVE_IFLIST_SYSCTL 1 +/* Define to 1 if you have the `if_nametoindex' function. */ +#define HAVE_IF_NAMETOINDEX 1 + +/* inline keyword or macro available */ +#define HAVE_INLINE 1 + /* Define to 1 if the system has the type `int16_t'. */ #define HAVE_INT16_T 1 +/* Define to 1 if the system has the type `int32'. */ +/* #undef HAVE_INT32 */ + +/* int32 type in DNS headers, not others. */ +/* #undef HAVE_INT32_ONLY_WITH_DNS */ + /* Define to 1 if the system has the type `int32_t'. */ #define HAVE_INT32_T 1 /* Define to 1 if the system has the type `int8_t'. */ #define HAVE_INT8_T 1 +/* Define to 1 if the system has the type `intmax_t'. */ +/* #undef HAVE_INTMAX_T */ + /* Define to 1 if the system has the type `intptr_t'. */ #define HAVE_INTPTR_T 1 @@ -393,23 +481,11 @@ /* Define to 1 if you have the `isfinite' function. */ #define HAVE_ISFINITE 1 -/* Define to 1 if you have the `kvm_open' function. */ -#define HAVE_KVM_OPEN 1 - -/* Define to 1 if you have the `K_open' function. */ -/* #undef HAVE_K_OPEN */ - -/* Define to 1 if you have the `advapi32' library (-ladvapi32). */ -/* #undef HAVE_LIBADVAPI32 */ +/* Define to 1 if you have the <kvm.h> header file. */ +#define HAVE_KVM_H 1 -/* Do we have the curses library? */ -/* #undef HAVE_LIBCURSES */ - -/* Do we have the edit library? */ -/* #undef HAVE_LIBEDIT */ - -/* Define to 1 if you have the `elf' library (-lelf). */ -#define HAVE_LIBELF 1 +/* Define to 1 if you have the `kvm_open' function. */ +/* #undef HAVE_KVM_OPEN */ /* Define to 1 if you have the `gen' library (-lgen). */ /* #undef HAVE_LIBGEN */ @@ -417,47 +493,50 @@ /* Define to 1 if you have the <libgen.h> header file. */ #define HAVE_LIBGEN_H 1 -/* Define to 1 if you have the `kvm' library (-lkvm). */ -#define HAVE_LIBKVM 1 +/* Define to 1 if you have the `intl' library (-lintl). */ +/* #undef HAVE_LIBINTL */ -/* Define to 1 if you have the `ld' library (-lld). */ -/* #undef HAVE_LIBLD */ +/* Define to 1 if you have the <libintl.h> header file. */ +/* #undef HAVE_LIBINTL_H */ -/* Define to 1 if you have the `md' library (-lmd). */ -#define HAVE_LIBMD 1 +/* Define to 1 if you have the <libscf.h> header file. */ +/* #undef HAVE_LIBSCF_H */ -/* Define to 1 if you have the `md5' library (-lmd5). */ -/* #undef HAVE_LIBMD5 */ +/* Define to 1 if you have the <limits.h> header file. */ +#define HAVE_LIMITS_H 1 -/* Define to 1 if you have the `mld' library (-lmld). */ -/* #undef HAVE_LIBMLD */ +/* using Linux pthread? */ +/* #undef HAVE_LINUXTHREADS */ -/* Define to 1 if you have the `nsl' library (-lnsl). */ -/* #undef HAVE_LIBNSL */ +/* Do we have Linux capabilities? */ +/* #undef HAVE_LINUX_CAPABILITIES */ -/* Define to 1 if you have the `posix4' library (-lposix4). */ -/* #undef HAVE_LIBPOSIX4 */ +/* Define to 1 if you have the <linux/if_addr.h> header file. */ +/* #undef HAVE_LINUX_IF_ADDR_H */ -/* Define to 1 if you have the `readline' library (-lreadline). */ -/* #undef HAVE_LIBREADLINE */ +/* if you have LinuxThreads */ +/* #undef HAVE_LINUX_THREADS */ -/* Define to 1 if you have the `rt' library (-lrt). */ -#define HAVE_LIBRT 1 +/* Define to 1 if you have the `localeconv' function. */ +/* #undef HAVE_LOCALECONV */ -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ +/* Define to 1 if you have the <locale.h> header file. */ +/* #undef HAVE_LOCALE_H */ -/* Define to 1 if you have the `syslog' library (-lsyslog). */ -/* #undef HAVE_LIBSYSLOG */ +/* Define to 1 if the system has the type `long double'. */ +/* #undef HAVE_LONG_DOUBLE */ -/* Define to 1 if you have the `xnet' library (-lxnet). */ -/* #undef HAVE_LIBXNET */ +/* Define to 1 if the system has the type `long long'. */ +#define HAVE_LONG_LONG 1 -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 +/* Define to 1 if the system has the type `long long int'. */ +/* #undef HAVE_LONG_LONG_INT */ -/* Do we have Linux capabilities? */ -/* #undef HAVE_LINUX_CAPABILITIES */ +/* if you have SunOS LWP package */ +/* #undef HAVE_LWP */ + +/* Define to 1 if you have the <lwp/lwp.h> header file. */ +/* #undef HAVE_LWP_LWP_H */ /* Define to 1 if you have the <machine/inline.h> header file. */ /* #undef HAVE_MACHINE_INLINE_H */ @@ -465,6 +544,12 @@ /* Define to 1 if you have the <machine/soundcard.h> header file. */ /* #undef HAVE_MACHINE_SOUNDCARD_H */ +/* define if you have Mach Cthreads */ +/* #undef HAVE_MACH_CTHREADS */ + +/* Define to 1 if you have the <mach/cthreads.h> header file. */ +/* #undef HAVE_MACH_CTHREADS_H */ + /* Define to 1 if you have the <math.h> header file. */ #define HAVE_MATH_H 1 @@ -474,21 +559,12 @@ /* Define to 1 if you have the <md5.h> header file. */ #define HAVE_MD5_H 1 -/* Define to 1 if you have the `memcpy' function. */ -#define HAVE_MEMCPY 1 - /* Define to 1 if you have the `memlk' function. */ /* #undef HAVE_MEMLK */ -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - /* Define to 1 if you have the <memory.h> header file. */ #define HAVE_MEMORY_H 1 -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - /* Define to 1 if you have the `mkstemp' function. */ #define HAVE_MKSTEMP 1 @@ -496,13 +572,14 @@ #define HAVE_MKTIME 1 /* Define to 1 if you have the `mlockall' function. */ -#if __FreeBSD_version >= 500102 #define HAVE_MLOCKALL 1 -#endif /* Define to 1 if you have the `mmap' function. */ #define HAVE_MMAP 1 +/* Define to 1 if you have the `nanosleep' function. */ +#define HAVE_NANOSLEEP 1 + /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ /* #undef HAVE_NDIR_H */ @@ -518,6 +595,9 @@ /* Define to 1 if you have the <netinet/in_systm.h> header file. */ #define HAVE_NETINET_IN_SYSTM_H 1 +/* Define to 1 if you have the <netinet/in_var.h> header file. */ +#define HAVE_NETINET_IN_VAR_H 1 + /* Define to 1 if you have the <netinet/ip.h> header file. */ #define HAVE_NETINET_IP_H 1 @@ -539,17 +619,29 @@ /* Define to 1 if you have the `nice' function. */ #define HAVE_NICE 1 -/* Define to 1 if you have the `nlist' function. */ -#define HAVE_NLIST 1 +/* Define to 1 if you have the <nlist.h> header file. */ +#define HAVE_NLIST_H 1 -/* Define to 1 if you have the `ntp_adjtime' function. */ +/* via __adjtimex */ #define HAVE_NTP_ADJTIME 1 -/* Define to 1 if you have the `ntp_gettime' function. */ +/* via __ntp_gettime */ #define HAVE_NTP_GETTIME 1 -/* Define this if pathfind(3) works */ -/* #undef HAVE_PATHFIND */ +/* Do we want support for Samba's signing daemon? */ +#define HAVE_NTP_SIGND 1 + +/* if you have NT Event Log */ +/* #undef HAVE_NT_EVENT_LOG */ + +/* if you have NT Service Manager */ +/* #undef HAVE_NT_SERVICE_MANAGER */ + +/* if you have NT Threads */ +/* #undef HAVE_NT_THREADS */ + +/* Define to 1 if the system has the type `pid_t'. */ +#define HAVE_PID_T 1 /* Define to 1 if you have the `plock' function. */ /* #undef HAVE_PLOCK */ @@ -560,47 +652,113 @@ /* Do we have the PPS API per the Draft RFC? */ #define HAVE_PPSAPI 1 -/* Are function prototypes OK? */ -#define HAVE_PROTOTYPES 1 +/* Define to 1 if you have the <priv.h> header file. */ +/* #undef HAVE_PRIV_H */ + +/* Define if you have POSIX threads libraries and header files. */ +/* #undef HAVE_PTHREAD */ + +/* define to pthreads API spec revision */ +#define HAVE_PTHREADS 10 + +/* Define to 1 if you have the `pthread_attr_getstacksize' function. */ +#define HAVE_PTHREAD_ATTR_GETSTACKSIZE 1 + +/* Define to 1 if you have the `pthread_attr_setstacksize' function. */ +#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1 + +/* define if you have pthread_detach function */ +#define HAVE_PTHREAD_DETACH 1 + +/* Define to 1 if you have the `pthread_getconcurrency' function. */ +#define HAVE_PTHREAD_GETCONCURRENCY 1 + +/* Define to 1 if you have the <pthread.h> header file. */ +#define HAVE_PTHREAD_H 1 + +/* Define to 1 if you have the `pthread_kill' function. */ +#define HAVE_PTHREAD_KILL 1 + +/* Define to 1 if you have the `pthread_kill_other_threads_np' function. */ +/* #undef HAVE_PTHREAD_KILL_OTHER_THREADS_NP */ + +/* define if you have pthread_rwlock_destroy function */ +#define HAVE_PTHREAD_RWLOCK_DESTROY 1 + +/* Define to 1 if you have the `pthread_setconcurrency' function. */ +#define HAVE_PTHREAD_SETCONCURRENCY 1 + +/* Define to 1 if you have the `pthread_yield' function. */ +#define HAVE_PTHREAD_YIELD 1 + +/* Define to 1 if you have the <pth.h> header file. */ +/* #undef HAVE_PTH_H */ + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#define HAVE_PTRDIFF_T 1 /* Define to 1 if you have the `pututline' function. */ /* #undef HAVE_PUTUTLINE */ /* Define to 1 if you have the `pututxline' function. */ -/* #undef HAVE_PUTUTXLINE */ +#define HAVE_PUTUTXLINE 1 + +/* Define to 1 if you have the `RAND_bytes' function. */ +#define HAVE_RAND_BYTES 1 + +/* Define to 1 if you have the `RAND_poll' function. */ +#define HAVE_RAND_POLL 1 + +/* Define to 1 if you have the <readline.h> header file. */ +/* #undef HAVE_READLINE_H */ + +/* Define if your readline library has \`add_history' */ +#define HAVE_READLINE_HISTORY 1 /* Define to 1 if you have the <readline/history.h> header file. */ -/* #undef HAVE_READLINE_HISTORY_H */ +#define HAVE_READLINE_HISTORY_H 1 /* Define to 1 if you have the <readline/readline.h> header file. */ -/* #undef HAVE_READLINE_READLINE_H */ +#define HAVE_READLINE_READLINE_H 1 /* Define to 1 if you have the `readlink' function. */ #define HAVE_READLINK 1 -/* Define this if we have a functional realpath(3C) */ -#define HAVE_REALPATH 1 - /* Define to 1 if you have the `recvmsg' function. */ #define HAVE_RECVMSG 1 /* Define to 1 if you have the <resolv.h> header file. */ #define HAVE_RESOLV_H 1 +/* Define to 1 if you have the `res_init' function. */ +#define HAVE_RES_INIT 1 + +/* Do we have Linux routing socket? */ +/* #undef HAVE_RTNETLINK */ + /* Define to 1 if you have the `rtprio' function. */ #define HAVE_RTPRIO 1 -/* Should be obvious... */ -#define HAVE_SA_LEN_IN_STRUCT_SOCKADDR 1 +/* Define to 1 if you have the <runetype.h> header file. */ +#define HAVE_RUNETYPE_H 1 -/* Obvious... */ +/* Obvious */ #define HAVE_SA_SIGACTION_IN_STRUCT_SIGACTION 1 /* Define to 1 if you have the <sched.h> header file. */ -/* #undef HAVE_SCHED_H */ +#define HAVE_SCHED_H 1 /* Define to 1 if you have the `sched_setscheduler' function. */ -/* #undef HAVE_SCHED_SETSCHEDULER */ +#define HAVE_SCHED_SETSCHEDULER 1 + +/* Define to 1 if you have the `sched_yield' function. */ +#define HAVE_SCHED_YIELD 1 + +/* Define to 1 if you have the <semaphore.h> header file. */ +#define HAVE_SEMAPHORE_H 1 + +/* Define to 1 if you have the `sem_timedwait' function. */ +#define HAVE_SEM_TIMEDWAIT 1 /* Define to 1 if you have the <setjmp.h> header file. */ #define HAVE_SETJMP_H 1 @@ -639,26 +797,35 @@ /* #undef HAVE_SIGNALED_IO */ /* Define to 1 if you have the `sigset' function. */ -/* #undef HAVE_SIGSET */ - -/* Define to 1 if you have the `sigsuspend' function. */ -#define HAVE_SIGSUSPEND 1 +#define HAVE_SIGSET 1 /* Define to 1 if you have the `sigvec' function. */ #define HAVE_SIGVEC 1 -/* Define to 1 if you have the `snprintf' function. */ +/* sigwait() available? */ +#define HAVE_SIGWAIT 1 + +/* Define to 1 if the system has the type `size_t'. */ +#define HAVE_SIZE_T 1 + +/* Define if C99-compliant `snprintf' is available. */ #define HAVE_SNPRINTF 1 -/* Does struct sockaddr_storage have ss_family? */ -#define HAVE_SS_FAMILY_IN_SS 1 +/* Define to 1 if you have the `socketpair' function. */ +#define HAVE_SOCKETPAIR 1 -/* Does struct sockaddr_storage have ss_len? */ -#define HAVE_SS_LEN_IN_SS 1 +/* Are Solaris privileges available? */ +/* #undef HAVE_SOLARIS_PRIVS */ /* Define to 1 if you have the <stdarg.h> header file. */ #define HAVE_STDARG_H 1 +/* Define to 1 if you have the <stdbool.h> header file. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the <stddef.h> header file. */ +/* #undef HAVE_STDDEF_H */ + /* Define to 1 if you have the <stdint.h> header file. */ #define HAVE_STDINT_H 1 @@ -677,8 +844,8 @@ /* Define to 1 if you have the `strerror' function. */ #define HAVE_STRERROR 1 -/* Define this if strftime() works */ -#define HAVE_STRFTIME 1 +/* Define to 1 if you have the `strerror_r' function. */ +#define HAVE_STRERROR_R 1 /* Define to 1 if you have the <strings.h> header file. */ #define HAVE_STRINGS_H 1 @@ -686,16 +853,34 @@ /* Define to 1 if you have the <string.h> header file. */ #define HAVE_STRING_H 1 +/* Define to 1 if you have the `strlcat' function. */ +#define HAVE_STRLCAT 1 + +/* Define to 1 if you have the `strlcpy' function. */ +#define HAVE_STRLCPY 1 + +/* Define to 1 if you have the <stropts.h> header file. */ +/* #undef HAVE_STROPTS_H */ + /* Define to 1 if you have the `strrchr' function. */ #define HAVE_STRRCHR 1 -/* Define to 1 if you have the `strstr' function. */ -#define HAVE_STRSTR 1 +/* Define to 1 if you have the `strsignal' function. */ +#define HAVE_STRSIGNAL 1 + +/* Define to 1 if you have the `strtoll' function. */ +#define HAVE_STRTOLL 1 + +/* Define to 1 if `decimal_point' is a member of `struct lconv'. */ +/* #undef HAVE_STRUCT_LCONV_DECIMAL_POINT */ + +/* Define to 1 if `thousands_sep' is a member of `struct lconv'. */ +/* #undef HAVE_STRUCT_LCONV_THOUSANDS_SEP */ /* Do we have struct ntptimeval? */ #define HAVE_STRUCT_NTPTIMEVAL 1 -/* Define to 1 if `time.tv_nsec' is member of `struct ntptimeval'. */ +/* Define to 1 if `time.tv_nsec' is a member of `struct ntptimeval'. */ #define HAVE_STRUCT_NTPTIMEVAL_TIME_TV_NSEC 1 /* Does a system header define struct ppsclockev? */ @@ -704,35 +889,32 @@ /* Do we have struct snd_size? */ #define HAVE_STRUCT_SND_SIZE 1 -/* Define to 1 if `sin6_scope_id' is member of `struct sockaddr_in6'. */ -#define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - /* Does a system header define struct sockaddr_storage? */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 -/* Do we have struct timespec? */ +/* struct timespec declared? */ #define HAVE_STRUCT_TIMESPEC 1 /* Define to 1 if you have the <sun/audioio.h> header file. */ /* #undef HAVE_SUN_AUDIOIO_H */ +/* Define to 1 if you have the <synch.h> header file. */ +/* #undef HAVE_SYNCH_H */ + /* Define to 1 if you have the `sysconf' function. */ #define HAVE_SYSCONF 1 -/* Define to 1 if you have the `sysctl' function. */ -#define HAVE_SYSCTL 1 - /* Define to 1 if you have the <sysexits.h> header file. */ #define HAVE_SYSEXITS_H 1 +/* */ +#define HAVE_SYSLOG_FACILITYNAMES 1 + /* Define to 1 if you have the <sys/audioio.h> header file. */ /* #undef HAVE_SYS_AUDIOIO_H */ /* Define to 1 if you have the <sys/capability.h> header file. */ -/* #undef HAVE_SYS_CAPABILITY_H */ - -/* Define to 1 if you have the <sys/clkdefs.h> header file. */ -/* #undef HAVE_SYS_CLKDEFS_H */ +#define HAVE_SYS_CAPABILITY_H 1 /* Define to 1 if you have the <sys/clockctl.h> header file. */ /* #undef HAVE_SYS_CLOCKCTL_H */ @@ -757,7 +939,7 @@ /* #undef HAVE_SYS_LIMITS_H */ /* Define to 1 if you have the <sys/lock.h> header file. */ -/* #undef HAVE_SYS_LOCK_H */ +#define HAVE_SYS_LOCK_H 1 /* Define to 1 if you have the <sys/mman.h> header file. */ #define HAVE_SYS_MMAN_H 1 @@ -808,9 +990,6 @@ /* Define to 1 if you have the <sys/signal.h> header file. */ #define HAVE_SYS_SIGNAL_H 1 -/* Define to 1 if you have the <sys/sio.h> header file. */ -/* #undef HAVE_SYS_SIO_H */ - /* Define to 1 if you have the <sys/socket.h> header file. */ #define HAVE_SYS_SOCKET_H 1 @@ -865,6 +1044,9 @@ /* Define to 1 if you have the <sys/un.h> header file. */ #define HAVE_SYS_UN_H 1 +/* Define to 1 if you have the <sys/var.h> header file. */ +/* #undef HAVE_SYS_VAR_H */ + /* Define to 1 if you have the <sys/wait.h> header file. */ #define HAVE_SYS_WAIT_H 1 @@ -877,8 +1059,23 @@ /* Define to 1 if you have the <termio.h> header file. */ /* #undef HAVE_TERMIO_H */ -/* Obvious... */ -/* #undef HAVE_TICKADJ_IN_STRUCT_CLOCKINFO */ +/* if you have Solaris LWP (thr) package */ +/* #undef HAVE_THR */ + +/* Define to 1 if you have the <thread.h> header file. */ +/* #undef HAVE_THREAD_H */ + +/* Define to 1 if you have the `thr_getconcurrency' function. */ +/* #undef HAVE_THR_GETCONCURRENCY */ + +/* Define to 1 if you have the `thr_setconcurrency' function. */ +/* #undef HAVE_THR_SETCONCURRENCY */ + +/* Define to 1 if you have the `thr_yield' function. */ +/* #undef HAVE_THR_YIELD */ + +/* Obvious */ +#define HAVE_TICKADJ_IN_STRUCT_CLOCKINFO 1 /* Define to 1 if you have the `timegm' function. */ #define HAVE_TIMEGM 1 @@ -887,14 +1084,14 @@ /* #undef HAVE_TIMEPPS_H */ /* Define to 1 if you have the `timer_create' function. */ -#define HAVE_TIMER_CREATE 1 - -/* Define to 1 if you have the `timer_settime' function. */ -#define HAVE_TIMER_SETTIME 1 +/* #undef HAVE_TIMER_CREATE */ /* Define to 1 if you have the <timex.h> header file. */ /* #undef HAVE_TIMEX_H */ +/* Define to 1 if you have the <time.h> header file. */ +#define HAVE_TIME_H 1 + /* Do we have the TIOCGPPSEV ioctl (Solaris)? */ /* #undef HAVE_TIOCGPPSEV */ @@ -904,12 +1101,6 @@ /* Do we have the TIO serial stuff? */ /* #undef HAVE_TIO_SERIAL_STUFF */ -/* Does u_int64_t exist? */ -#define HAVE_TYPE_U_INT64_T 1 - -/* Does u_int8_t exist? */ -#define HAVE_TYPE_U_INT8_T 1 - /* Define to 1 if the system has the type `uint16_t'. */ #define HAVE_UINT16_T 1 @@ -919,6 +1110,9 @@ /* Define to 1 if the system has the type `uint8_t'. */ #define HAVE_UINT8_T 1 +/* Define to 1 if the system has the type `uintmax_t'. */ +/* #undef HAVE_UINTMAX_T */ + /* Define to 1 if the system has the type `uintptr_t'. */ #define HAVE_UINTPTR_T 1 @@ -934,6 +1128,12 @@ /* Define to 1 if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 +/* deviant sigwait? */ +/* #undef HAVE_UNIXWARE_SIGWAIT */ + +/* Define to 1 if the system has the type `unsigned long long int'. */ +/* #undef HAVE_UNSIGNED_LONG_LONG_INT */ + /* Define to 1 if you have the `updwtmp' function. */ /* #undef HAVE_UPDWTMP */ @@ -944,25 +1144,55 @@ #define HAVE_UTIME_H 1 /* Define to 1 if you have the <utmpx.h> header file. */ -/* #undef HAVE_UTMPX_H */ +#define HAVE_UTMPX_H 1 /* Define to 1 if you have the <utmp.h> header file. */ /* #undef HAVE_UTMP_H */ +/* Define to 1 if the system has the type `u_int32'. */ +/* #undef HAVE_U_INT32 */ + +/* u_int32 type in DNS headers, not others. */ +/* #undef HAVE_U_INT32_ONLY_WITH_DNS */ + /* Define to 1 if you have the <values.h> header file. */ /* #undef HAVE_VALUES_H */ /* Define to 1 if you have the <varargs.h> header file. */ /* #undef HAVE_VARARGS_H */ +/* Define to 1 if you have the `vfork' function. */ +#define HAVE_VFORK 1 + +/* Define to 1 if you have the <vfork.h> header file. */ +/* #undef HAVE_VFORK_H */ + /* Define to 1 if you have the `vprintf' function. */ #define HAVE_VPRINTF 1 -/* Define to 1 if you have the `vsnprintf' function. */ +/* Define if C99-compliant `vsnprintf' is available. */ #define HAVE_VSNPRINTF 1 -/* Define to 1 if you have the `vsprintf' function. */ -#define HAVE_VSPRINTF 1 +/* Define to 1 if you have the <wchar.h> header file. */ +#define HAVE_WCHAR_H 1 + +/* Define to 1 if the system has the type `wchar_t'. */ +#define HAVE_WCHAR_T 1 + +/* Define to 1 if the system has the type `wint_t'. */ +#define HAVE_WINT_T 1 + +/* Define to 1 if `fork' works. */ +#define HAVE_WORKING_FORK 1 + +/* Define to 1 if `vfork' works. */ +#define HAVE_WORKING_VFORK 1 + +/* define if select implicitly yields */ +#define HAVE_YIELDING_SELECT 1 + +/* Define to 1 if you have the `_exit' function. */ +#define HAVE__EXIT 1 /* Define to 1 if you have the </sys/sync/queue.h> header file. */ /* #undef HAVE__SYS_SYNC_QUEUE_H */ @@ -973,63 +1203,102 @@ /* Define to 1 if you have the `__adjtimex' function. */ /* #undef HAVE___ADJTIMEX */ +/* defined if C compiler supports __attribute__((...)) */ +#define HAVE___ATTRIBUTE__ /**/ + + + /* define away __attribute__() if unsupported */ + #ifndef HAVE___ATTRIBUTE__ + # define __attribute__(x) /* empty */ + #endif + #define ISC_PLATFORM_NORETURN_PRE + #define ISC_PLATFORM_NORETURN_POST __attribute__((__noreturn__)) + + + /* Define to 1 if you have the `__ntp_gettime' function. */ /* #undef HAVE___NTP_GETTIME */ +/* Define to 1 if you have the `__res_init' function. */ +/* #undef HAVE___RES_INIT */ + /* Does struct sockaddr_storage have __ss_family? */ /* #undef HAVE___SS_FAMILY_IN_SS */ -/* Does struct sockaddr_storage have __ss_len? */ -/* #undef HAVE___SS_LEN_IN_SS */ + + /* Handle sockaddr_storage.__ss_family */ + #ifdef HAVE___SS_FAMILY_IN_SS + # define ss_family __ss_family + #endif /* HAVE___SS_FAMILY_IN_SS */ + + + +/* Define to provide `rpl_snprintf' function. */ +/* #undef HW_WANT_RPL_SNPRINTF */ + +/* Define to provide `rpl_vsnprintf' function. */ +/* #undef HW_WANT_RPL_VSNPRINTF */ + +/* Retry queries on _any_ DNS error? */ +/* #undef IGNORE_DNS_ERRORS */ /* Should we use the IRIG sawtooth filter? */ /* #undef IRIG_SUCKS */ +/* Enclose PTHREAD_ONCE_INIT in extra braces? */ +/* #undef ISC_PLATFORM_BRACEPTHREADONCEINIT */ + /* Do we need to fix in6isaddr? */ /* #undef ISC_PLATFORM_FIXIN6ISADDR */ /* ISC: do we have if_nametoindex()? */ #define ISC_PLATFORM_HAVEIFNAMETOINDEX 1 -/* ISC: have struct if_laddrconf? */ +/* have struct if_laddrconf? */ /* #undef ISC_PLATFORM_HAVEIF_LADDRCONF */ -/* ISC: have struct if_laddrreq? */ +/* have struct if_laddrreq? */ /* #undef ISC_PLATFORM_HAVEIF_LADDRREQ */ -/* ISC: Have struct in6_pktinfo? */ -#define ISC_PLATFORM_HAVEIN6PKTINFO - -/* ISC: Have IPv6? */ -#define ISC_PLATFORM_HAVEIPV6 +/* have struct in6_pktinfo? */ +#define ISC_PLATFORM_HAVEIN6PKTINFO 1 -/* ISC: struct sockaddr as sa_len? */ -#define ISC_PLATFORM_HAVESALEN +/* have IPv6? */ +#define ISC_PLATFORM_HAVEIPV6 1 -/* ISC: Have sin6_scope_id? */ -#define ISC_PLATFORM_HAVESCOPEID +/* struct sockaddr has sa_len? */ +#define ISC_PLATFORM_HAVESALEN 1 -/* ISC: provide inet_aton() */ -/* #undef ISC_PLATFORM_NEEDATON */ +/* sin6_scope_id? */ +#define ISC_PLATFORM_HAVESCOPEID 1 -/* ISC: Need in6addr_any? */ +/* missing in6addr_any? */ /* #undef ISC_PLATFORM_NEEDIN6ADDRANY */ +/* Do we need netinet6/in6.h? */ +/* #undef ISC_PLATFORM_NEEDNETINET6IN6H */ + /* ISC: provide inet_ntop() */ /* #undef ISC_PLATFORM_NEEDNTOP */ -/* Do we need our own in_port_t? */ +/* Declare in_port_t? */ /* #undef ISC_PLATFORM_NEEDPORTT */ /* ISC: provide inet_pton() */ /* #undef ISC_PLATFORM_NEEDPTON */ +/* enable libisc thread support? */ +#define ISC_PLATFORM_USETHREADS 1 + /* Does the kernel have an FLL bug? */ /* #undef KERNEL_FLL_BUG */ /* Does the kernel support precision time discipline? */ #define KERNEL_PLL 1 +/* Define to use libseccomp system call filtering. */ +/* #undef KERN_SECCOMP */ + /* What is (probably) the name of DOSYNCTODR in the kernel? */ #define K_DOSYNCTODR_NAME "_dosynctodr" @@ -1042,10 +1311,20 @@ /* What is the name of TICK in the kernel? */ #define K_TICK_NAME "_tick" +/* define to 1 if library is thread safe */ +#define LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE 1 + +/* Define to any value to include libseccomp sandboxing. */ +/* #undef LIBSECCOMP */ + /* Should we align with the NIST lockclock scheme? */ /* #undef LOCKCLOCK */ -/* Does the kernel support multicasting IP? */ +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Does the target support multicast IP? */ #define MCAST 1 /* Should we recommend a minimum value for tickadj? */ @@ -1057,10 +1336,19 @@ /* Do we want the HPUX FindConfig()? */ /* #undef NEED_HPUX_FINDCONFIG */ +/* We need to provide netsnmp_daemonize() */ +/* #undef NEED_NETSNMP_DAEMONIZE */ + +/* pthread_init() required? */ +/* #undef NEED_PTHREAD_INIT */ + +/* use PTHREAD_SCOPE_SYSTEM? */ +/* #undef NEED_PTHREAD_SCOPE_SYSTEM */ + /* Do we need the qnx adjtime call? */ /* #undef NEED_QNX_ADJTIME */ -/* Do we need extra room for SO_RCVBUF? (HPUX <8) */ +/* Do we need extra room for SO_RCVBUF? (HPUX < 8) */ /* #undef NEED_RCVBUF_SLOP */ /* Do we need an s_char typedef? */ @@ -1076,22 +1364,25 @@ #define NLIST_STRUCT 1 /* Should we NOT read /dev/kmem? */ -/* #undef NOKMEM */ +#define NOKMEM 1 /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ -/* Define this if optional arguments are disallowed */ -/* #undef NO_OPTIONAL_OPT_ARGS */ - /* Should we avoid #warning on option name collisions? */ /* #undef NO_OPTION_NAME_WARNINGS */ -/* Is there a problem using PARENB and IGNPAR (IRIX)? */ -#define NO_PARENB_IGNPAR 1 +/* Is there a problem using PARENB and IGNPAR? */ +/* #undef NO_PARENB_IGNPAR */ + +/* define if you have (or want) no threads */ +/* #undef NO_THREADS */ /* Default location of crypto key info */ -#define NTP_KEYSDIR "/etc/ntp" +#define NTP_KEYSDIR "/usr/local/etc" + +/* Path to sign daemon rendezvous socket */ +#define NTP_SIGND_PATH "/var/run/ntp_signd" /* Do we have ntp_{adj,get}time in libc? */ #define NTP_SYSCALLS_LIBC 1 @@ -1103,7 +1394,7 @@ #define ONCORE_SHMEM_STATUS 1 /* Use OpenSSL? */ -/* #undef OPENSSL */ +/* #define OPENSSL */ /* Should we open the broadcast socket? */ #define OPEN_BCAST_SOCKET 1 @@ -1111,8 +1402,7 @@ /* need to recreate sockets on changed routing? */ /* #undef OS_MISSES_SPECIFIC_ROUTE_UPDATES */ -/* wildcard socket needs to set REUSEADDR when binding to interface addresses - */ +/* wildcard socket needs REUSEADDR to bind interface addresses */ /* #undef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND */ /* Do we need to override the system's idea of HZ? */ @@ -1122,25 +1412,28 @@ #define PACKAGE "ntp" /* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "roberto@FreeBSD.org" +#define PACKAGE_BUGREPORT "http://bugs.ntp.org./" /* Define to the full name of this package. */ #define PACKAGE_NAME "ntp" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "ntp 4.2.4p5" +#define PACKAGE_STRING "ntp 4.2.8p2" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "ntp" +/* Define to the home page for this package. */ +#define PACKAGE_URL "http://www.ntp.org./" + /* Define to the version of this package. */ -#define PACKAGE_VERSION "4.2.4p5" +#define PACKAGE_VERSION "4.2.8p2" -/* Do we have the ppsclock streams module? */ -/* #undef PPS */ +/* data dir */ +#define PERLLIBDIR "/usr/local/share/ntp/lib" -/* PPS auxiliary interface for ATOM? */ -#define PPS_SAMPLE 1 +/* define to a working POSIX compliant shell */ +#define POSIX_SHELL "/bin/bash" /* PARSE kernel PLL PPS support */ /* #undef PPS_SYNC */ @@ -1151,54 +1444,60 @@ /* Preset a value for 'tickadj'? */ #define PRESET_TICKADJ 500/hz -/* Define to 1 if the C compiler supports function prototypes. */ -#define PROTOTYPES 1 - -/* Does qsort expect to work on "void *" stuff? */ -#define QSORT_USES_VOID_P 1 - /* Should we not IGNPAR (Linux)? */ /* #undef RAWDCF_NO_IGNPAR */ +/* enable thread safety */ +#define REENTRANT 1 + /* Basic refclock support? */ #define REFCLOCK 1 -/* name of regex header file */ -#define REGEX_HEADER <regex.h> - /* Do we want the ReliantUNIX clock hacks? */ /* #undef RELIANTUNIX_CLOCK */ +/* define if sched_yield yields the entire process */ +/* #undef REPLACE_BROKEN_YIELD */ + /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void +/* saveconfig mechanism */ +#define SAVECONFIG 1 + /* Do we want the SCO clock hacks? */ /* #undef SCO5_CLOCK */ -/* The size of a `char*', as computed by sizeof. */ +/* The size of `char*', as computed by sizeof. */ #if defined(__alpha__) || defined(__sparc64__) || defined(__amd64__) #define SIZEOF_CHARP 8 #else #define SIZEOF_CHARP 4 #endif -/* The size of a `int', as computed by sizeof. */ +/* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 -/* The size of a `long', as computed by sizeof. */ +/* The size of `long', as computed by sizeof. */ #if defined(__alpha__) || defined(__sparc64__) || defined(__amd64__) #define SIZEOF_LONG 8 #else #define SIZEOF_LONG 4 #endif -/* The size of a `short', as computed by sizeof. */ +/* The size of `long long', as computed by sizeof. */ +#define SIZEOF_LONG_LONG 8 + +/* The size of `pthread_t', as computed by sizeof. */ +#define SIZEOF_PTHREAD_T 8 + +/* The size of `short', as computed by sizeof. */ #define SIZEOF_SHORT 2 -/* The size of a `signed char', as computed by sizeof. */ +/* The size of `signed char', as computed by sizeof. */ #define SIZEOF_SIGNED_CHAR 1 -/* The size of a `time_t', as computed by sizeof. */ +/* The size of `time_t', as computed by sizeof. */ #if defined(__alpha__) || defined(__sparc64__) || defined(__amd64__) #define SIZEOF_TIME_T 8 #else @@ -1211,8 +1510,13 @@ /* Slew always? */ /* #undef SLEWALWAYS */ -/* *s*printf() functions are char* */ -/* #undef SPRINTF_CHAR */ +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 @@ -1220,6 +1524,9 @@ /* Step, then slew the clock? */ /* #undef STEP_SLEW */ +/* Define to 1 if strerror_r returns char *. */ +/* #undef STRERROR_R_CHAR_P */ + /* canonical system (cpu-vendor-os) of where we should run */ #if defined(__alpha__) #define STR_SYSTEM "alpha-undermydesk-freebsd" @@ -1231,15 +1538,18 @@ #define STR_SYSTEM "i386-undermydesk-freebsd" #endif -/* Buggy syscall() (Solaris2.4)? */ -/* #undef SYSCALL_BUG */ - /* Does Xettimeofday take 1 arg? */ /* #undef SYSV_TIMEOFDAY */ /* Do we need to #define _SVID3 when we #include <termios.h>? */ /* #undef TERMIOS_NEEDS__SVID3 */ +/* enable thread safety */ +#define THREADSAFE 1 + +/* enable thread safety */ +#define THREAD_SAFE 1 + /* Is K_TICKADJ_NAME in nanoseconds? */ /* #undef TICKADJ_NANO */ @@ -1252,9 +1562,6 @@ /* Define to 1 if your <sys/time.h> declares `struct tm'. */ /* #undef TM_IN_SYS_TIME */ -/* Do we have the tty_clk line discipline/streams module? */ -/* #undef TTYCLK */ - /* Provide a typedef for uintptr_t? */ #ifndef HAVE_UINTPTR_T typedef unsigned int uintptr_t; @@ -1267,12 +1574,15 @@ typedef unsigned int uintptr_t; /* Do we set process groups with -pid? */ /* #undef UDP_BACKWARDS_SETOWN */ -/* How do we create unsigned long constants? */ -#define ULONG_CONST(a) a ## UL - /* Must we have a CTTY for fsetown? */ #define USE_FSETOWNCTTY 1 +/* Use OpenSSL's crypto random functions */ +#define USE_OPENSSL_CRYPTO_RAND 1 + +/* OK to use snprintb()? */ +/* #undef USE_SNPRINTB */ + /* Can we use SIGPOLL for tty IO? */ /* #undef USE_TTY_SIGPOLL */ @@ -1280,36 +1590,28 @@ typedef unsigned int uintptr_t; /* #undef USE_UDP_SIGPOLL */ /* Version number of package */ -#define VERSION "4.2.4p5" +#define VERSION "4.2.8p2" -/* ISC: Want IPv6? */ -#define WANT_IPV6 1 +/* vsnprintf expands "%m" to strerror(errno) */ +/* #undef VSNPRINTF_PERCENT_M */ -/* Define this if a working libregex can be found */ -#define WITH_LIBREGEX 1 +/* configure --enable-ipv6 */ +#define WANT_IPV6 1 -/* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ -#if defined(__sparc64__) -#define WORDS_BIGENDIAN 1 +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif #endif -/* Handle ss_family */ -#if !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE___SS_FAMILY_IN_SS) -# define ss_family __ss_family -#endif /* !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE_SA_FAMILY_IN_SS) */ - -/* Handle ss_len */ -#if !defined(HAVE_SS_LEN_IN_SS) && defined(HAVE___SS_LEN_IN_SS) -# define ss_len __ss_len -#endif /* !defined(HAVE_SS_LEN_IN_SS) && defined(HAVE_SA_LEN_IN_SS) */ - -/* Define to 1 if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -/* # undef _ALL_SOURCE */ -#endif +/* routine worker child proc uses to exit. */ +#define WORKER_CHILD_EXIT exit /* Define to 1 if on MINIX. */ /* #undef _MINIX */ @@ -1321,13 +1623,53 @@ typedef unsigned int uintptr_t; /* Define to 1 if you need to in order for `stat' and other things to work. */ /* #undef _POSIX_SOURCE */ +/* enable thread safety */ +#define _REENTRANT 1 + +/* enable thread safety */ +#define _SGI_MP_SOURCE 1 + +/* enable thread safety */ +#define _THREADSAFE 1 + +/* enable thread safety */ +#define _THREAD_SAFE 1 + +/* Define to 500 only on HP-UX. */ +/* #undef _XOPEN_SOURCE */ + +/* Are we _special_? */ +/* #undef __APPLE_USE_RFC_3542 */ + /* Define to 1 if type `char' is unsigned and you are not using gcc. */ #ifndef __CHAR_UNSIGNED__ /* # undef __CHAR_UNSIGNED__ */ #endif -/* Define like PROTOTYPES; this can be used by system headers. */ -#define __PROTOTYPES 1 +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* deviant */ +/* #undef adjtimex */ /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ @@ -1341,20 +1683,89 @@ typedef unsigned int uintptr_t; /* #undef inline */ #endif -/* Define to `long' if <sys/types.h> does not define. */ +/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do + not define. */ +/* #undef intmax_t */ + +/* deviant */ +/* #undef ntp_adjtime */ + +/* deviant */ +/* #undef ntp_gettime */ + +/* Define to `long int' if <sys/types.h> does not define. */ /* #undef off_t */ -/* Define to `unsigned' if <sys/types.h> does not define. */ +/* Define to `int' if <sys/types.h> does not define. */ +/* #undef pid_t */ + +/* Define to `unsigned int' if <sys/types.h> does not define. */ /* #undef size_t */ -/* Define to `long' if <sys/types.h> does not define. */ -/* #undef time_t */ + + #if !defined(_KERNEL) && !defined(PARSESTREAM) + /* + * stdio.h must be included after _GNU_SOURCE is defined + * but before #define snprintf rpl_snprintf + */ + # include <stdio.h> + #endif + + +/* Define to rpl_snprintf if the replacement function should be used. */ +/* #undef snprintf */ /* Define to `int' if <sys/types.h> doesn't define. */ /* #undef uid_t */ -/* Alternate uintptr_t for systems without it. */ +/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h> + do not define. */ +/* #undef uintmax_t */ + +/* Define to the type of an unsigned integer type wide enough to hold a + pointer, if such a type exists, and if the system does not define it. */ /* #undef uintptr_t */ -/* Does the compiler like "volatile"? */ +/* Define as `fork' if `vfork' does not work. */ +/* #undef vfork */ + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ /* #undef volatile */ + +/* Define to rpl_vsnprintf if the replacement function should be used. */ +/* #undef vsnprintf */ + + +#ifndef MPINFOU_PREDECLARED +# define MPINFOU_PREDECLARED +typedef union mpinfou { + struct pdk_mpinfo *pdkptr; + struct mpinfo *pikptr; +} mpinfou_t; +#endif + + + + #if !defined(_KERNEL) && !defined(PARSESTREAM) + # if defined(HW_WANT_RPL_VSNPRINTF) + # if defined(__cplusplus) + extern "C" { + # endif + # include <stdarg.h> + int rpl_vsnprintf(char *, size_t, const char *, va_list); + # if defined(__cplusplus) + } + # endif + # endif + # if defined(HW_WANT_RPL_SNPRINTF) + # if defined(__cplusplus) + extern "C" { + # endif + int rpl_snprintf(char *, size_t, const char *, ...); + # if defined(__cplusplus) + } + # endif + # endif + #endif /* !defined(_KERNEL) && !defined(PARSESTREAM) */ + diff --git a/usr.sbin/ntp/doc/Makefile b/usr.sbin/ntp/doc/Makefile index 9c42b09..283d6ab 100644 --- a/usr.sbin/ntp/doc/Makefile +++ b/usr.sbin/ntp/doc/Makefile @@ -2,32 +2,33 @@ .include <src.opts.mk> +SUBDIR= drivers hints icons pic scripts + FILESDIR= ${SHAREDIR}/doc/ntp .if ${MK_HTML} != "no" -FILES= accopt.html assoc.html audio.html authopt.html build.html \ - clockopt.html \ - config.html confopt.html copyright.html debug.html driver1.html \ - driver10.html driver11.html driver12.html driver16.html driver18.html \ - driver19.html driver2.html driver20.html driver22.html \ - driver26.html driver27.html driver28.html driver29.html \ - driver3.html driver30.html driver32.html driver33.html driver34.html \ - driver35.html driver36.html driver37.html \ - driver4.html driver5.html driver6.html driver7.html driver8.html \ - driver9.html extern.html hints.html \ - howto.html index.html kern.html \ - ldisc.html measure.html miscopt.html monopt.html mx4200data.html \ - notes.html ntpd.html ntpdate.html ntpdc.html ntpq.html ntptime.html \ - ntptrace.html parsedata.html parsenew.html patches.html porting.html \ - pps.html prefer.html quick.html rdebug.html refclock.html \ - release.html tickadj.html +FILES= access.html accopt.html assoc.html audio.html authentic.html \ + authopt.html autokey.html bugs.html build.html clock.html \ + clockopt.html cluster.html comdex.html config.html confopt.html \ + copyright.html debug.html decode.html discipline.html discover.html \ + extern.html filter.html hints.html history.html howto.html \ + huffpuff.html index.html kern.html kernpps.html keygen.html leap.html \ + miscopt.html monopt.html msyslog.html ntp-keygen.html ntp-wait.html \ + ntp.conf.html ntp.keys.html ntp_conf.html ntpd.html ntpdate.html \ + ntpdc.html ntpdsim.html ntpdsim_new.html ntpq.html ntpsnmpd.html \ + ntptime.html ntptrace.html orphan.html parsedata.html \ + parsenew.html poll.html pps.html prefer.html quick.html rate.html \ + rdebug.html refclock.html release.html select.html sitemap.html \ + sntp.html stats.html tickadj.html warp.html xleave.html .endif MAN= ntp.conf.5 ntp.keys.5 -MAN+= ntp-keygen.8 ntpd.8 ntpdate.8 ntpdc.8 ntpq.8 ntptime.8 +MAN+= ntp-keygen.8 ntpd.8 ntpdate.8 ntpdc.8 ntpq.8 ntptime.8 sntp.8 .PATH: ${.CURDIR}/../../../contrib/ntp/html \ - ${.CURDIR}/../../../contrib/ntp/html/build \ - ${.CURDIR}/../../../contrib/ntp/html/drivers + ${.CURDIR}/../../../contrib/ntp/util \ + ${.CURDIR}/../../../contrib/ntp/util \ + ${.CURDIR}/../../../contrib/ntp/ntpd \ + ${.CURDIR}/../../../contrib/ntp/ntpsnmpd .include <bsd.prog.mk> diff --git a/usr.sbin/ntp/doc/drivers/Makefile b/usr.sbin/ntp/doc/drivers/Makefile new file mode 100644 index 0000000..7ae3cd2 --- /dev/null +++ b/usr.sbin/ntp/doc/drivers/Makefile @@ -0,0 +1,21 @@ +# $FreeBSD$ + +.include <src.opts.mk> + +SUBDIR= icons scripts +FILESDIR= ${SHAREDIR}/doc/ntp/drivers + +.if ${MK_HTML} != "no" +FILES= driver1.html driver10.html driver11.html driver12.html driver16.html \ + driver18.html driver19.html driver20.html driver22.html driver26.html \ + driver27.html driver28.html driver29.html driver3.html driver30.html \ + driver31.html driver32.html driver33.html driver34.html driver35.html \ + driver36.html driver37.html driver38.html driver39.html driver4.html \ + driver40.html driver42.html driver43.html driver44.html driver45.html \ + driver46.html driver5.html driver6.html driver7.html driver8.html \ + driver9.html mx4200data.html oncore-shmem.html tf582_4.html +.endif + +.PATH: ${.CURDIR}/../../../../contrib/ntp/html/drivers + +.include <bsd.prog.mk> diff --git a/usr.sbin/ntp/doc/drivers/icons/Makefile b/usr.sbin/ntp/doc/drivers/icons/Makefile new file mode 100644 index 0000000..e76e1fa --- /dev/null +++ b/usr.sbin/ntp/doc/drivers/icons/Makefile @@ -0,0 +1,13 @@ +# $FreeBSD$ + +.include <src.opts.mk> + +FILESDIR= ${SHAREDIR}/doc/ntp/drivers/icons + +.if ${MK_HTML} != "no" +FILES= home.gif mail2.gif +.endif + +.PATH: ${.CURDIR}/../../../../../contrib/ntp/html/drivers/icons + +.include <bsd.prog.mk> diff --git a/usr.sbin/ntp/doc/drivers/scripts/Makefile b/usr.sbin/ntp/doc/drivers/scripts/Makefile new file mode 100644 index 0000000..44ff1a6 --- /dev/null +++ b/usr.sbin/ntp/doc/drivers/scripts/Makefile @@ -0,0 +1,13 @@ +# $FreeBSD$ + +.include <src.opts.mk> + +FILESDIR= ${SHAREDIR}/doc/ntp/drivers/scripts + +.if ${MK_HTML} != "no" +FILES= footer.txt style.css +.endif + +.PATH: ${.CURDIR}/../../../../../contrib/ntp/html/drivers/scripts + +.include <bsd.prog.mk> diff --git a/usr.sbin/ntp/doc/hints/Makefile b/usr.sbin/ntp/doc/hints/Makefile new file mode 100644 index 0000000..fdbcea0 --- /dev/null +++ b/usr.sbin/ntp/doc/hints/Makefile @@ -0,0 +1,17 @@ +# $FreeBSD$ + +.include <src.opts.mk> + +FILESDIR= ${SHAREDIR}/doc/ntp/hints + +.if ${MK_HTML} != "no" +FILES= a-ux aix bsdi changes decosf1 decosf2 freebsd hpux linux mpeix \ + notes-xntp-v3 parse refclocks rs6000 sco.html sgi \ + solaris-dosynctodr.html solaris.html solaris.xtra.4023118 \ + solaris.xtra.4095849 solaris.xtra.S99ntpd solaris.xtra.patchfreq \ + sun4 svr4-dell svr4_package todo vxworks.html winnt.html +.endif + +.PATH: ${.CURDIR}/../../../../contrib/ntp/html/hints + +.include <bsd.prog.mk> diff --git a/usr.sbin/ntp/doc/icons/Makefile b/usr.sbin/ntp/doc/icons/Makefile new file mode 100644 index 0000000..410a380 --- /dev/null +++ b/usr.sbin/ntp/doc/icons/Makefile @@ -0,0 +1,13 @@ +# $FreeBSD$ + +.include <src.opts.mk> + +FILESDIR= ${SHAREDIR}/doc/ntp/icons + +.if ${MK_HTML} != "no" +FILES= home.gif mail2.gif sitemap.png +.endif + +.PATH: ${.CURDIR}/../../../../contrib/ntp/html/icons + +.include <bsd.prog.mk> diff --git a/usr.sbin/ntp/doc/ntp-keygen.8 b/usr.sbin/ntp/doc/ntp-keygen.8 index 2d48301..89c4e09 100644 --- a/usr.sbin/ntp/doc/ntp-keygen.8 +++ b/usr.sbin/ntp/doc/ntp-keygen.8 @@ -1,21 +1,25 @@ +.Dd February 4 2015 +.Dt NTP_KEYGEN 8 User Commands +.Os +.\" EDIT THIS FILE WITH CAUTION (ntp-keygen-opts.mdoc) .\" .\" $FreeBSD$ .\" -.Dd May 17, 2006 -.Dt NTP-KEYGEN 8 -.Os +.\" It has been AutoGen-ed February 4, 2015 at 02:44:02 AM by AutoGen 5.18.5pre4 +.\" From the definitions ntp-keygen-opts.def +.\" and the template file agmdoc-cmd.tpl .Sh NAME .Nm ntp-keygen -.Nd key generation program for ntpd +.Nd Create a NTP host key .Sh SYNOPSIS .Nm -.Op Fl deGgHIMnPT -.Op Fl c Ar scheme -.Op Fl i Ar name -.Op Fl p Ar password -.Op Fl S Op Cm RSA | DSA -.Op Fl s Ar name -.Op Fl v Ar nkeys +.\" Mixture of short (flag) options and long options +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option\-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +.Pp +All arguments must be options. +.Pp .Sh DESCRIPTION This program generates cryptographic data files used by the NTPv4 authentication and identification schemes. @@ -27,22 +31,142 @@ These files are used for cookie encryption, digital signature and challenge/response identification algorithms compatible with the Internet standard security infrastructure. .Pp -All files are in PEM-encoded printable ASCII format, +All files are in PEM\-encoded printable ASCII format, so they can be embedded as MIME attachments in mail to other sites and certificate authorities. By default, files are not encrypted. +.Pp +When used to generate message digest keys, the program produces a file +containing ten pseudo\-random printable ASCII strings suitable for the +MD5 message digest algorithm included in the distribution. +If the OpenSSL library is installed, it produces an additional ten +hex\-encoded random bit strings suitable for the SHA1 and other message +digest algorithms. +The message digest keys file must be distributed and stored +using secure means beyond the scope of NTP itself. +Besides the keys used for ordinary NTP associations, additional keys +can be defined as passwords for the +.Xr ntpq 8 +and +.Xr ntpdc 8 +utility programs. +.Pp +The remaining generated files are compatible with other OpenSSL +applications and other Public Key Infrastructure (PKI) resources. +Certificates generated by this program are compatible with extant +industry practice, although some users might find the interpretation of +X509v3 extension fields somewhat liberal. +However, the identity keys are probably not compatible with anything +other than Autokey. +.Pp +Some files used by this program are encrypted using a private password. The -.Fl p Ar password -option specifies the write password and -.Fl q Ar password -option the read password for previously encrypted files. +.Fl p +option specifies the password for local encrypted files and the +.Fl q +option the password for encrypted files sent to remote sites. +If no password is specified, the host name returned by the Unix +.Fn gethostname +function, normally the DNS name of the host is used. +.Pp The +.Ar pw +option of the +.Ar crypto +configuration command specifies the read +password for previously encrypted local files. +This must match the local password used by this program. +If not specified, the host name is used. +Thus, if files are generated by this program without password, +they can be read back by +.Ar ntpd +without password but only on the same host. +.Pp +Normally, encrypted files for each host are generated by that host and +used only by that host, although exceptions exist as noted later on +this page. +The symmetric keys file, normally called +.Ar ntp.keys , +is usually installed in +.Pa /etc . +Other files and links are usually installed in +.Pa /usr/local/etc , +which is normally in a shared filesystem in +NFS\-mounted networks and cannot be changed by shared clients. +The location of the keys directory can be changed by the +.Ar keysdir +configuration command in such cases. +Normally, this is in +.Pa /etc . +.Pp +This program directs commentary and error messages to the standard +error stream +.Ar stderr +and remote files to the standard output stream +.Ar stdout +where they can be piped to other applications or redirected to files. +The names used for generated files and links all begin with the +string +.Ar ntpkey +and include the file type, generating host and filestamp, +as described in the +.Dq Cryptographic Data Files +section below. +.Ss Running the Program +To test and gain experience with Autokey concepts, log in as root and +change to the keys directory, usually +.Pa /usr/local/etc +When run for the first time, or if all files with names beginning with +.Ar ntpkey +have been removed, use the .Nm -program prompts for the password if it reads an encrypted file -and the password is missing or incorrect. -If an encrypted file is read successfully and -no write password is specified, the read password is used -as the write password by default. +command without arguments to generate a +default RSA host key and matching RSA\-MD5 certificate with expiration +date one year hence. +If run again without options, the program uses the +existing keys and parameters and generates only a new certificate with +new expiration date one year hence. +.Pp +Run the command on as many hosts as necessary. +Designate one of them as the trusted host (TH) using +.Nm +with the +.Fl T +option and configure it to synchronize from reliable Internet servers. +Then configure the other hosts to synchronize to the TH directly or +indirectly. +A certificate trail is created when Autokey asks the immediately +ascendant host towards the TH to sign its certificate, which is then +provided to the immediately descendant host on request. +All group hosts should have acyclic certificate trails ending on the TH. +.Pp +The host key is used to encrypt the cookie when required and so must be +RSA type. +By default, the host key is also the sign key used to encrypt +signatures. +A different sign key can be assigned using the +.Fl S +option and this can be either RSA or DSA type. +By default, the signature +message digest type is MD5, but any combination of sign key type and +message digest type supported by the OpenSSL library can be specified +using the +.Fl c +option. +The rules say cryptographic media should be generated with proventic +filestamps, which means the host should already be synchronized before +this program is run. +This of course creates a chicken\-and\-egg problem +when the host is started for the first time. +Accordingly, the host time +should be set by some other means, such as eyeball\-and\-wristwatch, at +least so that the certificate lifetime is within the current year. +After that and when the host is synchronized to a proventic source, the +certificate should be re\-generated. +.Pp +Additional information on trusted groups and identity schemes is on the +.Dq Autokey Public\-Key Authentication +page. .Pp The .Xr ntpd 8 @@ -83,7 +207,125 @@ and generation date and time as comments. All files are installed by default in the keys directory .Pa /usr/local/etc , which is normally in a shared filesystem -in NFS-mounted networks. +in NFS\-mounted networks. +The actual location of the keys directory +and each file can be overridden by configuration commands, +but this is not recommended. +Normally, the files for each host are generated by that host +and used only by that host, although exceptions exist +as noted later on this page. +.Pp +Normally, files containing private values, +including the host key, sign key and identification parameters, +are permitted root read/write\-only; +while others containing public values are permitted world readable. +Alternatively, files containing private values can be encrypted +and these files permitted world readable, +which simplifies maintenance in shared file systems. +Since uniqueness is insured by the hostname and +file name extensions, the files for a NFS server and +dependent clients can all be installed in the same shared directory. +.Pp +The recommended practice is to keep the file name extensions +when installing a file and to install a soft link +from the generic names specified elsewhere on this page +to the generated files. +This allows new file generations to be activated simply +by changing the link. +If a link is present, ntpd follows it to the file name +to extract the filestamp. +If a link is not present, +.Xr ntpd 8 +extracts the filestamp from the file itself. +This allows clients to verify that the file and generation times +are always current. +The +.Nm +program uses the same timestamp extension for all files generated +at one time, so each generation is distinct and can be readily +recognized in monitoring data. +.Ss Running the program +The safest way to run the +.Nm +program is logged in directly as root. +The recommended procedure is change to the keys directory, +usually +.Pa /usr/local/etc , +then run the program. +When run for the first time, +or if all +.Cm ntpkey +files have been removed, +the program generates a RSA host key file and matching RSA\-MD5 certificate file, +which is all that is necessary in many cases. +The program also generates soft links from the generic names +to the respective files. +If run again, the program uses the same host key file, +but generates a new certificate file and link. +.Pp +The host key is used to encrypt the cookie when required and so must be RSA type. +By default, the host key is also the sign key used to encrypt signatures. +When necessary, a different sign key can be specified and this can be +either RSA or DSA type. +By default, the message digest type is MD5, but any combination +of sign key type and message digest type supported by the OpenSSL library +can be specified, including those using the MD2, MD5, SHA, SHA1, MDC2 +and RIPE160 message digest algorithms. +However, the scheme specified in the certificate must be compatible +with the sign key. +Certificates using any digest algorithm are compatible with RSA sign keys; +however, only SHA and SHA1 certificates are compatible with DSA sign keys. +.Pp +Private/public key files and certificates are compatible with +other OpenSSL applications and very likely other libraries as well. +Certificates or certificate requests derived from them should be compatible +with extant industry practice, although some users might find +the interpretation of X509v3 extension fields somewhat liberal. +However, the identification parameter files, although encoded +as the other files, are probably not compatible with anything other than Autokey. +.Pp +Running the program as other than root and using the Unix +.Ic su +command +to assume root may not work properly, since by default the OpenSSL library +looks for the random seed file +.Cm .rnd +in the user home directory. +However, there should be only one +.Cm .rnd , +most conveniently +in the root directory, so it is convenient to define the +.Cm $RANDFILE +environment variable used by the OpenSSL library as the path to +.Cm /.rnd . +.Pp +Installing the keys as root might not work in NFS\-mounted +shared file systems, as NFS clients may not be able to write +to the shared keys directory, even as root. +In this case, NFS clients can specify the files in another +directory such as +.Pa /etc +using the +.Ic keysdir +command. +There is no need for one client to read the keys and certificates +of other clients or servers, as these data are obtained automatically +by the Autokey protocol. +.Pp +Ordinarily, cryptographic files are generated by the host that uses them, +but it is possible for a trusted agent (TA) to generate these files +for other hosts; however, in such cases files should always be encrypted. +The subject name and trusted name default to the hostname +of the host generating the files, but can be changed by command line options. +It is convenient to designate the owner name and trusted name +as the subject and issuer fields, respectively, of the certificate. +The owner name is also used for the host and sign key files, +while the trusted name is used for the identity files. +.Pp +All files are installed by default in the keys directory +.Pa /usr/local/etc , +which is normally in a shared filesystem +in NFS\-mounted networks. The actual location of the keys directory and each file can be overridden by configuration commands, but this is not recommended. @@ -93,7 +335,7 @@ as noted later on this page. .Pp Normally, files containing private values, including the host key, sign key and identification parameters, -are permitted root read/write-only; +are permitted root read/write\-only; while others containing public values are permitted world readable. Alternatively, files containing private values can be encrypted and these files permitted world readable, @@ -132,7 +374,7 @@ When run for the first time, or if all .Cm ntpkey files have been removed, -the program generates a RSA host key file and matching RSA-MD5 certificate file, +the program generates a RSA host key file and matching RSA\-MD5 certificate file, which is all that is necessary in many cases. The program also generates soft links from the generic names to the respective files. @@ -175,7 +417,7 @@ in the root directory, so it is convenient to define the environment variable used by the OpenSSL library as the path to .Cm /.rnd . .Pp -Installing the keys as root might not work in NFS-mounted +Installing the keys as root might not work in NFS\-mounted shared file systems, as NFS clients may not be able to write to the shared keys directory, even as root. In this case, NFS clients can specify the files in another @@ -197,7 +439,9 @@ It is convenient to designate the owner name and trusted name as the subject and issuer fields, respectively, of the certificate. The owner name is also used for the host and sign key files, while the trusted name is used for the identity files. -.Ss Trusted Hosts and Groups +seconds. +seconds. +s Trusted Hosts and Groups Each cryptographic configuration involves selection of a signature scheme and identification scheme, called a cryptotype, as explained in the @@ -206,7 +450,7 @@ section of .Xr ntp.conf 5 . The default cryptotype uses RSA encryption, MD5 message digest and TC identification. -First, configure a NTP subnet including one or more low-stratum +First, configure a NTP subnet including one or more low\-stratum trusted hosts from which all other hosts derive synchronization directly or indirectly. Trusted hosts have trusted certificates; @@ -248,7 +492,7 @@ is either .Cm RSA or .Cm DSA . -The most often need to do this is when a DSA-signed certificate is used. +The most often need to do this is when a DSA\-signed certificate is used. If it is necessary to use a different certificate scheme than the default, run .Nm @@ -257,7 +501,7 @@ with the option and selected .Ar scheme as needed. -If +f .Nm is run again without these options, it generates a new certificate using the same scheme and sign key. @@ -311,7 +555,7 @@ On trusted host alice run to generate the host key file .Pa ntpkey_RSAkey_ Ns Ar alice.filestamp and trusted private certificate file -.Pa ntpkey_RSA-MD5_cert_ Ns Ar alice.filestamp . +.Pa ntpkey_RSA\-MD5_cert_ Ns Ar alice.filestamp . Copy both files to all group hosts; they replace the files which would be generated in other schemes. On each host bob install a soft link from the generic name @@ -424,16 +668,16 @@ Select certificate message digest/signature encryption scheme. The .Ar scheme can be one of the following: -. Cm RSA-MD2 , RSA-MD5 , RSA-SHA , RSA-SHA1 , RSA-MDC2 , RSA-RIPEMD160 , DSA-SHA , +. Cm RSA\-MD2 , RSA\-MD5 , RSA\-SHA , RSA\-SHA1 , RSA\-MDC2 , RSA\-RIPEMD160 , DSA\-SHA , or -.Cm DSA-SHA1 . +.Cm DSA\-SHA1 . Note that RSA schemes must be used with a RSA sign key and DSA schemes must be used with a DSA sign key. The default without this option is -.Cm RSA-MD5 . +.Cm RSA\-MD5 . .It Fl d Enable debugging. -This option displays the cryptographic data produced in eye-friendly billboards. +This option displays the cryptographic data produced in eye\-friendly billboards. .It Fl e Write the IFF client keys to the standard output. This is intended for automatic key distribution by mail. @@ -462,7 +706,7 @@ By default, the program generates public certificates. .It Fl p Ar password Encrypt generated files containing private data with .Ar password -and the DES-CBC algorithm. +and the DES\-CBC algorithm. .It Fl q Set the password for reading files to password. .It Fl S Oo Cm RSA | DSA Oc @@ -476,14 +720,14 @@ This is used for the issuer field in certificates and in the file name for identity files. .It Fl T Generate a trusted certificate. -By default, the program generates a non-trusted certificate. +By default, the program generates a non\-trusted certificate. .It Fl V Ar nkeys -Generate parameters and keys for the Mu-Varadharajan (MV) identification scheme. +Generate parameters and keys for the Mu\-Varadharajan (MV) identification scheme. .El .Ss Random Seed File All cryptographically sound key generation schemes must have means to randomize the entropy seed used to initialize -the internal pseudo-random number generator used +the internal pseudo\-random number generator used by the library routines. The OpenSSL library uses a designated random seed file for this purpose. The file must be available when starting the NTP daemon and @@ -496,7 +740,7 @@ It is important to understand that entropy must be evolved for each generation, for otherwise the random number sequence would be predictable. Various means dependent on external events, such as keystroke intervals, -can be used to do this and some systems have built-in entropy sources. +can be used to do this and some systems have built\-in entropy sources. Suitable means are described in the OpenSSL software documentation, but are outside the scope of this page. .Pp @@ -541,19 +785,19 @@ program and .Xr ntpd 8 daemon. Cryptographic values are encoded first using ASN.1 rules, -then encrypted if necessary, and finally written PEM-encoded +then encrypted if necessary, and finally written PEM\-encoded printable ASCII format preceded and followed by MIME content identifier lines. .Pp The format of the symmetric keys file is somewhat different than the other files in the interest of backward compatibility. -Since DES-CBC is deprecated in NTPv4, the only key format of interest +Since DES\-CBC is deprecated in NTPv4, the only key format of interest is MD5 alphanumeric strings. Following hte heard the keys are entered one per line in the format .D1 Ar keyno type key where .Ar keyno -is a positive integer in the range 1-65,535, +is a positive integer in the range 1\-65,535, .Ar type is the string MD5 defining the key format and .Ar key @@ -594,8 +838,236 @@ used by the and .Xr ntpdc 8 utilities. -.Sh Bugs +.Sh "OPTIONS" +.Bl -tag +.It Fl b Ar imbits , Fl \-imbits Ns = Ns Ar imbits +identity modulus bits. +This option takes an integer number as its argument. +The value of +.Ar imbits +is constrained to being: +.in +4 +.nf +.na +in the range 256 through 2048 +.fi +.in -4 +.sp +The number of bits in the identity modulus. The default is 256. +.It Fl c Ar scheme , Fl \-certificate Ns = Ns Ar scheme +certificate scheme. +.sp +scheme is one of +RSA\-MD2, RSA\-MD5, RSA\-SHA, RSA\-SHA1, RSA\-MDC2, RSA\-RIPEMD160, +DSA\-SHA, or DSA\-SHA1. +.sp +Select the certificate message digest/signature encryption scheme. +Note that RSA schemes must be used with a RSA sign key and DSA +schemes must be used with a DSA sign key. The default without +this option is RSA\-MD5. +.It Fl C Ar cipher , Fl \-cipher Ns = Ns Ar cipher +privatekey cipher. +.sp +Select the cipher which is used to encrypt the files containing +private keys. The default is three\-key triple DES in CBC mode, +equivalent to "@code{\-C des\-ede3\-cbc". The openssl tool lists ciphers +available in "\fBopenssl \-h\fP" output. +.It Fl d , Fl \-debug\-level +Increase debug verbosity level. +This option may appear an unlimited number of times. +.sp +.It Fl D Ar number , Fl \-set\-debug\-level Ns = Ns Ar number +Set the debug verbosity level. +This option may appear an unlimited number of times. +This option takes an integer number as its argument. +.sp +.It Fl e , Fl \-id\-key +Write IFF or GQ identity keys. +.sp +Write the IFF or GQ client keys to the standard output. This is +intended for automatic key distribution by mail. +.It Fl G , Fl \-gq\-params +Generate GQ parameters and keys. +.sp +Generate parameters and keys for the GQ identification scheme, +obsoleting any that may exist. +.It Fl H , Fl \-host\-key +generate RSA host key. +.sp +Generate new host keys, obsoleting any that may exist. +.It Fl I , Fl \-iffkey +generate IFF parameters. +.sp +Generate parameters for the IFF identification scheme, obsoleting +any that may exist. +.It Fl i Ar group , Fl \-ident Ns = Ns Ar group +set Autokey group name. +.sp +Set the optional Autokey group name to name. This is used in +the file name of IFF, GQ, and MV client parameters files. In +that role, the default is the host name if this option is not +provided. The group name, if specified using \fB\-i/\-\-ident\fP or +using \fB\-s/\-\-subject\-name\fP following an '\fB@\fP' character, +is also a part of the self\-signed host certificate's subject and +issuer names in the form \fBhost@group\fP and should match the +\'\fBcrypto ident\fP' or '\fBserver ident\fP' configuration in +\fBntpd\fP's configuration file. +.It Fl l Ar lifetime , Fl \-lifetime Ns = Ns Ar lifetime +set certificate lifetime. +This option takes an integer number as its argument. +.sp +Set the certificate expiration to lifetime days from now. +.It Fl M , Fl \-md5key +generate MD5 keys. +.sp +Generate MD5 keys, obsoleting any that may exist. +.It Fl m Ar modulus , Fl \-modulus Ns = Ns Ar modulus +modulus. +This option takes an integer number as its argument. +The value of +.Ar modulus +is constrained to being: +.in +4 +.nf +.na +in the range 256 through 2048 +.fi +.in -4 +.sp +The number of bits in the prime modulus. The default is 512. +.It Fl P , Fl \-pvt\-cert +generate PC private certificate. +.sp +Generate a private certificate. By default, the program generates +public certificates. +.It Fl p Ar passwd , Fl \-password Ns = Ns Ar passwd +local private password. +.sp +Local files containing private data are encrypted with the +DES\-CBC algorithm and the specified password. The same password +must be specified to the local ntpd via the "crypto pw password" +configuration command. The default password is the local +hostname. +.It Fl q Ar passwd , Fl \-export\-passwd Ns = Ns Ar passwd +export IFF or GQ group keys with password. +.sp +Export IFF or GQ identity group keys to the standard output, +encrypted with the DES\-CBC algorithm and the specified password. +The same password must be specified to the remote ntpd via the +"crypto pw password" configuration command. See also the option +-\-id\-key (\-e) for unencrypted exports. +.It Fl S Ar sign , Fl \-sign\-key Ns = Ns Ar sign +generate sign key (RSA or DSA). +.sp +Generate a new sign key of the designated type, obsoleting any +that may exist. By default, the program uses the host key as the +sign key. +.It Fl s Ar host@group , Fl \-subject\-name Ns = Ns Ar host@group +set host and optionally group name. +.sp +Set the Autokey host name, and optionally, group name specified +following an '\fB@\fP' character. The host name is used in the file +name of generated host and signing certificates, without the +group name. The host name, and if provided, group name are used +in \fBhost@group\fP form for the host certificate's subject and issuer +fields. Specifying '\fB\-s @group\fP' is allowed, and results in +leaving the host name unchanged while appending \fB@group\fP to the +subject and issuer fields, as with \fB\-i group\fP. The group name, or +if not provided, the host name are also used in the file names +of IFF, GQ, and MV client parameter files. +.It Fl T , Fl \-trusted\-cert +trusted certificate (TC scheme). +.sp +Generate a trusted certificate. By default, the program generates +a non\-trusted certificate. +.It Fl V Ar num , Fl \-mv\-params Ns = Ns Ar num +generate <num> MV parameters. +This option takes an integer number as its argument. +.sp +Generate parameters and keys for the Mu\-Varadharajan (MV) +identification scheme. +.It Fl v Ar num , Fl \-mv\-keys Ns = Ns Ar num +update <num> MV keys. +This option takes an integer number as its argument. +.sp +This option has not been fully documented. +.It Fl \&? , Fl \-help +Display usage information and exit. +.It Fl \&! , Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl > Oo Ar cfgfile Oc , Fl \-save\-opts Oo Ns = Ns Ar cfgfile Oc +Save the option state to \fIcfgfile\fP. The default is the \fIlast\fP +configuration file listed in the \fBOPTION PRESETS\fP section, below. +The command will exit after updating the config file. +.It Fl < Ar cfgfile , Fl \-load\-opts Ns = Ns Ar cfgfile , Fl \-no\-load\-opts +Load options from \fIcfgfile\fP. +The \fIno\-load\-opts\fP form will disable the loading +of earlier config/rc/ini files. \fI\-\-no\-load\-opts\fP is handled early, +out of order. +.It Fl \-version Op Brq Ar v|c|n +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. +.El +.Sh "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from configuration ("RC" or ".INI") file(s) and values from +environment variables named: +.nf + \fBNTP_KEYGEN_<option\-name>\fP or \fBNTP_KEYGEN\fP +.fi +.ad +The environmental presets take precedence (are processed later than) +the configuration files. +The \fIhomerc\fP files are "\fI$HOME\fP", and "\fI.\fP". +If any of these are directories, then the file \fI.ntprc\fP +is searched for within those directories. +.Sh USAGE +The +.Fl p Ar password +option specifies the write password and +.Fl q Ar password +option the read password for previously encrypted files. +The +.Nm +program prompts for the password if it reads an encrypted file +and the password is missing or incorrect. +If an encrypted file is read successfully and +no write password is specified, the read password is used +as the write password by default. +.Sh "ENVIRONMENT" +See \fBOPTION PRESETS\fP for configuration environment variables. +.Sh "FILES" +See \fBOPTION PRESETS\fP for configuration files. +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 66 " (EX_NOINPUT)" +A specified configuration file could not be loaded. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. +.El +.Sh "AUTHORS" +The University of Delaware and Network Time Foundation +.Sh "COPYRIGHT" +Copyright (C) 1992\-2015 The University of Delaware and Network Time Foundation all rights reserved. +This program is released under the terms of the NTP license, <http://ntp.org/license>. +.Sh BUGS It can take quite a while to generate some cryptographic values, from one to several minutes with modern architectures such as UltraSPARC and up to tens of minutes to an hour with older architectures such as SPARC IPC. +.Pp +Please report bugs to http://bugs.ntp.org . +.Pp +Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org +.Sh NOTES +Portions of this document came from FreeBSD. +.Pp +This manual page was \fIAutoGen\fP\-erated from the \fBntp\-keygen\fP +option definitions. diff --git a/usr.sbin/ntp/doc/ntp.conf.5 b/usr.sbin/ntp/doc/ntp.conf.5 index 1aeed33..4ed9440 100644 --- a/usr.sbin/ntp/doc/ntp.conf.5 +++ b/usr.sbin/ntp/doc/ntp.conf.5 @@ -1,14 +1,23 @@ +.Dd February 4 2015 +.Dt NTP_CONF 5 File Formats +.Os +.\" EDIT THIS FILE WITH CAUTION (ntp.mdoc) .\" .\" $FreeBSD$ .\" -.Dd December 21, 2006 -.Dt NTP.CONF 5 -.Os +.\" It has been AutoGen-ed February 4, 2015 at 02:42:07 AM by AutoGen 5.18.5pre4 +.\" From the definitions ntp.conf.def +.\" and the template file agmdoc-cmd.tpl .Sh NAME .Nm ntp.conf -.Nd Network Time Protocol (NTP) daemon configuration file +.Nd Network Time Protocol (NTP) daemon configuration file format .Sh SYNOPSIS -.Nm /etc/ntp.conf +.Nm +.Op Fl \-option\-name +.Op Fl \-option\-name Ar value +.Pp +All arguments must be options. +.Pp .Sh DESCRIPTION The .Nm @@ -24,16 +33,6 @@ but could be installed elsewhere .Fl c command line option). .Pp -The -.Pa /etc/rc.d/ntpdate -script reads this file to get a list of NTP servers to use if the -variable -.Dq Li ntpdate_hosts -was not declared. -Refer to the -.Xr rc.conf 5 -man page for further info about this. -.Pp The file format is similar to other .Ux configuration files. @@ -46,13 +45,13 @@ followed by a list of arguments, some of which may be optional, separated by whitespace. Commands may not be continued over multiple lines. Arguments may be host names, -host addresses written in numeric, dotted-quad form, +host addresses written in numeric, dotted\-quad form, integers, floating point numbers (when specifying times in seconds) and text strings. .Pp The rest of this page describes the configuration and control options. The -.Qq Notes on Configuring NTP and Setting up a NTP Subnet +.Qq Notes on Configuring NTP and Setting up an NTP Subnet page (available as part of the HTML documentation provided in @@ -81,6 +80,7 @@ Following these is a section describing .Sx Miscellaneous Options . While there is a rich set of options available, the only required option is one or more +.Ic pool , .Ic server , .Ic peer , .Ic broadcast @@ -110,7 +110,7 @@ Use of options not listed may not be caught as an error, but may result in some weird and even destructive behavior. .Pp -If the Basic Socket Interface Extensions for IPv6 (RFC-2553) +If the Basic Socket Interface Extensions for IPv6 (RFC\-2553) is detected, support for the IPv6 address family is generated in addition to the default support of the IPv4 address family. In a few cases, including the reslist billboard generated @@ -133,6 +133,14 @@ qualifier forces DNS resolution to the IPv6 namespace. See IPv6 references for the equivalent classes for that address family. .Bl -tag -width indent +.It Xo Ic pool Ar address +.Op Cm burst +.Op Cm iburst +.Op Cm version Ar version +.Op Cm prefer +.Op Cm minpoll Ar minpoll +.Op Cm maxpoll Ar maxpoll +.Xc .It Xo Ic server Ar address .Op Cm key Ar key \&| Cm autokey .Op Cm burst @@ -166,12 +174,12 @@ equivalent classes for that address family. .Xc .El .Pp -These four commands specify the time server name or address to +These five commands specify the time server name or address to be used and the mode in which to operate. The .Ar address can be -either a DNS name or an IP address in dotted-quad notation. +either a DNS name or an IP address in dotted\-quad notation. Additional information on association behavior can be found in the .Qq Association Management page @@ -179,6 +187,12 @@ page provided in .Pa /usr/share/doc/ntp ) . .Bl -tag -width indent +.It Ic pool +For type s addresses, this command mobilizes a persistent +client mode association with a number of remote servers. +In this mode the local clock can synchronized to the +remote server, but the remote server can never be synchronized to +the local clock. .It Ic server For type s and r addresses, this command mobilizes a persistent client mode association with the specified remote server or local @@ -192,7 +206,7 @@ be used for type b or m addresses. .It Ic peer For type s addresses (only), this command mobilizes a -persistent symmetric-active mode association with the specified +persistent symmetric\-active mode association with the specified remote peer. In this mode the local clock can be synchronized to the remote peer or the remote peer can be synchronized to the local @@ -268,7 +282,7 @@ Options: All packets sent to and received from the server or peer are to include authentication fields encrypted using the autokey scheme described in -.Sx Authentication Commands . +.Sx Authentication Options . .It Cm burst when the server is reachable, send a burst of eight packets instead of the usual one. @@ -305,7 +319,7 @@ default is to include no encryption field. .It Cm minpoll Ar minpoll .It Cm maxpoll Ar maxpoll These options specify the minimum and maximum poll intervals -for NTP messages, as a power of 2 in seconds. +for NTP messages, as a power of 2 in seconds The maximum poll interval defaults to 10 (1,024 s), but can be increased by the .Cm maxpoll @@ -317,7 +331,7 @@ the option to a lower limit of 4 (16 s). .It Cm noselect Marks the server as unused, except for display purposes. -The server is discarded by the selection algorithm. +The server is discarded by the selection algroithm. .It Cm prefer Marks the server as preferred. All other things being equal, @@ -333,7 +347,7 @@ for further information. .It Cm ttl Ar ttl This option is used only with broadcast server and manycast client modes. -It specifies the time-to-live +It specifies the time\-to\-live .Ar ttl to use on broadcast server and multicast server and the maximum @@ -346,7 +360,7 @@ network administrator. .It Cm version Ar version Specifies the version number to be used for outgoing NTP packets. -Versions 1-4 are the choices, with version 4 the +Versions 1\-4 are the choices, with version 4 the default. .El .Ss Auxiliary Commands @@ -361,9 +375,9 @@ server, then enters the broadcast client mode, in which it synchronizes to succeeding broadcast messages. Note that, in order to avoid accidental or malicious disruption in this mode, both the -server and client should operate using symmetric-key or public-key +server and client should operate using symmetric\-key or public\-key authentication as described in -.Sx Authentication Commands . +.Sx Authentication Options . .It Ic manycastserver Ar address ... This command enables reception of manycast client messages to the multicast group address(es) (type m) specified. @@ -374,9 +388,9 @@ taken to limit the span of the reply and avoid a possibly massive implosion at the original sender. Note that, in order to avoid accidental or malicious disruption in this mode, both the server -and client should operate using symmetric-key or public-key +and client should operate using symmetric\-key or public\-key authentication as described in -.Sx Authentication Commands . +.Sx Authentication Options . .It Ic multicastclient Ar address ... This command enables reception of multicast server messages to the multicast group address(es) (type m) specified. @@ -387,24 +401,38 @@ exchange with the server, then enters the broadcast client mode, in which it synchronizes to succeeding multicast messages. Note that, in order to avoid accidental or malicious disruption in this mode, -both the server and client should operate using symmetric-key or -public-key authentication as described in -.Sx Authentication Commands . +both the server and client should operate using symmetric\-key or +public\-key authentication as described in +.Sx Authentication Options . +.It Ic mdnstries Ar number +If we are participating in mDNS, +after we have synched for the first time +we attempt to register with the mDNS system. +If that registration attempt fails, +we try again at one minute intervals for up to +.Ic mdnstries +times. +After all, +.Ic ntpd +may be starting before mDNS. +The default value for +.Ic mdnstries +is 5. .El .Sh Authentication Support Authentication support allows the NTP client to verify that the server is in fact known and trusted and not an intruder intending accidentally or on purpose to masquerade as that server. The NTPv3 -specification RFC-1305 defines a scheme which provides +specification RFC\-1305 defines a scheme which provides cryptographic authentication of received NTP packets. Originally, this was done using the Data Encryption Standard (DES) algorithm operating in Cipher Block Chaining (CBC) mode, commonly called -DES-CBC. +DES\-CBC. Subsequently, this was replaced by the RSA Message Digest -5 (MD5) algorithm using a private key, commonly called keyed-MD5. -Either algorithm computes a message digest, or one-way hash, which +5 (MD5) algorithm using a private key, commonly called keyed\-MD5. +Either algorithm computes a message digest, or one\-way hash, which can be used to verify the server has the correct private key and key identifier. .Pp @@ -466,7 +494,7 @@ of these checks and be discarded. Furthermore, the Autokey scheme requires a preliminary protocol exchange to obtain the server certificate, verify its -credentials and initialize the protocol. +credentials and initialize the protocol .Pp The .Cm auth @@ -525,9 +553,9 @@ cryptography are summarized below; further details are in the briefings, papers and reports at the NTP project page linked from .Li http://www.ntp.org/ . -.Ss Symmetric-Key Cryptography -The original RFC-1305 specification allows any one of possibly -65,534 keys, each distinguished by a 32-bit key identifier, to +.Ss Symmetric\-Key Cryptography +The original RFC\-1305 specification allows any one of possibly +65,534 keys, each distinguished by a 32\-bit key identifier, to authenticate an association. The servers and clients involved must agree on the key and key identifier to @@ -575,7 +603,7 @@ command selects the key used as the password for the utility. .Ss Public Key Cryptography NTPv4 supports the original NTPv3 symmetric key scheme -described in RFC-1305 and in addition the Autokey protocol, +described in RFC\-1305 and in addition the Autokey protocol, which is based on public key cryptography. The Autokey Version 2 protocol described on the Autokey Protocol page verifies packet integrity using MD5 message digests @@ -603,8 +631,8 @@ corresponding to the various NTP modes supported. Most modes use a special cookie which can be computed independently by the client and server, but encrypted in transmission. -All modes use in addition a variant of the S-KEY scheme, -in which a pseudo-random key list is generated and used +All modes use in addition a variant of the S\-KEY scheme, +in which a pseudo\-random key list is generated and used in reverse order. These schemes are described along with an executive summary, current status, briefing slides and reading list on the @@ -614,7 +642,7 @@ page. The specific cryptographic environment used by Autokey servers and clients is determined by a set of files and soft links generated by the -.Xr ntp-keygen 8 +.Xr ntp\-keygen 1ntpkeygenmdoc program. This includes a required host key file, required certificate file and optional sign key file, @@ -669,7 +697,7 @@ using the host name, network address and public keys, all of which are bound together by the protocol specifically to deflect masquerade attacks. For this reason Autokey -includes the source and destination IP addresses in message digest +includes the source and destinatino IP addresses in message digest computations and so the same addresses must be available at both the server and client. For this reason operation @@ -744,9 +772,11 @@ If it's the same key and the message is verified, Bob sends Cathy a reply authenticated with that key. If verification fails, -Bob sends Cathy a thing called a crypto-NAK, which tells her +Bob sends Cathy a thing called a crypto\-NAK, which tells her something broke. -She can see the evidence using the ntpq program. +She can see the evidence using the +.Xr ntpq 8 +program. .Pp Denise has rolled her own host key and certificate. She also uses one of the identity schemes as Bob. @@ -766,7 +796,7 @@ with one server and no authentication with another might not be wise. .Ss Key Management The cryptographic values used by the Autokey protocol are incorporated as a set of files generated by the -.Xr ntp-keygen 8 +.Xr ntp\-keygen 1ntpkeygenmdoc utility program, including symmetric key, host key and public certificate files, as well as sign key, identity parameters and leapseconds files. @@ -783,7 +813,7 @@ The remaining files are necessary only for the Autokey protocol. .Pp Certificates imported from OpenSSL or public certificate -authorities have certain limitations. +authorities have certian limitations. The certificate should be in ASN.1 syntax, X.509 Version 3 format and encoded in PEM, which is the same format used by OpenSSL. @@ -796,7 +826,7 @@ The certificate extension fields must not contain either a subject key identifier or a issuer key identifier field; however, an extended key usage field for a trusted host must contain the value -.Cm trustRoot . +.Cm trustRoot ; . Other extension fields are ignored. .Ss Authentication Commands .Bl -tag -width indent @@ -814,7 +844,7 @@ sent. Specifies the key identifier to use with the .Xr ntpq 8 utility, which uses the standard -protocol defined in RFC-1305. +protocol defined in RFC\-1305. The .Ar key argument is @@ -904,7 +934,7 @@ containing the keys and key identifiers used by .Xr ntpd 8 , .Xr ntpq 8 and -.Xr ntpdc +.Xr ntpdc 8 when operating with symmetric key cryptography. This is the same operation as the .Fl k @@ -926,11 +956,11 @@ argument is a key identifier for the trusted key, where the value can be in the range 1 to 65,534, inclusive. .It Ic revoke Ar logsec -Specifies the interval between re-randomization of certain +Specifies the interval between re\-randomization of certain cryptographic values used by the Autokey scheme, as a power of 2 in seconds. These values need to be updated frequently in order to -deflect brute-force attacks on the algorithms of the scheme; +deflect brute\-force attacks on the algorithms of the scheme; however, updating some values is a relatively expensive operation. The default interval is 16 (65,536 s or about 18 hours). For poll @@ -950,7 +980,7 @@ purpose, although different keys can be used with different servers. The .Ar key -arguments are 32-bit unsigned +arguments are 32\-bit unsigned integers with values from 1 to 65,534. .El .Ss Error Codes @@ -1029,7 +1059,7 @@ automatically summarized and archived for retrospective analysis. .Bl -tag -width indent .It Ic statistics Ar name ... Enables writing of statistics records. -Currently, four kinds of +Currently, eight kinds of .Ar name statistics are supported. .Bl -tag -width indent @@ -1046,7 +1076,7 @@ the file generation set named The first two fields show the date (Modified Julian Day) and time (seconds and fraction past UTC midnight). The next field shows the -clock address in dotted-quad notation. +clock address in dotted\-quad notation. The final field shows the last timecode received from the clock in decoded ASCII format, where meaningful. @@ -1068,11 +1098,10 @@ following form to the file generation set named The first two fields show the date (Modified Julian Day) and time (seconds and fraction past UTC midnight). The next field shows the peer -address in dotted-quad notation. -The final message field includes the +address in dotted\-quad notation, The final message field includes the message type and certain ancillary information. See the -.Sx Authentication Commands +.Sx Authentication Options section for further information. .It Cm loopstats Enables recording of loop filter statistics information. @@ -1087,7 +1116,7 @@ the file generation set named The first two fields show the date (Modified Julian Day) and time (seconds and fraction past UTC midnight). The next five fields -show time offset (seconds), frequency offset (parts per million - +show time offset (seconds), frequency offset (parts per million \- PPM), RMS jitter (seconds), Allan deviation (PPM) and clock discipline time constant. .It Cm peerstats @@ -1100,20 +1129,20 @@ line of the following form to the current element of a file generation set named .Cm peerstats : .Bd -literal -48773 10847.650 127.127.4.1 9714 -0.001605376 0.000000000 0.001424877 0.000958674 +48773 10847.650 127.127.4.1 9714 \-0.001605376 0.000000000 0.001424877 0.000958674 .Ed .Pp The first two fields show the date (Modified Julian Day) and time (seconds and fraction past UTC midnight). The next two fields -show the peer address in dotted-quad notation and status, +show the peer address in dotted\-quad notation and status, respectively. The status field is encoded in hex in the format described in Appendix A of the NTP specification RFC 1305. The final four fields show the offset, delay, dispersion and RMS jitter, all in seconds. .It Cm rawstats -Enables recording of raw-timestamp statistics information. +Enables recording of raw\-timestamp statistics information. This includes statistics records of all peers of a NTP server and of special signals, where present and configured. @@ -1129,7 +1158,7 @@ The first two fields show the date (Modified Julian Day) and time (seconds and fraction past UTC midnight). The next two fields show the remote peer or clock address followed by the local address -in dotted-quad notation. +in dotted\-quad notation. The final four fields show the originate, receive, transmit and final NTP timestamps in order. The timestamp @@ -1156,7 +1185,7 @@ Time in hours since the system was last rebooted. .It Packets received Cm 81965 Total number of packets received. .It Packets processed Cm 0 -Number of packets received in response to previous packets sent. +Number of packets received in response to previous packets sent .It Current version Cm 9546 Number of packets matching the current NTP version. .It Previous version Cm 56 @@ -1227,7 +1256,7 @@ modifications via the .Ar filegen option. It is defined by the -server, usually specified as a compile-time constant. +server, usually specified as a compile\-time constant. It may, however, be configurable for individual file generation sets via other commands. @@ -1293,7 +1322,7 @@ and a day specification in the form .Cm YYYYMMdd . .Cm YYYY -is a 4-digit year number (e.g., 1992). +is a 4\-digit year number (e.g., 1992). .Cm MM is a two digit month number. .Cm dd @@ -1305,21 +1334,21 @@ in a file named .It Cm week Any file set member contains data related to a certain week of a year. -The term week is defined by computing day-of-year +The term week is defined by computing day\-of\-year modulo 7. Elements of such a file generation set are distinguished by appending the following suffix to the file set -filename base: A dot, a 4-digit year number, the letter +filename base: A dot, a 4\-digit year number, the letter .Cm W , -and a 2-digit week number. +and a 2\-digit week number. For example, information from January, 10th 1992 would end up in a file with suffix .No . Ns Ar 1992W1 . .It Cm month One generation file set element is generated per month. The -file name suffix consists of a dot, a 4-digit year number, and -a 2-digit month. +file name suffix consists of a dot, a 4\-digit year number, and +a 2\-digit month. .It Cm year One generation file element is generated per year. The filename @@ -1330,9 +1359,9 @@ the file set every 24 hours of server operation. The filename suffix consists of a dot, the letter .Cm a , -and an 8-digit number. +and an 8\-digit number. This number is taken to be the number of seconds the server is -running at the start of the corresponding 24-hour period. +running at the start of the corresponding 24\-hour period. Information is only written to a file generation by specifying .Cm enable ; output is prevented by specifying @@ -1369,7 +1398,7 @@ The daemon implements a general purpose address/mask based restriction list. The list contains address/match entries sorted first -by increasing address values and then by increasing mask values. +by increasing address values and and then by increasing mask values. A match occurs when the bitwise AND of the mask and the packet source address is equal to the bitwise AND of the mask and address in the list. @@ -1406,11 +1435,11 @@ at abusive rates. Some violations cause denied service only for the offending packet, others cause denied service for a timed period and others cause the denied service for -an indefinite period. +an indefinate period. When a client or network is denied access -for an indefinite period, the only way at present to remove +for an indefinate period, the only way at present to remove the restrictions is by restarting the server. -.Ss The Kiss-of-Death Packet +.Ss The Kiss\-of\-Death Packet Ordinarily, packets denied service are simply dropped with no further action except incrementing statistics counters. Sometimes a @@ -1418,9 +1447,9 @@ more proactive response is needed, such as a server message that explicitly requests the client to stop sending and leave a message for the system operator. A special packet format has been created -for this purpose called the "kiss-of-death" (KoD) packet. +for this purpose called the "kiss\-of\-death" (KoD) packet. KoD packets have the leap bits set unsynchronized and stratum set -to zero and the reference identifier field set to a four-byte +to zero and the reference identifier field set to a four\-byte ASCII code. If the .Cm noserve @@ -1462,12 +1491,12 @@ subcommand specifies the minimum average packet spacing, while the .Cm minimum subcommand specifies the minimum packet spacing. -Packets that violate these minimum are discarded -and a kiss-o'-death packet returned if enabled. +Packets that violate these minima are discarded +and a kiss\-o'\-death packet returned if enabled. The default minimum average and minimum are 5 and 2, respectively. The monitor subcommand specifies the probability of discard -for packets that overflow the rate-control window. +for packets that overflow the rate\-control window. .It Xo Ic restrict address .Op Cm mask Ar mask .Op Ar flag ... @@ -1475,13 +1504,13 @@ for packets that overflow the rate-control window. The .Ar address argument expressed in -dotted-quad form is the address of a host or network. +dotted\-quad form is the address of a host or network. Alternatively, the .Ar address argument can be a valid host DNS name. The .Ar mask -argument expressed in dotted-quad form defaults to +argument expressed in dotted\-quad form defaults to .Cm 255.255.255.255 , meaning that the .Ar address @@ -1505,7 +1534,7 @@ in that more restrictive flags will often make less restrictive ones redundant. The flags can generally be classed into two categories, those which restrict time service and those which -restrict informational queries and attempts to do run-time +restrict informational queries and attempts to do run\-time reconfiguration of the server. One or more of the following flags may be specified: @@ -1517,7 +1546,7 @@ and .Xr ntpdc 8 queries. .It Cm kod -If this flag is set when an access violation occurs, a kiss-o'-death +If this flag is set when an access violation occurs, a kiss\-o'\-death (KoD) packet is sent. KoD packets are rate limited to no more than one per second. @@ -1564,6 +1593,18 @@ Deny packets which would result in mobilizing a new association. This includes broadcast and symmetric active packets when a configured association does not exist. +It also includes +.Cm pool +associations, so if you want to use servers from a +.Cm pool +directive and also want to use +.Cm nopeer +by default, you'll want a +.Cm "restrict source ..." line as well that does +.It not +include the +.Cm nopeer +directive. .It Cm noserve Deny all packets except .Xr ntpq 8 @@ -1586,7 +1627,7 @@ UDP port (123). Both .Cm ntpport and -.Cm non-ntpport +.Cm non\-ntpport may be specified. The @@ -1621,7 +1662,7 @@ of the nearby manycast servers, yet automatically reconfigures to sustain this number of servers should one or another fail. .Pp Note that the manycasting paradigm does not coincide -with the anycast paradigm described in RFC-1546, +with the anycast paradigm described in RFC\-1546, which is designed to find a single server from a clique of servers providing the same service. The manycast paradigm is designed to find a plurality @@ -1650,7 +1691,7 @@ The IANA has designated IPv4 address 224.1.1.1 and IPv6 address FF05::101 (site local) for NTP. When more servers are needed, it broadcasts manycast client messages to this address at the minimum feasible rate -and minimum feasible time-to-live (TTL) hops, depending +and minimum feasible time\-to\-live (TTL) hops, depending on how many servers have already been found. There can be as many manycast client associations as different group address, each one serving as a template @@ -1680,7 +1721,7 @@ Then, the client polls the server at its unicast address in burst mode in order to reliably set the host clock and validate the source. This normally results -in a volley of eight client/server at 2-s intervals +in a volley of eight client/server at 2\-s intervals during which both the synchronization and cryptographic protocols run concurrently. Following the volley, @@ -1693,7 +1734,7 @@ in ordinary client/server mode. .Pp The manycast client polling strategy is designed to reduce as much as possible the volume of manycast client messages -and the effects of implosion due to near-simultaneous +and the effects of implosion due to near\-simultaneous arrival of manycast server messages. The strategy is determined by the .Ic manycastclient , @@ -1776,7 +1817,7 @@ It is often useful to narrow the range of acceptable servers which can be found by manycast client associations. Because manycast servers respond only when the client stratum is equal to or greater than the server stratum, -primary (stratum 1) servers will find only primary servers +primary (stratum 1) servers fill find only primary servers in TTL range, which is probably the most common objective. However, unless configured otherwise, all manycast clients in TTL range will eventually find all primary servers @@ -1859,7 +1900,7 @@ servers will find the servers at the same stratum level. If one of the primary servers loses its GPS receiver, it will continue to operate as a client and other clients will time out the corresponding association and -re-associate accordingly. +re\-associate accordingly. .Pp Some administrators prefer to avoid running .Xr ntpd 8 @@ -1956,7 +1997,7 @@ peers remaining. This value defaults to 1, but can be changed to any number from 1 to 15. .It Cm minclock Ar minclock -The clustering algorithm repeatedly casts out outerlayer +The clustering algorithm repeatedly casts out outlyer associations until no more than .Cm minclock associations remain. @@ -1966,7 +2007,7 @@ configured sources. .It Cm minsane Ar minsane This is the minimum number of candidates available to the clock selection algorithm in order to produce -one or more true chimers for the clustering algorithm. +one or more truechimers for the clustering algorithm. If fewer than this number are available, the clock is undisciplined and allowed to run free. The default is 1 @@ -1981,13 +2022,13 @@ a single falseticker. This command specifies a list of TTL values in increasing order, up to 8 values can be specified. In manycast mode these values are used in turn -in an expanding-ring search. +in an expanding\-ring search. The default is eight multiples of 32 starting at 31. .El .Sh Reference Clock Support The NTP Version 4 daemon supports some three dozen different radio, -satellite and modem reference clocks plus a special pseudo-clock +satellite and modem reference clocks plus a special pseudo\-clock used for backup or when no other clock source is available. Detailed descriptions of individual device drivers and options can be found in the @@ -2007,7 +2048,7 @@ provided in .Pa /usr/share/doc/ntp ) . In addition, support for a PPS signal is available as described in the -.Qq Pulse-per-second (PPS) Signal Interfacing +.Qq Pulse\-per\-second (PPS) Signal Interfacing page (available as part of the HTML documentation provided in @@ -2057,7 +2098,7 @@ is an integer denoting the clock type and .Ar u indicates the unit -number in the range 0-3. +number in the range 0\-3. While it may seem overkill, it is in fact sometimes useful to configure multiple reference clocks of the same type, in which case the unit numbers must be unique. @@ -2117,7 +2158,7 @@ and options can be used to override the defaults for the device. There are two optional -device-dependent time offsets and four flags that can be included +device\-dependent time offsets and four flags that can be included in the .Ic fudge command as well. @@ -2134,7 +2175,7 @@ The .Cm stratum option is used for this purpose. Also, in cases -involving both a reference clock and a pulse-per-second (PPS) +involving both a reference clock and a pulse\-per\-second (PPS) discipline signal, it is useful to specify the reference clock identifier as other than the default, depending on the driver. The @@ -2171,7 +2212,7 @@ provided in for further information. .It Cm mode Ar int Specifies a mode number which is interpreted in a -device-specific fashion. +device\-specific fashion. For instance, it selects a dialing protocol in the ACTS driver and a device subtype in the parse @@ -2221,7 +2262,7 @@ follows: .Bl -tag -width indent .It Cm time1 Ar sec Specifies a constant to be added to the time offset produced by -the driver, a fixed-point decimal number in seconds. +the driver, a fixed\-point decimal number in seconds. This is used as a calibration constant to adjust the nominal time offset of a particular clock to agree with an external standard, such as a @@ -2249,8 +2290,8 @@ page provided in .Pa /usr/share/doc/ntp ) . .It Cm time2 Ar secs -Specifies a fixed-point decimal number in seconds, which is -interpreted in a driver-dependent way. +Specifies a fixed\-point decimal number in seconds, which is +interpreted in a driver\-dependent way. See the descriptions of specific drivers in the .Qq Reference Clock Drivers @@ -2271,7 +2312,7 @@ overrides the default identifier ordinarily assigned by the driver itself. .It Cm mode Ar int Specifies a mode number which is interpreted in a -device-specific fashion. +device\-specific fashion. For instance, it selects a dialing protocol in the ACTS driver and a device subtype in the parse @@ -2338,7 +2379,7 @@ frequency of zero. .Pp The file format consists of a single line containing a single floating point number, which records the frequency offset measured -in parts-per-million (PPM). +in parts\-per\-million (PPM). The file is updated by first writing the current drift value into a temporary file and then renaming this file to replace the old version. @@ -2351,16 +2392,16 @@ otherwise, should be avoided. .Oo .Cm auth | Cm bclient | .Cm calibrate | Cm kernel | -.Cm monitor | Cm ntp | -.Cm pps | Cm stats +.Cm mode7 | monitor | +.Cm ntp | Cm stats .Oc .Xc .It Xo Ic disable .Oo .Cm auth | Cm bclient | .Cm calibrate | Cm kernel | -.Cm monitor | Cm ntp | -.Cm pps | Cm stats +.Cm mode7 | monitor | +.Cm ntp | Cm stats .Oc .Xc Provides a way to enable or disable various server options. @@ -2396,6 +2437,19 @@ flag is .Ic enable if support is available, otherwise .Ic disable . +.It Cm mode7 +Enables processing of NTP mode 7 implementation\-specific requests +which are used by the deprecated +.Xr ntpdc 8 +program. +The default for this flag is disable. +This flag is excluded from runtime configuration using +.Xr ntpq 8 . +The +.Xr ntpq 8 +program provides the same capabilities as +.Xr ntpdc 8 +using standard mode 6 requests. .It Cm monitor Enables the monitoring facility. See the @@ -2414,17 +2468,6 @@ closes the feedback loop, which is useful for testing. The default for this flag is .Ic enable . -.It Cm pps -Enables the pulse-per-second (PPS) signal when frequency and time is -disciplined by the precision time kernel modifications. -See the -.Qq A Kernel Model for Precision Timekeeping -(available as part of the HTML documentation -provided in -.Pa /usr/share/doc/ntp ) -page for further information. -The default for this flag is -.Ic disable . .It Cm stats Enables the statistics facility. See the @@ -2458,7 +2501,7 @@ keywords can be prefixed with .Ql = , .Ql + and -.Ql - , +.Ql \- , where .Ql = sets the @@ -2466,7 +2509,7 @@ sets the priority mask, .Ql + adds and -.Ql - +.Ql \- removes messages. .Xr syslog 3 @@ -2531,7 +2574,7 @@ This command specifies the location of an alternate log file to be used instead of the default system .Xr syslog 3 facility. -This is the same operation as the -l command line option. +This is the same operation as the \-l command line option. .It Ic setvar Ar variable Op Cm default This command adds an additional system variable. These @@ -2611,12 +2654,12 @@ The argument becomes the new value for the dispersion increase rate, normally .000015 s/s. .It Cm freq Ar freq The argument becomes the initial value of the frequency offset in -parts-per-million. +parts\-per\-million. This overrides the value in the frequency file, if present, and avoids the initial training state if it is not. .It Cm huffpuff Ar huffpuff The argument becomes the new value for the experimental -huff-n'-puff filter span, which determines the most recent interval +huff\-n'\-puff filter span, which determines the most recent interval the algorithm will search for a minimum delay. The lower limit is 900 s (15 m), but a more reasonable value is 7200 (2 hours). @@ -2644,6 +2687,29 @@ be set to any positive number in seconds. If set to zero, the stepout pulses will not be suppressed. .El +.It Xo Ic rlimit +.Oo +.Cm memlock Ar Nmegabytes | +.Cm stacksize Ar N4kPages +.Cm filenum Ar Nfiledescriptors +.Oc +.Xc +.Bl -tag -width indent +.It Cm memlock Ar Nmegabytes +Specify the number of megabytes of memory that can be allocated. +Probably only available under Linux, this option is useful +when dropping root (the +.Fl i +option). +The default is 32 megabytes. Setting this to zero will prevent any attemp to lock memory. +.It Cm stacksize Ar N4kPages +Specifies the maximum size of the process stack on systems with the +.It Cm filenum Ar Nfiledescriptors +Specifies the maximum number of file descriptors ntpd may have open at once. Defaults to the system default. +.Fn mlockall +function. +Defaults to 50 4k pages (200 4k pages in OpenBSD). +.El .It Xo Ic trap Ar host_address .Op Cm port Ar port_number .Op Cm interface Ar interface_address @@ -2669,10 +2735,30 @@ is started. This command specifies a list of TTL values in increasing order, up to 8 values can be specified. In manycast mode these values are used in turn in -an expanding-ring search. +an expanding\-ring search. The default is eight multiples of 32 starting at 31. .El +.Sh "OPTIONS" +.Bl -tag +.It Fl \-help +Display usage information and exit. +.It Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl \-version Op Brq Ar v|c|n +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. +.El +.Sh "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from environment variables named: +.nf + \fBNTP_CONF_<option\-name>\fP or \fBNTP_CONF\fP +.fi +.ad +.Sh "ENVIRONMENT" +See \fBOPTION PRESETS\fP for configuration environment variables. .Sh FILES .Bl -tag -width /etc/ntp.drift -compact .It Pa /etc/ntp.conf @@ -2684,10 +2770,20 @@ RSA private key .It Pa ntpkey_ Ns Ar host RSA public key .It Pa ntp_dh -Diffie-Hellman agreement parameters +Diffie\-Hellman agreement parameters +.El +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. .El -.Sh SEE ALSO -.Xr rc.conf 5 , +.Sh "SEE ALSO" .Xr ntpd 8 , .Xr ntpdc 8 , .Xr ntpq 8 @@ -2700,9 +2796,14 @@ A snapshot of this documentation is available in HTML format in .Pa /usr/share/doc/ntp . .Rs .%A David L. Mills -.%T Network Time Protocol (Version 3) -.%O RFC1305 +.%T Network Time Protocol (Version 4) +.%O RFC5905 .Re +.Sh "AUTHORS" +The University of Delaware and Network Time Foundation +.Sh "COPYRIGHT" +Copyright (C) 1992\-2015 The University of Delaware and Network Time Foundation all rights reserved. +This program is released under the terms of the NTP license, <http://ntp.org/license>. .Sh BUGS The syntax checking is not picky; some combinations of ridiculous and even hilarious options and modes may not be @@ -2714,3 +2815,10 @@ files are really digital certificates. These should be obtained via secure directory services when they become universally available. +.Pp +Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org +.Sh NOTES +This document was derived from FreeBSD. +.Pp +This manual page was \fIAutoGen\fP\-erated from the \fBntp.conf\fP +option definitions. diff --git a/usr.sbin/ntp/doc/ntp.keys.5 b/usr.sbin/ntp/doc/ntp.keys.5 index dc9531c..4ec3bb3 100644 --- a/usr.sbin/ntp/doc/ntp.keys.5 +++ b/usr.sbin/ntp/doc/ntp.keys.5 @@ -1,25 +1,37 @@ +.Dd February 4 2015 +.Dt NTP_KEYS 5 File Formats +.Os SunOS 5.10 +.\" EDIT THIS FILE WITH CAUTION (ntp.mdoc) .\" .\" $FreeBSD$ .\" -.Dd January 13, 2000 -.Dt NTP.KEYS 5 -.Os +.\" $FreeBSD$ +.\" +.\" It has been AutoGen-ed February 4, 2015 at 02:42:10 AM by AutoGen 5.18.5pre4 +.\" From the definitions ntp.keys.def +.\" and the template file agmdoc-file.tpl .Sh NAME .Nm ntp.keys -.Nd NTP daemon key file format +.Nd NTP symmetric key file format + +.Sh NAME +.Nm ntp.keys +.Nd NTP symmetric key file format .Sh SYNOPSIS -.Nm /etc/ntp.keys +.Nm +.Op Fl \-option\-name +.Op Fl \-option\-name Ar value +.Pp +All arguments must be options. +.Pp .Sh DESCRIPTION -Following is a description of the format of NTP key files. -For a description of the use of these files, see the +This document describes the format of an NTP symmetric key file. +For a description of the use of this type of file, see the .Qq Authentication Support section of the .Xr ntp.conf 5 page. .Pp -In the case of DES, the keys are 56 bits long with, -depending on type, a parity check on each byte. -In the case of MD5, the keys are 64 bits (8 bytes). .Xr ntpd 8 reads its keys from a file specified using the .Fl k @@ -29,7 +41,7 @@ statement in the configuration file. While key number 0 is fixed by the NTP standard (as 56 zero bits) and may not be changed, -one or more of the keys numbered 1 through 15 +one or more keys numbered between 1 and 65534 may be arbitrarily set in the keys file. .Pp The key file uses the same comment conventions @@ -40,57 +52,51 @@ Key entries use a fixed format of the form .Pp where .Ar keyno -is a positive integer, +is a positive integer (between 1 and 65534), .Ar type -is a single character which defines the key format, +is the message digest algorithm, and .Ar key is the key itself. .Pp The .Ar key -may be given in one of four different formats, +may be given in a format controlled by the .Ar type -character. -The four key types, and corresponding formats, -are listed following. -.Bl -tag -width X -.It Li S -The key is a 64-bit hexadecimal number in the format -specified in the DES specification; -that is, the high order seven bits of each octet are used -to form the 56-bit key -while the low order bit of each octet is given a value -such that odd parity is maintained for the octet. -Leading zeroes must be specified -(i.e., the key must be exactly 16 hex digits long) -and odd parity must be maintained. -Hence a zero key, in standard format, would be given as -.Ql 0101010101010101 . -.It Li N -The key is a 64-bit hexadecimal number in the format -specified in the NTP standard. -This is the same as the DES format, -except the bits in each octet have been rotated one bit right -so that the parity bit is now the high order bit of the octet. -Leading zeroes must be specified and odd parity must be maintained. -A zero key in NTP format would be specified as -.Ql 8080808080808080 . -.It Li A -The key is a 1-to-8 character ASCII string. -A key is formed from this by using the low order 7 bits -of each ASCII character in the string, -with zeroes added on the right -when necessary to form a full width 56-bit key, -in the same way that encryption keys are formed from -.Ux -passwords. -.It Li M -The key is a 1-to-8 character ASCII string, -using the MD5 authentication scheme. -Note that both the keys and the authentication schemes (DES or MD5) -must be identical between a set of peers sharing the same key number. +field. +The +.Ar type +.Li MD5 +is always supported. +If +.Li ntpd +was built with the OpenSSL library +then any digest library supported by that library may be specified. +However, if compliance with FIPS 140\-2 is required the +.Ar type +must be either +.Li SHA +or +.Li SHA1 . +.Pp +What follows are some key types, and corresponding formats: +.Pp +.Bl -tag -width RMD160 -compact +.It Li MD5 +The key is 1 to 16 printable characters terminated by +an EOL, +whitespace, +or +a +.Li # +(which is the "start of comment" character). +.Pp +.It Li SHA +.It Li SHA1 +.It Li RMD160 +The key is a hex\-encoded ASCII string of 40 characters, +which is truncated as necessary. .El .Pp Note that the keys used by the @@ -100,21 +106,57 @@ and programs are checked against passwords requested by the programs and entered by hand, so it is generally appropriate to specify these keys in ASCII format. +.Sh "OPTIONS" +.Bl -tag +.It Fl \-help +Display usage information and exit. +.It Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl \-version Op Brq Ar v|c|n +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. +.El +.Sh "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from environment variables named: +.nf + \fBNTP_KEYS_<option\-name>\fP or \fBNTP_KEYS\fP +.fi +.ad +.Sh "ENVIRONMENT" +See \fBOPTION PRESETS\fP for configuration environment variables. .Sh FILES -.Bl -tag -width /etc/ntp.drift -compact +.Bl -tag -width /etc/ntp.keys -compact .It Pa /etc/ntp.keys the default name of the configuration file .El -.Sh SEE ALSO +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. +.El +.Sh "SEE ALSO" .Xr ntp.conf 5 , .Xr ntpd 8 , .Xr ntpdate 8 , -.Xr ntpdc 8 -.Sh BUGS -.Xr ntpd 8 -has gotten rather fat. -While not huge, it has gotten larger than might -be desirable for an elevated-priority daemon running on a workstation, -particularly since many of the fancy features which consume the space -were designed more with a busy primary server, rather than a high -stratum workstation, in mind. +.Xr ntpdc 8 , +.Xr sntp 8 +.Sh "AUTHORS" +The University of Delaware and Network Time Foundation +.Sh "COPYRIGHT" +Copyright (C) 1992\-2015 The University of Delaware and Network Time Foundation all rights reserved. +This program is released under the terms of the NTP license, <http://ntp.org/license>. +.Sh "BUGS" +Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org +.Sh NOTES +This document was derived from FreeBSD. +.Pp +This manual page was \fIAutoGen\fP\-erated from the \fBntp.keys\fP +option definitions. diff --git a/usr.sbin/ntp/doc/ntpd.8 b/usr.sbin/ntp/doc/ntpd.8 index 069ef42..665aa0b 100644 --- a/usr.sbin/ntp/doc/ntpd.8 +++ b/usr.sbin/ntp/doc/ntpd.8 @@ -1,25 +1,24 @@ +.Dd February 4 2015 +.Dt NTPD 8 User Commands +.Os +.\" EDIT THIS FILE WITH CAUTION (ntpd-opts.mdoc) .\" .\" $FreeBSD$ .\" -.Dd May 18, 2010 -.Dt NTPD 8 -.Os +.\" It has been AutoGen-ed February 4, 2015 at 02:42:12 AM by AutoGen 5.18.5pre4 +.\" From the definitions ntpd-opts.def +.\" and the template file agmdoc-cmd.tpl .Sh NAME .Nm ntpd -.Nd Network Time Protocol (NTP) daemon +.Nd NTP daemon program .Sh SYNOPSIS .Nm -.Op Fl aAbDdgLmnPqx -.Op Fl c Ar conffile -.Op Fl f Ar driftfile -.Op Fl k Ar keyfile -.Op Fl l Ar logfile -.Op Fl p Ar pidfile -.Op Fl r Ar broadcastdelay -.Op Fl s Ar statsdir -.Op Fl t Ar key -.Op Fl v Ar variable -.Op Fl V Ar variable +.\" Mixture of short (flag) options and long options +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option\-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +[ <server1> ... <serverN> ] +.Pp .Sh DESCRIPTION The .Nm @@ -27,14 +26,15 @@ utility is an operating system daemon which sets and maintains the system time of day in synchronism with Internet standard time servers. It is a complete implementation of the -Network Time Protocol (NTP) version 4, but also retains -compatibility with version 3, as defined by RFC-1305, and version 1 -and 2, as defined by RFC-1059 and RFC-1119, respectively. +Network Time Protocol (NTP) version 4, as defined by RFC\-5905, +but also retains compatibility with +version 3, as defined by RFC\-1305, and versions 1 +and 2, as defined by RFC\-1059 and RFC\-1119, respectively. .Pp The .Nm -utility does most computations in 64-bit floating point -arithmetic and does relatively clumsy 64-bit fixed point operations +utility does most computations in 64\-bit floating point +arithmetic and does relatively clumsy 64\-bit fixed point operations only when necessary to preserve the ultimate precision, about 232 picoseconds. While the ultimate precision is not achievable with @@ -82,154 +82,307 @@ utility programs. When .Nm starts it looks at the value of -.Cm umask 2 , +.Xr umask 2 , and if zero .Nm will set the -.Cm umask 2 +.Xr umask 2 to 022. -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl a +.Sh "OPTIONS" +.Bl -tag +.It Fl 4 , Fl \-ipv4 +Force IPv4 DNS name resolution. +This option must not appear in combination with any of the following options: +ipv6. +.sp +Force DNS resolution of following host names on the command line +to the IPv4 namespace. +.It Fl 6 , Fl \-ipv6 +Force IPv6 DNS name resolution. +This option must not appear in combination with any of the following options: +ipv4. +.sp +Force DNS resolution of following host names on the command line +to the IPv6 namespace. +.It Fl a , Fl \-authreq +Require crypto authentication. +This option must not appear in combination with any of the following options: +authnoreq. +.sp Require cryptographic authentication for broadcast client, multicast client and symmetric passive associations. This is the default. -.It Fl A +.It Fl A , Fl \-authnoreq +Do not require crypto authentication. +This option must not appear in combination with any of the following options: +authreq. +.sp Do not require cryptographic authentication for broadcast client, multicast client and symmetric passive associations. This is almost never a good idea. -.It Fl b -Enable the client to synchronize to broadcast servers. -.It Fl c Ar conffile -Specify the name and path of the configuration file, default -.Pa /etc/ntp.conf . -.It Fl d -Specify debugging mode. -This option may occur more than once, -with each occurrence indicating greater detail of display. -You need to compile -.Nm -with DEBUG in order to use this. -.It Fl D Ar level -Specify debugging level directly. -.It Fl f Ar driftfile -Specify the name and path of the frequency file, default -.Pa /etc/ntp.drift . +.It Fl b , Fl \-bcastsync +Allow us to sync to broadcast servers. +.sp +.It Fl c Ar string , Fl \-configfile Ns = Ns Ar string +configuration file name. +.sp +The name and path of the configuration file, +\fI/etc/ntp.conf\fP +by default. +.It Fl d , Fl \-debug\-level +Increase debug verbosity level. +This option may appear an unlimited number of times. +.sp +.It Fl D Ar number , Fl \-set\-debug\-level Ns = Ns Ar number +Set the debug verbosity level. +This option may appear an unlimited number of times. +This option takes an integer number as its argument. +.sp +.It Fl f Ar string , Fl \-driftfile Ns = Ns Ar string +frequency drift file name. +.sp +The name and path of the frequency file, +\fI/etc/ntp.drift\fP +by default. This is the same operation as the -.Ic driftfile Ar driftfile -configuration command. -.It Fl g +\fBdriftfile\fP \fIdriftfile\fP +configuration specification in the +\fI/etc/ntp.conf\fP +file. +.It Fl g , Fl \-panicgate +Allow the first adjustment to be Big. +This option may appear an unlimited number of times. +.sp Normally, -.Nm -exits with a message to the system log if the offset exceeds -the panic threshold, which is 1000 s by default. -This option allows the time to be set to any value without restriction; -however, this can happen only once. -If the threshold is exceeded after that, -.Nm -will exit with a message to the system log. -This option can be used with the -.Fl q +\fBntpd\fP +exits with a message to the system log if the offset exceeds the panic threshold, which is 1000 s by default. This option allows the time to be set to any value without restriction; however, this can happen only once. If the threshold is exceeded after that, +\fBntpd\fP +will exit with a message to the system log. This option can be used with the +\fB\-q\fP and -.Fl x +\fB\-x\fP options. See the -.Ic tinker -command for other options. -.It Fl k Ar keyfile -Specify the name and path of the symmetric key file, default -.Pa /etc/ntp.keys . +\fBtinker\fP +configuration file directive for other options. +.It Fl i Ar string , Fl \-jaildir Ns = Ns Ar string +Jail directory. +.sp +Chroot the server to the directory +\fIjaildir\fP +. +This option also implies that the server attempts to drop root privileges at startup. +You may need to also specify a +\fB\-u\fP +option. +This option is only available if the OS supports adjusting the clock +without full root privileges. +This option is supported under NetBSD (configure with +\fB\-\-enable\-clockctl\fP) or Linux (configure with +\fB\-\-enable\-linuxcaps\fP) or Solaris (configure with \fB\-\-enable\-solarisprivs\fP). +.It Fl I Ar iface , Fl \-interface Ns = Ns Ar iface +Listen on an interface name or address. +This option may appear an unlimited number of times. +.sp +Open the network address given, or all the addresses associated with the +given interface name. This option may appear multiple times. This option +also implies not opening other addresses, except wildcard and localhost. +This option is deprecated. Please consider using the configuration file +\fBinterface\fP command, which is more versatile. +.It Fl k Ar string , Fl \-keyfile Ns = Ns Ar string +path to symmetric keys. +.sp +Specify the name and path of the symmetric key file. +\fI/etc/ntp.keys\fP +is the default. This is the same operation as the -.Ic keys Ar keyfile -configuration command. -.It Fl l Ar logfile +\fBkeys\fP \fIkeyfile\fP +configuration file directive. +.It Fl l Ar string , Fl \-logfile Ns = Ns Ar string +path to the log file. +.sp Specify the name and path of the log file. The default is the system log file. This is the same operation as the -.Ic logfile Ar logfile -configuration command. -.It Fl L -Do not listen to virtual IPs. -The default is to listen. -.It Fl m -Enable the client to synchronize to multicast servers at the IPv4 multicast -group address 224.0.1.1. -.It Fl n +\fBlogfile\fP \fIlogfile\fP +configuration file directive. +.It Fl L , Fl \-novirtualips +Do not listen to virtual interfaces. +.sp +Do not listen to virtual interfaces, defined as those with +names containing a colon. This option is deprecated. Please +consider using the configuration file \fBinterface\fP command, which +is more versatile. +.It Fl M , Fl \-modifymmtimer +Modify Multimedia Timer (Windows only). +.sp +Set the Windows Multimedia Timer to highest resolution. This +ensures the resolution does not change while ntpd is running, +avoiding timekeeping glitches associated with changes. +.It Fl n , Fl \-nofork Do not fork. -.It Fl N -To the extent permitted by the operating system, run the -.Nm +This option must not appear in combination with any of the following options: +wait\-sync. +.sp +.It Fl N , Fl \-nice +Run at high priority. +.sp +To the extent permitted by the operating system, run +\fBntpd\fP at the highest priority. -.It Fl p Ar pidfile -Specify the name and path of the file used to record the -.Nm +.It Fl p Ar string , Fl \-pidfile Ns = Ns Ar string +path to the PID file. +.sp +Specify the name and path of the file used to record +\fBntpd\fP's process ID. This is the same operation as the -.Ic pidfile Ar pidfile -configuration command. -.It Fl P Ar priority -To the extent permitted by the operating system, run the -.Nm -at the specified priority. -.It Fl q -Exit the -.Nm -just after the first time the clock is -set. -This behavior mimics that of the -.Xr ntpdate 8 -program, -which is to be retired. +\fBpidfile\fP \fIpidfile\fP +configuration file directive. +.It Fl P Ar number , Fl \-priority Ns = Ns Ar number +Process priority. +This option takes an integer number as its argument. +.sp +To the extent permitted by the operating system, run +\fBntpd\fP +at the specified +\fBsched_setscheduler(SCHED_FIFO)\fP +priority. +.It Fl q , Fl \-quit +Set the time and quit. +This option must not appear in combination with any of the following options: +saveconfigquit, wait\-sync. +.sp +\fBntpd\fP +will not daemonize and will exit after the clock is first +synchronized. This behavior mimics that of the +\fBntpdate\fP +program, which will soon be replaced with a shell script. The -.Fl g +\fB\-g\fP and -.Fl x -options can -be used with this option. +\fB\-x\fP +options can be used with this option. Note: The kernel time discipline is disabled with this option. -.It Fl r Ar broadcastdelay -Specify the default propagation delay from the -broadcast/multicast server to this client. -This is necessary -only if the delay cannot be computed automatically by the -protocol. -.It Fl s Ar statsdir -Specify the directory path for files created by the statistics -facility. +.It Fl r Ar string , Fl \-propagationdelay Ns = Ns Ar string +Broadcast/propagation delay. +.sp +Specify the default propagation delay from the broadcast/multicast server to this client. This is necessary only if the delay cannot be computed automatically by the protocol. +.It Fl \-saveconfigquit Ns = Ns Ar string +Save parsed configuration and quit. +This option must not appear in combination with any of the following options: +quit, wait\-sync. +.sp +Cause \fBntpd\fP to parse its startup configuration file and save an +equivalent to the given filename and exit. This option was +designed for automated testing. +.It Fl s Ar string , Fl \-statsdir Ns = Ns Ar string +Statistics file location. +.sp +Specify the directory path for files created by the statistics facility. This is the same operation as the -.Ic statsdir Ar statsdir -configuration command. -.It Fl t Ar key -Add a key number to the trusted key list. -This option can occur more than once. -.It Fl v Ar variable -.It Fl V Ar variable -Add a system variable listed by default. -.It Fl x -Normally, the time is slewed if the offset is less than the -step threshold, which is 128 ms by default, and stepped if above -the threshold. -This option sets the threshold to 600 s, -which is well within the accuracy window to set the clock manually. -Note: Since the slew rate of typical Unix kernels is limited to 0.5 ms/s, -each second of adjustment requires an amortization interval of 2000 s. +\fBstatsdir\fP \fIstatsdir\fP +configuration file directive. +.It Fl t Ar tkey , Fl \-trustedkey Ns = Ns Ar tkey +Trusted key number. +This option may appear an unlimited number of times. +.sp +Add the specified key number to the trusted key list. +.It Fl u Ar string , Fl \-user Ns = Ns Ar string +Run as userid (or userid:groupid). +.sp +Specify a user, and optionally a group, to switch to. +This option is only available if the OS supports adjusting the clock +without full root privileges. +This option is supported under NetBSD (configure with +\fB\-\-enable\-clockctl\fP) or Linux (configure with +\fB\-\-enable\-linuxcaps\fP) or Solaris (configure with \fB\-\-enable\-solarisprivs\fP). +.It Fl U Ar number , Fl \-updateinterval Ns = Ns Ar number +interval in seconds between scans for new or dropped interfaces. +This option takes an integer number as its argument. +.sp +Give the time in seconds between two scans for new or dropped interfaces. +For systems with routing socket support the scans will be performed shortly after the interface change +has been detected by the system. +Use 0 to disable scanning. 60 seconds is the minimum time between scans. +.It Fl \-var Ns = Ns Ar nvar +make ARG an ntp variable (RW). +This option may appear an unlimited number of times. +.sp +.It Fl \-dvar Ns = Ns Ar ndvar +make ARG an ntp variable (RW|DEF). +This option may appear an unlimited number of times. +.sp +.It Fl w Ar number , Fl \-wait\-sync Ns = Ns Ar number +Seconds to wait for first clock sync. +This option must not appear in combination with any of the following options: +nofork, quit, saveconfigquit. +This option takes an integer number as its argument. +.sp +If greater than zero, alters \fBntpd\fP's behavior when forking to +daemonize. Instead of exiting with status 0 immediately after +the fork, the parent waits up to the specified number of +seconds for the child to first synchronize the clock. The exit +status is zero (success) if the clock was synchronized, +otherwise it is \fBETIMEDOUT\fP. +This provides the option for a script starting \fBntpd\fP to easily +wait for the first set of the clock before proceeding. +.It Fl x , Fl \-slew +Slew up to 600 seconds. +.sp +Normally, the time is slewed if the offset is less than the step threshold, which is 128 ms by default, and stepped if above the threshold. +This option sets the threshold to 600 s, which is well within the accuracy window to set the clock manually. +Note: Since the slew rate of typical Unix kernels is limited to 0.5 ms/s, each second of adjustment requires an amortization interval of 2000 s. Thus, an adjustment as much as 600 s will take almost 14 days to complete. This option can be used with the -.Fl g +\fB\-g\fP and -.Fl q +\fB\-q\fP options. See the -.Ic tinker -command for other options. +\fBtinker\fP +configuration file directive for other options. Note: The kernel time discipline is disabled with this option. +.It Fl \-usepcc +Use CPU cycle counter (Windows only). +.sp +Attempt to substitute the CPU counter for \fBQueryPerformanceCounter\fP. +The CPU counter and \fBQueryPerformanceCounter\fP are compared, and if +they have the same frequency, the CPU counter (RDTSC on x86) is +used directly, saving the overhead of a system call. +.It Fl \-pccfreq Ns = Ns Ar string +Force CPU cycle counter use (Windows only). +.sp +Force substitution the CPU counter for \fBQueryPerformanceCounter\fP. +The CPU counter (RDTSC on x86) is used unconditionally with the +given frequency (in Hz). +.It Fl m , Fl \-mdns +Register with mDNS as a NTP server. +.sp +Registers as an NTP server with the local mDNS server which allows +the server to be discovered via mDNS client lookup. +.It Fl \&? , Fl \-help +Display usage information and exit. +.It Fl \&! , Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl \-version Op Brq Ar v|c|n +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. .El +.Sh "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from environment variables named: +.nf + \fBNTPD_<option\-name>\fP or \fBNTPD\fP +.fi +.ad +.Sh USAGE .Ss "How NTP Operates" The .Nm utility operates by exchanging messages with -one or more configured servers at designated poll intervals. +one or more configured servers over a range of designated poll intervals. When started, whether for the first or subsequent times, the program requires several exchanges from the majority of these servers so @@ -241,7 +394,8 @@ an interval randomized over a few seconds. At the default initial poll interval of 64s, several minutes can elapse before the clock is set. -The initial delay to set the clock can be reduced using the +This initial delay to set the clock +can be safely and dramatically reduced using the .Cm iburst keyword with the .Ic server @@ -250,19 +404,23 @@ command, as described in .Xr ntp.conf 5 . .Pp Most operating systems and hardware of today incorporate a -time-of-year (TOY) chip to maintain the time during periods when +time\-of\-year (TOY) chip to maintain the time during periods when the power is off. When the machine is booted, the chip is used to initialize the operating system time. After the machine has synchronized to a NTP server, the operating system corrects the chip from time to time. -In case there is no TOY chip or for some -reason its time is more than 1000s from the server time, +In the default case, if +.Nm +detects that the time on the host +is more than 1000s from the server time, .Nm assumes something must be terribly wrong and the only reliable action is for the operator to intervene and set the clock by hand. +(Reasons for this include there is no TOY chip, +or its battery is dead, or that the TOY chip is just of poor quality.) This causes .Nm to exit with a panic message to @@ -270,10 +428,12 @@ the system log. The .Fl g option overrides this check and the -clock will be set to the server time regardless of the chip time. +clock will be set to the server time regardless of the chip time +(up to 68 years in the past or future \(em +this is a limitation of the NTPv4 protocol). However, and to protect against broken hardware, such as when the CMOS battery fails or the clock counter becomes defective, once the -clock has been set, an error greater than 1000s will cause +clock has been set an error greater than 1000s will cause .Nm to exit anyway. .Pp @@ -284,7 +444,7 @@ small steps so that the timescale is effectively continuous and without discontinuities. Under conditions of extreme network congestion, the roundtrip delay jitter can exceed three seconds and -the synchronization distance, which is equal to one-half the +the synchronization distance, which is equal to one\-half the roundtrip delay plus error budget terms, can become very large. The .Nm @@ -297,27 +457,30 @@ In practice this reduces the false alarm rate where the clock is stepped in error to a vanishingly low incidence. .Pp -As the result of this behavior, once the clock has been set, it -very rarely strays more than 128 ms, even under extreme cases of +As the result of this behavior, once the clock has been set it +very rarely strays more than 128 ms even under extreme cases of network path congestion and jitter. Sometimes, in particular when .Nm -is first started, the error might exceed 128 ms. -This -may on occasion cause the clock to be set backwards if the local -clock time is more than 128 s in the future relative to the server. +is first started without a valid drift file +on a system with a large intrinsic drift +the error might grow to exceed 128 ms, +which would cause the clock to be set backwards +if the local clock time is more than 128 s +in the future relative to the server. In some applications, this behavior may be unacceptable. +There are several solutions, however. If the .Fl x option is included on the command line, the clock will never be stepped and only slew corrections will be used. -.Pp -The issues should be carefully explored before deciding to use +But this choice comes with a cost that +should be carefully explored before deciding to use the .Fl x option. The maximum slew rate possible is limited -to 500 parts-per-million (PPM) as a consequence of the correctness +to 500 parts\-per\-million (PPM) as a consequence of the correctness principles on which the NTP protocol and algorithm design are based. As a result, the local clock can take a long time to @@ -330,7 +493,7 @@ correctly synchronized network time. .Pp In spite of the above precautions, sometimes when large frequency errors are present the resulting time offsets stray -outside the 128-ms range and an eventual step or slew time +outside the 128\-ms range and an eventual step or slew time correction is required. If following such a correction the frequency error is so large that the first sample is outside the @@ -343,7 +506,7 @@ The intent of this behavior is to quickly correct the frequency and restore operation to the normal tracking mode. In the most extreme cases -( +(the host .Cm time.ien.it comes to mind), there may be occasional step/slew corrections and subsequent frequency corrections. @@ -351,7 +514,71 @@ It helps in these cases to use the .Cm burst keyword when -configuring the server. +configuring the server, but +ONLY +when you have permission to do so from the owner of the target host. +.Pp +Finally, +in the past many startup scripts would run +.Xr ntpdate 8 +to get the system clock close to correct before starting +.Xr ntpd 8 , +but this was never more than a mediocre hack and is no longer needed. +If you are following the instructions in +.Sx "Starting NTP (Best Current Practice)" +and you still need to set the system time before starting +.Nm , +please open a bug report and document what is going on, +and then look at using +.Xr sntp 8 . +.Pp +There is a way to start +.Xr ntpd 8 +that often addresses all of the problems mentioned above. +.Ss "Starting NTP (Best Current Practice)" +First, use the +.Cm iburst +option on your +.Cm server +entries. +.Pp +If you can also keep a good +.Pa ntp.drift +file then +.Xr ntpd 8 +will effectively "warm\-start" and your system's clock will +be stable in under 11 seconds' time. +.Pp +As soon as possible in the startup sequence, start +.Xr ntpd 8 +with at least the +.Fl g +and perhaps the +.Fl N +options. +Then, +start the rest of your "normal" processes. +This will give +.Xr ntpd 8 +as much time as possible to get the system's clock synchronized and stable. +.Pp +Finally, +if you have processes like +.Cm dovecot +or database servers +that require +monotonically\-increasing time, +run +.Xr ntp\-wait 1ntp\-waitmdoc +as late as possible in the boot sequence +(perhaps with the +.Fl v +flag) +and after +.Xr ntp\-wait 1ntp\-waitmdoc +exits successfully +it is as safe as it will ever be to start any process that require +stable time. .Ss "Frequency Discipline" The .Nm @@ -397,12 +624,12 @@ provided in It normally operates continuously while monitoring for small changes in frequency and trimming the clock for the ultimate precision. -However, it can operate in a one-time +However, it can operate in a one\-time mode where the time is set from an external server and frequency is set from a previously recorded frequency file. A broadcast/multicast or manycast client can discover remote servers, -compute server-client propagation delay correction factors and +compute server\-client propagation delay correction factors and configure itself automatically. This makes it possible to deploy a fleet of workstations without specifying configuration details @@ -427,16 +654,17 @@ to 1024s in order to reduce network overhead. .Pp In some cases it may not be practical for .Nm -to run -continuously. +to run continuously. A common workaround has been to run the .Xr ntpdate 8 -program from a +or +.Xr sntp 8 +programs from a .Xr cron 8 job at designated times. -However, this program does not have the crafted signal -processing, error checking and mitigation algorithms of +However, these programs do not have the crafted signal +processing, error checking or mitigation algorithms of .Nm . The .Fl q @@ -460,7 +688,7 @@ couple of minutes, the daemon times out and exits. After a suitable period of mourning, the .Xr ntpdate 8 -program may be +program will be retired. .Pp When kernel support is available to discipline the clock @@ -478,7 +706,7 @@ the frequency and offset to settle down. Then the .Nm is -stopped and run in one-time mode as required. +stopped and run in one\-time mode as required. At each startup, the frequency is read from the file and initializes the kernel frequency. @@ -529,7 +757,7 @@ this limit. Once this is done, the drift file is automatically updated once per hour and is available to initialize the frequency on subsequent daemon restarts. -.Ss "The huff-n'-puff Filter" +.Ss "The huff\-n'\-puff Filter" In scenarios where a considerable amount of data are to be downloaded or uploaded over telephone modems, timekeeping quality can be seriously degraded. @@ -540,7 +768,7 @@ many cases the apparent time errors are so large as to exceed the step threshold and a step correction can occur during and after the data transfer is in progress. .Pp -The huff-n'-puff filter is designed to correct the apparent time +The huff\-n'\-puff filter is designed to correct the apparent time offset in these cases. It depends on knowledge of the propagation delay when no other traffic is present. @@ -563,6 +791,8 @@ command and .Cm huffpuff keyword, as described in .Xr ntp.conf 5 . +.Sh "ENVIRONMENT" +See \fBOPTION PRESETS\fP for configuration environment variables. .Sh FILES .Bl -tag -width /etc/ntp.drift -compact .It Pa /etc/ntp.conf @@ -572,11 +802,23 @@ the default name of the drift file .It Pa /etc/ntp.keys the default name of the key file .El -.Sh SEE ALSO +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. +.El +.Sh "SEE ALSO" .Xr ntp.conf 5 , .Xr ntpdate 8 , .Xr ntpdc 8 , -.Xr ntpq 8 +.Xr ntpq 8 , +.Xr sntp 8 .Pp In addition to the manual pages provided, comprehensive documentation is available on the world wide web @@ -599,14 +841,53 @@ A snapshot of this documentation is available in HTML format in .%T Network Time Protocol (Version 3) .%O RFC1305 .Re +.Rs +.%A David L. Mills +.%A J. Martin, Ed. +.%A J. Burbank +.%A W. Kasch +.%T Network Time Protocol Version 4: Protocol and Algorithms Specification +.%O RFC5905 +.Re +.Rs +.%A David L. Mills +.%A B. Haberman, Ed. +.%T Network Time Protocol Version 4: Autokey Specification +.%O RFC5906 +.Re +.Rs +.%A H. Gerstung +.%A C. Elliott +.%A B. Haberman, Ed. +.%T Definitions of Managed Objects for Network Time Protocol Version 4: (NTPv4) +.%O RFC5907 +.Re +.Rs +.%A R. Gayraud +.%A B. Lourdelet +.%T Network Time Protocol (NTP) Server Option for DHCPv6 +.%O RFC5908 +.Re +.Sh "AUTHORS" +The University of Delaware and Network Time Foundation +.Sh "COPYRIGHT" +Copyright (C) 1992\-2015 The University of Delaware and Network Time Foundation all rights reserved. +This program is released under the terms of the NTP license, <http://ntp.org/license>. .Sh BUGS The .Nm utility has gotten rather fat. While not huge, it has gotten -larger than might be desirable for an elevated-priority +larger than might be desirable for an elevated\-priority .Nm running on a workstation, particularly since many of the fancy features which consume the space were designed more with a busy primary server, rather than a high stratum workstation in mind. +.Pp +Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org +.Sh NOTES +Portions of this document came from FreeBSD. +.Pp +This manual page was \fIAutoGen\fP\-erated from the \fBntpd\fP +option definitions. diff --git a/usr.sbin/ntp/doc/ntpdc.8 b/usr.sbin/ntp/doc/ntpdc.8 index 35ea7aa..3373614 100644 --- a/usr.sbin/ntp/doc/ntpdc.8 +++ b/usr.sbin/ntp/doc/ntpdc.8 @@ -1,25 +1,38 @@ +.Dd February 4 2015 +.Dt NTPDC 8 User Commands +.Os +.\" EDIT THIS FILE WITH CAUTION (ntpdc-opts.mdoc) .\" .\" $FreeBSD$ .\" -.Dd May 17, 2006 -.Dt NTPDC 8 -.Os +.\" It has been AutoGen-ed February 4, 2015 at 02:42:44 AM by AutoGen 5.18.5pre4 +.\" From the definitions ntpdc-opts.def +.\" and the template file agmdoc-cmd.tpl .Sh NAME .Nm ntpdc -.Nd special NTP query program +.Nd vendor-specific NTPD control program .Sh SYNOPSIS .Nm -.Op Fl 46ilnps -.Op Fl c Ar command -.Op Ar host -.Op Ar ... +.\" Mixture of short (flag) options and long options +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option\-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +[ host ...] +.Pp .Sh DESCRIPTION -The .Nm -utility is used to query the +is deprecated. +Please use +.Xr ntpq 8 instead \- it can do everything +.Nm +used to do, and it does so using a much more sane interface. +.Pp +.Nm +is a utility program used to query .Xr ntpd 8 -daemon about its +about its current state and to request changes in that state. +It uses NTP mode 7 control message formats described in the source code. The program may be run either in interactive mode or controlled using command line arguments. @@ -31,51 +44,103 @@ In addition, nearly all the configuration options which can be specified at startup using ntpd's configuration file may also be specified at run time using .Nm . -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl 4 -Force DNS resolution of following host names on the command line to the -IPv4 namespace. -.It Fl 6 -Force DNS resolution of following host names on the command line to the -IPv6 namespace. -.It Fl c Ar command -The following argument is interpreted as an interactive format -command and is added to the list of commands to be executed on the -specified host(s). -Multiple -.Fl c -options may be given. -.It Fl i -Force -.Nm -to operate in interactive mode. -Prompts -will be written to the standard output and commands read from the -standard input. -.It Fl l -Obtain a list of peers which are known to the server(s). -This -switch is equivalent to -.Ql Fl c Ar listpeers . -.It Fl n -Output all host addresses in dotted-quad numeric format rather -than converting to the canonical host names. -.It Fl p -Print a list of the peers known to the server as well as a -summary of their state. -This is equivalent to -.Ql Fn c Ar peers . -.It Fl s -Print a list of the peers known to the server as well as a -summary of their state, but in a slightly different format than the -.Fl p -switch. -This is equivalent to -.Ql Fl c Ar dmpeers . +.Sh "OPTIONS" +.Bl -tag +.It Fl 4 , Fl \-ipv4 +Force IPv4 DNS name resolution. +This option must not appear in combination with any of the following options: +ipv6. +.sp +Force DNS resolution of following host names on the command line +to the IPv4 namespace. +.It Fl 6 , Fl \-ipv6 +Force IPv6 DNS name resolution. +This option must not appear in combination with any of the following options: +ipv4. +.sp +Force DNS resolution of following host names on the command line +to the IPv6 namespace. +.It Fl c Ar cmd , Fl \-command Ns = Ns Ar cmd +run a command and exit. +This option may appear an unlimited number of times. +.sp +The following argument is interpreted as an interactive format command +and is added to the list of commands to be executed on the specified +host(s). +.It Fl d , Fl \-debug\-level +Increase debug verbosity level. +This option may appear an unlimited number of times. +.sp +.It Fl D Ar number , Fl \-set\-debug\-level Ns = Ns Ar number +Set the debug verbosity level. +This option may appear an unlimited number of times. +This option takes an integer number as its argument. +.sp +.It Fl i , Fl \-interactive +Force ntpq to operate in interactive mode. +This option must not appear in combination with any of the following options: +command, listpeers, peers, showpeers. +.sp +Force ntpq to operate in interactive mode. Prompts will be written +to the standard output and commands read from the standard input. +.It Fl l , Fl \-listpeers +Print a list of the peers. +This option must not appear in combination with any of the following options: +command. +.sp +Print a list of the peers known to the server as well as a summary of +their state. This is equivalent to the 'listpeers' interactive command. +.It Fl n , Fl \-numeric +numeric host addresses. +.sp +Output all host addresses in dotted\-quad numeric format rather than +converting to the canonical host names. +.It Fl p , Fl \-peers +Print a list of the peers. +This option must not appear in combination with any of the following options: +command. +.sp +Print a list of the peers known to the server as well as a summary +of their state. This is equivalent to the 'peers' interactive command. +.It Fl s , Fl \-showpeers +Show a list of the peers. +This option must not appear in combination with any of the following options: +command. +.sp +Print a list of the peers known to the server as well as a summary +of their state. This is equivalent to the 'dmpeers' interactive command. +.It Fl \&? , Fl \-help +Display usage information and exit. +.It Fl \&! , Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl > Oo Ar cfgfile Oc , Fl \-save\-opts Oo Ns = Ns Ar cfgfile Oc +Save the option state to \fIcfgfile\fP. The default is the \fIlast\fP +configuration file listed in the \fBOPTION PRESETS\fP section, below. +The command will exit after updating the config file. +.It Fl < Ar cfgfile , Fl \-load\-opts Ns = Ns Ar cfgfile , Fl \-no\-load\-opts +Load options from \fIcfgfile\fP. +The \fIno\-load\-opts\fP form will disable the loading +of earlier config/rc/ini files. \fI\-\-no\-load\-opts\fP is handled early, +out of order. +.It Fl \-version Op Brq Ar v|c|n +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. .El -.Pp +.Sh "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from configuration ("RC" or ".INI") file(s) and values from +environment variables named: +.nf + \fBNTPDC_<option\-name>\fP or \fBNTPDC\fP +.fi +.ad +The environmental presets take precedence (are processed later than) +the configuration files. +The \fIhomerc\fP files are "\fI$HOME\fP", and "\fI.\fP". +If any of these are directories, then the file \fI.ntprc\fP +is searched for within those directories. +.Sh USAGE If one or more request options are included on the command line when .Nm @@ -231,7 +296,7 @@ a timeout will be twice the timeout value set. .Ss "Control Message Commands" Query commands result in NTP mode 7 packets containing requests for information being sent to the server. -These are read-only commands +These are read\-only commands in that they make no modification of the server configuration state. .Bl -tag -width indent @@ -258,7 +323,7 @@ entry is operating in. A .Ql \&+ denotes symmetric active, a -.Ql \&- +.Ql \&\- indicates symmetric passive, a .Ql \&= means the @@ -267,6 +332,8 @@ remote server is being polled in client mode, a indicates that the server is broadcasting to this address, a .Ql \&~ denotes that the remote peer is sending broadcasts and a +.Ql \&~ +denotes that the remote peer is sending broadcasts and a .Ql \&* marks the peer the server is currently synchronizing to. @@ -279,7 +346,7 @@ name with its parameter or On .Ic hostnames .Cm no -only IP-addresses +only IP\-addresses will be displayed. .It Ic dmpeers A slightly different peer summary list. @@ -307,15 +374,15 @@ or more peers. Most of these values are described in the NTP Version 2 specification. .It Ic pstats Ar peer_address Oo Ar ... Oc -Show per-peer statistic counters associated with the specified +Show per\-peer statistic counters associated with the specified peer(s). -.It Ic clockinfo Ar clock_peer_address Oo Ar ... Oc +.It Ic clockstat Ar clock_peer_address Oo Ar ... Oc Obtain and print information concerning a peer clock. The values obtained provide information on the setting of fudge factors and other clock performance information. .It Ic kerninfo -Obtain and print kernel phase-lock loop operating parameters. +Obtain and print kernel phase\-lock loop operating parameters. This information is available only if the kernel has been specially modified for a precision timekeeping function. .It Ic loopinfo Op Cm oneline | Cm multiline @@ -329,12 +396,12 @@ is the last offset given to the loop filter by the packet processing code. The .Sq frequency -is the frequency error of the local clock in parts-per-million +is the frequency error of the local clock in parts\-per\-million (ppm). The .Sq time_const controls the stiffness of the -phase-lock loop and thus the speed at which it can adapt to +phase\-lock loop and thus the speed at which it can adapt to oscillator drift. The .Sq watchdog timer @@ -354,7 +421,7 @@ default. Print a variety of system state variables, i.e., state related to the local server. All except the last four lines are described -in the NTP Version 3 specification, RFC-1305. +in the NTP Version 3 specification, RFC\-1305. .Pp The .Sq system flags @@ -428,7 +495,7 @@ module. Print statistics counters related to memory allocation code. .It Ic iostats -Print statistics counters maintained in the input-output +Print statistics counters maintained in the input\-output module. .It Ic timerstats Print statistics counters maintained in the timer/event queue @@ -487,7 +554,7 @@ it more difficult to request configuration changes to your server from topologically remote hosts. While the reconfiguration facility will work well with a server on the local host, and may work -adequately between time-synchronized hosts on the same LAN, it will +adequately between time\-synchronized hosts on the same LAN, it will work very poorly for more distant hosts. As such, if reasonable passwords are chosen, care is taken in the distribution and @@ -523,7 +590,7 @@ The keyword indicates a preferred peer (and thus will be used primarily for clock synchronisation if possible). The -preferred peer also determines the validity of the PPS signal - if +preferred peer also determines the validity of the PPS signal \- if the preferred peer is suitable for synchronisation so is the PPS signal. .It Xo Ic addserver Ar peer_address @@ -547,7 +614,7 @@ The parameter can be the broadcast address of the local network or a multicast group address assigned to NTP. -If a multicast address, a multicast-capable kernel is +If a multicast address, a multicast\-capable kernel is required. .It Ic unconfig Ar peer_address Oo Ar ... Oc This command causes the configured bit to be removed from the @@ -607,9 +674,9 @@ Enables the kernel time discipline, if available. The default for this flag is enable if support is available, otherwise disable. .It Cm monitor Enables the monitoring facility. -See the -.Xr ntpdc 8 . -program and the monlist command or further information. +See the documentation here about the +.Cm monlist +command or further information. The default for this flag is enable. .It Cm ntp Enables time and frequency discipline. @@ -617,7 +684,7 @@ In effect, this switch opens and closes the feedback loop, which is useful for testing. The default for this flag is enable. .It Cm pps -Enables the pulse-per-second (PPS) signal when frequency +Enables the pulse\-per\-second (PPS) signal when frequency and time is disciplined by the precision time kernel modifications. See the .Qq A Kernel Model for Precision Timekeeping @@ -694,7 +761,24 @@ for further information. Clear the statistics counters in various modules of the server. See the source listing for further information. .El -.Sh SEE ALSO +.Sh "ENVIRONMENT" +See \fBOPTION PRESETS\fP for configuration environment variables. +.Sh "FILES" +See \fBOPTION PRESETS\fP for configuration files. +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 66 " (EX_NOINPUT)" +A specified configuration file could not be loaded. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. +.El +.Sh "SEE ALSO" .Xr ntp.conf 5 , .Xr ntpd 8 .Rs @@ -702,6 +786,11 @@ See the source listing for further information. .%T Network Time Protocol (Version 3) .%O RFC1305 .Re +.Sh AUTHORS +The formatting directives in this document came from FreeBSD. +.Sh "COPYRIGHT" +Copyright (C) 1992\-2015 The University of Delaware and Network Time Foundation all rights reserved. +This program is released under the terms of the NTP license, <http://ntp.org/license>. .Sh BUGS The .Nm @@ -713,3 +802,10 @@ program was designed so that new (and temporary) features were easy to hack in, at great expense to the program's ease of use. Despite this, the program is occasionally useful. +.Pp +Please report bugs to http://bugs.ntp.org . +.Pp +Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org +.Sh "NOTES" +This manual page was \fIAutoGen\fP\-erated from the \fBntpdc\fP +option definitions. diff --git a/usr.sbin/ntp/doc/ntpq.8 b/usr.sbin/ntp/doc/ntpq.8 index 0a47c76..1eba486 100644 --- a/usr.sbin/ntp/doc/ntpq.8 +++ b/usr.sbin/ntp/doc/ntpq.8 @@ -1,39 +1,44 @@ +.Dd February 4 2015 +.Dt NTPQ 8 User Commands +.Os +.\" EDIT THIS FILE WITH CAUTION (ntpq-opts.mdoc) .\" .\" $FreeBSD$ .\" -.Dd May 17, 2006 -.Dt NTPQ 8 -.Os +.\" It has been AutoGen-ed February 4, 2015 at 02:43:19 AM by AutoGen 5.18.5pre4 +.\" From the definitions ntpq-opts.def +.\" and the template file agmdoc-cmd.tpl .Sh NAME .Nm ntpq .Nd standard NTP query program .Sh SYNOPSIS .Nm -.Op Fl inp -.Op Fl c Ar command -.Op Ar host -.Op Ar ... +.\" Mixture of short (flag) options and long options +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option\-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +[ host ...] +.Pp .Sh DESCRIPTION The .Nm -utility is used to monitor NTP daemon -.Xr ntpd 8 -operations and determine performance. -It uses the standard NTP mode 6 control message formats -defined in Appendix B of the NTPv3 specification RFC1305. -The same formats are used in NTPv4, although some of the variables -have changed and new ones added. -The description on this page is for the NTPv4 variables. -.Pp -The program can be run either in interactive mode or controlled -using command line arguments. -Requests to read and write arbitrary variables can be assembled, -with raw and pretty-printed output options being available. +utility program is used to query NTP servers which +implement the standard NTP mode 6 control message formats defined +in Appendix B of the NTPv3 specification RFC1305, requesting +information about current state and/or changes in that state. +The same formats are used in NTPv4, although some of the +variables have changed and new ones added. The description on this +page is for the NTPv4 variables. +The program may be run either in interactive mode or controlled using +command line arguments. +Requests to read and write arbitrary +variables can be assembled, with raw and pretty\-printed output +options being available. The .Nm -can also obtain and print a list of peers in a common format -by sendingmultiple queries to the server. -.Pp +utility can also obtain and print a +list of peers in a common format by sending multiple queries to the +server. If one or more request options is included on the command line when .Nm @@ -51,10 +56,8 @@ The .Nm utility will prompt for commands if the standard input is a terminal device. -.Pp -The .Nm -utility uses NTP mode 6 packets to communicate with the +uses NTP mode 6 packets to communicate with the NTP server, and hence can be used to query any compatible server on the network which permits it. Note that since NTP is a UDP protocol @@ -66,55 +69,6 @@ utility makes one attempt to retransmit requests, and will time requests out if the remote host is not heard from within a suitable timeout time. -.Pp -For examples and usage, see the -.Qq NTP Debugging Techniques -page -(available as part of the HTML documentation -provided in -.Pa /usr/share/doc/ntp ) . -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl 4 -Force DNS resolution of following host names on the command line to the -IPv4 namespace. -.It Fl 6 -Force DNS resolution of following host names on the command line to the -IPv6 namespace. -.It Fl c -The following argument is interpreted as an interactive format -command and is added to the list of commands to be executed on the -specified host(s). -Multiple -.Fl c -options may be given. -.It Fl d -Turn on debugging mode. -.It Fl i -Force -.Nm -to operate in interactive mode. -Prompts -will be written to the standard output and commands read from the -standard input. -.It Fl n -Output all host addresses in dotted-quad numeric format rather -than converting to the canonical host names. -.It Fl p -Print a list of the peers known to the server as well as a -summary of their state. -This is equivalent to the -.Ic peers -interactive command. -.El -.Pp -Note that in contexts where a host name is expected, a -.Fl 4 -qualifier preceding the host name forces DNS resolution to the -IPv4 namespace, while a -.Fl 6 -qualifier forces DNS resolution to the IPv6 namespace. Specifying a command line option other than .Fl i @@ -132,11 +86,6 @@ Interactive format commands consist of a keyword followed by zero to four arguments. Only enough characters of the full keyword to uniquely identify the command need be typed. -The output of a -command is normally sent to the standard output, but optionally the -output of individual commands may be sent to a file by appending a -.Ql \&> , -followed by a file name, to the command line. A number of interactive format commands are executed entirely within the @@ -144,16 +93,16 @@ the utility itself and do not result in NTP mode 6 requests being sent to a server. These are described following. -.Bl -tag -width indent -.It Ic \&? Op Ar command_keyword +.Bl -tag -width "? [command_keyword]" -compact -offset indent +.It Ic ? Op Ar command_keyword .It Ic help Op Ar command_keyword A -.Sq Ic \&? +.Ql \&? by itself will print a list of all the command keywords known to this incarnation of .Nm . A -.Sq Ic \&? +.Ql \&? followed by a command keyword will print function and usage information about the command. This command is probably a better @@ -161,11 +110,12 @@ source of information about .Nm than this manual page. -.It Xo Ic addvars -.Ar variable_name Ns Op = Ns Ar value ... +.It Ic addvars Ar variable_name Ns Xo Op Ic =value +.Ic ... .Xc -.It Ic rmvars Ar variable_name ... +.It Ic rmvars Ar variable_name Ic ... .It Ic clearvars +.It Ic showvars The data carried by NTP mode 6 messages consists of a list of items of the form .Ql variable_name=value , @@ -186,7 +136,7 @@ The command allows variables and their optional values to be added to the list. If more than one variable is to be added, the list should -be comma-separated and not contain white space. +be comma\-separated and not contain white space. The .Ic rmvars command can be used to remove individual variables from the list, @@ -194,6 +144,32 @@ while the .Ic clearlist command removes all variables from the list. +The +.Ic showvars +command displays the current list of optional variables. +.It Ic authenticate Op yes | no +Normally +.Nm +does not authenticate requests unless +they are write requests. +The command +.Ql authenticate yes +causes +.Nm +to send authentication with all requests it +makes. +Authenticated requests causes some servers to handle +requests slightly differently, and can occasionally melt the CPU in +fuzzballs if you turn authentication on before doing a +.Ic peer +display. +The command +.Ql authenticate +causes +.Nm +to display whether or not +.Nm +is currently autheinticating requests. .It Ic cooked Causes output from query commands to be "cooked", so that variables which are recognized by @@ -202,15 +178,19 @@ will have their values reformatted for human consumption. Variables which .Nm -thinks should have a decodable value but did not are +thinks should have a decodable value but didn't are marked with a trailing .Ql \&? . -.It Xo Ic debug +.It Xo +.Ic debug +.Oo .Cm more | .Cm less | .Cm off +.Oc .Xc -Turns internal query program debugging on and off. +With no argument, displays the current debug level. +Otherwise, the debug level is changed to the indicated level. .It Ic delay Ar milliseconds Specify a time interval to be added to timestamps included in requests which require authentication. @@ -220,11 +200,14 @@ or between machines whose clocks are unsynchronized. Actually the server does not now require timestamps in authenticated requests, so this command may be obsolete. +.It Ic exit +Exit +.Nm . .It Ic host Ar hostname Set the host to which future queries will be sent. -Hostname may -be either a host name or a numeric address. -.It Ic hostnames Cm yes | Cm no +.Ar hostname +may be either a host name or a numeric address. +.It Ic hostnames Op Cm yes | Cm no If .Cm yes is specified, host names are printed in @@ -240,36 +223,64 @@ modified using the command line .Fl n switch. .It Ic keyid Ar keyid -This command specifies the key number to be used to authenticate -configuration requests. -This must correspond to a key number the server has -been configured to use for this purpose. -.It Xo Ic ntpversion +This command allows the specification of a key number to be +used to authenticate configuration requests. +This must correspond +to a key number the server has been configured to use for this +purpose. +.It Ic keytype Xo Oo +.Cm md5 | +.Cm OpenSSLDigestType +.Oc +.Xc +Specify the type of key to use for authenticating requests. +.Cm md5 +is alway supported. +If +.Nm +was built with OpenSSL support, +any digest type supported by OpenSSL can also be provided. +If no argument is given, the current +.Ic keytype +is displayed. +.It Ic ntpversion Xo Oo .Cm 1 | .Cm 2 | .Cm 3 | .Cm 4 +.Oc .Xc Sets the NTP version number which .Nm claims in packets. -Defaults to 3, Note that mode 6 control messages (and -modes, for that matter) did not exist in NTP version 1. +Defaults to 3, and note that mode 6 control messages (and +modes, for that matter) didn't exist in NTP version 1. There appear to be no servers left which demand version 1. +With no argument, displays the current NTP version that will be used +when communicating with servers. .It Ic passwd -This command prompts for a password (which will not be echoed) which will -be used to authenticate configuration requests. -The password must -correspond to the key configured for NTP server for this purpose. +This command prompts you to type in a password (which will not +be echoed) which will be used to authenticate configuration +requests. +The password must correspond to the key configured for +use by the NTP server for this purpose if such requests are to be +successful. +.\" Not yet implemented. +.\" .It Ic poll +.\" .Op Ar n +.\" .Op Ic verbose +.\" Poll an NTP server in client mode +.\" .Ar n +.\" times. .It Ic quit Exit .Nm . .It Ic raw Causes all output from query commands is printed as received from the remote server. -The only formatting/interpretation done on +The only formating/interpretation done on the data is to transform nonascii data into a printable (but barely understandable) form. .It Ic timeout Ar milliseconds @@ -280,572 +291,666 @@ Note that since .Nm retries each query once after a timeout, the total waiting time for a timeout will be twice the timeout value set. +.It Ic version +Print the version of the +.Nm +program. .El -.Ss Control Message Commands -Each association known to an NTP server has a 16 bit integer association -identifier. -NTP control messages which carry peer variables must identify the -peer the values correspond to by including its association ID. -An association -ID of 0 is special, and indicates the variables are system variables, whose -names are drawn from a separate name space. -.Pp -Control message commands result in one or more NTP mode 6 -messages being sent to the server, and cause the data returned to -be printed in some format. -Most commands currently implemented send -a single message and expect a single response. -The current -exceptions are the peers command, which will send a preprogrammed -series of messages to obtain the data it needs, and the mreadlist -and mreadvar commands, which will iterate over a range of -associations. -.Bl -tag -width indent -.It Ic associations -Obtains and prints a list of association identifiers and peer -statuses for in-spec peers of the server being queried. -The list is -printed in columns. -The first of these is an index numbering the -associations from 1 for internal use, the second the actual -association identifier returned by the server and the third the -status word for the peer. -This is followed by a number of columns -containing data decoded from the status word. -See the peers command -for a decode of the -.Sq condition -field. -Note that the data -returned by the -.Ic associations -command is cached internally -in -.Nm . -The index is then of use when dealing with stupid -servers which use association identifiers which are hard for humans -to type, in that for any subsequent commands which require an -association identifier as an argument, the form and index may be -used as an alternative. -.It Xo Ic clockvar Op Ar assocID -.Oo -.Ar variable_name Ns Op = Ns Ar value ... -.Oc -.Ar ... -.Xc -.It Xo Ic cv Op Ar assocID -.Oo -.Ar variable_name Ns Op = Ns Ar value ... -.Oc -.Ar ... -.Xc -Requests that a list of the server's clock variables be sent. -Servers which have a radio clock or other external synchronization -will respond positively to this. -If the association identifier is -omitted or zero the request is for the variables of the -.Sq system clock -and will generally get a positive response from all -servers with a clock. -If the server treats clocks as pseudo-peers, -and hence can possibly have more than one clock connected at once, -referencing the appropriate peer association ID will show the -variables of a particular clock. -Omitting the variable list will -cause the server to return a default variable display. +.Ss "Control Message Commands" +Association IDs are used to identify system, peer and clock variables. +System variables are assigned an association ID of zero and system name space, while each association is assigned a nonzero association ID and peer namespace. +Most control commands send a single mode\-6 message to the server and expect a single response message. +The exceptions are the +.Li peers +command, which sends a series of messages, +and the +.Li mreadlist +and +.Li mreadvar +commands, which iterate over a range of associations. +.Bl -tag -width "something" -compact -offset indent +.It Cm associations +Display a list of mobilized associations in the form: +.Dl ind assid status conf reach auth condition last_event cnt +.Bl -column -offset indent ".Sy Variable" ".Sy Description" +.It Sy String Ta Sy Description +.It Li ind Ta index on this list +.It Li assid Ta association ID +.It Li status Ta peer status word +.It Li conf Ta Li yes : persistent, Li no : ephemeral +.It Li reach Ta Li yes : reachable, Li no : unreachable +.It Li auth Ta Li ok , Li yes , Li bad and Li none +.It Li condition Ta selection status (see the Li select field of the peer status word) +.It Li last_event Ta event report (see the Li event field of the peer status word) +.It Li cnt Ta event count (see the Li count field of the peer status word) +.El +.It Cm authinfo +Display the authentication statistics. +.It Cm clockvar Ar assocID Oo Ar name Ns Oo Cm = Ns Ar value Oc Oc Op ... +.It Cm cv Ar assocID Oo Ar name Ns Oo Cm = Ns Ar value Oc Oc Op ... +Display a list of clock variables for those associations supporting a reference clock. +.It Cm :config Op ... +Send the remainder of the command line, including whitespace, to the server as a run\-time configuration command in the same format as a line in the configuration file. This command is experimental until further notice and clarification. Authentication is of course required. +.It Cm config\-from\-file Ar filename +Send the each line of +.Ar filename +to the server as run\-time configuration commands in the same format as a line in the configuration file. This command is experimental until further notice and clarification. Authentication is required. +.It Ic ifstats +Display statistics for each local network address. Authentication is required. +.It Ic iostats +Display network and reference clock I/O statistics. +.It Ic kerninfo +Display kernel loop and PPS statistics. As with other ntpq output, times are in milliseconds. The precision value displayed is in milliseconds as well, unlike the precision system variable. .It Ic lassociations -Obtains and prints a list of association identifiers and peer -statuses for all associations for which the server is maintaining -state. -This command differs from the -.Ic associations -command -only for servers which retain state for out-of-spec client -associations (i.e., fuzzballs). -Such associations are normally -omitted from the display when the -.Ic associations -command is -used, but are included in the output of -.Ic lassociations . -.It Ic lpassociations -Print data for all associations, including out-of-spec client -associations, from the internally cached list of associations. -This -command differs from -.Ic passociations -only when dealing with -fuzzballs. -.It Ic lpeers -Like R peers, except a summary of all associations for which -the server is maintaining state is printed. -This can produce a much -longer list of peers from fuzzball servers. -.It Ic mreadlist Ar assocID Ar assocID -.It Ic mrl Ar assocID Ar assocID -Like the -.Ic readlist -command, except the query is done -for each of a range of (nonzero) association IDs. -This range is -determined from the association list cached by the most recent -.Ic associations -command. -.It Xo Ic mreadvar Ar assocID Ar assocID -.Oo -.Ar variable_name Ns Op = Ns Ar value ... +Perform the same function as the associations command, except display mobilized and unmobilized associations. +.It Ic lopeers Xo +.Oo Ic \-4 | +.Ic \-6 .Oc .Xc -.It Xo Ic mrv Ar assocID Ar assocID -.Oo -.Ar variable_name Ns Op = Ns Ar value ... +Obtain and print a list of all peers and clients showing +.Ar dstadr +(associated with any given IP version). +.It Ic lpeers Xo +.Oo Ic \-4 | +.Ic \-6 .Oc .Xc -Like the +Print a peer spreadsheet for the appropriate IP version(s). +.Ar dstadr +(associated with any given IP version). +.It Ic monstats +Display monitor facility statistics. +.It Ic mrulist Oo Ic limited | Ic kod | Ic mincount Ns = Ns Ar count | Ic laddr Ns = Ns Ar localaddr | Ic sort Ns = Ns Ar sortorder | Ic resany Ns = Ns Ar hexmask | Ic resall Ns = Ns Ar hexmask Oc +Obtain and print traffic counts collected and maintained by the monitor facility. +With the exception of +.Cm sort Ns = Ns Ar sortorder , +the options filter the list returned by +.Cm ntpd. +The +.Cm limited +and +.Cm kod +options return only entries representing client addresses from which the last packet received triggered either discarding or a KoD response. +The +.Cm mincount Ns = Ns Ar count +option filters entries representing less than +.Ar count +packets. +The +.Cm laddr Ns = Ns Ar localaddr +option filters entries for packets received on any local address other than +.Ar localaddr . +.Cm resany Ns = Ns Ar hexmask +and +.Cm resall Ns = Ns Ar hexmask +filter entries containing none or less than all, respectively, of the bits in +.Ar hexmask , +which must begin with +.Cm 0x . +The +.Ar sortorder +defaults to +.Cm lstint +and may be any of +.Cm addr , +.Cm count , +.Cm avgint , +.Cm lstint , +or any of those preceded by a minus sign (hyphen) to reverse the sort order. +The output columns are: +.Bl -tag -width "something" -compact -offset indent +.It Column +Description +.It Ic lstint +Interval in s between the receipt of the most recent packet from this address and the completion of the retrieval of the MRU list by +.Nm . +.It Ic avgint +Average interval in s between packets from this address. +.It Ic rstr +Restriction flags associated with this address. +Most are copied unchanged from the matching +.Ic restrict +command, however 0x400 (kod) and 0x20 (limited) flags are cleared unless the last packet from this address triggered a rate control response. +.It Ic r +Rate control indicator, either +a period, +.Ic L +or +.Ic K +for no rate control response, +rate limiting by discarding, or rate limiting with a KoD response, respectively. +.It Ic m +Packet mode. +.It Ic v +Packet version number. +.It Ic count +Packets received from this address. +.It Ic rport +Source port of last packet from this address. +.It Ic remote address +DNS name, numeric address, or address followed by +claimed DNS name which could not be verified in parentheses. +.El +.It Ic mreadvar assocID assocID Oo Ar variable_name Ns Oo = Ns Ar value Oc Oc ... +.It Ic mrv assocID assocID Oo Ar variable_name Ns Oo = Ns Ar value Oc Oc ... +Perform the same function as the .Ic readvar -command, except the query is done for -each of a range of (nonzero) association IDs. -This range is -determined from the association list cached by the most recent +command, except for a range of association IDs. +This range is determined from the association list cached by the most recent .Ic associations command. -.It Ic opeers -An old form of the -.Ic peers -command with the reference ID -replaced by the local interface address. +.It Ic opeers Xo +.Oo Ic \-4 | +.Ic \-6 +.Oc +.Xc +Obtain and print the old\-style list of all peers and clients showing +.Ar dstadr +(associated with any given IP version), +rather than the +.Ar refid . .It Ic passociations -Displays association data concerning in-spec peers from the -internally cached list of associations. -This command performs -identically to the +Perform the same function as the .Ic associations -except that it displays -the internally stored data rather than making a new query. +command, +except that it uses previously stored data rather than making a new query. .It Ic peers -Obtains a current list peers of the server, along with a -summary of each peer's state. -Summary information includes the -address of the remote peer, the reference ID (0.0.0.0 if this is -unknown), the stratum of the remote peer, the type of the peer -(local, unicast, multicast or broadcast), when the last packet was -received, the polling interval, in seconds, the reachability -register, in octal, and the current estimated delay, -offset and dispersion of the peer, all in milliseconds. -The character at the left margin of each line shows the -synchronization status of the association and is a valuable -diagnostic tool. -The encoding and meaning of this character, -called the tally code, is given later in this page. -.It Ic pstatus Ar assocID -Sends a read status request to the server for the given -association. -The names and values of the peer variables returned -will be printed. -Note that the status word from the header is -displayed preceding the variables, both in hexadecimal and in -pidgeon English. +Display a list of peers in the form: +.Dl [tally]remote refid st t when pool reach delay offset jitter +.Bl -tag -width "something" -compact -offset indent +.It Variable +Description +.It Ic [tally] +single\-character code indicating current value of the +.Ic select +field of the +.Lk decode.html#peer "peer status word" +.It Ic remote +host name (or IP number) of peer. +The value displayed will be truncated to 15 characters unless the +.Fl w +flag is given, in which case the full value will be displayed +on the first line, +and the remaining data is displayed on the next line. +.It Ic refid +association ID or +.Lk decode.html#kiss "'kiss code" +.It Ic st +stratum +.It Ic t +.Ic u : +unicast or manycast client, +.Ic b : +broadcast or multicast client, +.Ic l : +local (reference clock), +.Ic s : +symmetric (peer), +.Ic A : +manycast server, +.Ic B : +broadcast server, +.Ic M : +multicast server +.It Ic when +sec/min/hr since last received packet +.It Ic poll +poll interval (log2 s) +.It Ic reach +reach shift register (octal) +.It Ic delay +roundtrip delay +.It Ic offset +offset of server relative to this host +.It Ic jitter +jitter +.El +.It Ic pstats Ar assocID +Show the statistics for the peer with the given +.Ar assocID . .It Ic readlist Ar assocID .It Ic rl Ar assocID -Requests that the values of the variables in the internal -variable list be returned by the server. -If the association ID is -omitted or is 0 the variables are assumed to be system variables. -Otherwise they are treated as peer variables. -If the internal -variable list is empty a request is sent without data, which should -induce the remote server to return a default display. -.It Xo Ic readvar Ar assocID -.Ar variable_name Ns Op = Ns Ar value -.Ar ... -.Xc -.It Xo Ic rv Ar assocID -.Ar variable_name Ns Op = Ns Ar value -.Ar ... -.Xc -Requests that the values of the specified variables be returned -by the server by sending a read variables request. +Read the system or peer variables included in the variable list. +.It Ic readvar Ar assocID Ar name Ns Oo Ns = Ns Ar value Oc Oo , ... Oc +.It Ic rv Ar assocID Ar name Ns Oo Ns = Ns Ar value Oc Oo , ... Oc +Display the specified variables. +If +.Ar assocID +is zero, the variables are from the +.Sx System Variables +name space, otherwise they are from the +.Sx Peer Variables +name space. +The +.Ar assocID +is required, as the same name can occur in both spaces. +If no +.Ar name +is included, all operative variables in the name space are displayed. +In this case only, if the +.Ar assocID +is omitted, it is assumed zero. +Multiple names are specified with comma separators and without whitespace. +Note that time values are represented in milliseconds +and frequency values in parts\-per\-million (PPM). +Some NTP timestamps are represented in the format +YYYYMMDDTTTT , +where YYYY is the year, +MM the month of year, +DD the day of month and +TTTT the time of day. +.It Ic reslist +Show the access control (restrict) list for +.Nm . +.It Ic saveconfig Ar filename +Write the current configuration, +including any runtime modifications given with +.Ic :config +or +.Ic config\-from\-file , +to the ntpd host's file +.Ar filename . +This command will be rejected by the server unless +.Lk miscopt.html#saveconfigdir "saveconfigdir" +appears in the +.Ic ntpd +configuration file. +.Ar filename +can use +.Xr strftime +format specifies to substitute the current date and time, for example, +.Ic q]saveconfig ntp\-%Y%m%d\-%H%M%S.confq] . +The filename used is stored in system variable +.Ic savedconfig . +Authentication is required. +.It Ic timerstats +Display interval timer counters. +.It Ic writelist Ar assocID +Write the system or peer variables included in the variable list. +.It Ic writevar Ar assocID Ar name Ns = Ns Ar value Op , ... +Write the specified variables. If the -association ID is omitted or is given as zero the variables are -system variables, otherwise they are peer variables and the values -returned will be those of the corresponding peer. -Omitting the -variable list will send a request with no data which should induce -the server to return a default display. +.Ar assocID +is zero, the variables are from the +.Sx System Variables +name space, otherwise they are from the +.Sx Peer Variables +name space. The -encoding and meaning of the variables derived from NTPv3 is given in -RFC-1305; the encoding and meaning of the additional NTPv4 variables are -given later in this page. -.It Xo Ic writevar Ar assocID -.Ar variable_name Ns Op = Ns Ar value -.Ar ... -.Xc -Like the readvar request, except the specified variables are -written instead of read. -.It Ic writelist Op Ar assocID -Like the readlist request, except the internal list variables -are written instead of read. +.Ar assocID +is required, as the same name can occur in both spaces. +.It Ic sysinfo +Display operational summary. +.It Ic sysstats +Print statistics counters maintained in the protocol module. .El -.Ss Tally Codes -The character in the left margin in the -.Sq peers -billboard, -called the tally code, shows the fate of each association -in the clock selection process. -Following is a list of these characters, the pigeon used -in the +.Ss Status Words and Kiss Codes +The current state of the operating program is shown +in a set of status words +maintained by the system. +Status information is also available on a per\-association basis. +These words are displayed in the .Ic rv -command, and a short explanation of the condition revealed. -.Bl -tag -width indent -.It space -.Pq reject -The peer is discarded as unreachable, synchronized to this server (synch -loop) or outrageous synchronization distance. -.It x -.Pq falsetick -The peer is discarded by the intersection algorithm as a falseticker. -.It \&. -.Pq excess -The peer is discarded as not among the first ten peers sorted by -synchronization distance and so is probably a poor candidate for further -consideration. -.It \&- -.Pq outlyer -The peer is discarded by the clustering algorithm as an outlyer. -.It \&+ -.Pq candidat -The peer is a survivor and a candidate for the combining algorithm. -.It \&# -.Pq selected -The peer is a survivor, but not among the first six peers sorted by -synchronization distance. -If the association is ephemeral, it may be -demobilized to conserve resources. -.It \&* -.Pq sys.peer -The peer has been declared the system peer and lends its variables to the -system variables. -.It o -.Pq pps.peer -The peer has been declared the system peer and lends its variables to -the system variables. -However, the actual system synchronization is derived -from a pulse-per-second (PPS) signal, either indirectly via the PPS -reference clock driver or directly via kernel interface. -.El -.Ss System Variables -The -.Cm status , -.Cm leap , -.Cm stratum , -.Cm precision , -.Cm rootdelay , -.Cm rootdispersion , -.Cm refid , -.Cm reftime , -.Cm poll , -.Cm offset , and -.Cm frequency -variables are described in RFC-1305 -specification. -Additional NTPv4 system variables include the following. -.Bl -tag -width indent -.It version -Everything you might need to know about the software version and generation -time. -.It processor -The processor and kernel identification string. -.It system -The operating system version and release identifier. -.It state -The state of the clock discipline state machine. -The values are described -in the architecture briefing on the NTP Project page linked from -www.ntp.org. -.It peer -The internal integer used to identify the association currently designated -the system peer. -.It jitter -The estimated time error of the system clock measured as an exponential -average of RMS time differences. -.It stability -The estimated frequency stability of the system clock measured as an -exponential average of RMS frequency differences. -.El +.Ic as +commands both in hexadecimal and in decoded short tip strings. +The codes, tips and short explanations are documented on the +.Lk decode.html "Event Messages and Status Words" +page. +The page also includes a list of system and peer messages, +the code for the latest of which is included in the status word. .Pp -When the NTPv4 daemon is compiled with the OpenSSL software library, additional -system variables are displayed, including some or all of the following, -depending on the particular dance: -.Bl -tag -width indent -.It flags -The current flags word bits and message digest algorithm identifier (NID) -in hex format. -The high order 16 bits of the four-byte word contain the NID -from the OpenSSL ligrary, while the low-order bits are interpreted as -follows: -.Bl -tag -width indent -.It 0x01 -autokey enabled -.It 0x02 -NIST leapseconds file loaded -.It 0x10 -PC identity scheme -.It 0x20 -IFF identity scheme -.It 0x40 -GQ identity scheme -.El -.It hostname -The name of the host as returned by the Unix -.Fn gethostname -library -function. -.It hostkey -The NTP filestamp of the host key file. -.It cert -A list of certificates held by the host. -Each entry includes the subject, -issuer, flags and NTP filestamp in order. -The bits are interpreted as -follows: -.Bl -tag -width indent -.It 0x01 -certificate has been signed by the server -.It 0x02 -certificate is trusted -.It 0x04 -certificate is private -.It 0x08 -certificate contains errors and should not be trusted +Information resulting from protocol machine state transitions +is displayed using an informal set of ASCII strings called +.Lk decode.html#kiss "kiss codes" . +The original purpose was for kiss\-o'\-death (KoD) packets +sent by the server to advise the client of an unusual condition. +They are now displayed, when appropriate, +in the reference identifier field in various billboards. +.Ss System Variables +The following system variables appear in the +.Ic rv +billboard. +Not all variables are displayed in some configurations. +.Bl -tag -width "something" -compact -offset indent +.It Variable +Description +.It Ic status +.Lk decode.html#sys "system status word" +.It Ic version +NTP software version and build time +.It Ic processor +hardware platform and version +.It Ic system +operating system and version +.It Ic leap +leap warning indicator (0\-3) +.It Ic stratum +stratum (1\-15) +.It Ic precision +precision (log2 s) +.It Ic rootdelay +total roundtrip delay to the primary reference clock +.It Ic rootdisp +total dispersion to the primary reference clock +.It Ic peer +system peer association ID +.It Ic tc +time constant and poll exponent (log2 s) (3\-17) +.It Ic mintc +minimum time constant (log2 s) (3\-10) +.It Ic clock +date and time of day +.It Ic refid +reference ID or +.Lk decode.html#kiss "kiss code" +.It Ic reftime +reference time +.It Ic offset +combined offset of server relative to this host +.It Ic sys_jitter +combined system jitter +.It Ic frequency +frequency offset (PPM) relative to hardware clock +.It Ic clk_wander +clock frequency wander (PPM) +.It Ic clk_jitter +clock jitter +.It Ic tai +TAI\-UTC offset (s) +.It Ic leapsec +NTP seconds when the next leap second is/was inserted +.It Ic expire +NTP seconds when the NIST leapseconds file expires .El -.It leapseconds -The NTP filestamp of the NIST leapseconds file. -.It refresh -The NTP timestamp when the host public cryptographic values were refreshed -and signed. -.It signature -The host digest/signature scheme name from the OpenSSL library. -.It tai -The TAI-UTC offset in seconds obtained from the NIST leapseconds table. +The jitter and wander statistics are exponentially\-weighted RMS averages. +The system jitter is defined in the NTPv4 specification; +the clock jitter statistic is computed by the clock discipline module. +.Pp +When the NTPv4 daemon is compiled with the OpenSSL software library, +additional system variables are displayed, +including some or all of the following, +depending on the particular Autokey dance: +.Bl -tag -width "something" -compact -offset indent +.It Variable +Description +.It Ic host +Autokey host name for this host +.It Ic ident +Autokey group name for this host +.It Ic flags +host flags (see Autokey specification) +.It Ic digest +OpenSSL message digest algorithm +.It Ic signature +OpenSSL digest/signature scheme +.It Ic update +NTP seconds at last signature update +.It Ic cert +certificate subject, issuer and certificate flags +.It Ic until +NTP seconds when the certificate expires .El .Ss Peer Variables -The -.Cm status , -.Cm srcadr , -.Cm srcport , -.Cm dstadr , -.Cm dstport , -.Cm leap , -.Cm stratum , -.Cm precision , -.Cm rootdelay , -.Cm rootdispersion , -.Cm readh , -.Cm hmode , -.Cm pmode , -.Cm hpoll , -.Cm ppoll , -.Cm offset , -.Cm delay , -.Cm dspersion , -.Cm reftime -variables are described in the RFC-1305 specification, as -are the timestamps -.Cm org , -.Cm rec -and -.Cm xmt . -Additional NTPv4 system variables include -the following. -.Bl -tag -width indent -.It flash -The flash code for the most recent packet received. -The encoding and -meaning of these codes is given later in this page. -.It jitter -The estimated time error of the peer clock measured as an exponential -average of RMS time differences. -.It unreach -The value of the counter which records the number of poll intervals since -the last valid packet was received. -.El -.Pp -When the NTPv4 daemon is compiled with the OpenSSL software library, additional -peer variables are displayed, including the following: -.Bl -tag -width indent -.It flags -The current flag bits. -This word is the server host status word with -additional bits used by the Autokey state machine. -See the source code for -the bit encoding. -.It hostname -The server host name. -.It initkey Ar key -The initial key used by the key list generator in the Autokey protocol. -.It initsequence Ar index -The initial index used by the key list generator in the Autokey protocol. -.It signature -The server message digest/signature scheme name from the OpenSSL software -library. -.It timestamp Ar time -The NTP timestamp when the last Autokey key list was generated and signed. +The following peer variables appear in the +.Ic rv +billboard for each association. +Not all variables are displayed in some configurations. +.Bl -tag -width "something" -compact -offset indent +.It Variable +Description +.It Ic associd +association ID +.It Ic status +.Lk decode.html#peer "peer status word" +.It Ic srcadr +source (remote) IP address +.It Ic srcport +source (remote) port +.It Ic dstadr +destination (local) IP address +.It Ic dstport +destination (local) port +.It Ic leap +leap indicator (0\-3) +.It Ic stratum +stratum (0\-15) +.It Ic precision +precision (log2 s) +.It Ic rootdelay +total roundtrip delay to the primary reference clock +.It Ic rootdisp +total root dispersion to the primary reference clock +.It Ic refid +reference ID or +.Lk decode.html#kiss "kiss code" +.It Ic reftime +reference time +.It Ic reach +reach register (octal) +.It Ic unreach +unreach counter +.It Ic hmode +host mode (1\-6) +.It Ic pmode +peer mode (1\-5) +.It Ic hpoll +host poll exponent (log2 s) (3\-17) +.It Ic ppoll +peer poll exponent (log2 s) (3\-17) +.It Ic headway +headway (see +.Lk rate.html "Rate Management and the Kiss\-o'\-Death Packet" ) +.It Ic flash +.Lk decode.html#flash "flash status word" +.It Ic offset +filter offset +.It Ic delay +filter delay +.It Ic dispersion +filter dispersion +.It Ic jitter +filter jitter +.It Ic ident +Autokey group name for this association +.It Ic bias +unicast/broadcast bias +.It Ic xleave +interleave delay (see +.Lk xleave.html "NTP Interleaved Modes" ) .El -.Ss Flash Codes The -.Cm flash -code is a valuable debugging aid displayed in the peer variables -list. -It shows the results of the original sanity checks defined in the NTP -specification RFC-1305 and additional ones added in NTPv4. -There are 12 tests -designated -.Sy TEST1 -through -.Sy TEST12 . -The tests are performed in a certain order -designed to gain maximum diagnostic information while protecting against -accidental or malicious errors. +.Ic bias +variable is calculated when the first broadcast packet is received +after the calibration volley. +It represents the offset of the broadcast subgraph relative to the unicast subgraph. The -.Sy flash -variable is initialized to zero as -each packet is received. -If after each set of tests one or more bits are set, -the packet is discarded. +.Ic xleave +variable appears only for the interleaved symmetric and interleaved modes. +It represents the internal queuing, buffering and transmission delays +for the preceding packet. .Pp -Tests -.Sy TEST1 -through -.Sy TEST3 -check the packet timestamps from which the offset and -delay are calculated. -If any bits are set, the packet is discarded; otherwise, -the packet header variables are saved. -.Sy TEST4 -and -.Sy TEST5 -are associated with -access control and cryptographic authentication. -If any bits are set, the -packet is discarded immediately with nothing changed. -.Pp -Tests -.Sy TEST6 -through -.Sy TEST8 -check the health of the server. -If any bits are set, -the packet is discarded; otherwise, the offset and delay relative to the server -are calculated and saved. -TEST9 checks the health of the association itself. -If -any bits are set, the packet is discarded; otherwise, the saved variables are -passed to the clock filter and mitigation algorithms. -.Pp -Tests -.Sy TEST10 -through -.Sy TEST12 -check the authentication state using Autokey -public-key cryptography, as described in the -.Sx Authentication Options -section of -.Xr ntp.conf 5 . -If -any bits are set and the association has previously been marked reachable, the -packet is discarded; otherwise, the originate and receive timestamps are saved, -as required by the NTP protocol, and processing continues. -.Pp -The -.Cm flash -bits for each test are defined as follows. -.Bl -tag -width indent -.It 0x001 -.Pq TEST1 -Duplicate packet. -The packet is at best a casual retransmission and at -worst a malicious replay. -.It 0x002 -.Pq TEST2 -Bogus packet. -The packet is not a reply to a message previously sent. -This -can happen when the NTP daemon is restarted and before somebody else -notices. -.It 0x004 -.Pq TEST3 -Unsynchronized. -One or more timestamp fields are invalid. -This normally -happens when the first packet from a peer is received. -.It 0x008 -.Pq TEST4 -Access is denied. -See the -.Sx Access Control Support -section of -.Xr ntp.conf 5 . -.It 0x010 -.Pq TEST5 -Cryptographic authentication fails. -See the -.Sx Authentication Options -section of -.Xr ntp.conf 5 . -.It 0x020 -.Pq TEST6 -The server is unsynchronized. -Wind up its clock first. -.It 0x040 -.Pq TEST7 -The server stratum is at the maximum than 15. -It is probably unsynchronized -and its clock needs to be wound up. -.It 0x080 -.Pq TEST8 -Either the root delay or dispersion is greater than one second, which is -highly unlikely unless the peer is unsynchronized to Mars. -.It 0x100 -.Pq TEST9 -Either the peer delay or dispersion is greater than one second, which is -higly unlikely unless the peer is on Mars. -.It 0x200 -.Pq TEST10 -The autokey protocol has detected an authentication failure. -See the -.Sx Authentication Options -section of -.Xr ntp.conf 5 . -.It 0x400 -.Pq TEST11 -The autokey protocol has not verified the server or peer is proventic and -has valid public key credentials. -See the -.Sx Authentication Options -section of -.Xr ntp.conf 5 . -.It 0x800 -.Pq TEST12 -A protocol or configuration error has occurred in the public key algorithms -or a possible intrusion event has been detected. -See the -.Sx Authentication Options -section of -.Xr ntp.conf 5 . +When the NTPv4 daemon is compiled with the OpenSSL software library, +additional peer variables are displayed, including the following: +.Bl -tag -width "something" -compact -offset indent +.It Variable +Description +.It Ic flags +peer flags (see Autokey specification) +.It Ic host +Autokey server name +.It Ic flags +peer flags (see Autokey specification) +.It Ic signature +OpenSSL digest/signature scheme +.It Ic initsequence +initial key ID +.It Ic initkey +initial key index +.It Ic timestamp +Autokey signature timestamp .El -.Sh SEE ALSO -.Xr ntp.conf 5 , -.Xr ntpd 8 , -.Xr ntpdc 8 -.Sh BUGS -The -.Ic peers -command is non-atomic and may occasionally result in -spurious error messages about invalid associations occurring and -terminating the command. -The timeout time is a fixed constant, -which means you wait a long time for timeouts since it assumes sort -of a worst case. -The program should improve the timeout estimate as -it sends queries to a particular host, but does not. +.Ss Clock Variables +The following clock variables appear in the +.Ic cv +billboard for each association with a reference clock. +Not all variables are displayed in some configurations. +.Bl -tag -width "something" -compact -offset indent +.It Variable +Description +.It Ic associd +association ID +.It Ic status +.Lk decode.html#clock "clock status word" +.It Ic device +device description +.It Ic timecode +ASCII time code string (specific to device) +.It Ic poll +poll messages sent +.It Ic noreply +no reply +.It Ic badformat +bad format +.It Ic baddata +bad date or time +.It Ic fudgetime1 +fudge time 1 +.It Ic fudgetime2 +fudge time 2 +.It Ic stratum +driver stratum +.It Ic refid +driver reference ID +.It Ic flags +driver flags +.El +.Sh "OPTIONS" +.Bl -tag +.It Fl 4 , Fl \-ipv4 +Force IPv4 DNS name resolution. +This option must not appear in combination with any of the following options: +ipv6. +.sp +Force DNS resolution of following host names on the command line +to the IPv4 namespace. +.It Fl 6 , Fl \-ipv6 +Force IPv6 DNS name resolution. +This option must not appear in combination with any of the following options: +ipv4. +.sp +Force DNS resolution of following host names on the command line +to the IPv6 namespace. +.It Fl c Ar cmd , Fl \-command Ns = Ns Ar cmd +run a command and exit. +This option may appear an unlimited number of times. +.sp +The following argument is interpreted as an interactive format command +and is added to the list of commands to be executed on the specified +host(s). +.It Fl d , Fl \-debug\-level +Increase debug verbosity level. +This option may appear an unlimited number of times. +.sp +.It Fl D Ar number , Fl \-set\-debug\-level Ns = Ns Ar number +Set the debug verbosity level. +This option may appear an unlimited number of times. +This option takes an integer number as its argument. +.sp +.It Fl i , Fl \-interactive +Force ntpq to operate in interactive mode. +This option must not appear in combination with any of the following options: +command, peers. +.sp +Force \fBntpq\fP to operate in interactive mode. +Prompts will be written to the standard output and +commands read from the standard input. +.It Fl n , Fl \-numeric +numeric host addresses. +.sp +Output all host addresses in dotted\-quad numeric format rather than +converting to the canonical host names. +.It Fl \-old\-rv +Always output status line with readvar. +.sp +By default, \fBntpq\fP now suppresses the \fBassocid=...\fP +line that precedes the output of \fBreadvar\fP +(alias \fBrv\fP) when a single variable is requested, such as +\fBntpq \-c "rv 0 offset"\fP. +This option causes \fBntpq\fP to include both lines of output +for a single\-variable \fBreadvar\fP. +Using an environment variable to +preset this option in a script will enable both older and +newer \fBntpq\fP to behave identically in this regard. +.It Fl p , Fl \-peers +Print a list of the peers. +This option must not appear in combination with any of the following options: +interactive. +.sp +Print a list of the peers known to the server as well as a summary +of their state. This is equivalent to the 'peers' interactive command. +.It Fl w , Fl \-wide +Display the full 'remote' value. +.sp +Display the full value of the 'remote' value. If this requires +more than 15 characters, display the full value, emit a newline, +and continue the data display properly indented on the next line. +.It Fl \&? , Fl \-help +Display usage information and exit. +.It Fl \&! , Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl > Oo Ar cfgfile Oc , Fl \-save\-opts Oo Ns = Ns Ar cfgfile Oc +Save the option state to \fIcfgfile\fP. The default is the \fIlast\fP +configuration file listed in the \fBOPTION PRESETS\fP section, below. +The command will exit after updating the config file. +.It Fl < Ar cfgfile , Fl \-load\-opts Ns = Ns Ar cfgfile , Fl \-no\-load\-opts +Load options from \fIcfgfile\fP. +The \fIno\-load\-opts\fP form will disable the loading +of earlier config/rc/ini files. \fI\-\-no\-load\-opts\fP is handled early, +out of order. +.It Fl \-version Op Brq Ar v|c|n +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. +.El +.Sh "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from configuration ("RC" or ".INI") file(s) and values from +environment variables named: +.nf + \fBNTPQ_<option\-name>\fP or \fBNTPQ\fP +.fi +.ad +The environmental presets take precedence (are processed later than) +the configuration files. +The \fIhomerc\fP files are "\fI$HOME\fP", and "\fI.\fP". +If any of these are directories, then the file \fI.ntprc\fP +is searched for within those directories. +.Sh "ENVIRONMENT" +See \fBOPTION PRESETS\fP for configuration environment variables. +.Sh "FILES" +See \fBOPTION PRESETS\fP for configuration files. +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 66 " (EX_NOINPUT)" +A specified configuration file could not be loaded. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. +.El +.Sh "AUTHORS" +The University of Delaware and Network Time Foundation +.Sh "COPYRIGHT" +Copyright (C) 1992\-2015 The University of Delaware and Network Time Foundation all rights reserved. +This program is released under the terms of the NTP license, <http://ntp.org/license>. +.Sh "BUGS" +Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org +.Sh "NOTES" +This manual page was \fIAutoGen\fP\-erated from the \fBntpq\fP +option definitions. diff --git a/usr.sbin/ntp/doc/ntptime.8 b/usr.sbin/ntp/doc/ntptime.8 index f130307..bb3b41a 100644 --- a/usr.sbin/ntp/doc/ntptime.8 +++ b/usr.sbin/ntp/doc/ntptime.8 @@ -1,7 +1,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 7, 2000 +.Dd April 27, 2015 .Dt NTPTIME 8 .Os .Sh NAME @@ -52,8 +52,6 @@ Specify estimated error, in microseconds. Specify frequency offset, in parts per million. .It Fl h Display help information. -.It Fl l -Specify the leap bits as a code from 0 to 3. .It Fl m Ar max_error Specify max possible errors, in microseconds. .It Fl o Ar offset diff --git a/usr.sbin/ntp/doc/ntptrace.8 b/usr.sbin/ntp/doc/ntptrace.8 index 554a3c0..40cb719 100644 --- a/usr.sbin/ntp/doc/ntptrace.8 +++ b/usr.sbin/ntp/doc/ntptrace.8 @@ -1,76 +1,93 @@ +.Dd February 4 2015 +.Dt NTPTRACE 8 User Commands +.Os +.\" EDIT THIS FILE WITH CAUTION (ntptrace-opts.mdoc) .\" .\" $FreeBSD$ .\" -.Dd January 6, 2000 -.Dt NTPTRACE 8 -.Os +.\" It has been AutoGen-ed February 4, 2015 at 02:37:48 AM by AutoGen 5.18.5pre4 +.\" From the definitions ntptrace-opts.def +.\" and the template file agmdoc-cmd.tpl .Sh NAME .Nm ntptrace -.Nd "trace a chain of NTP servers back to the primary source" +.Nd Trace peers of an NTP server .Sh SYNOPSIS .Nm -.Op Fl vdn -.Op Fl r Ar retries -.Op Fl t Ar timeout -.Op Ar server -.Sh DESCRIPTION -The -.Nm -utility determines where a given Network Time Protocol (NTP) server gets -its time from, and follows the chain of NTP servers back to their -master time source. -If given no arguments, it starts with -.Dq localhost . +.\" Mixture of short (flag) options and long options +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option\-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +[host] .Pp -Here is an example of the output from -.Nm : -.Bd -literal -% ntptrace -localhost: stratum 4, offset 0.0019529, synch distance 0.144135 -server2ozo.com: stratum 2, offset 0.0124263, synch distance 0.115784 -usndh.edu: stratum 1, offset 0.0019298, synch distance 0.011993, refid 'WWVB' +.Sh DESCRIPTION +\fBntptrace\fP is a perl script that uses the ntpq utility program to follow +the chain of NTP servers from a given host back to the primary time source. For +ntptrace to work properly, each of these servers must implement the NTP Control +and Monitoring Protocol specified in RFC 1305 and enable NTP Mode 6 packets. +.sp +If given no arguments, ntptrace starts with localhost. Here is an example of +the output from ntptrace: +.sp +.Bd -literal -offset indent +% ntptrace localhost: stratum 4, offset 0.0019529, synch distance 0.144135 +server2ozo.com: stratum 2, offset 0.0124263, synch distance 0.115784 usndh.edu: +stratum 1, offset 0.0019298, synch distance 0.011993, refid 'WWVB' .Ed -.Pp -On each line, the fields are (left to right): the host name, the -host stratum, -the time offset between that host and the local host -(as measured by -.Nm ; -this is why it is not always zero for -.Dq localhost ) , -the host -synchronization distance, -and (only for stratum-1 servers) the reference clock ID. -All times -are given in seconds. -Note that the stratum is the server hop count to the primary source, -while the synchronization distance is the estimated error -relative to the primary source. -These terms are precisely defined in RFC 1305. -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl d -Turn on some debugging output. -.It Fl n -Turn off the printing of host names; instead, host IP addresses -are given. -This may be necessary if a nameserver is down. -.It Fl r Ar retries -Set the number of retransmission attempts for each host; the default is 5. -.It Fl t Ar timeout -Set the retransmission timeout (in seconds); the default is 2. -.It Fl v -Print verbose information about the NTP servers. +.sp +On each line, the fields are (left to right): the host name, the host stratum, +the time offset between that host and the local host (as measured by +\fBntptrace\fP; this is why it is not always zero for "localhost"), the host +synchronization distance, and (only for stratum\-1 servers) the reference clock +ID. All times are given in seconds. Note that the stratum is the server hop +count to the primary source, while the synchronization distance is the +estimated error relative to the primary source. These terms are precisely +defined in RFC\-1305. +.Sh "OPTIONS" +.Bl -tag +.It Fl n , Fl \-numeric +Print IP addresses instead of hostnames. +.sp +Output hosts as dotted\-quad numeric format rather than converting to +the canonical host names. +.It Fl m Ar number , Fl \-max\-hosts Ns = Ns Ar number +Maximum number of peers to trace. +This option takes an integer number as its argument. +The default +.Ar number +for this option is: +.ti +4 + 99 +.sp +This option has not been fully documented. +.It Fl r Ar string , Fl \-host Ns = Ns Ar string +Single remote host. +The default +.Ar string +for this option is: +.ti +4 + 127.0.0.1 +.sp +This option has not been fully documented. +.It Fl \&? , Fl \-help +Display usage information and exit. +.It Fl \&! , Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl v Op Brq Ar v|c|n Fl \-version Op Brq Ar v|c|n +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. +.El +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. .El -.Sh SEE ALSO -.Xr ntpd 8 , -.Xr ntpdc 8 -.Rs -.%A D L Mills -.%T Network Time Protocol (Version 3) -.%O RFC1305 -.Re -.Sh BUGS -This program makes no attempt to improve accuracy by doing multiple -samples. +.Sh "NOTES" +This manual page was \fIAutoGen\fP\-erated from the \fBntptrace\fP +option definitions. diff --git a/usr.sbin/ntp/doc/pic/Makefile b/usr.sbin/ntp/doc/pic/Makefile new file mode 100644 index 0000000..11bcab6 --- /dev/null +++ b/usr.sbin/ntp/doc/pic/Makefile @@ -0,0 +1,27 @@ +# $FreeBSD$ + +.include <src.opts.mk> + +FILESDIR= ${SHAREDIR}/doc/ntp/pic + +.if ${MK_HTML} != "no" +FILES= 9400n.jpg alice11.gif alice13.gif alice15.gif alice23.gif \ + alice31.gif alice32.gif alice35.gif alice38.gif alice44.gif \ + alice47.gif alice51.gif alice61.gif barnstable.gif beaver.gif \ + boom3.gif boom3a.gif boom4.gif broad.gif bustardfly.gif c51.jpg \ + description.jpg discipline.gif dogsnake.gif driver29.gif \ + driver43_1.gif driver43_2.jpg fg6021.gif fg6039.jpg fig_3_1.gif \ + flatheads.gif flt1.gif flt2.gif flt3.gif flt4.gif flt5.gif flt6.gif \ + flt7.gif flt8.gif flt9.gif freq1211.gif gadget.jpg gps167.jpg \ + group.gif hornraba.gif igclock.gif neoclock4x.gif offset1211.gif \ + oncore_evalbig.gif oncore_remoteant.jpg oncore_utplusbig.gif oz2.gif \ + panda.gif pd_om006.gif pd_om011.gif peer.gif pogo.gif pogo1a.gif \ + pogo3a.gif pogo4.gif pogo5.gif pogo6.gif pogo7.gif pogo8.gif \ + pzf509.jpg pzf511.jpg rabbit.gif radio2.jpg sheepb.jpg stack1a.jpg \ + stats.gif sx5.gif thunderbolt.jpg time1.gif tonea.gif tribeb.gif \ + wingdorothy.gif +.endif + +.PATH: ${.CURDIR}/../../../../contrib/ntp/html/pic + +.include <bsd.prog.mk> diff --git a/usr.sbin/ntp/doc/scripts/Makefile b/usr.sbin/ntp/doc/scripts/Makefile new file mode 100644 index 0000000..13adda7 --- /dev/null +++ b/usr.sbin/ntp/doc/scripts/Makefile @@ -0,0 +1,15 @@ +# $FreeBSD$ + +.include <src.opts.mk> + +FILESDIR= ${SHAREDIR}/doc/ntp/scripts + +.if ${MK_HTML} != "no" +FILES= accopt.txt audio.txt authopt.txt clockopt.txt command.txt config.txt \ + confopt.txt external.txt footer.txt hand.txt install.txt manual.txt \ + misc.txt miscopt.txt monopt.txt refclock.txt special.txt style.css +.endif + +.PATH: ${.CURDIR}/../../../../contrib/ntp/html/scripts + +.include <bsd.prog.mk> diff --git a/usr.sbin/ntp/doc/sntp.8 b/usr.sbin/ntp/doc/sntp.8 new file mode 100644 index 0000000..4d09cb0 --- /dev/null +++ b/usr.sbin/ntp/doc/sntp.8 @@ -0,0 +1,313 @@ +.Dd February 4 2015 +.Dt SNTP 8 User Commands +.Os +.\" EDIT THIS FILE WITH CAUTION (sntp-opts.mdoc) +.\" +.\" $FreeBSD$ +.\" +.\" It has been AutoGen-ed February 4, 2015 at 02:34:20 AM by AutoGen 5.18.5pre4 +.\" From the definitions sntp-opts.def +.\" and the template file agmdoc-cmd.tpl +.Sh NAME +.Nm sntp +.Nd standard Simple Network Time Protocol client program +.Sh SYNOPSIS +.Nm +.\" Mixture of short (flag) options and long options +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option\-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +[ hostname\-or\-IP ...] +.Pp +.Sh DESCRIPTION +.Nm +can be used as an SNTP client to query a NTP or SNTP server and either display +the time or set the local system's time (given suitable privilege). It can be +run as an interactive command or from a +.Ic cron +job. +NTP (the Network Time Protocol) and SNTP (the Simple Network Time Protocol) +are defined and described by RFC 5905. +.Pp +The default is to write the estimated correct local date and time (i.e. not +UTC) to the standard output in a format like: +.Ic "'1996\-10\-15 20:17:25.123 (+0800) +4.567 +/\- 0.089 [host] IP sN'" +where the +.Ic "'(+0800)'" +means that to get to UTC from the reported local time one must +add 8 hours and 0 minutes, +the +.Ic "'+4.567'" +indicates the local clock is 4.567 seconds behind the correct time +(so 4.567 seconds must be added to the local clock to get it to be correct). +Note that the number of decimals printed for this value will change +based on the reported precision of the server. +.Ic "'+/\- 0.089'" +is the reported +.Em synchronization distance +(in seconds), which represents the maximum error due to all causes. +If the server does not report valid data needed to calculate the +synchronization distance, this will be reported as +.Ic "'+/\- ?'" . +If the +.Em host +is different from the +.Em IP , +both will be displayed. +Otherwise, only the +.Em IP +is displayed. +Finally, the +.Em stratum +of the host is reported. +.Sh "OPTIONS" +.Bl -tag +.It Fl 4 , Fl \-ipv4 +Force IPv4 DNS name resolution. +This option must not appear in combination with any of the following options: +ipv6. +.sp +Force DNS resolution of the following host names on the command line +to the IPv4 namespace. +.It Fl 6 , Fl \-ipv6 +Force IPv6 DNS name resolution. +This option must not appear in combination with any of the following options: +ipv4. +.sp +Force DNS resolution of the following host names on the command line +to the IPv6 namespace. +.It Fl a Ar auth\-keynumber , Fl \-authentication Ns = Ns Ar auth\-keynumber +Enable authentication with the key \fBauth\-keynumber\fP. +This option takes an integer number as its argument. +.sp +Enable authentication using the key specified in this option's +argument. The argument of this option is the \fBkeyid\fP, a +number specified in the \fBkeyfile\fP as this key's identifier. +See the \fBkeyfile\fP option (\fB\-k\fP) for more details. +.It Fl b Ar broadcast\-address , Fl \-broadcast Ns = Ns Ar broadcast\-address +Listen to the address specified for broadcast time sync. +This option may appear an unlimited number of times. +.sp +If specified \fBsntp\fP will listen to the specified address +for NTP broadcasts. The default maximum wait time +can (and probably should) be modified with \fB\-t\fP. +.It Fl c Ar host\-name , Fl \-concurrent Ns = Ns Ar host\-name +Concurrently query all IPs returned for host\-name. +This option may appear an unlimited number of times. +.sp +Requests from an NTP "client" to a "server" should never be sent +more rapidly than one every 2 seconds. By default, any IPs returned +as part of a DNS lookup are assumed to be for a single instance of +\fBntpd\fP, and therefore \fBsntp\fP will send queries to these IPs +one after another, with a 2\-second gap in between each query. +.sp +The \fB\-c\fP or \fB\-\-concurrent\fP flag says that any IPs +returned for the DNS lookup of the supplied host\-name are on +different machines, so we can send concurrent queries. +.It Fl d , Fl \-debug\-level +Increase debug verbosity level. +This option may appear an unlimited number of times. +.sp +.It Fl D Ar number , Fl \-set\-debug\-level Ns = Ns Ar number +Set the debug verbosity level. +This option may appear an unlimited number of times. +This option takes an integer number as its argument. +.sp +.It Fl g Ar milliseconds , Fl \-gap Ns = Ns Ar milliseconds +The gap (in milliseconds) between time requests. +This option takes an integer number as its argument. +The default +.Ar milliseconds +for this option is: +.ti +4 + 50 +.sp +Since we're only going to use the first valid response we get and +there is benefit to specifying a good number of servers to query, +separate the queries we send out by the specified number of +milliseconds. +.It Fl K Ar file\-name , Fl \-kod Ns = Ns Ar file\-name +KoD history filename. +The default +.Ar file\-name +for this option is: +.ti +4 + /var/db/ntp\-kod +.sp +Specifies the filename to be used for the persistent history of KoD +responses received from servers. If the file does not exist, a +warning message will be displayed. The file will not be created. +.It Fl k Ar file\-name , Fl \-keyfile Ns = Ns Ar file\-name +Look in this file for the key specified with \fB\-a\fP. +.sp +This option specifies the keyfile. +\fBsntp\fP will search for the key specified with \fB\-a\fP +\fIkeyno\fP in this file. See \fBntp.keys(5)\fP for more +information. +.It Fl l Ar file\-name , Fl \-logfile Ns = Ns Ar file\-name +Log to specified logfile. +.sp +This option causes the client to write log messages to the specified +\fIlogfile\fP. +.It Fl M Ar number , Fl \-steplimit Ns = Ns Ar number +Adjustments less than \fBsteplimit\fP msec will be slewed. +This option takes an integer number as its argument. +The value of +.Ar number +is constrained to being: +.in +4 +.nf +.na +greater than or equal to 0 +.fi +.in -4 +.sp +If the time adjustment is less than \fIsteplimit\fP milliseconds, +slew the amount using \fBadjtime(2)\fP. Otherwise, step the +correction using \fBsettimeofday(2)\fP. The default value is 0, +which means all adjustments will be stepped. This is a feature, as +different situations demand different values. +.It Fl o Ar number , Fl \-ntpversion Ns = Ns Ar number +Send \fBint\fP as our NTP protocol version. +This option takes an integer number as its argument. +The value of +.Ar number +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 7 +.fi +.in -4 +The default +.Ar number +for this option is: +.ti +4 + 4 +.sp +When sending requests to a remote server, tell them we are running +NTP protocol version \fIntpversion\fP . +.It Fl r , Fl \-usereservedport +Use the NTP Reserved Port (port 123). +.sp +Use port 123, which is reserved for NTP, for our network +communications. +.It Fl S , Fl \-step +OK to 'step' the time with \fBsettimeofday(2)\fP. +.sp +.It Fl s , Fl \-slew +OK to 'slew' the time with \fBadjtime(2)\fP. +.sp +.It Fl t Ar seconds , Fl \-timeout Ns = Ns Ar seconds +The number of seconds to wait for responses. +This option takes an integer number as its argument. +The default +.Ar seconds +for this option is: +.ti +4 + 5 +.sp +When waiting for a reply, \fBsntp\fP will wait the number +of seconds specified before giving up. The default should be +more than enough for a unicast response. If \fBsntp\fP is +only waiting for a broadcast response a longer timeout is +likely needed. +.It Fl \-wait , " Fl \-no\-wait" +Wait for pending replies (if not setting the time). +The \fIno\-wait\fP form will disable the option. +This option is enabled by default. +.sp +If we are not setting the time, wait for all pending responses. +.It Fl \&? , Fl \-help +Display usage information and exit. +.It Fl \&! , Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl > Oo Ar cfgfile Oc , Fl \-save\-opts Oo Ns = Ns Ar cfgfile Oc +Save the option state to \fIcfgfile\fP. The default is the \fIlast\fP +configuration file listed in the \fBOPTION PRESETS\fP section, below. +The command will exit after updating the config file. +.It Fl < Ar cfgfile , Fl \-load\-opts Ns = Ns Ar cfgfile , Fl \-no\-load\-opts +Load options from \fIcfgfile\fP. +The \fIno\-load\-opts\fP form will disable the loading +of earlier config/rc/ini files. \fI\-\-no\-load\-opts\fP is handled early, +out of order. +.It Fl \-version Op Brq Ar v|c|n +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. +.El +.Sh "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from configuration ("RC" or ".INI") file(s) and values from +environment variables named: +.nf + \fBSNTP_<option\-name>\fP or \fBSNTP\fP +.fi +.ad +The environmental presets take precedence (are processed later than) +the configuration files. +The \fIhomerc\fP files are "\fI$HOME\fP", and "\fI.\fP". +If any of these are directories, then the file \fI.ntprc\fP +is searched for within those directories. +.Sh USAGE +.Bl -tag -width indent +.It Li "sntp ntpserver.somewhere" +is the simplest use of this program +and can be run as an unprivileged command +to check the current time and error in the local clock. +.It Li "sntp \-Ss \-M 128 ntpserver.somewhere" +With suitable privilege, +run as a command +or from a +.Xr cron 8 +job, +.Ic "sntp \-Ss \-M 128 ntpserver.somewhere" +will request the time from the server, +and if that server reports that it is synchronized +then if the offset adjustment is less than 128 milliseconds +the correction will be slewed, +and if the correction is more than 128 milliseconds +the correction will be stepped. +.It Li "sntp \-S ntpserver.somewhere" +With suitable privilege, +run as a command +or from a +.Xr cron 8 +job, +.Ic "sntp \-S ntpserver.somewhere" +will set (step) the local clock from a synchronized specified server, +like the (deprecated) +.Xr ntpdate 8 , +or +.Xr rdate 8 +commands. +.El +.Sh "ENVIRONMENT" +See \fBOPTION PRESETS\fP for configuration environment variables. +.Sh "FILES" +See \fBOPTION PRESETS\fP for configuration files. +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 66 " (EX_NOINPUT)" +A specified configuration file could not be loaded. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. +.El +.Sh AUTHORS +.An "Johannes Maximilian Kuehn" +.An "Harlan Stenn" +.An "Dave Hart" +.Sh "COPYRIGHT" +Copyright (C) 1992\-2015 The University of Delaware and Network Time Foundation all rights reserved. +This program is released under the terms of the NTP license, <http://ntp.org/license>. +.Sh "BUGS" +Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org +.Sh "NOTES" +This manual page was \fIAutoGen\fP\-erated from the \fBsntp\fP +option definitions. diff --git a/usr.sbin/ntp/libntp/Makefile b/usr.sbin/ntp/libntp/Makefile index 83e654e..f83322f 100644 --- a/usr.sbin/ntp/libntp/Makefile +++ b/usr.sbin/ntp/libntp/Makefile @@ -1,37 +1,88 @@ # $FreeBSD$ .PATH: ${.CURDIR}/../../../contrib/ntp/libntp \ - ${.CURDIR}/../../../contrib/ntp/libisc + ${.CURDIR}/../../../contrib/ntp/lib/isc \ + ${.CURDIR}/../../../contrib/ntp/lib/isc/nls \ + ${.CURDIR}/../../../contrib/ntp/lib/isc/pthreads \ + ${.CURDIR}/../../../contrib/ntp/lib/isc/unix \ LIB= ntp INTERNALLIB= -NTP_SRCS= a_md5encrypt.c adjtime.c atoint.c atolfp.c \ - atouint.c audio.c authkeys.c \ - authreadkeys.c authusekey.c \ - buftvtots.c caljulian.c caltontp.c \ - calyearstart.c clocktime.c clocktypes.c decodenetnum.c \ - dofptoa.c dolfptoa.c emalloc.c findconfig.c \ - fptoa.c fptoms.c getopt.c \ - hextoint.c hextolfp.c humandate.c icom.c \ - inttoa.c iosignal.c lib_strbuf.c \ - machines.c md5c.c memmove.c \ - mfptoa.c mfptoms.c mktime.c modetoa.c \ - mstolfp.c ntp_random.c \ - msutotsf.c msyslog.c netof.c ntp_rfc2553.c \ +NTP_SRCS= systime.c a_md5encrypt.c adjtime.c atoint.c \ + atolfp.c atouint.c audio.c authkeys.c \ + authreadkeys.c authusekey.c bsd_strerror.c buftvtots.c \ + caljulian.c caltontp.c calyearstart.c clocktime.c \ + clocktypes.c decodenetnum.c dofptoa.c dolfptoa.c \ + emalloc.c findconfig.c getopt.c hextoint.c \ + hextolfp.c humandate.c icom.c iosignal.c \ + lib_strbuf.c machines.c mktime.c modetoa.c \ + mstolfp.c msyslog.c netof.c ntp_calendar.c \ + ntp_crypto_rnd.c ntp_intres.c ntp_libopts.c \ + ntp_lineedit.c ntp_random.c ntp_rfc2553.c ntp_worker.c \ numtoa.c numtohost.c octtoint.c prettydate.c \ - recvbuff.c refnumtoa.c snprintf.c socktoa.c \ - socktohost.c strstr.c systime.c statestr.c \ - strerror.c syssignal.c tsftomsu.c tstotv.c \ - tvtoa.c tvtots.c uglydate.c uinttoa.c \ - utvtoa.c ymd2yd.c + recvbuff.c refnumtoa.c snprintf.c socket.c \ + socktoa.c socktohost.c ssl_init.c statestr.c \ + strdup.c strl_obsd.c syssignal.c timetoa.c \ + timevalops.c uglydate.c vint64ops.c work_fork.c \ + work_thread.c ymd2yd.c -ISC_SRCS= assertions.c error.c inet_ntop.c inet_pton.c interfaceiter.c \ - isc_strerror.c lib.c mem.c msgcat.c net.c netscope.c netaddr.c \ - sockaddr.c +ISC_PTHREADS_SRCS= condition.c \ + thread.c \ + mutex.c -SRCS= ${NTP_SRCS} ${ISC_SRCS} +ISC_UNIX_SRCS= dir.c \ + errno2result.c \ + file.c \ + interfaceiter.c \ + net.c \ + stdio.c \ + stdtime.c \ + strerror.c \ + time.c -CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include -I${.CURDIR}/../ +ISC_NLS_SRCS= msgcat.c + +ISC_SRCS= assertions.c \ + buffer.c \ + backtrace-emptytbl.c \ + backtrace.c \ + error.c \ + event.c \ + inet_ntop.c \ + inet_pton.c \ + lib.c \ + log.c \ + md5.c \ + netaddr.c \ + netscope.c \ + ondestroy.c \ + random.c \ + result.c \ + task.c \ + sha1.c \ + sockaddr.c \ + ${ISC_NLS_SRCS} \ + ${ISC_PTHREADS_SRCS} \ + ${ISC_UNIX_SRCS} + +SRCS= ${NTP_SRCS} ${ISC_SRCS} version.c + +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/unix/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/pthreads/include \ + -I${.CURDIR}/../../../contrib/ntp/sntp/libopts \ + -I${.CURDIR}/../../../lib/libc/${MACHINE_ARCH} \ + -I${.CURDIR}/../../../lib/libedit/edit \ + -I${.CURDIR}/../ \ + -I${.CURDIR}/ + +CFLAGS+= -DHAVE_BSD_NICE -DHAVE_STDINT_H + +CLEANFILES+= .version version.c + +version.c: + sh -e ${.CURDIR}/../scripts/mkver ntpd .include <bsd.lib.mk> diff --git a/usr.sbin/ntp/libntp/Makefile.depend b/usr.sbin/ntp/libntp/Makefile.depend index edf9194..927153e 100644 --- a/usr.sbin/ntp/libntp/Makefile.depend +++ b/usr.sbin/ntp/libntp/Makefile.depend @@ -3,10 +3,11 @@ DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} DIRDEPS = \ + bin/cat.host \ include \ include/arpa \ include/xlocale \ - lib/libmd \ + lib/libedit/edit/readline \ lib/msun \ secure/lib/libcrypto \ @@ -15,4 +16,6 @@ DIRDEPS = \ .if ${DEP_RELDIR} == ${_DEP_RELDIR} # local dependencies - needed for -jN in clean tree +version.o: version.c +version.po: version.c .endif diff --git a/usr.sbin/ntp/libntpevent/Makefile b/usr.sbin/ntp/libntpevent/Makefile new file mode 100644 index 0000000..b912ed8 --- /dev/null +++ b/usr.sbin/ntp/libntpevent/Makefile @@ -0,0 +1,34 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../contrib/ntp/sntp/libevent + +LIB= ntpevent +INTERNALLIB= + +SRCS= buffer.c bufferevent.c bufferevent_filter.c bufferevent_openssl.c \ + bufferevent_pair.c epoll.c evdns.c event.c event_tagging.c \ + evmap.c evport.c evrpc.c evthread.c evthread_pthread.c evutil.c \ + evutil_rand.c evutil_time.c http.c kqueue.c listener.c log.c poll.c \ + select.c signal.c strlcpy.c + +.if ${MACHINE_ARCH} == "i386" +NTP_ATOMIC=x86_32 +.elif ${MACHINE_ARCH} == "amd64" +NTP_ATOMIC=x86_64 +.elif ${MACHINE_ARCH} == "ia64" +NTP_ATOMIC=ia64 +.elif ${MACHINE_ARCH} == "powerpc64" +NTP_ATOMIC=powerpc +.elif ${MACHINE_ARCH} == "sparc64" +NTP_ATOMIC=sparc64 +.else +NTP_ATOMIC=noatomic +.endif + +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/sntp/libevent/include \ + -I${.CURDIR}/ + +CFLAGS+= -DHAVE_BSD_NICE -DHAVE_STDINT_H + +.include <bsd.lib.mk> diff --git a/usr.sbin/ntp/libntpevent/Makefile.depend b/usr.sbin/ntp/libntpevent/Makefile.depend new file mode 100644 index 0000000..e848c2c --- /dev/null +++ b/usr.sbin/ntp/libntpevent/Makefile.depend @@ -0,0 +1,17 @@ +# Autogenerated - do NOT edit! + +DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} + +DIRDEPS = \ + include \ + include/arpa \ + include/xlocale \ + secure/lib/libcrypto \ + secure/lib/libssl \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.sbin/ntp/libntpevent/event2/event-config.h b/usr.sbin/ntp/libntpevent/event2/event-config.h new file mode 100644 index 0000000..920b7ba --- /dev/null +++ b/usr.sbin/ntp/libntpevent/event2/event-config.h @@ -0,0 +1,648 @@ +/* event2/event-config.h +* $FreeBSD$ +* +* This file was generated by autoconf when libevent was built, and post- +* processed by Libevent so that its macros would have a uniform prefix. +* +* DO NOT EDIT THIS FILE. +* +* Do not rely on macros in this file existing in later versions. +*/ + +#ifndef EVENT2_EVENT_CONFIG_H_INCLUDED_ +#define EVENT2_EVENT_CONFIG_H_INCLUDED_ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if libevent should build without support for a debug mode */ +/* #undef EVENT__DISABLE_DEBUG_MODE */ + +/* Define if libevent should not allow replacing the mm functions */ +/* #undef EVENT__DISABLE_MM_REPLACEMENT */ + +/* Define if libevent should not be compiled with thread support */ +/* #undef EVENT__DISABLE_THREAD_SUPPORT */ + +/* Define to 1 if you have the `accept4' function. */ +#define EVENT__HAVE_ACCEPT4 1 + +/* Define to 1 if you have the `arc4random' function. */ +#define EVENT__HAVE_ARC4RANDOM 1 + +/* Define to 1 if you have the `arc4random_buf' function. */ +#define EVENT__HAVE_ARC4RANDOM_BUF 1 + +/* Define to 1 if you have the <arpa/inet.h> header file. */ +#define EVENT__HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the `clock_gettime' function. */ +#define EVENT__HAVE_CLOCK_GETTIME 1 + +/* Define to 1 if you have the <cthreads.h> header file. */ +/* #undef EVENT__HAVE_CTHREADS_H */ + +/* Define to 1 if you have the declaration of `CTL_KERN', and to 0 if you + don't. */ +#define EVENT__HAVE_DECL_CTL_KERN 1 + +/* Define to 1 if you have the declaration of `KERN_ARND', and to 0 if you + don't. */ +#define EVENT__HAVE_DECL_KERN_ARND 1 + +/* Define to 1 if you have the declaration of `KERN_RANDOM', and to 0 if you + don't. */ +#define EVENT__HAVE_DECL_KERN_RANDOM 0 + +/* Define to 1 if you have the declaration of `RANDOM_UUID', and to 0 if you + don't. */ +#define EVENT__HAVE_DECL_RANDOM_UUID 0 + +/* Define if /dev/poll is available */ +/* #undef EVENT__HAVE_DEVPOLL */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define EVENT__HAVE_DLFCN_H 1 + +/* Define if your system supports the epoll system calls */ +/* #undef EVENT__HAVE_EPOLL */ + +/* Define to 1 if you have the `epoll_create1' function. */ +/* #undef EVENT__HAVE_EPOLL_CREATE1 */ + +/* Define to 1 if you have the `epoll_ctl' function. */ +/* #undef EVENT__HAVE_EPOLL_CTL */ + +/* Define to 1 if you have the `eventfd' function. */ +/* #undef EVENT__HAVE_EVENTFD */ + +/* Define if your system supports event ports */ +/* #undef EVENT__HAVE_EVENT_PORTS */ + +/* Define to 1 if you have the `fcntl' function. */ +#define EVENT__HAVE_FCNTL 1 + +/* Define to 1 if you have the <fcntl.h> header file. */ +#define EVENT__HAVE_FCNTL_H 1 + +/* Define to 1 if the system has the type `fd_mask'. */ +#define EVENT__HAVE_FD_MASK 1 + +/* Do we have getaddrinfo()? */ +#define EVENT__HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `getegid' function. */ +#define EVENT__HAVE_GETEGID 1 + +/* Define to 1 if you have the `geteuid' function. */ +#define EVENT__HAVE_GETEUID 1 + +/* Define this if you have any gethostbyname_r() */ +/* #undef EVENT__HAVE_GETHOSTBYNAME_R */ + +/* Define this if gethostbyname_r takes 3 arguments */ +/* #undef EVENT__HAVE_GETHOSTBYNAME_R_3_ARG */ + +/* Define this if gethostbyname_r takes 5 arguments */ +/* #undef EVENT__HAVE_GETHOSTBYNAME_R_5_ARG */ + +/* Define this if gethostbyname_r takes 6 arguments */ +/* #undef EVENT__HAVE_GETHOSTBYNAME_R_6_ARG */ + +/* Define to 1 if you have the `getifaddrs' function. */ +#define EVENT__HAVE_GETIFADDRS 1 + +/* Define to 1 if you have the `getnameinfo' function. */ +#define EVENT__HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the `getprotobynumber' function. */ +#define EVENT__HAVE_GETPROTOBYNUMBER 1 + +/* Define to 1 if you have the `getservbyname' function. */ +/* #undef EVENT__HAVE_GETSERVBYNAME */ + +/* Define to 1 if you have the `gettimeofday' function. */ +#define EVENT__HAVE_GETTIMEOFDAY 1 + +/* if you have GNU Pth */ +/* #undef EVENT__HAVE_GNU_PTH */ + +/* Define to 1 if you have the <ifaddrs.h> header file. */ +#define EVENT__HAVE_IFADDRS_H 1 + +/* Define to 1 if you have the `inet_ntop' function. */ +#define EVENT__HAVE_INET_NTOP 1 + +/* Define to 1 if you have the `inet_pton' function. */ +#define EVENT__HAVE_INET_PTON 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define EVENT__HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `issetugid' function. */ +#define EVENT__HAVE_ISSETUGID 1 + +/* Define to 1 if you have the `kqueue' function. */ +#define EVENT__HAVE_KQUEUE 1 + +/* Define if the system has zlib */ +#define EVENT__HAVE_LIBZ 1 + +/* if you have LinuxThreads */ +/* #undef EVENT__HAVE_LINUX_THREADS */ + +/* if you have SunOS LWP package */ +/* #undef EVENT__HAVE_LWP */ + +/* Define to 1 if you have the <lwp/lwp.h> header file. */ +/* #undef EVENT__HAVE_LWP_LWP_H */ + +/* Define to 1 if you have the `mach_absolute_time' function. */ +/* #undef EVENT__HAVE_MACH_ABSOLUTE_TIME */ + +/* define if you have Mach Cthreads */ +/* #undef EVENT__HAVE_MACH_CTHREADS */ + +/* Define to 1 if you have the <mach/cthreads.h> header file. */ +/* #undef EVENT__HAVE_MACH_CTHREADS_H */ + +/* Define to 1 if you have the <mach/mach_time.h> header file. */ +/* #undef EVENT__HAVE_MACH_MACH_TIME_H */ + +/* Define to 1 if you have the <memory.h> header file. */ +#define EVENT__HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mmap' function. */ +#define EVENT__HAVE_MMAP 1 + +/* Define to 1 if you have the `nanosleep' function. */ +#define EVENT__HAVE_NANOSLEEP 1 + +/* Define to 1 if you have the <netdb.h> header file. */ +#define EVENT__HAVE_NETDB_H 1 + +/* Define to 1 if you have the <netinet/in6.h> header file. */ +/* #undef EVENT__HAVE_NETINET_IN6_H */ + +/* Define to 1 if you have the <netinet/in.h> header file. */ +#define EVENT__HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the <netinet/tcp.h> header file. */ +#define EVENT__HAVE_NETINET_TCP_H 1 + +/* if you have NT Event Log */ +/* #undef EVENT__HAVE_NT_EVENT_LOG */ + +/* if you have NT Service Manager */ +/* #undef EVENT__HAVE_NT_SERVICE_MANAGER */ + +/* if you have NT Threads */ +/* #undef EVENT__HAVE_NT_THREADS */ + +/* Define if the system has openssl */ +/* #undef EVENT__HAVE_OPENSSL */ + +/* Define to 1 if you have the `pipe' function. */ +#define EVENT__HAVE_PIPE 1 + +/* Define to 1 if you have the `pipe2' function. */ +#define EVENT__HAVE_PIPE2 1 + +/* Define to 1 if you have the `poll' function. */ +#define EVENT__HAVE_POLL 1 + +/* Define to 1 if you have the <poll.h> header file. */ +#define EVENT__HAVE_POLL_H 1 + +/* Define to 1 if you have the `port_create' function. */ +/* #undef EVENT__HAVE_PORT_CREATE */ + +/* Define to 1 if you have the <port.h> header file. */ +/* #undef EVENT__HAVE_PORT_H */ + +/* Define if you have POSIX threads libraries and header files. */ +/* #undef EVENT__HAVE_PTHREAD */ + +/* define to pthreads API spec revision */ +#define EVENT__HAVE_PTHREADS 10 + +/* define if you have pthread_detach function */ +#define EVENT__HAVE_PTHREAD_DETACH 1 + +/* Define to 1 if you have the `pthread_getconcurrency' function. */ +#define EVENT__HAVE_PTHREAD_GETCONCURRENCY 1 + +/* Define to 1 if you have the <pthread.h> header file. */ +#define EVENT__HAVE_PTHREAD_H 1 + +/* Define to 1 if you have the `pthread_kill' function. */ +#define EVENT__HAVE_PTHREAD_KILL 1 + +/* Define to 1 if you have the `pthread_kill_other_threads_np' function. */ +/* #undef EVENT__HAVE_PTHREAD_KILL_OTHER_THREADS_NP */ + +/* define if you have pthread_rwlock_destroy function */ +#define EVENT__HAVE_PTHREAD_RWLOCK_DESTROY 1 + +/* Define to 1 if you have the `pthread_setconcurrency' function. */ +#define EVENT__HAVE_PTHREAD_SETCONCURRENCY 1 + +/* Define to 1 if you have the `pthread_yield' function. */ +#define EVENT__HAVE_PTHREAD_YIELD 1 + +/* Define to 1 if you have the <pth.h> header file. */ +/* #undef EVENT__HAVE_PTH_H */ + +/* Define to 1 if you have the `putenv' function. */ +#define EVENT__HAVE_PUTENV 1 + +/* Define to 1 if the system has the type `sa_family_t'. */ +#define EVENT__HAVE_SA_FAMILY_T 1 + +/* Define to 1 if you have the <sched.h> header file. */ +#define EVENT__HAVE_SCHED_H 1 + +/* Define to 1 if you have the `sched_yield' function. */ +#define EVENT__HAVE_SCHED_YIELD 1 + +/* Define to 1 if you have the `select' function. */ +#define EVENT__HAVE_SELECT 1 + +/* Define to 1 if you have the `sendfile' function. */ +#define EVENT__HAVE_SENDFILE 1 + +/* Define to 1 if you have the `setenv' function. */ +#define EVENT__HAVE_SETENV 1 + +/* Define if F_SETFD is defined in <fcntl.h> */ +#define EVENT__HAVE_SETFD 1 + +/* Define to 1 if you have the `setrlimit' function. */ +#define EVENT__HAVE_SETRLIMIT 1 + +/* Define to 1 if you have the `sigaction' function. */ +#define EVENT__HAVE_SIGACTION 1 + +/* Define to 1 if you have the `signal' function. */ +#define EVENT__HAVE_SIGNAL 1 + +/* Define to 1 if you have the `splice' function. */ +/* #undef EVENT__HAVE_SPLICE */ + +/* Define to 1 if you have the <stdarg.h> header file. */ +#define EVENT__HAVE_STDARG_H 1 + +/* Define to 1 if you have the <stddef.h> header file. */ +#define EVENT__HAVE_STDDEF_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define EVENT__HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define EVENT__HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define EVENT__HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define EVENT__HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcpy' function. */ +#define EVENT__HAVE_STRLCPY 1 + +/* Define to 1 if you have the `strsep' function. */ +#define EVENT__HAVE_STRSEP 1 + +/* Define to 1 if you have the `strtok_r' function. */ +#define EVENT__HAVE_STRTOK_R 1 + +/* Define to 1 if you have the `strtoll' function. */ +#define EVENT__HAVE_STRTOLL 1 + +/* Define to 1 if the system has the type `struct addrinfo'. */ +#define EVENT__HAVE_STRUCT_ADDRINFO 1 + +/* Define to 1 if the system has the type `struct in6_addr'. */ +#define EVENT__HAVE_STRUCT_IN6_ADDR 1 + +/* Define to 1 if `s6_addr16' is a member of `struct in6_addr'. */ +/* #undef EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16 */ + +/* Define to 1 if `s6_addr32' is a member of `struct in6_addr'. */ +/* #undef EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 */ + +/* Define to 1 if the system has the type `struct sockaddr_in6'. */ +#define EVENT__HAVE_STRUCT_SOCKADDR_IN6 1 + +/* Define to 1 if `sin6_len' is a member of `struct sockaddr_in6'. */ +#define EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 1 + +/* Define to 1 if `sin_len' is a member of `struct sockaddr_in'. */ +#define EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 1 + +/* Define to 1 if the system has the type `struct sockaddr_storage'. */ +#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */ +#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1 + +/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */ +/* #undef EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */ + +/* Define to 1 if the system has the type `struct so_linger'. */ +/* #undef EVENT__HAVE_STRUCT_SO_LINGER */ + +/* Define to 1 if you have the <synch.h> header file. */ +/* #undef EVENT__HAVE_SYNCH_H */ + +/* Define to 1 if you have the `sysctl' function. */ +#define EVENT__HAVE_SYSCTL 1 + +/* Define to 1 if you have the <sys/devpoll.h> header file. */ +/* #undef EVENT__HAVE_SYS_DEVPOLL_H */ + +/* Define to 1 if you have the <sys/epoll.h> header file. */ +/* #undef EVENT__HAVE_SYS_EPOLL_H */ + +/* Define to 1 if you have the <sys/eventfd.h> header file. */ +/* #undef EVENT__HAVE_SYS_EVENTFD_H */ + +/* Define to 1 if you have the <sys/event.h> header file. */ +#define EVENT__HAVE_SYS_EVENT_H 1 + +/* Define to 1 if you have the <sys/ioctl.h> header file. */ +#define EVENT__HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the <sys/mman.h> header file. */ +#define EVENT__HAVE_SYS_MMAN_H 1 + +/* Define to 1 if you have the <sys/param.h> header file. */ +#define EVENT__HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the <sys/queue.h> header file. */ +#define EVENT__HAVE_SYS_QUEUE_H 1 + +/* Define to 1 if you have the <sys/resource.h> header file. */ +#define EVENT__HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the <sys/select.h> header file. */ +#define EVENT__HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the <sys/sendfile.h> header file. */ +/* #undef EVENT__HAVE_SYS_SENDFILE_H */ + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#define EVENT__HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define EVENT__HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/sysctl.h> header file. */ +#define EVENT__HAVE_SYS_SYSCTL_H 1 + +/* Define to 1 if you have the <sys/timerfd.h> header file. */ +/* #undef EVENT__HAVE_SYS_TIMERFD_H */ + +/* Define to 1 if you have the <sys/time.h> header file. */ +#define EVENT__HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define EVENT__HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <sys/uio.h> header file. */ +#define EVENT__HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the <sys/wait.h> header file. */ +#define EVENT__HAVE_SYS_WAIT_H 1 + +/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */ +#define EVENT__HAVE_TAILQFOREACH 1 + +/* if you have Solaris LWP (thr) package */ +/* #undef EVENT__HAVE_THR */ + +/* Define to 1 if you have the <thread.h> header file. */ +/* #undef EVENT__HAVE_THREAD_H */ + +/* Define to 1 if you have the `thr_getconcurrency' function. */ +/* #undef EVENT__HAVE_THR_GETCONCURRENCY */ + +/* Define to 1 if you have the `thr_setconcurrency' function. */ +/* #undef EVENT__HAVE_THR_SETCONCURRENCY */ + +/* Define to 1 if you have the `thr_yield' function. */ +/* #undef EVENT__HAVE_THR_YIELD */ + +/* Define if timeradd is defined in <sys/time.h> */ +#define EVENT__HAVE_TIMERADD 1 + +/* Define if timerclear is defined in <sys/time.h> */ +#define EVENT__HAVE_TIMERCLEAR 1 + +/* Define if timercmp is defined in <sys/time.h> */ +#define EVENT__HAVE_TIMERCMP 1 + +/* Define to 1 if you have the `timerfd_create' function. */ +/* #undef EVENT__HAVE_TIMERFD_CREATE */ + +/* Define if timerisset is defined in <sys/time.h> */ +#define EVENT__HAVE_TIMERISSET 1 + +/* Define to 1 if the system has the type `uint16_t'. */ +#define EVENT__HAVE_UINT16_T 1 + +/* Define to 1 if the system has the type `uint32_t'. */ +#define EVENT__HAVE_UINT32_T 1 + +/* Define to 1 if the system has the type `uint64_t'. */ +#define EVENT__HAVE_UINT64_T 1 + +/* Define to 1 if the system has the type `uint8_t'. */ +#define EVENT__HAVE_UINT8_T 1 + +/* Define to 1 if the system has the type `uintptr_t'. */ +#define EVENT__HAVE_UINTPTR_T 1 + +/* Define to 1 if you have the `umask' function. */ +#define EVENT__HAVE_UMASK 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define EVENT__HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `unsetenv' function. */ +#define EVENT__HAVE_UNSETENV 1 + +/* Define to 1 if you have the `usleep' function. */ +#define EVENT__HAVE_USLEEP 1 + +/* Define to 1 if you have the `vasprintf' function. */ +#define EVENT__HAVE_VASPRINTF 1 + +/* Define if kqueue works correctly with pipes */ +#define EVENT__HAVE_WORKING_KQUEUE 1 + +/* define if select implicitly yields */ +#define EVENT__HAVE_YIELDING_SELECT 1 + +/* Define to 1 if you have the <zlib.h> header file. */ +#define EVENT__HAVE_ZLIB_H 1 + +/* define to 1 if library is thread safe */ +#define EVENT__LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define EVENT__LT_OBJDIR ".libs/" + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef EVENT__NO_MINUS_C_MINUS_O */ + +/* define if you have (or want) no threads */ +/* #undef EVENT__NO_THREADS */ + +/* Numeric representation of the version */ +#define EVENT__NUMERIC_VERSION 0x02010301 + +/* Name of package */ +#define EVENT__PACKAGE "libevent" + +/* Define to the address where bug reports for this package should be sent. */ +#define EVENT__PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define EVENT__PACKAGE_NAME "libevent" + +/* Define to the full name and version of this package. */ +#define EVENT__PACKAGE_STRING "libevent 2.1.3-alpha-dev" + +/* Define to the one symbol short name of this package. */ +#define EVENT__PACKAGE_TARNAME "libevent" + +/* Define to the home page for this package. */ +#define EVENT__PACKAGE_URL "" + +/* Define to the version of this package. */ +#define EVENT__PACKAGE_VERSION "2.1.3-alpha-dev" + +/* enable thread safety */ +#define EVENT__REENTRANT 1 + +/* define if sched_yield yields the entire process */ +/* #undef EVENT__REPLACE_BROKEN_YIELD */ + +/* The size of `int', as computed by sizeof. */ +#define EVENT__SIZEOF_INT 4 + +/* The size of `long', as computed by sizeof. */ +#define EVENT__SIZEOF_LONG 8 + +/* The size of `long long', as computed by sizeof. */ +#define EVENT__SIZEOF_LONG_LONG 8 + +/* The size of `off_t', as computed by sizeof. */ +#define EVENT__SIZEOF_OFF_T 8 + +/* The size of `pthread_t', as computed by sizeof. */ +#define EVENT__SIZEOF_PTHREAD_T 8 + +/* The size of `short', as computed by sizeof. */ +#define EVENT__SIZEOF_SHORT 2 + +/* The size of `size_t', as computed by sizeof. */ +#define EVENT__SIZEOF_SIZE_T 8 + +/* The size of `void *', as computed by sizeof. */ +#define EVENT__SIZEOF_VOID_P 8 + +/* Define to 1 if you have the ANSI C header files. */ +#define EVENT__STDC_HEADERS 1 + +/* enable thread safety */ +#define EVENT__THREADSAFE 1 + +/* enable thread safety */ +#define EVENT__THREAD_SAFE 1 + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#define EVENT__TIME_WITH_SYS_TIME 1 + +/* Version number of package */ +#define EVENT__VERSION "2.1.3-alpha-dev" + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef EVENT___FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef EVENT___LARGE_FILES */ + +/* Define to 1 if on MINIX. */ +/* #undef EVENT___MINIX */ + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +/* #undef EVENT___POSIX_1_SOURCE */ + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +/* #undef EVENT___POSIX_SOURCE */ + +/* enable thread safety */ +#define EVENT___REENTRANT 1 + +/* enable thread safety */ +#define EVENT___SGI_MP_SOURCE 1 + +/* enable thread safety */ +#define EVENT___THREADSAFE 1 + +/* enable thread safety */ +#define EVENT___THREAD_SAFE 1 + +/* Define to 500 only on HP-UX. */ +/* #undef EVENT___XOPEN_SOURCE */ + +/* Enable extensions on AIX 3, Interix. */ +#ifndef EVENT___ALL_SOURCE +# define EVENT___ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef EVENT___GNU_SOURCE +# define EVENT___GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef EVENT___POSIX_PTHREAD_SEMANTICS +# define EVENT___POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef EVENT___TANDEM_SOURCE +# define EVENT___TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef EVENT____EXTENSIONS__ +# define EVENT____EXTENSIONS__ 1 +#endif + + +/* Define to appropriate substitue if compiler doesnt have __func__ */ +/* #undef EVENT____func__ */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef EVENT__const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef EVENT____cplusplus +/* #undef EVENT__inline */ +#endif + +/* Define to `int' if <sys/types.h> does not define. */ +/* #undef EVENT__pid_t */ + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +/* #undef EVENT__size_t */ + +/* Define to unsigned int if you dont have it */ +/* #undef EVENT__socklen_t */ + +/* Define to `int' if <sys/types.h> does not define. */ +/* #undef EVENT__ssize_t */ + +#endif /* event2/event-config.h */ diff --git a/usr.sbin/ntp/libopts/Makefile b/usr.sbin/ntp/libopts/Makefile index c867ecc..3c7eef7 100644 --- a/usr.sbin/ntp/libopts/Makefile +++ b/usr.sbin/ntp/libopts/Makefile @@ -1,13 +1,14 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../../contrib/ntp/libopts +.PATH: ${.CURDIR}/../../../contrib/ntp/sntp/libopts -LIB= opts +LIB= opts INTERNALLIB= SRCS= libopts.c -CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include -I${.CURDIR}/../ \ - -I${.CURDIR}/../../../contrib/ntp/libopts +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/sntp/libopts \ + -I${.CURDIR}/../ .include <bsd.lib.mk> diff --git a/usr.sbin/ntp/libparse/Makefile b/usr.sbin/ntp/libparse/Makefile index 9ccc4b3..e99e471 100644 --- a/usr.sbin/ntp/libparse/Makefile +++ b/usr.sbin/ntp/libparse/Makefile @@ -2,15 +2,18 @@ .PATH: ${.CURDIR}/../../../contrib/ntp/libparse -LIB= parse +LIB= parse INTERNALLIB= -SRCS= clk_computime.c clk_dcf7000.c clk_hopf6021.c clk_meinberg.c \ - clk_rawdcf.c clk_rcc8000.c clk_schmid.c clk_trimtaip.c \ - clk_trimtsip.c clk_varitext.c clk_wharton.c data_mbg.c \ - info_trimble.c parse.c parse_conf.c trim_info.c \ - binio.c gpstolfp.c ieee754io.c mfp_mul.c +SRCS= binio.c clk_computime.c clk_dcf7000.c clk_hopf6021.c \ + clk_meinberg.c clk_rawdcf.c clk_rcc8000.c clk_schmid.c \ + clk_sel240x.c clk_trimtaip.c clk_trimtsip.c clk_varitext.c \ + clk_wharton.c data_mbg.c gpstolfp.c ieee754io.c \ + info_trimble.c mfp_mul.c parse.c parse_conf.c \ + trim_info.c -CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include -I${.CURDIR}/../ +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/unix/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/include -I${.CURDIR}/../ .include <bsd.lib.mk> diff --git a/usr.sbin/ntp/libparse/Makefile.depend b/usr.sbin/ntp/libparse/Makefile.depend index 83ac20f..ffaa905 100644 --- a/usr.sbin/ntp/libparse/Makefile.depend +++ b/usr.sbin/ntp/libparse/Makefile.depend @@ -4,6 +4,7 @@ DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} DIRDEPS = \ include \ + include/arpa \ include/xlocale \ lib/msun \ secure/lib/libcrypto \ diff --git a/usr.sbin/ntp/ntp-keygen/Makefile b/usr.sbin/ntp/ntp-keygen/Makefile index 78308fa..3c29f9b 100644 --- a/usr.sbin/ntp/ntp-keygen/Makefile +++ b/usr.sbin/ntp/ntp-keygen/Makefile @@ -4,21 +4,26 @@ MAN= .include <src.opts.mk> -.PATH: ${.CURDIR}/../../../contrib/ntp/util \ - ${.CURDIR}/../../../contrib/ntp/ntpd +.PATH: ${.CURDIR}/../../../contrib/ntp/util \ + ${.CURDIR}/../../../contrib/ntp/ntpd PROG= ntp-keygen SRCS= ntp-keygen.c ntp-keygen-opts.c -CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include -I${.CURDIR}/../ \ - -I${.CURDIR}/../../../contrib/ntp/libopts +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/unix/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/pthreads/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/${NTP_ATOMIC}/include \ + -I${.CURDIR}/../../../contrib/ntp/sntp/libopts \ + -I${.CURDIR}/../../../lib/libc/${MACHINE_ARCH} \ + -I${.CURDIR}/../ -DPADD= ${LIBNTP} ${LIBOPTS} -LDADD= ${LIBNTP} ${LIBOPTS} +LIBADD+= ntp opts pthread .if ${MK_OPENSSL} != "no" -DPADD+= ${LIBMD} ${LIBCRYPTO} -LDADD+= -lmd -lcrypto +LIBADD+= md crypto .endif .include <bsd.prog.mk> diff --git a/usr.sbin/ntp/ntp-keygen/Makefile.depend b/usr.sbin/ntp/ntp-keygen/Makefile.depend index 0a7e705..61817cc 100644 --- a/usr.sbin/ntp/ntp-keygen/Makefile.depend +++ b/usr.sbin/ntp/ntp-keygen/Makefile.depend @@ -6,11 +6,14 @@ DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ include \ + include/arpa \ include/xlocale \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ lib/libmd \ + lib/libthr \ + lib/msun \ secure/lib/libcrypto \ usr.sbin/ntp/libntp \ usr.sbin/ntp/libopts \ diff --git a/usr.sbin/ntp/ntpd/Makefile b/usr.sbin/ntp/ntpd/Makefile index 87b2d72..8da2c68 100644 --- a/usr.sbin/ntp/ntpd/Makefile +++ b/usr.sbin/ntp/ntpd/Makefile @@ -4,40 +4,41 @@ MAN= .include <src.opts.mk> -.PATH: ${.CURDIR}/../../../contrib/ntp/ntpd +.PATH: ${.CURDIR}/../../../contrib/ntp/ntpd \ + ${.OBJDIR} PROG= ntpd -SRCS= cmd_args.c ntp_config.c \ - ntp_control.c ntp_crypto.c ntp_filegen.c \ - ntp_intres.c ntp_io.c ntp_loopfilter.c \ - ntp_monitor.c ntp_peer.c ntp_proto.c \ - ntp_refclock.c ntp_request.c \ - ntp_restrict.c ntp_timer.c ntp_util.c \ - ntpd.c refclock_acts.c refclock_arbiter.c \ - refclock_arc.c refclock_as2201.c refclock_atom.c \ - refclock_bancomm.c refclock_chronolog.c refclock_chu.c \ - refclock_conf.c refclock_datum.c refclock_dumbclock.c \ - refclock_fg.c refclock_gpsvme.c refclock_heath.c \ - refclock_hopfpci.c refclock_hopfser.c refclock_hpgps.c \ - refclock_irig.c refclock_jupiter.c refclock_leitch.c \ - refclock_local.c refclock_msfees.c refclock_mx4200.c \ - refclock_neoclock4x.c refclock_nmea.c refclock_oncore.c \ - refclock_palisade.c refclock_parse.c refclock_pcf.c \ - refclock_pst.c refclock_ripencc.c \ - refclock_shm.c refclock_tpro.c refclock_trak.c refclock_true.c \ - refclock_ulink.c refclock_wwv.c \ - refclock_wwvb.c ntpd-opts.c \ - version.c - -CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include -I${.CURDIR}/../ \ - -I${.CURDIR}/../../../contrib/ntp/libopts -I${.CURDIR} - -DPADD= ${LIBPARSE} ${LIBNTP} ${LIBM} ${LIBMD} ${LIBRT} ${LIBOPTS} -LDADD= ${LIBPARSE} ${LIBNTP} -lm -lmd -lrt ${LIBOPTS} + +SRCS= cmd_args.c ntp_config.c ntp_control.c ntp_crypto.c ntp_filegen.c \ + ntp_io.c ntp_leapsec.c ntp_loopfilter.c ntp_monitor.c ntp_parser.c \ + ntp_peer.c ntp_proto.c ntp_refclock.c ntp_request.c ntp_restrict.c \ + ntp_scanner.c ntp_signd.c ntp_timer.c ntp_util.c ntpd-opts.c ntpd.c \ + refclock_acts.c refclock_arbiter.c refclock_arc.c refclock_as2201.c \ + refclock_atom.c refclock_bancomm.c refclock_chronolog.c \ + refclock_chu.c refclock_conf.c refclock_datum.c refclock_dumbclock.c \ + refclock_fg.c refclock_gpsdjson.c refclock_gpsvme.c refclock_heath.c \ + refclock_hopfpci.c refclock_hopfser.c refclock_hpgps.c \ + refclock_irig.c refclock_jjy.c refclock_jupiter.c refclock_leitch.c \ + refclock_local.c refclock_nmea.c refclock_neoclock4x.c \ + refclock_oncore.c refclock_palisade.c \ + refclock_parse.c refclock_pcf.c refclock_pst.c refclock_ripencc.c \ + refclock_shm.c refclock_tpro.c refclock_true.c refclock_tsyncpci.c \ + refclock_tt560.c refclock_ulink.c refclock_wwv.c refclock_wwvb.c \ + refclock_zyfer.c version.c + +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/ntpd \ + -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/pthreads/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/unix/include \ + -I${.CURDIR}/../../../contrib/ntp/sntp/libopts \ + -I${.CURDIR}/../ \ + -I${.CURDIR} + +LIBADD= parse ntp m rt opts md pthread .if ${MK_OPENSSL} != "no" -DPADD+= ${LIBCRYPTO} -LDADD+= -lcrypto +LIBADD+= crypto .endif CLEANFILES+= .version version.c diff --git a/usr.sbin/ntp/ntpdate/Makefile b/usr.sbin/ntp/ntpdate/Makefile index f55ec92..8fdd8f7 100644 --- a/usr.sbin/ntp/ntpdate/Makefile +++ b/usr.sbin/ntp/ntpdate/Makefile @@ -1,15 +1,24 @@ # $FreeBSD$ +.include <src.opts.mk> + .PATH: ${.CURDIR}/../../../contrib/ntp/ntpdate PROG= ntpdate MAN= SRCS= ntpdate.c version.c -CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include -I${.CURDIR}/../ +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/include/ \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/unix/include/ \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/pthreads/include \ + -I${.CURDIR}/../ + +LIBADD= rt ntp m pthread -DPADD= ${LIBNTP} ${LIBM} ${LIBMD} ${LIBRT} -LDADD= ${LIBNTP} -lm -lmd -lrt +.if ${MK_OPENSSL} != "no" +LIBADD+= md ssl crypto +.endif CLEANFILES+= .version version.c diff --git a/usr.sbin/ntp/ntpdate/Makefile.depend b/usr.sbin/ntp/ntpdate/Makefile.depend index 0701136..3f251af 100644 --- a/usr.sbin/ntp/ntpdate/Makefile.depend +++ b/usr.sbin/ntp/ntpdate/Makefile.depend @@ -17,6 +17,7 @@ DIRDEPS = \ lib/libthr \ lib/msun \ secure/lib/libcrypto \ + secure/lib/libssl \ usr.sbin/ntp/libntp \ diff --git a/usr.sbin/ntp/ntpdc/Makefile b/usr.sbin/ntp/ntpdc/Makefile index d3c37e1..2129c20 100644 --- a/usr.sbin/ntp/ntpdc/Makefile +++ b/usr.sbin/ntp/ntpdc/Makefile @@ -2,6 +2,7 @@ MAN= +.include <src.opts.mk> .include <bsd.own.mk> .PATH: ${.CURDIR}/../../../contrib/ntp/ntpdc @@ -9,17 +10,22 @@ MAN= PROG= ntpdc SRCS= ntpdc.c ntpdc_ops.c ntpdc-opts.c version.c -CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include -I${.CURDIR}/../ \ - -I${.CURDIR}/../../../contrib/ntp/libopts +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/unix/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/pthreads/include \ + -I${.CURDIR}/../../../contrib/ntp/sntp/libopts \ + -I${.CURDIR}/../../../lib/libc/${MACHINE_ARCH} \ + -I${.CURDIR}/../ -I${.CURDIR} -DPADD= ${LIBNTP} ${LIBM} ${LIBMD} ${LIBOPTS} -LDADD= ${LIBNTP} -lm -lmd ${LIBOPTS} - -DPADD+= ${LIBEDIT} ${LIBTERMCAPW} -LDADD+= -ledit -ltermcapw +LIBADD= edit md ntp m readline opts ncurses pthread CFLAGS+= -DHAVE_LIBEDIT -DHAVE_READLINE_READLINE_H \ -I${DESTDIR}/${INCLUDEDIR}/edit +.if ${MK_OPENSSL} != "no" +LIBADD+= ssl crypto +.endif + CLEANFILES+= .version version.c version.c: diff --git a/usr.sbin/ntp/ntpdc/Makefile.depend b/usr.sbin/ntp/ntpdc/Makefile.depend index d3c16eb..09b85e6 100644 --- a/usr.sbin/ntp/ntpdc/Makefile.depend +++ b/usr.sbin/ntp/ntpdc/Makefile.depend @@ -6,6 +6,7 @@ DIRDEPS = \ bin/cat.host \ gnu/lib/csu \ gnu/lib/libgcc \ + gnu/lib/libreadline/readline \ include \ include/arpa \ include/xlocale \ @@ -13,11 +14,13 @@ DIRDEPS = \ lib/libc \ lib/libcompiler_rt \ lib/libedit \ - lib/libedit/edit/readline \ lib/libmd \ + lib/libthr \ lib/msun \ + lib/ncurses/ncurses \ lib/ncurses/ncursesw \ secure/lib/libcrypto \ + secure/lib/libssl \ usr.sbin/ntp/libntp \ usr.sbin/ntp/libopts \ diff --git a/usr.sbin/ntp/ntpdc/nl.c b/usr.sbin/ntp/ntpdc/nl.c new file mode 100644 index 0000000..045d000 --- /dev/null +++ b/usr.sbin/ntp/ntpdc/nl.c @@ -0,0 +1,895 @@ +/* $FreeBSD$ */ + printf("sizeof(union req_data_u_tag) = %d\n", + (int) sizeof(union req_data_u_tag)); + printf("offsetof(u32) = %d\n", + (int) offsetof(union req_data_u_tag, u32)); + printf("offsetof(data) = %d\n", + (int) offsetof(union req_data_u_tag, data)); + printf("\n"); + + printf("sizeof(struct req_pkt) = %d\n", + (int) sizeof(struct req_pkt)); + printf("offsetof(rm_vn_mode) = %d\n", + (int) offsetof(struct req_pkt, rm_vn_mode)); + printf("offsetof(auth_seq) = %d\n", + (int) offsetof(struct req_pkt, auth_seq)); + printf("offsetof(implementation) = %d\n", + (int) offsetof(struct req_pkt, implementation)); + printf("offsetof(request) = %d\n", + (int) offsetof(struct req_pkt, request)); + printf("offsetof(err_nitems) = %d\n", + (int) offsetof(struct req_pkt, err_nitems)); + printf("offsetof(mbz_itemsize) = %d\n", + (int) offsetof(struct req_pkt, mbz_itemsize)); + printf("offsetof(u) = %d\n", + (int) offsetof(struct req_pkt, u)); + printf("offsetof(tstamp) = %d\n", + (int) offsetof(struct req_pkt, tstamp)); + printf("offsetof(keyid) = %d\n", + (int) offsetof(struct req_pkt, keyid)); + printf("offsetof(mac) = %d\n", + (int) offsetof(struct req_pkt, mac)); + printf("\n"); + + printf("sizeof(struct req_pkt_tail) = %d\n", + (int) sizeof(struct req_pkt_tail)); + printf("offsetof(tstamp) = %d\n", + (int) offsetof(struct req_pkt_tail, tstamp)); + printf("offsetof(keyid) = %d\n", + (int) offsetof(struct req_pkt_tail, keyid)); + printf("offsetof(mac) = %d\n", + (int) offsetof(struct req_pkt_tail, mac)); + printf("\n"); + + printf("sizeof(union resp_pkt_u_tag) = %d\n", + (int) sizeof(union resp_pkt_u_tag)); + printf("offsetof(data) = %d\n", + (int) offsetof(union resp_pkt_u_tag, data)); + printf("offsetof(u32) = %d\n", + (int) offsetof(union resp_pkt_u_tag, u32)); + printf("\n"); + + printf("sizeof(struct resp_pkt) = %d\n", + (int) sizeof(struct resp_pkt)); + printf("offsetof(rm_vn_mode) = %d\n", + (int) offsetof(struct resp_pkt, rm_vn_mode)); + printf("offsetof(auth_seq) = %d\n", + (int) offsetof(struct resp_pkt, auth_seq)); + printf("offsetof(implementation) = %d\n", + (int) offsetof(struct resp_pkt, implementation)); + printf("offsetof(request) = %d\n", + (int) offsetof(struct resp_pkt, request)); + printf("offsetof(err_nitems) = %d\n", + (int) offsetof(struct resp_pkt, err_nitems)); + printf("offsetof(mbz_itemsize) = %d\n", + (int) offsetof(struct resp_pkt, mbz_itemsize)); + printf("offsetof(u) = %d\n", + (int) offsetof(struct resp_pkt, u)); + printf("\n"); + + printf("sizeof(struct info_peer_list) = %d\n", + (int) sizeof(struct info_peer_list)); + printf("offsetof(addr) = %d\n", + (int) offsetof(struct info_peer_list, addr)); + printf("offsetof(port) = %d\n", + (int) offsetof(struct info_peer_list, port)); + printf("offsetof(hmode) = %d\n", + (int) offsetof(struct info_peer_list, hmode)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct info_peer_list, flags)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct info_peer_list, v6_flag)); + printf("offsetof(unused1) = %d\n", + (int) offsetof(struct info_peer_list, unused1)); + printf("offsetof(addr6) = %d\n", + (int) offsetof(struct info_peer_list, addr6)); + printf("\n"); + + printf("sizeof(struct info_peer_summary) = %d\n", + (int) sizeof(struct info_peer_summary)); + printf("offsetof(dstadr) = %d\n", + (int) offsetof(struct info_peer_summary, dstadr)); + printf("offsetof(srcadr) = %d\n", + (int) offsetof(struct info_peer_summary, srcadr)); + printf("offsetof(srcport) = %d\n", + (int) offsetof(struct info_peer_summary, srcport)); + printf("offsetof(stratum) = %d\n", + (int) offsetof(struct info_peer_summary, stratum)); + printf("offsetof(hpoll) = %d\n", + (int) offsetof(struct info_peer_summary, hpoll)); + printf("offsetof(ppoll) = %d\n", + (int) offsetof(struct info_peer_summary, ppoll)); + printf("offsetof(reach) = %d\n", + (int) offsetof(struct info_peer_summary, reach)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct info_peer_summary, flags)); + printf("offsetof(hmode) = %d\n", + (int) offsetof(struct info_peer_summary, hmode)); + printf("offsetof(delay) = %d\n", + (int) offsetof(struct info_peer_summary, delay)); + printf("offsetof(offset) = %d\n", + (int) offsetof(struct info_peer_summary, offset)); + printf("offsetof(dispersion) = %d\n", + (int) offsetof(struct info_peer_summary, dispersion)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct info_peer_summary, v6_flag)); + printf("offsetof(unused1) = %d\n", + (int) offsetof(struct info_peer_summary, unused1)); + printf("offsetof(dstadr6) = %d\n", + (int) offsetof(struct info_peer_summary, dstadr6)); + printf("offsetof(srcadr6) = %d\n", + (int) offsetof(struct info_peer_summary, srcadr6)); + printf("\n"); + + printf("sizeof(struct info_peer) = %d\n", + (int) sizeof(struct info_peer)); + printf("offsetof(dstadr) = %d\n", + (int) offsetof(struct info_peer, dstadr)); + printf("offsetof(srcadr) = %d\n", + (int) offsetof(struct info_peer, srcadr)); + printf("offsetof(srcport) = %d\n", + (int) offsetof(struct info_peer, srcport)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct info_peer, flags)); + printf("offsetof(leap) = %d\n", + (int) offsetof(struct info_peer, leap)); + printf("offsetof(hmode) = %d\n", + (int) offsetof(struct info_peer, hmode)); + printf("offsetof(pmode) = %d\n", + (int) offsetof(struct info_peer, pmode)); + printf("offsetof(stratum) = %d\n", + (int) offsetof(struct info_peer, stratum)); + printf("offsetof(ppoll) = %d\n", + (int) offsetof(struct info_peer, ppoll)); + printf("offsetof(hpoll) = %d\n", + (int) offsetof(struct info_peer, hpoll)); + printf("offsetof(precision) = %d\n", + (int) offsetof(struct info_peer, precision)); + printf("offsetof(version) = %d\n", + (int) offsetof(struct info_peer, version)); + printf("offsetof(unused8) = %d\n", + (int) offsetof(struct info_peer, unused8)); + printf("offsetof(reach) = %d\n", + (int) offsetof(struct info_peer, reach)); + printf("offsetof(unreach) = %d\n", + (int) offsetof(struct info_peer, unreach)); + printf("offsetof(flash) = %d\n", + (int) offsetof(struct info_peer, flash)); + printf("offsetof(ttl) = %d\n", + (int) offsetof(struct info_peer, ttl)); + printf("offsetof(flash2) = %d\n", + (int) offsetof(struct info_peer, flash2)); + printf("offsetof(associd) = %d\n", + (int) offsetof(struct info_peer, associd)); + printf("offsetof(keyid) = %d\n", + (int) offsetof(struct info_peer, keyid)); + printf("offsetof(pkeyid) = %d\n", + (int) offsetof(struct info_peer, pkeyid)); + printf("offsetof(refid) = %d\n", + (int) offsetof(struct info_peer, refid)); + printf("offsetof(timer) = %d\n", + (int) offsetof(struct info_peer, timer)); + printf("offsetof(rootdelay) = %d\n", + (int) offsetof(struct info_peer, rootdelay)); + printf("offsetof(rootdispersion) = %d\n", + (int) offsetof(struct info_peer, rootdispersion)); + printf("offsetof(reftime) = %d\n", + (int) offsetof(struct info_peer, reftime)); + printf("offsetof(org) = %d\n", + (int) offsetof(struct info_peer, org)); + printf("offsetof(rec) = %d\n", + (int) offsetof(struct info_peer, rec)); + printf("offsetof(xmt) = %d\n", + (int) offsetof(struct info_peer, xmt)); + printf("offsetof(filtdelay) = %d\n", + (int) offsetof(struct info_peer, filtdelay)); + printf("offsetof(filtoffset) = %d\n", + (int) offsetof(struct info_peer, filtoffset)); + printf("offsetof(order) = %d\n", + (int) offsetof(struct info_peer, order)); + printf("offsetof(delay) = %d\n", + (int) offsetof(struct info_peer, delay)); + printf("offsetof(dispersion) = %d\n", + (int) offsetof(struct info_peer, dispersion)); + printf("offsetof(offset) = %d\n", + (int) offsetof(struct info_peer, offset)); + printf("offsetof(selectdisp) = %d\n", + (int) offsetof(struct info_peer, selectdisp)); + printf("offsetof(unused1) = %d\n", + (int) offsetof(struct info_peer, unused1)); + printf("offsetof(unused2) = %d\n", + (int) offsetof(struct info_peer, unused2)); + printf("offsetof(unused3) = %d\n", + (int) offsetof(struct info_peer, unused3)); + printf("offsetof(unused4) = %d\n", + (int) offsetof(struct info_peer, unused4)); + printf("offsetof(unused5) = %d\n", + (int) offsetof(struct info_peer, unused5)); + printf("offsetof(unused6) = %d\n", + (int) offsetof(struct info_peer, unused6)); + printf("offsetof(unused7) = %d\n", + (int) offsetof(struct info_peer, unused7)); + printf("offsetof(estbdelay) = %d\n", + (int) offsetof(struct info_peer, estbdelay)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct info_peer, v6_flag)); + printf("offsetof(unused9) = %d\n", + (int) offsetof(struct info_peer, unused9)); + printf("offsetof(dstadr6) = %d\n", + (int) offsetof(struct info_peer, dstadr6)); + printf("offsetof(srcadr6) = %d\n", + (int) offsetof(struct info_peer, srcadr6)); + printf("\n"); + + printf("sizeof(struct info_peer_stats) = %d\n", + (int) sizeof(struct info_peer_stats)); + printf("offsetof(dstadr) = %d\n", + (int) offsetof(struct info_peer_stats, dstadr)); + printf("offsetof(srcadr) = %d\n", + (int) offsetof(struct info_peer_stats, srcadr)); + printf("offsetof(srcport) = %d\n", + (int) offsetof(struct info_peer_stats, srcport)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct info_peer_stats, flags)); + printf("offsetof(timereset) = %d\n", + (int) offsetof(struct info_peer_stats, timereset)); + printf("offsetof(timereceived) = %d\n", + (int) offsetof(struct info_peer_stats, timereceived)); + printf("offsetof(timetosend) = %d\n", + (int) offsetof(struct info_peer_stats, timetosend)); + printf("offsetof(timereachable) = %d\n", + (int) offsetof(struct info_peer_stats, timereachable)); + printf("offsetof(sent) = %d\n", + (int) offsetof(struct info_peer_stats, sent)); + printf("offsetof(unused1) = %d\n", + (int) offsetof(struct info_peer_stats, unused1)); + printf("offsetof(processed) = %d\n", + (int) offsetof(struct info_peer_stats, processed)); + printf("offsetof(unused2) = %d\n", + (int) offsetof(struct info_peer_stats, unused2)); + printf("offsetof(badauth) = %d\n", + (int) offsetof(struct info_peer_stats, badauth)); + printf("offsetof(bogusorg) = %d\n", + (int) offsetof(struct info_peer_stats, bogusorg)); + printf("offsetof(oldpkt) = %d\n", + (int) offsetof(struct info_peer_stats, oldpkt)); + printf("offsetof(unused3) = %d\n", + (int) offsetof(struct info_peer_stats, unused3)); + printf("offsetof(unused4) = %d\n", + (int) offsetof(struct info_peer_stats, unused4)); + printf("offsetof(seldisp) = %d\n", + (int) offsetof(struct info_peer_stats, seldisp)); + printf("offsetof(selbroken) = %d\n", + (int) offsetof(struct info_peer_stats, selbroken)); + printf("offsetof(unused5) = %d\n", + (int) offsetof(struct info_peer_stats, unused5)); + printf("offsetof(candidate) = %d\n", + (int) offsetof(struct info_peer_stats, candidate)); + printf("offsetof(unused6) = %d\n", + (int) offsetof(struct info_peer_stats, unused6)); + printf("offsetof(unused7) = %d\n", + (int) offsetof(struct info_peer_stats, unused7)); + printf("offsetof(unused8) = %d\n", + (int) offsetof(struct info_peer_stats, unused8)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct info_peer_stats, v6_flag)); + printf("offsetof(unused9) = %d\n", + (int) offsetof(struct info_peer_stats, unused9)); + printf("offsetof(dstadr6) = %d\n", + (int) offsetof(struct info_peer_stats, dstadr6)); + printf("offsetof(srcadr6) = %d\n", + (int) offsetof(struct info_peer_stats, srcadr6)); + printf("\n"); + + printf("sizeof(struct info_loop) = %d\n", + (int) sizeof(struct info_loop)); + printf("offsetof(last_offset) = %d\n", + (int) offsetof(struct info_loop, last_offset)); + printf("offsetof(drift_comp) = %d\n", + (int) offsetof(struct info_loop, drift_comp)); + printf("offsetof(compliance) = %d\n", + (int) offsetof(struct info_loop, compliance)); + printf("offsetof(watchdog_timer) = %d\n", + (int) offsetof(struct info_loop, watchdog_timer)); + printf("\n"); + + printf("sizeof(struct info_sys) = %d\n", + (int) sizeof(struct info_sys)); + printf("offsetof(peer) = %d\n", + (int) offsetof(struct info_sys, peer)); + printf("offsetof(peer_mode) = %d\n", + (int) offsetof(struct info_sys, peer_mode)); + printf("offsetof(leap) = %d\n", + (int) offsetof(struct info_sys, leap)); + printf("offsetof(stratum) = %d\n", + (int) offsetof(struct info_sys, stratum)); + printf("offsetof(precision) = %d\n", + (int) offsetof(struct info_sys, precision)); + printf("offsetof(rootdelay) = %d\n", + (int) offsetof(struct info_sys, rootdelay)); + printf("offsetof(rootdispersion) = %d\n", + (int) offsetof(struct info_sys, rootdispersion)); + printf("offsetof(refid) = %d\n", + (int) offsetof(struct info_sys, refid)); + printf("offsetof(reftime) = %d\n", + (int) offsetof(struct info_sys, reftime)); + printf("offsetof(poll) = %d\n", + (int) offsetof(struct info_sys, poll)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct info_sys, flags)); + printf("offsetof(unused1) = %d\n", + (int) offsetof(struct info_sys, unused1)); + printf("offsetof(unused2) = %d\n", + (int) offsetof(struct info_sys, unused2)); + printf("offsetof(unused3) = %d\n", + (int) offsetof(struct info_sys, unused3)); + printf("offsetof(bdelay) = %d\n", + (int) offsetof(struct info_sys, bdelay)); + printf("offsetof(frequency) = %d\n", + (int) offsetof(struct info_sys, frequency)); + printf("offsetof(authdelay) = %d\n", + (int) offsetof(struct info_sys, authdelay)); + printf("offsetof(stability) = %d\n", + (int) offsetof(struct info_sys, stability)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct info_sys, v6_flag)); + printf("offsetof(unused4) = %d\n", + (int) offsetof(struct info_sys, unused4)); + printf("offsetof(peer6) = %d\n", + (int) offsetof(struct info_sys, peer6)); + printf("\n"); + + printf("sizeof(struct info_sys_stats) = %d\n", + (int) sizeof(struct info_sys_stats)); + printf("offsetof(timeup) = %d\n", + (int) offsetof(struct info_sys_stats, timeup)); + printf("offsetof(timereset) = %d\n", + (int) offsetof(struct info_sys_stats, timereset)); + printf("offsetof(denied) = %d\n", + (int) offsetof(struct info_sys_stats, denied)); + printf("offsetof(oldversionpkt) = %d\n", + (int) offsetof(struct info_sys_stats, oldversionpkt)); + printf("offsetof(newversionpkt) = %d\n", + (int) offsetof(struct info_sys_stats, newversionpkt)); + printf("offsetof(unknownversion) = %d\n", + (int) offsetof(struct info_sys_stats, unknownversion)); + printf("offsetof(badlength) = %d\n", + (int) offsetof(struct info_sys_stats, badlength)); + printf("offsetof(processed) = %d\n", + (int) offsetof(struct info_sys_stats, processed)); + printf("offsetof(badauth) = %d\n", + (int) offsetof(struct info_sys_stats, badauth)); + printf("offsetof(received) = %d\n", + (int) offsetof(struct info_sys_stats, received)); + printf("offsetof(limitrejected) = %d\n", + (int) offsetof(struct info_sys_stats, limitrejected)); + printf("\n"); + + printf("sizeof(struct old_info_sys_stats) = %d\n", + (int) sizeof(struct old_info_sys_stats)); + printf("offsetof(timeup) = %d\n", + (int) offsetof(struct old_info_sys_stats, timeup)); + printf("offsetof(timereset) = %d\n", + (int) offsetof(struct old_info_sys_stats, timereset)); + printf("offsetof(denied) = %d\n", + (int) offsetof(struct old_info_sys_stats, denied)); + printf("offsetof(oldversionpkt) = %d\n", + (int) offsetof(struct old_info_sys_stats, oldversionpkt)); + printf("offsetof(newversionpkt) = %d\n", + (int) offsetof(struct old_info_sys_stats, newversionpkt)); + printf("offsetof(unknownversion) = %d\n", + (int) offsetof(struct old_info_sys_stats, unknownversion)); + printf("offsetof(badlength) = %d\n", + (int) offsetof(struct old_info_sys_stats, badlength)); + printf("offsetof(processed) = %d\n", + (int) offsetof(struct old_info_sys_stats, processed)); + printf("offsetof(badauth) = %d\n", + (int) offsetof(struct old_info_sys_stats, badauth)); + printf("offsetof(wanderhold) = %d\n", + (int) offsetof(struct old_info_sys_stats, wanderhold)); + printf("\n"); + + printf("sizeof(struct info_mem_stats) = %d\n", + (int) sizeof(struct info_mem_stats)); + printf("offsetof(timereset) = %d\n", + (int) offsetof(struct info_mem_stats, timereset)); + printf("offsetof(totalpeermem) = %d\n", + (int) offsetof(struct info_mem_stats, totalpeermem)); + printf("offsetof(freepeermem) = %d\n", + (int) offsetof(struct info_mem_stats, freepeermem)); + printf("offsetof(findpeer_calls) = %d\n", + (int) offsetof(struct info_mem_stats, findpeer_calls)); + printf("offsetof(allocations) = %d\n", + (int) offsetof(struct info_mem_stats, allocations)); + printf("offsetof(demobilizations) = %d\n", + (int) offsetof(struct info_mem_stats, demobilizations)); + printf("offsetof(hashcount) = %d\n", + (int) offsetof(struct info_mem_stats, hashcount)); + printf("\n"); + + printf("sizeof(struct info_io_stats) = %d\n", + (int) sizeof(struct info_io_stats)); + printf("offsetof(timereset) = %d\n", + (int) offsetof(struct info_io_stats, timereset)); + printf("offsetof(totalrecvbufs) = %d\n", + (int) offsetof(struct info_io_stats, totalrecvbufs)); + printf("offsetof(freerecvbufs) = %d\n", + (int) offsetof(struct info_io_stats, freerecvbufs)); + printf("offsetof(fullrecvbufs) = %d\n", + (int) offsetof(struct info_io_stats, fullrecvbufs)); + printf("offsetof(lowwater) = %d\n", + (int) offsetof(struct info_io_stats, lowwater)); + printf("offsetof(dropped) = %d\n", + (int) offsetof(struct info_io_stats, dropped)); + printf("offsetof(ignored) = %d\n", + (int) offsetof(struct info_io_stats, ignored)); + printf("offsetof(received) = %d\n", + (int) offsetof(struct info_io_stats, received)); + printf("offsetof(sent) = %d\n", + (int) offsetof(struct info_io_stats, sent)); + printf("offsetof(notsent) = %d\n", + (int) offsetof(struct info_io_stats, notsent)); + printf("offsetof(interrupts) = %d\n", + (int) offsetof(struct info_io_stats, interrupts)); + printf("offsetof(int_received) = %d\n", + (int) offsetof(struct info_io_stats, int_received)); + printf("\n"); + + printf("sizeof(struct info_timer_stats) = %d\n", + (int) sizeof(struct info_timer_stats)); + printf("offsetof(timereset) = %d\n", + (int) offsetof(struct info_timer_stats, timereset)); + printf("offsetof(alarms) = %d\n", + (int) offsetof(struct info_timer_stats, alarms)); + printf("offsetof(overflows) = %d\n", + (int) offsetof(struct info_timer_stats, overflows)); + printf("offsetof(xmtcalls) = %d\n", + (int) offsetof(struct info_timer_stats, xmtcalls)); + printf("\n"); + + printf("sizeof(struct old_conf_peer) = %d\n", + (int) sizeof(struct old_conf_peer)); + printf("offsetof(peeraddr) = %d\n", + (int) offsetof(struct old_conf_peer, peeraddr)); + printf("offsetof(hmode) = %d\n", + (int) offsetof(struct old_conf_peer, hmode)); + printf("offsetof(version) = %d\n", + (int) offsetof(struct old_conf_peer, version)); + printf("offsetof(minpoll) = %d\n", + (int) offsetof(struct old_conf_peer, minpoll)); + printf("offsetof(maxpoll) = %d\n", + (int) offsetof(struct old_conf_peer, maxpoll)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct old_conf_peer, flags)); + printf("offsetof(ttl) = %d\n", + (int) offsetof(struct old_conf_peer, ttl)); + printf("offsetof(unused) = %d\n", + (int) offsetof(struct old_conf_peer, unused)); + printf("offsetof(keyid) = %d\n", + (int) offsetof(struct old_conf_peer, keyid)); + printf("\n"); + + printf("sizeof(struct conf_peer) = %d\n", + (int) sizeof(struct conf_peer)); + printf("offsetof(peeraddr) = %d\n", + (int) offsetof(struct conf_peer, peeraddr)); + printf("offsetof(hmode) = %d\n", + (int) offsetof(struct conf_peer, hmode)); + printf("offsetof(version) = %d\n", + (int) offsetof(struct conf_peer, version)); + printf("offsetof(minpoll) = %d\n", + (int) offsetof(struct conf_peer, minpoll)); + printf("offsetof(maxpoll) = %d\n", + (int) offsetof(struct conf_peer, maxpoll)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct conf_peer, flags)); + printf("offsetof(ttl) = %d\n", + (int) offsetof(struct conf_peer, ttl)); + printf("offsetof(unused1) = %d\n", + (int) offsetof(struct conf_peer, unused1)); + printf("offsetof(keyid) = %d\n", + (int) offsetof(struct conf_peer, keyid)); + printf("offsetof(keystr) = %d\n", + (int) offsetof(struct conf_peer, keystr)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct conf_peer, v6_flag)); + printf("offsetof(unused2) = %d\n", + (int) offsetof(struct conf_peer, unused2)); + printf("offsetof(peeraddr6) = %d\n", + (int) offsetof(struct conf_peer, peeraddr6)); + printf("\n"); + + printf("sizeof(struct conf_unpeer) = %d\n", + (int) sizeof(struct conf_unpeer)); + printf("offsetof(peeraddr) = %d\n", + (int) offsetof(struct conf_unpeer, peeraddr)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct conf_unpeer, v6_flag)); + printf("offsetof(peeraddr6) = %d\n", + (int) offsetof(struct conf_unpeer, peeraddr6)); + printf("\n"); + + printf("sizeof(struct conf_sys_flags) = %d\n", + (int) sizeof(struct conf_sys_flags)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct conf_sys_flags, flags)); + printf("\n"); + + printf("sizeof(struct info_restrict) = %d\n", + (int) sizeof(struct info_restrict)); + printf("offsetof(addr) = %d\n", + (int) offsetof(struct info_restrict, addr)); + printf("offsetof(mask) = %d\n", + (int) offsetof(struct info_restrict, mask)); + printf("offsetof(count) = %d\n", + (int) offsetof(struct info_restrict, count)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct info_restrict, flags)); + printf("offsetof(mflags) = %d\n", + (int) offsetof(struct info_restrict, mflags)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct info_restrict, v6_flag)); + printf("offsetof(unused1) = %d\n", + (int) offsetof(struct info_restrict, unused1)); + printf("offsetof(addr6) = %d\n", + (int) offsetof(struct info_restrict, addr6)); + printf("offsetof(mask6) = %d\n", + (int) offsetof(struct info_restrict, mask6)); + printf("\n"); + + printf("sizeof(struct conf_restrict) = %d\n", + (int) sizeof(struct conf_restrict)); + printf("offsetof(addr) = %d\n", + (int) offsetof(struct conf_restrict, addr)); + printf("offsetof(mask) = %d\n", + (int) offsetof(struct conf_restrict, mask)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct conf_restrict, flags)); + printf("offsetof(mflags) = %d\n", + (int) offsetof(struct conf_restrict, mflags)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct conf_restrict, v6_flag)); + printf("offsetof(addr6) = %d\n", + (int) offsetof(struct conf_restrict, addr6)); + printf("offsetof(mask6) = %d\n", + (int) offsetof(struct conf_restrict, mask6)); + printf("\n"); + + printf("sizeof(struct info_monitor_1) = %d\n", + (int) sizeof(struct info_monitor_1)); + printf("offsetof(avg_int) = %d\n", + (int) offsetof(struct info_monitor_1, avg_int)); + printf("offsetof(last_int) = %d\n", + (int) offsetof(struct info_monitor_1, last_int)); + printf("offsetof(restr) = %d\n", + (int) offsetof(struct info_monitor_1, restr)); + printf("offsetof(count) = %d\n", + (int) offsetof(struct info_monitor_1, count)); + printf("offsetof(addr) = %d\n", + (int) offsetof(struct info_monitor_1, addr)); + printf("offsetof(daddr) = %d\n", + (int) offsetof(struct info_monitor_1, daddr)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct info_monitor_1, flags)); + printf("offsetof(port) = %d\n", + (int) offsetof(struct info_monitor_1, port)); + printf("offsetof(mode) = %d\n", + (int) offsetof(struct info_monitor_1, mode)); + printf("offsetof(version) = %d\n", + (int) offsetof(struct info_monitor_1, version)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct info_monitor_1, v6_flag)); + printf("offsetof(unused1) = %d\n", + (int) offsetof(struct info_monitor_1, unused1)); + printf("offsetof(addr6) = %d\n", + (int) offsetof(struct info_monitor_1, addr6)); + printf("offsetof(daddr6) = %d\n", + (int) offsetof(struct info_monitor_1, daddr6)); + printf("\n"); + + printf("sizeof(struct info_monitor) = %d\n", + (int) sizeof(struct info_monitor)); + printf("offsetof(avg_int) = %d\n", + (int) offsetof(struct info_monitor, avg_int)); + printf("offsetof(last_int) = %d\n", + (int) offsetof(struct info_monitor, last_int)); + printf("offsetof(restr) = %d\n", + (int) offsetof(struct info_monitor, restr)); + printf("offsetof(count) = %d\n", + (int) offsetof(struct info_monitor, count)); + printf("offsetof(addr) = %d\n", + (int) offsetof(struct info_monitor, addr)); + printf("offsetof(port) = %d\n", + (int) offsetof(struct info_monitor, port)); + printf("offsetof(mode) = %d\n", + (int) offsetof(struct info_monitor, mode)); + printf("offsetof(version) = %d\n", + (int) offsetof(struct info_monitor, version)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct info_monitor, v6_flag)); + printf("offsetof(unused1) = %d\n", + (int) offsetof(struct info_monitor, unused1)); + printf("offsetof(addr6) = %d\n", + (int) offsetof(struct info_monitor, addr6)); + printf("\n"); + + printf("sizeof(struct old_info_monitor) = %d\n", + (int) sizeof(struct old_info_monitor)); + printf("offsetof(lasttime) = %d\n", + (int) offsetof(struct old_info_monitor, lasttime)); + printf("offsetof(firsttime) = %d\n", + (int) offsetof(struct old_info_monitor, firsttime)); + printf("offsetof(count) = %d\n", + (int) offsetof(struct old_info_monitor, count)); + printf("offsetof(addr) = %d\n", + (int) offsetof(struct old_info_monitor, addr)); + printf("offsetof(port) = %d\n", + (int) offsetof(struct old_info_monitor, port)); + printf("offsetof(mode) = %d\n", + (int) offsetof(struct old_info_monitor, mode)); + printf("offsetof(version) = %d\n", + (int) offsetof(struct old_info_monitor, version)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct old_info_monitor, v6_flag)); + printf("offsetof(addr6) = %d\n", + (int) offsetof(struct old_info_monitor, addr6)); + printf("\n"); + + printf("sizeof(struct reset_flags) = %d\n", + (int) sizeof(struct reset_flags)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct reset_flags, flags)); + printf("\n"); + + printf("sizeof(struct info_auth) = %d\n", + (int) sizeof(struct info_auth)); + printf("offsetof(timereset) = %d\n", + (int) offsetof(struct info_auth, timereset)); + printf("offsetof(numkeys) = %d\n", + (int) offsetof(struct info_auth, numkeys)); + printf("offsetof(numfreekeys) = %d\n", + (int) offsetof(struct info_auth, numfreekeys)); + printf("offsetof(keylookups) = %d\n", + (int) offsetof(struct info_auth, keylookups)); + printf("offsetof(keynotfound) = %d\n", + (int) offsetof(struct info_auth, keynotfound)); + printf("offsetof(encryptions) = %d\n", + (int) offsetof(struct info_auth, encryptions)); + printf("offsetof(decryptions) = %d\n", + (int) offsetof(struct info_auth, decryptions)); + printf("offsetof(expired) = %d\n", + (int) offsetof(struct info_auth, expired)); + printf("offsetof(keyuncached) = %d\n", + (int) offsetof(struct info_auth, keyuncached)); + printf("\n"); + + printf("sizeof(struct info_trap) = %d\n", + (int) sizeof(struct info_trap)); + printf("offsetof(local_address) = %d\n", + (int) offsetof(struct info_trap, local_address)); + printf("offsetof(trap_address) = %d\n", + (int) offsetof(struct info_trap, trap_address)); + printf("offsetof(trap_port) = %d\n", + (int) offsetof(struct info_trap, trap_port)); + printf("offsetof(sequence) = %d\n", + (int) offsetof(struct info_trap, sequence)); + printf("offsetof(settime) = %d\n", + (int) offsetof(struct info_trap, settime)); + printf("offsetof(origtime) = %d\n", + (int) offsetof(struct info_trap, origtime)); + printf("offsetof(resets) = %d\n", + (int) offsetof(struct info_trap, resets)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct info_trap, flags)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct info_trap, v6_flag)); + printf("offsetof(local_address6) = %d\n", + (int) offsetof(struct info_trap, local_address6)); + printf("offsetof(trap_address6) = %d\n", + (int) offsetof(struct info_trap, trap_address6)); + printf("\n"); + + printf("sizeof(struct conf_trap) = %d\n", + (int) sizeof(struct conf_trap)); + printf("offsetof(local_address) = %d\n", + (int) offsetof(struct conf_trap, local_address)); + printf("offsetof(trap_address) = %d\n", + (int) offsetof(struct conf_trap, trap_address)); + printf("offsetof(trap_port) = %d\n", + (int) offsetof(struct conf_trap, trap_port)); + printf("offsetof(unused) = %d\n", + (int) offsetof(struct conf_trap, unused)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct conf_trap, v6_flag)); + printf("offsetof(local_address6) = %d\n", + (int) offsetof(struct conf_trap, local_address6)); + printf("offsetof(trap_address6) = %d\n", + (int) offsetof(struct conf_trap, trap_address6)); + printf("\n"); + + printf("sizeof(struct info_control) = %d\n", + (int) sizeof(struct info_control)); + printf("offsetof(ctltimereset) = %d\n", + (int) offsetof(struct info_control, ctltimereset)); + printf("offsetof(numctlreq) = %d\n", + (int) offsetof(struct info_control, numctlreq)); + printf("offsetof(numctlbadpkts) = %d\n", + (int) offsetof(struct info_control, numctlbadpkts)); + printf("offsetof(numctlresponses) = %d\n", + (int) offsetof(struct info_control, numctlresponses)); + printf("offsetof(numctlfrags) = %d\n", + (int) offsetof(struct info_control, numctlfrags)); + printf("offsetof(numctlerrors) = %d\n", + (int) offsetof(struct info_control, numctlerrors)); + printf("offsetof(numctltooshort) = %d\n", + (int) offsetof(struct info_control, numctltooshort)); + printf("offsetof(numctlinputresp) = %d\n", + (int) offsetof(struct info_control, numctlinputresp)); + printf("offsetof(numctlinputfrag) = %d\n", + (int) offsetof(struct info_control, numctlinputfrag)); + printf("offsetof(numctlinputerr) = %d\n", + (int) offsetof(struct info_control, numctlinputerr)); + printf("offsetof(numctlbadoffset) = %d\n", + (int) offsetof(struct info_control, numctlbadoffset)); + printf("offsetof(numctlbadversion) = %d\n", + (int) offsetof(struct info_control, numctlbadversion)); + printf("offsetof(numctldatatooshort) = %d\n", + (int) offsetof(struct info_control, numctldatatooshort)); + printf("offsetof(numctlbadop) = %d\n", + (int) offsetof(struct info_control, numctlbadop)); + printf("offsetof(numasyncmsgs) = %d\n", + (int) offsetof(struct info_control, numasyncmsgs)); + printf("\n"); + + printf("sizeof(struct info_clock) = %d\n", + (int) sizeof(struct info_clock)); + printf("offsetof(clockadr) = %d\n", + (int) offsetof(struct info_clock, clockadr)); + printf("offsetof(type) = %d\n", + (int) offsetof(struct info_clock, type)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct info_clock, flags)); + printf("offsetof(lastevent) = %d\n", + (int) offsetof(struct info_clock, lastevent)); + printf("offsetof(currentstatus) = %d\n", + (int) offsetof(struct info_clock, currentstatus)); + printf("offsetof(polls) = %d\n", + (int) offsetof(struct info_clock, polls)); + printf("offsetof(noresponse) = %d\n", + (int) offsetof(struct info_clock, noresponse)); + printf("offsetof(badformat) = %d\n", + (int) offsetof(struct info_clock, badformat)); + printf("offsetof(baddata) = %d\n", + (int) offsetof(struct info_clock, baddata)); + printf("offsetof(timestarted) = %d\n", + (int) offsetof(struct info_clock, timestarted)); + printf("offsetof(fudgetime1) = %d\n", + (int) offsetof(struct info_clock, fudgetime1)); + printf("offsetof(fudgetime2) = %d\n", + (int) offsetof(struct info_clock, fudgetime2)); + printf("offsetof(fudgeval1) = %d\n", + (int) offsetof(struct info_clock, fudgeval1)); + printf("offsetof(fudgeval2) = %d\n", + (int) offsetof(struct info_clock, fudgeval2)); + printf("\n"); + + printf("sizeof(struct conf_fudge) = %d\n", + (int) sizeof(struct conf_fudge)); + printf("offsetof(clockadr) = %d\n", + (int) offsetof(struct conf_fudge, clockadr)); + printf("offsetof(which) = %d\n", + (int) offsetof(struct conf_fudge, which)); + printf("offsetof(fudgetime) = %d\n", + (int) offsetof(struct conf_fudge, fudgetime)); + printf("offsetof(fudgeval_flags) = %d\n", + (int) offsetof(struct conf_fudge, fudgeval_flags)); + printf("\n"); + + printf("sizeof(struct info_clkbug) = %d\n", + (int) sizeof(struct info_clkbug)); + printf("offsetof(clockadr) = %d\n", + (int) offsetof(struct info_clkbug, clockadr)); + printf("offsetof(nvalues) = %d\n", + (int) offsetof(struct info_clkbug, nvalues)); + printf("offsetof(ntimes) = %d\n", + (int) offsetof(struct info_clkbug, ntimes)); + printf("offsetof(svalues) = %d\n", + (int) offsetof(struct info_clkbug, svalues)); + printf("offsetof(stimes) = %d\n", + (int) offsetof(struct info_clkbug, stimes)); + printf("offsetof(values) = %d\n", + (int) offsetof(struct info_clkbug, values)); + printf("offsetof(times) = %d\n", + (int) offsetof(struct info_clkbug, times)); + printf("\n"); + + printf("sizeof(struct info_kernel) = %d\n", + (int) sizeof(struct info_kernel)); + printf("offsetof(offset) = %d\n", + (int) offsetof(struct info_kernel, offset)); + printf("offsetof(freq) = %d\n", + (int) offsetof(struct info_kernel, freq)); + printf("offsetof(maxerror) = %d\n", + (int) offsetof(struct info_kernel, maxerror)); + printf("offsetof(esterror) = %d\n", + (int) offsetof(struct info_kernel, esterror)); + printf("offsetof(status) = %d\n", + (int) offsetof(struct info_kernel, status)); + printf("offsetof(shift) = %d\n", + (int) offsetof(struct info_kernel, shift)); + printf("offsetof(constant) = %d\n", + (int) offsetof(struct info_kernel, constant)); + printf("offsetof(precision) = %d\n", + (int) offsetof(struct info_kernel, precision)); + printf("offsetof(tolerance) = %d\n", + (int) offsetof(struct info_kernel, tolerance)); + printf("offsetof(ppsfreq) = %d\n", + (int) offsetof(struct info_kernel, ppsfreq)); + printf("offsetof(jitter) = %d\n", + (int) offsetof(struct info_kernel, jitter)); + printf("offsetof(stabil) = %d\n", + (int) offsetof(struct info_kernel, stabil)); + printf("offsetof(jitcnt) = %d\n", + (int) offsetof(struct info_kernel, jitcnt)); + printf("offsetof(calcnt) = %d\n", + (int) offsetof(struct info_kernel, calcnt)); + printf("offsetof(errcnt) = %d\n", + (int) offsetof(struct info_kernel, errcnt)); + printf("offsetof(stbcnt) = %d\n", + (int) offsetof(struct info_kernel, stbcnt)); + printf("\n"); + + printf("sizeof(struct info_if_stats) = %d\n", + (int) sizeof(struct info_if_stats)); + printf("offsetof(unaddr) = %d\n", + (int) offsetof(struct info_if_stats, unaddr)); + printf("offsetof(unbcast) = %d\n", + (int) offsetof(struct info_if_stats, unbcast)); + printf("offsetof(unmask) = %d\n", + (int) offsetof(struct info_if_stats, unmask)); + printf("offsetof(v6_flag) = %d\n", + (int) offsetof(struct info_if_stats, v6_flag)); + printf("offsetof(name) = %d\n", + (int) offsetof(struct info_if_stats, name)); + printf("offsetof(flags) = %d\n", + (int) offsetof(struct info_if_stats, flags)); + printf("offsetof(last_ttl) = %d\n", + (int) offsetof(struct info_if_stats, last_ttl)); + printf("offsetof(num_mcast) = %d\n", + (int) offsetof(struct info_if_stats, num_mcast)); + printf("offsetof(received) = %d\n", + (int) offsetof(struct info_if_stats, received)); + printf("offsetof(sent) = %d\n", + (int) offsetof(struct info_if_stats, sent)); + printf("offsetof(notsent) = %d\n", + (int) offsetof(struct info_if_stats, notsent)); + printf("offsetof(uptime) = %d\n", + (int) offsetof(struct info_if_stats, uptime)); + printf("offsetof(scopeid) = %d\n", + (int) offsetof(struct info_if_stats, scopeid)); + printf("offsetof(ifindex) = %d\n", + (int) offsetof(struct info_if_stats, ifindex)); + printf("offsetof(ifnum) = %d\n", + (int) offsetof(struct info_if_stats, ifnum)); + printf("offsetof(peercnt) = %d\n", + (int) offsetof(struct info_if_stats, peercnt)); + printf("offsetof(family) = %d\n", + (int) offsetof(struct info_if_stats, family)); + printf("offsetof(ignore_packets) = %d\n", + (int) offsetof(struct info_if_stats, ignore_packets)); + printf("offsetof(action) = %d\n", + (int) offsetof(struct info_if_stats, action)); + printf("offsetof(_filler0) = %d\n", + (int) offsetof(struct info_if_stats, _filler0)); + printf("\n"); + + printf("sizeof(struct info_dns_assoc) = %d\n", + (int) sizeof(struct info_dns_assoc)); + printf("offsetof(peeraddr) = %d\n", + (int) offsetof(struct info_dns_assoc, peeraddr)); + printf("offsetof(associd) = %d\n", + (int) offsetof(struct info_dns_assoc, associd)); + printf("offsetof(hostname) = %d\n", + (int) offsetof(struct info_dns_assoc, hostname)); + printf("\n"); + diff --git a/usr.sbin/ntp/ntpq/Makefile b/usr.sbin/ntp/ntpq/Makefile index 369bd58..d512cff 100644 --- a/usr.sbin/ntp/ntpq/Makefile +++ b/usr.sbin/ntp/ntpq/Makefile @@ -2,6 +2,7 @@ MAN= +.include <src.opts.mk> .include <bsd.own.mk> .PATH: ${.CURDIR}/../../../contrib/ntp/ntpq @@ -11,14 +12,21 @@ BINDIR= /usr/bin PROG= ntpq SRCS= ntpq.c ntpq-opts.c ntpq-subs.c version.c -CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include -I${.CURDIR}/../ \ - -I${.CURDIR}/../../../contrib/ntp/libopts +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/unix/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/pthreads/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/${NTP_ATOMIC}/include \ + -I${.CURDIR}/../../../contrib/ntp/sntp/libopts \ + -I${.CURDIR}/../ -DPADD= ${LIBNTP} ${LIBM} ${LIBMD} ${LIBOPTS} -LDADD= ${LIBNTP} -lm -lmd ${LIBOPTS} +LIBADD+= edit md ntp opts m pthread + +.if ${MK_OPENSSL} != "no" +LIBADD+= ssl crypto +.endif -DPADD+= ${LIBEDIT} ${LIBTERMCAPW} -LDADD+= -ledit -ltermcapw CFLAGS+= -DHAVE_LIBEDIT -DHAVE_READLINE_READLINE_H \ -I${DESTDIR}/${INCLUDEDIR}/edit diff --git a/usr.sbin/ntp/ntpq/Makefile.depend b/usr.sbin/ntp/ntpq/Makefile.depend index d3c16eb..1a4abc4 100644 --- a/usr.sbin/ntp/ntpq/Makefile.depend +++ b/usr.sbin/ntp/ntpq/Makefile.depend @@ -13,11 +13,12 @@ DIRDEPS = \ lib/libc \ lib/libcompiler_rt \ lib/libedit \ - lib/libedit/edit/readline \ lib/libmd \ + lib/libthr \ lib/msun \ lib/ncurses/ncursesw \ secure/lib/libcrypto \ + secure/lib/libssl \ usr.sbin/ntp/libntp \ usr.sbin/ntp/libopts \ diff --git a/usr.sbin/ntp/ntptime/Makefile b/usr.sbin/ntp/ntptime/Makefile index d3bf7a7..ef02d0f 100644 --- a/usr.sbin/ntp/ntptime/Makefile +++ b/usr.sbin/ntp/ntptime/Makefile @@ -5,9 +5,12 @@ PROG= ntptime MAN= -CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include -I${.CURDIR}/../ +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/include/ \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/unix/include/ \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/pthreads/include \ + -I${.CURDIR}/../ -DPADD= ${LIBNTP} -LDADD= ${LIBNTP} +LIBADD= ntp pthread .include <bsd.prog.mk> diff --git a/usr.sbin/ntp/ntptime/Makefile.depend b/usr.sbin/ntp/ntptime/Makefile.depend index a173739..6dc23de 100644 --- a/usr.sbin/ntp/ntptime/Makefile.depend +++ b/usr.sbin/ntp/ntptime/Makefile.depend @@ -6,10 +6,14 @@ DIRDEPS = \ gnu/lib/csu \ gnu/lib/libgcc \ include \ + include/arpa \ include/xlocale \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ + lib/libthr \ + lib/msun \ + secure/lib/libcrypto \ usr.sbin/ntp/libntp \ diff --git a/usr.sbin/ntp/scripts/mkver b/usr.sbin/ntp/scripts/mkver index a8f5175..f34267d 100755 --- a/usr.sbin/ntp/scripts/mkver +++ b/usr.sbin/ntp/scripts/mkver @@ -6,7 +6,7 @@ PROG=${1-UNKNOWN} ConfStr="$PROG" -ConfStr="$ConfStr 4.2.4p5" +ConfStr="$ConfStr 4.2.8p2" case "$CSET" in '') ;; diff --git a/usr.sbin/ntp/sntp/Makefile b/usr.sbin/ntp/sntp/Makefile index 11316c5..eba7b83 100644 --- a/usr.sbin/ntp/sntp/Makefile +++ b/usr.sbin/ntp/sntp/Makefile @@ -1,16 +1,29 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../../contrib/ntp/sntp +.include <src.opts.mk> + +.PATH: ${.CURDIR}/../../../contrib/ntp/sntp PROG= sntp -MAN= sntp.1 -SRCS= internet.c main.c socket.c timing.c unix.c +MK_MAN= no +SRCS= crypto.c kod_management.c log.c main.c networking.c \ + sntp-opts.c sntp.c utilities.c + +CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/unix/include \ + -I${.CURDIR}/../../../contrib/ntp/lib/isc/pthreads/include \ + -I${.CURDIR}/../../../contrib/ntp/sntp \ + -I${.CURDIR}/../../../contrib/ntp/sntp/libopts \ + -I${.CURDIR}/../../../contrib/ntp/sntp/libevent/include \ + -I${.CURDIR}/../libntpevent \ + -I${.CURDIR}/../ -CFLAGS+= -I${.CURDIR}/../../../contrib/ntp/include -I${.CURDIR}/../ \ - -DPACKAGE=\"sntp\" -DVERSION=\"1.6\" \ - -I${.CURDIR}/../../../contrib/ntp/libopts +LIBADD= m opts ntp ntpevent pthread -DPADD= ${LIBM} ${LIBOPTS} -LDADD= -lm ${LIBOPTS} +.if ${MK_OPENSSL} != "no" +LIBADD+= md ssl crypto +.endif .include <bsd.prog.mk> diff --git a/usr.sbin/ntp/sntp/Makefile.depend b/usr.sbin/ntp/sntp/Makefile.depend index e7a994a..da4042f 100644 --- a/usr.sbin/ntp/sntp/Makefile.depend +++ b/usr.sbin/ntp/sntp/Makefile.depend @@ -11,7 +11,13 @@ DIRDEPS = \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ + lib/libmd \ + lib/libthr \ lib/msun \ + secure/lib/libcrypto \ + secure/lib/libssl \ + usr.sbin/ntp/libntp \ + usr.sbin/ntp/libntpevent \ usr.sbin/ntp/libopts \ diff --git a/usr.sbin/ofwdump/ofwdump.c b/usr.sbin/ofwdump/ofwdump.c index ea25caa..9a356f4 100644 --- a/usr.sbin/ofwdump/ofwdump.c +++ b/usr.sbin/ofwdump/ofwdump.c @@ -49,8 +49,9 @@ __FBSDID("$FreeBSD$"); static void usage(void); static void ofw_indent(int); -static void ofw_dump_properties(int, phandle_t, int, const char *, int, - int); +static void ofw_dump_properties(int, phandle_t, int, int, int); +static void ofw_dump_property(int fd, phandle_t n, int level, + const char *prop, int raw, int str); static void ofw_dump(int, const char *, int, int, const char *, int, int); static void @@ -140,62 +141,67 @@ ofw_indent(int level) } static void -ofw_dump_properties(int fd, phandle_t n, int level, const char *pmatch, int raw, +ofw_dump_properties(int fd, phandle_t n, int level, int raw, int str) +{ + int nlen; + char prop[32]; + + for (nlen = ofw_firstprop(fd, n, prop, sizeof(prop)); nlen != 0; + nlen = ofw_nextprop(fd, n, prop, prop, sizeof(prop))) + ofw_dump_property(fd, n, level, prop, raw, str); +} + +static void +ofw_dump_property(int fd, phandle_t n, int level, const char *prop, int raw, int str) { static void *pbuf = NULL; static char *visbuf = NULL; static char printbuf[CHARSPERLINE + 1]; static int pblen = 0, vblen = 0; - char prop[32]; - int nlen, len, i, j, max, vlen; - - for (nlen = ofw_firstprop(fd, n, prop, sizeof(prop)); nlen != 0; - nlen = ofw_nextprop(fd, n, prop, prop, sizeof(prop))) { - if (pmatch != NULL && strcmp(pmatch, prop) != 0) - continue; - len = ofw_getprop_alloc(fd, n, prop, &pbuf, &pblen, 1); - if (len < 0) - continue; - if (raw) - write(STDOUT_FILENO, pbuf, len); - else if (str) - printf("%.*s\n", len, (char *)pbuf); - else { - ofw_indent(level * LVLINDENT + NAMEINDENT); - printf("%s:\n", prop); - /* Print in hex. */ - for (i = 0; i < len; i += BYTESPERLINE) { - max = len - i; - max = max > BYTESPERLINE ? BYTESPERLINE : max; - ofw_indent(level * LVLINDENT + DUMPINDENT); - for (j = 0; j < max; j++) - printf("%02x ", - ((unsigned char *)pbuf)[i + j]); - printf("\n"); - } - /* - * strvis() and print if it looks like it is - * zero-terminated. - */ - if (((char *)pbuf)[len - 1] == '\0' && - strlen(pbuf) == (unsigned)len - 1) { - if (vblen < (len - 1) * 4 + 1) { - if (visbuf != NULL) - free(visbuf); - vblen = (OFIOCMAXVALUE + len) * 4 + 1; + int len, i, j, max, vlen; + + len = ofw_getprop_alloc(fd, n, prop, &pbuf, &pblen, 1); + if (len < 0) + return; + if (raw) + write(STDOUT_FILENO, pbuf, len); + else if (str) + printf("%.*s\n", len, (char *)pbuf); + else { + ofw_indent(level * LVLINDENT + NAMEINDENT); + printf("%s:\n", prop); + /* Print in hex. */ + for (i = 0; i < len; i += BYTESPERLINE) { + max = len - i; + max = max > BYTESPERLINE ? BYTESPERLINE : max; + ofw_indent(level * LVLINDENT + DUMPINDENT); + for (j = 0; j < max; j++) + printf("%02x ", + ((unsigned char *)pbuf)[i + j]); + printf("\n"); + } + /* + * strvis() and print if it looks like it is + * zero-terminated. + */ + if (((char *)pbuf)[len - 1] == '\0' && + strlen(pbuf) == (unsigned)len - 1) { + if (vblen < (len - 1) * 4 + 1) { + if (visbuf != NULL) + free(visbuf); + vblen = (OFIOCMAXVALUE + len) * 4 + 1; if ((visbuf = malloc(vblen)) == NULL) err(EX_OSERR, "malloc() failed"); - } - vlen = strvis(visbuf, pbuf, VIS_TAB | VIS_NL); - for (i = 0; i < vlen; i += CHARSPERLINE) { - ofw_indent(level * LVLINDENT + - DUMPINDENT); - strlcpy(printbuf, &visbuf[i], - sizeof(printbuf)); - printf("'%s'\n", printbuf); - } + } + vlen = strvis(visbuf, pbuf, VIS_TAB | VIS_NL); + for (i = 0; i < vlen; i += CHARSPERLINE) { + ofw_indent(level * LVLINDENT + + DUMPINDENT); + strlcpy(printbuf, &visbuf[i], + sizeof(printbuf)); + printf("'%s'\n", printbuf); } } } @@ -219,8 +225,12 @@ ofw_dump_node(int fd, phandle_t n, int level, int rec, int prop, else putchar('\n'); } - if (prop) - ofw_dump_properties(fd, n, level, pmatch, raw, str); + if (prop) { + if (pmatch) + ofw_dump_property(fd, n, level, pmatch, raw, str); + else + ofw_dump_properties(fd, n, level, raw, str); + } if (rec) { for (c = ofw_child(fd, n); c != 0; c = ofw_peer(fd, c)) { ofw_dump_node(fd, c, level + 1, rec, prop, pmatch, diff --git a/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh b/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh index fd6556d..a75fad7 100755 --- a/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh +++ b/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh @@ -303,7 +303,7 @@ fetch_split_files() OUTFILE="${FSMNT}/.fetch-${INSFILE}" fi - DIRS="base catpages dict doc games info manpages proflibs kernels src" + DIRS="base catpages dict doc info manpages proflibs kernels src" if [ "${FBSD_ARCH}" = "amd64" ] then DIRS="${DIRS} lib32" diff --git a/usr.sbin/pciconf/cap.c b/usr.sbin/pciconf/cap.c index bdcbe1d..2e2e359 100644 --- a/usr.sbin/pciconf/cap.c +++ b/usr.sbin/pciconf/cap.c @@ -37,6 +37,7 @@ static const char rcsid[] = #include <err.h> #include <stdio.h> +#include <strings.h> #include <sys/agpio.h> #include <sys/pciio.h> @@ -636,7 +637,7 @@ ecap_aer(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) printf(" %d fatal", bitcount32(sta & mask)); printf(" %d non-fatal", bitcount32(sta & ~mask)); sta = read_config(fd, &p->pc_sel, ptr + PCIR_AER_COR_STATUS, 4); - printf(" %d corrected", bitcount32(sta)); + printf(" %d corrected\n", bitcount32(sta)); } static void @@ -652,6 +653,7 @@ ecap_vc(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) if ((cap1 & PCIM_VC_CAP1_LOWPRI_EXT_COUNT) != 0) printf(" lowpri VC0-VC%d", (cap1 & PCIM_VC_CAP1_LOWPRI_EXT_COUNT) >> 4); + printf("\n"); } static void @@ -664,7 +666,7 @@ ecap_sernum(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) return; low = read_config(fd, &p->pc_sel, ptr + PCIR_SERIAL_LOW, 4); high = read_config(fd, &p->pc_sel, ptr + PCIR_SERIAL_HIGH, 4); - printf(" %08x%08x", high, low); + printf(" %08x%08x\n", high, low); } static void @@ -676,7 +678,7 @@ ecap_vendor(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) if (ver < 1) return; val = read_config(fd, &p->pc_sel, ptr + 4, 4); - printf(" ID %d", val & 0xffff); + printf(" ID %d\n", val & 0xffff); } static void @@ -688,7 +690,69 @@ ecap_sec_pcie(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) if (ver < 1) return; val = read_config(fd, &p->pc_sel, ptr + 8, 4); - printf(" lane errors %#x", val); + printf(" lane errors %#x\n", val); +} + +static const char * +check_enabled(int value) +{ + + return (value ? "enabled" : "disabled"); +} + +static void +ecap_sriov(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) +{ + const char *comma, *enabled; + uint16_t iov_ctl, total_vfs, num_vfs, vf_offset, vf_stride, vf_did; + uint32_t page_caps, page_size, page_shift, size; + int i; + + printf("SR-IOV %d ", ver); + + iov_ctl = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_CTL, 2); + printf("IOV %s, Memory Space %s, ARI %s\n", + check_enabled(iov_ctl & PCIM_SRIOV_VF_EN), + check_enabled(iov_ctl & PCIM_SRIOV_VF_MSE), + check_enabled(iov_ctl & PCIM_SRIOV_ARI_EN)); + + total_vfs = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_TOTAL_VFS, 2); + num_vfs = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_NUM_VFS, 2); + printf(" "); + printf("%d VFs configured out of %d supported\n", num_vfs, total_vfs); + + vf_offset = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_VF_OFF, 2); + vf_stride = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_VF_STRIDE, 2); + printf(" "); + printf("First VF RID Offset 0x%04x, VF RID Stride 0x%04x\n", vf_offset, + vf_stride); + + vf_did = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_VF_DID, 2); + printf(" VF Device ID 0x%04x\n", vf_did); + + page_caps = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_PAGE_CAP, 4); + page_size = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_PAGE_SIZE, 4); + printf(" "); + printf("Page Sizes: "); + comma = ""; + while (page_caps != 0) { + page_shift = ffs(page_caps) - 1; + + if (page_caps & page_size) + enabled = " (enabled)"; + else + enabled = ""; + + size = (1 << (page_shift + PCI_SRIOV_BASE_PAGE_SHIFT)); + printf("%s%d%s", comma, size, enabled); + comma = ", "; + + page_caps &= ~(1 << page_shift); + } + printf("\n"); + + for (i = 0; i <= PCIR_MAX_BAR_0; i++) + print_bar(fd, p, "iov bar ", ptr + PCIR_SRIOV_BAR(i)); } struct { @@ -704,7 +768,6 @@ struct { { PCIZ_ACS, "ACS" }, { PCIZ_ARI, "ARI" }, { PCIZ_ATS, "ATS" }, - { PCIZ_SRIOV, "SRIOV" }, { PCIZ_MULTICAST, "Multicast" }, { PCIZ_RESIZE_BAR, "Resizable BAR" }, { PCIZ_DPA, "DPA" }, @@ -743,6 +806,9 @@ list_ecaps(int fd, struct pci_conf *p) case PCIZ_SEC_PCIE: ecap_sec_pcie(fd, p, ptr, PCI_EXTCAP_VER(ecap)); break; + case PCIZ_SRIOV: + ecap_sriov(fd, p, ptr, PCI_EXTCAP_VER(ecap)); + break; default: name = "unknown"; for (i = 0; ecap_names[i].name != NULL; i++) @@ -750,10 +816,9 @@ list_ecaps(int fd, struct pci_conf *p) name = ecap_names[i].name; break; } - printf("%s %d", name, PCI_EXTCAP_VER(ecap)); + printf("%s %d\n", name, PCI_EXTCAP_VER(ecap)); break; } - printf("\n"); ptr = PCI_EXTCAP_NEXTPTR(ecap); if (ptr == 0) break; diff --git a/usr.sbin/pciconf/err.c b/usr.sbin/pciconf/err.c index b67d1f5..7a77903 100644 --- a/usr.sbin/pciconf/err.c +++ b/usr.sbin/pciconf/err.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Advanced Computing Technologies LLC + * Copyright (c) 2012 Hudson River Trading LLC * Written by: John H. Baldwin <jhb@FreeBSD.org> * All rights reserved. * diff --git a/usr.sbin/pciconf/pciconf.c b/usr.sbin/pciconf/pciconf.c index 22bb61d..31b3880 100644 --- a/usr.sbin/pciconf/pciconf.c +++ b/usr.sbin/pciconf/pciconf.c @@ -234,9 +234,9 @@ list_devs(const char *name, int verbose, int bars, int caps, int errors, for (p = conf; p < &conf[pc.num_matches]; p++) { printf("%s%d@pci%d:%d:%d:%d:\tclass=0x%06x card=0x%08x " "chip=0x%08x rev=0x%02x hdr=0x%02x\n", - (p->pd_name && *p->pd_name) ? p->pd_name : + *p->pd_name ? p->pd_name : "none", - (p->pd_name && *p->pd_name) ? (int)p->pd_unit : + *p->pd_name ? (int)p->pd_unit : none_count++, p->pc_sel.pc_domain, p->pc_sel.pc_bus, p->pc_sel.pc_dev, p->pc_sel.pc_func, (p->pc_class << 16) | @@ -263,10 +263,7 @@ list_devs(const char *name, int verbose, int bars, int caps, int errors, static void list_bars(int fd, struct pci_conf *p) { - struct pci_bar_io bar; - uint64_t base; - const char *type; - int i, range, max; + int i, max; switch (p->pc_hdr & PCIM_HDRTYPE) { case PCIM_HDRTYPE_NORMAL: @@ -282,40 +279,50 @@ list_bars(int fd, struct pci_conf *p) return; } - for (i = 0; i <= max; i++) { - bar.pbi_sel = p->pc_sel; - bar.pbi_reg = PCIR_BAR(i); - if (ioctl(fd, PCIOCGETBAR, &bar) < 0) - continue; - if (PCI_BAR_IO(bar.pbi_base)) { - type = "I/O Port"; + for (i = 0; i <= max; i++) + print_bar(fd, p, "bar ", PCIR_BAR(i)); +} + +void +print_bar(int fd, struct pci_conf *p, const char *label, uint16_t bar_offset) +{ + uint64_t base; + const char *type; + struct pci_bar_io bar; + int range; + + bar.pbi_sel = p->pc_sel; + bar.pbi_reg = bar_offset; + if (ioctl(fd, PCIOCGETBAR, &bar) < 0) + return; + if (PCI_BAR_IO(bar.pbi_base)) { + type = "I/O Port"; + range = 32; + base = bar.pbi_base & PCIM_BAR_IO_BASE; + } else { + if (bar.pbi_base & PCIM_BAR_MEM_PREFETCH) + type = "Prefetchable Memory"; + else + type = "Memory"; + switch (bar.pbi_base & PCIM_BAR_MEM_TYPE) { + case PCIM_BAR_MEM_32: range = 32; - base = bar.pbi_base & PCIM_BAR_IO_BASE; - } else { - if (bar.pbi_base & PCIM_BAR_MEM_PREFETCH) - type = "Prefetchable Memory"; - else - type = "Memory"; - switch (bar.pbi_base & PCIM_BAR_MEM_TYPE) { - case PCIM_BAR_MEM_32: - range = 32; - break; - case PCIM_BAR_MEM_1MB: - range = 20; - break; - case PCIM_BAR_MEM_64: - range = 64; - break; - default: - range = -1; - } - base = bar.pbi_base & ~((uint64_t)0xf); + break; + case PCIM_BAR_MEM_1MB: + range = 20; + break; + case PCIM_BAR_MEM_64: + range = 64; + break; + default: + range = -1; } - printf(" bar [%02x] = type %s, range %2d, base %#jx, ", - PCIR_BAR(i), type, range, (uintmax_t)base); - printf("size %ju, %s\n", (uintmax_t)bar.pbi_length, - bar.pbi_enabled ? "enabled" : "disabled"); + base = bar.pbi_base & ~((uint64_t)0xf); } + printf(" %s[%02x] = type %s, range %2d, base %#jx, ", + label, bar_offset, type, range, (uintmax_t)base); + printf("size %ju, %s\n", (uintmax_t)bar.pbi_length, + bar.pbi_enabled ? "enabled" : "disabled"); } static void diff --git a/usr.sbin/pciconf/pciconf.h b/usr.sbin/pciconf/pciconf.h index 042c4a1..734007e 100644 --- a/usr.sbin/pciconf/pciconf.h +++ b/usr.sbin/pciconf/pciconf.h @@ -37,6 +37,7 @@ void list_caps(int fd, struct pci_conf *p); void list_errors(int fd, struct pci_conf *p); uint8_t pci_find_cap(int fd, struct pci_conf *p, uint8_t id); uint16_t pcie_find_cap(int fd, struct pci_conf *p, uint16_t id); +void print_bar(int fd, struct pci_conf *p, const char *label, uint16_t bar); uint32_t read_config(int fd, struct pcisel *sel, long reg, int width); #endif diff --git a/usr.sbin/pkg/Makefile b/usr.sbin/pkg/Makefile index c372a3c..0884b6b 100644 --- a/usr.sbin/pkg/Makefile +++ b/usr.sbin/pkg/Makefile @@ -6,9 +6,6 @@ MAN= pkg.7 CFLAGS+=-I${.CURDIR}/../../contrib/libucl/include .PATH: ${.CURDIR}/../../contrib/libucl/include -DPADD= ${LIBARCHIVE} ${LIBFETCH} ${LIBUCL} ${LIBSBUF} ${LIBSSL} \ - ${LIBCRYPTO} ${LIBM} -LDADD= -larchive -lfetch ${LDUCL} -lsbuf -lssl -lcrypto -lm -USEPRIVATELIB= ucl +LIBADD= archive fetch ucl sbuf crypto .include <bsd.prog.mk> diff --git a/usr.sbin/pkg/Makefile.depend b/usr.sbin/pkg/Makefile.depend index b61c29c..d8f6d63 100644 --- a/usr.sbin/pkg/Makefile.depend +++ b/usr.sbin/pkg/Makefile.depend @@ -17,6 +17,7 @@ DIRDEPS = \ lib/libfetch \ lib/liblzma \ lib/libsbuf \ + lib/libthr \ lib/libucl \ lib/libz \ lib/msun \ diff --git a/usr.sbin/pkg/pkg.c b/usr.sbin/pkg/pkg.c index 8f26c61..5ae6c19 100644 --- a/usr.sbin/pkg/pkg.c +++ b/usr.sbin/pkg/pkg.c @@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$"); #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <time.h> #include <unistd.h> #include <ucl.h> @@ -177,14 +176,11 @@ fetch_to_fd(const char *url, char *path) /* To store _https._tcp. + hostname + \0 */ int fd; int retry, max_retry; - off_t done, r; - time_t now, last; + ssize_t r; char buf[10240]; char zone[MAXHOSTNAMELEN + 13]; static const char *mirror_type = NULL; - done = 0; - last = 0; max_retry = 3; current = mirrors = NULL; remote = NULL; @@ -202,7 +198,11 @@ fetch_to_fd(const char *url, char *path) retry = max_retry; - u = fetchParseURL(url); + if ((u = fetchParseURL(url)) == NULL) { + warn("fetchParseURL('%s')", url); + return (-1); + } + while (remote == NULL) { if (retry == max_retry) { if (strcmp(u->scheme, "file") != 0 && @@ -234,19 +234,16 @@ fetch_to_fd(const char *url, char *path) } } - while (done < st.size) { - if ((r = fread(buf, 1, sizeof(buf), remote)) < 1) - break; - + while ((r = fread(buf, 1, sizeof(buf), remote)) > 0) { if (write(fd, buf, r) != r) { warn("write()"); goto fetchfail; } + } - done += r; - now = time(NULL); - if (now > last || done == st.size) - last = now; + if (r != 0) { + warn("An error occurred while fetching pkg(8)"); + goto fetchfail; } if (ferror(remote)) @@ -371,8 +368,11 @@ load_fingerprints(const char *path, int *count) return (NULL); STAILQ_INIT(fingerprints); - if ((d = opendir(path)) == NULL) + if ((d = opendir(path)) == NULL) { + free(fingerprints); + return (NULL); + } while ((ent = readdir(d))) { if (strcmp(ent->d_name, ".") == 0 || @@ -799,8 +799,11 @@ cleanup: close(fd_sig); unlink(tmpsig); } - close(fd_pkg); - unlink(tmppkg); + + if (fd_pkg != -1) { + close(fd_pkg); + unlink(tmppkg); + } return (ret); } @@ -849,7 +852,7 @@ bootstrap_pkg_local(const char *pkgpath, bool force) if (config_string(SIGNATURE_TYPE, &signature_type) != 0) { warnx("Error looking up SIGNATURE_TYPE"); - return (-1); + goto cleanup; } if (signature_type != NULL && strcasecmp(signature_type, "FINGERPRINTS") == 0) { diff --git a/usr.sbin/pmccontrol/Makefile b/usr.sbin/pmccontrol/Makefile index 0f6dc76..1940b1f 100644 --- a/usr.sbin/pmccontrol/Makefile +++ b/usr.sbin/pmccontrol/Makefile @@ -5,8 +5,7 @@ PROG= pmccontrol MAN= pmccontrol.8 -DPADD= ${LIBPMC} -LDADD= -lpmc +LIBADD+= pmc SRCS= pmccontrol.c diff --git a/usr.sbin/pmccontrol/pmccontrol.c b/usr.sbin/pmccontrol/pmccontrol.c index b3585d0..c1e2acd 100644 --- a/usr.sbin/pmccontrol/pmccontrol.c +++ b/usr.sbin/pmccontrol/pmccontrol.c @@ -147,11 +147,9 @@ pmcc_do_enable_disable(struct pmcc_op_list *op_list) if (npmc == 0) errx(EX_CONFIG, "No PMCs found"); - if ((map = malloc(npmc * ncpu)) == NULL) + if ((map = calloc(npmc, ncpu)) == NULL) err(EX_SOFTWARE, "Out of memory"); - (void) memset(map, PMCC_OP_IGNORE, npmc*ncpu); - error = 0; STAILQ_FOREACH(np, op_list, op_next) { diff --git a/usr.sbin/pmcstat/Makefile b/usr.sbin/pmcstat/Makefile index 78cde44..dc5a30a 100644 --- a/usr.sbin/pmcstat/Makefile +++ b/usr.sbin/pmcstat/Makefile @@ -5,8 +5,7 @@ PROG= pmcstat MAN= pmcstat.8 -DPADD= ${LIBELF} ${LIBKVM} ${LIBPMC} ${LIBM} ${LIBNCURSESW} -LDADD= -lelf -lkvm -lpmc -lm -lncursesw +LIBADD= elf kvm pmc m ncursesw SRCS= pmcstat.c pmcstat.h pmcstat_log.c \ pmcpl_callgraph.c pmcpl_gprof.c pmcpl_annotate.c \ diff --git a/usr.sbin/pmcstat/pmcstat.8 b/usr.sbin/pmcstat/pmcstat.8 index d34cb6b..6478241 100644 --- a/usr.sbin/pmcstat/pmcstat.8 +++ b/usr.sbin/pmcstat/pmcstat.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Oct 27, 2014 +.Dd May 8, 2015 .Dt PMCSTAT 8 .Os .Sh NAME @@ -236,7 +236,7 @@ This option requires the .Fl R option to read in samples that were previously collected and saved with the -.Fl o +.Fl O option. .It Fl c Ar cpu-spec Set the cpus for subsequent system mode PMCs specified on the @@ -279,8 +279,9 @@ Set the pathname of the kernel directory to argument This directory specifies where .Nm should look for the kernel and its modules. -The default is -.Pa /boot/kernel . +The default is to use the path of the running kernel obtained from the +.Va kern.bootfile +sysctl. .It Fl l Ar secs Set system-wide performance measurement duration for .Ar secs @@ -301,6 +302,12 @@ is a this information is sent to the output file specified by the .Fl o option. +This option requires the +.Fl R +option to read in samples that were previously collected and +saved with the +.Fl O +option. .It Fl n Ar rate Set the default sampling rate for subsequent sampling mode PMCs specified on the command line. diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c index a045706..c7f36bc 100644 --- a/usr.sbin/pmcstat/pmcstat.c +++ b/usr.sbin/pmcstat/pmcstat.c @@ -557,7 +557,7 @@ main(int argc, char **argv) int c, check_driver_stats, current_sampling_count; int do_callchain, do_descendants, do_logproccsw, do_logprocexit; int do_print, do_read; - size_t dummy; + size_t len; int graphdepth; int pipefd[2], rfd; int use_cumulative_counts; @@ -586,7 +586,6 @@ main(int argc, char **argv) args.pa_verbosity = 1; args.pa_logfd = -1; args.pa_fsroot = ""; - args.pa_kernel = strdup("/boot/kernel"); args.pa_samplesdir = "."; args.pa_printfile = stderr; args.pa_graphdepth = DEFAULT_CALLGRAPH_DEPTH; @@ -610,12 +609,20 @@ main(int argc, char **argv) ev = NULL; CPU_ZERO(&cpumask); + /* Default to using the running system kernel. */ + len = 0; + if (sysctlbyname("kern.bootfile", NULL, &len, NULL, 0) == -1) + err(EX_OSERR, "ERROR: Cannot determine path of running kernel"); + args.pa_kernel = malloc(len + 1); + if (sysctlbyname("kern.bootfile", args.pa_kernel, &len, NULL, 0) == -1) + err(EX_OSERR, "ERROR: Cannot determine path of running kernel"); + /* * The initial CPU mask specifies all non-halted CPUS in the * system. */ - dummy = sizeof(int); - if (sysctlbyname("hw.ncpu", &ncpu, &dummy, NULL, 0) < 0) + len = sizeof(int); + if (sysctlbyname("hw.ncpu", &ncpu, &len, NULL, 0) < 0) err(EX_OSERR, "ERROR: Cannot determine the number of CPUs"); for (hcpu = 0; hcpu < ncpu; hcpu++) CPU_SET(hcpu, &cpumask); @@ -940,7 +947,7 @@ main(int argc, char **argv) errx(EX_USAGE, "ERROR: options -T and -l are mutually " "exclusive."); - /* -m option is allowed with -R only. */ + /* -a and -m require -R */ if (args.pa_flags & FLAG_DO_ANNOTATE && args.pa_inputpath == NULL) errx(EX_USAGE, "ERROR: option %s requires an input file", args.pa_plugin == PMCSTAT_PL_ANNOTATE ? "-m" : "-a"); @@ -1061,33 +1068,31 @@ main(int argc, char **argv) ); /* - * Check if "-k kerneldir" was specified, and if whether - * 'kerneldir' actually refers to a file. If so, use - * `dirname path` to determine the kernel directory. + * Check if 'kerneldir' refers to a file rather than a + * directory. If so, use `dirname path` to determine the + * kernel directory. */ - if (args.pa_flags & FLAG_HAS_KERNELPATH) { - (void) snprintf(buffer, sizeof(buffer), "%s%s", args.pa_fsroot, - args.pa_kernel); + (void) snprintf(buffer, sizeof(buffer), "%s%s", args.pa_fsroot, + args.pa_kernel); + if (stat(buffer, &sb) < 0) + err(EX_OSERR, "ERROR: Cannot locate kernel \"%s\"", + buffer); + if (!S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode)) + errx(EX_USAGE, "ERROR: \"%s\": Unsupported file type.", + buffer); + if (!S_ISDIR(sb.st_mode)) { + tmp = args.pa_kernel; + args.pa_kernel = strdup(dirname(args.pa_kernel)); + free(tmp); + (void) snprintf(buffer, sizeof(buffer), "%s%s", + args.pa_fsroot, args.pa_kernel); if (stat(buffer, &sb) < 0) - err(EX_OSERR, "ERROR: Cannot locate kernel \"%s\"", + err(EX_OSERR, "ERROR: Cannot stat \"%s\"", buffer); - if (!S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode)) - errx(EX_USAGE, "ERROR: \"%s\": Unsupported file type.", + if (!S_ISDIR(sb.st_mode)) + errx(EX_USAGE, + "ERROR: \"%s\" is not a directory.", buffer); - if (!S_ISDIR(sb.st_mode)) { - tmp = args.pa_kernel; - args.pa_kernel = strdup(dirname(args.pa_kernel)); - free(tmp); - (void) snprintf(buffer, sizeof(buffer), "%s%s", - args.pa_fsroot, args.pa_kernel); - if (stat(buffer, &sb) < 0) - err(EX_OSERR, "ERROR: Cannot stat \"%s\"", - buffer); - if (!S_ISDIR(sb.st_mode)) - errx(EX_USAGE, - "ERROR: \"%s\" is not a directory.", - buffer); - } } /* diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c index 40de320..fbc358d 100644 --- a/usr.sbin/pmcstat/pmcstat_log.c +++ b/usr.sbin/pmcstat/pmcstat_log.c @@ -716,7 +716,8 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image) ph.p_offset); break; case PT_LOAD: - if ((ph.p_offset & (-ph.p_align)) == 0) + if ((ph.p_flags & PF_X) != 0 && + (ph.p_offset & (-ph.p_align)) == 0) image->pi_vaddr = ph.p_vaddr & (-ph.p_align); break; } @@ -1531,7 +1532,9 @@ pmcstat_analyze_log(void) free(ppm); } - /* associate this process image */ + /* + * Associate this process image. + */ image_path = pmcstat_string_intern( ev.pl_u.pl_x.pl_pathname); assert(image_path != NULL); diff --git a/usr.sbin/pmcstudy/Makefile b/usr.sbin/pmcstudy/Makefile new file mode 100644 index 0000000..5ff3ba7 --- /dev/null +++ b/usr.sbin/pmcstudy/Makefile @@ -0,0 +1,12 @@ +# @(#)Makefile 8.1 (Berkeley) 6/9/93 +# $FreeBSD$ + +PROG= pmcstudy +MAN= pmcstudy.8 +SRCS= pmcstudy.c eval_expr.c +CFLAGS+= -Wall -Werror + +BINDIR= /usr/bin + +.include <bsd.prog.mk> + diff --git a/usr.sbin/pmcstudy/eval_expr.c b/usr.sbin/pmcstudy/eval_expr.c new file mode 100644 index 0000000..c225391 --- /dev/null +++ b/usr.sbin/pmcstudy/eval_expr.c @@ -0,0 +1,717 @@ +/*- + * Copyright (c) 2015 Netflix Inc. + * 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, + * in this position and unchanged. + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <strings.h> +#include <ctype.h> +#include "eval_expr.h" +__FBSDID("$FreeBSD$"); + +static struct expression * +alloc_and_hook_expr(struct expression **exp_p, struct expression **last_p) +{ + struct expression *ex, *at; + + ex = malloc(sizeof(struct expression)); + if (ex == NULL) { + printf("Out of memory in exp allocation\n"); + exit(-2); + } + memset(ex, 0, sizeof(struct expression)); + if (*exp_p == NULL) { + *exp_p = ex; + } + at = *last_p; + if (at == NULL) { + /* First one, its last */ + *last_p = ex; + } else { + /* Chain it to the end and update last */ + at->next = ex; + ex->prev = at; + *last_p = ex; + } + return (ex); +} + + +static int +validate_expr(struct expression *exp, int val1_is_set, int op_is_set, int val2_is_set, + int *op_cnt) +{ + int val1, op, val2; + int open_cnt; + val1 = op = val2 = 0; + if (val1_is_set) { + val1 = 1; + } + if (op_is_set) { + op = 1; + } + if (val2_is_set) { + val2 = 1; + } + open_cnt = *op_cnt; + if (exp == NULL) { + /* End of the road */ + if (val1 && op && val2 && (open_cnt == 0)) { + return(0); + } else { + return(1); + } + } + switch(exp->type) { + case TYPE_OP_PLUS: + case TYPE_OP_MINUS: + case TYPE_OP_MULT: + case TYPE_OP_DIVIDE: + if (val1 && op && val2) { + /* We are at x + y + + * collapse back to val/op + */ + val1 = 1; + op = 1; + val2 = 0; + } else if ((op == 0) && (val1)) { + op = 1; + } else { + printf("Op but no val1 set\n"); + return(-1); + } + break; + case TYPE_PARN_OPEN: + if (exp->next == NULL) { + printf("NULL after open paren\n"); + exit(-1); + } + if ((exp->next->type == TYPE_OP_PLUS) || + (exp->next->type == TYPE_OP_MINUS) || + (exp->next->type == TYPE_OP_DIVIDE) || + (exp->next->type == TYPE_OP_MULT)) { + printf("'( OP' -- not allowed\n"); + return(-1); + } + if (val1 && (op == 0)) { + printf("'Val (' -- not allowed\n"); + return(-1); + } + if (val1 && op && val2) { + printf("'Val OP Val (' -- not allowed\n"); + return(-1); + } + open_cnt++; + *op_cnt = open_cnt; + if (val1) { + if (validate_expr(exp->next, 0, 0, 0, op_cnt) == 0) { + val2 = 1; + } else { + return(-1); + } + } else { + return(validate_expr(exp->next, 0, 0, 0, op_cnt)); + } + break; + case TYPE_PARN_CLOSE: + open_cnt--; + *op_cnt = open_cnt; + if (val1 && op && val2) { + return(0); + } else { + printf("Found close paren and not complete\n"); + return(-1); + } + break; + case TYPE_VALUE_CON: + case TYPE_VALUE_PMC: + if (val1 == 0) { + val1 = 1; + } else if (val1 && op) { + val2 = 1; + } else { + printf("val1 set, val2 about to be set op empty\n"); + return(-1); + } + break; + default: + printf("unknown type %d\n", exp->type); + exit(-5); + break; + } + return(validate_expr(exp->next, val1, op, val2, op_cnt)); +} + +void +print_exp(struct expression *exp) +{ + if (exp == NULL) { + printf("\n"); + return; + } + switch(exp->type) { + case TYPE_OP_PLUS: + printf(" + "); + break; + case TYPE_OP_MINUS: + printf(" - "); + break; + case TYPE_OP_MULT: + printf(" * "); + break; + case TYPE_OP_DIVIDE: + printf(" / "); + break; + case TYPE_PARN_OPEN: + printf(" ( "); + break; + case TYPE_PARN_CLOSE: + printf(" ) "); + break; + case TYPE_VALUE_CON: + printf("%f", exp->value); + break; + case TYPE_VALUE_PMC: + printf("%s", exp->name); + break; + default: + printf("Unknown op %d\n", exp->type); + break; + } + print_exp(exp->next); +} + +static void +walk_back_and_insert_paren(struct expression **beg, struct expression *frm) +{ + struct expression *at, *ex; + + /* Setup our new open paren */ + ex = malloc(sizeof(struct expression)); + if (ex == NULL) { + printf("Out of memory in exp allocation\n"); + exit(-2); + } + memset(ex, 0, sizeof(struct expression)); + ex->type = TYPE_PARN_OPEN; + /* Now lets place it */ + at = frm->prev; + if (at == *beg) { + /* We are inserting at the head of the list */ + in_beg: + ex->next = at; + at->prev = ex; + *beg = ex; + return; + } else if ((at->type == TYPE_VALUE_CON) || + (at->type == TYPE_VALUE_PMC)) { + /* Simple case we have a value in the previous position */ + in_mid: + ex->prev = at->prev; + ex->prev->next = ex; + ex->next = at; + at->prev = ex; + return; + } else if (at->type == TYPE_PARN_CLOSE) { + /* Skip through until we reach beg or all ( closes */ + int par_cnt=1; + + at = at->prev; + while(par_cnt) { + if (at->type == TYPE_PARN_CLOSE) { + par_cnt++; + } else if (at->type == TYPE_PARN_OPEN) { + par_cnt--; + if (par_cnt == 0) { + break; + } + } + at = at->prev; + } + if (at == *beg) { + /* At beginning we insert */ + goto in_beg; + } else { + goto in_mid; + } + } else { + printf("%s:Unexpected type:%d?\n", + __FUNCTION__, at->type); + exit(-1); + } +} + +static void +walk_fwd_and_insert_paren(struct expression *frm, struct expression **added) +{ + struct expression *at, *ex; + /* Setup our new close paren */ + ex = malloc(sizeof(struct expression)); + if (ex == NULL) { + printf("Out of memory in exp allocation\n"); + exit(-2); + } + memset(ex, 0, sizeof(struct expression)); + ex->type = TYPE_PARN_CLOSE; + *added = ex; + /* Now lets place it */ + at = frm->next; + if ((at->type == TYPE_VALUE_CON) || + (at->type == TYPE_VALUE_PMC)) { + /* Simple case we have a value in the previous position */ + insertit: + ex->next = at->next; + ex->prev = at; + at->next = ex; + return; + } else if (at->type == TYPE_PARN_OPEN) { + int par_cnt=1; + at = at->next; + while(par_cnt) { + if (at->type == TYPE_PARN_OPEN) { + par_cnt++; + } else if (at->type == TYPE_PARN_CLOSE) { + par_cnt--; + if (par_cnt == 0) { + break; + } + } + at = at->next; + } + goto insertit; + } else { + printf("%s:Unexpected type:%d?\n", + __FUNCTION__, + at->type); + exit(-1); + } +} + + +static void +add_precendence(struct expression **beg, struct expression *start, struct expression *end) +{ + /* + * Between start and end add () around any * or /. This + * is quite tricky since if there is a () set inside the + * list we need to skip over everything in the ()'s considering + * that just a value. + */ + struct expression *at, *newone; + int open_cnt; + + at = start; + open_cnt = 0; + while(at != end) { + if (at->type == TYPE_PARN_OPEN) { + open_cnt++; + } + if (at->type == TYPE_PARN_CLOSE) { + open_cnt--; + } + if (open_cnt == 0) { + if ((at->type == TYPE_OP_MULT) || + (at->type == TYPE_OP_DIVIDE)) { + walk_back_and_insert_paren(beg, at); + walk_fwd_and_insert_paren(at, &newone); + at = newone->next; + continue; + } + } + at = at->next; + } + +} + +static void +set_math_precidence(struct expression **beg, struct expression *exp, struct expression **stopped) +{ + struct expression *at, *start, *end; + int cnt_lower, cnt_upper; + /* + * Walk through and set any math precedence to + * get proper precedence we insert () around * / over + - + */ + end = NULL; + start = at = exp; + cnt_lower = cnt_upper = 0; + while(at) { + if (at->type == TYPE_PARN_CLOSE) { + /* Done with that paren */ + if (stopped) { + *stopped = at; + } + if (cnt_lower && cnt_upper) { + /* We have a mixed set ... add precedence between start/end */ + add_precendence(beg, start, end); + } + return; + } + if (at->type == TYPE_PARN_OPEN) { + set_math_precidence(beg, at->next, &end); + at = end; + continue; + } else if ((at->type == TYPE_OP_PLUS) || + (at->type == TYPE_OP_MINUS)) { + cnt_lower++; + } else if ((at->type == TYPE_OP_DIVIDE) || + (at->type == TYPE_OP_MULT)) { + cnt_upper++; + } + at = at->next; + } + if (cnt_lower && cnt_upper) { + add_precendence(beg, start, NULL); + } +} + +extern char **valid_pmcs; +extern int valid_pmc_cnt; + +static void +pmc_name_set(struct expression *at) +{ + int i, idx, fnd; + + if (at->name[0] == '%') { + /* Special number after $ gives index */ + idx = strtol(&at->name[1], NULL, 0); + if (idx >= valid_pmc_cnt) { + printf("Unknown PMC %s -- largest we have is $%d -- can't run your expression\n", + at->name, valid_pmc_cnt); + exit(-1); + } + strcpy(at->name, valid_pmcs[idx]); + } else { + for(i=0, fnd=0; i<valid_pmc_cnt; i++) { + if (strcmp(valid_pmcs[i], at->name) == 0) { + fnd = 1; + break; + } + } + if (!fnd) { + printf("PMC %s does not exist on this machine -- can't run your expression\n", + at->name); + exit(-1); + } + } +} + +struct expression * +parse_expression(char *str) +{ + struct expression *exp=NULL, *last=NULL, *at; + int open_par, close_par; + int op_cnt=0; + size_t siz, i, x; + /* + * Walk through a string expression and convert + * it to a linked list of actions. We do this by: + * a) Counting the open/close paren's, there must + * be a matching number. + * b) If we have balanced paren's then create a linked list + * of the operators, then we validate that expression further. + * c) Validating that we have: + * val OP val <or> + * val OP ( <and> + * inside every paran you have a: + * val OP val <or> + * val OP ( <recursively> + * d) A final optional step (not implemented yet) would be + * to insert the mathimatical precedence paran's. For + * the start we will just do the left to right evaluation and + * then later we can add this guy to add paran's to make it + * mathimatically correct... i.e instead of 1 + 2 * 3 we + * would translate it into 1 + ( 2 * 3). + */ + open_par = close_par = 0; + siz = strlen(str); + /* No trailing newline please */ + if (str[(siz-1)] == '\n') { + str[(siz-1)] = 0; + siz--; + } + for(i=0; i<siz; i++) { + if (str[i] == '(') { + open_par++; + } else if (str[i] == ')') { + close_par++; + } + } + if (open_par != close_par) { + printf("Invalid expression '%s' %d open paren's and %d close?\n", + str, open_par, close_par); + exit(-1); + } + for(i=0; i<siz; i++) { + if (str[i] == '(') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_PARN_OPEN; + } else if (str[i] == ')') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_PARN_CLOSE; + } else if (str[i] == ' ') { + /* Extra blank */ + continue; + } else if (str[i] == '\t') { + /* Extra tab */ + continue; + } else if (str[i] == '+') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_OP_PLUS; + } else if (str[i] == '-') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_OP_MINUS; + } else if (str[i] == '/') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_OP_DIVIDE; + } else if (str[i] == '*') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_OP_MULT; + } else { + /* Its a value or PMC constant */ + at = alloc_and_hook_expr(&exp, &last); + if (isdigit(str[i]) || (str[i] == '.')) { + at->type = TYPE_VALUE_CON; + } else { + at->type = TYPE_VALUE_PMC; + } + x = 0; + while ((str[i] != ' ') && + (str[i] != '\t') && + (str[i] != 0) && + (str[i] != ')') && + (str[i] != '(')) { + /* We collect the constant until a space or tab */ + at->name[x] = str[i]; + i++; + x++; + if (x >=(sizeof(at->name)-1)) { + printf("Value/Constant too long %d max:%d\n", + (int)x, (int)(sizeof(at->name)-1)); + exit(-3); + } + } + if (str[i] != 0) { + /* Need to back up and see the last char since + * the for will increment the loop. + */ + i--; + } + /* Now we have pulled the string, set it up */ + if (at->type == TYPE_VALUE_CON) { + at->state = STATE_FILLED; + at->value = strtod(at->name, NULL); + } else { + pmc_name_set(at); + } + } + } + /* Now lets validate its a workable expression */ + if (validate_expr(exp, 0, 0, 0, &op_cnt)) { + printf("Invalid expression\n"); + exit(-4); + } + set_math_precidence(&exp, exp, NULL); + return (exp); +} + + + +static struct expression * +gather_exp_to_paren_close(struct expression *exp, double *val_fill) +{ + /* + * I have been given ( ??? + * so I could see either + * ( + * or + * Val Op + * + */ + struct expression *lastproc; + double val; + + if (exp->type == TYPE_PARN_OPEN) { + lastproc = gather_exp_to_paren_close(exp->next, &val); + *val_fill = val; + } else { + *val_fill = run_expr(exp, 0, &lastproc); + } + return(lastproc); +} + + +double +run_expr(struct expression *exp, int initial_call, struct expression **lastone) +{ + /* + * We expect to find either + * a) A Open Paren + * or + * b) Val-> Op -> Val + * or + * c) Val-> Op -> Open Paren + */ + double val1, val2, res; + struct expression *op, *other_half, *rest; + + if (exp->type == TYPE_PARN_OPEN) { + op = gather_exp_to_paren_close(exp->next, &val1); + } else if(exp->type == TYPE_VALUE_CON) { + val1 = exp->value; + op = exp->next; + } else if (exp->type == TYPE_VALUE_PMC) { + val1 = exp->value; + op = exp->next; + } else { + printf("Illegal value in %s huh?\n", __FUNCTION__); + exit(-1); + } + if (op == NULL) { + return (val1); + } +more_to_do: + other_half = op->next; + if (other_half->type == TYPE_PARN_OPEN) { + rest = gather_exp_to_paren_close(other_half->next, &val2); + } else if(other_half->type == TYPE_VALUE_CON) { + val2 = other_half->value; + rest = other_half->next; + } else if (other_half->type == TYPE_VALUE_PMC) { + val2 = other_half->value; + rest = other_half->next; + } else { + printf("Illegal2 value in %s huh?\n", __FUNCTION__); + exit(-1); + } + switch(op->type) { + case TYPE_OP_PLUS: + res = val1 + val2; + break; + case TYPE_OP_MINUS: + res = val1 - val2; + break; + case TYPE_OP_MULT: + res = val1 * val2; + break; + case TYPE_OP_DIVIDE: + if (val2 != 0.0) + res = val1 / val2; + else { + printf("Division by zero averted\n"); + res = 1.0; + } + break; + default: + printf("Op is not an operator -- its %d\n", + op->type); + exit(-1); + break; + } + if (rest == NULL) { + if (lastone) { + *lastone = NULL; + } + return (res); + } + if ((rest->type == TYPE_PARN_CLOSE) && (initial_call == 0)) { + if (lastone) { + *lastone = rest->next; + } + return(res); + } + /* There is more, as in + * a + b + c + * where we just did a + b + * so now it becomes val1 is set to res and + * we need to proceed with the rest of it. + */ + val1 = res; + op = rest; + if ((op->type != TYPE_OP_PLUS) && + (op->type != TYPE_OP_MULT) && + (op->type != TYPE_OP_MINUS) && + (op->type != TYPE_OP_DIVIDE)) { + printf("%s ending on type:%d not an op??\n", __FUNCTION__, op->type); + return(res); + } + if (op) + goto more_to_do; + return (res); +} + +#ifdef STAND_ALONE_TESTING + +static double +calc_expr(struct expression *exp) +{ + struct expression *at; + double xx; + + /* First clear PMC's setting */ + for(at = exp; at != NULL; at = at->next) { + if (at->type == TYPE_VALUE_PMC) { + at->state = STATE_UNSET; + } + } + /* Now for all pmc's make up values .. here is where I would pull them */ + for(at = exp; at != NULL; at = at->next) { + if (at->type == TYPE_VALUE_PMC) { + at->value = (random() * 1.0); + at->state = STATE_FILLED; + if (at->value == 0.0) { + /* So we don't have div by 0 */ + at->value = 1.0; + } + } + } + /* Now lets calculate the expression */ + print_exp(exp); + xx = run_expr(exp, 1, NULL); + printf("Answer is %f\n", xx); + return(xx); +} + + +int +main(int argc, char **argv) +{ + struct expression *exp; + if (argc < 2) { + printf("Use %s expression\n", argv[0]); + return(-1); + } + exp = parse_expression(argv[1]); + printf("Now the calc\n"); + calc_expr(exp); + return(0); +} + +#endif diff --git a/usr.sbin/pmcstudy/eval_expr.h b/usr.sbin/pmcstudy/eval_expr.h new file mode 100644 index 0000000..f095513 --- /dev/null +++ b/usr.sbin/pmcstudy/eval_expr.h @@ -0,0 +1,58 @@ +#ifndef __eval_expr_h__ +#define __eval_expr_h__ +/*- + * Copyright (c) 2015 Netflix Inc. + * 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, + * in this position and unchanged. + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ +__FBSDID("$FreeBSD$"); + +enum exptype { + TYPE_OP_PLUS, + TYPE_OP_MINUS, + TYPE_OP_MULT, + TYPE_OP_DIVIDE, + TYPE_PARN_OPEN, + TYPE_PARN_CLOSE, + TYPE_VALUE_CON, + TYPE_VALUE_PMC +}; + +#define STATE_UNSET 0 /* We have no setting yet in value */ +#define STATE_FILLED 1 /* We have filled in value */ + +struct expression { + struct expression *next; /* Next in expression. */ + struct expression *prev; /* Prev in expression. */ + double value; /* If there is a value to set */ + enum exptype type; /* What is it */ + uint8_t state; /* Current state if value type */ + char name[252]; /* If a PMC whats the name, con value*/ +}; + +struct expression *parse_expression(char *str); +double run_expr(struct expression *exp, int initial_call, struct expression **lastone); +void print_exp(struct expression *exp); +#endif diff --git a/usr.sbin/pmcstudy/pmcstudy.8 b/usr.sbin/pmcstudy/pmcstudy.8 new file mode 100644 index 0000000..4ddb3e4 --- /dev/null +++ b/usr.sbin/pmcstudy/pmcstudy.8 @@ -0,0 +1,143 @@ +.\" Copyright (c) 2015 +.\" Netflix Inc. +.\" +.\" 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 REGENTS 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 REGENTS 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. +.\" +.\" $FreeBSD$ +.\" +.Dd Mar 26, 2015 +.Dt PMCSTUDY 8 +.Os +.Sh NAME +.Nm pmcstudy +.Nd Perform various studies on a system's overall PMCs. +.Sh SYNOPSIS +.Nm +.Oo Fl i Ar inputfile | Fl T | Fl v | Fl m Ar max | Fl e exp | Fl Ar E | Fl h | fl H Oc +.Nm +.Fl i Ar inputfile +.Nm +.Fl v +.Nm +.Fl m Ar max +.Nm +.Fl e Ar exp-name +.Nm +.Fl E Ar your-expr +.Nm +.Fl h +.Nm +.Fl H +.Nm +.Fl T +.Sh DESCRIPTION +The +.Nm +program is designed to run various tests against your systems +performance. +There are roughly 20-22 canned tests that setup specific +PMCs and then run various formulas on the output information. +These formulas can be found in Intel documentation "Using Intel Vtune +amplifier xe on NNN Generation Intel Core Processors". +The NNN is either +2nd, 3rd or 4th generation i.e., Sandy Bridge, Ivy Bridge and Haswell. +Currently the program only works on these three Intel processor types. +.Sh OPTIONS +The following options are available: +.Bl -tag -width indent +.It Fl i Ar filename +If this option is supplied, instead of running a +.Xr pmcstat 8 +command to collect the current running information the filename will be read +in as input instead. +.It Fl H +This option will display the complete list of canned formulas that can be run including +their names which can be input to the +.Fl e +option. +.It Fl e Ar name +Execute the canned test +.Ar name +on the running kernel. +.It Fl h +If you add this option to the +.Fl e +option the test will not execute but instead give you a small description +of the test that would run. +.It Fl T +This option will execute a test of every PMC to validate that they are working +on your system. +If a PMC does not show up in this test chances +are the kernel +.Xr hwpmc 4 +driver needs updating with new PMC information. +.It Fl m Ar num +This option can restrict the number of one second samples that will +be collected by your system when running a test (it bounds the +time the test will run). +Without this option the test will run +for 1024 seconds or until the user types ctrl-c. +.It Fl v +The verbose option adds debugging output to the command. +.It Fl E Ar expression +This option can be used by those that have their own ideas +on what formulas they want to run. +The expression given to the +.Fl E +option is a "formula". +The formula can declare directly the PMCs by name +or you can use an abbreviation %NNN. +To find out the abbreviations +on your system you may run the +.Fl L +option. +An example of a formula of your own might be +.Fl E +"FP_ASSIST.ANY / INST_RETIRED.ANY_P" or using the abbreviations on a +Haswell machine you would type +.Fl E +" %176 / %150". +You must have spaces between each entry and +you may use parentheses to prioritize the operators. +Add (+), Subtract (-), +Divide (/) and Multiplication (*) are supported. +You may also introduce +constant numbers. +For example you can do a standard efficency +test like +.Fl E +"UOPS_RETIRED.RETIRE_SLOTS / (4 * CPU_CLK_UNHALTED.THREAD_P)". +.It Fl L +This option will list all known PMCs and their abbreviation (%NNN). +.El +.Sh SEE ALSO +.Xr pmc 3 , +.Xr pmclog 3 , +.Xr hwpmc 4 , +.Xr pmcstat 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 11.0. +.Sh AUTHORS +.An Randall Stewart Aq Mt rrs@FreeBSD.org diff --git a/usr.sbin/pmcstudy/pmcstudy.c b/usr.sbin/pmcstudy/pmcstudy.c new file mode 100644 index 0000000..1a3da45 --- /dev/null +++ b/usr.sbin/pmcstudy/pmcstudy.c @@ -0,0 +1,2438 @@ +/*- + * Copyright (c) 2014, 2015 Netflix Inc. + * 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, + * in this position and unchanged. + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <strings.h> +#include <sys/errno.h> +#include <signal.h> +#include <sys/wait.h> +#include <getopt.h> +#include "eval_expr.h" +__FBSDID("$FreeBSD$"); + +#define MAX_COUNTER_SLOTS 1024 +#define MAX_NLEN 64 +#define MAX_CPU 64 +static int verbose = 0; + +extern char **environ; +extern struct expression *master_exp; +struct expression *master_exp=NULL; + +#define PMC_INITIAL_ALLOC 512 +extern char **valid_pmcs; +char **valid_pmcs = NULL; +extern int valid_pmc_cnt; +int valid_pmc_cnt=0; +extern int pmc_allocated_cnt; +int pmc_allocated_cnt=0; + +/* + * The following two varients on popen and pclose with + * the cavet that they get you the PID so that you + * can supply it to pclose so it can send a SIGTERM + * to the process. + */ +static FILE * +my_popen(const char *command, const char *dir, pid_t *p_pid) +{ + FILE *io_out, *io_in; + int pdesin[2], pdesout[2]; + char *argv[4]; + pid_t pid; + char cmd[4]; + char cmd2[1024]; + char arg1[4]; + + if ((strcmp(dir, "r") != 0) && + (strcmp(dir, "w") != 0)) { + errno = EINVAL; + return(NULL); + } + if (pipe(pdesin) < 0) + return (NULL); + + if (pipe(pdesout) < 0) { + (void)close(pdesin[0]); + (void)close(pdesin[1]); + return (NULL); + } + strcpy(cmd, "sh"); + strcpy(arg1, "-c"); + strcpy(cmd2, command); + argv[0] = cmd; + argv[1] = arg1; + argv[2] = cmd2; + argv[3] = NULL; + + switch (pid = fork()) { + case -1: /* Error. */ + (void)close(pdesin[0]); + (void)close(pdesin[1]); + (void)close(pdesout[0]); + (void)close(pdesout[1]); + return (NULL); + /* NOTREACHED */ + case 0: /* Child. */ + /* Close out un-used sides */ + (void)close(pdesin[1]); + (void)close(pdesout[0]); + /* Now prepare the stdin of the process */ + close(0); + (void)dup(pdesin[0]); + (void)close(pdesin[0]); + /* Now prepare the stdout of the process */ + close(1); + (void)dup(pdesout[1]); + /* And lets do stderr just in case */ + close(2); + (void)dup(pdesout[1]); + (void)close(pdesout[1]); + /* Now run it */ + execve("/bin/sh", argv, environ); + exit(127); + /* NOTREACHED */ + } + /* Parent; assume fdopen can't fail. */ + /* Store the pid */ + *p_pid = pid; + if (strcmp(dir, "r") != 0) { + io_out = fdopen(pdesin[1], "w"); + (void)close(pdesin[0]); + (void)close(pdesout[0]); + (void)close(pdesout[1]); + return(io_out); + } else { + /* Prepare the input stream */ + io_in = fdopen(pdesout[0], "r"); + (void)close(pdesout[1]); + (void)close(pdesin[0]); + (void)close(pdesin[1]); + return (io_in); + } +} + +/* + * pclose -- + * Pclose returns -1 if stream is not associated with a `popened' command, + * if already `pclosed', or waitpid returns an error. + */ +static void +my_pclose(FILE *io, pid_t the_pid) +{ + int pstat; + pid_t pid; + + /* + * Find the appropriate file pointer and remove it from the list. + */ + (void)fclose(io); + /* Die if you are not dead! */ + kill(the_pid, SIGTERM); + do { + pid = wait4(the_pid, &pstat, 0, (struct rusage *)0); + } while (pid == -1 && errno == EINTR); +} + +struct counters { + struct counters *next_cpu; + char counter_name[MAX_NLEN]; /* Name of counter */ + int cpu; /* CPU we are on */ + int pos; /* Index we are filling to. */ + uint64_t vals[MAX_COUNTER_SLOTS]; /* Last 64 entries */ + uint64_t sum; /* Summary of entries */ +}; + +extern struct counters *glob_cpu[MAX_CPU]; +struct counters *glob_cpu[MAX_CPU]; + +extern struct counters *cnts; +struct counters *cnts=NULL; + +extern int ncnts; +int ncnts=0; + +extern int (*expression)(struct counters *, int); +int (*expression)(struct counters *, int); + +static const char *threshold=NULL; +static const char *command; + +struct cpu_entry { + const char *name; + const char *thresh; + const char *command; + int (*func)(struct counters *, int); +}; + + +struct cpu_type { + char cputype[32]; + int number; + struct cpu_entry *ents; + void (*explain)(const char *name); +}; +extern struct cpu_type the_cpu; +struct cpu_type the_cpu; + +static void +explain_name_sb(const char *name) +{ + const char *mythresh; + if (strcmp(name, "allocstall1") == 0) { + printf("Examine PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "allocstall2") == 0) { + printf("Examine PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP_CYCLES/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "br_miss") == 0) { + printf("Examine (20 * BR_MISP_RETIRED.ALL_BRANCHES)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "splitload") == 0) { + printf("Examine MEM_UOP_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "splitstore") == 0) { + printf("Examine MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES\n"); + mythresh = "thresh >= .01"; + } else if (strcmp(name, "contested") == 0) { + printf("Examine (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "blockstorefwd") == 0) { + printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "cache2") == 0) { + printf("Examine ((MEM_LOAD_RETIRED.L3_HIT * 26) + \n"); + printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 43) + \n"); + printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60)) / CPU_CLK_UNHALTED.THREAD_P\n"); + printf("**Note we have it labeled MEM_LOAD_UOPS_RETIRED.LLC_HIT not MEM_LOAD_RETIRED.L3_HIT\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "cache1") == 0) { + printf("Examine (MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS * 180) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "dtlbmissload") == 0) { + printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "frontendstall") == 0) { + printf("Examine IDQ_UOPS_NOT_DELIVERED.CORE / (CPU_CLK_UNHALTED.THREAD_P * 4)\n"); + mythresh = "thresh >= .15"; + } else if (strcmp(name, "clears") == 0) { + printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n"); + printf(" MACHINE_CLEARS.SMC + \n"); + printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .02"; + } else if (strcmp(name, "microassist") == 0) { + printf("Examine IDQ.MS_CYCLES / (CPU_CLK_UNHALTED.THREAD_P * 4)\n"); + printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "aliasing_4k") == 0) { + printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "fpassist") == 0) { + printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistavx") == 0) { + printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistsse") == 0) { + printf("Examine (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "eff1") == 0) { + printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh < .9"; + } else if (strcmp(name, "eff2") == 0) { + printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n"); + mythresh = "thresh > 1.0"; + } else if (strcmp(name, "dtlbmissstore") == 0) { + printf("Examine (((DTLB_STORE_MISSES.STLB_HIT * 7) + DTLB_STORE_MISSES.WALK_DURATION)\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh >= .05"; + } else { + printf("Unknown name:%s\n", name); + mythresh = "unknown entry"; + } + printf("If the value printed is %s we may have the ability to improve performance\n", mythresh); +} + +static void +explain_name_ib(const char *name) +{ + const char *mythresh; + if (strcmp(name, "br_miss") == 0) { + printf("Examine ((BR_MISP_RETIRED.ALL_BRANCHES /(BR_MISP_RETIRED.ALL_BRANCHES +\n"); + printf(" MACHINE_CLEAR.COUNT) * ((UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES)\n"); + printf("/ (4 * CPU_CLK_UNHALTED.THREAD))))\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "eff1") == 0) { + printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh < .9"; + } else if (strcmp(name, "eff2") == 0) { + printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n"); + mythresh = "thresh > 1.0"; + } else if (strcmp(name, "cache1") == 0) { + printf("Examine (MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "cache2") == 0) { + printf("Examine (MEM_LOAD_UOPS_RETIRED.LLC_HIT / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "itlbmiss") == 0) { + printf("Examine ITLB_MISSES.WALK_DURATION / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "icachemiss") == 0) { + printf("Examine (ICACHE.IFETCH_STALL - ITLB_MISSES.WALK_DURATION)/ CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "lcpstall") == 0) { + printf("Examine ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "datashare") == 0) { + printf("Examine (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 43)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "blockstorefwd") == 0) { + printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "splitload") == 0) { + printf("Examine ((L1D_PEND_MISS.PENDING / MEM_LOAD_UOPS_RETIRED.L1_MISS) *\n"); + printf(" LD_BLOCKS.NO_SR)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "splitstore") == 0) { + printf("Examine MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES\n"); + mythresh = "thresh >= .01"; + } else if (strcmp(name, "aliasing_4k") == 0) { + printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "dtlbmissload") == 0) { + printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "dtlbmissstore") == 0) { + printf("Examine (((DTLB_STORE_MISSES.STLB_HIT * 7) + DTLB_STORE_MISSES.WALK_DURATION)\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "contested") == 0) { + printf("Examine (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "clears") == 0) { + printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n"); + printf(" MACHINE_CLEARS.SMC + \n"); + printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .02"; + } else if (strcmp(name, "microassist") == 0) { + printf("Examine IDQ.MS_CYCLES / (4 * CPU_CLK_UNHALTED.THREAD_P)\n"); + printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "fpassist") == 0) { + printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistavx") == 0) { + printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistsse") == 0) { + printf("Examine (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else { + printf("Unknown name:%s\n", name); + mythresh = "unknown entry"; + } + printf("If the value printed is %s we may have the ability to improve performance\n", mythresh); +} + + +static void +explain_name_has(const char *name) +{ + const char *mythresh; + if (strcmp(name, "eff1") == 0) { + printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh < .75"; + } else if (strcmp(name, "eff2") == 0) { + printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n"); + mythresh = "thresh > 1.0"; + } else if (strcmp(name, "itlbmiss") == 0) { + printf("Examine ITLB_MISSES.WALK_DURATION / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "icachemiss") == 0) { + printf("Examine (36 * ICACHE.MISSES)/ CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "lcpstall") == 0) { + printf("Examine ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "cache1") == 0) { + printf("Examine (MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "cache2") == 0) { + printf("Examine ((MEM_LOAD_UOPS_RETIRED.LLC_HIT * 36) + \n"); + printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 72) + \n"); + printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84))\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "contested") == 0) { + printf("Examine (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "datashare") == 0) { + printf("Examine (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 72)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "blockstorefwd") == 0) { + printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "splitload") == 0) { + printf("Examine (MEM_UOP_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "splitstore") == 0) { + printf("Examine MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES\n"); + mythresh = "thresh >= .01"; + } else if (strcmp(name, "aliasing_4k") == 0) { + printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "dtlbmissload") == 0) { + printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "br_miss") == 0) { + printf("Examine (20 * BR_MISP_RETIRED.ALL_BRANCHES)/CPU_CLK_UNHALTED.THREAD\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "clears") == 0) { + printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n"); + printf(" MACHINE_CLEARS.SMC + \n"); + printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .02"; + } else if (strcmp(name, "microassist") == 0) { + printf("Examine IDQ.MS_CYCLES / (4 * CPU_CLK_UNHALTED.THREAD_P)\n"); + printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "fpassist") == 0) { + printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistavx") == 0) { + printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistsse") == 0) { + printf("Examine (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else { + printf("Unknown name:%s\n", name); + mythresh = "unknown entry"; + } + printf("If the value printed is %s we may have the ability to improve performance\n", mythresh); +} + + +static struct counters * +find_counter(struct counters *base, const char *name) +{ + struct counters *at; + int len; + + at = base; + len = strlen(name); + while(at) { + if (strncmp(at->counter_name, name, len) == 0) { + return(at); + } + at = at->next_cpu; + } + printf("Can't find counter %s\n", name); + printf("We have:\n"); + at = base; + while(at) { + printf("- %s\n", at->counter_name); + at = at->next_cpu; + } + exit(-1); +} + +static int +allocstall1(struct counters *cpu, int pos) +{ +/* 1 - PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW/CPU_CLK_UNHALTED.THREAD_P (thresh > .05)*/ + int ret; + struct counters *partial; + struct counters *unhalt; + double un, par, res; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + partial = find_counter(cpu, "PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW"); + if (pos != -1) { + par = partial->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + par = partial->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = par/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +allocstall2(struct counters *cpu, int pos) +{ +/* 2 - PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP_CYCLES/CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */ + int ret; + struct counters *partial; + struct counters *unhalt; + double un, par, res; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + partial = find_counter(cpu, "PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP"); + if (pos != -1) { + par = partial->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + par = partial->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = par/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +br_mispredict(struct counters *cpu, int pos) +{ + struct counters *brctr; + struct counters *unhalt; + int ret; +/* 3 - (20 * BR_MISP_RETIRED.ALL_BRANCHES)/CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */ + double br, un, con, res; + con = 20.0; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + brctr = find_counter(cpu, "BR_MISP_RETIRED.ALL_BRANCHES"); + if (pos != -1) { + br = brctr->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + br = brctr->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (con * br)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +br_mispredictib(struct counters *cpu, int pos) +{ + struct counters *brctr; + struct counters *unhalt; + struct counters *clear, *clear2, *clear3; + struct counters *uops; + struct counters *recv; + struct counters *iss; +/* "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -s INT_MISC.RECOVERY_CYCLES -w 1",*/ + int ret; + /* + * (BR_MISP_RETIRED.ALL_BRANCHES / + * (BR_MISP_RETIRED.ALL_BRANCHES + + * MACHINE_CLEAR.COUNT) * + * ((UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES) / (4 * CPU_CLK_UNHALTED.THREAD))) + * + */ + double br, cl, cl2, cl3, uo, re, un, con, res, is; + con = 4.0; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + brctr = find_counter(cpu, "BR_MISP_RETIRED.ALL_BRANCHES"); + clear = find_counter(cpu, "MACHINE_CLEARS.MEMORY_ORDERING"); + clear2 = find_counter(cpu, "MACHINE_CLEARS.SMC"); + clear3 = find_counter(cpu, "MACHINE_CLEARS.MASKMOV"); + uops = find_counter(cpu, "UOPS_RETIRED.RETIRE_SLOTS"); + iss = find_counter(cpu, "UOPS_ISSUED.ANY"); + recv = find_counter(cpu, "INT_MISC.RECOVERY_CYCLES"); + if (pos != -1) { + br = brctr->vals[pos] * 1.0; + cl = clear->vals[pos] * 1.0; + cl2 = clear2->vals[pos] * 1.0; + cl3 = clear3->vals[pos] * 1.0; + uo = uops->vals[pos] * 1.0; + re = recv->vals[pos] * 1.0; + is = iss->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + br = brctr->sum * 1.0; + cl = clear->sum * 1.0; + cl2 = clear2->sum * 1.0; + cl3 = clear3->sum * 1.0; + uo = uops->sum * 1.0; + re = recv->sum * 1.0; + is = iss->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (br/(br + cl + cl2 + cl3) * ((is - uo + con * re) / (con * un))); + ret = printf("%1.3f", res); + return(ret); +} + +static int +splitloadib(struct counters *cpu, int pos) +{ + int ret; + struct counters *mem; + struct counters *l1d, *ldblock; + struct counters *unhalt; + double un, memd, res, l1, ldb; + /* + * ((L1D_PEND_MISS.PENDING / MEM_LOAD_UOPS_RETIRED.L1_MISS) * LD_BLOCKS.NO_SR) / CPU_CLK_UNHALTED.THREAD_P + * "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s L1D_PEND_MISS.PENDING -s MEM_LOAD_UOPS_RETIRED.L1_MISS -s LD_BLOCKS.NO_SR -w 1", + */ + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.L1_MISS"); + l1d = find_counter(cpu, "L1D_PEND_MISS.PENDING"); + ldblock = find_counter(cpu, "LD_BLOCKS.NO_SR"); + if (pos != -1) { + memd = mem->vals[pos] * 1.0; + l1 = l1d->vals[pos] * 1.0; + ldb = ldblock->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + memd = mem->sum * 1.0; + l1 = l1d->sum * 1.0; + ldb = ldblock->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((l1 / memd) * ldb)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +splitload(struct counters *cpu, int pos) +{ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, memd, res; +/* 4 - (MEM_UOP_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .1)*/ + + con = 5.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_UOP_RETIRED.SPLIT_LOADS"); + if (pos != -1) { + memd = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + memd = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (memd * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +splitstore(struct counters *cpu, int pos) +{ + /* 5 - MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES (thresh > 0.01) */ + int ret; + struct counters *mem_split; + struct counters *mem_stores; + double memsplit, memstore, res; + mem_split = find_counter(cpu, "MEM_UOP_RETIRED.SPLIT_STORES"); + mem_stores = find_counter(cpu, "MEM_UOP_RETIRED.ALL_STORES"); + if (pos != -1) { + memsplit = mem_split->vals[pos] * 1.0; + memstore = mem_stores->vals[pos] * 1.0; + } else { + memsplit = mem_split->sum * 1.0; + memstore = mem_stores->sum * 1.0; + } + res = memsplit/memstore; + ret = printf("%1.3f", res); + return(ret); +} + + +static int +contested(struct counters *cpu, int pos) +{ + /* 6 - (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60) / CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, memd, res; + + con = 60.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM"); + if (pos != -1) { + memd = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + memd = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (memd * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +contested_has(struct counters *cpu, int pos) +{ + /* 6 - (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84) / CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, memd, res; + + con = 84.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM"); + if (pos != -1) { + memd = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + memd = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (memd * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + + +static int +blockstoreforward(struct counters *cpu, int pos) +{ + /* 7 - (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .05)*/ + int ret; + struct counters *ldb; + struct counters *unhalt; + double con, un, ld, res; + + con = 13.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + ldb = find_counter(cpu, "LD_BLOCKS_STORE_FORWARD"); + if (pos != -1) { + ld = ldb->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ld = ldb->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (ld * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +cache2(struct counters *cpu, int pos) +{ + /* ** Suspect *** + * 8 - ((MEM_LOAD_RETIRED.L3_HIT * 26) + (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 43) + + * (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60)) / CPU_CLK_UNHALTED.THREAD_P (thresh >.2) + */ + int ret; + struct counters *mem1, *mem2, *mem3; + struct counters *unhalt; + double con1, con2, con3, un, me_1, me_2, me_3, res; + + con1 = 26.0; + con2 = 43.0; + con3 = 60.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); +/* Call for MEM_LOAD_RETIRED.L3_HIT possibly MEM_LOAD_UOPS_RETIRED.LLC_HIT ?*/ + mem1 = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.LLC_HIT"); + mem2 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT"); + mem3 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM"); + if (pos != -1) { + me_1 = mem1->vals[pos] * 1.0; + me_2 = mem2->vals[pos] * 1.0; + me_3 = mem3->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me_1 = mem1->sum * 1.0; + me_2 = mem2->sum * 1.0; + me_3 = mem3->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((me_1 * con1) + (me_2 * con2) + (me_3 * con3))/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +datasharing(struct counters *cpu, int pos) +{ + /* + * (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 43)/ CPU_CLK_UNHALTED.THREAD_P (thresh >.2) + */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, res, me, un; + + con = 43.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT"); + if (pos != -1) { + me = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (me * con)/un; + ret = printf("%1.3f", res); + return(ret); + +} + + +static int +datasharing_has(struct counters *cpu, int pos) +{ + /* + * (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 43)/ CPU_CLK_UNHALTED.THREAD_P (thresh >.2) + */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, res, me, un; + + con = 72.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT"); + if (pos != -1) { + me = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (me * con)/un; + ret = printf("%1.3f", res); + return(ret); + +} + + +static int +cache2ib(struct counters *cpu, int pos) +{ + /* + * (29 * MEM_LOAD_UOPS_RETIRED.LLC_HIT / CPU_CLK_UNHALTED.THREAD_P (thresh >.2) + */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, me, res; + + con = 29.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.LLC_HIT"); + if (pos != -1) { + me = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (con * me)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +cache2has(struct counters *cpu, int pos) +{ + /* + * Examine ((MEM_LOAD_UOPS_RETIRED.LLC_HIT * 36) + \ + * (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 72) + + * (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84)) + * / CPU_CLK_UNHALTED.THREAD_P + */ + int ret; + struct counters *mem1, *mem2, *mem3; + struct counters *unhalt; + double con1, con2, con3, un, me1, me2, me3, res; + + con1 = 36.0; + con2 = 72.0; + con3 = 84.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem1 = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.LLC_HIT"); + mem2 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT"); + mem3 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM"); + if (pos != -1) { + me1 = mem1->vals[pos] * 1.0; + me2 = mem2->vals[pos] * 1.0; + me3 = mem3->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me1 = mem1->sum * 1.0; + me2 = mem2->sum * 1.0; + me3 = mem3->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((me1 * con1) + (me2 * con2) + (me3 * con3))/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +cache1(struct counters *cpu, int pos) +{ + /* 9 - (MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS * 180) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, me, res; + + con = 180.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS"); + if (pos != -1) { + me = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (me * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +cache1ib(struct counters *cpu, int pos) +{ + /* 9 - (MEM_LOAD_UOPS_L3_MISS_RETIRED.LCOAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, me, res; + + con = 180.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM"); + if (pos != -1) { + me = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (me * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + + +static int +dtlb_missload(struct counters *cpu, int pos) +{ + /* 10 - ((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION) / CPU_CLK_UNHALTED.THREAD_P (t >=.1) */ + int ret; + struct counters *dtlb_m, *dtlb_d; + struct counters *unhalt; + double con, un, d1, d2, res; + + con = 7.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + dtlb_m = find_counter(cpu, "DTLB_LOAD_MISSES.STLB_HIT"); + dtlb_d = find_counter(cpu, "DTLB_LOAD_MISSES.WALK_DURATION"); + if (pos != -1) { + d1 = dtlb_m->vals[pos] * 1.0; + d2 = dtlb_d->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + d1 = dtlb_m->sum * 1.0; + d2 = dtlb_d->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((d1 * con) + d2)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +dtlb_missstore(struct counters *cpu, int pos) +{ + /* + * ((DTLB_STORE_MISSES.STLB_HIT * 7) + DTLB_STORE_MISSES.WALK_DURATION) / + * CPU_CLK_UNHALTED.THREAD_P (t >= .1) + */ + int ret; + struct counters *dtsb_m, *dtsb_d; + struct counters *unhalt; + double con, un, d1, d2, res; + + con = 7.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + dtsb_m = find_counter(cpu, "DTLB_STORE_MISSES.STLB_HIT"); + dtsb_d = find_counter(cpu, "DTLB_STORE_MISSES.WALK_DURATION"); + if (pos != -1) { + d1 = dtsb_m->vals[pos] * 1.0; + d2 = dtsb_d->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + d1 = dtsb_m->sum * 1.0; + d2 = dtsb_d->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((d1 * con) + d2)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +itlb_miss(struct counters *cpu, int pos) +{ + /* ITLB_MISSES.WALK_DURATION / CPU_CLK_UNTHREAD_P IB */ + int ret; + struct counters *itlb; + struct counters *unhalt; + double un, d1, res; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + itlb = find_counter(cpu, "ITLB_MISSES.WALK_DURATION"); + if (pos != -1) { + d1 = itlb->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + d1 = itlb->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = d1/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +icache_miss(struct counters *cpu, int pos) +{ + /* (ICACHE.IFETCH_STALL - ITLB_MISSES.WALK_DURATION) / CPU_CLK_UNHALTED.THREAD_P IB */ + + int ret; + struct counters *itlb, *icache; + struct counters *unhalt; + double un, d1, ic, res; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + itlb = find_counter(cpu, "ITLB_MISSES.WALK_DURATION"); + icache = find_counter(cpu, "ICACHE.IFETCH_STALL"); + if (pos != -1) { + d1 = itlb->vals[pos] * 1.0; + ic = icache->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + d1 = itlb->sum * 1.0; + ic = icache->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (ic-d1)/un; + ret = printf("%1.3f", res); + return(ret); + +} + +static int +icache_miss_has(struct counters *cpu, int pos) +{ + /* (36 * ICACHE.MISSES) / CPU_CLK_UNHALTED.THREAD_P */ + + int ret; + struct counters *icache; + struct counters *unhalt; + double un, con, ic, res; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + icache = find_counter(cpu, "ICACHE.MISSES"); + con = 36.0; + if (pos != -1) { + ic = icache->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ic = icache->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (con * ic)/un; + ret = printf("%1.3f", res); + return(ret); + +} + +static int +lcp_stall(struct counters *cpu, int pos) +{ + /* ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P IB */ + int ret; + struct counters *ild; + struct counters *unhalt; + double un, d1, res; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + ild = find_counter(cpu, "ILD_STALL.LCP"); + if (pos != -1) { + d1 = ild->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + d1 = ild->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = d1/un; + ret = printf("%1.3f", res); + return(ret); + +} + + +static int +frontendstall(struct counters *cpu, int pos) +{ + /* 12 - IDQ_UOPS_NOT_DELIVERED.CORE / (CPU_CLK_UNHALTED.THREAD_P * 4) (thresh >= .15) */ + int ret; + struct counters *idq; + struct counters *unhalt; + double con, un, id, res; + + con = 4.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + idq = find_counter(cpu, "IDQ_UOPS_NOT_DELIVERED.CORE"); + if (pos != -1) { + id = idq->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + id = idq->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = id/(un * con); + ret = printf("%1.3f", res); + return(ret); +} + +static int +clears(struct counters *cpu, int pos) +{ + /* 13 - ((MACHINE_CLEARS.MEMORY_ORDERING + MACHINE_CLEARS.SMC + MACHINE_CLEARS.MASKMOV ) * 100 ) + * / CPU_CLK_UNHALTED.THREAD_P (thresh >= .02)*/ + + int ret; + struct counters *clr1, *clr2, *clr3; + struct counters *unhalt; + double con, un, cl1, cl2, cl3, res; + + con = 100.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + clr1 = find_counter(cpu, "MACHINE_CLEARS.MEMORY_ORDERING"); + clr2 = find_counter(cpu, "MACHINE_CLEARS.SMC"); + clr3 = find_counter(cpu, "MACHINE_CLEARS.MASKMOV"); + + if (pos != -1) { + cl1 = clr1->vals[pos] * 1.0; + cl2 = clr2->vals[pos] * 1.0; + cl3 = clr3->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + cl1 = clr1->sum * 1.0; + cl2 = clr2->sum * 1.0; + cl3 = clr3->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((cl1 + cl2 + cl3) * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +microassist(struct counters *cpu, int pos) +{ + /* 14 - IDQ.MS_CYCLES / CPU_CLK_UNHALTED.THREAD_P (thresh > .05) */ + int ret; + struct counters *idq; + struct counters *unhalt; + double un, id, res, con; + + con = 4.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + idq = find_counter(cpu, "IDQ.MS_UOPS"); + if (pos != -1) { + id = idq->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + id = idq->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = id/(un * con); + ret = printf("%1.3f", res); + return(ret); +} + + +static int +aliasing(struct counters *cpu, int pos) +{ + /* 15 - (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh > .1) */ + int ret; + struct counters *ld; + struct counters *unhalt; + double un, lds, con, res; + + con = 5.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + ld = find_counter(cpu, "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS"); + if (pos != -1) { + lds = ld->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + lds = ld->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (lds * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +fpassists(struct counters *cpu, int pos) +{ + /* 16 - FP_ASSIST.ANY/INST_RETIRED.ANY_P */ + int ret; + struct counters *fp; + struct counters *inst; + double un, fpd, res; + + inst = find_counter(cpu, "INST_RETIRED.ANY_P"); + fp = find_counter(cpu, "FP_ASSIST.ANY"); + if (pos != -1) { + fpd = fp->vals[pos] * 1.0; + un = inst->vals[pos] * 1.0; + } else { + fpd = fp->sum * 1.0; + un = inst->sum * 1.0; + } + res = fpd/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +otherassistavx(struct counters *cpu, int pos) +{ + /* 17 - (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P thresh .1*/ + int ret; + struct counters *oth; + struct counters *unhalt; + double un, ot, con, res; + + con = 75.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + oth = find_counter(cpu, "OTHER_ASSISTS.AVX_TO_SSE"); + if (pos != -1) { + ot = oth->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ot = oth->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (ot * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +otherassistsse(struct counters *cpu, int pos) +{ + + int ret; + struct counters *oth; + struct counters *unhalt; + double un, ot, con, res; + + /* 18 (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P thresh .1*/ + con = 75.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + oth = find_counter(cpu, "OTHER_ASSISTS.SSE_TO_AVX"); + if (pos != -1) { + ot = oth->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ot = oth->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (ot * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +efficiency1(struct counters *cpu, int pos) +{ + + int ret; + struct counters *uops; + struct counters *unhalt; + double un, ot, con, res; + + /* 19 (UOPS_RETIRED.RETIRE_SLOTS/(4*CPU_CLK_UNHALTED.THREAD_P) look if thresh < .9*/ + con = 4.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + uops = find_counter(cpu, "UOPS_RETIRED.RETIRE_SLOTS"); + if (pos != -1) { + ot = uops->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ot = uops->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ot/(con * un); + ret = printf("%1.3f", res); + return(ret); +} + +static int +efficiency2(struct counters *cpu, int pos) +{ + + int ret; + struct counters *uops; + struct counters *unhalt; + double un, ot, res; + + /* 20 - CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P good if > 1. (comp factor)*/ + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + uops = find_counter(cpu, "INST_RETIRED.ANY_P"); + if (pos != -1) { + ot = uops->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ot = uops->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = un/ot; + ret = printf("%1.3f", res); + return(ret); +} + +#define SANDY_BRIDGE_COUNT 20 +static struct cpu_entry sandy_bridge[SANDY_BRIDGE_COUNT] = { +/*01*/ { "allocstall1", "thresh > .05", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW -w 1", + allocstall1 }, +/*02*/ { "allocstall2", "thresh > .05", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP_CYCLES -w 1", + allocstall2 }, +/*03*/ { "br_miss", "thresh >= .2", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -w 1", + br_mispredict }, +/*04*/ { "splitload", "thresh >= .1", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s MEM_UOP_RETIRED.SPLIT_LOADS -w 1", + splitload }, +/*05*/ { "splitstore", "thresh >= .01", + "pmcstat -s MEM_UOP_RETIRED.SPLIT_STORES -s MEM_UOP_RETIRED.ALL_STORES -w 1", + splitstore }, +/*06*/ { "contested", "thresh >= .05", + "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + contested }, +/*07*/ { "blockstorefwd", "thresh >= .05", + "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1", + blockstoreforward }, +/*08*/ { "cache2", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache2 }, +/*09*/ { "cache1", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache1 }, +/*10*/ { "dtlbmissload", "thresh >= .1", + "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + dtlb_missload }, +/*11*/ { "dtlbmissstore", "thresh >= .05", + "pmcstat -s DTLB_STORE_MISSES.STLB_HIT -s DTLB_STORE_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + dtlb_missstore }, +/*12*/ { "frontendstall", "thresh >= .15", + "pmcstat -s IDQ_UOPS_NOT_DELIVERED.CORE -s CPU_CLK_UNHALTED.THREAD_P -w 1", + frontendstall }, +/*13*/ { "clears", "thresh >= .02", + "pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1", + clears }, +/*14*/ { "microassist", "thresh >= .05", + "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1", + microassist }, +/*15*/ { "aliasing_4k", "thresh >= .1", + "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + aliasing }, +/*16*/ { "fpassist", "look for a excessive value", + "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1", + fpassists }, +/*17*/ { "otherassistavx", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistavx }, +/*18*/ { "otherassistsse", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistsse }, +/*19*/ { "eff1", "thresh < .9", + "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency1 }, +/*20*/ { "eff2", "thresh > 1.0", + "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency2 }, +}; + + +#define IVY_BRIDGE_COUNT 21 +static struct cpu_entry ivy_bridge[IVY_BRIDGE_COUNT] = { +/*1*/ { "eff1", "thresh < .75", + "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency1 }, +/*2*/ { "eff2", "thresh > 1.0", + "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency2 }, +/*3*/ { "itlbmiss", "thresh > .05", + "pmcstat -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + itlb_miss }, +/*4*/ { "icachemiss", "thresh > .05", + "pmcstat -s ICACHE.IFETCH_STALL -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + icache_miss }, +/*5*/ { "lcpstall", "thresh > .05", + "pmcstat -s ILD_STALL.LCP -s CPU_CLK_UNHALTED.THREAD_P -w 1", + lcp_stall }, +/*6*/ { "cache1", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache1ib }, +/*7*/ { "cache2", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache2ib }, +/*8*/ { "contested", "thresh >= .05", + "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + contested }, +/*9*/ { "datashare", "thresh >= .05", + "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1", + datasharing }, +/*10*/ { "blockstorefwd", "thresh >= .05", + "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1", + blockstoreforward }, +/*11*/ { "splitload", "thresh >= .1", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s L1D_PEND_MISS.PENDING -s MEM_LOAD_UOPS_RETIRED.L1_MISS -s LD_BLOCKS.NO_SR -w 1", + splitloadib }, +/*12*/ { "splitstore", "thresh >= .01", + "pmcstat -s MEM_UOP_RETIRED.SPLIT_STORES -s MEM_UOP_RETIRED.ALL_STORES -w 1", + splitstore }, +/*13*/ { "aliasing_4k", "thresh >= .1", + "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + aliasing }, +/*14*/ { "dtlbmissload", "thresh >= .1", + "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + dtlb_missload }, +/*15*/ { "dtlbmissstore", "thresh >= .05", + "pmcstat -s DTLB_STORE_MISSES.STLB_HIT -s DTLB_STORE_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + dtlb_missstore }, +/*16*/ { "br_miss", "thresh >= .2", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -s INT_MISC.RECOVERY_CYCLES -w 1", + br_mispredictib }, +/*17*/ { "clears", "thresh >= .02", + "pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1", + clears }, +/*18*/ { "microassist", "thresh >= .05", + "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1", + microassist }, +/*19*/ { "fpassist", "look for a excessive value", + "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1", + fpassists }, +/*20*/ { "otherassistavx", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistavx }, +/*21*/ { "otherassistsse", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistsse }, +}; + +#define HASWELL_COUNT 20 +static struct cpu_entry haswell[HASWELL_COUNT] = { +/*1*/ { "eff1", "thresh < .75", + "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency1 }, +/*2*/ { "eff2", "thresh > 1.0", + "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency2 }, +/*3*/ { "itlbmiss", "thresh > .05", + "pmcstat -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + itlb_miss }, +/*4*/ { "icachemiss", "thresh > .05", + "pmcstat -s ICACHE.MISSES --s CPU_CLK_UNHALTED.THREAD_P -w 1", + icache_miss_has }, +/*5*/ { "lcpstall", "thresh > .05", + "pmcstat -s ILD_STALL.LCP -s CPU_CLK_UNHALTED.THREAD_P -w 1", + lcp_stall }, +/*6*/ { "cache1", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache1ib }, +/*7*/ { "cache2", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache2has }, +/*8*/ { "contested", "thresh >= .05", + "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + contested_has }, +/*9*/ { "datashare", "thresh >= .05", + "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1", + datasharing_has }, +/*10*/ { "blockstorefwd", "thresh >= .05", + "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1", + blockstoreforward }, +/*11*/ { "splitload", "thresh >= .1", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s MEM_UOP_RETIRED.SPLIT_LOADS -w 1", + splitload }, +/*12*/ { "splitstore", "thresh >= .01", + "pmcstat -s MEM_UOP_RETIRED.SPLIT_STORES -s MEM_UOP_RETIRED.ALL_STORES -w 1", + splitstore }, +/*13*/ { "aliasing_4k", "thresh >= .1", + "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + aliasing }, +/*14*/ { "dtlbmissload", "thresh >= .1", + "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + dtlb_missload }, +/*15*/ { "br_miss", "thresh >= .2", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -w 1", + br_mispredict }, +/*16*/ { "clears", "thresh >= .02", + "pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1", + clears }, +/*17*/ { "microassist", "thresh >= .05", + "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1", + microassist }, +/*18*/ { "fpassist", "look for a excessive value", + "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1", + fpassists }, +/*19*/ { "otherassistavx", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistavx }, +/*20*/ { "otherassistsse", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistsse }, +}; + + +static void +set_sandybridge(void) +{ + strcpy(the_cpu.cputype, "SandyBridge PMC"); + the_cpu.number = SANDY_BRIDGE_COUNT; + the_cpu.ents = sandy_bridge; + the_cpu.explain = explain_name_sb; +} + +static void +set_ivybridge(void) +{ + strcpy(the_cpu.cputype, "IvyBridge PMC"); + the_cpu.number = IVY_BRIDGE_COUNT; + the_cpu.ents = ivy_bridge; + the_cpu.explain = explain_name_ib; +} + + +static void +set_haswell(void) +{ + strcpy(the_cpu.cputype, "HASWELL PMC"); + the_cpu.number = HASWELL_COUNT; + the_cpu.ents = haswell; + the_cpu.explain = explain_name_has; +} + +static void +set_expression(char *name) +{ + int found = 0, i; + for(i=0 ; i< the_cpu.number; i++) { + if (strcmp(name, the_cpu.ents[i].name) == 0) { + found = 1; + expression = the_cpu.ents[i].func; + command = the_cpu.ents[i].command; + threshold = the_cpu.ents[i].thresh; + break; + } + } + if (!found) { + printf("For CPU type %s we have no expression:%s\n", + the_cpu.cputype, name); + exit(-1); + } +} + + + + + +static int +validate_expression(char *name) +{ + int i, found; + + found = 0; + for(i=0 ; i< the_cpu.number; i++) { + if (strcmp(name, the_cpu.ents[i].name) == 0) { + found = 1; + break; + } + } + if (!found) { + return(-1); + } + return (0); +} + +static void +do_expression(struct counters *cpu, int pos) +{ + if (expression == NULL) + return; + (*expression)(cpu, pos); +} + +static void +process_header(int idx, char *p) +{ + struct counters *up; + int i, len, nlen; + /* + * Given header element idx, at p in + * form 's/NN/nameof' + * process the entry to pull out the name and + * the CPU number. + */ + if (strncmp(p, "s/", 2)) { + printf("Check -- invalid header no s/ in %s\n", + p); + return; + } + up = &cnts[idx]; + up->cpu = strtol(&p[2], NULL, 10); + len = strlen(p); + for (i=2; i<len; i++) { + if (p[i] == '/') { + nlen = strlen(&p[(i+1)]); + if (nlen < (MAX_NLEN-1)) { + strcpy(up->counter_name, &p[(i+1)]); + } else { + strncpy(up->counter_name, &p[(i+1)], (MAX_NLEN-1)); + } + } + } +} + +static void +build_counters_from_header(FILE *io) +{ + char buffer[8192], *p; + int i, len, cnt; + size_t mlen; + + /* We have a new start, lets + * setup our headers and cpus. + */ + if (fgets(buffer, sizeof(buffer), io) == NULL) { + printf("First line can't be read from file err:%d\n", errno); + return; + } + /* + * Ok output is an array of counters. Once + * we start to read the values in we must + * put them in there slot to match there CPU and + * counter being updated. We create a mass array + * of the counters, filling in the CPU and + * counter name. + */ + /* How many do we get? */ + len = strlen(buffer); + for (i=0, cnt=0; i<len; i++) { + if (strncmp(&buffer[i], "s/", 2) == 0) { + cnt++; + for(;i<len;i++) { + if (buffer[i] == ' ') + break; + } + } + } + mlen = sizeof(struct counters) * cnt; + cnts = malloc(mlen); + ncnts = cnt; + if (cnts == NULL) { + printf("No memory err:%d\n", errno); + return; + } + memset(cnts, 0, mlen); + for (i=0, cnt=0; i<len; i++) { + if (strncmp(&buffer[i], "s/", 2) == 0) { + p = &buffer[i]; + for(;i<len;i++) { + if (buffer[i] == ' ') { + buffer[i] = 0; + break; + } + } + process_header(cnt, p); + cnt++; + } + } + if (verbose) + printf("We have %d entries\n", cnt); +} +extern int max_to_collect; +int max_to_collect = MAX_COUNTER_SLOTS; + +static int +read_a_line(FILE *io) +{ + char buffer[8192], *p, *stop; + int pos, i; + + if (fgets(buffer, sizeof(buffer), io) == NULL) { + return(0); + } + p = buffer; + for (i=0; i<ncnts; i++) { + pos = cnts[i].pos; + cnts[i].vals[pos] = strtol(p, &stop, 0); + cnts[i].pos++; + cnts[i].sum += cnts[i].vals[pos]; + p = stop; + } + return (1); +} + +extern int cpu_count_out; +int cpu_count_out=0; + +static void +print_header(void) +{ + int i, cnt, printed_cnt; + + printf("*********************************\n"); + for(i=0, cnt=0; i<MAX_CPU; i++) { + if (glob_cpu[i]) { + cnt++; + } + } + cpu_count_out = cnt; + for(i=0, printed_cnt=0; i<MAX_CPU; i++) { + if (glob_cpu[i]) { + printf("CPU%d", i); + printed_cnt++; + } + if (printed_cnt == cnt) { + printf("\n"); + break; + } else { + printf("\t"); + } + } +} + +static void +lace_cpus_together(void) +{ + int i, j, lace_cpu; + struct counters *cpat, *at; + + for(i=0; i<ncnts; i++) { + cpat = &cnts[i]; + if (cpat->next_cpu) { + /* Already laced in */ + continue; + } + lace_cpu = cpat->cpu; + if (lace_cpu >= MAX_CPU) { + printf("CPU %d to big\n", lace_cpu); + continue; + } + if (glob_cpu[lace_cpu] == NULL) { + glob_cpu[lace_cpu] = cpat; + } else { + /* Already processed this cpu */ + continue; + } + /* Ok look forward for cpu->cpu and link in */ + for(j=(i+1); j<ncnts; j++) { + at = &cnts[j]; + if (at->next_cpu) { + continue; + } + if (at->cpu == lace_cpu) { + /* Found one */ + cpat->next_cpu = at; + cpat = at; + } + } + } +} + + +static void +process_file(char *filename) +{ + FILE *io; + int i; + int line_at, not_done; + pid_t pid_of_command=0; + + if (filename == NULL) { + io = my_popen(command, "r", &pid_of_command); + if (io == NULL) { + printf("Can't popen the command %s\n", command); + return; + } + } else { + io = fopen(filename, "r"); + if (io == NULL) { + printf("Can't process file %s err:%d\n", + filename, errno); + return; + } + } + build_counters_from_header(io); + if (cnts == NULL) { + /* Nothing we can do */ + printf("Nothing to do -- no counters built\n"); + if (filename) { + fclose(io); + } else { + my_pclose(io, pid_of_command); + } + return; + } + lace_cpus_together(); + print_header(); + if (verbose) { + for (i=0; i<ncnts; i++) { + printf("Counter:%s cpu:%d index:%d\n", + cnts[i].counter_name, + cnts[i].cpu, i); + } + } + line_at = 0; + not_done = 1; + while(not_done) { + if (read_a_line(io)) { + line_at++; + } else { + break; + } + if (line_at >= max_to_collect) { + not_done = 0; + } + if (filename == NULL) { + int cnt; + /* For the ones we dynamically open we print now */ + for(i=0, cnt=0; i<MAX_CPU; i++) { + do_expression(glob_cpu[i], (line_at-1)); + cnt++; + if (cnt == cpu_count_out) { + printf("\n"); + break; + } else { + printf("\t"); + } + } + } + } + if (filename) { + fclose(io); + } else { + my_pclose(io, pid_of_command); + } +} +#if defined(__amd64__) +#define cpuid(in,a,b,c,d)\ + asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in)); +#else +#define cpuid(in, a, b, c, d) +#endif + +static void +get_cpuid_set(void) +{ + unsigned long eax, ebx, ecx, edx; + int model; + pid_t pid_of_command=0; + size_t sz, len; + FILE *io; + char linebuf[1024], *str; + + eax = ebx = ecx = edx = 0; + + cpuid(0, eax, ebx, ecx, edx); + if (ebx == 0x68747541) { + printf("AMD processors are not supported by this program\n"); + printf("Sorry\n"); + exit(0); + } else if (ebx == 0x6972794) { + printf("Cyrix processors are not supported by this program\n"); + printf("Sorry\n"); + exit(0); + } else if (ebx == 0x756e6547) { + printf("Genuine Intel\n"); + } else { + printf("Unknown processor type 0x%lx Only Intel AMD64 types are supported by this routine!\n", ebx); + exit(0); + } + cpuid(1, eax, ebx, ecx, edx); + model = (((eax & 0xF0000) >> 12) | ((eax & 0xF0) >> 4)); + printf("CPU model is 0x%x id:0x%lx\n", model, eax); + switch (eax & 0xF00) { + case 0x500: /* Pentium family processors */ + printf("Intel Pentium P5\n"); + goto not_supported; + break; + case 0x600: /* Pentium Pro, Celeron, Pentium II & III */ + switch (model) { + case 0x1: + printf("Intel Pentium P6\n"); + goto not_supported; + break; + case 0x3: + case 0x5: + printf("Intel PII\n"); + goto not_supported; + break; + case 0x6: case 0x16: + printf("Intel CL\n"); + goto not_supported; + break; + case 0x7: case 0x8: case 0xA: case 0xB: + printf("Intel PIII\n"); + goto not_supported; + break; + case 0x9: case 0xD: + printf("Intel PM\n"); + goto not_supported; + break; + case 0xE: + printf("Intel CORE\n"); + goto not_supported; + break; + case 0xF: + printf("Intel CORE2\n"); + goto not_supported; + break; + case 0x17: + printf("Intel CORE2EXTREME\n"); + goto not_supported; + break; + case 0x1C: /* Per Intel document 320047-002. */ + printf("Intel ATOM\n"); + goto not_supported; + break; + case 0x1A: + case 0x1E: /* + * Per Intel document 253669-032 9/2009, + * pages A-2 and A-57 + */ + case 0x1F: /* + * Per Intel document 253669-032 9/2009, + * pages A-2 and A-57 + */ + printf("Intel COREI7\n"); + goto not_supported; + break; + case 0x2E: + printf("Intel NEHALEM\n"); + goto not_supported; + break; + case 0x25: /* Per Intel document 253669-033US 12/2009. */ + case 0x2C: /* Per Intel document 253669-033US 12/2009. */ + printf("Intel WESTMERE\n"); + goto not_supported; + break; + case 0x2F: /* Westmere-EX, seen in wild */ + printf("Intel WESTMERE\n"); + goto not_supported; + break; + case 0x2A: /* Per Intel document 253669-039US 05/2011. */ + printf("Intel SANDYBRIDGE\n"); + set_sandybridge(); + break; + case 0x2D: /* Per Intel document 253669-044US 08/2012. */ + printf("Intel SANDYBRIDGE_XEON\n"); + set_sandybridge(); + break; + case 0x3A: /* Per Intel document 253669-043US 05/2012. */ + printf("Intel IVYBRIDGE\n"); + set_ivybridge(); + break; + case 0x3E: /* Per Intel document 325462-045US 01/2013. */ + printf("Intel IVYBRIDGE_XEON\n"); + set_ivybridge(); + break; + case 0x3F: /* Per Intel document 325462-045US 09/2014. */ + printf("Intel HASWELL (Xeon)\n"); + set_haswell(); + break; + case 0x3C: /* Per Intel document 325462-045US 01/2013. */ + case 0x45: + case 0x46: + printf("Intel HASWELL\n"); + set_haswell(); + break; + case 0x4D: + /* Per Intel document 330061-001 01/2014. */ + printf("Intel ATOM_SILVERMONT\n"); + goto not_supported; + break; + default: + printf("Intel model 0x%x is not known -- sorry\n", + model); + goto not_supported; + break; + } + break; + case 0xF00: /* P4 */ + printf("Intel unknown model %d\n", model); + goto not_supported; + break; + } + /* Ok lets load the list of all known PMC's */ + io = my_popen("/usr/sbin/pmccontrol -L", "r", &pid_of_command); + if (valid_pmcs == NULL) { + /* Likely */ + pmc_allocated_cnt = PMC_INITIAL_ALLOC; + sz = sizeof(char *) * pmc_allocated_cnt; + valid_pmcs = malloc(sz); + if (valid_pmcs == NULL) { + printf("No memory allocation fails at startup?\n"); + exit(-1); + } + memset(valid_pmcs, 0, sz); + } + + while (fgets(linebuf, sizeof(linebuf), io) != NULL) { + if (linebuf[0] != '\t') { + /* sometimes headers ;-) */ + continue; + } + len = strlen(linebuf); + if (linebuf[(len-1)] == '\n') { + /* Likely */ + linebuf[(len-1)] = 0; + } + str = &linebuf[1]; + len = strlen(str) + 1; + valid_pmcs[valid_pmc_cnt] = malloc(len); + if (valid_pmcs[valid_pmc_cnt] == NULL) { + printf("No memory2 allocation fails at startup?\n"); + exit(-1); + } + memset(valid_pmcs[valid_pmc_cnt], 0, len); + strcpy(valid_pmcs[valid_pmc_cnt], str); + valid_pmc_cnt++; + if (valid_pmc_cnt >= pmc_allocated_cnt) { + /* Got to expand -- unlikely */ + char **more; + + sz = sizeof(char *) * (pmc_allocated_cnt * 2); + more = malloc(sz); + if (more == NULL) { + printf("No memory3 allocation fails at startup?\n"); + exit(-1); + } + memset(more, 0, sz); + memcpy(more, valid_pmcs, sz); + pmc_allocated_cnt *= 2; + free(valid_pmcs); + valid_pmcs = more; + } + } + my_pclose(io, pid_of_command); + return; +not_supported: + printf("Not supported\n"); + exit(-1); +} + +static void +explain_all(void) +{ + int i; + printf("For CPU's of type %s the following expressions are available:\n",the_cpu.cputype); + printf("-------------------------------------------------------------\n"); + for(i=0; i<the_cpu.number; i++){ + printf("For -e %s ", the_cpu.ents[i].name); + (*the_cpu.explain)(the_cpu.ents[i].name); + printf("----------------------------\n"); + } +} + +static void +test_for_a_pmc(const char *pmc, int out_so_far) +{ + FILE *io; + pid_t pid_of_command=0; + char my_command[1024]; + char line[1024]; + char resp[1024]; + int len, llen, i; + + if (out_so_far < 50) { + len = 50 - out_so_far; + for(i=0; i<len; i++) { + printf(" "); + } + } + sprintf(my_command, "/usr/sbin/pmcstat -w .25 -c 0 -s %s", pmc); + io = my_popen(my_command, "r", &pid_of_command); + if (io == NULL) { + printf("Failed -- popen fails\n"); + return; + } + /* Setup what we expect */ + len = sprintf(resp, "%s", pmc); + if (fgets(line, sizeof(line), io) == NULL) { + printf("Failed -- no output from pmstat\n"); + goto out; + } + llen = strlen(line); + if (line[(llen-1)] == '\n') { + line[(llen-1)] = 0; + llen--; + } + for(i=2; i<(llen-len); i++) { + if (strncmp(&line[i], "ERROR", 5) == 0) { + printf("Failed %s\n", line); + goto out; + } else if (strncmp(&line[i], resp, len) == 0) { + int j, k; + + if (fgets(line, sizeof(line), io) == NULL) { + printf("Failed -- no second output from pmstat\n"); + goto out; + } + len = strlen(line); + for (j=0; j<len; j++) { + if (line[j] == ' ') { + j++; + } else { + break; + } + } + printf("Pass"); + len = strlen(&line[j]); + if (len < 20) { + for(k=0; k<(20-len); k++) { + printf(" "); + } + } + if (len) { + printf("%s", &line[j]); + } else { + printf("\n"); + } + goto out; + } + } + printf("Failed -- '%s' not '%s'\n", line, resp); +out: + my_pclose(io, pid_of_command); + +} + +static int +add_it_to(char **vars, int cur_cnt, char *name) +{ + int i; + size_t len; + for(i=0; i<cur_cnt; i++) { + if (strcmp(vars[i], name) == 0) { + /* Already have */ + return(0); + } + } + if (vars[cur_cnt] != NULL) { + printf("Cur_cnt:%d filled with %s??\n", + cur_cnt, vars[cur_cnt]); + exit(-1); + } + /* Ok its new */ + len = strlen(name) + 1; + vars[cur_cnt] = malloc(len); + if (vars[cur_cnt] == NULL) { + printf("No memory %s\n", __FUNCTION__); + exit(-1); + } + memset(vars[cur_cnt], 0, len); + strcpy(vars[cur_cnt], name); + return(1); +} + +static char * +build_command_for_exp(struct expression *exp) +{ + /* + * Build the pmcstat command to handle + * the passed in expression. + * /usr/sbin/pmcstat -w 1 -s NNN -s QQQ + * where NNN and QQQ represent the PMC's in the expression + * uniquely.. + */ + char forming[1024]; + int cnt_pmc, alloced_pmcs, i; + struct expression *at; + char **vars, *cmd; + size_t mal; + + alloced_pmcs = cnt_pmc = 0; + /* first how many do we have */ + at = exp; + while (at) { + if (at->type == TYPE_VALUE_PMC) { + cnt_pmc++; + } + at = at->next; + } + if (cnt_pmc == 0) { + printf("No PMC's in your expression -- nothing to do!!\n"); + exit(0); + } + mal = cnt_pmc * sizeof(char *); + vars = malloc(mal); + if (vars == NULL) { + printf("No memory\n"); + exit(-1); + } + memset(vars, 0, mal); + at = exp; + while (at) { + if (at->type == TYPE_VALUE_PMC) { + if(add_it_to(vars, alloced_pmcs, at->name)) { + alloced_pmcs++; + } + } + at = at->next; + } + /* Now we have a unique list in vars so create our command */ + mal = 23; /* "/usr/sbin/pmcstat -w 1" + \0 */ + for(i=0; i<alloced_pmcs; i++) { + mal += strlen(vars[i]) + 4; /* var + " -s " */ + } + cmd = malloc((mal+2)); + if (cmd == NULL) { + printf("%s out of mem\n", __FUNCTION__); + exit(-1); + } + memset(cmd, 0, (mal+2)); + strcpy(cmd, "/usr/sbin/pmcstat -w 1"); + at = exp; + for(i=0; i<alloced_pmcs; i++) { + sprintf(forming, " -s %s", vars[i]); + strcat(cmd, forming); + free(vars[i]); + vars[i] = NULL; + } + free(vars); + return(cmd); +} + +static int +user_expr(struct counters *cpu, int pos) +{ + int ret; + double res; + struct counters *var; + struct expression *at; + + at = master_exp; + while (at) { + if (at->type == TYPE_VALUE_PMC) { + var = find_counter(cpu, at->name); + if (var == NULL) { + printf("%s:Can't find counter %s?\n", __FUNCTION__, at->name); + exit(-1); + } + if (pos != -1) { + at->value = var->vals[pos] * 1.0; + } else { + at->value = var->sum * 1.0; + } + } + at = at->next; + } + res = run_expr(master_exp, 1, NULL); + ret = printf("%1.3f", res); + return(ret); +} + + +static void +set_manual_exp(struct expression *exp) +{ + expression = user_expr; + command = build_command_for_exp(exp); + threshold = "User defined threshold"; +} + +static void +run_tests(void) +{ + int i, lenout; + printf("Running tests on %d PMC's this may take some time\n", valid_pmc_cnt); + printf("------------------------------------------------------------------------\n"); + for(i=0; i<valid_pmc_cnt; i++) { + lenout = printf("%s", valid_pmcs[i]); + fflush(stdout); + test_for_a_pmc(valid_pmcs[i], lenout); + } +} +static void +list_all(void) +{ + int i, cnt, j; + printf("PMC Abbreviation\n"); + printf("--------------------------------------------------------------\n"); + for(i=0; i<valid_pmc_cnt; i++) { + cnt = printf("%s", valid_pmcs[i]); + for(j=cnt; j<52; j++) { + printf(" "); + } + printf("%%%d\n", i); + } +} + + +int +main(int argc, char **argv) +{ + int i, j, cnt; + char *filename=NULL; + char *name=NULL; + int help_only = 0; + int test_mode = 0; + + get_cpuid_set(); + memset(glob_cpu, 0, sizeof(glob_cpu)); + while ((i = getopt(argc, argv, "LHhvm:i:?e:TE:")) != -1) { + switch (i) { + case 'L': + list_all(); + return(0); + case 'H': + printf("**********************************\n"); + explain_all(); + printf("**********************************\n"); + return(0); + break; + case 'T': + test_mode = 1; + break; + case 'E': + master_exp = parse_expression(optarg); + if (master_exp) { + set_manual_exp(master_exp); + } + break; + case 'e': + if (validate_expression(optarg)) { + printf("Unknown expression %s\n", optarg); + return(0); + } + name = optarg; + set_expression(optarg); + break; + case 'm': + max_to_collect = strtol(optarg, NULL, 0); + if (max_to_collect > MAX_COUNTER_SLOTS) { + /* You can't collect more than max in array */ + max_to_collect = MAX_COUNTER_SLOTS; + } + break; + case 'v': + verbose++; + break; + case 'h': + help_only = 1; + break; + case 'i': + filename = optarg; + break; + case '?': + default: + use: + printf("Use %s [ -i inputfile -v -m max_to_collect -e expr -E -h -? -H]\n", + argv[0]); + printf("-i inputfile -- use source as inputfile not stdin (if stdin collect)\n"); + printf("-v -- verbose dump debug type things -- you don't want this\n"); + printf("-m N -- maximum to collect is N measurments\n"); + printf("-e expr-name -- Do expression expr-name\n"); + printf("-E 'your expression' -- Do your expression\n"); + printf("-h -- Don't do the expression I put in -e xxx just explain what it does and exit\n"); + printf("-H -- Don't run anything, just explain all canned expressions\n"); + printf("-T -- Test all PMC's defined by this processor\n"); + return(0); + break; + }; + } + if ((name == NULL) && (filename == NULL) && (test_mode == 0) && (master_exp == NULL)) { + printf("Without setting an expression we cannot dynamically gather information\n"); + printf("you must supply a filename (and you probably want verbosity)\n"); + goto use; + } + if (test_mode) { + run_tests(); + return(0); + } + printf("*********************************\n"); + if (master_exp == NULL) { + (*the_cpu.explain)(name); + } else { + printf("Examine your expression "); + print_exp(master_exp); + printf("User defined threshold\n"); + } + if (help_only) { + return(0); + } + process_file(filename); + if (verbose >= 2) { + for (i=0; i<ncnts; i++) { + printf("Counter:%s cpu:%d index:%d\n", + cnts[i].counter_name, + cnts[i].cpu, i); + for(j=0; j<cnts[i].pos; j++) { + printf(" val - %ld\n", (long int)cnts[i].vals[j]); + } + printf(" sum - %ld\n", (long int)cnts[i].sum); + } + } + if (expression == NULL) { + return(0); + } + for(i=0, cnt=0; i<MAX_CPU; i++) { + if (glob_cpu[i]) { + do_expression(glob_cpu[i], -1); + cnt++; + if (cnt == cpu_count_out) { + printf("\n"); + break; + } else { + printf("\t"); + } + } + } + return(0); +} diff --git a/usr.sbin/portsnap/phttpget/Makefile b/usr.sbin/portsnap/phttpget/Makefile index a43672f..51c5b99 100644 --- a/usr.sbin/portsnap/phttpget/Makefile +++ b/usr.sbin/portsnap/phttpget/Makefile @@ -1,7 +1,7 @@ # $FreeBSD$ PROG= phttpget -MAN= +MAN= phttpget.8 BINDIR= ${LIBEXECDIR} diff --git a/usr.sbin/portsnap/phttpget/phttpget.8 b/usr.sbin/portsnap/phttpget/phttpget.8 new file mode 100644 index 0000000..f0c8210 --- /dev/null +++ b/usr.sbin/portsnap/phttpget/phttpget.8 @@ -0,0 +1,88 @@ +.\"- +.\" Copyright (c) 2015 Xin Li <delphij@FreeBSD.org> +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd January 3, 2015 +.Dt PHTTPGET 8 +.Os +.Sh NAME +.Nm phttpget +.Nd retrieve multiple files via pipelined HTTP +.Sh SYNOPSIS +.Nm +.Ar server +.Ar file ... +.Sh DESCRIPTION +The +.Nm +utility is a minimalist pipelined HTTP client, +which is used to retrieve multiple +.Ar file Ns s +from one +.Ar server , +and saves the downloaded files in the current working directory, +using the last portion of their download path as file names. +.Pp +By making several "in flight" HTTP requests, +it can dramatically increase performance when a large number of +small files need to be downloaded. +.Pp +The +.Xr freebsd-update 8 +and +.Xr portnap 8 +tools use +.Nm +to download binary patch files. +.Sh ENVIRONMENT +.Bl -tag -width HTTP_PROXY_AUTH +.It Ev HTTP_PROXY +URL of the proxy to use for HTTP requests. +.It Ev HTTP_PROXY_AUTH +Authorization parameters for the HTTP proxy. +.It Ev HTTP_USER_AGENT +The User-Agent string to use for HTTP requests. +The default is +.Dq phttpget/0.1 . +.It Ev HTTP_TIMEOUT +Timeout for HTTP request in seconds. +.El +.Sh SEE ALSO +.Xr fetch 1 , +.Xr freebsd-update 8 , +.Xr portsnap 8 +.Sh AUTHORS +.An -nosplit +The +.Nm +utility was written by +.An Colin Percival Aq Mt cperciva@FreeBSD.org +for use with +.Xr portsnap 8 +and later with +.Xr freebsd-update 8 . +This manual page was written by +.An Xin LI Aq Mt delphij@FreeBSD.org . diff --git a/usr.sbin/powerd/Makefile b/usr.sbin/powerd/Makefile index 62f8da1..4434dcf 100644 --- a/usr.sbin/powerd/Makefile +++ b/usr.sbin/powerd/Makefile @@ -3,7 +3,6 @@ PROG= powerd MAN= powerd.8 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/powerd/powerd.c b/usr.sbin/powerd/powerd.c index 3f628f6..367a31f 100644 --- a/usr.sbin/powerd/powerd.c +++ b/usr.sbin/powerd/powerd.c @@ -127,6 +127,12 @@ static int devd_pipe = -1; #define DEVD_RETRY_INTERVAL 60 /* seconds */ static struct timeval tried_devd; +/* + * This function returns summary load of all CPUs. It was made so + * intentionally to not reduce performance in scenarios when several + * threads are processing requests as a pipeline -- running one at + * a time on different CPUs and waiting for each other. + */ static int read_usage_times(int *load) { diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile index dda493e..e0772af 100644 --- a/usr.sbin/ppp/Makefile +++ b/usr.sbin/ppp/Makefile @@ -31,6 +31,9 @@ PPP_NO_NETGRAPH= .if ${MK_PAM_SUPPORT} == "no" PPP_NO_PAM= .endif +.if ${MK_RADIUS_SUPPORT} == "no" +PPP_NO_RADIUS= +.endif .if defined(PPP_NO_SUID) BINMODE=554 @@ -41,8 +44,7 @@ BINOWN= root BINGRP= network M4FLAGS= -LDADD= -lcrypt -lmd -lutil -lz -DPADD= ${LIBCRYPT} ${LIBMD} ${LIBUTIL} ${LIBZ} +LIBADD= md util z .if defined(PPP_CONFDIR) && !empty(PPP_CONFDIR) CFLAGS+=-DPPP_CONFDIR=\"${PPP_CONFDIR}\" @@ -60,8 +62,7 @@ CFLAGS+=-DNOINET6 CFLAGS+=-DNONAT .else SRCS+= nat_cmd.c -LDADD+= -lalias -DPADD+= ${LIBALIAS} +LIBADD+= alias .endif .if defined(PPP_NO_ATM) @@ -80,24 +81,21 @@ SRCS+= id.c CFLAGS+=-DNODES .else SRCS+= chap_ms.c mppe.c -LDADD+= -lcrypto -DPADD+= ${LIBCRYPTO} +LIBADD+= crypto .endif .if defined(PPP_NO_RADIUS) CFLAGS+=-DNORADIUS .else SRCS+= radius.c -LDADD+= -lradius -DPADD+= ${LIBRADIUS} +LIBADD+= radius .endif .if defined(PPP_NO_NETGRAPH) CFLAGS+=-DNONETGRAPH .else SRCS+= ether.c -LDADD+= -lnetgraph -DPADD+= ${LIBNETGRAPH} +LIBADD+= netgraph .if defined(EXPERIMENTAL_NETGRAPH) CFLAGS+=-DEXPERIMENTAL_NETGRAPH SRCS+= netgraph.c @@ -107,8 +105,7 @@ SRCS+= netgraph.c .if defined(PPP_NO_PAM) CFLAGS+=-DNOPAM .else -LDADD+= ${MINUSLPAM} -DPADD+= ${LIBPAM} +LIBADD+= pam .endif .include <bsd.prog.mk> diff --git a/usr.sbin/ppp/Makefile.depend b/usr.sbin/ppp/Makefile.depend index e1dc9b4..6be8d6a 100644 --- a/usr.sbin/ppp/Makefile.depend +++ b/usr.sbin/ppp/Makefile.depend @@ -12,7 +12,6 @@ DIRDEPS = \ lib/libalias/libalias \ lib/libc \ lib/libcompiler_rt \ - lib/libcrypt \ lib/libmd \ lib/libnetgraph \ lib/libpam/libpam \ diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c index 6bdf0c9..e90d96b 100644 --- a/usr.sbin/ppp/command.c +++ b/usr.sbin/ppp/command.c @@ -2051,7 +2051,7 @@ SetVariable(struct cmdargs const *arg) res = 1; } else { arg->bundle->radius.alive.interval = atoi(argp); - if (arg->bundle->radius.alive.interval && !arg->bundle->radius.cfg.file) { + if (arg->bundle->radius.alive.interval && !*arg->bundle->radius.cfg.file) { log_Printf(LogWARN, "rad_alive requires radius to be configured\n"); res = 1; } else if (arg->bundle->ncp.ipcp.fsm.state == ST_OPENED) { @@ -2335,7 +2335,7 @@ SetVariable(struct cmdargs const *arg) res = 1; } - if (arg->bundle->radius.port_id_type && !arg->bundle->radius.cfg.file) { + if (arg->bundle->radius.port_id_type && !*arg->bundle->radius.cfg.file) { log_Printf(LogWARN, "rad_port_id requires radius to be configured\n"); res = 1; } diff --git a/usr.sbin/ppp/iface.c b/usr.sbin/ppp/iface.c index 8fee189..5f17769 100644 --- a/usr.sbin/ppp/iface.c +++ b/usr.sbin/ppp/iface.c @@ -31,9 +31,6 @@ #include <netinet/in.h> #include <net/if.h> #include <net/if_dl.h> -#ifdef __FreeBSD__ -#include <net/if_var.h> -#endif #include <net/route.h> #include <netinet/in_systm.h> #include <netinet/in_var.h> diff --git a/usr.sbin/ppp/ipcp.c b/usr.sbin/ppp/ipcp.c index 80b3a1b..dbb1e79 100644 --- a/usr.sbin/ppp/ipcp.c +++ b/usr.sbin/ppp/ipcp.c @@ -880,7 +880,7 @@ IpcpLayerDown(struct fsm *fp) radius_Account(&fp->bundle->radius, &fp->bundle->radacct, fp->bundle->links, RAD_STOP, &ipcp->throughput); - if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) + if (*fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) system_Select(fp->bundle, fp->bundle->radius.filterid, LINKDOWNFILE, NULL, NULL); radius_StopTimer(&fp->bundle->radius); @@ -949,7 +949,7 @@ IpcpLayerUp(struct fsm *fp) radius_Account(&fp->bundle->radius, &fp->bundle->radacct, fp->bundle->links, RAD_START, &ipcp->throughput); - if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) + if (*fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) system_Select(fp->bundle, fp->bundle->radius.filterid, LINKUPFILE, NULL, NULL); radius_StartTimer(fp->bundle); diff --git a/usr.sbin/ppp/ipv6cp.c b/usr.sbin/ppp/ipv6cp.c index 72c3b9a..9088680 100644 --- a/usr.sbin/ppp/ipv6cp.c +++ b/usr.sbin/ppp/ipv6cp.c @@ -486,7 +486,7 @@ ipv6cp_LayerUp(struct fsm *fp) * evaluated. */ if (!Enabled(fp->bundle, OPT_IPCP)) { - if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) + if (*fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) system_Select(fp->bundle, fp->bundle->radius.filterid, LINKUPFILE, NULL, NULL); } @@ -539,7 +539,7 @@ ipv6cp_LayerDown(struct fsm *fp) * evaluated. */ if (!Enabled(fp->bundle, OPT_IPCP)) { - if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) + if (*fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) system_Select(fp->bundle, fp->bundle->radius.filterid, LINKDOWNFILE, NULL, NULL); } diff --git a/usr.sbin/ppp/radius.c b/usr.sbin/ppp/radius.c index dc71ab3..f798141 100644 --- a/usr.sbin/ppp/radius.c +++ b/usr.sbin/ppp/radius.c @@ -1345,7 +1345,7 @@ radius_alive(void *v) void radius_StartTimer(struct bundle *bundle) { - if (bundle->radius.cfg.file && bundle->radius.alive.interval) { + if (*bundle->radius.cfg.file && bundle->radius.alive.interval) { bundle->radius.alive.timer.func = radius_alive; bundle->radius.alive.timer.name = "radius alive"; bundle->radius.alive.timer.load = bundle->radius.alive.interval * SECTICKS; diff --git a/usr.sbin/ppp/server.c b/usr.sbin/ppp/server.c index 864c627..3997eaf 100644 --- a/usr.sbin/ppp/server.c +++ b/usr.sbin/ppp/server.c @@ -248,7 +248,7 @@ server_LocalOpen(struct bundle *bundle, const char *name, mode_t mask) oldmask = (mode_t)-1; /* Silence compiler */ - if (server.cfg.sockname && !strcmp(server.cfg.sockname, name)) + if (server.cfg.sockname[0] != '\0' && !strcmp(server.cfg.sockname, name)) server_Close(bundle); memset(&ifsun, '\0', sizeof ifsun); diff --git a/usr.sbin/pppctl/Makefile b/usr.sbin/pppctl/Makefile index 4a03b86..dcb7931 100644 --- a/usr.sbin/pppctl/Makefile +++ b/usr.sbin/pppctl/Makefile @@ -5,7 +5,6 @@ MAN= pppctl.8 WARNS?= 2 -DPADD= ${LIBPTHREAD} ${LIBEDIT} ${LIBTERMCAPW} -LDADD= -lpthread -ledit -ltermcapw +LIBADD= edit pthread .include <bsd.prog.mk> diff --git a/usr.sbin/praliases/Makefile b/usr.sbin/praliases/Makefile index 120028d..6fadc1b 100644 --- a/usr.sbin/praliases/Makefile +++ b/usr.sbin/praliases/Makefile @@ -13,17 +13,7 @@ CFLAGS+= -DNEWDB -DNOT_SENDMAIL WARNS?= 2 -LIBSMDIR= ${.OBJDIR}/../../lib/libsm -LIBSM= ${LIBSMDIR}/libsm.a - -LIBSMDBDIR= ${.OBJDIR}/../../lib/libsmdb -LIBSMDB= ${LIBSMDBDIR}/libsmdb.a - -LIBSMUTILDIR= ${.OBJDIR}/../../lib/libsmutil -LIBSMUTIL= ${LIBSMUTILDIR}/libsmutil.a - -DPADD= ${LIBSMDB} ${LIBSMUTIL} ${LIBSM} -LDADD= ${LIBSMDB} ${LIBSMUTIL} ${LIBSM} +LIBADD= sm smdb smutil SRCS+= sm_os.h CLEANFILES+=sm_os.h diff --git a/usr.sbin/praudit/Makefile b/usr.sbin/praudit/Makefile index 6a61fd1..6d85fb3 100644 --- a/usr.sbin/praudit/Makefile +++ b/usr.sbin/praudit/Makefile @@ -10,7 +10,6 @@ MAN= praudit.1 WARNS?= 3 -DPADD= ${LIBBSM} -LDADD= -lbsm +LIBADD= bsm .include <bsd.prog.mk> diff --git a/usr.sbin/pstat/Makefile b/usr.sbin/pstat/Makefile index 414708c..e3b0533 100644 --- a/usr.sbin/pstat/Makefile +++ b/usr.sbin/pstat/Makefile @@ -6,7 +6,6 @@ LINKS= ${BINDIR}/pstat ${BINDIR}/swapinfo MAN= pstat.8 MLINKS= pstat.8 swapinfo.8 -DPADD= ${LIBKVM} ${LIBUTIL} -LDADD= -lkvm -lutil +LIBADD= kvm util .include <bsd.prog.mk> diff --git a/usr.sbin/pw/Makefile b/usr.sbin/pw/Makefile index 8c5acf9..69953da 100644 --- a/usr.sbin/pw/Makefile +++ b/usr.sbin/pw/Makefile @@ -8,8 +8,7 @@ SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c pw_vpw.c \ WARNS?= 2 -DPADD= ${LIBCRYPT} ${LIBUTIL} -LDADD= -lcrypt -lutil +LIBADD= crypt util sbuf .include <src.opts.mk> diff --git a/usr.sbin/pw/Makefile.depend b/usr.sbin/pw/Makefile.depend index 8595bfc..e9c6d4c 100644 --- a/usr.sbin/pw/Makefile.depend +++ b/usr.sbin/pw/Makefile.depend @@ -11,6 +11,7 @@ DIRDEPS = \ lib/libc \ lib/libcompiler_rt \ lib/libcrypt \ + lib/libsbuf \ lib/libutil \ diff --git a/usr.sbin/pw/fileupd.c b/usr.sbin/pw/fileupd.c index 7df4bb1..dc32712 100644 --- a/usr.sbin/pw/fileupd.c +++ b/usr.sbin/pw/fileupd.c @@ -29,32 +29,11 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ -#include <stdio.h> -#include <fcntl.h> #include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <errno.h> -#include <unistd.h> #include "pwupd.h" int -extendline(char **buf, int * buflen, int needed) -{ - if (needed > *buflen) { - char *tmp = realloc(*buf, needed); - if (tmp == NULL) - return -1; - *buf = tmp; - *buflen = needed; - } - return *buflen; -} - -int extendarray(char ***buf, int * buflen, int needed) { if (needed > *buflen) { diff --git a/usr.sbin/pw/grupd.c b/usr.sbin/pw/grupd.c index 3f78e95..74cc390 100644 --- a/usr.sbin/pw/grupd.c +++ b/usr.sbin/pw/grupd.c @@ -35,10 +35,6 @@ static const char rcsid[] = #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> #include <sys/param.h> #include "pwupd.h" diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index 1289b3e..99d3e8f 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -29,9 +29,12 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include <sys/types.h> +#include <sys/sbuf.h> #include <string.h> #include <ctype.h> #include <fcntl.h> +#include <err.h> #include "pw.h" @@ -209,19 +212,16 @@ boolean_str(int val) char * newstr(char const * p) { - char *q = NULL; + char *q; - if ((p = unquote(p)) != NULL) { - int l = strlen(p) + 1; + if ((p = unquote(p)) == NULL) + return (NULL); - if ((q = malloc(l)) != NULL) - memcpy(q, p, l); - } - return q; -} - -#define LNBUFSZ 1024 + if ((q = strdup(p)) == NULL) + err(1, "strdup()"); + return (q); +} struct userconf * read_userconfig(char const * file) @@ -234,8 +234,10 @@ read_userconfig(char const * file) buf = NULL; linecap = 0; - extendarray(&config.groups, &config.numgroups, 200); - memset(config.groups, 0, config.numgroups * sizeof(char *)); + config.numgroups = 200; + config.groups = calloc(config.numgroups, sizeof(char *)); + if (config.groups == NULL) + err(1, "calloc()"); if (file == NULL) file = _PATH_PW_CONF; @@ -366,138 +368,132 @@ int write_userconfig(char const * file) { int fd; + int i, j; + struct sbuf *buf; + FILE *fp; if (file == NULL) file = _PATH_PW_CONF; - if ((fd = open(file, O_CREAT | O_RDWR | O_TRUNC | O_EXLOCK, 0644)) != -1) { - FILE *fp; + if ((fd = open(file, O_CREAT|O_RDWR|O_TRUNC|O_EXLOCK, 0644)) == -1) + return (0); - if ((fp = fdopen(fd, "w")) == NULL) - close(fd); - else { - int i, j, k; - int len = LNBUFSZ; - char *buf = malloc(len); - - for (i = _UC_NONE; i < _UC_FIELDS; i++) { - int quote = 1; - char const *val = buf; - - *buf = '\0'; - switch (i) { - case _UC_DEFAULTPWD: - val = boolean_str(config.default_password); - break; - case _UC_REUSEUID: - val = boolean_str(config.reuse_uids); - break; - case _UC_REUSEGID: - val = boolean_str(config.reuse_gids); - break; - case _UC_NISPASSWD: - val = config.nispasswd ? config.nispasswd : ""; - quote = 0; - break; - case _UC_DOTDIR: - val = config.dotdir ? config.dotdir : boolean_str(0); - break; - case _UC_NEWMAIL: - val = config.newmail ? config.newmail : boolean_str(0); - break; - case _UC_LOGFILE: - val = config.logfile ? config.logfile : boolean_str(0); - break; - case _UC_HOMEROOT: - val = config.home; - break; - case _UC_HOMEMODE: - sprintf(buf, "%04o", config.homemode); - quote = 0; - break; - case _UC_SHELLPATH: - val = config.shelldir; - break; - case _UC_SHELLS: - for (j = k = 0; j < _UC_MAXSHELLS && system_shells[j] != NULL; j++) { - char lbuf[64]; - int l = snprintf(lbuf, sizeof lbuf, "%s\"%s\"", k ? "," : "", system_shells[j]); - if (l < 0) - l = 0; - if (l + k + 1 < len || extendline(&buf, &len, len + LNBUFSZ) != -1) { - strcpy(buf + k, lbuf); - k += l; - } - } - quote = 0; - break; - case _UC_DEFAULTSHELL: - val = config.shell_default ? config.shell_default : bourne_shell; - break; - case _UC_DEFAULTGROUP: - val = config.default_group ? config.default_group : ""; - break; - case _UC_EXTRAGROUPS: - extendarray(&config.groups, &config.numgroups, 200); - for (j = k = 0; j < config.numgroups && config.groups[j] != NULL; j++) { - char lbuf[64]; - int l = snprintf(lbuf, sizeof lbuf, "%s\"%s\"", k ? "," : "", config.groups[j]); - if (l < 0) - l = 0; - if (l + k + 1 < len || extendline(&buf, &len, len + 1024) != -1) { - strcpy(buf + k, lbuf); - k += l; - } - } - quote = 0; - break; - case _UC_DEFAULTCLASS: - val = config.default_class ? config.default_class : ""; - break; - case _UC_MINUID: - sprintf(buf, "%lu", (unsigned long) config.min_uid); - quote = 0; - break; - case _UC_MAXUID: - sprintf(buf, "%lu", (unsigned long) config.max_uid); - quote = 0; - break; - case _UC_MINGID: - sprintf(buf, "%lu", (unsigned long) config.min_gid); - quote = 0; - break; - case _UC_MAXGID: - sprintf(buf, "%lu", (unsigned long) config.max_gid); - quote = 0; - break; - case _UC_EXPIRE: - sprintf(buf, "%d", config.expire_days); - quote = 0; - break; - case _UC_PASSWORD: - sprintf(buf, "%d", config.password_days); - quote = 0; - break; - case _UC_NONE: - break; - } + if ((fp = fdopen(fd, "w")) == NULL) { + close(fd); + return (0); + } + + buf = sbuf_new_auto(); + for (i = _UC_NONE; i < _UC_FIELDS; i++) { + int quote = 1; + + sbuf_clear(buf); + switch (i) { + case _UC_DEFAULTPWD: + sbuf_cat(buf, boolean_str(config.default_password)); + break; + case _UC_REUSEUID: + sbuf_cat(buf, boolean_str(config.reuse_uids)); + break; + case _UC_REUSEGID: + sbuf_cat(buf, boolean_str(config.reuse_gids)); + break; + case _UC_NISPASSWD: + sbuf_cat(buf, config.nispasswd ? config.nispasswd : + ""); + quote = 0; + break; + case _UC_DOTDIR: + sbuf_cat(buf, config.dotdir ? config.dotdir : + boolean_str(0)); + break; + case _UC_NEWMAIL: + sbuf_cat(buf, config.newmail ? config.newmail : + boolean_str(0)); + break; + case _UC_LOGFILE: + sbuf_cat(buf, config.logfile ? config.logfile : + boolean_str(0)); + break; + case _UC_HOMEROOT: + sbuf_cat(buf, config.home); + break; + case _UC_HOMEMODE: + sbuf_printf(buf, "%04o", config.homemode); + quote = 0; + break; + case _UC_SHELLPATH: + sbuf_cat(buf, config.shelldir); + break; + case _UC_SHELLS: + for (j = 0; j < _UC_MAXSHELLS && + system_shells[j] != NULL; j++) + sbuf_printf(buf, "%s\"%s\"", j ? + "," : "", system_shells[j]); + quote = 0; + break; + case _UC_DEFAULTSHELL: + sbuf_cat(buf, config.shell_default ? + config.shell_default : bourne_shell); + break; + case _UC_DEFAULTGROUP: + sbuf_cat(buf, config.default_group ? + config.default_group : ""); + break; + case _UC_EXTRAGROUPS: + for (j = 0; j < config.numgroups && + config.groups[j] != NULL; j++) + sbuf_printf(buf, "%s\"%s\"", j ? + "," : "", config.groups[j]); + quote = 0; + break; + case _UC_DEFAULTCLASS: + sbuf_cat(buf, config.default_class ? + config.default_class : ""); + break; + case _UC_MINUID: + sbuf_printf(buf, "%lu", (unsigned long) config.min_uid); + quote = 0; + break; + case _UC_MAXUID: + sbuf_printf(buf, "%lu", (unsigned long) config.max_uid); + quote = 0; + break; + case _UC_MINGID: + sbuf_printf(buf, "%lu", (unsigned long) config.min_gid); + quote = 0; + break; + case _UC_MAXGID: + sbuf_printf(buf, "%lu", (unsigned long) config.max_gid); + quote = 0; + break; + case _UC_EXPIRE: + sbuf_printf(buf, "%d", config.expire_days); + quote = 0; + break; + case _UC_PASSWORD: + sbuf_printf(buf, "%d", config.password_days); + quote = 0; + break; + case _UC_NONE: + break; + } + sbuf_finish(buf); - if (comments[i]) - fputs(comments[i], fp); + if (comments[i]) + fputs(comments[i], fp); - if (*kwds[i]) { - if (quote) - fprintf(fp, "%s = \"%s\"\n", kwds[i], val); - else - fprintf(fp, "%s = %s\n", kwds[i], val); + if (*kwds[i]) { + if (quote) + fprintf(fp, "%s = \"%s\"\n", kwds[i], + sbuf_data(buf)); + else + fprintf(fp, "%s = %s\n", kwds[i], sbuf_data(buf)); #if debugging - printf("WROTE: %s = %s\n", kwds[i], val); + printf("WROTE: %s = %s\n", kwds[i], sbuf_data(buf)); #endif - } - } - free(buf); - return fclose(fp) != EOF; } } - return 0; + sbuf_delete(buf); + return (fclose(fp) != EOF); } diff --git a/usr.sbin/pw/pw_nis.c b/usr.sbin/pw/pw_nis.c index 918fc30..c786cc7 100644 --- a/usr.sbin/pw/pw_nis.c +++ b/usr.sbin/pw/pw_nis.c @@ -29,9 +29,6 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <sys/types.h> #include <err.h> #include <pwd.h> diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 483148a..b058aab 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -40,7 +40,6 @@ static const char rcsid[] = #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> -#include <unistd.h> #include <login_cap.h> #include <pwd.h> #include <grp.h> @@ -185,8 +184,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) * But we create a symlink from cnf->home -> "/usr" -> cnf->home */ if (strchr(cnf->home+1, '/') == NULL) { - strcpy(dbuf, "/usr"); - strncat(dbuf, cnf->home, MAXPATHLEN-5); + snprintf(dbuf, MAXPATHLEN, "/usr%s", cnf->home); if (mkdir(dbuf, _DEF_DIRMODE) != -1 || errno == EEXIST) { chown(dbuf, 0, 0); /* @@ -364,11 +362,9 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if (mode == M_LOCK) { if (strncmp(pwd->pw_passwd, locked_str, sizeof(locked_str)-1) == 0) errx(EX_DATAERR, "user '%s' is already locked", pwd->pw_name); - passtmp = malloc(strlen(pwd->pw_passwd) + sizeof(locked_str)); + asprintf(&passtmp, "%s%s", locked_str, pwd->pw_passwd); if (passtmp == NULL) /* disaster */ errx(EX_UNAVAILABLE, "out of memory"); - strcpy(passtmp, locked_str); - strcat(passtmp, pwd->pw_passwd); pwd->pw_passwd = passtmp; edited = 1; } else if (mode == M_UNLOCK) { @@ -401,7 +397,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) */ snprintf(file, sizeof(file), "/var/cron/tabs/%s", pwd->pw_name); if (access(file, F_OK) == 0) { - sprintf(file, "crontab -u %s -r", pwd->pw_name); + snprintf(file, sizeof(file), "crontab -u %s -r", pwd->pw_name); system(file); } } @@ -409,7 +405,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) * Save these for later, since contents of pwd may be * invalidated by deletion */ - sprintf(file, "%s/%s", _PATH_MAILDIR, pwd->pw_name); + snprintf(file, sizeof(file), "%s/%s", _PATH_MAILDIR, pwd->pw_name); strlcpy(home, pwd->pw_dir, sizeof(home)); gr = GETGRGID(pwd->pw_gid); if (gr != NULL) @@ -815,7 +811,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) */ if (mode == M_ADD) { if (!PWALTDIR()) { - sprintf(line, "%s/%s", _PATH_MAILDIR, pwd->pw_name); + snprintf(line, sizeof(line), "%s/%s", _PATH_MAILDIR, pwd->pw_name); close(open(line, O_RDWR | O_CREAT, 0600)); /* Preserve contents & * mtime */ chown(line, pwd->pw_uid, pwd->pw_gid); @@ -959,7 +955,7 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer * function will happily handle that case for us and exit. */ if (GETGRGID(prefer) == NULL) { - sprintf(tmp, "%lu", (unsigned long) prefer); + snprintf(tmp, sizeof(tmp), "%u", prefer); addarg(&grpargs, 'g', tmp); } if (getarg(args, 'N')) @@ -1022,17 +1018,16 @@ static char * pw_homepolicy(struct userconf * cnf, struct cargs * args, char const * user) { struct carg *arg = getarg(args, 'd'); + static char home[128]; if (arg) - return arg->val; - else { - static char home[128]; + return (arg->val); - if (cnf->home == NULL || *cnf->home == '\0') - errx(EX_CONFIG, "no base home directory set"); - sprintf(home, "%s/%s", cnf->home, user); - return home; - } + if (cnf->home == NULL || *cnf->home == '\0') + errx(EX_CONFIG, "no base home directory set"); + snprintf(home, sizeof(home), "%s/%s", cnf->home, user); + + return (home); } static char * @@ -1053,12 +1048,12 @@ shell_path(char const * path, char *shells[], char *sh) static char shellpath[256]; if (sh != NULL) { - sprintf(shellpath, "%s/%s", p, sh); + snprintf(shellpath, sizeof(shellpath), "%s/%s", p, sh); if (access(shellpath, X_OK) == 0) return shellpath; } else for (i = 0; i < _UC_MAXSHELLS && shells[i] != NULL; i++) { - sprintf(shellpath, "%s/%s", p, shells[i]); + snprintf(shellpath, sizeof(shellpath), "%s/%s", p, shells[i]); if (access(shellpath, X_OK) == 0) return shellpath; } @@ -1308,7 +1303,7 @@ rmat(uid_t uid) st.st_uid == uid) { char tmp[MAXPATHLEN]; - sprintf(tmp, "/usr/bin/atrm %s", e->d_name); + snprintf(tmp, sizeof(tmp), "/usr/bin/atrm %s", e->d_name); system(tmp); } } diff --git a/usr.sbin/pw/pwupd.c b/usr.sbin/pw/pwupd.c index c2a9a53..710e901 100644 --- a/usr.sbin/pw/pwupd.c +++ b/usr.sbin/pw/pwupd.c @@ -33,7 +33,6 @@ static const char rcsid[] = #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <stdarg.h> #include <pwd.h> #include <libutil.h> #include <errno.h> @@ -52,12 +51,13 @@ int setpwdir(const char * dir) { if (dir == NULL) - return -1; + return (-1); else pwpath = strdup(dir); if (pwpath == NULL) - return -1; - return 0; + return (-1); + + return (0); } char * @@ -66,23 +66,20 @@ getpwpath(char const * file) static char pathbuf[MAXPATHLEN]; snprintf(pathbuf, sizeof pathbuf, "%s/%s", pwpath, file); - return pathbuf; + + return (pathbuf); } static int -pwdb(char *arg,...) +pwdb_check(void) { int i = 0; pid_t pid; - va_list ap; char *args[10]; args[i++] = _PATH_PWD_MKDB; - va_start(ap, arg); - while (i < 6 && arg != NULL) { - args[i++] = arg; - arg = va_arg(ap, char *); - } + args[i++] = "-C"; + if (pwpath != pathpwd) { args[i++] = "-d"; args[i++] = pwpath; @@ -100,65 +97,66 @@ pwdb(char *arg,...) if (WEXITSTATUS(i)) i = EIO; } - va_end(ap); - return i; + + return (i); } static int pw_update(struct passwd * pwd, char const * user) { - int rc = 0; - - rc = pwdb("-C", (char *)NULL); /* Check only */ - if (rc == 0) { - int pfd, tfd; - struct passwd *pw = NULL; - struct passwd *old_pw = NULL; - - if (pwd != NULL) - pw = pw_dup(pwd); - - if (user != NULL) - old_pw = GETPWNAM(user); - - if (pw_init(pwpath, NULL)) - err(1, "pw_init()"); - if ((pfd = pw_lock()) == -1) { - pw_fini(); - err(1, "pw_lock()"); - } - if ((tfd = pw_tmp(-1)) == -1) { - pw_fini(); - err(1, "pw_tmp()"); - } - if (pw_copy(pfd, tfd, pw, old_pw) == -1) { - pw_fini(); - err(1, "pw_copy()"); - } - /* - * in case of deletion of a user, the whole database - * needs to be regenerated - */ - if (pw_mkdb(pw != NULL ? pw->pw_name : NULL) == -1) { - pw_fini(); - err(1, "pw_mkdb()"); - } - free(pw); + struct passwd *pw = NULL; + struct passwd *old_pw = NULL; + int rc, pfd, tfd; + + if ((rc = pwdb_check()) != 0) + return (rc); + + if (pwd != NULL) + pw = pw_dup(pwd); + + if (user != NULL) + old_pw = GETPWNAM(user); + + if (pw_init(pwpath, NULL)) + err(1, "pw_init()"); + if ((pfd = pw_lock()) == -1) { pw_fini(); + err(1, "pw_lock()"); } - return 0; + if ((tfd = pw_tmp(-1)) == -1) { + pw_fini(); + err(1, "pw_tmp()"); + } + if (pw_copy(pfd, tfd, pw, old_pw) == -1) { + pw_fini(); + err(1, "pw_copy()"); + } + /* + * in case of deletion of a user, the whole database + * needs to be regenerated + */ + if (pw_mkdb(pw != NULL ? pw->pw_name : NULL) == -1) { + pw_fini(); + err(1, "pw_mkdb()"); + } + free(pw); + pw_fini(); + + return (0); } int addpwent(struct passwd * pwd) { - return pw_update(pwd, NULL); + + return (pw_update(pwd, NULL)); } int chgpwent(char const * login, struct passwd * pwd) { - return pw_update(pwd, login); + + return (pw_update(pwd, login)); } int @@ -167,5 +165,6 @@ delpwent(struct passwd * pwd) char login[MAXLOGNAME]; strlcpy(login, pwd->pw_name, MAXLOGNAME); - return pw_update(NULL, login); + + return (pw_update(NULL, login)); } diff --git a/usr.sbin/pw/pwupd.h b/usr.sbin/pw/pwupd.h index 200ffee..d6e39ce 100644 --- a/usr.sbin/pw/pwupd.h +++ b/usr.sbin/pw/pwupd.h @@ -112,10 +112,7 @@ void vendgrent(void); void copymkdir(char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid); void rm_r(char const * dir, uid_t uid); -int extendline(char **buf, int *buflen, int needed); int extendarray(char ***buf, int *buflen, int needed); __END_DECLS -#define PWBUFSZ 1024 - #endif /* !_PWUPD_H */ diff --git a/usr.sbin/pw/tests/Makefile b/usr.sbin/pw/tests/Makefile index 6bc9433..37d9c71 100644 --- a/usr.sbin/pw/tests/Makefile +++ b/usr.sbin/pw/tests/Makefile @@ -5,10 +5,18 @@ TESTSRC= ${.CURDIR}/../../../contrib/netbsd-tests/usr.sbin/useradd TESTSDIR= ${TESTSBASE}/usr.sbin/pw -ATF_TESTS_SH= pw_delete pw_lock pw_modify pw_etcdir +ATF_TESTS_SH= pw_etcdir \ + pw_lock \ + pw_groupdel \ + pw_groupmod \ + pw_useradd \ + pw_userdel \ + pw_usermod \ + pw_usernext -TEST_METADATA.pw_delete+= required_user="root" -TEST_METADATA.pw_modify+= required_user="root" +.for tp in ${ATF_TESTS_SH} +TEST_METADATA.${tp}+= required_user="root" +.endfor FILES= group helper_functions.shin master.passwd FILESDIR= ${TESTSDIR} diff --git a/usr.sbin/pw/tests/helper_functions.shin b/usr.sbin/pw/tests/helper_functions.shin index f87b1e7..3680dfe 100755 --- a/usr.sbin/pw/tests/helper_functions.shin +++ b/usr.sbin/pw/tests/helper_functions.shin @@ -1,5 +1,8 @@ # $FreeBSD$ +# The pw command +PW="pw -V ${HOME}" + # Workdir to run tests in TESTDIR=$(atf_get_srcdir) diff --git a/usr.sbin/pw/tests/pw_delete.sh b/usr.sbin/pw/tests/pw_delete.sh deleted file mode 100755 index 02a9ade..0000000 --- a/usr.sbin/pw/tests/pw_delete.sh +++ /dev/null @@ -1,47 +0,0 @@ -# $FreeBSD$ - -# Import helper functions -. $(atf_get_srcdir)/helper_functions.shin - -# Test that a user can be deleted when another user is part of this -# user's default group and does not go into an infinate loop. -# PR: 191427 -atf_test_case rmuser_seperate_group cleanup -rmuser_seperate_group_head() { - atf_set "timeout" "30" -} -rmuser_seperate_group_body() { - populate_etc_skel - pw -V ${HOME} useradd test || atf_fail "Creating test user" - pw -V ${HOME} groupmod test -M 'test,root' || \ - atf_fail "Modifying the group" - pw -V ${HOME} userdel test || atf_fail "Delete the test user" -} - -atf_test_case group_do_not_delete_wheel_if_group_unknown -group_do_not_delete_wheel_if_group_unknown_head() { - atf_set "descr" "Make sure we do not consider gid 0 an unknown group" -} - -group_do_not_delete_wheel_if_group_unknown_body() { - populate_etc_skel - atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x pw -V ${HOME} groupshow wheel - atf_check -e inline:"pw: -g expects a number\n" -s exit:64 -x pw -V ${HOME} groupdel -g I_do_not_exist - atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x pw -V ${HOME} groupshow wheel -} - -atf_test_case user_do_not_try_to_delete_root_if_user_unknown -user_do_not_try_to_delete_root_if_user_unknown_head() { - atf_set "descr" "Make sure not to try to remove root if deleting an unknown user" -} - -user_do_not_try_to_delete_root_if_user_unknown_body() { - populate_etc_skel - atf_check -e inline:"pw: -u expects a number\n" -s exit:64 -x pw -V ${HOME} userdel -u plop -} - -atf_init_test_cases() { - atf_add_test_case rmuser_seperate_group - atf_add_test_case group_do_not_delete_wheel_if_group_unknown - atf_add_test_case user_do_not_try_to_delete_root_if_user_unknown -} diff --git a/usr.sbin/pw/tests/pw_groupdel.sh b/usr.sbin/pw/tests/pw_groupdel.sh new file mode 100755 index 0000000..75b063a --- /dev/null +++ b/usr.sbin/pw/tests/pw_groupdel.sh @@ -0,0 +1,24 @@ +# $FreeBSD$ + +# Import helper functions +. $(atf_get_srcdir)/helper_functions.shin + + +# Test to make sure we do not accidentially delete wheel when trying to delete +# an unknown group +atf_test_case group_do_not_delete_wheel_if_group_unknown +group_do_not_delete_wheel_if_group_unknown_head() { + atf_set "descr" "Make sure we do not consider gid 0 an unknown group" +} +group_do_not_delete_wheel_if_group_unknown_body() { + populate_etc_skel + atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x ${PW} groupshow wheel + atf_check -e inline:"pw: -g expects a number\n" -s exit:64 -x \ + ${PW} groupdel -g I_do_not_exist + atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x ${PW} groupshow wheel +} + + +atf_init_test_cases() { + atf_add_test_case group_do_not_delete_wheel_if_group_unknown +} diff --git a/usr.sbin/pw/tests/pw_modify.sh b/usr.sbin/pw/tests/pw_groupmod.sh index b81f105..ad7ad0a 100755 --- a/usr.sbin/pw/tests/pw_modify.sh +++ b/usr.sbin/pw/tests/pw_groupmod.sh @@ -8,11 +8,11 @@ atf_test_case groupmod_user groupmod_user_body() { populate_etc_skel - atf_check -s exit:0 pw -V ${HOME} addgroup test - atf_check -s exit:0 pw -V ${HOME} groupmod test -m root + atf_check -s exit:0 ${PW} addgroup test + atf_check -s exit:0 ${PW} groupmod test -m root atf_check -s exit:0 -o match:"^test:\*:1001:root$" \ grep "^test:\*:.*:root$" $HOME/group - atf_check -s exit:0 pw -V ${HOME} groupmod test -d root + atf_check -s exit:0 ${PW} groupmod test -d root atf_check -s exit:0 -o match:"^test:\*:1001:$" \ grep "^test:\*:.*:$" $HOME/group } @@ -22,9 +22,9 @@ groupmod_user_body() { atf_test_case groupmod_invalid_user groupmod_invalid_user_body() { populate_etc_skel - atf_check -s exit:0 pw -V ${HOME} addgroup test - atf_check -s exit:67 -e match:"does not exist" pw -V ${HOME} groupmod test -m foo - atf_check -s exit:0 pw -V ${HOME} groupmod test -d foo + atf_check -s exit:0 ${PW} addgroup test + atf_check -s exit:67 -e match:"does not exist" ${PW} groupmod test -m foo + atf_check -s exit:0 ${PW} groupmod test -d foo } atf_test_case groupmod_bug_193704 @@ -33,9 +33,9 @@ groupmod_bug_193704_head() { } groupmod_bug_193704_body() { populate_etc_skel - atf_check -s exit:0 -x pw -V ${HOME} groupadd test - atf_check -s exit:0 -x pw -V ${HOME} groupmod test -l newgroupname - atf_check -s exit:65 -e match:"^pw: unknown group" -x pw -V ${HOME} groupshow test + atf_check -s exit:0 -x ${PW} groupadd test + atf_check -s exit:0 -x ${PW} groupmod test -l newgroupname + atf_check -s exit:65 -e match:"^pw: unknown group" -x ${PW} groupshow test } atf_test_case usermod_bug_185666 @@ -45,17 +45,17 @@ usermod_bug_185666_head() { usermod_bug_185666_body() { populate_etc_skel - atf_check -s exit:0 -x pw -V ${HOME} useradd testuser - atf_check -s exit:0 -x pw -V ${HOME} groupadd testgroup - atf_check -s exit:0 -x pw -V ${HOME} groupadd testgroup2 - atf_check -s exit:0 -x pw -V ${HOME} usermod testuser -G testgroup - atf_check -o inline:"testuser:*:1001:\n" -x pw -V${HOME} groupshow testuser - atf_check -o inline:"testgroup:*:1002:testuser\n" -x pw -V ${HOME} groupshow testgroup - atf_check -o inline:"testgroup2:*:1003:\n" -x pw -V${HOME} groupshow testgroup2 - atf_check -s exit:0 -x pw -V ${HOME} usermod testuser -G testgroup2 - atf_check -o inline:"testuser:*:1001:\n" -x pw -V ${HOME} groupshow testuser - atf_check -o inline:"testgroup:*:1002:\n" -x pw -V ${HOME} groupshow testgroup - atf_check -o inline:"testgroup2:*:1003:testuser\n" -x pw -V ${HOME} groupshow testgroup2 + atf_check -s exit:0 -x ${PW} useradd testuser + atf_check -s exit:0 -x ${PW} groupadd testgroup + atf_check -s exit:0 -x ${PW} groupadd testgroup2 + atf_check -s exit:0 -x ${PW} usermod testuser -G testgroup + atf_check -o inline:"testuser:*:1001:\n" -x ${PW} groupshow testuser + atf_check -o inline:"testgroup:*:1002:testuser\n" -x ${PW} groupshow testgroup + atf_check -o inline:"testgroup2:*:1003:\n" -x ${PW} groupshow testgroup2 + atf_check -s exit:0 -x ${PW} usermod testuser -G testgroup2 + atf_check -o inline:"testuser:*:1001:\n" -x ${PW} groupshow testuser + atf_check -o inline:"testgroup:*:1002:\n" -x ${PW} groupshow testgroup + atf_check -o inline:"testgroup2:*:1003:testuser\n" -x ${PW} groupshow testgroup2 } atf_test_case do_not_duplicate_group_on_gid_change @@ -65,8 +65,8 @@ do_not_duplicate_group_on_gid_change_head() { do_not_duplicate_group_on_gid_change_body() { populate_etc_skel - atf_check -s exit:0 -x pw -V ${HOME} groupadd testgroup - atf_check -s exit:0 -x pw -V ${HOME} groupmod testgroup -g 12345 + atf_check -s exit:0 -x ${PW} groupadd testgroup + atf_check -s exit:0 -x ${PW} groupmod testgroup -g 12345 # use grep to see if the entry has not be duplicated atf_check -o inline:"testgroup:*:12345:\n" -s exit:0 -x grep "^testgroup" ${HOME}/group } diff --git a/usr.sbin/pw/tests/pw_lock.sh b/usr.sbin/pw/tests/pw_lock.sh index 070a6f9..9f14e24 100755 --- a/usr.sbin/pw/tests/pw_lock.sh +++ b/usr.sbin/pw/tests/pw_lock.sh @@ -7,11 +7,11 @@ atf_test_case user_locking cleanup user_locking_body() { populate_etc_skel - pw -V ${HOME} useradd test || atf_fail "Creating test user" - pw -V ${HOME} lock test || atf_fail "Locking the user" + ${PW} useradd test || atf_fail "Creating test user" + ${PW} lock test || atf_fail "Locking the user" atf_check -s exit:0 -o match:"^test:\*LOCKED\*\*:1001:" \ grep "^test:\*LOCKED\*\*:1001:" $HOME/master.passwd - pw -V ${HOME} unlock test || atf_fail "Locking the user" + ${PW} unlock test || atf_fail "Locking the user" atf_check -s exit:0 -o match:"^test:\*:1001:" \ grep "^test:\*:1001:" $HOME/master.passwd } diff --git a/usr.sbin/pw/tests/pw_useradd.sh b/usr.sbin/pw/tests/pw_useradd.sh new file mode 100755 index 0000000..48612ed --- /dev/null +++ b/usr.sbin/pw/tests/pw_useradd.sh @@ -0,0 +1,188 @@ +# $FreeBSD$ + +# Import helper functions +. $(atf_get_srcdir)/helper_functions.shin + +# Test add user +atf_test_case user_add +user_add_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd test + atf_check -s exit:0 -o match:"^test:.*" \ + grep "^test:.*" $HOME/master.passwd +} + +# Test add user with option -N +atf_test_case user_add_noupdate +user_add_noupdate_body() { + populate_etc_skel + + atf_check -s exit:0 -o match:"^test:.*" ${PW} useradd test -N + atf_check -s exit:1 -o empty grep "^test:.*" $HOME/master.passwd +} + +# Test add user with comments +atf_test_case user_add_comments +user_add_comments_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd test -c "Test User,work,123,456" + atf_check -s exit:0 -o match:"^test:.*:Test User,work,123,456:" \ + grep "^test:.*:Test User,work,123,456:" $HOME/master.passwd +} + +# Test add user with comments and option -N +atf_test_case user_add_comments_noupdate +user_add_comments_noupdate_body() { + populate_etc_skel + + atf_check -s exit:0 -o match:"^test:.*:Test User,work,123,456:" \ + ${PW} useradd test -c "Test User,work,123,456" -N + atf_check -s exit:1 -o empty grep "^test:.*" $HOME/master.passwd +} + +# Test add user with invalid comments +atf_test_case user_add_comments_invalid +user_add_comments_invalid_body() { + populate_etc_skel + + atf_check -s exit:65 -e match:"invalid character" \ + ${PW} useradd test -c "Test User,work,123:456,456" + atf_check -s exit:1 -o empty \ + grep "^test:.*:Test User,work,123:456,456:" $HOME/master.passwd +} + +# Test add user with invalid comments and option -N +atf_test_case user_add_comments_invalid_noupdate +user_add_comments_invalid_noupdate_body() { + populate_etc_skel + + atf_check -s exit:65 -e match:"invalid character" \ + ${PW} useradd test -c "Test User,work,123:456,456" -N + atf_check -s exit:1 -o empty grep "^test:.*" $HOME/master.passwd +} + +# Test add user with alternate homedir +atf_test_case user_add_homedir +user_add_homedir_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd test -d /foo/bar + atf_check -s exit:0 -o match:"^test:\*:.*::0:0:User &:/foo/bar:.*" \ + ${PW} usershow test +} + +# Test add user with account expiration as an epoch date +atf_test_case user_add_account_expiration_epoch +user_add_account_expiration_epoch_body() { + populate_etc_skel + + DATE=`date -j -v+1d "+%s"` + atf_check -s exit:0 ${PW} useradd test -e ${DATE} + atf_check -s exit:0 -o match:"^test:\*:.*::0:${DATE}:.*" \ + ${PW} usershow test +} + +# Test add user with account expiration as a DD-MM-YYYY date +atf_test_case user_add_account_expiration_date_numeric +user_add_account_expiration_date_numeric_body() { + populate_etc_skel + + DATE=`date -j -v+1d "+%d-%m-%Y"` + EPOCH=`date -j -f "%d-%m-%Y %H:%M:%S" "${DATE} 00:00:00" "+%s"` + atf_check -s exit:0 ${PW} useradd test -e ${DATE} + atf_check -s exit:0 -o match:"^test:\*:.*::0:${EPOCH}:User &:.*" \ + ${PW} usershow test +} + +# Test add user with account expiration as a DD-MM-YYYY date +atf_test_case user_add_account_expiration_date_month +user_add_account_expiration_date_month_body() { + populate_etc_skel + + DATE=`date -j -v+1d "+%d-%b-%Y"` + EPOCH=`date -j -f "%d-%b-%Y %H:%M:%S" "${DATE} 00:00:00" "+%s"` + atf_check -s exit:0 ${PW} useradd test -e ${DATE} + atf_check -s exit:0 -o match:"^test:\*:.*::0:${EPOCH}:User &:.*" \ + ${PW} usershow test +} + +# Test add user with account expiration as a relative date +atf_test_case user_add_account_expiration_date_relative +user_add_account_expiration_date_relative_body() { + populate_etc_skel + + EPOCH=`date -j -v+13m "+%s"` + BUF=`expr $EPOCH + 5` + atf_check -s exit:0 ${PW} useradd test -e +13o + TIME=`${PW} usershow test | awk -F ':' '{print $7}'` + [ ! -z $TIME -a $TIME -ge $EPOCH -a $TIME -lt $BUF ] || \ + atf_fail "Expiration time($TIME) was not within $EPOCH - $BUF seconds." +} + +# Test add user with password expiration as an epoch date +atf_test_case user_add_password_expiration_epoch +user_add_password_expiration_epoch_body() { + populate_etc_skel + + DATE=`date -j -v+1d "+%s"` + atf_check -s exit:0 ${PW} useradd test -p ${DATE} + atf_check -s exit:0 -o match:"^test:\*:.*::${DATE}:0:.*" \ + ${PW} usershow test +} + +# Test add user with password expiration as a DD-MM-YYYY date +atf_test_case user_add_password_expiration_date_numeric +user_add_password_expiration_date_numeric_body() { + populate_etc_skel + + DATE=`date -j -v+1d "+%d-%m-%Y"` + EPOCH=`date -j -f "%d-%m-%Y %H:%M:%S" "${DATE} 00:00:00" "+%s"` + atf_check -s exit:0 ${PW} useradd test -p ${DATE} + atf_check -s exit:0 -o match:"^test:\*:.*::${EPOCH}:0:User &:.*" \ + ${PW} usershow test +} + +# Test add user with password expiration as a DD-MMM-YYYY date +atf_test_case user_add_password_expiration_date_month +user_add_password_expiration_date_month_body() { + populate_etc_skel + + DATE=`date -j -v+1d "+%d-%b-%Y"` + EPOCH=`date -j -f "%d-%b-%Y %H:%M:%S" "${DATE} 00:00:00" "+%s"` + atf_check -s exit:0 ${PW} useradd test -p ${DATE} + atf_check -s exit:0 -o match:"^test:\*:.*::${EPOCH}:0:User &:.*" \ + ${PW} usershow test +} + +# Test add user with password expiration as a relative date +atf_test_case user_add_password_expiration_date_relative +user_add_password_expiration_date_relative_body() { + populate_etc_skel + + EPOCH=`date -j -v+13m "+%s"` + BUF=`expr $EPOCH + 5` + atf_check -s exit:0 ${PW} useradd test -p +13o + TIME=`${PW} usershow test | awk -F ':' '{print $6}'` + [ ! -z $TIME -a $TIME -ge $EPOCH -a $TIME -lt $BUF ] || \ + atf_fail "Expiration time($TIME) was not within $EPOCH - $BUF seconds." +} + +atf_init_test_cases() { + atf_add_test_case user_add + atf_add_test_case user_add_noupdate + atf_add_test_case user_add_comments + atf_add_test_case user_add_comments_noupdate + atf_add_test_case user_add_comments_invalid + atf_add_test_case user_add_comments_invalid_noupdate + atf_add_test_case user_add_homedir + atf_add_test_case user_add_account_expiration_epoch + atf_add_test_case user_add_account_expiration_date_numeric + atf_add_test_case user_add_account_expiration_date_month + atf_add_test_case user_add_account_expiration_date_relative + atf_add_test_case user_add_password_expiration_epoch + atf_add_test_case user_add_password_expiration_date_numeric + atf_add_test_case user_add_password_expiration_date_month + atf_add_test_case user_add_password_expiration_date_relative +} diff --git a/usr.sbin/pw/tests/pw_userdel.sh b/usr.sbin/pw/tests/pw_userdel.sh new file mode 100755 index 0000000..71a7033 --- /dev/null +++ b/usr.sbin/pw/tests/pw_userdel.sh @@ -0,0 +1,37 @@ +# $FreeBSD$ + +# Import helper functions +. $(atf_get_srcdir)/helper_functions.shin + + +# Test that a user can be deleted when another user is part of this +# user's default group and does not go into an infinate loop. +# PR: 191427 +atf_test_case rmuser_seperate_group cleanup +rmuser_seperate_group_head() { + atf_set "timeout" "30" +} +rmuser_seperate_group_body() { + populate_etc_skel + ${PW} useradd test || atf_fail "Creating test user" + ${PW} groupmod test -M 'test,root' || \ + atf_fail "Modifying the group" + ${PW} userdel test || atf_fail "Delete the test user" +} + + +atf_test_case user_do_not_try_to_delete_root_if_user_unknown +user_do_not_try_to_delete_root_if_user_unknown_head() { + atf_set "descr" \ + "Make sure not to try to remove root if deleting an unknown user" +} +user_do_not_try_to_delete_root_if_user_unknown_body() { + populate_etc_skel + atf_check -e inline:"pw: -u expects a number\n" -s exit:64 -x \ + ${PW} userdel -u plop +} + +atf_init_test_cases() { + atf_add_test_case rmuser_seperate_group + atf_add_test_case user_do_not_try_to_delete_root_if_user_unknown +} diff --git a/usr.sbin/pw/tests/pw_usermod.sh b/usr.sbin/pw/tests/pw_usermod.sh new file mode 100755 index 0000000..88bd316 --- /dev/null +++ b/usr.sbin/pw/tests/pw_usermod.sh @@ -0,0 +1,112 @@ +# $FreeBSD$ + +# Import helper functions +. $(atf_get_srcdir)/helper_functions.shin + +# Test modifying a user +atf_test_case user_mod +user_mod_body() { + populate_etc_skel + + atf_check -s exit:67 -e match:"no such user" ${PW} usermod test + atf_check -s exit:0 ${PW} useradd test + atf_check -s exit:0 ${PW} usermod test + atf_check -s exit:0 -o match:"^test:.*" \ + grep "^test:.*" $HOME/master.passwd +} + +# Test modifying a user with option -N +atf_test_case user_mod_noupdate +user_mod_noupdate_body() { + populate_etc_skel + + atf_check -s exit:67 -e match:"no such user" ${PW} usermod test -N + atf_check -s exit:0 ${PW} useradd test + atf_check -s exit:0 -o match:"^test:.*" ${PW} usermod test -N + atf_check -s exit:0 -o match:"^test:.*" \ + grep "^test:.*" $HOME/master.passwd +} + +# Test modifying a user with comments +atf_test_case user_mod_comments +user_mod_comments_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd test -c "Test User,home,123,456" + atf_check -s exit:0 ${PW} usermod test -c "Test User,work,123,456" + atf_check -s exit:0 -o match:"^test:.*:Test User,work,123,456:" \ + grep "^test:.*:Test User,work,123,456:" $HOME/master.passwd +} + +# Test modifying a user with comments with option -N +atf_test_case user_mod_comments_noupdate +user_mod_comments_noupdate_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd test -c "Test User,home,123,456" + atf_check -s exit:0 -o match:"^test:.*:Test User,work,123,456:" \ + ${PW} usermod test -c "Test User,work,123,456" -N + atf_check -s exit:0 -o match:"^test:.*:Test User,home,123,456:" \ + grep "^test:.*:Test User,home,123,456:" $HOME/master.passwd +} + +# Test modifying a user with invalid comments +atf_test_case user_mod_comments_invalid +user_mod_comments_invalid_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd test + atf_check -s exit:65 -e match:"invalid character" \ + ${PW} usermod test -c "Test User,work,123:456,456" + atf_check -s exit:1 -o empty \ + grep "^test:.*:Test User,work,123:456,456:" $HOME/master.passwd + atf_check -s exit:0 -o match:"^test:\*" \ + grep "^test:\*" $HOME/master.passwd +} + +# Test modifying a user with invalid comments with option -N +atf_test_case user_mod_comments_invalid_noupdate +user_mod_comments_invalid_noupdate_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd test + atf_check -s exit:65 -e match:"invalid character" \ + ${PW} usermod test -c "Test User,work,123:456,456" -N + atf_check -s exit:1 -o empty \ + grep "^test:.*:Test User,work,123:456,456:" $HOME/master.passwd + atf_check -s exit:0 -o match:"^test:\*" \ + grep "^test:\*" $HOME/master.passwd +} + +# Test modifying a user name with -l +atf_test_case user_mod_name +user_mod_name_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo + atf_check -s exit:0 ${PW} usermod foo -l "bar" + atf_check -s exit:0 -o match:"^bar:.*" \ + grep "^bar:.*" $HOME/master.passwd +} + +# Test modifying a user name with -l with option -N +atf_test_case user_mod_name_noupdate +user_mod_name_noupdate_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo + atf_check -s exit:0 -o match:"^bar:.*" ${PW} usermod foo -l "bar" -N + atf_check -s exit:0 -o match:"^foo:.*" \ + grep "^foo:.*" $HOME/master.passwd +} + +atf_init_test_cases() { + atf_add_test_case user_mod + atf_add_test_case user_mod_noupdate + atf_add_test_case user_mod_comments + atf_add_test_case user_mod_comments_noupdate + atf_add_test_case user_mod_comments_invalid + atf_add_test_case user_mod_comments_invalid_noupdate + atf_add_test_case user_mod_name + atf_add_test_case user_mod_name_noupdate +} diff --git a/usr.sbin/pw/tests/pw_usernext.sh b/usr.sbin/pw/tests/pw_usernext.sh new file mode 100755 index 0000000..89f938e --- /dev/null +++ b/usr.sbin/pw/tests/pw_usernext.sh @@ -0,0 +1,45 @@ +# $FreeBSD$ + +# Import helper functions +. $(atf_get_srcdir)/helper_functions.shin + +# Test usernext after adding a random number of new users. +atf_test_case usernext +usernext_body() { + populate_etc_skel + + CURRENT=`${PW} usernext | sed -e 's/:.*//'` + RANDOM=`jot -r 1 1 150` + MAX=`expr ${CURRENT} + ${RANDOM}` + while [ "${CURRENT}" -lt "${MAX}" ] + do + atf_check -s exit:0 ${PW} useradd test${CURRENT} + CURRENT=`expr ${CURRENT} + 1` + done + atf_check -s exit:0 -o match:"${CURRENT}:${CURRENT}" \ + ${PW} usernext +} + +# Test usernext when multiple users are added to the same group so +# that group id doesn't increment at the same pace as new users. +atf_test_case usernext_assigned_group +usernext_assigned_group_body() { + populate_etc_skel + + CURRENT=`${PW} usernext | sed -e 's/:.*//'` + CURRENTGID=`${PW} groupnext` + RANDOM=`jot -r 1 1 150` + MAX=`expr ${CURRENT} + ${RANDOM}` + while [ "${CURRENT}" -lt "${MAX}" ] + do + atf_check -s exit:0 ${PW} useradd -n test${CURRENT} -g 0 + CURRENT=`expr ${CURRENT} + 1` + done + atf_check -s exit:0 -o match:"${CURRENT}:${CURRENTGID}" \ + ${PW} usernext +} + +atf_init_test_cases() { + atf_add_test_case usernext + atf_add_test_case usernext_assigned_group +} diff --git a/usr.sbin/quotaon/Makefile b/usr.sbin/quotaon/Makefile index 23ba8d1..ec3dc1a 100644 --- a/usr.sbin/quotaon/Makefile +++ b/usr.sbin/quotaon/Makefile @@ -6,7 +6,6 @@ LINKS= ${BINDIR}/quotaon ${BINDIR}/quotaoff MAN= quotaon.8 MLINKS= quotaon.8 quotaoff.8 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/rarpd/Makefile b/usr.sbin/rarpd/Makefile index 52a9f92..b7816cd 100644 --- a/usr.sbin/rarpd/Makefile +++ b/usr.sbin/rarpd/Makefile @@ -4,8 +4,7 @@ PROG= rarpd MAN= rarpd.8 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util WARNS?= 3 # This breaks with format strings returned by expand_syslog_m().. argh! diff --git a/usr.sbin/repquota/Makefile b/usr.sbin/repquota/Makefile index ed80132..78fd398 100644 --- a/usr.sbin/repquota/Makefile +++ b/usr.sbin/repquota/Makefile @@ -3,7 +3,6 @@ PROG= repquota MAN= repquota.8 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/rip6query/rip6query.c b/usr.sbin/rip6query/rip6query.c index ea448ba2..a35c750 100644 --- a/usr.sbin/rip6query/rip6query.c +++ b/usr.sbin/rip6query/rip6query.c @@ -46,9 +46,6 @@ #include <sys/queue.h> #include <net/if.h> -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include <net/if_var.h> -#endif /* __FreeBSD__ >= 3 */ #include <netinet/in.h> #include <netinet/in_var.h> #include <arpa/inet.h> diff --git a/usr.sbin/route6d/route6d.c b/usr.sbin/route6d/route6d.c index 258219b..3c3d9d3 100644 --- a/usr.sbin/route6d/route6d.c +++ b/usr.sbin/route6d/route6d.c @@ -63,7 +63,6 @@ static const char _rcsid[] = "$KAME: route6d.c,v 1.104 2003/10/31 00:30:20 itoju #include <sys/sysctl.h> #include <sys/uio.h> #include <net/if.h> -#include <net/if_var.h> #include <net/route.h> #include <netinet/in.h> #include <netinet/in_var.h> diff --git a/usr.sbin/rpc.lockd/Makefile b/usr.sbin/rpc.lockd/Makefile index 139f4bc..73c69ef 100644 --- a/usr.sbin/rpc.lockd/Makefile +++ b/usr.sbin/rpc.lockd/Makefile @@ -9,8 +9,7 @@ SRCS= kern.c nlm_prot_svc.c lockd.c lock_proc.c lockd_lock.c CFLAGS+= -I. -I${DESTDIR}/usr/include/rpcsvc WARNS?= 3 -DPADD= ${LIBRPCSVC} ${LIBUTIL} -LDADD= -lrpcsvc -lutil +LIBADD= rpcsvc CLEANFILES= nlm_prot_svc.c nlm_prot.h test diff --git a/usr.sbin/rpc.lockd/lockd.c b/usr.sbin/rpc.lockd/lockd.c index 2974acb..4f1347e 100644 --- a/usr.sbin/rpc.lockd/lockd.c +++ b/usr.sbin/rpc.lockd/lockd.c @@ -518,7 +518,6 @@ create_service(struct netconfig *nconf) /* Get rpc.statd's address on this transport */ memset(&hints, 0, sizeof hints); - hints.ai_flags = AI_PASSIVE; hints.ai_family = si.si_af; hints.ai_socktype = si.si_socktype; hints.ai_protocol = si.si_proto; @@ -534,6 +533,7 @@ create_service(struct netconfig *nconf) out_of_mem(); sock_fd[sock_fdcnt++] = -1; /* Set invalid for now. */ mallocd_res = 0; + hints.ai_flags = AI_PASSIVE; /* * XXX - using RPC library internal functions. diff --git a/usr.sbin/rpc.statd/Makefile b/usr.sbin/rpc.statd/Makefile index 6fa2b1e..43504e4 100644 --- a/usr.sbin/rpc.statd/Makefile +++ b/usr.sbin/rpc.statd/Makefile @@ -7,8 +7,7 @@ SRCS= file.c sm_inter_svc.c sm_inter.h statd.c procs.c CFLAGS+= -I. WARNS?= 2 -DPADD= ${LIBRPCSVC} -LDADD= -lrpcsvc +LIBADD= rpcsvc CLEANFILES= sm_inter_svc.c sm_inter.h diff --git a/usr.sbin/rpc.statd/statd.c b/usr.sbin/rpc.statd/statd.c index ff537f8..faa8513 100644 --- a/usr.sbin/rpc.statd/statd.c +++ b/usr.sbin/rpc.statd/statd.c @@ -343,7 +343,6 @@ create_service(struct netconfig *nconf) /* Get rpc.statd's address on this transport */ memset(&hints, 0, sizeof hints); - hints.ai_flags = AI_PASSIVE; hints.ai_family = si.si_af; hints.ai_socktype = si.si_socktype; hints.ai_protocol = si.si_proto; @@ -359,6 +358,7 @@ create_service(struct netconfig *nconf) out_of_mem(); sock_fd[sock_fdcnt++] = -1; /* Set invalid for now. */ mallocd_res = 0; + hints.ai_flags = AI_PASSIVE; /* * XXX - using RPC library internal functions. diff --git a/usr.sbin/rpc.umntall/rpc.umntall.8 b/usr.sbin/rpc.umntall/rpc.umntall.8 index 7f294a0..1f7607f 100644 --- a/usr.sbin/rpc.umntall/rpc.umntall.8 +++ b/usr.sbin/rpc.umntall/rpc.umntall.8 @@ -114,8 +114,8 @@ entry. mounted nfs-file systems .El .Sh SEE ALSO -.Xr mountd 8 , .Xr mount_nfs 8 , +.Xr mountd 8 , .Xr umount 8 .Sh HISTORY The diff --git a/usr.sbin/rpc.yppasswdd/Makefile b/usr.sbin/rpc.yppasswdd/Makefile index a9d3a75..5f5fb77 100644 --- a/usr.sbin/rpc.yppasswdd/Makefile +++ b/usr.sbin/rpc.yppasswdd/Makefile @@ -20,8 +20,7 @@ CFLAGS+= -I${.CURDIR}/../../usr.sbin/vipw \ -I${.CURDIR}/../../usr.sbin/ypserv \ -I${.CURDIR}/../../libexec/ypxfr \ -I${.CURDIR} -I. -DPADD= ${LIBRPCSVC} ${LIBCRYPT} ${LIBUTIL} -LDADD= -lrpcsvc -lcrypt -lutil +LIBADD= rpcsvc crypt util CLEANFILES= ${GENSRCS} diff --git a/usr.sbin/rpc.ypupdated/Makefile b/usr.sbin/rpc.ypupdated/Makefile index 03c1142..d5c346e 100644 --- a/usr.sbin/rpc.ypupdated/Makefile +++ b/usr.sbin/rpc.ypupdated/Makefile @@ -13,8 +13,7 @@ CFLAGS+= -I${.CURDIR}/../ypserv -I. -I${.CURDIR}/../../libexec/ypxfr WARNS?= 1 -DPADD= ${LIBRPCSVC} -LDADD= -lrpcsvc +LIBADD= rpcsvc CLEANFILES= ypupdate_prot_svc.c ypupdate_prot.h diff --git a/usr.sbin/rpc.ypxfrd/Makefile b/usr.sbin/rpc.ypxfrd/Makefile index 05971b1..903ac16 100644 --- a/usr.sbin/rpc.ypxfrd/Makefile +++ b/usr.sbin/rpc.ypxfrd/Makefile @@ -11,8 +11,7 @@ CFLAGS+= -I. -DXFRBLOCKSIZE=65535 WARNS?= 2 -DPADD= ${LIBRPCSVC} -LDADD= -lrpcsvc +LIBADD= rpcsvc CLEANFILES= ypxfrd_svc.c ypxfrd.h diff --git a/usr.sbin/rpcbind/Makefile b/usr.sbin/rpcbind/Makefile index 44a030e..2b679f4 100644 --- a/usr.sbin/rpcbind/Makefile +++ b/usr.sbin/rpcbind/Makefile @@ -16,7 +16,6 @@ CFLAGS+= -DINET6 WARNS?= 1 -DPADD= ${LIBWRAP} -LDADD= -lwrap +LIBADD= wrap .include <bsd.prog.mk> diff --git a/usr.sbin/rrenumd/Makefile b/usr.sbin/rrenumd/Makefile index 091e528..8c82fc3 100644 --- a/usr.sbin/rrenumd/Makefile +++ b/usr.sbin/rrenumd/Makefile @@ -23,8 +23,7 @@ YFLAGS= -d WARNS?= 2 -LDADD= -lipsec -ll -ly -DPADD= ${LIBIPSEC} ${LIBL} ${LIBY} +LIBADD= ipsec l y CLEANFILES= y.tab.h SRCS+= y.tab.h diff --git a/usr.sbin/rrenumd/Makefile.depend b/usr.sbin/rrenumd/Makefile.depend index fdcd9a0..9ea337d 100644 --- a/usr.sbin/rrenumd/Makefile.depend +++ b/usr.sbin/rrenumd/Makefile.depend @@ -14,6 +14,7 @@ DIRDEPS = \ lib/libipsec \ lib/liby \ usr.bin/lex/lib \ + usr.bin/yacc.host \ .include <dirdeps.mk> diff --git a/usr.sbin/rrenumd/lexer.l b/usr.sbin/rrenumd/lexer.l index 6e55f9e..47656e8 100644 --- a/usr.sbin/rrenumd/lexer.l +++ b/usr.sbin/rrenumd/lexer.l @@ -40,10 +40,6 @@ #include <string.h> #include <net/if.h> -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include <net/if_var.h> -#endif /* __FreeBSD__ >= 3 */ - #include <netinet/in.h> #include <netinet/in_var.h> #include <netinet/icmp6.h> diff --git a/usr.sbin/rrenumd/parser.y b/usr.sbin/rrenumd/parser.y index 65dfd46..6436df7 100644 --- a/usr.sbin/rrenumd/parser.y +++ b/usr.sbin/rrenumd/parser.y @@ -39,9 +39,6 @@ #include <sys/queue.h> #include <net/if.h> -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include <net/if_var.h> -#endif /* __FreeBSD__ >= 3 */ #include <netinet/in.h> #include <netinet/in_var.h> diff --git a/usr.sbin/rtadvctl/rtadvctl.8 b/usr.sbin/rtadvctl/rtadvctl.8 index 5df6e5c..4b7c888 100644 --- a/usr.sbin/rtadvctl/rtadvctl.8 +++ b/usr.sbin/rtadvctl/rtadvctl.8 @@ -92,8 +92,8 @@ Displays information on Router Advertisement messages being sent on each interface. .El .Sh SEE ALSO -.Xr rtadvd 8 , -.Xr rtadvd.conf 5 +.Xr rtadvd.conf 5 , +.Xr rtadvd 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/rtadvctl/rtadvctl.c b/usr.sbin/rtadvctl/rtadvctl.c index 3f22518..f1657d7 100644 --- a/usr.sbin/rtadvctl/rtadvctl.c +++ b/usr.sbin/rtadvctl/rtadvctl.c @@ -36,7 +36,6 @@ #include <net/if.h> #include <net/if_dl.h> #include <net/if_types.h> -#include <net/if_var.h> #include <net/ethernet.h> #include <netinet/in.h> #include <netinet/ip6.h> diff --git a/usr.sbin/rtadvd/Makefile b/usr.sbin/rtadvd/Makefile index d48832d..33e90b6 100644 --- a/usr.sbin/rtadvd/Makefile +++ b/usr.sbin/rtadvd/Makefile @@ -19,8 +19,7 @@ MAN= rtadvd.conf.5 rtadvd.8 SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c timer_subr.c \ control.c control_server.c -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util CFLAGS+= -DHAVE_ARC4RANDOM diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c index 5c9d778..4f14e0fb 100644 --- a/usr.sbin/rtadvd/config.c +++ b/usr.sbin/rtadvd/config.c @@ -36,7 +36,6 @@ #include <sys/socket.h> #include <net/if.h> -#include <net/if_var.h> #include <net/route.h> #include <net/if_dl.h> diff --git a/usr.sbin/rtadvd/if.c b/usr.sbin/rtadvd/if.c index 5413cdf..0eef734 100644 --- a/usr.sbin/rtadvd/if.c +++ b/usr.sbin/rtadvd/if.c @@ -38,7 +38,6 @@ #include <net/if.h> #include <net/if_dl.h> #include <net/if_types.h> -#include <net/if_var.h> #include <net/ethernet.h> #include <net/route.h> #include <netinet/in.h> diff --git a/usr.sbin/rtadvd/rrenum.c b/usr.sbin/rtadvd/rrenum.c index 0c97d98..eede4b6 100644 --- a/usr.sbin/rtadvd/rrenum.c +++ b/usr.sbin/rtadvd/rrenum.c @@ -37,7 +37,6 @@ #include <net/if.h> #include <net/if_dl.h> -#include <net/if_var.h> #include <net/route.h> #include <netinet/in.h> #include <netinet/in_var.h> diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c index ba71954..0169a56 100644 --- a/usr.sbin/rtadvd/rtadvd.c +++ b/usr.sbin/rtadvd/rtadvd.c @@ -51,7 +51,6 @@ #include <arpa/inet.h> -#include <net/if_var.h> #include <netinet/in_var.h> #include <netinet6/nd6.h> @@ -1230,6 +1229,12 @@ ra_input(int len, struct nd_router_advert *nra, return; } +static uint32_t +udiff(uint32_t u, uint32_t v) +{ + return (u >= v ? u - v : v - u); +} + /* return a non-zero value if the received prefix is inconsitent with ours */ static int prefix_check(struct nd_opt_prefix_info *pinfo, @@ -1288,7 +1293,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo, preferred_time += now.tv_sec; if (!pfx->pfx_timer && rai->rai_clockskew && - abs(preferred_time - pfx->pfx_pltimeexpire) > rai->rai_clockskew) { + udiff(preferred_time, pfx->pfx_pltimeexpire) > rai->rai_clockskew) { syslog(LOG_INFO, "<%s> preferred lifetime for %s/%d" " (decr. in real time) inconsistent on %s:" @@ -1321,7 +1326,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo, valid_time += now.tv_sec; if (!pfx->pfx_timer && rai->rai_clockskew && - abs(valid_time - pfx->pfx_vltimeexpire) > rai->rai_clockskew) { + udiff(valid_time, pfx->pfx_vltimeexpire) > rai->rai_clockskew) { syslog(LOG_INFO, "<%s> valid lifetime for %s/%d" " (decr. in real time) inconsistent on %s:" diff --git a/usr.sbin/rtadvd/rtadvd.conf.5 b/usr.sbin/rtadvd/rtadvd.conf.5 index e8b3011..d4a0c02 100644 --- a/usr.sbin/rtadvd/rtadvd.conf.5 +++ b/usr.sbin/rtadvd/rtadvd.conf.5 @@ -488,8 +488,8 @@ ef0:\\ :addr="2001:db8:ffff:1000::":prefixlen#64:tc=default: .Ed .Sh SEE ALSO -.Xr termcap 5 , .Xr resolver 5 , +.Xr termcap 5 , .Xr rtadvd 8 , .Xr rtsol 8 .Rs diff --git a/usr.sbin/rtsold/Makefile b/usr.sbin/rtsold/Makefile index efc322c..a235dfb 100644 --- a/usr.sbin/rtsold/Makefile +++ b/usr.sbin/rtsold/Makefile @@ -21,7 +21,5 @@ SRCS= rtsold.c rtsol.c if.c probe.c dump.c rtsock.c WARNS?= 3 CFLAGS+= -DHAVE_ARC4RANDOM -DHAVE_POLL_H -DPADD= ${LIBKVM} -LDADD= -lkvm .include <bsd.prog.mk> diff --git a/usr.sbin/rtsold/Makefile.depend b/usr.sbin/rtsold/Makefile.depend index 3820cc8..b68b4bb 100644 --- a/usr.sbin/rtsold/Makefile.depend +++ b/usr.sbin/rtsold/Makefile.depend @@ -11,7 +11,6 @@ DIRDEPS = \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ - lib/libkvm \ .include <dirdeps.mk> diff --git a/usr.sbin/rtsold/if.c b/usr.sbin/rtsold/if.c index 2bf946d..b8a90b6 100644 --- a/usr.sbin/rtsold/if.c +++ b/usr.sbin/rtsold/if.c @@ -38,7 +38,6 @@ #include <sys/queue.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_types.h> #include <net/route.h> #include <net/if_dl.h> @@ -248,9 +247,7 @@ lladdropt_length(struct sockaddr_dl *sdl) { switch (sdl->sdl_type) { case IFT_ETHER: -#ifdef IFT_IEEE80211 case IFT_IEEE80211: -#endif return (ROUNDUP8(ETHER_ADDR_LEN + 2)); default: return (0); @@ -266,9 +263,7 @@ lladdropt_fill(struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt) switch (sdl->sdl_type) { case IFT_ETHER: -#ifdef IFT_IEEE80211 case IFT_IEEE80211: -#endif ndopt->nd_opt_len = (ROUNDUP8(ETHER_ADDR_LEN + 2)) >> 3; addr = (char *)(ndopt + 1); memcpy(addr, LLADDR(sdl), ETHER_ADDR_LEN); diff --git a/usr.sbin/rtsold/probe.c b/usr.sbin/rtsold/probe.c index 5ec54aa..89a1617a 100644 --- a/usr.sbin/rtsold/probe.c +++ b/usr.sbin/rtsold/probe.c @@ -40,7 +40,6 @@ #include <sys/queue.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_dl.h> #include <netinet/in.h> diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c index a97b884..bba15bb 100644 --- a/usr.sbin/rtsold/rtsold.c +++ b/usr.sbin/rtsold/rtsold.c @@ -38,7 +38,6 @@ #include <net/if.h> #include <net/if_dl.h> -#include <net/if_var.h> #include <netinet/in.h> #include <netinet/icmp6.h> diff --git a/usr.sbin/sa/db.c b/usr.sbin/sa/db.c index 557f406..6634e54 100644 --- a/usr.sbin/sa/db.c +++ b/usr.sbin/sa/db.c @@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$"); #include "extern.h" /* Key used to store the version of the database data elements. */ -#define VERSION_KEY "\0VERSION" +static char VERSION_KEY[] = "\0VERSION"; /* * Create the in-memory database, *mdb. diff --git a/usr.sbin/sendmail/Makefile b/usr.sbin/sendmail/Makefile index 893b6fd..1537d33 100644 --- a/usr.sbin/sendmail/Makefile +++ b/usr.sbin/sendmail/Makefile @@ -45,17 +45,7 @@ CFLAGS+= -DNETINET6 WARNS?= 1 -DPADD= ${LIBUTIL} ${LIBWRAP} -LDADD= -lutil -lwrap - -LIBSMDIR= ${.OBJDIR}/../../lib/libsm -LIBSM= ${LIBSMDIR}/libsm.a - -LIBSMUTILDIR= ${.OBJDIR}/../../lib/libsmutil -LIBSMUTIL= ${LIBSMUTILDIR}/libsmutil.a - -DPADD+= ${LIBSMUTIL} ${LIBSM} -LDADD+= ${LIBSMUTIL} ${LIBSM} +LIBADD= util wrap sm smutil SRCS+= sm_os.h CLEANFILES+=sm_os.h @@ -63,8 +53,7 @@ CLEANFILES+=sm_os.h .if ${MK_OPENSSL} != "no" # STARTTLS support CFLAGS+= -DSTARTTLS -D_FFR_TLS_1 -DPADD+= ${LIBSSL} ${LIBCRYPTO} -LDADD+= -lssl -lcrypto +LIBADD+= ssl crypto .endif # User customizations to the sendmail build environment diff --git a/usr.sbin/services_mkdb/Makefile b/usr.sbin/services_mkdb/Makefile index e61c6df..05a4b76 100644 --- a/usr.sbin/services_mkdb/Makefile +++ b/usr.sbin/services_mkdb/Makefile @@ -4,7 +4,6 @@ PROG= services_mkdb MAN= services_mkdb.8 SRCS= services_mkdb.c uniq.c extern.h -DPADD+= ${LIBUTIL} -LDADD+= -lutil +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/smbmsg/smbmsg.c b/usr.sbin/smbmsg/smbmsg.c index 425b782..4e7e609 100644 --- a/usr.sbin/smbmsg/smbmsg.c +++ b/usr.sbin/smbmsg/smbmsg.c @@ -163,7 +163,8 @@ do_io(void) } if (iflag == 1 && oflag == -1) { /* command + 1 byte input: read byte op. */ - c.data.byte_ptr = ibuf; + c.rbuf = ibuf; + c.rcount = iflag; if (ioctl(fd, SMB_READB, &c) == -1) return (-1); printf(fmt, (int)(unsigned char)ibuf[0]); @@ -171,11 +172,12 @@ do_io(void) return (0); } else if (iflag == -1 && oflag == 1) { /* command + 1 byte output: write byte op. */ - c.data.byte = obuf[0]; + c.wdata.byte = obuf[0]; return (ioctl(fd, SMB_WRITEB, &c)); } else if (wflag && iflag == 2 && oflag == -1) { /* command + 2 bytes input: read word op. */ - c.data.word_ptr = &iword; + c.rbuf = (char*) &iword; + c.rcount = iflag; if (ioctl(fd, SMB_READW, &c) == -1) return (-1); printf(fmt, (int)(unsigned short)iword); @@ -183,15 +185,16 @@ do_io(void) return (0); } else if (wflag && iflag == -1 && oflag == 2) { /* command + 2 bytes output: write word op. */ - c.data.word = oword; + c.wdata.word = oword; return (ioctl(fd, SMB_WRITEW, &c)); } else if (wflag && iflag == 2 && oflag == 2) { /* * command + 2 bytes output + 2 bytes input: * "process call" op. */ - c.data.process.sdata = oword; - c.data.process.rdata = &iword; + c.wdata.word = oword; + c.rbuf = (char*) &iword; + c.rcount = iflag; if (ioctl(fd, SMB_PCALL, &c) == -1) return (-1); printf(fmt, (int)(unsigned short)iword); @@ -199,8 +202,8 @@ do_io(void) return (0); } else if (iflag > 1 && oflag == -1) { /* command + > 1 bytes of input: block read */ - c.data.byte_ptr = ibuf; - c.count = iflag; + c.rbuf = ibuf; + c.rcount = iflag; if (ioctl(fd, SMB_BREAD, &c) == -1) return (-1); for (i = 0; i < iflag; i++) { @@ -212,8 +215,8 @@ do_io(void) return (0); } else if (iflag == -1 && oflag > 1) { /* command + > 1 bytes of output: block write */ - c.data.byte_ptr = obuf; - c.count = oflag; + c.wbuf = obuf; + c.wcount = oflag; return (ioctl(fd, SMB_BWRITE, &c)); } diff --git a/usr.sbin/snapinfo/Makefile b/usr.sbin/snapinfo/Makefile index c5175f1..7601374 100644 --- a/usr.sbin/snapinfo/Makefile +++ b/usr.sbin/snapinfo/Makefile @@ -4,7 +4,6 @@ PROG= snapinfo MAN= snapinfo.8 -DPADD= ${LIBUFS} -LDADD= -lufs +LIBADD= ufs -.include <bsd.prog.mk> +.include <bsd.prog.mk> diff --git a/usr.sbin/spray/Makefile b/usr.sbin/spray/Makefile index c2515e0..f007072 100644 --- a/usr.sbin/spray/Makefile +++ b/usr.sbin/spray/Makefile @@ -3,7 +3,6 @@ PROG= spray MAN= spray.8 -DPADD= ${LIBRPCSVC} -LDADD= -lrpcsvc +LIBADD= rpcsvc .include <bsd.prog.mk> diff --git a/usr.sbin/syslogd/Makefile b/usr.sbin/syslogd/Makefile index 069e093..716efbe 100644 --- a/usr.sbin/syslogd/Makefile +++ b/usr.sbin/syslogd/Makefile @@ -9,8 +9,7 @@ PROG= syslogd MAN= syslog.conf.5 syslogd.8 SRCS= syslogd.c ttymsg.c -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util WARNS?= 3 diff --git a/usr.sbin/syslogd/pathnames.h b/usr.sbin/syslogd/pathnames.h index 24fbc4c..00631e0 100644 --- a/usr.sbin/syslogd/pathnames.h +++ b/usr.sbin/syslogd/pathnames.h @@ -30,8 +30,6 @@ * $FreeBSD$ */ -#include <paths.h> - #define _PATH_KLOG "/dev/klog" #define _PATH_LOGCONF "/etc/syslog.conf" #define _PATH_LOGPID "/var/run/syslog.pid" diff --git a/usr.sbin/syslogd/syslogd.8 b/usr.sbin/syslogd/syslogd.8 index 5b175a6..b2e8818 100644 --- a/usr.sbin/syslogd/syslogd.8 +++ b/usr.sbin/syslogd/syslogd.8 @@ -28,7 +28,7 @@ .\" @(#)syslogd.8 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd May 13, 2008 +.Dd March 3, 2015 .Dt SYSLOGD 8 .Os .Sh NAME @@ -36,7 +36,7 @@ .Nd log systems messages .Sh SYNOPSIS .Nm -.Op Fl 468ACcdkNnosTuv +.Op Fl 468ACcdFkNnosTuv .Op Fl a Ar allowed_peer .Op Fl b Ar bind_address .Op Fl f Ar config_file @@ -213,6 +213,17 @@ This is probably only of use to developers working on Specify the pathname of an alternate configuration file; the default is .Pa /etc/syslog.conf . +.It Fl F +Run +.Nm +in the foreground, rather than going into daemon mode. This is useful if +some other process uses +.Xr fork 2 +and +.Xr exec 3 +to run +.Nm , +and wants to monitor when and how it exits. .It Fl k Disable the translation of messages received with facility diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index 60c74d1..baa79c8 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -271,6 +271,7 @@ static struct filed *Files; /* Log files that we write to */ static struct filed consfile; /* Console */ static int Debug; /* debug flag */ +static int Foreground = 0; /* Run in foreground, instead of daemonizing */ static int resolve = 1; /* resolve hostname */ static char LocalHostName[MAXHOSTNAMELEN]; /* our hostname */ static const char *LocalDomain; /* our local domain name */ @@ -360,7 +361,7 @@ main(int argc, char *argv[]) dprintf("madvise() failed: %s\n", strerror(errno)); bindhostname = NULL; - while ((ch = getopt(argc, argv, "468Aa:b:cCdf:kl:m:nNop:P:sS:Tuv")) + while ((ch = getopt(argc, argv, "468Aa:b:cCdf:Fkl:m:nNop:P:sS:Tuv")) != -1) switch (ch) { case '4': @@ -396,6 +397,9 @@ main(int argc, char *argv[]) case 'f': /* configuration file */ ConfFile = optarg; break; + case 'F': /* run in foreground instead of daemon */ + Foreground++; + break; case 'k': /* keep remote kern fac */ KeepKernFac = 1; break; @@ -487,14 +491,14 @@ main(int argc, char *argv[]) warn("cannot open pid file"); } - if (!Debug) { + if ((!Foreground) && (!Debug)) { ppid = waitdaemon(0, 0, 30); if (ppid < 0) { warn("could not become daemon"); pidfile_remove(pfh); exit(1); } - } else { + } else if (Debug) { setlinebuf(stdout); } @@ -557,7 +561,8 @@ main(int argc, char *argv[]) if (finet) { if (SecureMode) { for (i = 0; i < *finet; i++) { - if (shutdown(finet[i+1], SHUT_RD) < 0) { + if (shutdown(finet[i+1], SHUT_RD) < 0 && + errno != ENOTCONN) { logerror("shutdown"); if (!Debug) die(0); @@ -713,7 +718,7 @@ usage(void) { fprintf(stderr, "%s\n%s\n%s\n%s\n", - "usage: syslogd [-468ACcdknosTuv] [-a allowed_peer]", + "usage: syslogd [-468ACcdFknosTuv] [-a allowed_peer]", " [-b bind_address] [-f config_file]", " [-l [mode:]path] [-m mark_interval]", " [-P pid_file] [-p log_socket]"); @@ -1020,7 +1025,7 @@ logmsg(int pri, const char *msg, const char *from, int flags) */ if (no_compress - (f->f_type != F_PIPE) < 1 && (flags & MARK) == 0 && msglen == f->f_prevlen && - f->f_prevline && !strcmp(msg, f->f_prevline) && + !strcmp(msg, f->f_prevline) && !strcasecmp(from, f->f_prevhost)) { (void)strlcpy(f->f_lasttime, timestamp, sizeof(f->f_lasttime)); @@ -1175,11 +1180,9 @@ fprintlog(struct filed *f, int flags, const char *msg) v->iov_base = repbuf; v->iov_len = snprintf(repbuf, sizeof repbuf, "last message repeated %d times", f->f_prevcount); - } else if (f->f_prevline) { + } else { v->iov_base = f->f_prevline; v->iov_len = f->f_prevlen; - } else { - return; } v++; @@ -1542,7 +1545,7 @@ init(int signo) struct filed *f, *next, **nextp; char *p; char cline[LINE_MAX]; - char prog[NAME_MAX+1]; + char prog[LINE_MAX]; char host[MAXHOSTNAMELEN]; char oldLocalHostName[MAXHOSTNAMELEN]; char hostMsg[2*MAXHOSTNAMELEN+40]; @@ -1664,7 +1667,7 @@ init(int signo) (void)strlcpy(prog, "*", sizeof(prog)); continue; } - for (i = 0; i < NAME_MAX; i++) { + for (i = 0; i < LINE_MAX - 1; i++) { if (!isprint(p[i]) || isspace(p[i])) break; prog[i] = p[i]; diff --git a/usr.sbin/sysrc/sysrc b/usr.sbin/sysrc/sysrc index 8a1a863..67b5e14 100644 --- a/usr.sbin/sysrc/sysrc +++ b/usr.sbin/sysrc/sysrc @@ -1,6 +1,6 @@ #!/bin/sh #- -# Copyright (c) 2010-2014 Devin Teske +# Copyright (c) 2010-2015 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -40,7 +40,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig" # # Version information # -SYSRC_VERSION="6.2 Nov-3,2014" +SYSRC_VERSION="6.3 Mar-4,2015" # # Options @@ -80,7 +80,7 @@ die() # usage() { - f_err "Usage: %s [OPTIONS] name[[+]=value] ...\n" "$pgm" + f_err "Usage: %s [OPTIONS] name[[+|-]=value] ...\n" "$pgm" f_err "Try \`%s --help' for more information.\n" "$pgm" die } @@ -94,7 +94,7 @@ help() local optfmt="\t%-11s%s\n" local envfmt="\t%-17s%s\n" - f_err "Usage: %s [OPTIONS] name[[+]=value] ...\n" "$pgm" + f_err "Usage: %s [OPTIONS] name[[+|-]=value] ...\n" "$pgm" f_err "OPTIONS:\n" f_err "$optfmt" "-a" \ @@ -531,6 +531,7 @@ while [ $# -gt 0 ]; do case "$NAME" in *+) mode=APPEND NAME="${NAME%+}" ;; + *-) mode=REMOVE NAME="${NAME%-}" ;; *) mode=ASSIGN esac @@ -594,29 +595,70 @@ while [ $# -gt 0 ]; do fi # - # If `-N' is passed, simplify the output + # Determine both `before' value and appropriate `new' value # - if [ ! "$SHOW_VALUE" ]; then - echo "$NAME" - case "$mode" in - APPEND) - before=$( f_sysrc_get "$NAME" ) - f_sysrc_set "$NAME" "$before${1#*=}" - ;; - *) - f_sysrc_set "$NAME" "${1#*=}" + case "$mode" in + APPEND) + before=$( f_sysrc_get "$NAME" ) + add="${1#*=}" + delim="${add%"${add#?}"}" # first character + oldIFS="$IFS" + case "$delim" in + ""|[$IFS]|[a-zA-Z0-9]) delim=" " ;; + *) IFS="$delim" esac - else + new="$before" + for a in $add; do + [ "$a" ] || continue + skip= + for b in $before; do + [ "$b" = "$a" ] && skip=1 break + done + [ "$skip" ] || new="$new$delim$a" + done + new="${new#"$delim"}" IFS="$oldIFS" + unset add delim oldIFS a skip b + [ "$SHOW_FILE" ] && before=$( f_sysrc_find "$NAME" ) + ;; + REMOVE) + before=$( f_sysrc_get "$NAME" ) + remove="${1#*=}" + delim="${remove%"${remove#?}"}" # first character + oldIFS="$IFS" + case "$delim" in + ""|[$IFS]|[a-zA-Z0-9]) delim=" " ;; + *) IFS="$delim" + esac + new= + for b in $before; do + [ "$b" ] || continue + add=1 + for r in $remove; do + [ "$r" = "$b" ] && add= break + done + [ "$add" ] && new="$new$delim$b" + done + new="${new#"$delim"}" IFS="$oldIFS" + unset remove delim oldIFS b add r + [ "$SHOW_FILE" ] && before=$( f_sysrc_find "$NAME" ) + ;; + *) if [ "$SHOW_FILE" ]; then before=$( f_sysrc_find "$NAME" ) else before=$( f_sysrc_get "$NAME" ) fi - if case "$mode" in - APPEND) f_sysrc_set "$NAME" "$before${1#*=}" ;; - *) f_sysrc_set "$NAME" "${1#*=}" - esac - then + new="${1#*=}" + esac + + # + # If `-N' is passed, simplify the output + # + if [ ! "$SHOW_VALUE" ]; then + echo "$NAME" + f_sysrc_set "$NAME" "$new" + else + if f_sysrc_set "$NAME" "$new"; then if [ "$SHOW_FILE" ]; then after=$( f_sysrc_find "$NAME" ) else diff --git a/usr.sbin/sysrc/sysrc.8 b/usr.sbin/sysrc/sysrc.8 index cba481f..1bd761a 100644 --- a/usr.sbin/sysrc/sysrc.8 +++ b/usr.sbin/sysrc/sysrc.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2011-2014 Devin Teske +.\" Copyright (c) 2011-2015 Devin Teske .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 4, 2014 +.Dd March 4, 2015 .Dt SYSRC 8 .Os .Sh NAME @@ -35,7 +35,7 @@ .Op Fl cdDeFhinNqvx .Op Fl f Ar file .Op Fl j Ar jail | Fl R Ar dir -.Ar name Ns Op Ns Oo + Oc Ns = Ns Ar value +.Ar name Ns Op Ns Oo +|- Oc Ns = Ns Ar value .Ar ... .Nm .Op Fl cdDeFhinNqvx @@ -136,9 +136,14 @@ and also has the same .Ql name[=value] syntax for making queries/assignments. In addition -.Pq unlike Xr sysctl 8 , +.Pq but unlike Xr sysctl 8 , .Ql name+=value -is supported for appending values. +is supported for adding items to values +.Pq see APPENDING VALUES +and +.Ql name-=value +is supported for removing items from values +.Pq see SUBTRACTING VALUES . .Pp However, while .Xr sysctl 8 @@ -187,6 +192,115 @@ modifying these integral files (yet taking care not to allow the file to grow unwieldy should .Nm be called repeatedly). +.Sh APPENDING VALUES +When using the +.Ql key+=value +syntax to add items to existing values, +the first character of the value is taken as the delimiter separating items +.Pq usually Qo \ Qc or Qo , Qc . +For example, in the following statement: +.Bl -tag -width indent+ +.It \ +.Nm +cloned_interfaces+=" gif0" +.El +.Pp +the first character is a space, informing +.Nm +that existing values are to be considered separated by whitespace. +If +.Ql gif0 +is not found in the existing value for +.Va cloned_interfaces , +it is added +.Pq with delimiter only if existing value is non-NULL . +.Pp +For convenience, if the first character is alpha-numeric +.Pq letters A-Z, a-z, or numbers 0-9 , +.Nm +uses the default setting of whitespace as separator. +For example, the above and below statements are equivalent since +.Dq gif0 +starts with an alpha-numeric character +.Pq the letter Li g : +.Pp +.Bl -tag -width indent+ +.It \ +.Nm +cloned_interfaces+=gif0 +.El +.Pp +Take the following sequence for example: +.Bl -tag -width indent+ +.It \ +.Nm +cloned_interfaces= # start with NULL +.It \ +.Nm +cloned_interfaces+=gif0 +.Dl # NULL -> `gif0' Pq NB: no preceding delimiter +.It \ +.Nm +cloned_interfaces+=gif0 # no change +.It \ +.Nm +cloned_interfaces+="tun0 gif0" +.Dl # `gif0' -> `gif0 tun0' Pq NB: no duplication +.El +.Pp +.Nm +prevents the same value from being added if already there. +.Sh SUBTRACTING VALUES +When using the +.Ql key-=value +syntax to remove items from existing values, +the first character of the value is taken as the delimiter separating items +.Pq usually Qo \ Qc or Qo , Qc . +For example, in the following statement: +.Pp +.Dl Nm cloned_interfaces-=" gif0" +.Pp +the first character is a space, informing +.Nm +that existing values are to be considered separated by whitespace. +If +.Ql gif0 +is found in the existing value for +.Va cloned_interfaces , +it is removed +.Pq extra delimiters removed . +.Pp +For convenience, if the first character is alpha-numeric +.Pq letters A-Z, a-z, or numbers 0-9 , +.Nm +uses the default setting of whitespace as separator. +For example, the above and below statements are equivalent since +.Dq gif0 +starts with an alpha-numeric character +.Pq the letter Li g : +.Pp +.Bl -tag -width indent+ +.It \ +.Nm +cloned_interfaces-=gif0 +.El +.Pp +Take the following sequence for example: +.Bl -tag -width indent+ +.It \ +.Nm +foo="bar baz" # start +.It \ +.Nm +foo-=bar # `bar baz' -> `baz' +.It \ +.Nm +foo-=baz # `baz' -> NULL +.El +.Pp +.Nm +removes all occurrences of all items provided +and collapses extra delimiters between items. .Sh ENVIRONMENT The following environment variables are referenced by .Nm : @@ -250,8 +364,12 @@ Working on other files, such as Appending to existing values: .Pp .Nm -\&cloned_interfaces+=" gif0" -.Dl appends Qo \ gif0 Qc to $cloned_interfaces . +\&cloned_interfaces+=gif0 +.Dl appends Qo gif0 Qc to $cloned_interfaces Pq see APPENDING VALUES . +.Pp +.Nm +\&cloned_interfaces-=gif0 +.Dl removes Qo gif0 Qc from $cloned_interfaces Pq see SUBTRACTING VALUES . .Pp In addition to the above syntax, .Nm diff --git a/usr.sbin/tcpdchk/Makefile b/usr.sbin/tcpdchk/Makefile index e979916..5faea18 100644 --- a/usr.sbin/tcpdchk/Makefile +++ b/usr.sbin/tcpdchk/Makefile @@ -17,7 +17,6 @@ CFLAGS+=-DINET6 WARNS?= 0 -DPADD= ${LIBWRAP} -LDADD= -lwrap +LIBADD= wrap .include <bsd.prog.mk> diff --git a/usr.sbin/tcpdmatch/Makefile b/usr.sbin/tcpdmatch/Makefile index f8ccf8a..bbe29a4 100644 --- a/usr.sbin/tcpdmatch/Makefile +++ b/usr.sbin/tcpdmatch/Makefile @@ -16,7 +16,6 @@ CFLAGS+=-DINET6 WARNS?= 0 -DPADD= ${LIBWRAP} -LDADD= -lwrap +LIBADD= wrap .include <bsd.prog.mk> diff --git a/usr.sbin/tcpdump/tcpdump/Makefile b/usr.sbin/tcpdump/tcpdump/Makefile index fcaa13e..00d768e 100644 --- a/usr.sbin/tcpdump/tcpdump/Makefile +++ b/usr.sbin/tcpdump/tcpdump/Makefile @@ -23,7 +23,9 @@ SRCS= addrtoname.c \ print-802_11.c \ print-802_15_4.c \ print-ah.c \ + print-ahcp.c \ print-aodv.c \ + print-aoe.c \ print-ap1394.c \ print-arcnet.c \ print-arp.c \ @@ -35,6 +37,7 @@ SRCS= addrtoname.c \ print-bgp.c \ print-bootp.c \ print-bt.c \ + print-calm-fast.c \ print-carp.c \ print-cdp.c \ print-cfm.c \ @@ -55,6 +58,7 @@ SRCS= addrtoname.c \ print-fddi.c \ print-forces.c \ print-fr.c \ + print-geonet.c \ print-gre.c \ print-hsrp.c \ print-icmp.c \ @@ -75,22 +79,28 @@ SRCS= addrtoname.c \ print-llc.c \ print-lldp.c \ print-lmp.c \ + print-loopback.c \ print-lspping.c \ print-lwapp.c \ print-lwres.c \ + print-m3ua.c \ print-mobile.c \ print-mpcp.c \ print-mpls.c \ + print-mptcp.c \ print-msdp.c \ print-msnlb.c \ print-nfs.c \ print-ntp.c \ print-null.c \ print-olsr.c \ + print-openflow.c \ + print-openflow-1.0.c \ print-ospf.c \ print-otv.c \ print-pgm.c \ print-pim.c \ + print-pktap.c \ print-ppi.c \ print-ppp.c \ print-pppoe.c \ @@ -160,16 +170,13 @@ CFLAGS+= -DINET6 CFLAGS+= -DLBL_ALIGN .endif -DPADD= ${LIBL} ${LIBPCAP} -LDADD= -ll -lpcap +LIBADD= l pcap .if ${MK_CASPER} != "no" -DPADD+= ${LIBCAPSICUM} ${LIBNV} -LDADD+= -lcapsicum -lnv -CFLAGS+=-DHAVE_LIBCAPSICUM +LIBADD+= capsicum +CFLAGS+=-DHAVE_CAPSICUM .endif .if ${MK_OPENSSL} != "no" -DPADD+= ${LIBCRYPTO} -LDADD+= -lcrypto +LIBADD+= crypto CFLAGS+= -I${DESTDIR}/usr/include/openssl CFLAGS+= -DHAVE_LIBCRYPTO -DHAVE_OPENSSL_EVP_H .endif diff --git a/usr.sbin/tcpdump/tcpdump/config.h b/usr.sbin/tcpdump/tcpdump/config.h index 62fa3cd..84dc094 100644 --- a/usr.sbin/tcpdump/tcpdump/config.h +++ b/usr.sbin/tcpdump/tcpdump/config.h @@ -3,92 +3,39 @@ /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.in by autoheader. */ -/* "generated automatically" means DO NOT MAKE CHANGES TO config.h.in -- - * make them to acconfig.h and rerun autoheader */ -/* Define if you enable IPv6 support */ -/* See Makefile */ -/* #undef INET6 */ - -/* Define if you enable support for the libsmi. */ -/* #undef LIBSMI */ - -/* define if you have the addrinfo function. */ +/* define if you have the addrinfo function */ #define HAVE_ADDRINFO 1 -/* define if you need to include missing/addrinfoh.h. */ -/* #undef NEED_ADDRINFO_H */ - -/* define ifyou have the h_errno variable. */ -#define HAVE_H_ERRNO 1 - -/* define if you have struct sockaddr_storage */ -#define HAVE_SOCKADDR_STORAGE 1 - -/* define if you have both getipnodebyname() and getipnodebyaddr() */ -/* #undef USE_GETIPNODEBY */ - -/* define if you have ether_ntohost() and it works */ -#define USE_ETHER_NTOHOST 1 - -/* define if libpcap has pcap_version */ -/* #undef HAVE_PCAP_VERSION */ - -/* define if libpcap has pcap_debug */ -/* #undef HAVE_PCAP_DEBUG */ - -/* define if libpcap has yydebug */ -/* #undef HAVE_YYDEBUG */ - -/* define if libpcap has pcap_list_datalinks() */ -#define HAVE_PCAP_LIST_DATALINKS 1 - -/* define if libpcap has pcap_set_datalink() */ -#define HAVE_PCAP_SET_DATALINK 1 - -/* define if libpcap has pcap_datalink_name_to_val() */ -#define HAVE_PCAP_DATALINK_NAME_TO_VAL 1 - -/* define if libpcap has pcap_datalink_val_to_description() */ -#define HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION 1 - -/* define if libpcap has pcap_dump_ftell() */ -#define HAVE_PCAP_DUMP_FTELL 1 - -/* define if you have getrpcbynumber() */ -#define HAVE_GETRPCBYNUMBER 1 +/* Define to 1 if you have the `alarm' function. */ +#define HAVE_ALARM 1 -/* Workaround for missing 64-bit formats */ -/* #undef PRId64 */ -/* #undef PRIo64 */ -/* #undef PRIx64 */ -/* #undef PRIu64 */ +/* Define to 1 if you have the `bpf_dump' function. */ +#define HAVE_BPF_DUMP 1 -/* Whether or not to include the possibly-buggy SMB printer */ -#define TCPDUMP_DO_SMB 1 +/* capsicum support available */ +/* See Makefile */ +/* #undef HAVE_CAPSICUM */ -/* Define if you have the dnet_htoa function. */ -/* #undef HAVE_DNET_HTOA */ +/* Define to 1 if you have the `cap_enter' function. */ +#define HAVE_CAP_ENTER 1 -/* Define if you have a dnet_htoa declaration in <netdnet/dnetdb.h>. */ -/* #undef HAVE_NETDNET_DNETDB_H_DNET_HTOA */ +/* Define to 1 if you have the `cap_ioctls_limit' function. */ +#define HAVE_CAP_IOCTLS_LIMIT 1 -/* define if should drop privileges by default */ -/* #undef WITH_USER */ +/* Define to 1 if you have the `cap_rights_init' function. */ +/* #undef HAVE_CAP_RIGHTS_INIT */ -/* define if should chroot when dropping privileges */ -/* #undef WITH_CHROOT */ - -/* Define to 1 if you have the `alarm' function. */ -#define HAVE_ALARM 1 - -/* Define to 1 if you have the `bpf_dump' function. */ -#define HAVE_BPF_DUMP 1 +/* Define to 1 if you have the `cap_rights_limit' function. */ +#define HAVE_CAP_RIGHTS_LIMIT 1 /* Define to 1 if you have the declaration of `ether_ntohost', and to 0 if you don't. */ #define HAVE_DECL_ETHER_NTOHOST 1 +/* define if you have the dnet_htoa function */ +/* #undef HAVE_DNET_HTOA */ + /* Define to 1 if you have the `ether_ntohost' function. */ #define HAVE_ETHER_NTOHOST 1 @@ -101,6 +48,15 @@ /* Define to 1 if you have the `getnameinfo' function. */ #define HAVE_GETNAMEINFO 1 +/* Define to 1 if you have the `getopt_long' function. */ +#define HAVE_GETOPT_LONG 1 + +/* define if you have getrpcbynumber() */ +#define HAVE_GETRPCBYNUMBER 1 + +/* define if you have the h_errno variable */ +#define HAVE_H_ERRNO 1 + /* Define to 1 if you have the <inttypes.h> header file. */ #define HAVE_INTTYPES_H 1 @@ -111,15 +67,15 @@ /* Define to 1 if you have the `rpc' library (-lrpc). */ /* #undef HAVE_LIBRPC */ -/* Define to 1 if you have the `smi' library (-lsmi). */ -/* #undef HAVE_LIBSMI */ - /* Define to 1 if you have the <memory.h> header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the <netdnet/dnetdb.h> header file. */ /* #undef HAVE_NETDNET_DNETDB_H */ +/* define if you have a dnet_htoa declaration in <netdnet/dnetdb.h> */ +/* #undef HAVE_NETDNET_DNETDB_H_DNET_HTOA */ + /* Define to 1 if you have the <netinet/ether.h> header file. */ /* #undef HAVE_NETINET_ETHER_H */ @@ -130,6 +86,9 @@ /* See Makefile */ /* #undef HAVE_NET_PFVAR_H */ +/* Define to 1 if you have the `openat' function. */ +#define HAVE_OPENAT 1 + /* Define to 1 if you have the <openssl/evp.h> header file. */ /* See Makefile */ /* #undef HAVE_OPENSSL_EVP_H 1 */ @@ -146,24 +105,57 @@ /* Define to 1 if you have the `pcap_create' function. */ #define HAVE_PCAP_CREATE 1 +/* define if libpcap has pcap_datalink_name_to_val() */ +#define HAVE_PCAP_DATALINK_NAME_TO_VAL 1 + +/* define if libpcap has pcap_datalink_val_to_description() */ +#define HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION 1 + +/* define if libpcap has pcap_debug */ +/* #undef HAVE_PCAP_DEBUG */ + /* Define to 1 if you have the `pcap_dump_flush' function. */ #define HAVE_PCAP_DUMP_FLUSH 1 +/* define if libpcap has pcap_dump_ftell() */ +#define HAVE_PCAP_DUMP_FTELL 1 + /* Define to 1 if you have the `pcap_findalldevs' function. */ #define HAVE_PCAP_FINDALLDEVS 1 +/* Define to 1 if you have the `pcap_free_datalinks' function. */ +#define HAVE_PCAP_FREE_DATALINKS 1 + /* Define to 1 if the system has the type `pcap_if_t'. */ #define HAVE_PCAP_IF_T 1 /* Define to 1 if you have the `pcap_lib_version' function. */ #define HAVE_PCAP_LIB_VERSION 1 +/* define if libpcap has pcap_list_datalinks() */ +#define HAVE_PCAP_LIST_DATALINKS 1 + +/* Define to 1 if you have the <pcap/nflog.h> header file. */ +/* #undef HAVE_PCAP_NFLOG_H */ + +/* Define to 1 if you have the `pcap_setdirection' function. */ +#define HAVE_PCAP_SETDIRECTION 1 + +/* Define to 1 if you have the `pcap_set_datalink' function. */ +#define HAVE_PCAP_SET_DATALINK 1 + +/* Define to 1 if you have the `pcap_set_tstamp_precision' function. */ +#define HAVE_PCAP_SET_TSTAMP_PRECISION 1 + /* Define to 1 if you have the `pcap_set_tstamp_type' function. */ #define HAVE_PCAP_SET_TSTAMP_TYPE 1 /* Define to 1 if you have the <pcap/usb.h> header file. */ /* #undef HAVE_PCAP_USB_H */ +/* define if libpcap has pcap_version */ +/* #undef HAVE_PCAP_VERSION */ + /* Define to 1 if you have the `pfopen' function. */ /* #undef HAVE_PFOPEN */ @@ -182,9 +174,6 @@ /* Define to 1 if you have the `sigset' function. */ /* #undef HAVE_SIGSET */ -/* Define to 1 if you have the <smi.h> header file. */ -/* #undef HAVE_SMI_H */ - /* Define to 1 if you have the `snprintf' function. */ #define HAVE_SNPRINTF 1 @@ -224,9 +213,6 @@ /* Define to 1 if the system has the type `struct ether_addr'. */ /* #undef HAVE_STRUCT_ETHER_ADDR */ -/* Define to 1 if you have the <sys/bitypes.h> header file. */ -/* #undef HAVE_SYS_BITYPES_H */ - /* Define to 1 if you have the <sys/stat.h> header file. */ #define HAVE_SYS_STAT_H 1 @@ -245,12 +231,22 @@ /* Define to 1 if you have the `vsnprintf' function. */ #define HAVE_VSNPRINTF 1 +/* define if libpcap has yydebug */ +/* #undef HAVE_YYDEBUG */ + /* define if your compiler has __attribute__ */ #define HAVE___ATTRIBUTE__ 1 +/* Define if you enable IPv6 support */ +/* See Makefile */ +/* #undef INET6 */ + /* if unaligned access fails */ /* #undef LBL_ALIGN */ +/* define if you need to include missing/addrinfo.h */ +/* #undef NEED_ADDRINFO_H */ + /* Define to 1 if netinet/ether.h declares `ether_ntohost' */ /* #undef NETINET_ETHER_H_DECLARES_ETHER_NTOHOST */ @@ -269,9 +265,24 @@ /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "" +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + /* Define to the version of this package. */ #define PACKAGE_VERSION "" +/* define if the platform doesn't define PRId64 */ +/* #undef PRId64 */ + +/* define if the platform doesn't define PRIo64 */ +/* #undef PRIo64 */ + +/* define if the platform doesn't define PRIx64 */ +/* #undef PRIu64 */ + +/* define if the platform doesn't define PRIu64 */ +/* #undef PRIx64 */ + /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void @@ -281,48 +292,102 @@ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 +/* define if you want to build the possibly-buggy SMB printer */ +#define TCPDUMP_DO_SMB 1 + /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ #define TIME_WITH_SYS_TIME 1 +/* define if you have ether_ntohost() and it works */ +#define USE_ETHER_NTOHOST 1 + +/* Define if you enable support for libsmi */ +/* #undef USE_LIBSMI */ + +/* define if should chroot when dropping privileges */ +/* #undef WITH_CHROOT */ + +/* define if should drop privileges by default */ +/* #undef WITH_USER */ + /* get BSD semantics on Irix */ /* #undef _BSD_SIGNALS */ -/* needed on HP-UX */ -/* #undef _HPUX_SOURCE */ - /* define on AIX to get certain functions */ /* #undef _SUN */ +/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT32_T */ + +/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT64_T */ + +/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT8_T */ + +/* define if your compiler allows __attribute__((format)) without a warning */ +#define __ATTRIBUTE___FORMAT_OK 1 + /* define if your compiler allows __attribute__((format)) to be applied to function pointers */ #define __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS 1 +/* define if your compiler allows __attribute__((noreturn)) to be applied to + function pointers */ +#define __ATTRIBUTE___NORETURN_OK_FOR_FUNCTION_POINTERS 1 + /* to handle Ultrix compilers that don't support const in prototypes */ /* #undef const */ /* Define as token for inline if inlining supported */ #define inline inline -/* Define to `short' if int16_t not defined. */ +/* Define to the type of a signed integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ /* #undef int16_t */ -/* Define to `int' if int32_t not defined. */ +/* Define to the type of a signed integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ /* #undef int32_t */ -/* Define to `long long' if int64_t not defined. */ +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ /* #undef int64_t */ -/* Define to `signed char' if int8_t not defined. */ +/* Define to the type of a signed integer type of width exactly 8 bits if such + a type exists and the standard includes do not define it. */ /* #undef int8_t */ -/* Define to `unsigned short' if u_int16_t not defined. */ +/* Define to `uint16_t' if u_int16_t not defined. */ /* #undef u_int16_t */ -/* Define to `unsigned int' if u_int32_t not defined. */ +/* Define to `uint32_t' if u_int32_t not defined. */ /* #undef u_int32_t */ -/* Define to `unsigned long long' if u_int64_t not defined. */ +/* Define to `uint64_t' if u_int64_t not defined. */ /* #undef u_int64_t */ -/* Define to `unsigned char' if u_int8_t not defined. */ +/* Define to `uint8_t' if u_int8_t not defined. */ /* #undef u_int8_t */ + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint16_t */ + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint32_t */ + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint64_t */ + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint8_t */ diff --git a/usr.sbin/tcpdump/tcpdump/tcpdump.1 b/usr.sbin/tcpdump/tcpdump/tcpdump.1 index ca6d795..bef5690 100644 --- a/usr.sbin/tcpdump/tcpdump/tcpdump.1 +++ b/usr.sbin/tcpdump/tcpdump/tcpdump.1 @@ -1,6 +1,4 @@ .\" $FreeBSD$ -.\" @(#) $Header: /tcpdump/master/tcpdump/tcpdump.1.in,v 1.2 2008-11-09 23:35:03 mcr Exp $ (LBL) -.\" .\" $NetBSD: tcpdump.8,v 1.9 2003/03/31 00:18:17 perry Exp $ .\" .\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997 @@ -23,18 +21,21 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH TCPDUMP 1 "12 July 2012" +.TH TCPDUMP 1 "11 July 2014" .SH NAME tcpdump \- dump traffic on a network .SH SYNOPSIS .na .B tcpdump [ -.B \-AbdDefhHIJKlLnNOpqRStuUvxX +.B \-AbdDefhHIJKlLnNOpqRStuUvxX# ] [ .B \-B .I buffer_size -] [ +] +.br +.ti +8 +[ .B \-c .I count ] @@ -71,6 +72,14 @@ tcpdump \- dump traffic on a network .br .ti +8 [ +.B \-\-number +] +[ +.B \-Q +.I in|out|inout +] +.ti +8 +[ .B \-r .I file ] @@ -118,6 +127,13 @@ tcpdump \- dump traffic on a network ] .ti +8 [ +.BI \-\-time\-stamp\-precision= tstamp_precision +] +[ +.B \-\-version +] +.ti +8 +[ .I expression ] .br @@ -206,14 +222,18 @@ capturing web pages. Print the AS number in BGP packets in ASDOT notation rather than ASPLAIN notation. .TP -.B \-B +.BI \-B " buffer_size" +.PD 0 +.TP +.BI \-\-buffer\-size= buffer_size +.PD Set the operating system capture buffer size to \fIbuffer_size\fP, in units of KiB (1024 bytes). .TP -.B \-c +.BI \-c " count" Exit after receiving \fIcount\fP packets. .TP -.B \-C +.BI \-C " file_size" Before writing a raw packet to a savefile, check whether the file is currently larger than \fIfile_size\fP and, if so, close the current savefile and open a new one. Savefiles after the first savefile will @@ -236,6 +256,10 @@ program fragment. Dump packet-matching code as decimal numbers (preceded with a count). .TP .B \-D +.PD 0 +.TP +.B \-\-list\-interfaces +.PD Print the list of the network interfaces available on the system and on which .I tcpdump @@ -315,11 +339,11 @@ because the capture is being done on the Linux "any" interface, which can capture on more than one interface, this option will not work correctly. .TP -.B \-F +.BI \-F " file" Use \fIfile\fP as input for the filter expression. An additional expression given on the command line is ignored. .TP -.B \-G +.BI \-G " rotate_seconds" If specified, rotates the dump file specified with the .B \-w option every \fIrotate_seconds\fP seconds. @@ -334,17 +358,29 @@ If used in conjunction with the option, filenames will take the form of `\fIfile\fP<count>'. .TP .B \-h +.PD 0 +.TP +.B \-\-help +.PD Print the tcpdump and libpcap version strings, print a usage message, and exit. .TP +.B \-\-version +.PD +Print the tcpdump and libpcap version strings and exit. +.TP .B \-H Attempt to detect 802.11s draft mesh headers. .TP -.B \-i +.BI \-i " interface" +.PD 0 +.TP +.BI \-\-interface= interface +.PD Listen on \fIinterface\fP. If unspecified, \fItcpdump\fP searches the system interface list for the -lowest numbered, configured up interface (excluding loopback). -Ties are broken by choosing the earliest match. +lowest numbered, configured up interface (excluding loopback), which may turn +out to be, for example, ``eth0''. .IP On Linux systems with 2.2 or later kernels, an .I interface @@ -360,6 +396,10 @@ used as the argument. .TP .B \-I +.PD 0 +.TP +.B \-\-monitor\-mode +.PD Put the interface in "monitor mode"; this is supported only on IEEE 802.11 Wi-Fi interfaces, and supported only on some operating systems. .IP @@ -380,19 +420,50 @@ monitor mode will be shown; if is specified, only those link-layer types available when in monitor mode will be shown. .TP -.B \-j +.BI \-j " tstamp_type" +.PD 0 +.TP +.BI \-\-time\-stamp\-type= tstamp_type +.PD Set the time stamp type for the capture to \fItstamp_type\fP. The names to use for the time stamp types are given in -.BR pcap-tstamp-type (7); +.BR pcap-tstamp (7); not all the types listed there will necessarily be valid for any given interface. .TP .B \-J +.PD 0 +.TP +.B \-\-list\-time\-stamp\-types +.PD List the supported time stamp types for the interface and exit. If the time stamp type cannot be set for the interface, no time stamp types are listed. .TP +.BI \-\-time\-stamp\-precision= tstamp_precision +When capturing, set the time stamp precision for the capture to +\fItstamp_precision\fP. Note that availability of high precision time +stamps (nanoseconds) and their actual accuracy is platform and hardware +dependent. Also note that when writing captures made with nanosecond +accuracy to a savefile, the time stamps are written with nanosecond +resolution, and the file is written with a different magic number, to +indicate that the time stamps are in seconds and nanoseconds; not all +programs that read pcap savefiles will be able to read those captures. +.LP +When reading a savefile, convert time stamps to the precision specified +by \fItimestamp_precision\fP, and display them with that resolution. If +the precision specified is less than the precision of time stamps in the +file, the conversion will lose precision. +.LP +The supported values for \fItimestamp_precision\fP are \fBmicro\fP for +microsecond resolution and \fBnano\fP for nanosecond resolution. The +default is microsecond resolution. +.TP .B \-K +.PD 0 +.TP +.B \-\-dont\-verify\-checksums +.PD Don't attempt to verify IP, TCP, or UDP checksums. This is useful for interfaces that perform some or all of those checksum calculation in hardware; otherwise, all outgoing TCP checksums will be flagged as bad. @@ -435,6 +506,10 @@ than at the end of each line; this is buffered on all platforms, including Windows. .TP .B \-L +.PD 0 +.TP +.B \-\-list\-data\-link\-types +.PD List the known data link types for the interface, in the specified mode, and exit. The list of known data link types may be dependent on the specified mode; for example, on some platforms, a Wi-Fi interface might @@ -445,12 +520,12 @@ and another set of data link types when in monitor mode (for example, it might support 802.11 headers, or 802.11 headers with radio information, only in monitor mode). .TP -.B \-m +.BI \-m " module" Load SMI MIB module definitions from file \fImodule\fR. This option can be used several times to load several MIB modules into \fItcpdump\fP. .TP -.B \-M +.BI \-M " secret" Use \fIsecret\fP as a shared secret for validating the digests found in TCP segments with the TCP-MD5 option (RFC 2385), if present. .TP @@ -463,18 +538,42 @@ E.g., if you give this flag then \fItcpdump\fP will print ``nic'' instead of ``nic.ddn.mil''. .TP +.B \-# +.PD 0 +.TP +.B \-\-number +.PD +Print an optional packet number at the beginning of the line. +.TP .B \-O +.PD 0 +.TP +.B \-\-no\-optimize +.PD Do not run the packet-matching code optimizer. This is useful only if you suspect a bug in the optimizer. .TP .B \-p +.PD 0 +.TP +.B \-\-no\-promiscuous\-mode +.PD \fIDon't\fP put the interface into promiscuous mode. Note that the interface might be in promiscuous mode for some other reason; hence, `-p' cannot be used as an abbreviation for `ether host {local-hw-addr} or ether broadcast'. .TP +.BI \-Q " direction" +.PD 0 +.TP +.BI \-\-direction= direction +.PD +Choose send/receive direction \fIdirection\fR for which packets should be +captured. Possible values are `in', `out' and `inout'. Not available +on all platforms. +.TP .B \-q Quick (quiet?) output. Print less protocol information so output @@ -486,16 +585,24 @@ If specified, \fItcpdump\fP will not print replay prevention field. Since there is no protocol version field in ESP/AH specification, \fItcpdump\fP cannot deduce the version of ESP/AH protocol. .TP -.B \-r +.BI \-r " file" Read packets from \fIfile\fR (which was created with the .B \-w -option). +option or by other tools that write pcap or pcap-ng files). Standard input is used if \fIfile\fR is ``-''. .TP .B \-S +.PD 0 +.TP +.B \-\-absolute\-tcp\-sequence\-numbers +.PD Print absolute, rather than relative, TCP sequence numbers. .TP -.B \-s +.BI \-s " snaplen" +.PD 0 +.TP +.BI \-\-snapshot\-length= snaplen +.PD Snarf \fIsnaplen\fP bytes of data from each packet rather than the default of 65535 bytes. Packets truncated because of a limited snapshot @@ -513,13 +620,16 @@ Setting for backwards compatibility with recent older versions of .IR tcpdump . .TP -.B \-T +.BI \-T " type" Force packets selected by "\fIexpression\fP" to be interpreted the specified \fItype\fR. Currently known types are \fBaodv\fR (Ad-hoc On-demand Distance Vector protocol), \fBcarp\fR (Common Address Redundancy Protocol), \fBcnfp\fR (Cisco NetFlow protocol), +\fBlmp\fR (Link Management Protocol), +\fBpgm\fR (Pragmatic General Multicast), +\fBpgm_zmtp1\fR (ZMTP/1.0 inside PGM/EPGM), \fBradius\fR (RADIUS), \fBrpc\fR (Remote Procedure Call), \fBrtp\fR (Real-Time Applications protocol), @@ -531,6 +641,16 @@ Currently known types are \fBzmtp1\fR (ZeroMQ Message Transport Protocol 1.0) and \fBvxlan\fR (Virtual eXtensible Local Area Network). +.IP +Note that the \fBpgm\fR type above affects UDP interpretation only, the native +PGM is always recognised as IP protocol 113 regardless. UDP-encapsulated PGM is +often called "EPGM" or "PGM/UDP". +.IP +Note that the \fBpgm_zmtp1\fR type above affects interpretation of both native +PGM and UDP at once. During the native PGM decoding the application data of an +ODATA/RDATA packet would be decoded as a ZeroMQ datagram with ZMTP/1.0 frames. +During the UDP decoding in addition to that any UDP packet would be treated as +an encapsulated PGM packet. .TP .B \-t \fIDon't\fP print a timestamp on each dump line. @@ -553,6 +673,10 @@ on each dump line. Print undecoded NFS handles. .TP .B \-U +.PD 0 +.TP +.B \-\-packet\-buffered +.PD If the .B \-w option is not specified, make the printed packet output @@ -603,11 +727,11 @@ With .B \-X Telnet options are printed in hex as well. .TP -.B \-V +.BI \-V " file" Read a list of filenames from \fIfile\fR. Standard input is used if \fIfile\fR is ``-''. .TP -.B \-w +.BI \-w " file" Write the raw packets to \fIfile\fR rather than parsing and printing them out. They can later be printed with the \-r option. @@ -680,10 +804,14 @@ each packet, .I including its link level header, in hex and ASCII. .TP -.B \-y +.BI \-y " datalinktype" +.PD 0 +.TP +.BI \-\-linktype= datalinktype +.PD Set the data link type to use while capturing packets to \fIdatalinktype\fP. .TP -.B \-z +.BI \-z " postrotate-command" Used in conjunction with the .B -C or @@ -691,7 +819,7 @@ or options, this will make .I tcpdump run " -.I command file +.I postrotate-command file " where .I file is the savefile being closed after each rotation. For example, specifying @@ -708,7 +836,11 @@ different arguments, you can always write a shell script that will take the savefile name as the only argument, make the flags & arguments arrangements and execute the command that you want. .TP -.B \-Z +.BI \-Z " user" +.PD 0 +.TP +.BI \-\-relinquish\-privileges= user +.PD If .I tcpdump is running as root, after opening the capture device or input savefile, @@ -729,8 +861,8 @@ only packets for which \fIexpression\fP is `true' will be dumped. For the \fIexpression\fP syntax, see .BR pcap-filter (7). .LP -Expression arguments can be passed to \fItcpdump\fP as either a single -argument or as multiple arguments, whichever is more convenient. +The \fIexpression\fP argument can be passed to \fItcpdump\fP as either a single +Shell argument, or as multiple Shell arguments, whichever is more convenient. Generally, if the expression contains Shell metacharacters, such as backslashes used to escape protocol names, it is easier to pass it as a single, quoted argument rather than to escape the Shell @@ -1390,39 +1522,45 @@ Sun NFS (Network File System) requests and replies are printed as: .RS .nf .sp .5 -\fIsrc.xid > dst.nfs: len op args\fP -\fIsrc.nfs > dst.xid: reply stat len op results\fP +\fIsrc.sport > dst.nfs: NFS request xid xid len op args\fP +\fIsrc.nfs > dst.dport: NFS reply xid xid reply stat len op results\fP .sp .5 \f(CW -sushi.6709 > wrl.nfs: 112 readlink fh 21,24/10.73165 -wrl.nfs > sushi.6709: reply ok 40 readlink "../var" -sushi.201b > wrl.nfs: +sushi.1023 > wrl.nfs: NFS request xid 26377 + 112 readlink fh 21,24/10.73165 +wrl.nfs > sushi.1023: NFS reply xid 26377 + reply ok 40 readlink "../var" +sushi.1022 > wrl.nfs: NFS request xid 8219 144 lookup fh 9,74/4096.6878 "xcolors" -wrl.nfs > sushi.201b: +wrl.nfs > sushi.1022: NFS reply xid 8219 reply ok 128 lookup fh 9,74/4134.3150 \fR .sp .5 .fi .RE -In the first line, host \fIsushi\fP sends a transaction with id \fI6709\fP -to \fIwrl\fP (note that the number following the src host is a -transaction id, \fInot\fP the source port). +In the first line, host \fIsushi\fP sends a transaction with id \fI26377\fP +to \fIwrl\fP. The request was 112 bytes, excluding the UDP and IP headers. The operation was a \fIreadlink\fP (read symbolic link) on file handle (\fIfh\fP) 21,24/10.731657119. (If one is lucky, as in this case, the file handle can be interpreted as a major,minor device number pair, followed by the inode number and -generation number.) -\fIWrl\fP replies `ok' with the contents of the link. +generation number.) In the second line, \fIwrl\fP replies `ok' with +the same transaction id and the contents of the link. +.LP +In the third line, \fIsushi\fP asks (using a new transaction id) \fIwrl\fP +to lookup the name `\fIxcolors\fP' in directory file 9,74/4096.6878. In +the fourth line, \fIwrl\fP sends a reply with the respective transaction id. .LP -In the third line, \fIsushi\fP asks \fIwrl\fP to lookup the name -`\fIxcolors\fP' in directory file 9,74/4096.6878. Note that the data printed depends on the operation type. The format is intended to be self explanatory if read in conjunction with an NFS protocol spec. +Also note that older versions of tcpdump printed NFS packets in a +slightly different format: the transaction id (xid) would be printed +instead of the non-NFS port number of the packet. .LP If the \-v (verbose) flag is given, additional information is printed. For example: @@ -1430,9 +1568,9 @@ For example: .nf .sp .5 \f(CW -sushi.1372a > wrl.nfs: +sushi.1023 > wrl.nfs: NFS request xid 79658 148 read fh 21,11/12.195 8192 bytes @ 24576 -wrl.nfs > sushi.1372a: +wrl.nfs > sushi.1023: NFS reply xid 79658 reply ok 1472 read REG 100664 ids 417/0 sz 29388 \fP .sp .5 @@ -1735,7 +1873,7 @@ Ethernet interface removed the packet from the wire and when the kernel serviced the `new packet' interrupt. .SH "SEE ALSO" stty(1), pcap(3PCAP), bpf(4), nit(4P), pcap-savefile(5), -pcap-filter(7), pcap-tstamp-type(7) +pcap-filter(7), pcap-tstamp(7) .LP .RS .I http://www.iana.org/assignments/media-types/application/vnd.tcpdump.pcap diff --git a/usr.sbin/timed/timed/Makefile b/usr.sbin/timed/timed/Makefile index af70b06..d4ce0fb 100644 --- a/usr.sbin/timed/timed/Makefile +++ b/usr.sbin/timed/timed/Makefile @@ -8,8 +8,7 @@ MAN= timed.8 SRCS= acksend.c candidate.c correct.c master.c networkdelta.c readmsg.c \ slave.c timed.c byteorder.c measure.c cksum.c -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util WARNS?= 1 diff --git a/usr.sbin/traceroute/Makefile b/usr.sbin/traceroute/Makefile index 12f9a0b..a3b6a14 100644 --- a/usr.sbin/traceroute/Makefile +++ b/usr.sbin/traceroute/Makefile @@ -25,8 +25,7 @@ CFLAGS+= -DIPSEC # CFLAGS+= -DSANE_PRECISION .if !defined(TRACEROUTE_NO_IPSEC) -DPADD= ${LIBIPSEC} -LDADD= -lipsec +LIBADD+= ipsec .endif CFLAGS+= -I${TRACEROUTE_DISTDIR} diff --git a/usr.sbin/traceroute6/Makefile b/usr.sbin/traceroute6/Makefile index 4428d5b..fc0b5fe 100644 --- a/usr.sbin/traceroute6/Makefile +++ b/usr.sbin/traceroute6/Makefile @@ -27,7 +27,6 @@ CFLAGS+= -I${.CURDIR} -I${TRACEROUTE_DISTDIR} -I. WARNS?= 3 -DPADD= ${LIBIPSEC} -LDADD= -lipsec +LIBADD= ipsec .include <bsd.prog.mk> diff --git a/usr.sbin/tzsetup/Makefile b/usr.sbin/tzsetup/Makefile index 4ef6533..de7375f 100644 --- a/usr.sbin/tzsetup/Makefile +++ b/usr.sbin/tzsetup/Makefile @@ -7,7 +7,6 @@ CFLAGS+= -I${.CURDIR}/../../contrib/dialog -I. WARNS?= 3 -DPADD= ${LIBDIALOG} ${LIBNCURSESW} ${LIBM} -LDADD= -ldialog -lncursesw -lm +LIBADD= dialog ncursesw .include <bsd.prog.mk> diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c index 71ba63b..fc80364 100644 --- a/usr.sbin/tzsetup/tzsetup.c +++ b/usr.sbin/tzsetup/tzsetup.c @@ -475,7 +475,7 @@ read_zones(void) FILE *fp; struct continent *cont; size_t len; - char *line, *tlc, *coord, *file, *descr, *p; + char *line, *tlc, *file, *descr, *p; int lineno; fp = fopen(path_zonetab, "r"); @@ -495,7 +495,7 @@ read_zones(void) if (strlen(tlc) != 2) errx(1, "%s:%d: invalid country code `%s'", path_zonetab, lineno, tlc); - coord = strsep(&line, "\t"); /* Unused */ + /* coord = */ strsep(&line, "\t"); /* Unused */ file = strsep(&line, "\t"); p = strchr(file, '/'); if (p == 0) diff --git a/usr.sbin/uefisign/Makefile b/usr.sbin/uefisign/Makefile new file mode 100644 index 0000000..3fdebc2 --- /dev/null +++ b/usr.sbin/uefisign/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +PROG= uefisign +SRCS= uefisign.c child.c pe.c +MAN= uefisign.8 + +LIBADD= crypto + +WARNS= 6 + +.include <bsd.prog.mk> diff --git a/usr.sbin/uefisign/child.c b/usr.sbin/uefisign/child.c new file mode 100644 index 0000000..7dfc211 --- /dev/null +++ b/usr.sbin/uefisign/child.c @@ -0,0 +1,277 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#if __FreeBSD_version >= 1100000 +#include <sys/capsicum.h> +#else +#include <sys/capability.h> +#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/pem.h> + +#include "uefisign.h" + +static void +load(struct executable *x) +{ + int error, fd; + struct stat sb; + char *buf; + size_t nread, len; + + fd = fileno(x->x_fp); + + error = fstat(fd, &sb); + if (error != 0) + err(1, "%s: fstat", x->x_path); + + len = sb.st_size; + if (len <= 0) + errx(1, "%s: file is empty", x->x_path); + + buf = malloc(len); + if (buf == NULL) + err(1, "%s: cannot malloc %zd bytes", x->x_path, len); + + nread = fread(buf, len, 1, x->x_fp); + if (nread != 1) + err(1, "%s: fread", x->x_path); + + x->x_buf = buf; + x->x_len = len; +} + +static void +digest_range(struct executable *x, EVP_MD_CTX *mdctx, off_t off, size_t len) +{ + int ok; + + range_check(x, off, len, "chunk"); + + ok = EVP_DigestUpdate(mdctx, x->x_buf + off, len); + if (ok == 0) { + ERR_print_errors_fp(stderr); + errx(1, "EVP_DigestUpdate(3) failed"); + } +} + +static void +digest(struct executable *x) +{ + EVP_MD_CTX *mdctx; + const EVP_MD *md; + size_t sum_of_bytes_hashed; + int i, ok; + + /* + * Windows Authenticode Portable Executable Signature Format + * spec version 1.0 specifies MD5 and SHA1. However, pesign + * and sbsign both use SHA256, so do the same. + */ + md = EVP_get_digestbyname(DIGEST); + if (md == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "EVP_get_digestbyname(\"%s\") failed", DIGEST); + } + + mdctx = EVP_MD_CTX_create(); + if (mdctx == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "EVP_MD_CTX_create(3) failed"); + } + + ok = EVP_DigestInit_ex(mdctx, md, NULL); + if (ok == 0) { + ERR_print_errors_fp(stderr); + errx(1, "EVP_DigestInit_ex(3) failed"); + } + + /* + * According to the Authenticode spec, we need to compute + * the digest in a rather... specific manner; see "Calculating + * the PE Image Hash" part of the spec for details. + * + * First, everything from 0 to before the PE checksum. + */ + digest_range(x, mdctx, 0, x->x_checksum_off); + + /* + * Second, from after the PE checksum to before the Certificate + * entry in Data Directory. + */ + digest_range(x, mdctx, x->x_checksum_off + x->x_checksum_len, + x->x_certificate_entry_off - + (x->x_checksum_off + x->x_checksum_len)); + + /* + * Then, from after the Certificate entry to the end of headers. + */ + digest_range(x, mdctx, + x->x_certificate_entry_off + x->x_certificate_entry_len, + x->x_headers_len - + (x->x_certificate_entry_off + x->x_certificate_entry_len)); + + /* + * Then, each section in turn, as specified in the PE Section Table. + * + * XXX: Sorting. + */ + sum_of_bytes_hashed = x->x_headers_len; + for (i = 0; i < x->x_nsections; i++) { + digest_range(x, mdctx, + x->x_section_off[i], x->x_section_len[i]); + sum_of_bytes_hashed += x->x_section_len[i]; + } + + /* + * I believe this can happen with overlapping sections. + */ + if (sum_of_bytes_hashed > x->x_len) + errx(1, "number of bytes hashed is larger than file size"); + + /* + * I can't really explain this one; just do what the spec says. + */ + if (sum_of_bytes_hashed < x->x_len) { + digest_range(x, mdctx, sum_of_bytes_hashed, + x->x_len - (signature_size(x) + sum_of_bytes_hashed)); + } + + ok = EVP_DigestFinal_ex(mdctx, x->x_digest, &x->x_digest_len); + if (ok == 0) { + ERR_print_errors_fp(stderr); + errx(1, "EVP_DigestFinal_ex(3) failed"); + } + + EVP_MD_CTX_destroy(mdctx); +} + +static void +show_digest(const struct executable *x) +{ + int i; + + printf("computed %s digest ", DIGEST); + for (i = 0; i < (int)x->x_digest_len; i++) + printf("%02x", (unsigned char)x->x_digest[i]); + printf("; digest len %u\n", x->x_digest_len); +} + +static void +send_digest(const struct executable *x, int pipefd) +{ + + send_chunk(x->x_digest, x->x_digest_len, pipefd); +} + +static void +receive_signature(struct executable *x, int pipefd) +{ + + receive_chunk(&x->x_signature, &x->x_signature_len, pipefd); +} + +static void +save(struct executable *x, FILE *fp, const char *path) +{ + size_t nwritten; + + assert(fp != NULL); + assert(path != NULL); + + nwritten = fwrite(x->x_buf, x->x_len, 1, fp); + if (nwritten != 1) + err(1, "%s: fwrite", path); +} + +int +child(const char *inpath, const char *outpath, int pipefd, + bool Vflag, bool vflag) +{ + int error; + FILE *outfp = NULL, *infp = NULL; + struct executable *x; + + infp = checked_fopen(inpath, "r"); + if (outpath != NULL) + outfp = checked_fopen(outpath, "w"); + + error = cap_enter(); + if (error != 0 && errno != ENOSYS) + err(1, "cap_enter"); + + x = calloc(1, sizeof(*x)); + if (x == NULL) + err(1, "calloc"); + x->x_path = inpath; + x->x_fp = infp; + + load(x); + parse(x); + if (Vflag) { + if (signature_size(x) == 0) + errx(1, "file not signed"); + + printf("file contains signature\n"); + if (vflag) { + digest(x); + show_digest(x); + show_certificate(x); + } + } else { + if (signature_size(x) != 0) + errx(1, "file already signed"); + + digest(x); + if (vflag) + show_digest(x); + send_digest(x, pipefd); + receive_signature(x, pipefd); + update(x); + save(x, outfp, outpath); + } + + return (0); +} diff --git a/usr.sbin/uefisign/magic.h b/usr.sbin/uefisign/magic.h new file mode 100644 index 0000000..4c3ad4e --- /dev/null +++ b/usr.sbin/uefisign/magic.h @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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. + * + * $FreeBSD$ + * + */ + +/* + * This file contains Authenticode-specific ASN.1 "configuration", used, + * after being processed by asprintf(3), as an input to ASN1_generate_nconf(3). + */ +static const char *magic_fmt = +"asn1 = SEQUENCE:SpcIndirectDataContent\n" +"\n" +"[SpcIndirectDataContent]\n" +"a = SEQUENCE:SpcAttributeTypeAndOptionalValue\n" +"b = SEQUENCE:DigestInfo\n" +"\n" +"[SpcAttributeTypeAndOptionalValue]\n" +"# SPC_PE_IMAGE_DATAOBJ\n" +"a = OID:1.3.6.1.4.1.311.2.1.15\n" +"b = SEQUENCE:SpcPeImageData\n" +"\n" +"[SpcPeImageData]\n" +"a = FORMAT:HEX,BITSTRING:00\n" +/* + * Well, there should be some other struct here, "SPCLink", but it doesn't + * appear to be neccessary for UEFI, and I have no idea how to synthesize it, + * as it uses the CHOICE type. + */ +"\n" +"[DigestInfo]\n" +"a = SEQUENCE:AlgorithmIdentifier\n" +/* + * Here goes the digest computed from PE headers and sections. + */ +"b = FORMAT:HEX,OCTETSTRING:%s\n" +"\n" +"[AlgorithmIdentifier]\n" +"a = OBJECT:sha256\n" +"b = NULL\n"; diff --git a/usr.sbin/uefisign/pe.c b/usr.sbin/uefisign/pe.c new file mode 100644 index 0000000..f4695b4 --- /dev/null +++ b/usr.sbin/uefisign/pe.c @@ -0,0 +1,564 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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. + * + */ + +/* + * PE format reference: + * http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "uefisign.h" + +#ifndef CTASSERT +#define CTASSERT(x) _CTASSERT(x, __LINE__) +#define _CTASSERT(x, y) __CTASSERT(x, y) +#define __CTASSERT(x, y) typedef char __assert_ ## y [(x) ? 1 : -1] +#endif + +struct mz_header { + uint8_t mz_signature[2]; + uint8_t mz_dont_care[58]; + uint16_t mz_lfanew; +} __attribute__((packed)); + +struct coff_header { + uint8_t coff_dont_care[2]; + uint16_t coff_number_of_sections; + uint8_t coff_dont_care_either[16]; +} __attribute__((packed)); + +#define PE_SIGNATURE 0x00004550 + +struct pe_header { + uint32_t pe_signature; + struct coff_header pe_coff; +} __attribute__((packed)); + +#define PE_OPTIONAL_MAGIC_32 0x010B +#define PE_OPTIONAL_MAGIC_32_PLUS 0x020B + +#define PE_OPTIONAL_SUBSYSTEM_EFI_APPLICATION 10 +#define PE_OPTIONAL_SUBSYSTEM_EFI_BOOT 11 +#define PE_OPTIONAL_SUBSYSTEM_EFI_RUNTIME 12 + +struct pe_optional_header_32 { + uint16_t po_magic; + uint8_t po_dont_care[58]; + uint32_t po_size_of_headers; + uint32_t po_checksum; + uint16_t po_subsystem; + uint8_t po_dont_care_either[22]; + uint32_t po_number_of_rva_and_sizes; +} __attribute__((packed)); + +CTASSERT(offsetof(struct pe_optional_header_32, po_size_of_headers) == 60); +CTASSERT(offsetof(struct pe_optional_header_32, po_checksum) == 64); +CTASSERT(offsetof(struct pe_optional_header_32, po_subsystem) == 68); +CTASSERT(offsetof(struct pe_optional_header_32, po_number_of_rva_and_sizes) == 92); + +struct pe_optional_header_32_plus { + uint16_t po_magic; + uint8_t po_dont_care[58]; + uint32_t po_size_of_headers; + uint32_t po_checksum; + uint16_t po_subsystem; + uint8_t po_dont_care_either[38]; + uint32_t po_number_of_rva_and_sizes; +} __attribute__((packed)); + +CTASSERT(offsetof(struct pe_optional_header_32_plus, po_size_of_headers) == 60); +CTASSERT(offsetof(struct pe_optional_header_32_plus, po_checksum) == 64); +CTASSERT(offsetof(struct pe_optional_header_32_plus, po_subsystem) == 68); +CTASSERT(offsetof(struct pe_optional_header_32_plus, po_number_of_rva_and_sizes) == 108); + +#define PE_DIRECTORY_ENTRY_CERTIFICATE 4 + +struct pe_directory_entry { + uint32_t pde_rva; + uint32_t pde_size; +} __attribute__((packed)); + +struct pe_section_header { + uint8_t psh_dont_care[16]; + uint32_t psh_size_of_raw_data; + uint32_t psh_pointer_to_raw_data; + uint8_t psh_dont_care_either[16]; +} __attribute__((packed)); + +CTASSERT(offsetof(struct pe_section_header, psh_size_of_raw_data) == 16); +CTASSERT(offsetof(struct pe_section_header, psh_pointer_to_raw_data) == 20); + +#define PE_CERTIFICATE_REVISION 0x0200 +#define PE_CERTIFICATE_TYPE 0x0002 + +struct pe_certificate { + uint32_t pc_len; + uint16_t pc_revision; + uint16_t pc_type; + char pc_signature[0]; +} __attribute__((packed)); + +void +range_check(const struct executable *x, off_t off, size_t len, + const char *name) +{ + + if (off < 0) { + errx(1, "%s starts at negative offset %jd", + name, (intmax_t)off); + } + if (off >= (off_t)x->x_len) { + errx(1, "%s starts at %jd, past the end of executable at %zd", + name, (intmax_t)off, x->x_len); + } + if (len >= x->x_len) { + errx(1, "%s size %zd is larger than the executable size %zd", + name, len, x->x_len); + } + if (off + len > x->x_len) { + errx(1, "%s extends to %jd, past the end of executable at %zd", + name, (intmax_t)(off + len), x->x_len); + } +} + +size_t +signature_size(const struct executable *x) +{ + const struct pe_directory_entry *pde; + + range_check(x, x->x_certificate_entry_off, + x->x_certificate_entry_len, "Certificate Directory"); + + pde = (struct pe_directory_entry *) + (x->x_buf + x->x_certificate_entry_off); + + if (pde->pde_rva != 0 && pde->pde_size == 0) + warnx("signature size is 0, but its RVA is %d", pde->pde_rva); + if (pde->pde_rva == 0 && pde->pde_size != 0) + warnx("signature RVA is 0, but its size is %d", pde->pde_size); + + return (pde->pde_size); +} + +void +show_certificate(const struct executable *x) +{ + struct pe_certificate *pc; + const struct pe_directory_entry *pde; + + range_check(x, x->x_certificate_entry_off, + x->x_certificate_entry_len, "Certificate Directory"); + + pde = (struct pe_directory_entry *) + (x->x_buf + x->x_certificate_entry_off); + + if (signature_size(x) == 0) { + printf("file not signed\n"); + return; + } + +#if 0 + printf("certificate chunk at offset %zd, size %zd\n", + pde->pde_rva, pde->pde_size); +#endif + + range_check(x, pde->pde_rva, pde->pde_size, "Certificate chunk"); + + pc = (struct pe_certificate *)(x->x_buf + pde->pde_rva); + if (pc->pc_revision != PE_CERTIFICATE_REVISION) { + errx(1, "wrong certificate chunk revision, is %d, should be %d", + pc->pc_revision, PE_CERTIFICATE_REVISION); + } + if (pc->pc_type != PE_CERTIFICATE_TYPE) { + errx(1, "wrong certificate chunk type, is %d, should be %d", + pc->pc_type, PE_CERTIFICATE_TYPE); + } + printf("to dump PKCS7:\n " + "dd if='%s' bs=1 skip=%zd | openssl pkcs7 -inform DER -print\n", + x->x_path, pde->pde_rva + offsetof(struct pe_certificate, pc_signature)); + printf("to dump raw ASN.1:\n " + "openssl asn1parse -i -inform DER -offset %zd -in '%s'\n", + pde->pde_rva + offsetof(struct pe_certificate, pc_signature), x->x_path); +} + +static void +parse_section_table(struct executable *x, off_t off, int number_of_sections) +{ + const struct pe_section_header *psh; + int i; + + range_check(x, off, sizeof(*psh) * number_of_sections, + "section table"); + + if (x->x_headers_len <= off + sizeof(*psh) * number_of_sections) + errx(1, "section table outside of headers"); + + psh = (const struct pe_section_header *)(x->x_buf + off); + + if (number_of_sections >= MAX_SECTIONS) { + errx(1, "too many sections: got %d, should be %d", + number_of_sections, MAX_SECTIONS); + } + x->x_nsections = number_of_sections; + + for (i = 0; i < number_of_sections; i++) { + if (psh->psh_pointer_to_raw_data < x->x_headers_len) + errx(1, "section points inside the headers"); + + range_check(x, psh->psh_pointer_to_raw_data, + psh->psh_size_of_raw_data, "section"); +#if 0 + printf("section %d: start %d, size %d\n", + i, psh->psh_pointer_to_raw_data, psh->psh_size_of_raw_data); +#endif + x->x_section_off[i] = psh->psh_pointer_to_raw_data; + x->x_section_len[i] = psh->psh_size_of_raw_data; + psh++; + } +} + +static void +parse_directory(struct executable *x, off_t off, + int number_of_rva_and_sizes, int number_of_sections) +{ + //int i; + const struct pe_directory_entry *pde; + + //printf("Data Directory at offset %zd\n", off); + + if (number_of_rva_and_sizes <= PE_DIRECTORY_ENTRY_CERTIFICATE) { + errx(1, "wrong NumberOfRvaAndSizes %d; should be at least %d", + number_of_rva_and_sizes, PE_DIRECTORY_ENTRY_CERTIFICATE); + } + + range_check(x, off, sizeof(*pde) * number_of_rva_and_sizes, + "PE Data Directory"); + if (x->x_headers_len <= off + sizeof(*pde) * number_of_rva_and_sizes) + errx(1, "PE Data Directory outside of headers"); + + x->x_certificate_entry_off = + off + sizeof(*pde) * PE_DIRECTORY_ENTRY_CERTIFICATE; + x->x_certificate_entry_len = sizeof(*pde); +#if 0 + printf("certificate directory entry at offset %zd, len %zd\n", + x->x_certificate_entry_off, x->x_certificate_entry_len); + + pde = (struct pe_directory_entry *)(x->x_buf + off); + for (i = 0; i < number_of_rva_and_sizes; i++) { + printf("rva %zd, size %zd\n", pde->pde_rva, pde->pde_size); + pde++; + } +#endif + + return (parse_section_table(x, + off + sizeof(*pde) * number_of_rva_and_sizes, number_of_sections)); +} + +/* + * The PE checksum algorithm is undocumented; this code is mostly based on + * http://forum.sysinternals.com/optional-header-checksum-calculation_topic24214.html + * + * "Sum the entire image file, excluding the CheckSum field in the optional + * header, as an array of USHORTs, allowing any carry above 16 bits to be added + * back onto the low 16 bits. Then add the file size to get a 32-bit value." + * + * Note that most software does not care about the checksum at all; perhaps + * we could just set it to 0 instead. + * + * XXX: Endianess? + */ +static uint32_t +compute_checksum(const struct executable *x) +{ + uint32_t cksum = 0; + uint16_t tmp; + int i; + + range_check(x, x->x_checksum_off, x->x_checksum_len, "PE checksum"); + + assert(x->x_checksum_off % 2 == 0); + + for (i = 0; i + sizeof(tmp) < x->x_len; i += 2) { + /* + * Don't checksum the checksum. The +2 is because the checksum + * is 4 bytes, and here we're iterating over 2 byte chunks. + */ + if (i == x->x_checksum_off || i == x->x_checksum_off + 2) { + tmp = 0; + } else { + assert(i + sizeof(tmp) <= x->x_len); + memcpy(&tmp, x->x_buf + i, sizeof(tmp)); + } + + cksum += tmp; + cksum += cksum >> 16; + cksum &= 0xffff; + } + + cksum += cksum >> 16; + cksum &= 0xffff; + + cksum += x->x_len; + + return (cksum); +} + +static void +parse_optional_32_plus(struct executable *x, off_t off, + int number_of_sections) +{ +#if 0 + uint32_t computed_checksum; +#endif + const struct pe_optional_header_32_plus *po; + + range_check(x, off, sizeof(*po), "PE Optional Header"); + + po = (struct pe_optional_header_32_plus *)(x->x_buf + off); + switch (po->po_subsystem) { + case PE_OPTIONAL_SUBSYSTEM_EFI_APPLICATION: + case PE_OPTIONAL_SUBSYSTEM_EFI_BOOT: + case PE_OPTIONAL_SUBSYSTEM_EFI_RUNTIME: + break; + default: + errx(1, "wrong PE Optional Header subsystem 0x%x", + po->po_subsystem); + } + +#if 0 + printf("subsystem %d, checksum 0x%x, %d data directories\n", + po->po_subsystem, po->po_checksum, po->po_number_of_rva_and_sizes); +#endif + + x->x_checksum_off = off + + offsetof(struct pe_optional_header_32_plus, po_checksum); + x->x_checksum_len = sizeof(po->po_checksum); +#if 0 + printf("checksum 0x%x at offset %zd, len %zd\n", + po->po_checksum, x->x_checksum_off, x->x_checksum_len); + + computed_checksum = compute_checksum(x); + if (computed_checksum != po->po_checksum) { + warnx("invalid PE+ checksum; is 0x%x, should be 0x%x", + po->po_checksum, computed_checksum); + } +#endif + + if (x->x_len < x->x_headers_len) + errx(1, "invalid SizeOfHeaders %d", po->po_size_of_headers); + x->x_headers_len = po->po_size_of_headers; + //printf("Size of Headers: %d\n", po->po_size_of_headers); + + return (parse_directory(x, off + sizeof(*po), + po->po_number_of_rva_and_sizes, number_of_sections)); +} + +static void +parse_optional_32(struct executable *x, off_t off, int number_of_sections) +{ +#if 0 + uint32_t computed_checksum; +#endif + const struct pe_optional_header_32 *po; + + range_check(x, off, sizeof(*po), "PE Optional Header"); + + po = (struct pe_optional_header_32 *)(x->x_buf + off); + switch (po->po_subsystem) { + case PE_OPTIONAL_SUBSYSTEM_EFI_APPLICATION: + case PE_OPTIONAL_SUBSYSTEM_EFI_BOOT: + case PE_OPTIONAL_SUBSYSTEM_EFI_RUNTIME: + break; + default: + errx(1, "wrong PE Optional Header subsystem 0x%x", + po->po_subsystem); + } + +#if 0 + printf("subsystem %d, checksum 0x%x, %d data directories\n", + po->po_subsystem, po->po_checksum, po->po_number_of_rva_and_sizes); +#endif + + x->x_checksum_off = off + + offsetof(struct pe_optional_header_32, po_checksum); + x->x_checksum_len = sizeof(po->po_checksum); +#if 0 + printf("checksum at offset %zd, len %zd\n", + x->x_checksum_off, x->x_checksum_len); + + computed_checksum = compute_checksum(x); + if (computed_checksum != po->po_checksum) { + warnx("invalid PE checksum; is 0x%x, should be 0x%x", + po->po_checksum, computed_checksum); + } +#endif + + if (x->x_len < x->x_headers_len) + errx(1, "invalid SizeOfHeaders %d", po->po_size_of_headers); + x->x_headers_len = po->po_size_of_headers; + //printf("Size of Headers: %d\n", po->po_size_of_headers); + + return (parse_directory(x, off + sizeof(*po), + po->po_number_of_rva_and_sizes, number_of_sections)); +} + +static void +parse_optional(struct executable *x, off_t off, int number_of_sections) +{ + const struct pe_optional_header_32 *po; + + //printf("Optional header offset %zd\n", off); + + range_check(x, off, sizeof(*po), "PE Optional Header"); + + po = (struct pe_optional_header_32 *)(x->x_buf + off); + + switch (po->po_magic) { + case PE_OPTIONAL_MAGIC_32: + return (parse_optional_32(x, off, number_of_sections)); + case PE_OPTIONAL_MAGIC_32_PLUS: + return (parse_optional_32_plus(x, off, number_of_sections)); + default: + errx(1, "wrong PE Optional Header magic 0x%x", po->po_magic); + } +} + +static void +parse_pe(struct executable *x, off_t off) +{ + const struct pe_header *pe; + + //printf("PE offset %zd, PE size %zd\n", off, sizeof(*pe)); + + range_check(x, off, sizeof(*pe), "PE header"); + + pe = (struct pe_header *)(x->x_buf + off); + if (pe->pe_signature != PE_SIGNATURE) + errx(1, "wrong PE signature 0x%x", pe->pe_signature); + + //printf("Number of sections: %d\n", pe->pe_coff.coff_number_of_sections); + + parse_optional(x, off + sizeof(*pe), + pe->pe_coff.coff_number_of_sections); +} + +void +parse(struct executable *x) +{ + const struct mz_header *mz; + + range_check(x, 0, sizeof(*mz), "MZ header"); + + mz = (struct mz_header *)x->x_buf; + if (mz->mz_signature[0] != 'M' || mz->mz_signature[1] != 'Z') + errx(1, "MZ header not found"); + + return (parse_pe(x, mz->mz_lfanew)); +} + +static off_t +append(struct executable *x, void *ptr, size_t len) +{ + off_t off; + + /* + * XXX: Alignment. + */ + off = x->x_len; + x->x_buf = realloc(x->x_buf, x->x_len + len); + if (x->x_buf == NULL) + err(1, "realloc"); + memcpy(x->x_buf + x->x_len, ptr, len); + x->x_len += len; + + return (off); +} + +void +update(struct executable *x) +{ + uint32_t checksum; + struct pe_certificate *pc; + struct pe_directory_entry pde; + size_t pc_len; + off_t pc_off; + + pc_len = sizeof(*pc) + x->x_signature_len; + pc = calloc(1, pc_len); + if (pc == NULL) + err(1, "calloc"); + +#if 0 + /* + * Note that pc_len is the length of pc_certificate, + * not the whole structure. + * + * XXX: That's what the spec says - but it breaks at least + * sbverify and "pesign -S", so the spec is probably wrong. + */ + pc->pc_len = x->x_signature_len; +#else + pc->pc_len = pc_len; +#endif + pc->pc_revision = PE_CERTIFICATE_REVISION; + pc->pc_type = PE_CERTIFICATE_TYPE; + memcpy(&pc->pc_signature, x->x_signature, x->x_signature_len); + + pc_off = append(x, pc, pc_len); +#if 0 + printf("added signature chunk at offset %zd, len %zd\n", + pc_off, pc_len); +#endif + + free(pc); + + pde.pde_rva = pc_off; + pde.pde_size = pc_len; + memcpy(x->x_buf + x->x_certificate_entry_off, &pde, sizeof(pde)); + + checksum = compute_checksum(x); + assert(sizeof(checksum) == x->x_checksum_len); + memcpy(x->x_buf + x->x_checksum_off, &checksum, sizeof(checksum)); +#if 0 + printf("new checksum 0x%x\n", checksum); +#endif +} diff --git a/usr.sbin/uefisign/uefisign.8 b/usr.sbin/uefisign/uefisign.8 new file mode 100644 index 0000000..0bda8c9 --- /dev/null +++ b/usr.sbin/uefisign/uefisign.8 @@ -0,0 +1,93 @@ +.\" Copyright (c) 2014 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This software was developed by Edward Tomasz Napierala under sponsorship +.\" from the FreeBSD Foundation. +.\" +.\" 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 AUTHORS 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 AUTHORS 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. +.\" +.\" $FreeBSD$ +.\" +.Dd December 10, 2014 +.Dt UEFISIGN 8 +.Os +.Sh NAME +.Nm uefisign +.Nd UEFI Secure Boot signing utility +.Sh SYNOPSIS +.Nm +.Fl k Ar key +.Fl c Ar certificate +.Fl o Ar output +.Op Fl v +.Ar file +.Nm +.Fl V +.Op Fl v +.Ar file +.Sh DESCRIPTION +The +.Nm +utility signs PE binary files using Authenticode scheme, as required by +UEFI Secure Boot specification. +Alternatively, it can be used to view and verify existing signatures. +These options are available: +.Bl -tag -width ".Fl l" +.It Fl V +Determine whether the file is signed. +Note that this does not verify the correctness of the signature; +only that the file contains a signature. +.It Fl k +Name of file containing the private key used to sign the binary. +.It Fl c +Name of file containing the certificate used to sign the binary. +.It Fl o +Name of file to write the signed binary to. +.It Fl v +Be verbose. +.El +.Sh EXIT STATUS +The +.Nm +utility exits 0 on success, and >0 if an error occurs. +.Sh EXAMPLES +Generate self-signed certificate and use it to sign a binary: +.Dl /usr/share/examples/uefisign/uefikeys testcert +.Dl uefisign -c testcert.pem -k testcert.key -o signed-binary binary +.Pp +View signature: +.Dl uefisign -Vv binary +.Sh SEE ALSO +.Xr openssl 1 , +.Xr loader 8 , +.Xr uefi 8 +.Sh HISTORY +The +.Nm +command appeared in +.Fx 11.0 . +.Sh AUTHORS +The +.Nm +utility was developed by +.An Edward Tomasz Napierala Aq Mt trasz@FreeBSD.org +under sponsorship from the FreeBSD Foundation. diff --git a/usr.sbin/uefisign/uefisign.c b/usr.sbin/uefisign/uefisign.c new file mode 100644 index 0000000..927f02b --- /dev/null +++ b/usr.sbin/uefisign/uefisign.c @@ -0,0 +1,425 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/wait.h> +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <openssl/conf.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/pem.h> +#include <openssl/pkcs7.h> + +#include "uefisign.h" +#include "magic.h" + +static void +usage(void) +{ + + fprintf(stderr, "usage: uefisign -c cert -k key -o outfile [-v] file\n" + " uefisign -V [-c cert] [-v] file\n"); + exit(1); +} + +static char * +checked_strdup(const char *s) +{ + char *c; + + c = strdup(s); + if (c == NULL) + err(1, "strdup"); + return (c); +} + +FILE * +checked_fopen(const char *path, const char *mode) +{ + FILE *fp; + + assert(path != NULL); + + fp = fopen(path, mode); + if (fp == NULL) + err(1, "%s", path); + return (fp); +} + +void +send_chunk(const void *buf, size_t len, int pipefd) +{ + ssize_t ret; + + ret = write(pipefd, &len, sizeof(len)); + if (ret != sizeof(len)) + err(1, "write"); + ret = write(pipefd, buf, len); + if (ret != (ssize_t)len) + err(1, "write"); +} + +void +receive_chunk(void **bufp, size_t *lenp, int pipefd) +{ + ssize_t ret; + size_t len; + void *buf; + + ret = read(pipefd, &len, sizeof(len)); + if (ret != sizeof(len)) + err(1, "read"); + + buf = calloc(1, len); + if (buf == NULL) + err(1, "calloc"); + + ret = read(pipefd, buf, len); + if (ret != (ssize_t)len) + err(1, "read"); + + *bufp = buf; + *lenp = len; +} + +static char * +bin2hex(const char *bin, size_t bin_len) +{ + unsigned char *hex, *tmp, ch; + size_t hex_len; + size_t i; + + hex_len = bin_len * 2 + 1; /* +1 for '\0'. */ + hex = malloc(hex_len); + if (hex == NULL) + err(1, "malloc"); + + tmp = hex; + for (i = 0; i < bin_len; i++) { + ch = bin[i]; + tmp += sprintf(tmp, "%02x", ch); + } + + return (hex); +} + +/* + * We need to replace a standard chunk of PKCS7 signature with one mandated + * by Authenticode. Problem is, replacing it just like that and then calling + * PKCS7_final() would make OpenSSL segfault somewhere in PKCS7_dataFinal(). + * So, instead, we call PKCS7_dataInit(), then put our Authenticode-specific + * data into BIO it returned, then call PKCS7_dataFinal() - which now somehow + * does not panic - and _then_ we replace it in the signature. This technique + * was used in sbsigntool by Jeremy Kerr, and might have originated in + * osslsigncode. + */ +static void +magic(PKCS7 *pkcs7, const char *digest, size_t digest_len) +{ + BIO *bio, *t_bio; + ASN1_TYPE *t; + ASN1_STRING *s; + CONF *cnf; + unsigned char *buf, *tmp; + char *digest_hex, *magic_conf, *str; + int len, nid, ok; + + digest_hex = bin2hex(digest, digest_len); + + /* + * Construct the SpcIndirectDataContent chunk. + */ + nid = OBJ_create("1.3.6.1.4.1.311.2.1.4", NULL, NULL); + + asprintf(&magic_conf, magic_fmt, digest_hex); + if (magic_conf == NULL) + err(1, "asprintf"); + + bio = BIO_new_mem_buf((void *)magic_conf, -1); + if (bio == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "BIO_new_mem_buf(3) failed"); + } + + cnf = NCONF_new(NULL); + if (cnf == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "NCONF_new(3) failed"); + } + + ok = NCONF_load_bio(cnf, bio, NULL); + if (ok == 0) { + ERR_print_errors_fp(stderr); + errx(1, "NCONF_load_bio(3) failed"); + } + + str = NCONF_get_string(cnf, "default", "asn1"); + if (str == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "NCONF_get_string(3) failed"); + } + + t = ASN1_generate_nconf(str, cnf); + if (t == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "ASN1_generate_nconf(3) failed"); + } + + /* + * We now have our proprietary piece of ASN.1. Let's do + * the actual signing. + */ + len = i2d_ASN1_TYPE(t, NULL); + tmp = buf = calloc(1, len); + if (tmp == NULL) + err(1, "calloc"); + i2d_ASN1_TYPE(t, &tmp); + + /* + * We now have contents of 't' stuffed into memory buffer 'buf'. + */ + tmp = NULL; + t = NULL; + + t_bio = PKCS7_dataInit(pkcs7, NULL); + if (t_bio == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "PKCS7_dataInit(3) failed"); + } + + BIO_write(t_bio, buf + 2, len - 2); + + ok = PKCS7_dataFinal(pkcs7, t_bio); + if (ok == 0) { + ERR_print_errors_fp(stderr); + errx(1, "PKCS7_dataFinal(3) failed"); + } + + t = ASN1_TYPE_new(); + s = ASN1_STRING_new(); + ASN1_STRING_set(s, buf, len); + ASN1_TYPE_set(t, V_ASN1_SEQUENCE, s); + + PKCS7_set0_type_other(pkcs7->d.sign->contents, nid, t); +} + +static void +sign(X509 *cert, EVP_PKEY *key, int pipefd) +{ + PKCS7 *pkcs7; + BIO *bio, *out; + const EVP_MD *md; + PKCS7_SIGNER_INFO *info; + void *digest, *signature; + size_t digest_len, signature_len; + int ok; + + assert(cert != NULL); + assert(key != NULL); + + receive_chunk(&digest, &digest_len, pipefd); + + bio = BIO_new_mem_buf(digest, digest_len); + if (bio == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "BIO_new_mem_buf(3) failed"); + } + + pkcs7 = PKCS7_sign(NULL, NULL, NULL, bio, PKCS7_BINARY | PKCS7_PARTIAL); + if (pkcs7 == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "PKCS7_sign(3) failed"); + } + + md = EVP_get_digestbyname(DIGEST); + if (md == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "EVP_get_digestbyname(\"%s\") failed", DIGEST); + } + + info = PKCS7_sign_add_signer(pkcs7, cert, key, md, 0); + if (info == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "PKCS7_sign_add_signer(3) failed"); + } + + /* + * XXX: All the signed binaries seem to have this, but where is it + * described in the spec? + */ + PKCS7_add_signed_attribute(info, NID_pkcs9_contentType, + V_ASN1_OBJECT, OBJ_txt2obj("1.3.6.1.4.1.311.2.1.4", 1)); + + magic(pkcs7, digest, digest_len); + +#if 0 + out = BIO_new(BIO_s_file()); + BIO_set_fp(out, stdout, BIO_NOCLOSE); + PKCS7_print_ctx(out, pkcs7, 0, NULL); + + i2d_PKCS7_bio(out, pkcs7); +#endif + + out = BIO_new(BIO_s_mem()); + if (out == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "BIO_new(3) failed"); + } + + ok = i2d_PKCS7_bio(out, pkcs7); + if (ok == 0) { + ERR_print_errors_fp(stderr); + errx(1, "i2d_PKCS7_bio(3) failed"); + } + + signature_len = BIO_get_mem_data(out, &signature); + if (signature_len <= 0) { + ERR_print_errors_fp(stderr); + errx(1, "BIO_get_mem_data(3) failed"); + } + + (void)BIO_set_close(out, BIO_NOCLOSE); + BIO_free(out); + + send_chunk(signature, signature_len, pipefd); +} + +static int +wait_for_child(pid_t pid) +{ + int status; + + pid = waitpid(pid, &status, 0); + if (pid == -1) + err(1, "waitpid"); + + return (WEXITSTATUS(status)); +} + +int +main(int argc, char **argv) +{ + int ch, error; + bool Vflag = false, vflag = false; + const char *certpath = NULL, *keypath = NULL, *outpath = NULL, *inpath = NULL; + FILE *certfp = NULL, *keyfp = NULL; + X509 *cert = NULL; + EVP_PKEY *key = NULL; + pid_t pid; + int pipefds[2]; + + while ((ch = getopt(argc, argv, "Vc:k:o:v")) != -1) { + switch (ch) { + case 'V': + Vflag = true; + break; + case 'c': + certpath = checked_strdup(optarg); + break; + case 'k': + keypath = checked_strdup(optarg); + break; + case 'o': + outpath = checked_strdup(optarg); + break; + case 'v': + vflag = true; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + if (argc != 1) + usage(); + + if (Vflag) { + if (certpath != NULL) + errx(1, "-V and -c are mutually exclusive"); + if (keypath != NULL) + errx(1, "-V and -k are mutually exclusive"); + if (outpath != NULL) + errx(1, "-V and -o are mutually exclusive"); + } else { + if (certpath == NULL) + errx(1, "-c option is mandatory"); + if (keypath == NULL) + errx(1, "-k option is mandatory"); + if (outpath == NULL) + errx(1, "-o option is mandatory"); + } + + inpath = argv[0]; + + OPENSSL_config(NULL); + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + + error = pipe(pipefds); + if (error != 0) + err(1, "pipe"); + + pid = fork(); + if (pid < 0) + err(1, "fork"); + + if (pid == 0) + return (child(inpath, outpath, pipefds[1], Vflag, vflag)); + + if (!Vflag) { + certfp = checked_fopen(certpath, "r"); + cert = PEM_read_X509(certfp, NULL, NULL, NULL); + if (cert == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "failed to load certificate from %s", certpath); + } + + keyfp = checked_fopen(keypath, "r"); + key = PEM_read_PrivateKey(keyfp, NULL, NULL, NULL); + if (key == NULL) { + ERR_print_errors_fp(stderr); + errx(1, "failed to load private key from %s", keypath); + } + + sign(cert, key, pipefds[0]); + } + + return (wait_for_child(pid)); +} diff --git a/usr.sbin/uefisign/uefisign.h b/usr.sbin/uefisign/uefisign.h new file mode 100644 index 0000000..d0920b8 --- /dev/null +++ b/usr.sbin/uefisign/uefisign.h @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * 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. + * + * $FreeBSD$ + */ + +#ifndef EFISIGN_H +#define EFISIGN_H + +#include <stdbool.h> +#include <openssl/evp.h> + +#define DIGEST "SHA256" +#define MAX_SECTIONS 128 + +struct executable { + const char *x_path; + FILE *x_fp; + + char *x_buf; + size_t x_len; + + /* + * Set by pe_parse(), used by digest(). + */ + size_t x_headers_len; + + off_t x_checksum_off; + size_t x_checksum_len; + + off_t x_certificate_entry_off; + size_t x_certificate_entry_len; + + int x_nsections; + off_t x_section_off[MAX_SECTIONS]; + size_t x_section_len[MAX_SECTIONS]; + + /* + * Computed by digest(). + */ + unsigned char x_digest[EVP_MAX_MD_SIZE]; + unsigned int x_digest_len; + + /* + * Received from the parent process, which computes it in sign(). + */ + void *x_signature; + size_t x_signature_len; +}; + + +FILE *checked_fopen(const char *path, const char *mode); +void send_chunk(const void *buf, size_t len, int pipefd); +void receive_chunk(void **bufp, size_t *lenp, int pipefd); + +int child(const char *inpath, const char *outpath, int pipefd, + bool Vflag, bool vflag); + +void parse(struct executable *x); +void update(struct executable *x); +size_t signature_size(const struct executable *x); +void show_certificate(const struct executable *x); +void range_check(const struct executable *x, + off_t off, size_t len, const char *name); + +#endif /* !EFISIGN_H */ diff --git a/usr.sbin/ugidfw/Makefile b/usr.sbin/ugidfw/Makefile index d89bc85..7a5453e 100644 --- a/usr.sbin/ugidfw/Makefile +++ b/usr.sbin/ugidfw/Makefile @@ -3,7 +3,6 @@ PROG= ugidfw MAN= ugidfw.8 -DPADD= ${LIBUGIDFW} -LDADD= -lugidfw +LIBADD= ugidfw .include <bsd.prog.mk> diff --git a/usr.sbin/uhsoctl/Makefile b/usr.sbin/uhsoctl/Makefile index 565b2e6..264384b 100644 --- a/usr.sbin/uhsoctl/Makefile +++ b/usr.sbin/uhsoctl/Makefile @@ -4,7 +4,6 @@ PROG= uhsoctl MAN= uhsoctl.1 WARNS?= 1 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/uhsoctl/uhsoctl.c b/usr.sbin/uhsoctl/uhsoctl.c index 21b6220..686d45f 100644 --- a/usr.sbin/uhsoctl/uhsoctl.c +++ b/usr.sbin/uhsoctl/uhsoctl.c @@ -37,7 +37,6 @@ #include <arpa/inet.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_dl.h> #include <net/route.h> #include <netinet/in.h> diff --git a/usr.sbin/unbound/anchor/Makefile b/usr.sbin/unbound/anchor/Makefile index 970fb70..64e01d2 100644 --- a/usr.sbin/unbound/anchor/Makefile +++ b/usr.sbin/unbound/anchor/Makefile @@ -10,9 +10,7 @@ EXPATDIR= ${.CURDIR}/../../../contrib/expat PROG= unbound-anchor SRCS= unbound-anchor.c CFLAGS= -I${UNBOUNDDIR} -I${LDNSDIR} -I${EXPATDIR}/lib -DPADD= ${LIBUNBOUND} ${LIBLDNS} ${LIBUTIL} ${LIBBSDXML} ${LIBSSL} ${LIBCRYPTO} ${LIBPTHREAD} -LDADD= ${LDUNBOUND} ${LDLDNS} -lutil -lbsdxml -lssl -lcrypto -lpthread -USEPRIVATELIB= ldns +LIBADD= unbound bsdxml ssl crypto pthread MAN= unbound-anchor.8 .include <bsd.prog.mk> diff --git a/usr.sbin/unbound/checkconf/Makefile b/usr.sbin/unbound/checkconf/Makefile index 0993d3d..884465b 100644 --- a/usr.sbin/unbound/checkconf/Makefile +++ b/usr.sbin/unbound/checkconf/Makefile @@ -9,9 +9,7 @@ UNBOUNDDIR= ${.CURDIR}/../../../contrib/unbound PROG= unbound-checkconf SRCS= unbound-checkconf.c worker_cb.c CFLAGS= -I${UNBOUNDDIR} -I${LDNSDIR} -DPADD= ${LIBUNBOUND} ${LIBLDNS} ${LIBUTIL} ${LIBSSL} ${LIBCRYPTO} ${LIBPTHREAD} -LDADD= ${LDUNBOUND} ${LDLDNS} -lutil -lssl -lcrypto -lpthread -USEPRIVATELIB= ldns +LIBADD= unbound pthread MAN= unbound-checkconf.8 .include <bsd.prog.mk> diff --git a/usr.sbin/unbound/control/Makefile b/usr.sbin/unbound/control/Makefile index 2989e73..1614127 100644 --- a/usr.sbin/unbound/control/Makefile +++ b/usr.sbin/unbound/control/Makefile @@ -10,9 +10,7 @@ PROG= unbound-control SCRIPTS= unbound-control-setup.sh SRCS= unbound-control.c worker_cb.c CFLAGS= -I${UNBOUNDDIR} -I${LDNSDIR} -DPADD= ${LIBUNBOUND} ${LIBLDNS} ${LIBUTIL} ${LIBSSL} ${LIBCRYPTO} ${LIBPTHREAD} -LDADD= ${LDUNBOUND} ${LDLDNS} -lutil -lssl -lcrypto -lpthread -USEPRIVATELIB= ldns +LIBADD= unbound crypto ssl pthread MAN= unbound-control.8 .include <bsd.prog.mk> diff --git a/usr.sbin/unbound/daemon/Makefile b/usr.sbin/unbound/daemon/Makefile index a8b1bb2..f90e06e 100644 --- a/usr.sbin/unbound/daemon/Makefile +++ b/usr.sbin/unbound/daemon/Makefile @@ -9,9 +9,7 @@ UNBOUNDDIR= ${.CURDIR}/../../../contrib/unbound PROG= unbound SRCS= acl_list.c cachedump.c daemon.c remote.c stats.c unbound.c worker.c CFLAGS= -I${UNBOUNDDIR} -I${LDNSDIR} -DPADD= ${LIBUNBOUND} ${LIBLDNS} ${LIBUTIL} ${LIBSSL} ${LIBCRYPTO} ${LIBPTHREAD} -LDADD= ${LDUNBOUND} ${LDLDNS} -lutil -lssl -lcrypto -lpthread -USEPRIVATELIB= ldns +LIBADD= unbound util ssl crypto pthread MAN= unbound.8 unbound.conf.5 .include <bsd.prog.mk> diff --git a/usr.sbin/unbound/local-setup/local-unbound-setup.sh b/usr.sbin/unbound/local-setup/local-unbound-setup.sh index a16e6d0..4c464d1 100755 --- a/usr.sbin/unbound/local-setup/local-unbound-setup.sh +++ b/usr.sbin/unbound/local-setup/local-unbound-setup.sh @@ -34,6 +34,8 @@ user="" unbound_conf="" forward_conf="" lanzones_conf="" +control_conf="" +control_socket="" workdir="" confdir="" chrootdir="" @@ -61,6 +63,8 @@ set_defaults() { : ${unbound_conf:=${workdir}/unbound.conf} : ${forward_conf:=${workdir}/forward.conf} : ${lanzones_conf:=${workdir}/lan-zones.conf} + : ${control_conf:=${workdir}/control.conf} + : ${control_socket:=/var/run/local_unbound.ctl} : ${anchor:=${workdir}/root.key} : ${pidfile:=/var/run/local_unbound.pid} : ${resolv_conf:=/etc/resolv.conf} @@ -76,7 +80,7 @@ set_defaults() { set_chrootdir() { chrootdir="${workdir}" for file in "${unbound_conf}" "${forward_conf}" \ - "${lanzones_conf}" "${anchor}" ; do + "${lanzones_conf}" "${control_conf}" "${anchor}" ; do if [ "${file#${workdir%/}/}" = "${file}" ] ; then echo "warning: ${file} is outside ${workdir}" >&2 chrootdir="" @@ -153,6 +157,14 @@ gen_resolv_conf() { } # +# Boilerplate +# +do_not_edit() { + echo "# This file was generated by $self." + echo "# Modifications will be overwritten." +} + +# # Generate resolvconf.conf so it updates forward.conf in addition to # resolv.conf. Note "in addition to" rather than "instead of", # because we still want it to update the domain name and search path @@ -160,7 +172,7 @@ gen_resolv_conf() { # the libc resolver will try unbound first. # gen_resolvconf_conf() { - echo "# Generated by $self" + do_not_edit echo "resolv_conf=\"/dev/null\" # prevent updating ${resolv_conf}" echo "unbound_conf=\"${forward_conf}\"" echo "unbound_pid=\"${pidfile}\"" @@ -173,8 +185,7 @@ gen_resolvconf_conf() { # Generate forward.conf # gen_forward_conf() { - echo "# Generated by $self" - echo "# Do not edit this file." + do_not_edit echo "forward-zone:" echo " name: ." for forwarder ; do @@ -190,8 +201,7 @@ gen_forward_conf() { # Generate lan-zones.conf # gen_lanzones_conf() { - echo "# Generated by $self" - echo "# Do not edit this file." + do_not_edit echo "server:" echo " # Unblock reverse lookups for LAN addresses" echo " unblock-lan-zones: yes" @@ -223,10 +233,21 @@ gen_lanzones_conf() { } # +# Generate control.conf +# +gen_control_conf() { + do_not_edit + echo "remote-control:" + echo " control-enable: yes" + echo " control-interface: ${control_socket}" + echo " control-use-cert: no" +} + +# # Generate unbound.conf # gen_unbound_conf() { - echo "# Generated by $self" + do_not_edit echo "server:" echo " username: ${user}" echo " directory: ${workdir}" @@ -240,6 +261,9 @@ gen_unbound_conf() { if [ -f "${lanzones_conf}" ] ; then echo "include: ${lanzones_conf}" fi + if [ -f "${control_conf}" ] ; then + echo "include: ${control_conf}" + fi if [ -d "${confdir}" ] ; then echo "include: ${confdir}/*.conf" fi @@ -278,6 +302,8 @@ usage() { echo " -C path full path to additional configuration directory" echo " -c path full path to unbound configuration file" echo " -f path full path to forwarding configuration" + echo " -O path full path to remote control socket" + echo " -o path full path to remote control configuration" echo " -p path full path to pid file" echo " -R path full path to resolvconf.conf" echo " -r path full path to resolv.conf" @@ -296,7 +322,7 @@ main() { # # Parse and validate command-line options # - while getopts "a:C:c:f:np:R:r:s:u:w:" option ; do + while getopts "a:C:c:f:no:p:R:r:s:u:w:" option ; do case $option in a) anchor="$OPTARG" @@ -313,6 +339,12 @@ main() { n) start_unbound="no" ;; + O) + control_socket="$OPTARG" + ;; + o) + control_conf="$OPTARG" + ;; p) pidfile="$OPTARG" ;; @@ -361,7 +393,7 @@ main() { fi else local tmp_forward_conf=$(mktemp -u "${forward_conf}.XXXXX") - gen_forward_conf ${forwarders} >"${tmp_forward_conf}" + gen_forward_conf ${forwarders} | unexpand >"${tmp_forward_conf}" replace "${forward_conf}" "${tmp_forward_conf}" fi @@ -369,15 +401,22 @@ main() { # Generate lan-zones.conf. # local tmp_lanzones_conf=$(mktemp -u "${lanzones_conf}.XXXXX") - gen_lanzones_conf >"${tmp_lanzones_conf}" + gen_lanzones_conf | unexpand >"${tmp_lanzones_conf}" replace "${lanzones_conf}" "${tmp_lanzones_conf}" # + # Generate control.conf. + # + local tmp_control_conf=$(mktemp -u "${control_conf}.XXXXX") + gen_control_conf | unexpand >"${tmp_control_conf}" + replace "${control_conf}" "${tmp_control_conf}" + + # # Generate unbound.conf. # local tmp_unbound_conf=$(mktemp -u "${unbound_conf}.XXXXX") set_chrootdir - gen_unbound_conf >"${tmp_unbound_conf}" + gen_unbound_conf | unexpand >"${tmp_unbound_conf}" replace "${unbound_conf}" "${tmp_unbound_conf}" # @@ -401,14 +440,14 @@ main() { # instead of resolv.conf. # local tmp_resolvconf_conf=$(mktemp -u "${resolvconf_conf}.XXXXX") - gen_resolvconf_conf >"${tmp_resolvconf_conf}" + gen_resolvconf_conf | unexpand >"${tmp_resolvconf_conf}" replace "${resolvconf_conf}" "${tmp_resolvconf_conf}" # # Finally, rewrite resolv.conf. # local tmp_resolv_conf=$(mktemp -u "${resolv_conf}.XXXXX") - gen_resolv_conf <"${resolv_conf}" >"${tmp_resolv_conf}" + gen_resolv_conf <"${resolv_conf}" | unexpand >"${tmp_resolv_conf}" replace "${resolv_conf}" "${tmp_resolv_conf}" } diff --git a/usr.sbin/usbconfig/Makefile b/usr.sbin/usbconfig/Makefile index 0aa51fa..bfc4b63 100644 --- a/usr.sbin/usbconfig/Makefile +++ b/usr.sbin/usbconfig/Makefile @@ -4,7 +4,6 @@ PROG= usbconfig MAN= usbconfig.8 SRCS= usbconfig.c dump.c -DPADD+= ${LIBUSB} -LDADD+= -lusb +LIBADD= usb .include <bsd.prog.mk> diff --git a/usr.sbin/vidcontrol/vidcontrol.c b/usr.sbin/vidcontrol/vidcontrol.c index 3001f69..cbf8f47 100644 --- a/usr.sbin/vidcontrol/vidcontrol.c +++ b/usr.sbin/vidcontrol/vidcontrol.c @@ -1085,12 +1085,16 @@ show_mode_info(void) printf("---------------------------------------" "---------------------------------------\n"); + memset(&_info, 0, sizeof(_info)); for (mode = 0; mode <= M_VESA_MODE_MAX; ++mode) { _info.vi_mode = mode; if (ioctl(0, CONS_MODEINFO, &_info)) continue; if (_info.vi_mode != mode) continue; + if (_info.vi_width == 0 && _info.vi_height == 0 && + _info.vi_cwidth == 0 && _info.vi_cheight == 0) + continue; printf("%3d (0x%03x)", mode, mode); printf(" 0x%08x", _info.vi_flags); @@ -1343,7 +1347,7 @@ main(int argc, char **argv) if (vt4_mode) opts = "b:Cc:fg:h:Hi:M:m:pPr:S:s:T:t:x"; else - opts = "b:Cc:df:g:h:Hi:l:LM:m:pPr:S:s:T:t:x"; + opts = "b:Cc:dfg:h:Hi:l:LM:m:pPr:S:s:T:t:x"; while ((opt = getopt(argc, argv, opts)) != -1) switch(opt) { diff --git a/usr.sbin/vigr/Makefile b/usr.sbin/vigr/Makefile new file mode 100644 index 0000000..d71998b --- /dev/null +++ b/usr.sbin/vigr/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +SCRIPTS= vigr +MAN= vigr.8 + +.include <bsd.prog.mk> diff --git a/usr.sbin/vigr/vigr.8 b/usr.sbin/vigr/vigr.8 new file mode 100644 index 0000000..3fd582b --- /dev/null +++ b/usr.sbin/vigr/vigr.8 @@ -0,0 +1,71 @@ +.\"- +.\" Copyright (c) 2014 Dag-Erling Smørgrav +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd December 14, 2014 +.Dt VIGR 8 +.Os +.Sh NAME +.Nm vigr +.Nd edit the group file +.Sh SYNOPSIS +.Nm +.Op Fl d Ar directory +.Sh DESCRIPTION +The +.Nm +utility makes a temporary copy of the group file, allows the user to +edit it, then verifies that the edited file is valid before installing +it. +.Pp +The following options are available: +.Bl -tag -width Fl +.It Fl d Ar directory +Edit the group file in the specified directory instead of the default +.Pa /etc/group . +.El +.Sh ENVIRONMENT +.Bl -tag -width EDITOR +.It Ev EDITOR +The editor to use instead of +.Xr vi 1 . +.It Ev TMPDIR +The directory in which to store the temporary copy of the group file. +.El +.Sh SEE ALSO +.Xr group 5 , +.Xr chkgrp 8 , +.Xr vipw 8 +.Sh HISTORY +The +.Nm +utility appeared in +.Fx 11.0 . +.Sh AUTHORS +The +.Nm +utility and this manual page were written by +.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org . diff --git a/usr.sbin/vigr/vigr.sh b/usr.sbin/vigr/vigr.sh new file mode 100644 index 0000000..c5dc65d --- /dev/null +++ b/usr.sbin/vigr/vigr.sh @@ -0,0 +1,95 @@ +#!/bin/sh +#- +# Copyright (c) 2014 Dag-Erling Smørgrav +# 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. +# +# $FreeBSD$ +# + +error() { + echo "$@" >&2 + exit 1 +} + +usage() { + error "usage: vigr [-d dir]" +} + +# Check arguments +while getopts d: opt ; do + case $opt in + d) + etcdir="${OPTARG}" + ;; + *) + usage + ;; + esac +done + +# Look for the current group file +grpfile="${etcdir:-/etc}/group" +if [ ! -f "${grpfile}" ] ; then + error "Missing group file" +fi + +# Create a secure temporary working directory +tmpdir=$(mktemp -d -t vigr) +if [ -z "${tmpdir}" -o ! -d "${tmpdir}" ] ; then + error "Unable to create the temporary directory" +fi +tmpfile="${tmpdir}/group" + +# Clean up on exit +trap "exit 1" INT +trap "rm -rf '${tmpdir}'" EXIT +set -e + +# Make a copy of the group file for the user to edit +cp "${grpfile}" "${tmpfile}" + +while :; do + # Let the user edit the file + ${EDITOR:-/usr/bin/vi} "${tmpfile}" + + # If the result is valid, install it and exit + if chkgrp -q "${tmpfile}" ; then + install -b -m 0644 -C -S "${tmpfile}" "${grpfile}" + exit 0 + fi + + # If it is not, offer to re-edit + while :; do + echo -n "Re-edit the group file? " + read ans + case $ans in + [Yy]|[Yy][Ee][Ss]) + break + ;; + [Nn]|[Nn][Oo]) + exit 1 + ;; + esac + done +done diff --git a/usr.sbin/vipw/Makefile b/usr.sbin/vipw/Makefile index d98e401..f36825d 100644 --- a/usr.sbin/vipw/Makefile +++ b/usr.sbin/vipw/Makefile @@ -4,7 +4,6 @@ PROG= vipw MAN= vipw.8 -DPADD= ${LIBUTIL} -LDADD= -lutil +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/watch/Makefile b/usr.sbin/watch/Makefile index 184d331..981aec0 100644 --- a/usr.sbin/watch/Makefile +++ b/usr.sbin/watch/Makefile @@ -5,7 +5,6 @@ MAN= watch.8 WARNS?= 2 -DPADD= ${LIBTERMCAPW} -LDADD= -ltermcapw +LIBADD= ncursesw .include <bsd.prog.mk> diff --git a/usr.sbin/watchdogd/Makefile b/usr.sbin/watchdogd/Makefile index 5df7946..bce983f 100644 --- a/usr.sbin/watchdogd/Makefile +++ b/usr.sbin/watchdogd/Makefile @@ -4,8 +4,7 @@ PROG= watchdogd LINKS= ${BINDIR}/watchdogd ${BINDIR}/watchdog MAN= watchdogd.8 watchdog.8 -LDADD= -lutil -DPADD= ${LIBUTIL} +LIBADD= util .include <bsd.prog.mk> diff --git a/usr.sbin/wpa/Makefile.crypto b/usr.sbin/wpa/Makefile.crypto index 94367bb..46cd9ef 100644 --- a/usr.sbin/wpa/Makefile.crypto +++ b/usr.sbin/wpa/Makefile.crypto @@ -2,8 +2,7 @@ .if ${MK_OPENSSL} != "no" && !defined(RELEASE_CRUNCH) SRCS+= crypto_openssl.c random.c sha1-prf.c sha256-prf.c -DPADD+= ${LIBSSL} ${LIBCRYPTO} -LDADD+= -lssl -lcrypto +LIBADD+= ssl crypto CFLAGS+= -DCONFIG_SHA256 .else CFLAGS+=-DCONFIG_CRYPTO_INTERNAL @@ -54,7 +53,8 @@ SRCS+= tls_openssl.c .endif .if defined(CONFIG_INTERNAL_AES) -SRCS+= aes-internal.c \ +SRCS+= aes-unwrap.c aes-wrap.c \ + aes-internal.c \ aes-internal-dec.c \ aes-internal-enc.c .endif @@ -93,7 +93,7 @@ SRCS+= md4-internal.c .endif .if defined(CONFIG_INTERNAL_MD5) -SRCS+= md5-internal.c +SRCS+= md5.c md5-internal.c .endif .if defined(NEED_FIPS186_2_PRF) diff --git a/usr.sbin/wpa/hostapd/Makefile b/usr.sbin/wpa/hostapd/Makefile index 7ab542f..04fbc4d 100644 --- a/usr.sbin/wpa/hostapd/Makefile +++ b/usr.sbin/wpa/hostapd/Makefile @@ -7,15 +7,17 @@ ${WPA_DISTDIR}/src/drivers PROG= hostapd -SRCS= accounting.c aes-wrap.c ap_config.c ap_drv_ops.c ap_mlme.c authsrv.c \ - base64.c beacon.c chap.c common.c config_file.c ctrl_iface.c \ +SRCS= accounting.c aes-omac1.c ap_config.c ap_drv_ops.c ap_mlme.c authsrv.c \ + base64.c beacon.c bss_load.c chap.c common.c config_file.c \ + ctrl_iface.c \ ctrl_iface_ap.c driver_common.c l2_packet_freebsd.c driver_bsd.c \ drivers.c drv_callbacks.c eap_common.c eap_peap_common.c \ eap_register.c eap_server.c eap_server_methods.c eap_user_db.c \ eapol_auth_dump.c eapol_auth_sm.c eloop.c gas.c gas_serv.c hostapd.c \ - hs20.c http_client.c http_server.c httpread.c ieee802_11_auth.c \ + hs20.c http_client.c http_server.c httpread.c \ + hw_features_common.c ieee802_11_auth.c \ ieee802_11_common.c ieee802_11_shared.c ieee802_1x.c ip_addr.c \ - main.c md5.c ms_funcs.c os_unix.c peerkey_auth.c pmksa_cache_auth.c \ + main.c ms_funcs.c os_unix.c peerkey_auth.c pmksa_cache_auth.c \ preauth_auth.c radius.c radius_client.c radius_das.c sta_info.c \ tkip_countermeasures.c upnp_xml.c utils.c uuid.c vlan_init.c \ wpa_auth.c wpa_auth_glue.c wpa_auth_ie.c wpa_common.c wpa_debug.c \ @@ -46,8 +48,7 @@ CFLAGS+=-DCONFIG_DRIVER_BSD \ CFLAGS+= -DCONFIG_IPV6 .endif #CFLAGS+= -g -DPADD+= ${LIBPCAP} ${LIBUTIL} -LDADD+= -lpcap -lutil +LIBADD+= pcap util # User customizations for wpa_supplicant/hostapd build environment CFLAGS+=${HOSTAPD_CFLAGS} @@ -65,10 +66,9 @@ CFLAGS+=-DDPKCS12_FUNCS \ -DEAP_SERVER_TLS \ -DEAP_SERVER_TTLS \ -DEAP_TLS_FUNCS \ - -DEAP_SERVER_WSC \ - -DCONFIG_NO_DUMP_STATE -SRCS+= dump_state.c \ - eap_server_gtc.c \ + -DEAP_SERVER_WSC + +SRCS+= eap_server_gtc.c \ eap_server_identity.c \ eap_server_md5.c \ eap_server_mschapv2.c \ diff --git a/usr.sbin/wpa/hostapd_cli/Makefile b/usr.sbin/wpa/hostapd_cli/Makefile index 3542aac..48af140 100644 --- a/usr.sbin/wpa/hostapd_cli/Makefile +++ b/usr.sbin/wpa/hostapd_cli/Makefile @@ -10,8 +10,7 @@ SRCS= common.c edit.c eloop.c hostapd_cli.c os_unix.c wpa_ctrl.c wpa_debug.c CFLAGS+= -DCONFIG_CTRL_IFACE CFLAGS+= -DCONFIG_CTRL_IFACE_UNIX -DPADD+= ${LIBUTIL} -LDADD+= -lutil +LIBADD+= util MAN= hostapd_cli.8 diff --git a/usr.sbin/wpa/ndis_events/ndis_events.c b/usr.sbin/wpa/ndis_events/ndis_events.c index 9c6e9de..b61fd0a 100644 --- a/usr.sbin/wpa/ndis_events/ndis_events.c +++ b/usr.sbin/wpa/ndis_events/ndis_events.c @@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <net/if.h> #include <net/if_dl.h> -#include <net/if_var.h> #include <netinet/in.h> #include <arpa/inet.h> diff --git a/usr.sbin/wpa/wpa_cli/Makefile b/usr.sbin/wpa/wpa_cli/Makefile index 9530b73..3203829 100644 --- a/usr.sbin/wpa/wpa_cli/Makefile +++ b/usr.sbin/wpa/wpa_cli/Makefile @@ -15,7 +15,6 @@ CFLAGS+= -DCONFIG_CTRL_IFACE_UNIX CFLAGS+= -D_DIRENT_HAVE_D_TYPE CFLAGS+= -DCONFIG_WPA_CLI_EDIT=y -LDADD+= -lutil -DPADD+= ${LIBUTIL} +LIBADD+= util .include <bsd.prog.mk> diff --git a/usr.sbin/wpa/wpa_passphrase/Makefile b/usr.sbin/wpa/wpa_passphrase/Makefile index d0f5198..aaf5c19 100644 --- a/usr.sbin/wpa/wpa_passphrase/Makefile +++ b/usr.sbin/wpa/wpa_passphrase/Makefile @@ -5,14 +5,12 @@ .PATH.c:${WPA_SUPPLICANT_DISTDIR} PROG= wpa_passphrase -SRCS= common.c md5-internal.c md5.c os_unix.c sha1-internal.c sha1-pbkdf2.c sha1.c \ - wpa_passphrase.c +SRCS= common.c md5-internal.c md5.c os_unix.c sha1-internal.c sha1-pbkdf2.c \ + sha1.c wpa_passphrase.c -CFLAGS+= -DINTERNAL_SHA1 -CFLAGS+= -DINTERNAL_MD5 +CFLAGS+= -DCONFIG_CRYPTO_INTERNAL -DINTERNAL_SHA1 -DINTERNAL_MD5 -DPADD+= ${LIBUTIL} -LDADD+= -lutil +LIBADD+= util MAN= wpa_passphrase.8 diff --git a/usr.sbin/wpa/wpa_priv/Makefile b/usr.sbin/wpa/wpa_priv/Makefile index 4dbc631..cf77678 100644 --- a/usr.sbin/wpa/wpa_priv/Makefile +++ b/usr.sbin/wpa/wpa_priv/Makefile @@ -9,8 +9,7 @@ PROG= wpa_priv SRCS= drivers.c os_unix.c eloop.c common.c wpa_debug.c wpabuf.c wpa_priv.c \ driver_common.c l2_packet_freebsd.c -DPADD+= ${LIBPCAP} -LDADD+= -lpcap +LIBADD= pcap .include "${.CURDIR}/../Makefile.crypto" diff --git a/usr.sbin/wpa/wpa_supplicant/Makefile b/usr.sbin/wpa/wpa_supplicant/Makefile index 673a04d..ecbacb1 100644 --- a/usr.sbin/wpa/wpa_supplicant/Makefile +++ b/usr.sbin/wpa/wpa_supplicant/Makefile @@ -8,14 +8,17 @@ ${WPA_DISTDIR}/src/drivers PROG= wpa_supplicant -SRCS= aes-unwrap.c base64.c blacklist.c bss.c common.c config.c \ +SRCS= ap_drv_ops.c base64.c blacklist.c bss.c common.c config.c \ config_file.c ctrl_iface.c ctrl_iface_unix.c driver_bsd.c \ driver_common.c driver_ndis.c driver_wired.c drivers.c \ eap_register.c eloop.c events.c gas.c gas_query.c hs20.c \ hs20_supplicant.c http_client.c http_server.c httpread.c \ - ieee802_11_common.c interworking.c l2_packet_freebsd.c main.c \ - md5.c notify.c offchannel.c os_unix.c peerkey.c pmksa_cache.c \ - preauth.c scan.c upnp_xml.c uuid.c wpa.c wpa_common.c wpa_debug.c \ + hw_features_common.c \ + ieee802_11_common.c ieee802_11_shared.c \ + interworking.c l2_packet_freebsd.c main.c \ + notify.c offchannel.c os_unix.c peerkey.c pmksa_cache.c \ + preauth.c scan.c upnp_xml.c uuid.c wmm_ac.c \ + wpa.c wpa_common.c wpa_debug.c \ wpa_ft.c wpa_ie.c wpa_supplicant.c wpabuf.c wpas_glue.c wps.c \ wps_attr_build.c wps_attr_parse.c wps_attr_process.c \ wps_common.c wps_dev_attr.c wps_enrollee.c wps_registrar.c \ @@ -49,8 +52,7 @@ CFLAGS+=-DCONFIG_BACKEND_FILE \ -DCONFIG_GAS \ -DPKCS12_FUNCS #CFLAGS+= -g -DPADD+= ${LIBPCAP} ${LIBUTIL} -LDADD+= -lpcap -lutil +LIBADD= pcap util # User customizations to the wpa_supplicant build environment CFLAGS+=${WPA_SUPPLICANT_CFLAGS} @@ -127,8 +129,7 @@ NEED_FIPS186_2_PRF=y # .if !empty(CFLAGS:M*-DPCSC_FUNCS) SRCS+= pcsc_funcs.c -DPADD+=${LIBPTHREAD} -LDADD+=-lpcsclite -lpthread +LIBADD+= pcslite pthread .endif .if !empty(CFLAGS:M*-DEAP_GPSK) diff --git a/usr.sbin/wpa/wpa_supplicant/Packet32.c b/usr.sbin/wpa/wpa_supplicant/Packet32.c index 876417e..8e7da03 100644 --- a/usr.sbin/wpa/wpa_supplicant/Packet32.c +++ b/usr.sbin/wpa/wpa_supplicant/Packet32.c @@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$"); #include <sys/fcntl.h> #include <net/if.h> #include <net/if_dl.h> -#include <net/if_var.h> #include <netinet/in.h> #include <arpa/inet.h> diff --git a/usr.sbin/ypserv/Makefile b/usr.sbin/ypserv/Makefile index cb24c43..28d6a66 100644 --- a/usr.sbin/ypserv/Makefile +++ b/usr.sbin/ypserv/Makefile @@ -12,8 +12,7 @@ CFLAGS+= -DDB_CACHE -DTCP_WRAPPER -I. WARNS?= 0 -DPADD= ${LIBWRAP} -LDADD= -lwrap +LIBADD= wrap CLEANFILES= yp_svc.c ypxfr_clnt.c yp.h |