From 5ac01ce026aa871e24065f931b5b5c36024c96f9 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 6 Aug 2020 20:44:40 +0000 Subject: [PATCH 01/28] ctfmerge: Fix missing pthread_cond_init() This does not appear to matter on FreeBSD or Linux, but when building an amd64 kernel on macOS I was seeing infinite loops in ctfmerge. It turns out the loop in wip_save_work() was looping forever due to pthread_cond_wait() always returning -EINVAL. Reviewed By: markj, brooks Differential Revision: https://reviews.freebsd.org/D25973 --- cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c index a3d05ad20b28..ddb5f388ca98 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c @@ -665,6 +665,7 @@ wq_init(workqueue_t *wq, int nfiles) for (i = 0; i < nslots; i++) { pthread_mutex_init(&wq->wq_wip[i].wip_lock, NULL); + pthread_cond_init(&wq->wq_wip[i].wip_cv, NULL); wq->wq_wip[i].wip_batchid = wq->wq_next_batchid++; } From a583962d617da79596bc9f0f235a60a8e4d45709 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 6 Aug 2020 20:46:13 +0000 Subject: [PATCH 02/28] Allow bootstrapping pwd_mkdb on Linux/macOS We need to provide a struct passwd that is compatible with the target system and this is not the case when cross-building from macOS/Linux. It should also be a problem when bootstrapping for an i386 target from a FreeBSD amd64 host since time_t does not match across those systems. However, pwd_mkdb always truncates integer values to 32-bit so this difference does not result in different databases. Reviewed By: brooks Differential Revision: https://reviews.freebsd.org/D25931 --- usr.sbin/pwd_mkdb/Makefile | 3 ++ usr.sbin/pwd_mkdb/pwd.h | 66 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 usr.sbin/pwd_mkdb/pwd.h diff --git a/usr.sbin/pwd_mkdb/Makefile b/usr.sbin/pwd_mkdb/Makefile index 14255fa6ac7f..4fea2f33796d 100644 --- a/usr.sbin/pwd_mkdb/Makefile +++ b/usr.sbin/pwd_mkdb/Makefile @@ -9,5 +9,8 @@ MAN= pwd_mkdb.8 SRCS= pw_scan.c pwd_mkdb.c CFLAGS+= -I${SRCTOP}/lib/libc/gen # for pw_scan.h +.if defined(BOOTSTRAPPING) +CFLAGS+=-I${.CURDIR} +.endif .include diff --git a/usr.sbin/pwd_mkdb/pwd.h b/usr.sbin/pwd_mkdb/pwd.h new file mode 100644 index 000000000000..a3b595881e21 --- /dev/null +++ b/usr.sbin/pwd_mkdb/pwd.h @@ -0,0 +1,66 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright 2018-2020 Alex Richardson + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory (Department of Computer Science and + * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the + * DARPA SSITH research programme. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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$ + */ + +/* + * When building pwd_mkdb we need to use target systems definition of + * struct passwd. This protects against future changes to struct passwd and + * is essential to allow cross-building from Linux/macOS hosts since the + * structure is not compatible there. + */ +#include +#include +/* + * Note: pwd_mkdb always stores uint32_t for all integer fields (including + * time_t!) so these definitions do not need to match sys/sys/_types.h + */ +typedef uint32_t _bootstrap_gid_t; +typedef uint32_t _bootstrap_uid_t; +typedef uint64_t _bootstrap_time_t; +#define _GID_T_DECLARED +#define _TIME_T_DECLARED +#define _UID_T_DECLARED +#define _SIZE_T_DECLARED + +#define gid_t _bootstrap_gid_t +#define uid_t _bootstrap_uid_t +#define time_t _bootstrap_time_t +#define passwd _bootstrap_passwd +#include "../../include/pwd.h" +#undef gid_t +#undef uid_t +#undef time_t From d8e1e85c42f989df0343e2130de542d553a691c9 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 6 Aug 2020 20:46:18 +0000 Subject: [PATCH 03/28] stand: use portable ln -n instead of ln -h This fixes the build on Linux Differential Revision: https://reviews.freebsd.org/D24783 --- stand/defs.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stand/defs.mk b/stand/defs.mk index bcc06f459b63..5bfc03cb7e89 100644 --- a/stand/defs.mk +++ b/stand/defs.mk @@ -237,6 +237,6 @@ ${_ILINKS}: .NOMETA esac ; \ path=`(cd $$path && /bin/pwd)` ; \ ${ECHO} ${.TARGET} "->" $$path ; \ - ln -fhs $$path ${.TARGET} + ln -fns $$path ${.TARGET} .endif # !NO_OBJ .endif # __BOOT_DEFS_MK__ From 7e6223b23f67a1d0e0cf47942f2117648bfb9f14 Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Thu, 6 Aug 2020 21:01:26 +0000 Subject: [PATCH 04/28] em(4): honor vlanhwtag offload The FreeBSD em driver fails to properly reset the VME flag in the e1000 CTRL register oneg the following ifconfig command ifconfig em1 -vlanhwtag Tested on the e1000 device emulated by QEMU, and on a real NIC (chip=0x10d38086). PR: 236584 Submitted by: murat@sunnyvalley.io Reported by: murat@sunnyvalley.io MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D25286 --- sys/dev/e1000/if_em.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 2eb8b1ddc541..3db75524963d 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1334,6 +1334,11 @@ em_if_init(if_ctx_t ctx) ctrl |= E1000_CTRL_VME; E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); } + } else { + u32 ctrl; + ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL); + ctrl &= ~E1000_CTRL_VME; + E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); } /* Don't lose promiscuous settings */ From ee07345d20fca4196592d9ce11394de87ef2b67c Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Thu, 6 Aug 2020 21:32:25 +0000 Subject: [PATCH 05/28] iflib: netmap: don't increment ifl_cidx on the wrong free list Netmap only uses free list 0 to keep it consistent with its one-to-one mapping between each netmap ring and a device RX (or TX) queue. However, the current iflib_netmap_rxsync() routine was mistakenly updating the ifl_cidx field of both free lists. PR: 248494 MFC after: 2 weeks --- sys/net/iflib.c | 74 +++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/sys/net/iflib.c b/sys/net/iflib.c index 9a37f30b43f6..7468c1d70c0a 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -1076,28 +1076,28 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) struct netmap_adapter *na = kring->na; struct netmap_ring *ring = kring->ring; if_t ifp = na->ifp; - iflib_fl_t fl; uint32_t nm_i; /* index into the netmap ring */ uint32_t nic_i; /* index into the NIC ring */ - u_int i, n; + u_int n; u_int const lim = kring->nkr_num_slots - 1; u_int const head = kring->rhead; int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; - struct if_rxd_info ri; if_ctx_t ctx = ifp->if_softc; iflib_rxq_t rxq = &ctx->ifc_rxqs[kring->ring_id]; + iflib_fl_t fl = &rxq->ifr_fl[0]; + struct if_rxd_info ri; + if (head > lim) return netmap_ring_reinit(kring); /* - * XXX netmap_fl_refill() only ever (re)fills free list 0 so far. + * netmap only uses free list 0, to avoid out of order consumption + * of receive buffers */ - for (i = 0, fl = rxq->ifr_fl; i < rxq->ifr_nfl; i++, fl++) { - bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - } + bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); /* * First part: import newly received packets. @@ -1119,38 +1119,35 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) int crclen = iflib_crcstrip ? 0 : 4; int error, avail; - for (i = 0; i < rxq->ifr_nfl; i++) { - fl = &rxq->ifr_fl[i]; - nic_i = fl->ifl_cidx; - nm_i = netmap_idx_n2k(kring, nic_i); - avail = ctx->isc_rxd_available(ctx->ifc_softc, - rxq->ifr_id, nic_i, USHRT_MAX); - for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { - rxd_info_zero(&ri); - ri.iri_frags = rxq->ifr_frags; - ri.iri_qsidx = kring->ring_id; - ri.iri_ifp = ctx->ifc_ifp; - ri.iri_cidx = nic_i; + nic_i = fl->ifl_cidx; + nm_i = netmap_idx_n2k(kring, nic_i); + avail = ctx->isc_rxd_available(ctx->ifc_softc, + rxq->ifr_id, nic_i, USHRT_MAX); + for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { + rxd_info_zero(&ri); + ri.iri_frags = rxq->ifr_frags; + ri.iri_qsidx = kring->ring_id; + ri.iri_ifp = ctx->ifc_ifp; + ri.iri_cidx = nic_i; - error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, &ri); - ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen; - ring->slot[nm_i].flags = 0; - bus_dmamap_sync(fl->ifl_buf_tag, - fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); - nm_i = nm_next(nm_i, lim); - nic_i = nm_next(nic_i, lim); - } - if (n) { /* update the state variables */ - if (netmap_no_pendintr && !force_update) { - /* diagnostics */ - iflib_rx_miss ++; - iflib_rx_miss_bufs += n; - } - fl->ifl_cidx = nic_i; - kring->nr_hwtail = nm_i; - } - kring->nr_kflags &= ~NKR_PENDINTR; + error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, &ri); + ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen; + ring->slot[nm_i].flags = 0; + bus_dmamap_sync(fl->ifl_buf_tag, + fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); + nm_i = nm_next(nm_i, lim); + nic_i = nm_next(nic_i, lim); } + if (n) { /* update the state variables */ + if (netmap_no_pendintr && !force_update) { + /* diagnostics */ + iflib_rx_miss ++; + iflib_rx_miss_bufs += n; + } + fl->ifl_cidx = nic_i; + kring->nr_hwtail = nm_i; + } + kring->nr_kflags &= ~NKR_PENDINTR; } /* * Second part: skip past packets that userspace has released. @@ -1160,7 +1157,6 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) * nic_i is the index in the NIC ring, and * nm_i == (nic_i + kring->nkr_hwofs) % ring_size */ - /* XXX not sure how this will work with multiple free lists */ nm_i = kring->nr_hwcur; return (netmap_fl_refill(rxq, kring, nm_i, false)); From c9d886cd7f83bccdf25b839868afed4a089c50ec Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Thu, 6 Aug 2020 21:37:38 +0000 Subject: [PATCH 06/28] iflib: netmap: drop redundant check The validity of head is already checked by nm_rxsync_prologue(). MFC after: 2 weeks --- sys/net/iflib.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/net/iflib.c b/sys/net/iflib.c index 7468c1d70c0a..b7cc308d22f2 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -1080,7 +1080,6 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) uint32_t nic_i; /* index into the NIC ring */ u_int n; u_int const lim = kring->nkr_num_slots - 1; - u_int const head = kring->rhead; int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; if_ctx_t ctx = ifp->if_softc; @@ -1088,9 +1087,6 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) iflib_fl_t fl = &rxq->ifr_fl[0]; struct if_rxd_info ri; - if (head > lim) - return netmap_ring_reinit(kring); - /* * netmap only uses free list 0, to avoid out of order consumption * of receive buffers From 57d4cc2c58b361cac8cae0b48ee094b6ea6870f1 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 7 Aug 2020 02:48:19 +0000 Subject: [PATCH 07/28] All the other printf() calls cast to (void) here, do the two newer ones for consistency. --- sbin/mount/mount.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c index 938a220b41c3..e9424c4eb413 100644 --- a/sbin/mount/mount.c +++ b/sbin/mount/mount.c @@ -697,9 +697,9 @@ prmount(struct statfs *sfp) (uintmax_t)sfp->f_syncreads, (uintmax_t)sfp->f_asyncreads); if (sfp->f_fsid.val[0] != 0 || sfp->f_fsid.val[1] != 0) { - printf(", fsid "); + (void)printf(", fsid "); for (i = 0; i < sizeof(sfp->f_fsid); i++) - printf("%02x", ((u_char *)&sfp->f_fsid)[i]); + (void)printf("%02x", ((u_char *)&sfp->f_fsid)[i]); } } (void)printf(")\n"); From 4310fb0cefb0c7c15d77ec087e9b0cfe171ba983 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Fri, 7 Aug 2020 08:41:14 +0000 Subject: [PATCH 08/28] telnet(1): Document -P option PR: 248157 Submitted by: Juraj Lutter Reviewed by: bcr Approved by: bcr Obtained from: NetBSD MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D25794 --- contrib/telnet/telnet/telnet.1 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/contrib/telnet/telnet/telnet.1 b/contrib/telnet/telnet/telnet.1 index 32190112866b..b7004ee94a5d 100644 --- a/contrib/telnet/telnet/telnet.1 +++ b/contrib/telnet/telnet/telnet.1 @@ -28,7 +28,7 @@ .\" @(#)telnet.1 8.6 (Berkeley) 6/1/94 .\" $FreeBSD$ .\" -.Dd September 18, 2006 +.Dd August 7, 2020 .Dt TELNET 1 .Os .Sh NAME @@ -47,6 +47,7 @@ protocol .Op Fl l Ar user .Op Fl n Ar tracefile .Op Fl s Ar src_addr +.Op Fl P Ar policy .Oo .Ar host .Op Ar port @@ -189,6 +190,13 @@ for recording trace information. See the .Ic set tracefile command below. +.It Fl P Ar policy +Use IPsec policy specification string +.Ar policy , +for the connections. +See +.Xr ipsec_set_policy 3 +for details. .It Fl r Specifies a user interface similar to .Xr rlogin 1 . From da34299940738805ada87105c8fc1af3117a1e76 Mon Sep 17 00:00:00 2001 From: Li-Wen Hsu Date: Fri, 7 Aug 2020 08:57:31 +0000 Subject: [PATCH 09/28] Add a .Pp to separate description and sample code for readability. --- share/man/man9/seqc.9 | 1 + 1 file changed, 1 insertion(+) diff --git a/share/man/man9/seqc.9 b/share/man/man9/seqc.9 index 19c9ecf626c9..34783fff7448 100644 --- a/share/man/man9/seqc.9 +++ b/share/man/man9/seqc.9 @@ -98,6 +98,7 @@ obj->var2 = 2; seqc_write_end(&obj->seqc); unlock_exclusive(&obj->lock); .Ed +.Pp The following example for a reader reads the .Va var1 and From 096026e5167bd8219450bfa1ede3403c9710128e Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Fri, 7 Aug 2020 10:20:39 +0000 Subject: [PATCH 10/28] pkgbase: Fix dependancies The package name is converted with _ instead of - as we have some variables that cannot contain - Convert back the dependancies with - instead of _ --- release/packages/generate-ucl.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release/packages/generate-ucl.sh b/release/packages/generate-ucl.sh index 99bf150b3276..38bbb992d454 100755 --- a/release/packages/generate-ucl.sh +++ b/release/packages/generate-ucl.sh @@ -97,6 +97,8 @@ main() { outname="${outname%%_*}" + pkgdeps="$(echo ${pkgdeps} | tr '_' '-')" + desc="$(make -C ${srctree}/release/packages -f Makefile.package -V ${outname}_DESC)" comment="$(make -C ${srctree}/release/packages -f Makefile.package -V ${outname}_COMMENT)" From 43233543248c0c0ffa0e5621c31bbb1bab77fd58 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Fri, 7 Aug 2020 12:19:21 +0000 Subject: [PATCH 11/28] pkgbase: We can't easily have a package with either a - or a _ Rename iscsi_legacy to iscsilegacy, having - or _ in a package name cause problems when we process them and generate the ucl. --- sbin/iscontrol/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/iscontrol/Makefile b/sbin/iscontrol/Makefile index 07dcbfec9f1c..613444a468f4 100644 --- a/sbin/iscontrol/Makefile +++ b/sbin/iscontrol/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -PACKAGE=iscsi_legacy +PACKAGE=iscsilegacy SRCS= iscontrol.c pdu.c fsm.c config.c login.c auth_subr.c misc.c PROG= iscontrol LIBADD= cam md From 7d1d4407f569fad7d495bdb492cc088d0aed48e3 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 7 Aug 2020 12:24:23 +0000 Subject: [PATCH 12/28] net80211/ifconfig: print hardware device name for wlan interfaces Add IEEE80211_IOC_IC_NAME to query the ic_name field and in ifconfig to print the parent interface again. This functionality was lost around r287197. It helps in case of multiple wlan interfaces and multiple underlying hardware devices to keep track which wlan interface belongs to which physical device. Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate") Reviewed by: adrian, Idwer Vollering MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D25832 --- sbin/ifconfig/ifieee80211.c | 23 +++++++++++++++++++++++ share/man/man4/net80211.4 | 12 +++++++++++- sys/net80211/ieee80211_ioctl.c | 7 +++++++ sys/net80211/ieee80211_ioctl.h | 3 +++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index d63c9710d8bf..88d905698c17 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -4779,6 +4779,23 @@ getid(int s, int ix, void *data, size_t len, int *plen, int mesh) return 0; } +static int +getdevicename(int s, void *data, size_t len, int *plen) +{ + struct ieee80211req ireq; + + (void) memset(&ireq, 0, sizeof(ireq)); + (void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name)); + ireq.i_type = IEEE80211_IOC_IC_NAME; + ireq.i_val = -1; + ireq.i_data = data; + ireq.i_len = len; + if (ioctl(s, SIOCG80211, &ireq) < 0) + return (-1); + *plen = ireq.i_len; + return (0); +} + static void ieee80211_status(int s) { @@ -5503,6 +5520,12 @@ ieee80211_status(int s) } LINE_BREAK(); + + if (getdevicename(s, data, sizeof(data), &len) < 0) + return; + LINE_CHECK("parent interface: %s", data); + + LINE_BREAK(); } static int diff --git a/share/man/man4/net80211.4 b/share/man/man4/net80211.4 index 650bbf48272a..629e84c35566 100644 --- a/share/man/man4/net80211.4 +++ b/share/man/man4/net80211.4 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 10, 2009 +.Dd August 7, 2020 .Dt NET80211 4 .Os .Sh NAME @@ -393,6 +393,16 @@ Valid values are: and .Dv IEEE80211_HWMP_ROOTMODE_RANN (send broadcast Root Announcement (RANN) frames). +.It Dv IEEE80211_IOC_IC_NAME +Return the underlying hardware +.Xr device 9 +name in the buffer pointed to by +.Va i_data +and the name length including terminating NUL character in +.Va i_len . +If the buffer length is too small to hold the full name +.Er EINVAL +will be returned. .It Dv IEEE80211_IOC_INACTIVITY Return whether or not the system handles inactivity processing in .Va i_val . diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index 0c3794f62669..3ed58ab1801d 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -785,6 +785,13 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd, int error = 0; switch (ireq->i_type) { + case IEEE80211_IOC_IC_NAME: + len = strlen(ic->ic_name) + 1; + if (len > ireq->i_len) + return (EINVAL); + ireq->i_len = len; + error = copyout(ic->ic_name, ireq->i_data, ireq->i_len); + break; case IEEE80211_IOC_SSID: switch (vap->iv_state) { case IEEE80211_S_INIT: diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h index eb933a5c0532..573661d5323d 100644 --- a/sys/net80211/ieee80211_ioctl.h +++ b/sys/net80211/ieee80211_ioctl.h @@ -743,6 +743,9 @@ struct ieee80211req { #define IEEE80211_IOC_QUIET_OFFSET 207 /* Quiet Offset */ #define IEEE80211_IOC_QUIET_DUR 208 /* Quiet Duration */ #define IEEE80211_IOC_QUIET_COUNT 209 /* Quiet Count */ + +#define IEEE80211_IOC_IC_NAME 210 /* HW device name. */ + /* * Parameters for controlling a scan requested with * IEEE80211_IOC_SCAN_REQ. From d4a5edc3e3ca26bc52dd8929e89be6110841a15c Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 7 Aug 2020 12:47:00 +0000 Subject: [PATCH 13/28] lib80211: fix indentation of comments for some netbands. Whitespace only; no functional changes. MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate") --- lib/lib80211/lib80211_regdomain.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/lib80211/lib80211_regdomain.h b/lib/lib80211/lib80211_regdomain.h index a8a4207c98ac..913dc161cdb0 100644 --- a/lib/lib80211/lib80211_regdomain.h +++ b/lib/lib80211/lib80211_regdomain.h @@ -73,10 +73,10 @@ struct regdomain { netband_head bands_11b; /* 11b operation */ netband_head bands_11g; /* 11g operation */ netband_head bands_11a; /* 11a operation */ - netband_head bands_11ng;/* 11ng operation */ - netband_head bands_11na;/* 11na operation */ - netband_head bands_11ac;/* 11ac 5GHz operation */ - netband_head bands_11acg;/* 11ac 2GHz operation */ + netband_head bands_11ng; /* 11ng operation */ + netband_head bands_11na; /* 11na operation */ + netband_head bands_11ac; /* 11ac 5GHz operation */ + netband_head bands_11acg; /* 11ac 2GHz operation */ LIST_ENTRY(regdomain) next; }; From 9f91d464a9c40899b1e7ad86aa86885166ab5b41 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 7 Aug 2020 13:35:34 +0000 Subject: [PATCH 14/28] Allow ACPI APEI driver build without PCI. On x86 it seems difficult to build ACPI without PCI, but some aarch64 users appears to be doing it. MFC after: 3 days --- sys/dev/acpica/acpi_apei.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/dev/acpica/acpi_apei.c b/sys/dev/acpica/acpi_apei.c index 8cdf09ee150c..5cc08b4137f1 100644 --- a/sys/dev/acpica/acpi_apei.c +++ b/sys/dev/acpica/acpi_apei.c @@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$"); #include "opt_acpi.h" +#include "opt_pci.h" #include #include @@ -207,8 +208,10 @@ static int apei_pcie_handler(ACPI_HEST_GENERIC_DATA *ged) { struct apei_pcie_error *p = (struct apei_pcie_error *)(ged + 1); + int h = 0, off; +#ifdef DEV_PCI device_t dev; - int h = 0, off, sev; + int sev; if ((p->ValidationBits & 0x8) == 0x8) { mtx_lock(&Giant); @@ -235,6 +238,7 @@ apei_pcie_handler(ACPI_HEST_GENERIC_DATA *ged) } if (h) return (h); +#endif printf("APEI %s PCIe Error:\n", apei_severity(ged->ErrorSeverity)); if (p->ValidationBits & 0x01) From a9839c4aee0f04590ce4e45a132992bf9035fe8d Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 7 Aug 2020 15:13:53 +0000 Subject: [PATCH 15/28] IPV6_PKTINFO support for v4-mapped IPv6 sockets When using v4-mapped IPv6 sockets with IPV6_PKTINFO we do not respect the given v4-mapped src address on the IPv4 socket. Implement the needed functionality. This allows single-socket UDP applications (such as OpenVPN) to work better on FreeBSD. Requested by: Gert Doering (gert greenie.net), pfsense Tested by: Gert Doering (gert greenie.net) Reviewed by: melifaro MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D24135 --- sys/netinet/udp_usrreq.c | 67 ++++++++++++++++++++++++++++++++++++-- sys/netinet6/udp6_usrreq.c | 2 +- sys/sys/protosw.h | 1 + 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index b1fcbda2a566..0eea51cba697 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -163,7 +163,7 @@ VNET_PCPUSTAT_SYSUNINIT(udpstat); #ifdef INET static void udp_detach(struct socket *so); static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *, - struct mbuf *, struct thread *); + struct mbuf *, struct thread *, int); #endif static void @@ -1083,9 +1083,65 @@ udp_ctloutput(struct socket *so, struct sockopt *sopt) } #ifdef INET +#ifdef INET6 +/* The logic here is derived from ip6_setpktopt(). See comments there. */ +static int +udp_v4mapped_pktinfo(struct cmsghdr *cm, struct sockaddr_in * src, + struct inpcb *inp, int flags) +{ + struct ifnet *ifp; + struct in6_pktinfo *pktinfo; + struct in_addr ia; + + if ((flags & PRUS_IPV6) == 0) + return (0); + + if (cm->cmsg_level != IPPROTO_IPV6) + return (0); + + if (cm->cmsg_type != IPV6_2292PKTINFO && + cm->cmsg_type != IPV6_PKTINFO) + return (0); + + if (cm->cmsg_len != + CMSG_LEN(sizeof(struct in6_pktinfo))) + return (EINVAL); + + pktinfo = (struct in6_pktinfo *)CMSG_DATA(cm); + if (!IN6_IS_ADDR_V4MAPPED(&pktinfo->ipi6_addr) && + !IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) + return (EINVAL); + + /* Validate the interface index if specified. */ + if (pktinfo->ipi6_ifindex > V_if_index) + return (ENXIO); + + ifp = NULL; + if (pktinfo->ipi6_ifindex) { + ifp = ifnet_byindex(pktinfo->ipi6_ifindex); + if (ifp == NULL) + return (ENXIO); + } + if (ifp != NULL && !IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) { + + ia.s_addr = pktinfo->ipi6_addr.s6_addr32[3]; + if (in_ifhasaddr(ifp, ia) == 0) + return (EADDRNOTAVAIL); + } + + bzero(src, sizeof(*src)); + src->sin_family = AF_INET; + src->sin_len = sizeof(*src); + src->sin_port = inp->inp_lport; + src->sin_addr.s_addr = pktinfo->ipi6_addr.s6_addr32[3]; + + return (0); +} +#endif + static int udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, - struct mbuf *control, struct thread *td) + struct mbuf *control, struct thread *td, int flags) { struct udpiphdr *ui; int len = m->m_pkthdr.len; @@ -1149,6 +1205,11 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, error = EINVAL; break; } +#ifdef INET6 + error = udp_v4mapped_pktinfo(cm, &src, inp, flags); + if (error != 0) + break; +#endif if (cm->cmsg_level != IPPROTO_IP) continue; @@ -1696,7 +1757,7 @@ udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, inp = sotoinpcb(so); KASSERT(inp != NULL, ("udp_send: inp == NULL")); - return (udp_output(inp, m, addr, control, td)); + return (udp_output(inp, m, addr, control, td, flags)); } #endif /* INET */ diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 2c53834417ec..5fd83bde1a4b 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -784,7 +784,7 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, in6_sin6_2_sin_in_sock((struct sockaddr *)sin6); pru = inetsw[ip_protox[nxt]].pr_usrreqs; /* addr will just be freed in sendit(). */ - return ((*pru->pru_send)(so, flags_arg, m, + return ((*pru->pru_send)(so, flags_arg | PRUS_IPV6, m, (struct sockaddr *)sin6, control, td)); } } else diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index 35b2aaf6ffb6..9c3139c866bd 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -210,6 +210,7 @@ struct pr_usrreqs { #define PRUS_EOF 0x2 #define PRUS_MORETOCOME 0x4 #define PRUS_NOTREADY 0x8 +#define PRUS_IPV6 0x10 int (*pru_ready)(struct socket *so, struct mbuf *m, int count); int (*pru_sense)(struct socket *so, struct stat *sb); int (*pru_shutdown)(struct socket *so); From 826c0793734aa74f0f71f85662e42e8635afbd2c Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 7 Aug 2020 15:32:42 +0000 Subject: [PATCH 16/28] Add full support support for dynamic allocation and freeing of epoch's. Make sure to reclaim epoch structures when they are freed to support dynamic allocation and freeing of epoch structures. While at it, move the 64 supported epoch control structures to the static memory domain. This overall simplifies the management and debugging of system epoch's. Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D25960 MFC after: 1 week Sponsored by: Mellanox Technologies --- sys/kern/subr_epoch.c | 71 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/sys/kern/subr_epoch.c b/sys/kern/subr_epoch.c index dcf21d97c262..b457b070cb65 100644 --- a/sys/kern/subr_epoch.c +++ b/sys/kern/subr_epoch.c @@ -58,8 +58,6 @@ __FBSDID("$FreeBSD$"); #include -static MALLOC_DEFINE(M_EPOCH, "epoch", "epoch based reclamation"); - #ifdef __amd64__ #define EPOCH_ALIGN CACHE_LINE_SIZE*2 #else @@ -79,7 +77,7 @@ typedef struct epoch_record { struct epoch { struct ck_epoch e_epoch __aligned(EPOCH_ALIGN); epoch_record_t e_pcpu_record; - int e_idx; + int e_in_use; int e_flags; struct sx e_drain_sx; struct mtx e_drain_mtx; @@ -128,19 +126,23 @@ TAILQ_HEAD (threadlist, thread); CK_STACK_CONTAINER(struct ck_epoch_entry, stack_entry, ck_epoch_entry_container) -epoch_t allepochs[MAX_EPOCHS]; +static struct epoch epoch_array[MAX_EPOCHS]; DPCPU_DEFINE(struct grouptask, epoch_cb_task); DPCPU_DEFINE(int, epoch_cb_count); static __read_mostly int inited; -static __read_mostly int epoch_count; __read_mostly epoch_t global_epoch; __read_mostly epoch_t global_epoch_preempt; static void epoch_call_task(void *context __unused); static uma_zone_t pcpu_zone_record; +static struct sx epoch_sx; + +#define EPOCH_LOCK() sx_xlock(&epoch_sx) +#define EPOCH_UNLOCK() sx_xunlock(&epoch_sx) + #ifdef EPOCH_TRACE struct stackentry { RB_ENTRY(stackentry) se_node; @@ -281,6 +283,7 @@ epoch_init(void *arg __unused) #ifdef EPOCH_TRACE SLIST_INIT(&thread0.td_epochs); #endif + sx_init(&epoch_sx, "epoch-sx"); inited = 1; global_epoch = epoch_alloc("Global", 0); global_epoch_preempt = epoch_alloc("Global preemptible", EPOCH_PREEMPT); @@ -326,19 +329,48 @@ epoch_t epoch_alloc(const char *name, int flags) { epoch_t epoch; + int i; + + MPASS(name != NULL); if (__predict_false(!inited)) panic("%s called too early in boot", __func__); - epoch = malloc(sizeof(struct epoch), M_EPOCH, M_ZERO | M_WAITOK); + + EPOCH_LOCK(); + + /* + * Find a free index in the epoch array. If no free index is + * found, try to use the index after the last one. + */ + for (i = 0;; i++) { + /* + * If too many epochs are currently allocated, + * return NULL. + */ + if (i == MAX_EPOCHS) { + epoch = NULL; + goto done; + } + if (epoch_array[i].e_in_use == 0) + break; + } + + epoch = epoch_array + i; ck_epoch_init(&epoch->e_epoch); epoch_ctor(epoch); - MPASS(epoch_count < MAX_EPOCHS - 2); epoch->e_flags = flags; - epoch->e_idx = epoch_count; epoch->e_name = name; sx_init(&epoch->e_drain_sx, "epoch-drain-sx"); mtx_init(&epoch->e_drain_mtx, "epoch-drain-mtx", NULL, MTX_DEF); - allepochs[epoch_count++] = epoch; + + /* + * Set e_in_use last, because when this field is set the + * epoch_call_task() function will start scanning this epoch + * structure. + */ + atomic_store_rel_int(&epoch->e_in_use, 1); +done: + EPOCH_UNLOCK(); return (epoch); } @@ -346,13 +378,24 @@ void epoch_free(epoch_t epoch) { + EPOCH_LOCK(); + + MPASS(epoch->e_in_use != 0); + epoch_drain_callbacks(epoch); - allepochs[epoch->e_idx] = NULL; + + atomic_store_rel_int(&epoch->e_in_use, 0); + /* + * Make sure the epoch_call_task() function see e_in_use equal + * to zero, by calling epoch_wait() on the global_epoch: + */ epoch_wait(global_epoch); uma_zfree_pcpu(pcpu_zone_record, epoch->e_pcpu_record); mtx_destroy(&epoch->e_drain_mtx); sx_destroy(&epoch->e_drain_sx); - free(epoch, M_EPOCH); + memset(epoch, 0, sizeof(*epoch)); + + EPOCH_UNLOCK(); } static epoch_record_t @@ -705,8 +748,10 @@ epoch_call_task(void *arg __unused) ck_stack_init(&cb_stack); critical_enter(); epoch_enter(global_epoch); - for (total = i = 0; i < epoch_count; i++) { - if (__predict_false((epoch = allepochs[i]) == NULL)) + for (total = i = 0; i != MAX_EPOCHS; i++) { + epoch = epoch_array + i; + if (__predict_false( + atomic_load_acq_int(&epoch->e_in_use) == 0)) continue; er = epoch_currecord(epoch); record = &er->er_record; From 88d241831d991f7c79242bf0bfe034541d373951 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Fri, 7 Aug 2020 16:01:05 +0000 Subject: [PATCH 17/28] grep(1): correct typos for 'if a name patches' to 'if a name matches' PR: 237635 Submitted by: durin42 Reviewed by: kevans Approved by: kevans MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D25994 --- usr.bin/grep/grep.1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/usr.bin/grep/grep.1 b/usr.bin/grep/grep.1 index e2a966456593..b6f6e6f31d22 100644 --- a/usr.bin/grep/grep.1 +++ b/usr.bin/grep/grep.1 @@ -30,7 +30,7 @@ .\" .\" @(#)grep.1 8.3 (Berkeley) 4/18/94 .\" -.Dd August 21, 2018 +.Dd August 7, 2020 .Dt GREP 1 .Os .Sh NAME @@ -209,7 +209,7 @@ Note that and .Fl Fl include patterns are processed in the order given. -If a name patches multiple patterns, the latest matching rule wins. +If a name matches multiple patterns, the latest matching rule wins. If no .Fl Fl include pattern is specified, all files are searched that are @@ -228,7 +228,7 @@ Note that and .Fl Fl include-dir patterns are processed in the order given. -If a name patches multiple patterns, the latest matching rule wins. +If a name matches multiple patterns, the latest matching rule wins. If no .Fl Fl include-dir pattern is specified, all directories are searched that are @@ -284,7 +284,7 @@ Note that and .Fl Fl exclude patterns are processed in the order given. -If a name patches multiple patterns, the latest matching rule wins. +If a name matches multiple patterns, the latest matching rule wins. Patterns are matched to the full path specified, not only to the filename component. .It Fl Fl include-dir Ar pattern @@ -298,7 +298,7 @@ Note that and .Fl Fl exclude-dir patterns are processed in the order given. -If a name patches multiple patterns, the latest matching rule wins. +If a name matches multiple patterns, the latest matching rule wins. .It Fl L , Fl Fl files-without-match Only the names of files not containing selected lines are written to standard output. From ec4deee4e4f2aef1b97d9424f25d04e91fd7dc10 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 7 Aug 2020 16:03:55 +0000 Subject: [PATCH 18/28] Fix cddl tools bootstrapping on macOS and Linux Reviewed By: brooks Differential Revision: https://reviews.freebsd.org/D25979 --- .../contrib/opensolaris/lib/libctf/common/ctf_lib.c | 1 + cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h | 10 ++++++++++ sys/cddl/compat/opensolaris/sys/stat.h | 13 +++++++++++-- sys/cddl/compat/opensolaris/sys/time.h | 1 + .../contrib/opensolaris/uts/common/sys/sysmacros.h | 9 ++++++++- 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c b/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c index c35b1a526d21..f48c09cce0e2 100644 --- a/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c +++ b/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c @@ -27,6 +27,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include +#include #include #include #include diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h b/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h index c8d272faa419..b7da16ac3ddd 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h @@ -38,6 +38,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -65,6 +66,15 @@ extern "C" { #define MIN(a, b) ((a) > (b) ? (b) : (a)) #endif +/* Sanity check for cross-build bootstrap tools */ +#if !defined(BYTE_ORDER) +#error "Missing BYTE_ORDER defines" +#elif !defined(_LITTLE_ENDIAN) +#error "Missing _LITTLE_ENDIAN defines" +#elif !defined(_BIG_ENDIAN) +#error "Missing _BIG_ENDIAN defines" +#endif + #define TRUE 1 #define FALSE 0 diff --git a/sys/cddl/compat/opensolaris/sys/stat.h b/sys/cddl/compat/opensolaris/sys/stat.h index d7301841d08b..05b9671789dd 100644 --- a/sys/cddl/compat/opensolaris/sys/stat.h +++ b/sys/cddl/compat/opensolaris/sys/stat.h @@ -32,11 +32,19 @@ #include_next +/* + * When bootstrapping on Linux a stat64/fstat64 functions exists in both + * glibc and musl libc. To avoid compilation errors, use those functions instead + * of redefining them to stat/fstat. + * Similarly, macOS provides (deprecated) stat64 functions that we can use + * for now. + */ +#if !defined(__linux__) && !defined(__APPLE__) #define stat64 stat #define MAXOFFSET_T OFF_MAX -#ifndef _KERNEL +#if !defined(_KERNEL) #include static __inline int @@ -51,6 +59,7 @@ fstat64(int fd, struct stat *sb) } return (ret); } -#endif +#endif /* !defined(_KERNEL) */ +#endif /* !defined(__linux__) && !defined(__APPLE__) */ #endif /* !_COMPAT_OPENSOLARIS_SYS_STAT_H_ */ diff --git a/sys/cddl/compat/opensolaris/sys/time.h b/sys/cddl/compat/opensolaris/sys/time.h index 64dd9bb9f918..5f51d08550f4 100644 --- a/sys/cddl/compat/opensolaris/sys/time.h +++ b/sys/cddl/compat/opensolaris/sys/time.h @@ -29,6 +29,7 @@ #ifndef _OPENSOLARIS_SYS_TIME_H_ #define _OPENSOLARIS_SYS_TIME_H_ +#include #include_next #define SEC 1 diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h b/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h index 675e4893aa1d..7b738c8b0d13 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h @@ -46,8 +46,12 @@ extern "C" { /* * Disk blocks (sectors) and bytes. */ +#ifndef dtob #define dtob(DD) ((DD) << DEV_BSHIFT) +#endif +#ifndef btod #define btod(BB) (((BB) + DEV_BSIZE - 1) >> DEV_BSHIFT) +#endif #define btodt(BB) ((BB) >> DEV_BSHIFT) #define lbtod(BB) (((offset_t)(BB) + DEV_BSIZE - 1) >> DEV_BSHIFT) @@ -220,9 +224,12 @@ extern unsigned char bcd_to_byte[256]; /* * Macros for counting and rounding. */ +#ifndef howmany #define howmany(x, y) (((x)+((y)-1))/(y)) +#endif +#ifndef roundup #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) - +#endif /* * Macro to determine if value is a power of 2 */ From 4f971ddf330c34c35c18a4698370413367c061dd Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 7 Aug 2020 16:04:01 +0000 Subject: [PATCH 19/28] Always install usr.bin/grep as grep when bootstrapping We have to bootstrap grep when cross-building from macOS/Linux. --- usr.bin/grep/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.bin/grep/Makefile b/usr.bin/grep/Makefile index b51f51c8bd5e..418889047052 100644 --- a/usr.bin/grep/Makefile +++ b/usr.bin/grep/Makefile @@ -4,7 +4,7 @@ .include -.if ${MK_BSD_GREP} == "yes" +.if ${MK_BSD_GREP} == "yes" || defined(BOOTSTRAPPING) PROG= grep MAN1= grep.1 zgrep.1 .else @@ -50,7 +50,7 @@ MLINKS= zgrep.1 zfgrep.1 \ CFLAGS.gcc+= --param max-inline-insns-single=500 -.if ${MK_BSD_GREP} == "yes" +.if ${MK_BSD_GREP} == "yes" || defined(BOOTSTRAPPING) LINKS+= ${BINDIR}/grep ${BINDIR}/egrep \ ${BINDIR}/grep ${BINDIR}/fgrep \ ${BINDIR}/grep ${BINDIR}/rgrep \ From b4e38a41f584ad4391c04b8cfec81f46176b18b0 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 7 Aug 2020 16:04:06 +0000 Subject: [PATCH 20/28] makefs: Drop unnecessary sys/clock.h include This breaks the build on macOS where this header doesn't exist. I could also add a compat header to tools/build/cross-build but since it's not needed removing it seems like the better solution. --- usr.sbin/makefs/msdos/msdosfs_vnops.c | 1 - 1 file changed, 1 deletion(-) diff --git a/usr.sbin/makefs/msdos/msdosfs_vnops.c b/usr.sbin/makefs/msdos/msdosfs_vnops.c index 703482f75b45..7ecf32f78472 100644 --- a/usr.sbin/makefs/msdos/msdosfs_vnops.c +++ b/usr.sbin/makefs/msdos/msdosfs_vnops.c @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #include -#include #include #include #include From 03266a2f085a816e141dc8288f2ee3f9bb58cd6d Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 7 Aug 2020 16:04:10 +0000 Subject: [PATCH 21/28] Don't link against libdialog/ncurses when bootstrapping tzsetup --- usr.sbin/tzsetup/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/tzsetup/Makefile b/usr.sbin/tzsetup/Makefile index 1c8c2e5462ce..e3d7526838a1 100644 --- a/usr.sbin/tzsetup/Makefile +++ b/usr.sbin/tzsetup/Makefile @@ -7,7 +7,7 @@ MAN= tzsetup.8 CFLAGS+= -I. -.if ${MK_DIALOG} != no +.if ${MK_DIALOG} != no && !defined(BOOTSTRAPPING) WARNS?= 3 CFLAGS+= -I${SRCTOP}/contrib/dialog -DHAVE_DIALOG LIBADD= dialog ncursesw From 0d834e0f4dc9612016d8124921d21531c8389088 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 7 Aug 2020 16:04:15 +0000 Subject: [PATCH 22/28] Fix duplicate assignment of _localedef in Makefile.inc1 The same .if exists a few lines below. --- Makefile.inc1 | 3 --- 1 file changed, 3 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 9dc0be374a81..6d58e641fd00 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -2179,9 +2179,6 @@ _yacc= usr.bin/yacc _gensnmptree= usr.sbin/bsnmpd/gensnmptree .endif -.if ${MK_LOCALES} != "no" -_localedef= usr.bin/localedef -.endif # We need to build tblgen when we're building clang or lld, either as # bootstrap tools, or as the part of the normal build. From 11412d5bc9215d065730856cea8c8a1b861ab3e7 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 7 Aug 2020 16:04:21 +0000 Subject: [PATCH 23/28] Fix linker error in libuutil with recent LLVM Not marking the function as static can result in a linker error: undefined reference to __assfail [--no-allow-shlib-undefined] I noticed this error after updating our CHERI LLVM to the latest upstream LLVM HEAD revision. This change effectively reverts r329984 and marks dmu_buf_init_user as static (which keeps the GCC build happy). Reviewed By: #zfs, asomers, freqlabs, mav Differential Revision: https://reviews.freebsd.org/D25663 --- sys/cddl/compat/opensolaris/sys/assfail.h | 4 +--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c | 7 ------- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h | 2 +- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/sys/cddl/compat/opensolaris/sys/assfail.h b/sys/cddl/compat/opensolaris/sys/assfail.h index 4f10a878d372..553da6983538 100644 --- a/sys/cddl/compat/opensolaris/sys/assfail.h +++ b/sys/cddl/compat/opensolaris/sys/assfail.h @@ -48,9 +48,7 @@ void assfail3(const char *, uintmax_t, const char *, uintmax_t, const char *, #ifndef HAVE_ASSFAIL extern int aok; -__inline int __assfail(const char *expr, const char *file, int line); - -__inline int +static __inline int __assfail(const char *expr, const char *file, int line) { diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c index 651fd3897132..1974ff2197c2 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c @@ -175,13 +175,6 @@ static int __dbuf_hold_impl(struct dbuf_hold_impl_data *dh); static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx); static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx); -#ifndef __lint -extern inline void dmu_buf_init_user(dmu_buf_user_t *dbu, - dmu_buf_evict_func_t *evict_func_sync, - dmu_buf_evict_func_t *evict_func_async, - dmu_buf_t **clear_on_evict_dbufp); -#endif /* ! __lint */ - /* * Global data structures and functions for the dbuf cache. */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h index 3f79409d65d1..1f5a837cc717 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h @@ -610,7 +610,7 @@ typedef struct dmu_buf_user { * To allow enforcement of this, dbu must already be zeroed on entry. */ /*ARGSUSED*/ -inline void +static inline void dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func_sync, dmu_buf_evict_func_t *evict_func_async, dmu_buf_t **clear_on_evict_dbufp) { From 6b839ff47b68e5f12898f239d64ad617b4237b10 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 7 Aug 2020 16:15:44 +0000 Subject: [PATCH 24/28] Implement radix_tree_store() in the LinuxKPI for use with the coming extensible arrays implementation. While at it add some more comments explaining the current radix_tree_insert() function and make sure to clean the root node when the radix tree reaches the maximum height. This can happen if the index passed is too big when the tree is empty. The radix_tree_store() function is basically a copy of the radix_tree_insert() function with some added functionality. The radix_tree_store() function is local to FreeBSD and does not yet exist in Linux. Reviewed by: kib MFC after: 1 week Sponsored by: Mellanox Technologies --- .../common/include/linux/radix-tree.h | 1 + sys/compat/linuxkpi/common/src/linux_radix.c | 143 ++++++++++++++++-- 2 files changed, 134 insertions(+), 10 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/radix-tree.h b/sys/compat/linuxkpi/common/include/linux/radix-tree.h index a4ef12b11f74..1bef60c44c41 100644 --- a/sys/compat/linuxkpi/common/include/linux/radix-tree.h +++ b/sys/compat/linuxkpi/common/include/linux/radix-tree.h @@ -78,6 +78,7 @@ radix_tree_exception(void *arg) void *radix_tree_lookup(struct radix_tree_root *, unsigned long); void *radix_tree_delete(struct radix_tree_root *, unsigned long); int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); +int radix_tree_store(struct radix_tree_root *, unsigned long, void **); bool radix_tree_iter_find(struct radix_tree_root *, struct radix_tree_iter *, void ***); void radix_tree_iter_delete(struct radix_tree_root *, struct radix_tree_iter *, void **); diff --git a/sys/compat/linuxkpi/common/src/linux_radix.c b/sys/compat/linuxkpi/common/src/linux_radix.c index da49f8b73d5a..17c7b4bb48e7 100644 --- a/sys/compat/linuxkpi/common/src/linux_radix.c +++ b/sys/compat/linuxkpi/common/src/linux_radix.c @@ -2,7 +2,7 @@ * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. - * Copyright (c) 2013-2018 Mellanox Technologies, Ltd. + * Copyright (c) 2013-2020 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,6 +55,17 @@ radix_pos(long id, int height) return (id >> (RADIX_TREE_MAP_SHIFT * height)) & RADIX_TREE_MAP_MASK; } +static void +radix_tree_clean_root_node(struct radix_tree_root *root) +{ + /* Check if the root node should be freed */ + if (root->rnode->count == 0) { + free(root->rnode, M_RADIX); + root->rnode = NULL; + root->height = 0; + } +} + void * radix_tree_lookup(struct radix_tree_root *root, unsigned long index) { @@ -197,8 +208,10 @@ radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item) while (radix_max(root) < index) { /* check if the radix tree is getting too big */ - if (root->height == RADIX_TREE_MAX_HEIGHT) + if (root->height == RADIX_TREE_MAX_HEIGHT) { + radix_tree_clean_root_node(root); return (-E2BIG); + } /* * If the root radix level is not empty, we need to @@ -206,8 +219,16 @@ radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item) */ if (node->count != 0) { node = malloc(sizeof(*node), M_RADIX, root->gfp_mask | M_ZERO); - if (node == NULL) + if (node == NULL) { + /* + * Freeing the already allocated radix + * levels, if any, will be handled by + * the radix_tree_delete() function. + * This code path can only happen when + * the tree is not empty. + */ return (-ENOMEM); + } node->slots[0] = root->rnode; node->count++; root->rnode = node; @@ -231,14 +252,9 @@ radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item) temp[idx] = malloc(sizeof(*node), M_RADIX, root->gfp_mask | M_ZERO); if (temp[idx] == NULL) { - while(idx--) + while (idx--) free(temp[idx], M_RADIX); - /* Check if we should free the root node as well. */ - if (root->rnode->count == 0) { - free(root->rnode, M_RADIX); - root->rnode = NULL; - root->height = 0; - } + radix_tree_clean_root_node(root); return (-ENOMEM); } } @@ -262,3 +278,110 @@ radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item) return (0); } + +int +radix_tree_store(struct radix_tree_root *root, unsigned long index, void **ppitem) +{ + struct radix_tree_node *node; + struct radix_tree_node *temp[RADIX_TREE_MAX_HEIGHT - 1]; + void *pitem; + int height; + int idx; + + /* + * Inserting a NULL item means delete it. The old pointer is + * stored at the location pointed to by "ppitem". + */ + if (*ppitem == NULL) { + *ppitem = radix_tree_delete(root, index); + return (0); + } + + /* get root node, if any */ + node = root->rnode; + + /* allocate root node, if any */ + if (node == NULL) { + node = malloc(sizeof(*node), M_RADIX, root->gfp_mask | M_ZERO); + if (node == NULL) + return (-ENOMEM); + root->rnode = node; + root->height++; + } + + /* expand radix tree as needed */ + while (radix_max(root) < index) { + + /* check if the radix tree is getting too big */ + if (root->height == RADIX_TREE_MAX_HEIGHT) { + radix_tree_clean_root_node(root); + return (-E2BIG); + } + + /* + * If the root radix level is not empty, we need to + * allocate a new radix level: + */ + if (node->count != 0) { + node = malloc(sizeof(*node), M_RADIX, root->gfp_mask | M_ZERO); + if (node == NULL) { + /* + * Freeing the already allocated radix + * levels, if any, will be handled by + * the radix_tree_delete() function. + * This code path can only happen when + * the tree is not empty. + */ + return (-ENOMEM); + } + node->slots[0] = root->rnode; + node->count++; + root->rnode = node; + } + root->height++; + } + + /* get radix tree height index */ + height = root->height - 1; + + /* walk down the tree until the first missing node, if any */ + for ( ; height != 0; height--) { + idx = radix_pos(index, height); + if (node->slots[idx] == NULL) + break; + node = node->slots[idx]; + } + + /* allocate the missing radix levels, if any */ + for (idx = 0; idx != height; idx++) { + temp[idx] = malloc(sizeof(*node), M_RADIX, + root->gfp_mask | M_ZERO); + if (temp[idx] == NULL) { + while (idx--) + free(temp[idx], M_RADIX); + radix_tree_clean_root_node(root); + return (-ENOMEM); + } + } + + /* setup new radix levels, if any */ + for ( ; height != 0; height--) { + idx = radix_pos(index, height); + node->slots[idx] = temp[height - 1]; + node->count++; + node = node->slots[idx]; + } + + /* + * Insert and adjust count if the item does not already exist. + */ + idx = radix_pos(index, 0); + /* swap */ + pitem = node->slots[idx]; + node->slots[idx] = *ppitem; + *ppitem = pitem; + + if (pitem == NULL) + node->count++; + return (0); +} From 1f325602e470231d230d79526e98c4000403ca41 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Fri, 7 Aug 2020 16:20:07 +0000 Subject: [PATCH 25/28] tmpnam(3): Also mention tmpfile in the ENVIRONMENT section PR: 181785 Submitted by: Kevin P. Neal MFC after: 1 week --- lib/libc/stdio/tmpnam.3 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/libc/stdio/tmpnam.3 b/lib/libc/stdio/tmpnam.3 index afe54f3b7247..6300a1725eba 100644 --- a/lib/libc/stdio/tmpnam.3 +++ b/lib/libc/stdio/tmpnam.3 @@ -32,7 +32,7 @@ .\" @(#)tmpnam.3 8.2 (Berkeley) 11/17/93 .\" $FreeBSD$ .\" -.Dd March 18, 2007 +.Dd August 7, 2020 .Dt TMPFILE 3 .Os .Sh NAME @@ -156,6 +156,8 @@ on error. .Bl -tag -width Ds .It Ev TMPDIR .Pf [ Fn tempnam +and +.Fn tmpfile only] If set, the directory in which the temporary file is stored. From 33176cdc87a6c7d2993b4e6b95e9ce8b016454b4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 7 Aug 2020 16:26:56 +0000 Subject: [PATCH 26/28] The practice of creating symbolic links is somewhat fragile. Always make copies instead. There's too many times that we can't run the new binaries with old libraries. Making the links when things are known to be 'safe' is a nice optimization, but a copy of all the binaries is only 30MB, so saving the copies at the cost of increased support when new symbols are added and used as part of the bootstrap seems to be unwise. There may be additional optimizations possible here, especially for !FreeBSD hosts. However, that's beyond the scope of the problem I'm trying to fix with make failing mid-way through an installworld across change r363679. This optimization there caused us to run a new binary with an old library once a new make was installed due to the symbolic link. One could just copy make, but then other binaries fail as well, so rather than play whack-a-mole, I opted to take us back to the old way. Before r340157 or so we did copies (thogh of a lot fewer artifacts), and we didn't have issues like this. Reviewed by: arichards@ Differential Revision: https://reviews.freebsd.org/D25967 --- Makefile.inc1 | 13 ++++++------- UPDATING | 6 ++++++ tools/build/Makefile | 27 +++++++++++++-------------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 6d58e641fd00..00abab63d24b 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -2293,13 +2293,12 @@ ${_bt}-links: .PHONY .for _tool in ${_bootstrap_tools_links} ${_bt}-link-${_tool}: .PHONY .MAKE - @if [ ! -e "${WORLDTMP}/legacy/bin/${_tool}" ]; then \ - source_path=`which ${_tool}`; \ - if [ ! -e "$${source_path}" ] ; then \ - echo "Cannot find host tool '${_tool}'"; false; \ - fi; \ - ln -sfnv "$${source_path}" "${WORLDTMP}/legacy/bin/${_tool}"; \ - fi + @rm -f "${WORLDTMP}/legacy/bin/${_tool}"; \ + source_path=`which ${_tool}`; \ + if [ ! -e "$${source_path}" ] ; then \ + echo "Cannot find host tool '${_tool}'"; false; \ + fi; \ + cp -f "$${source_path}" "${WORLDTMP}/legacy/bin/${_tool}" ${_bt}-links: ${_bt}-link-${_tool} .endfor diff --git a/UPDATING b/UPDATING index 9cd27c5f4f37..206953b5b37b 100644 --- a/UPDATING +++ b/UPDATING @@ -26,6 +26,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20200807: + Makefile.inc has been updated to work around the issue documented in + 20200729. It was a case where the optimization of using symbolic links + to point to binaries created a situation where we'd run new binaries + with old libraries starting midway through the installworld process. + 20200729: r363679 has redefined some undefined behavior in regcomp(3); notably, extraneous escapes of most ordinary characters will no longer be diff --git a/tools/build/Makefile b/tools/build/Makefile index 0db3f8b2f11b..73eeac3ee09a 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile @@ -119,26 +119,25 @@ _host_abs_tools_to_symlink= ${_make_abs}:make ${_make_abs}:bmake host-symlinks: @echo "Linking host tools into ${DESTDIR}/bin" .for _tool in ${_host_tools_to_symlink} - @if [ ! -e "${DESTDIR}/bin/${_tool}" ]; then \ - source_path=`which ${_tool}`; \ - if [ ! -e "$${source_path}" ] ; then \ - echo "Cannot find host tool '${_tool}'"; false; \ - fi; \ - ln -sfnv "$${source_path}" "${DESTDIR}/bin/${_tool}"; \ - fi + @source_path=`which ${_tool}`; \ + if [ ! -e "$${source_path}" ] ; then \ + echo "Cannot find host tool '${_tool}'"; false; \ + fi; \ + rm -f "${DESTDIR}/bin/${_tool}"; \ + cp -f "$${source_path}" "${DESTDIR}/bin/${_tool}" .endfor .for _tool in ${_host_abs_tools_to_symlink} @source_path="${_tool:S/:/ /:[1]}"; \ target_path="${DESTDIR}/bin/${_tool:S/:/ /:[2]}"; \ - if [ ! -e "$${target_path}" ] ; then \ - if [ ! -e "$${source_path}" ] ; then \ - echo "Host tool '${src_path}' is missing"; false; \ - fi; \ - ln -sfnv "$${source_path}" "$${target_path}"; \ - fi + if [ ! -e "$${source_path}" ] ; then \ + echo "Host tool '${src_path}' is missing"; false; \ + fi; \ + rm -f "$${target_path}"; \ + cp -f "$${source_path}" "$${target_path}" .endfor .if exists(/usr/libexec/flua) - ln -sf /usr/libexec/flua ${DESTDIR}/usr/libexec/flua + rm -f ${DESTDIR}/usr/libexec/flua + cp -f /usr/libexec/flua ${DESTDIR}/usr/libexec/flua .endif # Create all the directories that are needed during the legacy, bootstrap-tools From 90fb6afc5534df63f5c211d71e44263de646bce2 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Fri, 7 Aug 2020 16:56:43 +0000 Subject: [PATCH 27/28] mbsrtowcs(3): Clarify the RETURN VALUES section PR: 215848 Submitted by: Andrew Stevenson MFC after: 1 week --- lib/libc/locale/mbsrtowcs.3 | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/libc/locale/mbsrtowcs.3 b/lib/libc/locale/mbsrtowcs.3 index eaf9f9093056..fb2076f98cdf 100644 --- a/lib/libc/locale/mbsrtowcs.3 +++ b/lib/libc/locale/mbsrtowcs.3 @@ -23,7 +23,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 21, 2004 +.Dd August 7, 2020 .Dt MBSRTOWCS 3 .Os .Sh NAME @@ -98,15 +98,29 @@ except that conversion stops after reading at most bytes from the buffer pointed to by .Fa src . .Sh RETURN VALUES -The +If successful, and +.Fa dst +is not NULL, the .Fn mbsrtowcs and .Fn mbsnrtowcs functions return the number of wide characters stored in the array pointed to by +.Fa dst . +.Pp +If .Fa dst -if successful, otherwise it returns -.Po Vt size_t Pc Ns \-1 . +was NULL then the functions +.Fn mbsrtowcs +and +.Fn mbsnrtowcs +return the number of wide characters that would have been stored where +.Fa dst +points to an infinitely large array. +.Pp +If either one of the functions is not successful then +.Po Vt size_t Pc Ns \-1 +is returned. .Sh ERRORS The .Fn mbsrtowcs From eef7327a689b9c748707e59dab3dc0c454b0f29e Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Fri, 7 Aug 2020 17:25:56 +0000 Subject: [PATCH 28/28] setlocale(3): Add an EXAMPLES section and add LANG category PR: 41824 Submitted by: Slaven Rezic Obtained from: NetBSD MFC after: 1 week --- lib/libc/locale/setlocale.3 | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/libc/locale/setlocale.3 b/lib/libc/locale/setlocale.3 index 586d82dd3dc2..bef7b0bdd17c 100644 --- a/lib/libc/locale/setlocale.3 +++ b/lib/libc/locale/setlocale.3 @@ -31,7 +31,7 @@ .\" @(#)setlocale.3 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd September 9, 2019 +.Dd August 7, 2020 .Dt SETLOCALE 3 .Os .Sh NAME @@ -98,6 +98,10 @@ as well as values returned by Set a locale for formatting dates and times using the .Fn strftime function. +.It Dv LANG +Sets the generic locale category for native language, local customs +and coded character set in the absence of more specific locale +variables. .El .Pp Only three locales are defined by default, @@ -153,6 +157,25 @@ if the given combination of and .Fa locale makes no sense. +.Sh EXAMPLES +The following code illustrates how a program can initialize the +international environment for one language, while selectively +modifying the program's locale such that regular expressions and +string operations can be applied to text recorded in a different +language: +.Bd -literal + setlocale(LC_ALL, "de"); + setlocale(LC_COLLATE, "fr"); +.Ed +.Pp +When a process is started, its current locale is set to the C or POSIX +locale. +An internationalized program that depends on locale data not defined in +the C or POSIX locale must invoke the setlocale subroutine in the +following manner before using any of the locale-specific information: +.Bd -literal + setlocale(LC_ALL, ""); +.Ed .Sh FILES .Bl -tag -width /usr/share/locale/locale/category -compact .It Pa $PATH_LOCALE/ Ns Em locale/category