aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ddb/ddb.81
-rw-r--r--sbin/decryptcore/decryptcore.82
-rw-r--r--sbin/devd/devd.conf.54
-rwxr-xr-xsbin/dhclient/dhclient-script4
-rw-r--r--sbin/dump/main.c2
-rw-r--r--sbin/dumpfs/dumpfs.83
-rw-r--r--sbin/dumpfs/dumpfs.c10
-rw-r--r--sbin/dumpon/dumpon.86
-rw-r--r--sbin/ffsinfo/ffsinfo.c5
-rw-r--r--sbin/fsck_ffs/dir.c18
-rw-r--r--sbin/fsck_ffs/fsck.h11
-rw-r--r--sbin/fsck_ffs/fsutil.c74
-rw-r--r--sbin/fsck_ffs/globs.c2
-rw-r--r--sbin/fsck_ffs/inode.c41
-rw-r--r--sbin/fsck_ffs/main.c2
-rw-r--r--sbin/fsck_ffs/pass1.c29
-rw-r--r--sbin/fsck_ffs/pass1b.c2
-rw-r--r--sbin/fsck_ffs/pass2.c127
-rw-r--r--sbin/fsck_ffs/setup.c165
-rw-r--r--sbin/fsdb/fsdb.c2
-rw-r--r--sbin/fsirand/fsirand.c8
-rw-r--r--sbin/geom/core/geom.c5
-rw-r--r--sbin/geom/misc/subr.c2
-rw-r--r--sbin/growfs/growfs.c2
-rw-r--r--sbin/gvinum/gvinum.82
-rw-r--r--sbin/ifconfig/ifconfig.828
-rw-r--r--sbin/ifconfig/ifconfig.c2
-rw-r--r--sbin/ifconfig/ifieee80211.c2
-rw-r--r--sbin/ifconfig/ifvlan.c10
-rw-r--r--sbin/init/init.c6
-rw-r--r--sbin/ipf/common/ipf.h2
-rw-r--r--sbin/ipf/ipf/ipf.42
-rw-r--r--sbin/ipf/ippool/ippool.86
-rw-r--r--sbin/ipf/ippool/ippool.c68
-rw-r--r--sbin/ipf/libipf/interror.c4
-rw-r--r--sbin/ipf/libipf/printpool_live.c18
-rw-r--r--sbin/ipf/libipf/printpooldata.c10
-rw-r--r--sbin/ipfw/ipfw.810
-rw-r--r--sbin/ipfw/ipfw2.c15
-rw-r--r--sbin/md5/md5.111
-rw-r--r--sbin/md5/md5.c2
-rw-r--r--sbin/mount/mount.84
-rw-r--r--sbin/mount_fusefs/mount_fusefs.88
-rw-r--r--sbin/mount_nfs/Makefile2
-rw-r--r--sbin/mount_nfs/mount_nfs.845
-rw-r--r--sbin/natd/natd.c8
-rw-r--r--sbin/newfs/mkfs.c23
-rw-r--r--sbin/newfs/newfs.82
-rw-r--r--sbin/nvmecontrol/modules/wdc/wdc.c10
-rw-r--r--sbin/pfctl/parse.y27
-rw-r--r--sbin/pfctl/pfctl.c221
-rw-r--r--sbin/pfctl/pfctl_altq.c2
-rw-r--r--sbin/pfctl/pfctl_parser.c13
-rw-r--r--sbin/pfctl/pfctl_radix.c2
-rw-r--r--sbin/pfctl/tests/files/pf0100.ok10
-rw-r--r--sbin/pfctl/tests/files/pf1010.in2
-rw-r--r--sbin/pfctl/tests/files/pf1010.ok2
-rw-r--r--sbin/pfctl/tests/pfctl_test_list.inc1
-rw-r--r--sbin/ping/ping6.c2
-rw-r--r--sbin/quotacheck/quotacheck.c2
-rw-r--r--sbin/setkey/setkey.817
-rw-r--r--sbin/tunefs/tunefs.842
-rw-r--r--sbin/veriexec/veriexec.88
-rw-r--r--sbin/veriexec/veriexec.c6
64 files changed, 745 insertions, 439 deletions
diff --git a/sbin/ddb/ddb.8 b/sbin/ddb/ddb.8
index 0fb9687991e5..54e5aa1b390c 100644
--- a/sbin/ddb/ddb.8
+++ b/sbin/ddb/ddb.8
@@ -150,6 +150,7 @@ and
manual pages.
.Sh SEE ALSO
.Xr ddb 4 ,
+.Xr mac_ddb 4 ,
.Xr textdump 4 ,
.Xr sysctl 8
.Sh HISTORY
diff --git a/sbin/decryptcore/decryptcore.8 b/sbin/decryptcore/decryptcore.8
index fc6a1dadc7b5..e02c0e42bb60 100644
--- a/sbin/decryptcore/decryptcore.8
+++ b/sbin/decryptcore/decryptcore.8
@@ -110,7 +110,7 @@ Specify a number of a crash dump to be decrypted.
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
-.Xr kgdb 1 ,
+.Xr kgdb 1 Pq Pa ports/devel/gdb ,
.Xr capsicum 4 ,
.Xr dumpon 8 ,
.Xr savecore 8 ,
diff --git a/sbin/devd/devd.conf.5 b/sbin/devd/devd.conf.5
index dd9faa05c869..af96843937c5 100644
--- a/sbin/devd/devd.conf.5
+++ b/sbin/devd/devd.conf.5
@@ -40,7 +40,7 @@
.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
.\" SOFTWARE.
.\"
-.Dd November 3, 2021
+.Dd September 22, 2022
.Dt DEVD.CONF 5
.Os
.Sh NAME
@@ -177,8 +177,6 @@ For network devices,
will match devices that have the given media type.
Valid media types are:
.Dq Li Ethernet ,
-.Dq Li Tokenring ,
-.Dq Li FDDI ,
.Dq Li 802.11 ,
and
.Dq Li ATM .
diff --git a/sbin/dhclient/dhclient-script b/sbin/dhclient/dhclient-script
index 3439fd960773..c5649e1a1d2a 100755
--- a/sbin/dhclient/dhclient-script
+++ b/sbin/dhclient/dhclient-script
@@ -173,6 +173,10 @@ add_new_routes() {
if [ "$new_ip_address" = "$router" ]; then
route add default -iface $router >/dev/null 2>&1
else
+ if [ "$new_subnet_mask" = "255.255.255.255" ]; then
+ route add "$router" -iface "$interface" >/dev/null 2>&1
+ fi
+
route add default $router >/dev/null 2>&1
fi
fi
diff --git a/sbin/dump/main.c b/sbin/dump/main.c
index 8752f2c1bea5..779db5fb4b43 100644
--- a/sbin/dump/main.c
+++ b/sbin/dump/main.c
@@ -457,7 +457,7 @@ main(int argc, char *argv[])
msgtail("to %s\n", tape);
sync();
- if ((ret = sbget(diskfd, &sblock, STDSB)) != 0) {
+ if ((ret = sbget(diskfd, &sblock, UFS_STDSB, UFS_NOCSUM)) != 0) {
switch (ret) {
case ENOENT:
warn("Cannot find file system superblock");
diff --git a/sbin/dumpfs/dumpfs.8 b/sbin/dumpfs/dumpfs.8
index ec5b12550447..2ca6eb11c31a 100644
--- a/sbin/dumpfs/dumpfs.8
+++ b/sbin/dumpfs/dumpfs.8
@@ -89,7 +89,8 @@ and
are not handled and
.Fl p
is not useful in this case so is omitted.
-.Xr Newfs 8
+The
+.Xr newfs 8
options
.Fl n
and
diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c
index 7c43cf4489a8..4983645156ff 100644
--- a/sbin/dumpfs/dumpfs.c
+++ b/sbin/dumpfs/dumpfs.c
@@ -130,7 +130,8 @@ main(int argc, char *argv[])
usage();
while ((name = *argv++) != NULL) {
- if (ufs_disk_fillout(&disk, name) == -1) {
+ if (ufs_disk_fillout_blank(&disk, name) == -1 ||
+ sbfind(&disk, 0) == -1) {
ufserr(name);
eval |= 1;
continue;
@@ -233,8 +234,8 @@ dumpfs(const char *name, int dosb)
printf("sbsize\t%d\tcgsize\t%d\tcgoffset %d\tcgmask\t0x%08x\n",
afs.fs_sbsize, afs.fs_cgsize, afs.fs_old_cgoffset,
afs.fs_old_cgmask);
- printf("csaddr\t%d\tcssize\t%d\n",
- afs.fs_old_csaddr, afs.fs_cssize);
+ printf("csaddr\t%jd\tcssize\t%d\n",
+ (intmax_t)afs.fs_csaddr, afs.fs_cssize);
printf("rotdelay %dms\trps\t%d\ttrackskew %d\tinterleave %d\n",
afs.fs_old_rotdelay, afs.fs_old_rps, afs.fs_old_trackskew,
afs.fs_old_interleave);
@@ -308,9 +309,6 @@ dumpfs(const char *name, int dosb)
afs.fs_volname, (uintmax_t)afs.fs_swuid,
(uintmax_t)afs.fs_providersize);
printf("\ncs[].cs_(nbfree,ndir,nifree,nffree):\n\t");
- afs.fs_csp = calloc(1, afs.fs_cssize);
- if (bread(&disk, fsbtodb(&afs, afs.fs_csaddr), afs.fs_csp, afs.fs_cssize) == -1)
- goto err;
for (i = 0; i < afs.fs_ncg; i++) {
struct csum *cs = &afs.fs_cs(&afs, i);
if (i && i % 4 == 0)
diff --git a/sbin/dumpon/dumpon.8 b/sbin/dumpon/dumpon.8
index de9bd648e68b..473f0658158a 100644
--- a/sbin/dumpon/dumpon.8
+++ b/sbin/dumpon/dumpon.8
@@ -312,7 +312,7 @@ or shorter:
The
.Pa vmcore.#
can be now examined using
-.Xr kgdb 1 :
+.Xr kgdb 1 Pq Pa ports/devel/gdb :
.Pp
.Dl # kgdb /boot/kernel/kernel vmcore.#
.Pp
@@ -321,7 +321,7 @@ or shorter:
.Dl # kgdb -n #
.Pp
The core was decrypted properly if
-.Xr kgdb 1
+.Xr kgdb 1 Pq Pa ports/devel/gdb
does not print any errors.
Note that the live kernel might be at a different path
which can be examined by looking at the
@@ -368,7 +368,7 @@ Be sure to fill in the server IP address and change the interface name if
needed.
.Sh SEE ALSO
.Xr gzip 1 ,
-.Xr kgdb 1 ,
+.Xr kgdb 1 Pq Pa ports/devel/gdb ,
.Xr zstd 1 ,
.Xr ddb 4 ,
.Xr netdump 4 ,
diff --git a/sbin/ffsinfo/ffsinfo.c b/sbin/ffsinfo/ffsinfo.c
index 33ec5f175cbd..9d447d209ffd 100644
--- a/sbin/ffsinfo/ffsinfo.c
+++ b/sbin/ffsinfo/ffsinfo.c
@@ -223,8 +223,9 @@ main(int argc, char **argv)
device = special;
}
- if (ufs_disk_fillout(&disk, device) == -1)
- err(1, "ufs_disk_fillout(%s) failed: %s", device, disk.d_error);
+ if (ufs_disk_fillout_blank(&disk, device) == -1 ||
+ sbfind(&disk, 0) == -1)
+ err(1, "superblock fetch(%s) failed: %s", device, disk.d_error);
DBG_OPEN(out_file); /* already here we need a superblock */
diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c
index 42ecf4112253..ba286a965513 100644
--- a/sbin/fsck_ffs/dir.c
+++ b/sbin/fsck_ffs/dir.c
@@ -474,6 +474,7 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
union dinode *dp;
int lostdir;
ino_t oldlfdir;
+ struct inoinfo *inp;
struct inodesc idesc;
char tempname[BUFSIZ];
@@ -581,10 +582,13 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
inodirty(&ip);
inoinfo(lfdir)->ino_linkcnt++;
pwarn("DIR I=%lu CONNECTED. ", (u_long)orphan);
- if (parentdir != (ino_t)-1) {
+ inp = getinoinfo(parentdir);
+ if (parentdir != (ino_t)-1 && inp != NULL &&
+ (inp->i_flags & INFO_NEW) == 0) {
printf("PARENT WAS I=%lu\n", (u_long)parentdir);
/*
- * The parent directory, because of the ordering
+ * If the parent directory did not have to
+ * be replaced then because of the ordering
* guarantees, has had the link count incremented
* for the child, but no entry was made. This
* fixes the parent link count so that fsck does
@@ -823,7 +827,12 @@ allocdir(ino_t parent, ino_t request, int mode)
inodirty(&ip);
if (ino == UFS_ROOTINO) {
inoinfo(ino)->ino_linkcnt = DIP(dp, di_nlink);
- cacheino(dp, ino);
+ if ((inp = getinoinfo(ino)) == NULL)
+ inp = cacheino(dp, ino);
+ else
+ inp->i_flags = INFO_NEW;
+ inp->i_parent = parent;
+ inp->i_dotdot = parent;
irelse(&ip);
return(ino);
}
@@ -832,8 +841,7 @@ allocdir(ino_t parent, ino_t request, int mode)
irelse(&ip);
return (0);
}
- cacheino(dp, ino);
- inp = getinoinfo(ino);
+ inp = cacheino(dp, ino);
inp->i_parent = parent;
inp->i_dotdot = parent;
inoinfo(ino)->ino_state = inoinfo(parent)->ino_state;
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index 1fb0df0c5124..d1b45a0850da 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/fsck.h
@@ -311,9 +311,15 @@ extern struct inoinfo {
ino_t i_parent; /* inode number of parent */
ino_t i_dotdot; /* inode number of `..' */
size_t i_isize; /* size of inode */
+ u_int i_flags; /* flags, see below */
u_int i_numblks; /* size of block array in bytes */
ufs2_daddr_t i_blks[1]; /* actually longer */
} **inphead, **inpsort;
+/*
+ * flags for struct inoinfo
+ */
+#define INFO_NEW 0x0000001 /* replaced broken directory */
+
extern long dirhash, inplast;
extern unsigned long numdirs, listmax;
extern long countdirs; /* number of directories we actually found */
@@ -363,7 +369,6 @@ extern char preen; /* just fix normal inconsistencies */
extern char rerun; /* rerun fsck. Only used in non-preen mode */
extern char resolved; /* cleared if unresolved changes => not clean */
extern int returntosingle; /* 1 => return to single user mode on exit */
-extern int sbhashfailed; /* when reading superblock check hash failed */
extern long secsize; /* actual disk sector size */
extern char skipclean; /* skip clean file systems if preening */
extern char snapname[BUFSIZ]; /* when doing snapshots, the name of the file */
@@ -447,7 +452,7 @@ void blwrite(int fd, char *buf, ufs2_daddr_t blk, ssize_t size);
void blerase(int fd, ufs2_daddr_t blk, long size);
void blzero(int fd, ufs2_daddr_t blk, long size);
void brelse(struct bufarea *);
-void cacheino(union dinode *dp, ino_t inumber);
+struct inoinfo *cacheino(union dinode *dp, ino_t inumber);
void catch(int);
void catchquit(int);
void cgdirty(struct bufarea *);
@@ -502,7 +507,7 @@ void pfatal(const char *fmt, ...) __printflike(1, 2);
void propagate(void);
void prtinode(struct inode *);
void pwarn(const char *fmt, ...) __printflike(1, 2);
-int readsb(int listerr);
+int readsb(void);
int reply(const char *question);
void rwerror(const char *mesg, ufs2_daddr_t blk);
void sblock_init(void);
diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index 711c9bb63549..f1834e1235d8 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -81,9 +81,9 @@ int slowio_pollcnt;
static struct bufarea cgblk; /* backup buffer for cylinder group blocks */
static TAILQ_HEAD(bufqueue, bufarea) bufqueuehd; /* head of buffer cache LRU */
static LIST_HEAD(bufhash, bufarea) bufhashhd[HASHSIZE]; /* buffer hash list */
-static int numbufs; /* size of buffer cache */
-static int cachelookups; /* number of cache lookups */
-static int cachereads; /* number of cache reads */
+static int numbufs; /* size of buffer cache */
+static int cachelookups; /* number of cache lookups */
+static int cachereads; /* number of cache reads */
static int flushtries; /* number of tries to reclaim memory */
char *buftype[BT_NUMBUFTYPES] = BT_NAMES;
@@ -129,7 +129,8 @@ reply(const char *question)
if (preen)
pfatal("INTERNAL ERROR: GOT TO reply()");
- persevere = !strcmp(question, "CONTINUE");
+ persevere = strcmp(question, "CONTINUE") == 0 ||
+ strcmp(question, "LOOK FOR ALTERNATE SUPERBLOCKS") == 0;
printf("\n");
if (!persevere && (nflag || (fswritefd < 0 && bkgrdflag == 0))) {
printf("%s? no\n\n", question);
@@ -464,13 +465,13 @@ flush(int fd, struct bufarea *bp)
struct ufs2_dinode *dp = bp->b_un.b_dinode2;
int i;
- for (i = 0; i < INOPB(&sblock); dp++, i++) {
+ for (i = 0; i < bp->b_size; dp++, i += sizeof(*dp)) {
if (ffs_verify_dinode_ckhash(&sblock, dp) == 0)
continue;
pwarn("flush: INODE CHECK-HASH FAILED");
ip.i_bp = bp;
ip.i_dp = (union dinode *)dp;
- ip.i_number = bp->b_index + i;
+ ip.i_number = bp->b_index + (i / sizeof(*dp));
prtinode(&ip);
if (preen || reply("FIX") != 0) {
if (preen)
@@ -681,14 +682,17 @@ ckfini(int markclean)
if (debug)
printf("Flush the superblock\n");
flush(fswritefd, &sblk);
- if (havesb && cursnapshot == 0 && sblock.fs_magic == FS_UFS2_MAGIC &&
- sblk.b_bno != sblock.fs_sblockloc / dev_bsize &&
- !preen && reply("UPDATE STANDARD SUPERBLOCK")) {
- /* Change the write destination to standard superblock */
- sblock.fs_sblockactualloc = sblock.fs_sblockloc;
- sblk.b_bno = sblock.fs_sblockloc / dev_bsize;
- sbdirty();
- flush(fswritefd, &sblk);
+ if (havesb && cursnapshot == 0 &&
+ sblk.b_bno != sblock.fs_sblockloc / dev_bsize) {
+ if (preen || reply("UPDATE STANDARD SUPERBLOCK")) {
+ /* Change write destination to standard superblock */
+ sblock.fs_sblockactualloc = sblock.fs_sblockloc;
+ sblk.b_bno = sblock.fs_sblockloc / dev_bsize;
+ sbdirty();
+ flush(fswritefd, &sblk);
+ } else {
+ markclean = 0;
+ }
}
if (cursnapshot == 0 && sblock.fs_clean != markclean) {
if ((sblock.fs_clean = markclean) != 0) {
@@ -945,12 +949,22 @@ blzero(int fd, ufs2_daddr_t blk, long size)
* Verify cylinder group's magic number and other parameters. If the
* test fails, offer an option to rebuild the whole cylinder group.
*/
+#undef CHK
+#define CHK(lhs, op, rhs, fmt) \
+ if (lhs op rhs) { \
+ pwarn("UFS%d cylinder group %d failed: " \
+ "%s (" #fmt ") %s %s (" #fmt ")\n", \
+ sblock.fs_magic == FS_UFS1_MAGIC ? 1 : 2, cg, \
+ #lhs, (intmax_t)lhs, #op, #rhs, (intmax_t)rhs); \
+ error = 1; \
+ }
int
check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild)
{
struct cg *cgp = cgbp->b_un.b_cg;
uint32_t cghash, calchash;
static int prevfailcg = -1;
+ int error;
/*
* Extended cylinder group checks.
@@ -963,19 +977,20 @@ check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild)
calchash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize);
cgp->cg_ckhash = cghash;
}
- if (cgp->cg_ckhash == calchash &&
- cg_chkmagic(cgp) &&
- cgp->cg_cgx == cg &&
- ((sblock.fs_magic == FS_UFS1_MAGIC &&
- cgp->cg_old_niblk == sblock.fs_ipg &&
- cgp->cg_ndblk <= sblock.fs_fpg &&
- cgp->cg_old_ncyl <= sblock.fs_old_cpg) ||
- (sblock.fs_magic == FS_UFS2_MAGIC &&
- cgp->cg_niblk == sblock.fs_ipg &&
- cgp->cg_ndblk <= sblock.fs_fpg &&
- cgp->cg_initediblk <= sblock.fs_ipg))) {
- return (1);
+ error = 0;
+ CHK(cgp->cg_ckhash, !=, calchash, "%jd");
+ CHK(cg_chkmagic(cgp), ==, 0, "%jd");
+ CHK(cgp->cg_cgx, !=, cg, "%jd");
+ CHK(cgp->cg_ndblk, >, sblock.fs_fpg, "%jd");
+ if (sblock.fs_magic == FS_UFS1_MAGIC) {
+ CHK(cgp->cg_old_niblk, !=, sblock.fs_ipg, "%jd");
+ CHK(cgp->cg_old_ncyl, >, sblock.fs_old_cpg, "%jd");
+ } else if (sblock.fs_magic == FS_UFS2_MAGIC) {
+ CHK(cgp->cg_niblk, !=, sblock.fs_ipg, "%jd");
+ CHK(cgp->cg_initediblk, >, sblock.fs_ipg, "%jd");
}
+ if (error == 0)
+ return (1);
if (prevfailcg == cg)
return (0);
prevfailcg = cg;
@@ -1026,6 +1041,7 @@ check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild)
cgp->cg_nextfreeoff = cgp->cg_clusteroff +
howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
}
+ cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize);
cgdirty(cgbp);
return (0);
}
@@ -1250,9 +1266,9 @@ prtbuf(const char *msg, struct bufarea *bp)
{
printf("%s: bp %p, type %s, bno %jd, size %d, refcnt %d, flags %s, "
- "index %jd\n", msg, bp, BT_BUFTYPE(bp->b_type), (intmax_t) bp->b_bno,
- bp->b_size, bp->b_refcnt, bp->b_flags & B_DIRTY ? "dirty" : "clean",
- (intmax_t) bp->b_index);
+ "index %jd\n", msg, bp, BT_BUFTYPE(bp->b_type),
+ (intmax_t) bp->b_bno, bp->b_size, bp->b_refcnt,
+ bp->b_flags & B_DIRTY ? "dirty" : "clean", (intmax_t) bp->b_index);
}
/*
diff --git a/sbin/fsck_ffs/globs.c b/sbin/fsck_ffs/globs.c
index 09dbcc6694a2..306944fa95b9 100644
--- a/sbin/fsck_ffs/globs.c
+++ b/sbin/fsck_ffs/globs.c
@@ -96,7 +96,6 @@ char preen; /* just fix normal inconsistencies */
char rerun; /* rerun fsck. Only used in non-preen mode */
int returntosingle; /* 1 => return to single user mode on exit */
char resolved; /* cleared if unresolved changes => not clean */
-int sbhashfailed; /* when reading superblock check hash failed */
char havesb; /* superblock has been read */
char skipclean; /* skip clean file systems if preening */
int fsmodified; /* 1 => write done to file system */
@@ -156,7 +155,6 @@ fsckinit(void)
resolved = 0;
havesb = 0;
fsmodified = 0;
- sbhashfailed = 0;
fsreadfd = -1;
fswritefd = -1;
maxfsblock = 0;
diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c
index 47f72c84a1f2..c261b254ace9 100644
--- a/sbin/fsck_ffs/inode.c
+++ b/sbin/fsck_ffs/inode.c
@@ -415,7 +415,12 @@ chkrange(ufs2_daddr_t blk, int cnt)
/*
* General purpose interface for reading inodes.
+ *
+ * firstinum and lastinum track contents of getnextino() cache (below).
*/
+static ino_t firstinum, lastinum;
+static struct bufarea inobuf;
+
void
ginode(ino_t inumber, struct inode *ip)
{
@@ -425,11 +430,17 @@ ginode(ino_t inumber, struct inode *ip)
errx(EEXIT, "bad inode number %ju to ginode",
(uintmax_t)inumber);
ip->i_number = inumber;
- if (icachebp != NULL &&
+ if (inumber >= firstinum && inumber < lastinum) {
+ /* contents in getnextino() cache */
+ ip->i_bp = &inobuf;
+ inobuf.b_refcnt++;
+ inobuf.b_index = firstinum;
+ } else if (icachebp != NULL &&
inumber >= icachebp->b_index &&
inumber < icachebp->b_index + INOPB(&sblock)) {
/* take an additional reference for the returned inode */
icachebp->b_refcnt++;
+ ip->i_bp = icachebp;
} else {
iblk = ino_to_fsba(&sblock, inumber);
/* release our cache-hold reference on old icachebp */
@@ -445,15 +456,15 @@ ginode(ino_t inumber, struct inode *ip)
/* take a cache-hold reference on new icachebp */
icachebp->b_refcnt++;
icachebp->b_index = rounddown(inumber, INOPB(&sblock));
+ ip->i_bp = icachebp;
}
- ip->i_bp = icachebp;
if (sblock.fs_magic == FS_UFS1_MAGIC) {
ip->i_dp = (union dinode *)
- &icachebp->b_un.b_dinode1[inumber % INOPB(&sblock)];
+ &ip->i_bp->b_un.b_dinode1[inumber - ip->i_bp->b_index];
return;
}
ip->i_dp = (union dinode *)
- &icachebp->b_un.b_dinode2[inumber % INOPB(&sblock)];
+ &ip->i_bp->b_un.b_dinode2[inumber - ip->i_bp->b_index];
if (ffs_verify_dinode_ckhash(&sblock, (struct ufs2_dinode *)ip->i_dp)) {
pwarn("INODE CHECK-HASH FAILED");
prtinode(ip);
@@ -474,6 +485,9 @@ void
irelse(struct inode *ip)
{
+ /* Check for failed inode read */
+ if (ip->i_bp == NULL)
+ return;
if (ip->i_bp->b_refcnt <= 0)
pfatal("irelse: releasing unreferenced ino %ju\n",
(uintmax_t) ip->i_number);
@@ -484,9 +498,8 @@ irelse(struct inode *ip)
* Special purpose version of ginode used to optimize first pass
* over all the inodes in numerical order.
*/
-static ino_t nextino, lastinum, lastvalidinum;
+static ino_t nextinum, lastvalidinum;
static long readcount, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
-static struct bufarea inobuf;
union dinode *
getnextinode(ino_t inumber, int rebuildcg)
@@ -499,11 +512,12 @@ getnextinode(ino_t inumber, int rebuildcg)
struct inode ip;
static caddr_t nextinop;
- if (inumber != nextino++ || inumber > lastvalidinum)
+ if (inumber != nextinum++ || inumber > lastvalidinum)
errx(EEXIT, "bad inode number %ju to nextinode",
(uintmax_t)inumber);
if (inumber >= lastinum) {
readcount++;
+ firstinum = lastinum;
blk = ino_to_fsba(&sblock, lastinum);
if (readcount % readpercg == 0) {
size = partialsize;
@@ -517,6 +531,9 @@ getnextinode(ino_t inumber, int rebuildcg)
* If getblk encounters an error, it will already have zeroed
* out the buffer, so we do not need to do so here.
*/
+ if (inobuf.b_refcnt != 0)
+ pfatal("Non-zero getnextinode() ref count %d\n",
+ inobuf.b_refcnt);
flush(fswritefd, &inobuf);
getblk(&inobuf, blk, size);
nextinop = inobuf.b_un.b_buf;
@@ -601,7 +618,7 @@ setinodebuf(int cg, ino_t inosused)
inum = cg * sblock.fs_ipg;
lastvalidinum = inum + inosused - 1;
- nextino = inum;
+ nextinum = inum;
lastinum = inum;
readcount = 0;
/* Flush old contents in case they have been updated */
@@ -671,6 +688,7 @@ freeinodebuf(void)
if (inobuf.b_un.b_buf != NULL)
free((char *)inobuf.b_un.b_buf);
inobuf.b_un.b_buf = NULL;
+ firstinum = lastinum = 0;
}
/*
@@ -680,12 +698,15 @@ freeinodebuf(void)
*
* Enter inodes into the cache.
*/
-void
+struct inoinfo *
cacheino(union dinode *dp, ino_t inumber)
{
struct inoinfo *inp, **inpp;
int i, blks;
+ if (getinoinfo(inumber) != NULL)
+ pfatal("cacheino: duplicate entry for ino %jd\n",
+ (intmax_t)inumber);
if (howmany(DIP(dp, di_size), sblock.fs_bsize) > UFS_NDADDR)
blks = UFS_NDADDR + UFS_NIADDR;
else if (DIP(dp, di_size) > 0)
@@ -717,6 +738,7 @@ cacheino(union dinode *dp, ino_t inumber)
errx(EEXIT, "cannot increase directory list");
}
inpsort[inplast++] = inp;
+ return (inp);
}
/*
@@ -732,7 +754,6 @@ getinoinfo(ino_t inumber)
continue;
return (inp);
}
- errx(EEXIT, "cannot find inode %ju", (uintmax_t)inumber);
return ((struct inoinfo *)0);
}
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c
index 18634a93c05c..b638d31040dd 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -271,7 +271,7 @@ checkfilesys(char *filesys)
*/
sblock_init();
sbreadfailed = 0;
- if (openfilesys(filesys) == 0 || readsb(0) == 0)
+ if (openfilesys(filesys) == 0 || readsb() == 0)
sbreadfailed = 1;
if (bkgrdcheck) {
if (sbreadfailed)
diff --git a/sbin/fsck_ffs/pass1.c b/sbin/fsck_ffs/pass1.c
index 319a324cc070..49418ec38e4b 100644
--- a/sbin/fsck_ffs/pass1.c
+++ b/sbin/fsck_ffs/pass1.c
@@ -251,8 +251,10 @@ checkinode(ino_t inumber, struct inodesc *idesc, int rebuildcg)
intmax_t size, fixsize;
int j, ret, offset;
- if ((dp = getnextinode(inumber, rebuildcg)) == NULL)
+ if ((dp = getnextinode(inumber, rebuildcg)) == NULL) {
+ pfatal("INVALID INODE");
goto unknown;
+ }
mode = DIP(dp, di_mode) & IFMT;
if (mode == 0) {
if ((sblock.fs_magic == FS_UFS1_MAGIC &&
@@ -290,6 +292,7 @@ checkinode(ino_t inumber, struct inodesc *idesc, int rebuildcg)
(mode == IFDIR && DIP(dp, di_size) > MAXDIRSIZE)) {
if (debug)
printf("bad size %ju:", (uintmax_t)DIP(dp, di_size));
+ pfatal("BAD FILE SIZE");
goto unknown;
}
if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) {
@@ -305,19 +308,22 @@ checkinode(ino_t inumber, struct inodesc *idesc, int rebuildcg)
if (debug)
printf("bad special-file size %ju:",
(uintmax_t)DIP(dp, di_size));
+ pfatal("BAD SPECIAL-FILE SIZE");
goto unknown;
}
if ((mode == IFBLK || mode == IFCHR) &&
(dev_t)DIP(dp, di_rdev) == NODEV) {
if (debug)
printf("bad special-file rdev NODEV:");
+ pfatal("BAD SPECIAL-FILE RDEV");
goto unknown;
}
ndb = howmany(DIP(dp, di_size), sblock.fs_bsize);
if (ndb < 0) {
if (debug)
- printf("bad size %ju ndb %ju:",
+ printf("negative size %ju ndb %ju:",
(uintmax_t)DIP(dp, di_size), (uintmax_t)ndb);
+ pfatal("NEGATIVE FILE SIZE");
goto unknown;
}
if (mode == IFBLK || mode == IFCHR)
@@ -345,8 +351,9 @@ checkinode(ino_t inumber, struct inodesc *idesc, int rebuildcg)
for (j = ndb; ndb < UFS_NDADDR && j < UFS_NDADDR; j++)
if (DIP(dp, di_db[j]) != 0) {
if (debug)
- printf("bad direct addr[%d]: %ju\n", j,
+ printf("invalid direct addr[%d]: %ju\n", j,
(uintmax_t)DIP(dp, di_db[j]));
+ pfatal("INVALID DIRECT BLOCK");
goto unknown;
}
for (j = 0, ndb -= UFS_NDADDR; ndb > 0; j++)
@@ -354,12 +361,15 @@ checkinode(ino_t inumber, struct inodesc *idesc, int rebuildcg)
for (; j < UFS_NIADDR; j++)
if (DIP(dp, di_ib[j]) != 0) {
if (debug)
- printf("bad indirect addr: %ju\n",
+ printf("invalid indirect addr: %ju\n",
(uintmax_t)DIP(dp, di_ib[j]));
+ pfatal("INVALID INDIRECT BLOCK");
goto unknown;
}
- if (ftypeok(dp) == 0)
+ if (ftypeok(dp) == 0) {
+ pfatal("UNKNOWN FILE TYPE");
goto unknown;
+ }
n_files++;
inoinfo(inumber)->ino_linkcnt = DIP(dp, di_nlink);
if (mode == IFDIR) {
@@ -483,15 +493,14 @@ checkinode(ino_t inumber, struct inodesc *idesc, int rebuildcg)
}
return (1);
unknown:
- pfatal("UNKNOWN FILE TYPE I=%lu", (u_long)inumber);
- inoinfo(inumber)->ino_state = FCLEAR;
+ ginode(inumber, &ip);
+ prtinode(&ip);
+ inoinfo(inumber)->ino_state = USTATE;
if (reply("CLEAR") == 1) {
- inoinfo(inumber)->ino_state = USTATE;
- ginode(inumber, &ip);
clearinode(ip.i_dp);
inodirty(&ip);
- irelse(&ip);
}
+ irelse(&ip);
return (1);
}
diff --git a/sbin/fsck_ffs/pass1b.c b/sbin/fsck_ffs/pass1b.c
index 17a3b6495dc4..e2a200b8b2f2 100644
--- a/sbin/fsck_ffs/pass1b.c
+++ b/sbin/fsck_ffs/pass1b.c
@@ -88,10 +88,12 @@ pass1b(void)
if (inoinfo(inumber)->ino_state != USTATE &&
(ckinode(dp, &idesc) & STOP)) {
rerun = 1;
+ freeinodebuf();
return;
}
}
}
+ freeinodebuf();
}
static int
diff --git a/sbin/fsck_ffs/pass2.c b/sbin/fsck_ffs/pass2.c
index 8632cf4878b1..78815493fba8 100644
--- a/sbin/fsck_ffs/pass2.c
+++ b/sbin/fsck_ffs/pass2.c
@@ -217,9 +217,9 @@ pass2(void)
continue;
if (inp->i_dotdot == 0) {
inp->i_dotdot = inp->i_parent;
- fileerror(inp->i_parent, inp->i_number, "MISSING '..'");
- if (reply("FIX") == 0)
- continue;
+ if (debug)
+ fileerror(inp->i_parent, inp->i_number,
+ "DEFERRED MISSING '..' FIX");
(void)makeentry(inp->i_number, inp->i_parent, "..");
inoinfo(inp->i_parent)->ino_linkcnt--;
continue;
@@ -289,7 +289,7 @@ pass2check(struct inodesc *idesc)
struct inode ip;
union dinode *dp;
const char *errmsg;
- struct direct proto;
+ struct direct proto, *newdirp;
/*
* check for "."
@@ -301,45 +301,52 @@ pass2check(struct inodesc *idesc)
if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") == 0) {
if (dirp->d_ino != idesc->id_number) {
direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'");
- dirp->d_ino = idesc->id_number;
- if (reply("FIX") == 1)
+ if (reply("FIX") == 1) {
+ dirp->d_ino = idesc->id_number;
ret |= ALTERED;
+ }
}
if (dirp->d_type != DT_DIR) {
direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'");
- dirp->d_type = DT_DIR;
- if (reply("FIX") == 1)
+ if (reply("FIX") == 1) {
+ dirp->d_type = DT_DIR;
ret |= ALTERED;
+ }
}
goto chk1;
}
- direrror(idesc->id_number, "MISSING '.'");
proto.d_ino = idesc->id_number;
proto.d_type = DT_DIR;
proto.d_namlen = 1;
(void)strcpy(proto.d_name, ".");
entrysize = DIRSIZ(0, &proto);
- if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
- pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
- dirp->d_name);
- } else if (dirp->d_reclen < entrysize) {
- pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
- } else if (dirp->d_reclen < 2 * entrysize) {
+ direrror(idesc->id_number, "MISSING '.'");
+ errmsg = "ADD '.' ENTRY";
+ if (dirp->d_reclen < entrysize + DIRSIZ(0, dirp)) {
+ /* Not enough space to add '.', replace first entry with '.' */
+ if (dirp->d_ino != 0) {
+ pwarn("\nFIRST ENTRY IN DIRECTORY CONTAINS %s\n",
+ dirp->d_name);
+ errmsg = "REPLACE WITH '.'";
+ }
+ if (reply(errmsg) == 0)
+ goto chk1;
proto.d_reclen = dirp->d_reclen;
memmove(dirp, &proto, (size_t)entrysize);
- if (reply("FIX") == 1)
- ret |= ALTERED;
+ ret |= ALTERED;
} else {
- n = dirp->d_reclen - entrysize;
+ /* Move over first entry and add '.' entry */
+ if (reply(errmsg) == 0)
+ goto chk1;
+ newdirp = (struct direct *)((char *)(dirp) + entrysize);
+ dirp->d_reclen -= entrysize;
+ memmove(newdirp, dirp, dirp->d_reclen);
proto.d_reclen = entrysize;
memmove(dirp, &proto, (size_t)entrysize);
idesc->id_entryno++;
- inoinfo(dirp->d_ino)->ino_linkcnt--;
- dirp = (struct direct *)((char *)(dirp) + entrysize);
- memset(dirp, 0, (size_t)n);
- dirp->d_reclen = n;
- if (reply("FIX") == 1)
- ret |= ALTERED;
+ inoinfo(idesc->id_number)->ino_linkcnt--;
+ dirp = newdirp;
+ ret |= ALTERED;
}
chk1:
if (idesc->id_entryno > 1)
@@ -372,30 +379,60 @@ chk1:
}
goto chk2;
}
- if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") != 0) {
- fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
- pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
- dirp->d_name);
- inp->i_dotdot = (ino_t)-1;
- } else if (dirp->d_reclen < entrysize) {
- fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
- pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n");
- inp->i_dotdot = (ino_t)-1;
- } else if (inp->i_parent != 0) {
- /*
- * We know the parent, so fix now.
- */
- inp->i_dotdot = inp->i_parent;
- fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
+ fileerror(inp->i_parent != 0 ? inp->i_parent : idesc->id_number,
+ idesc->id_number, "MISSING '..'");
+ errmsg = "ADD '..' ENTRY";
+ if (dirp->d_reclen < entrysize + DIRSIZ(0, dirp)) {
+ /* No space to add '..', replace second entry with '..' */
+ if (dirp->d_ino != 0) {
+ pfatal("SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
+ dirp->d_name);
+ errmsg = "REPLACE WITH '..'";
+ }
+ if (reply(errmsg) == 0) {
+ inp->i_dotdot = (ino_t)-1;
+ goto chk2;
+ }
+ if (proto.d_ino == 0) {
+ /* Defer processing until parent known */
+ idesc->id_entryno++;
+ if (debug)
+ printf("(FIX DEFERRED)\n");
+ }
+ inp->i_dotdot = proto.d_ino;
proto.d_reclen = dirp->d_reclen;
memmove(dirp, &proto, (size_t)entrysize);
- if (reply("FIX") == 1)
- ret |= ALTERED;
+ ret |= ALTERED;
+ } else {
+ /* Move over second entry and add '..' entry */
+ if (reply(errmsg) == 0) {
+ inp->i_dotdot = (ino_t)-1;
+ goto chk2;
+ }
+ if (proto.d_ino == 0) {
+ /* Defer processing until parent known */
+ idesc->id_entryno++;
+ if (debug)
+ printf("(FIX DEFERRED)\n");
+ }
+ inp->i_dotdot = proto.d_ino;
+ if (dirp->d_ino == 0) {
+ proto.d_reclen = dirp->d_reclen;
+ memmove(dirp, &proto, (size_t)entrysize);
+ } else {
+ newdirp = (struct direct *)((char *)(dirp) + entrysize);
+ dirp->d_reclen -= entrysize;
+ memmove(newdirp, dirp, dirp->d_reclen);
+ proto.d_reclen = entrysize;
+ memmove(dirp, &proto, (size_t)entrysize);
+ if (dirp->d_ino != 0) {
+ idesc->id_entryno++;
+ inoinfo(dirp->d_ino)->ino_linkcnt--;
+ }
+ dirp = newdirp;
+ }
+ ret |= ALTERED;
}
- idesc->id_entryno++;
- if (dirp->d_ino != 0)
- inoinfo(dirp->d_ino)->ino_linkcnt--;
- return (ret|KEEPON);
chk2:
if (dirp->d_ino == 0)
return (ret|KEEPON);
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index 0f0d9b61a076..69b027a3a5c8 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -60,8 +60,7 @@ __FBSDID("$FreeBSD$");
struct inoinfo **inphead, **inpsort; /* info about all inodes */
-struct bufarea asblk;
-#define altsblock (*asblk.b_un.b_fs)
+static int sbhashfailed;
#define POWEROF2(num) (((num) & ((num) - 1)) == 0)
static int calcsb(char *dev, int devfd, struct fs *fs);
@@ -76,39 +75,15 @@ static int chkrecovery(int devfd);
int
setup(char *dev)
{
- long cg, bmapsize;
- struct fs proto;
+ long bmapsize;
/*
- * We are expected to have an open file descriptor
+ * We are expected to have an open file descriptor and a superblock.
*/
- if (fsreadfd < 0)
+ if (fsreadfd < 0 || havesb == 0) {
+ if (debug)
+ printf("setup: bad fsreadfd or missing superblock\n");
return (0);
- /*
- * If we do not yet have a superblock, read it in looking
- * for alternates if necessary.
- */
- if (havesb == 0 && readsb(1) == 0) {
- skipclean = 0;
- if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0)
- return(0);
- if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0)
- return (0);
- for (cg = 0; cg < proto.fs_ncg; cg++) {
- bflag = fsbtodb(&proto, cgsblock(&proto, cg));
- if (readsb(0) != 0)
- break;
- }
- if (cg >= proto.fs_ncg) {
- printf("SEARCH FOR ALTERNATE SUPER-BLOCK FAILED. "
- "YOU MUST USE THE\n-b OPTION TO FSCK TO SPECIFY "
- "THE LOCATION OF AN ALTERNATE\nSUPER-BLOCK TO "
- "SUPPLY NEEDED INFORMATION; SEE fsck_ffs(8).\n");
- bflag = 0;
- return(0);
- }
- pwarn("USING ALTERNATE SUPERBLOCK AT %jd\n", bflag);
- bflag = 0;
}
if (preen == 0)
printf("** %s", dev);
@@ -163,10 +138,6 @@ setup(char *dev)
pfatal("from before 2002 with the command ``fsck -c 2''\n");
exit(EEXIT);
}
- if ((asblk.b_flags & B_DIRTY) != 0 && !bflag) {
- memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize);
- flush(fswritefd, &asblk);
- }
if (preen == 0 && yflag == 0 && sblock.fs_magic == FS_UFS2_MAGIC &&
fswritefd != -1 && chkrecovery(fsreadfd) == 0 &&
reply("SAVE DATA TO FIND ALTERNATE SUPERBLOCKS") != 0)
@@ -174,6 +145,7 @@ setup(char *dev)
/*
* allocate and initialize the necessary maps
*/
+ bufinit();
bmapsize = roundup(howmany(maxfsblock, CHAR_BIT), sizeof(short));
blockmap = Calloc((unsigned)bmapsize, sizeof (char));
if (blockmap == NULL) {
@@ -198,7 +170,6 @@ setup(char *dev)
(uintmax_t)numdirs * sizeof(struct inoinfo *));
goto badsb;
}
- bufinit();
if (sblock.fs_flags & FS_DOSOFTDEP)
usedsoftdep = 1;
else
@@ -249,38 +220,64 @@ openfilesys(char *dev)
* Read in the super block and its summary info.
*/
int
-readsb(int listerr)
+readsb(void)
{
- off_t super;
- int bad, ret;
struct fs *fs;
- super = bflag ? bflag * dev_bsize :
- sbhashfailed ? STDSB_NOHASHFAIL_NOMSG : STDSB_NOMSG;
+ sbhashfailed = 0;
readcnt[sblk.b_type]++;
- while ((ret = sbget(fsreadfd, &fs, super)) != 0) {
- switch (ret) {
+ /*
+ * If bflag is given, then check just that superblock.
+ */
+ if (bflag) {
+ switch (sbget(fsreadfd, &fs, bflag * dev_bsize, 0)) {
+ case 0:
+ goto goodsb;
case EINTEGRITY:
- if (bflag || super == STDSB_NOHASHFAIL_NOMSG)
- return (0);
- super = STDSB_NOHASHFAIL_NOMSG;
- sbhashfailed = 1;
- continue;
+ printf("Check hash failed for superblock at %jd\n",
+ bflag);
+ return (0);
case ENOENT:
- if (bflag)
- printf("%jd is not a file system "
- "superblock\n", super / dev_bsize);
- else
- printf("Cannot find file system "
- "superblock\n");
+ printf("%jd is not a file system superblock\n", bflag);
return (0);
case EIO:
default:
- printf("I/O error reading %jd\n",
- super / dev_bsize);
+ printf("I/O error reading %jd\n", bflag);
return (0);
}
}
+ /*
+ * Check for the standard superblock and use it if good.
+ */
+ if (sbget(fsreadfd, &fs, UFS_STDSB, UFS_NOMSG) == 0)
+ goto goodsb;
+ /*
+ * Check if the only problem is a check-hash failure.
+ */
+ skipclean = 0;
+ if (sbget(fsreadfd, &fs, UFS_STDSB, UFS_NOMSG | UFS_NOHASHFAIL) == 0) {
+ sbhashfailed = 1;
+ goto goodsb;
+ }
+ /*
+ * Do an exhaustive search for a usable superblock.
+ */
+ switch (sbsearch(fsreadfd, &fs, 0)) {
+ case 0:
+ goto goodsb;
+ case ENOENT:
+ printf("SEARCH FOR ALTERNATE SUPER-BLOCK FAILED. "
+ "YOU MUST USE THE\n-b OPTION TO FSCK TO SPECIFY "
+ "THE LOCATION OF AN ALTERNATE\nSUPER-BLOCK TO "
+ "SUPPLY NEEDED INFORMATION; SEE fsck_ffs(8).\n");
+ return (0);
+ case EIO:
+ default:
+ printf("I/O error reading a usable superblock\n");
+ return (0);
+ }
+
+goodsb:
memcpy(&sblock, fs, fs->fs_sbsize);
free(fs);
/*
@@ -292,58 +289,6 @@ readsb(int listerr)
sblk.b_bno = sblock.fs_sblockactualloc / dev_bsize;
sblk.b_size = SBLOCKSIZE;
/*
- * Compare all fields that should not differ in alternate super block.
- * When an alternate super-block is specified this check is skipped.
- */
- if (bflag)
- goto out;
- getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
- if (asblk.b_errs)
- return (0);
- bad = 0;
-#define CHK(x, y) \
- if (altsblock.x != sblock.x) { \
- bad++; \
- if (listerr && debug) \
- printf("SUPER BLOCK VS ALTERNATE MISMATCH %s: " y " vs " y "\n", \
- #x, (intmax_t)sblock.x, (intmax_t)altsblock.x); \
- }
- CHK(fs_sblkno, "%jd");
- CHK(fs_cblkno, "%jd");
- CHK(fs_iblkno, "%jd");
- CHK(fs_dblkno, "%jd");
- CHK(fs_ncg, "%jd");
- CHK(fs_bsize, "%jd");
- CHK(fs_fsize, "%jd");
- CHK(fs_frag, "%jd");
- CHK(fs_bmask, "%#jx");
- CHK(fs_fmask, "%#jx");
- CHK(fs_bshift, "%jd");
- CHK(fs_fshift, "%jd");
- CHK(fs_fragshift, "%jd");
- CHK(fs_fsbtodb, "%jd");
- CHK(fs_sbsize, "%jd");
- CHK(fs_nindir, "%jd");
- CHK(fs_inopb, "%jd");
- CHK(fs_cssize, "%jd");
- CHK(fs_ipg, "%jd");
- CHK(fs_fpg, "%jd");
- CHK(fs_magic, "%#jx");
-#undef CHK
- if (bad) {
- if (listerr == 0)
- return (0);
- if (preen)
- printf("%s: ", cdevname);
- printf(
- "VALUES IN SUPER BLOCK LSB=%jd DISAGREE WITH THOSE IN\n"
- "LAST ALTERNATE LSB=%jd\n",
- sblk.b_bno, asblk.b_bno);
- if (reply("IGNORE ALTERNATE SUPER BLOCK") == 0)
- return (0);
- }
-out:
- /*
* If not yet done, update UFS1 superblock with new wider fields.
*/
if (sblock.fs_magic == FS_UFS1_MAGIC &&
@@ -371,10 +316,8 @@ sblock_init(void)
fsmodified = 0;
lfdir = 0;
initbarea(&sblk, BT_SUPERBLK);
- initbarea(&asblk, BT_SUPERBLK);
sblk.b_un.b_buf = Malloc(SBLOCKSIZE);
- asblk.b_un.b_buf = Malloc(SBLOCKSIZE);
- if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
+ if (sblk.b_un.b_buf == NULL)
errx(EEXIT, "cannot allocate space for superblock");
dev_bsize = secsize = DEV_BSIZE;
}
diff --git a/sbin/fsdb/fsdb.c b/sbin/fsdb/fsdb.c
index c935f88952b4..f9775c7da089 100644
--- a/sbin/fsdb/fsdb.c
+++ b/sbin/fsdb/fsdb.c
@@ -111,7 +111,7 @@ main(int argc, char *argv[])
fsys = argv[0];
sblock_init();
- if (openfilesys(fsys) == 0 || readsb(0) == 0 || setup(fsys) == 0)
+ if (openfilesys(fsys) == 0 || readsb() == 0 || setup(fsys) == 0)
errx(1, "cannot set up file system `%s'", fsys);
if (fswritefd < 0)
nflag++;
diff --git a/sbin/fsirand/fsirand.c b/sbin/fsirand/fsirand.c
index c4db8848f18b..90305416f556 100644
--- a/sbin/fsirand/fsirand.c
+++ b/sbin/fsirand/fsirand.c
@@ -112,7 +112,7 @@ fsirand(char *device)
struct fs *sblock;
ino_t inumber;
ufs2_daddr_t dblk;
- int devfd, n, cg, ret;
+ int devfd, n, cg;
u_int32_t bsize = DEV_BSIZE;
if ((devfd = open(device, printonly ? O_RDONLY : O_RDWR)) < 0) {
@@ -124,10 +124,10 @@ fsirand(char *device)
dp2 = NULL;
/* Read in master superblock */
- if ((ret = sbget(devfd, &sblock, STDSB)) != 0) {
- switch (ret) {
+ if ((errno = sbget(devfd, &sblock, UFS_STDSB, UFS_NOCSUM)) != 0) {
+ switch (errno) {
case ENOENT:
- warn("Cannot find file system superblock");
+ warnx("Cannot find file system superblock");
return (1);
default:
warn("Unable to read file system superblock");
diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c
index 9b43910b88f9..535d7d9f6f21 100644
--- a/sbin/geom/core/geom.c
+++ b/sbin/geom/core/geom.c
@@ -503,7 +503,10 @@ run_command(int argc, char *argv[])
}
if (errstr != NULL && errstr[0] != '\0') {
warnx("%s", errstr);
- if (strncmp(errstr, "warning: ", strlen("warning: ")) != 0) {
+ /* Suppress EXIT_FAILURE for warnings */
+ if (strncmp(errstr, "warning: ", strlen("warning: ")) == 0)
+ req->nerror = 0;
+ if (req->nerror != 0) {
gctl_free(req);
exit(EXIT_FAILURE);
}
diff --git a/sbin/geom/misc/subr.c b/sbin/geom/misc/subr.c
index 3985ae56edc6..297a1cc09a36 100644
--- a/sbin/geom/misc/subr.c
+++ b/sbin/geom/misc/subr.c
@@ -398,6 +398,8 @@ gctl_error(struct gctl_req *req, const char *error, ...)
fprintf(stderr, "\n");
}
va_end(ap);
+ if (req != NULL && req->nerror == 0)
+ req->nerror = EINVAL;
}
static void *
diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c
index 69e6f04dd4c2..4a8d935d91c7 100644
--- a/sbin/growfs/growfs.c
+++ b/sbin/growfs/growfs.c
@@ -1455,7 +1455,7 @@ main(int argc, char **argv)
/*
* Read the current superblock, and take a backup.
*/
- if ((ret = sbget(fsi, &fs, STDSB)) != 0) {
+ if ((ret = sbget(fsi, &fs, UFS_STDSB, 0)) != 0) {
switch (ret) {
case ENOENT:
errx(1, "superblock not recognized");
diff --git a/sbin/gvinum/gvinum.8 b/sbin/gvinum/gvinum.8
index a8135e9bf4a2..2726152df48d 100644
--- a/sbin/gvinum/gvinum.8
+++ b/sbin/gvinum/gvinum.8
@@ -47,7 +47,7 @@ Users are advised to migrate to
.Xr gstripe 8 ,
.Xr graid 8 ,
or
-.Xr ZFS 8 .
+.Xr zfs 8 .
More information is available at
.Pa https://wiki.freebsd.org/DeprecationPlan/gvinum .
.Sh SYNOPSIS
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index e059c172dd5c..c7729dd338e1 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$
.\"
-.Dd June 24, 2022
+.Dd July 11, 2022
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -487,13 +487,10 @@ Assign the interface to a
Any interface can be in multiple groups.
.Pp
Cloned interfaces are members of their interface family group by default.
-For example, a PPP interface such as
-.Em ppp0
-is a member of the PPP interface family group,
-.Em ppp .
-.\" The interface(s) the default route(s) point to are members of the
-.\" .Em egress
-.\" interface group.
+For example, a VLAN interface such as
+.Em vlan10
+is a member of the VLAN interface family group,
+.Em vlan .
.It Cm -group Ar groupname
Remove the interface from the given
.Dq group .
@@ -520,9 +517,10 @@ Specify tunnel FIB.
A FIB
.Ar fib_number
is assigned to all packets encapsulated by tunnel interface, e.g.,
-.Xr gif 4
+.Xr gif 4 ,
+.Xr gre 4
and
-.Xr gre 4 .
+.Xr vxlan 4 .
.It Cm maclabel Ar label
If Mandatory Access Control support is enabled in the kernel,
set the MAC label to
@@ -2720,19 +2718,19 @@ Hash is calculated by using flowid bits in a packet header mbuf
which are shifted by the number of this parameter.
.It Cm use_numa
Enable selection of egress ports based on the native
-.Xr NUMA 4
+.Xr numa 4
domain for the packets being transmitted.
This is currently only implemented for lacp mode.
This works only on
-.Xr NUMA 4
+.Xr numa 4
hardware, running a kernel compiled with the
-.Xr NUMA 4
+.Xr numa 4
option, and when interfaces from multiple
-.Xr NUMA 4
+.Xr numa 4
domains are ports of the aggregation interface.
.It Cm -use_numa
Disable selection of egress ports based on the native
-.Xr NUMA 4
+.Xr numa 4
domain for the packets being transmitted.
.It Cm lacp_fast_timeout
Enable lacp fast-timeout on the interface.
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index ec8a3fd52803..462d543125c4 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -208,7 +208,7 @@ ioctl_ifcreate(int s, struct ifreq *ifr)
case EEXIST:
errx(1, "interface %s already exists", ifr->ifr_name);
default:
- err(1, "SIOCIFCREATE2");
+ err(1, "SIOCIFCREATE2 (%s)", ifr->ifr_name);
}
}
}
diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c
index ee611a14b45e..cb465a02b794 100644
--- a/sbin/ifconfig/ifieee80211.c
+++ b/sbin/ifconfig/ifieee80211.c
@@ -5733,7 +5733,7 @@ setdefregdomain(int s)
/* Send changes to net80211. */
setregdomain_cb(s, &regdomain);
- /* Cleanup (so it can be overriden by subsequent parameters). */
+ /* Cleanup (so it can be overridden by subsequent parameters). */
regdomain.regdomain = 0;
regdomain.country = CTRY_DEFAULT;
regdomain.isocc[0] = 0;
diff --git a/sbin/ifconfig/ifvlan.c b/sbin/ifconfig/ifvlan.c
index 8b7b6e9daf9a..74d683ebb55a 100644
--- a/sbin/ifconfig/ifvlan.c
+++ b/sbin/ifconfig/ifvlan.c
@@ -204,8 +204,11 @@ DECL_CMD_FUNC(setvlantag, val, d)
if (params.vlr_tag != ul)
errx(1, "value for vlan out of range");
- if (getvlan(s, &ifr, &vreq) != -1)
+ if (getvlan(s, &ifr, &vreq) != -1) {
+ vreq.vlr_tag = params.vlr_tag;
+ memcpy(&params, &vreq, sizeof(params));
vlan_set(s, &ifr);
+ }
}
static
@@ -233,8 +236,11 @@ DECL_CMD_FUNC(setvlanproto, val, d)
} else
errx(1, "invalid value for vlanproto");
- if (getvlan(s, &ifr, &vreq) != -1)
+ if (getvlan(s, &ifr, &vreq) != -1) {
+ vreq.vlr_proto = params.vlr_proto;
+ memcpy(&params, &vreq, sizeof(params));
vlan_set(s, &ifr);
+ }
}
static
diff --git a/sbin/init/init.c b/sbin/init/init.c
index 813387f63c81..cf48721faf8d 100644
--- a/sbin/init/init.c
+++ b/sbin/init/init.c
@@ -1143,10 +1143,10 @@ run_script(const char *script)
do {
if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
collect_child(wpid);
+ if (requested_transition == death_single ||
+ requested_transition == reroot)
+ return (state_func_t) requested_transition;
if (wpid == -1) {
- if (requested_transition == death_single ||
- requested_transition == reroot)
- return (state_func_t) requested_transition;
if (errno == EINTR)
continue;
warning("wait for %s on %s failed: %m; going to "
diff --git a/sbin/ipf/common/ipf.h b/sbin/ipf/common/ipf.h
index b278d8ec5d6c..977b3f0fd105 100644
--- a/sbin/ipf/common/ipf.h
+++ b/sbin/ipf/common/ipf.h
@@ -318,7 +318,7 @@ extern ipf_dstnode_t *printdstlistnode(ipf_dstnode_t *, copyfunc_t,
extern void printdstlistpolicy(ippool_policy_t);
extern struct ip_pool_s *printpool(struct ip_pool_s *, copyfunc_t,
char *, int, wordtab_t *);
-extern struct ip_pool_s *printpool_live(struct ip_pool_s *, int,
+extern void printpool_live(struct ip_pool_s *, int,
char *, int, wordtab_t *);
extern void printpooldata(ip_pool_t *, int);
extern void printpoolfield(void *, int, int);
diff --git a/sbin/ipf/ipf/ipf.4 b/sbin/ipf/ipf/ipf.4
index 73a17a0cc8d3..73b272a4ccba 100644
--- a/sbin/ipf/ipf/ipf.4
+++ b/sbin/ipf/ipf/ipf.4
@@ -121,7 +121,7 @@ Flags which are recognised in fr_flags:
FR_RETRST 0x000080 /* return a TCP RST packet if blocked */
FR_RETICMP 0x000100 /* return an ICMP packet if blocked */
FR_FAKEICMP 0x00180 /* Return ICMP unreachable with fake source */
- FR_NOMATCH 0x000200 /* no match occured */
+ FR_NOMATCH 0x000200 /* no match occurred */
FR_ACCOUNT 0x000400 /* count packet bytes */
FR_KEEPFRAG 0x000800 /* keep fragment information */
FR_KEEPSTATE 0x001000 /* keep `connection' state information */
diff --git a/sbin/ipf/ippool/ippool.8 b/sbin/ipf/ippool/ippool.8
index bcc8f3cbd71d..358ece5a26ff 100644
--- a/sbin/ipf/ippool/ippool.8
+++ b/sbin/ipf/ippool/ippool.8
@@ -18,7 +18,7 @@ ippool \- user interface to the IPFilter pools
-F [-dv] [-o <role>] [-t <type>]
.br
.B ippool
--l [-dv] [-m <name>] [-t <type>] [-o <role>] [-M <core>] [-N <namelist>]
+-l [-dDv] [-m <name>] [-t <type>] [-o <role>] [-M <core>] [-N <namelist>]
.br
.B ippool
-r [-dnv] [-m <name>] [-o <role>] [-t <type>] -i <ipaddr>[/<netmask>]
@@ -121,6 +121,10 @@ as a number of seconds.
When parsing a configuration file, rather than load new pool data into the
kernel, unload it.
.TP
+.B -D
+When used in conjuction with -l, dump the ippool configuration to stdout in
+a format that can be subsequently used as input into ippool -f.
+.TP
.SH FILES
.br
/dev/iplookup
diff --git a/sbin/ipf/ippool/ippool.c b/sbin/ipf/ippool/ippool.c
index 3e8918e1fcfa..53e1f19c6f90 100644
--- a/sbin/ipf/ippool/ippool.c
+++ b/sbin/ipf/ippool/ippool.c
@@ -47,15 +47,15 @@ int poolnodecommand(int, int, char *[]);
int loadpoolfile(int, char *[], char *);
int poollist(int, char *[]);
void poollist_dead(int, char *, int, char *, char *);
-void poollist_live(int, char *, int, int);
+int poollist_live(int, char *, int, int);
int poolflush(int, char *[]);
int poolstats(int, char *[]);
int gettype(char *, u_int *);
int getrole(char *);
int setnodeaddr(int, int, void *ptr, char *arg);
-void showpools_live(int, int, ipf_pool_stat_t *, char *);
-void showhashs_live(int, int, iphtstat_t *, char *);
-void showdstls_live(int, int, ipf_dstl_stat_t *, char *);
+int showpools_live(int, int, ipf_pool_stat_t *, char *);
+int showhashs_live(int, int, iphtstat_t *, char *);
+int showdstls_live(int, int, ipf_dstl_stat_t *, char *);
int opts = 0;
int fd = -1;
@@ -670,12 +670,15 @@ poollist(int argc, char *argv[])
poolname = NULL;
role = IPL_LOGALL;
- while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1)
+ while ((c = getopt(argc, argv, "dDm:M:N:o:t:v")) != -1)
switch (c)
{
case 'd' :
opts |= OPT_DEBUG;
break;
+ case 'D' :
+ opts |= OPT_SAVEOUT;
+ break;
case 'm' :
poolname = optarg;
break;
@@ -740,9 +743,10 @@ poollist(int argc, char *argv[])
}
op.iplo_unit = role;
- if (live_kernel)
- poollist_live(role, poolname, type, fd);
- else
+ if (live_kernel) {
+ if (poollist_live(role, poolname, type, fd) != 0)
+ return (1);
+ } else
poollist_dead(role, poolname, type, kernel, core);
return (0);
}
@@ -817,7 +821,7 @@ poollist_dead(int role, char *poolname, int type, char *kernel, char *core)
}
-void
+int
poollist_live(int role, char *poolname, int type, int fd)
{
ipf_pool_stat_t plstat;
@@ -837,10 +841,11 @@ poollist_live(int role, char *poolname, int type, int fd)
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
- return;
+ return (1);
}
- showpools_live(fd, role, &plstat, poolname);
+ if (showpools_live(fd, role, &plstat, poolname))
+ return (1);
} else {
for (role = -1; role <= IPL_LOGMAX; role++) {
op.iplo_unit = role;
@@ -848,10 +853,11 @@ poollist_live(int role, char *poolname, int type, int fd)
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
- return;
+ return (1);
}
- showpools_live(fd, role, &plstat, poolname);
+ if (showpools_live(fd, role, &plstat, poolname))
+ return (1);
}
role = IPL_LOGALL;
@@ -873,9 +879,10 @@ poollist_live(int role, char *poolname, int type, int fd)
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
- return;
+ return (1);
}
- showhashs_live(fd, role, &htstat, poolname);
+ if (showhashs_live(fd, role, &htstat, poolname))
+ return (1);
} else {
for (role = 0; role <= IPL_LOGMAX; role++) {
@@ -883,10 +890,11 @@ poollist_live(int role, char *poolname, int type, int fd)
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
- return;
+ return (1);
}
- showhashs_live(fd, role, &htstat, poolname);
+ if (showhashs_live(fd, role, &htstat, poolname))
+ return(1);
}
role = IPL_LOGALL;
}
@@ -907,9 +915,10 @@ poollist_live(int role, char *poolname, int type, int fd)
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
- return;
+ return (1);
}
- showdstls_live(fd, role, &dlstat, poolname);
+ if (showdstls_live(fd, role, &dlstat, poolname))
+ return (1);
} else {
for (role = 0; role <= IPL_LOGMAX; role++) {
@@ -917,18 +926,20 @@ poollist_live(int role, char *poolname, int type, int fd)
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
- return;
+ return (1);
}
- showdstls_live(fd, role, &dlstat, poolname);
+ if (showdstls_live(fd, role, &dlstat, poolname))
+ return (1);
}
role = IPL_LOGALL;
}
}
+ return (0);
}
-void
+int
showpools_live(int fd, int role, ipf_pool_stat_t *plstp, char *poolname)
{
ipflookupiter_t iter;
@@ -953,7 +964,7 @@ showpools_live(int fd, int role, ipf_pool_stat_t *plstp, char *poolname)
while (plstp->ipls_list[role + 1] != NULL) {
if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
ipferror(fd, "ioctl(SIOCLOOKUPITER)");
- break;
+ return (1);
}
if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
((opts & OPT_DEBUG) != 0))
@@ -961,10 +972,11 @@ showpools_live(int fd, int role, ipf_pool_stat_t *plstp, char *poolname)
plstp->ipls_list[role + 1] = pool.ipo_next;
}
+ return (0);
}
-void
+int
showhashs_live(int fd, int role, iphtstat_t *htstp, char *poolname)
{
ipflookupiter_t iter;
@@ -987,17 +999,18 @@ showhashs_live(int fd, int role, iphtstat_t *htstp, char *poolname)
while (htstp->iphs_tables != NULL) {
if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
ipferror(fd, "ioctl(SIOCLOOKUPITER)");
- break;
+ return (1);
}
printhash_live(&table, fd, poolname, opts, pool_fields);
htstp->iphs_tables = table.iph_next;
}
+ return (0);
}
-void
+int
showdstls_live(int fd, int role, ipf_dstl_stat_t *dlstp, char *poolname)
{
ipflookupiter_t iter;
@@ -1020,13 +1033,14 @@ showdstls_live(int fd, int role, ipf_dstl_stat_t *dlstp, char *poolname)
while (dlstp->ipls_list[role] != NULL) {
if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
ipferror(fd, "ioctl(SIOCLOOKUPITER)");
- break;
+ return (1);
}
printdstl_live(&table, fd, poolname, opts, pool_fields);
dlstp->ipls_list[role] = table.ipld_next;
}
+ return (0);
}
diff --git a/sbin/ipf/libipf/interror.c b/sbin/ipf/libipf/interror.c
index ca97254cb382..994fb9d2b320 100644
--- a/sbin/ipf/libipf/interror.c
+++ b/sbin/ipf/libipf/interror.c
@@ -17,7 +17,7 @@ typedef struct {
static ipf_error_entry_t *find_error(int);
-#define IPF_NUM_ERRORS 475
+#define IPF_NUM_ERRORS 477
/*
* NO REUSE OF NUMBERS!
@@ -355,6 +355,7 @@ log" },
{ 60073, "unknown lookup group for next address (ipv6)" },
{ 60074, "unknown next address type (ipv6)" },
{ 60075, "one object at a time must be copied" },
+ { 60076, "NAT ioctl denied in jail without VNET" },
/* -------------------------------------------------------------------------- */
{ 70001, "incorrect object size to get pool stats" },
{ 70002, "could not malloc memory for new pool node" },
@@ -516,6 +517,7 @@ log" },
{ 130015, "ipf_init_all failed" },
{ 130016, "finding pfil head failed" },
{ 130017, "ipfilter is already initialised and running" },
+ { 130018, "ioctl denied in jail without VNET" },
};
diff --git a/sbin/ipf/libipf/printpool_live.c b/sbin/ipf/libipf/printpool_live.c
index 324deb629d0b..9bb19f2888b4 100644
--- a/sbin/ipf/libipf/printpool_live.c
+++ b/sbin/ipf/libipf/printpool_live.c
@@ -9,7 +9,7 @@
#include "netinet/ipl.h"
-ip_pool_t *
+void
printpool_live(ip_pool_t *pool, int fd, char *name, int opts,
wordtab_t *fields)
{
@@ -19,14 +19,16 @@ printpool_live(ip_pool_t *pool, int fd, char *name, int opts,
ipfobj_t obj;
if ((name != NULL) && strncmp(name, pool->ipo_name, FR_GROUPLEN))
- return (pool->ipo_next);
+ return;
if (fields == NULL)
printpooldata(pool, opts);
if ((pool->ipo_flags & IPOOL_DELETE) != 0)
PRINTF("# ");
- if ((opts & OPT_DEBUG) == 0)
+ if (opts & OPT_SAVEOUT)
+ PRINTF("{\n");
+ else if ((opts & OPT_DEBUG) == 0)
PRINTF("\t{");
obj.ipfo_rev = IPFILTER_VERSION;
@@ -48,9 +50,13 @@ printpool_live(ip_pool_t *pool, int fd, char *name, int opts,
while (!last && (ioctl(fd, SIOCLOOKUPITER, &obj) == 0)) {
if (entry.ipn_next == NULL)
last = 1;
+ if (opts & OPT_SAVEOUT)
+ PRINTF("\t");
(void) printpoolnode(&entry, opts, fields);
if ((opts & OPT_DEBUG) == 0)
putchar(';');
+ if (opts & OPT_SAVEOUT)
+ PRINTF("\n");
printed++;
}
}
@@ -58,10 +64,12 @@ printpool_live(ip_pool_t *pool, int fd, char *name, int opts,
if (printed == 0)
putchar(';');
- if ((opts & OPT_DEBUG) == 0)
+ if (opts & OPT_SAVEOUT)
+ PRINTF("};\n");
+ else if ((opts & OPT_DEBUG) == 0)
PRINTF(" };\n");
(void) ioctl(fd,SIOCIPFDELTOK, &iter.ili_key);
- return (pool->ipo_next);
+ return;
}
diff --git a/sbin/ipf/libipf/printpooldata.c b/sbin/ipf/libipf/printpooldata.c
index ce754f9a89bb..bd5af316eb19 100644
--- a/sbin/ipf/libipf/printpooldata.c
+++ b/sbin/ipf/libipf/printpooldata.c
@@ -12,7 +12,9 @@ void
printpooldata(ip_pool_t *pool, int opts)
{
- if ((opts & OPT_DEBUG) == 0) {
+ if (opts & OPT_SAVEOUT) {
+ PRINTF("pool ");
+ } else if ((opts & OPT_DEBUG) == 0) {
if ((pool->ipo_flags & IPOOL_ANON) != 0)
PRINTF("# 'anonymous' tree %s\n", pool->ipo_name);
if ((pool->ipo_flags & IPOOL_DELETE) != 0)
@@ -32,7 +34,11 @@ printpooldata(ip_pool_t *pool, int opts)
printunit(pool->ipo_unit);
- if ((opts & OPT_DEBUG) == 0) {
+ if ((opts & OPT_SAVEOUT)) {
+ PRINTF("/tree (%s \"\%s\";)\n",
+ (!*pool->ipo_name || ISDIGIT(*pool->ipo_name)) ? \
+ "number" : "name", pool->ipo_name);
+ } else if ((opts & OPT_DEBUG) == 0) {
PRINTF(" type=tree %s=%s\n",
(!*pool->ipo_name || ISDIGIT(*pool->ipo_name)) ? \
"number" : "name", pool->ipo_name);
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index db8a11525b4d..dbc551042859 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,7 +1,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 4, 2022
+.Dd August 17, 2022
.Dt IPFW 8
.Os
.Sh NAME
@@ -1080,7 +1080,7 @@ Send a copy of packets matching this rule to the
socket bound to port
.Ar port .
The search continues with the next rule.
-.It Cm unreach Ar code
+.It Cm unreach Ar code Op mtu
Discard packets that match this rule, and try to send an ICMP
unreachable notice with code
.Ar code ,
@@ -1093,6 +1093,12 @@ is a number from 0 to 255, or one of these aliases:
.Cm toshost , filter-prohib , host-precedence
or
.Cm precedence-cutoff .
+The
+.Cm needfrag
+code may have an optional
+.Ar mtu
+parameter.
+If specified, the MTU value will be put into generated ICMP packet.
The search terminates.
.It Cm unreach6 Ar code
Discard packets that match this rule, and try to send an ICMPv6
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 7d820698a25d..698e0d147669 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -1890,6 +1890,10 @@ print_action_instruction(struct buf_pr *bp, const struct format_opts *fo,
bprintf(bp, "abort");
else if (cmd->arg1 == ICMP_UNREACH_HOST)
bprintf(bp, "reject");
+ else if (cmd->arg1 == ICMP_UNREACH_NEEDFRAG &&
+ cmd->len == F_INSN_SIZE(ipfw_insn_u16))
+ bprintf(bp, "needfrag %u",
+ ((const ipfw_insn_u16 *)cmd)->ports[0]);
else
print_reject_code(bp, cmd->arg1);
break;
@@ -3992,6 +3996,17 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
NEED1("missing reject code");
fill_reject_code(&action->arg1, *av);
av++;
+ if (action->arg1 == ICMP_UNREACH_NEEDFRAG && isdigit(**av)) {
+ uint16_t mtu;
+
+ mtu = strtoul(*av, NULL, 10);
+ if (mtu < 68 || mtu >= IP_MAXPACKET)
+ errx(EX_DATAERR, "illegal argument for %s",
+ *(av - 1));
+ action->len = F_INSN_SIZE(ipfw_insn_u16);
+ ((ipfw_insn_u16 *)action)->ports[0] = mtu;
+ av++;
+ }
break;
case TOK_UNREACH6:
diff --git a/sbin/md5/md5.1 b/sbin/md5/md5.1
index 899e49ba3517..a3db48596606 100644
--- a/sbin/md5/md5.1
+++ b/sbin/md5/md5.1
@@ -1,5 +1,5 @@
.\" $FreeBSD$
-.Dd Feb 5, 2022
+.Dd July 26, 2022
.Dt MD5 1
.Os
.Sh NAME
@@ -86,6 +86,9 @@ coreutils versions of these programs.
If the program was called with a name that does not end in
.Nm sum ,
compare the digest of the file against this string.
+If combined with the
+.Fl q
+option, the calculated digest is printed in addition to the exit status being set.
.Pq Note that this option is not yet useful if multiple files are specified.
.It Fl c Ar file
If the program was called with a name that does end in
@@ -94,7 +97,7 @@ the file passed as argument must contain digest lines generated by the same
digest algorithm with or without the
.Fl r
option
-.Pq i.e. in either classical BSD format or in GNU coreutils format .
+.Pq i.e., in either classical BSD format or in GNU coreutils format .
A line with the file name followed by a colon
.Dq ":"
and either OK or FAILED is written for each well-formed line in the digest file.
@@ -164,7 +167,7 @@ d80bf36c332dc0fdc479366ec3fa44cd /etc/rc.conf
.Pd
The
.Nm -sum
-variants put 2 blank characters between hash and file name for full compatibility
+variants put 2 blank characters between hash and file name for full compatibility
with the coreutils versions of these commands.
.Ed
.Pp
@@ -207,7 +210,7 @@ $ md5 -c digest /boot/loader.conf
The digest file may contain any number of lines in the format generated with or without the
.Fl r
option
-.Pq i.e. in either classical BSD format or in GNU coreutils format .
+.Pq i.e., in either classical BSD format or in GNU coreutils format .
If a hash value does not match the file, FAILED is printed instead of OK.
.Sh SEE ALSO
.Xr cksum 1 ,
diff --git a/sbin/md5/md5.c b/sbin/md5/md5.c
index 7235e6e0a39f..97c587efd63c 100644
--- a/sbin/md5/md5.c
+++ b/sbin/md5/md5.c
@@ -436,6 +436,8 @@ MDOutput(const Algorithm_t *alg, char *p, char *argv[])
printf("%s: %s\n", *argv, checkfailed ? "FAILED" : "OK");
} else if (qflag || argv == NULL) {
printf("%s\n", p);
+ if (cflag)
+ checkfailed = strcasecmp(checkAgainst, p) != 0;
} else {
if (rflag)
if (gnu_emu)
diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8
index 2a877c04c079..63b265982a3e 100644
--- a/sbin/mount/mount.8
+++ b/sbin/mount/mount.8
@@ -264,9 +264,7 @@ mounted partition.
.It Cm nosuid
Do not allow set-user-identifier or set-group-identifier bits to take effect.
Note: this option is worthless if a public available suid or sgid
-wrapper like
-.Xr suidperl 1
-is installed on your system.
+wrapper is installed on your system.
It is set automatically when the user does not have super-user privileges.
.It Cm nosymfollow
Do not follow symlinks
diff --git a/sbin/mount_fusefs/mount_fusefs.8 b/sbin/mount_fusefs/mount_fusefs.8
index 9740d0ed59ff..86138dadc6a3 100644
--- a/sbin/mount_fusefs/mount_fusefs.8
+++ b/sbin/mount_fusefs/mount_fusefs.8
@@ -110,7 +110,7 @@ Prohibit the
.Cm allow_other
mount flag.
Intended for use in scripts and the
-.Xr sudoers 5
+.Xr sudoers 5 Pq Pa ports/security/sudo
file.
.It Fl S , Ic --safe
Run in safe mode (i.e., reject invoking a filesystem daemon).
@@ -253,7 +253,7 @@ beyond the
.Va vfs.usermount
sysctl).
The primary tool for such purposes is
-.Xr sudo 8 .
+.Xr sudo 8 Pq Pa ports/security/sudo .
However, given that
.Nm
is capable of invoking an arbitrary program, one must be careful when doing this.
@@ -275,7 +275,7 @@ ignores the environment variable
and always behaves as described.
.Pp
In general, to be as scripting /
-.Xr sudoers 5
+.Xr sudoers 5 Pq Pa ports/security/sudo
friendly as possible, no information has a fixed
position in the command line, but once a given piece of information is
provided, subsequent arguments/options cannot override it (with the
@@ -355,7 +355,7 @@ does not call any external utility and also provides a hacky
.Sh SEE ALSO
.Xr fstat 1 ,
.Xr mount 8 ,
-.Xr sudo 8 ,
+.Xr sudo 8 Pq Pa ports/security/sudo ,
.Xr umount 8
.Sh HISTORY
.Nm
diff --git a/sbin/mount_nfs/Makefile b/sbin/mount_nfs/Makefile
index a896edef898f..527ea42575a5 100644
--- a/sbin/mount_nfs/Makefile
+++ b/sbin/mount_nfs/Makefile
@@ -2,7 +2,7 @@
#
# $FreeBSD$
-PACKAGE=runtime
+PACKAGE=nfs
PROG= mount_nfs
SRCS= mount_nfs.c getmntopts.c mounttab.c
MAN= mount_nfs.8
diff --git a/sbin/mount_nfs/mount_nfs.8 b/sbin/mount_nfs/mount_nfs.8
index 88c9b11e9392..0e6ea0538063 100644
--- a/sbin/mount_nfs/mount_nfs.8
+++ b/sbin/mount_nfs/mount_nfs.8
@@ -28,7 +28,7 @@
.\" @(#)mount_nfs.8 8.3 (Berkeley) 3/29/95
.\" $FreeBSD$
.\"
-.Dd July 2, 2022
+.Dd September 24, 2022
.Dt MOUNT_NFS 8
.Os
.Sh NAME
@@ -188,6 +188,10 @@ Same as not specifying
Make the mount interruptible, which implies that file system calls that
are delayed due to an unresponsive server will fail with EINTR when a
termination signal is posted for the process.
+To avoid leaving file locks in an indeterminate state on the NFS
+server, it is recommended that the
+.Cm nolockd
+option be used with this option.
.It Cm maxgroups Ns = Ns Aq Ar value
Set the maximum size of the group list for the credentials to the
specified value.
@@ -242,6 +246,9 @@ supported by the NFS Version 4 server will be used.
See the
.Cm minorversion
option.
+Make sure that all your NFS Version 4 clients have unique
+values in
+.Pa /etc/hostid .
.It Cm minorversion Ns = Ns Aq Ar value
Use the specified minor version for a NFS Version 4 mount,
overriding the default.
@@ -314,22 +321,23 @@ Do
.Em not
forward
.Xr fcntl 2
-locks over the wire via the NLM protocol for NFSv3 mounts.
+locks over the wire via the NLM protocol for NFSv3 mounts
+or via the NFSv4 protocol for NFSv4 mounts.
All locks will be local and not seen by the server
-and likewise not seen by other NFS clients for NFSv3 mounts.
+and likewise not seen by other NFS clients for NFSv3 or NFSv4 mounts.
This removes the need to run the
.Xr rpcbind 8
service and the
.Xr rpc.statd 8
and
.Xr rpc.lockd 8
-servers on the client.
+servers on the client for NFSv3 mounts.
Note that this option will only be honored when performing the
initial mount, it will be silently ignored if used while updating
the mount options.
-Also, note that NFSv4 mounts do not use these daemons and handle locks over the
-wire in the NFSv4 protocol.
-As such, this option is meaningless for NFSv4 mounts.
+Also, note that NFSv4 mounts do not use these daemons.
+The NFSv4 protocol handles locks,
+unless this option is specified.
.It Cm noncontigwr
This mount option allows the NFS client to
combine non-contiguous byte ranges being written
@@ -458,7 +466,7 @@ Alias for
.Cm timeout .
.It Cm tls
This option specifies that the connection to the server must use TLS
-per RFC NNNN.
+per RFC 9289.
TLS is only supported for TCP connections and the
.Xr rpc.tlsclntd 8
daemon must be running for an NFS over TCP connection to use TLS.
@@ -656,14 +664,25 @@ A version of the
utility appeared in
.Bx 4.4 .
.Sh BUGS
-Since nfsv4 performs open/lock operations that have their ordering strictly
+Since NFSv4 performs open/lock operations that have their ordering strictly
enforced by the server, the options
.Cm intr
and
.Cm soft
cannot be safely used.
-For NFSv4 minor version 1 or 2 mounts, these options may
-also result
-in hung mount points, due to corruption of session slots.
+For NFSv4 minor version 1 or 2 mounts, the ordering is done
+via session slots and the NFSv4 client now handles broken session slots
+fairly well.
+As such, if the
+.Cm nolockd
+option is used along with
+.Cm intr
+and/or
+.Cm soft ,
+an NFSv4 minor version 1 or 2 mount
+should work fairly well, although still not completely correctly.
+For NFSv4 minor version 0 mounts,
.Cm hard
-nfsv4 mounts are strongly recommended.
+mounts without the
+.Cm intr
+mount option is strongly recommended.
diff --git a/sbin/natd/natd.c b/sbin/natd/natd.c
index 402c430dfdfd..599a5247ac85 100644
--- a/sbin/natd/natd.c
+++ b/sbin/natd/natd.c
@@ -226,7 +226,7 @@ int main (int argc, char** argv)
*/
if (mip->inOutPort) {
- mip->divertInOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT);
+ mip->divertInOut = socket(PF_DIVERT, SOCK_RAW, 0);
if (mip->divertInOut == -1)
Quit ("Unable to create divert socket.");
if (mip->divertInOut > fdMax)
@@ -249,14 +249,14 @@ int main (int argc, char** argv)
}
else {
- mip->divertIn = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT);
+ mip->divertIn = socket(PF_DIVERT, SOCK_RAW, 0);
if (mip->divertIn == -1)
Quit ("Unable to create incoming divert socket.");
if (mip->divertIn > fdMax)
fdMax = mip->divertIn;
- mip->divertOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT);
+ mip->divertOut = socket(PF_DIVERT, SOCK_RAW, 0);
if (mip->divertOut == -1)
Quit ("Unable to create outgoing divert socket.");
if (mip->divertOut > fdMax)
@@ -317,7 +317,7 @@ int main (int argc, char** argv)
}
if (globalPort) {
- divertGlobal = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT);
+ divertGlobal = socket(PF_DIVERT, SOCK_RAW, 0);
if (divertGlobal == -1)
Quit ("Unable to create divert socket.");
if (divertGlobal > fdMax)
diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c
index a6c4ee60c2d5..48091d7882d0 100644
--- a/sbin/newfs/mkfs.c
+++ b/sbin/newfs/mkfs.c
@@ -636,23 +636,26 @@ restart:
* Read the last sector of the boot block, replace the last
* 20 bytes with the recovery information, then write it back.
* The recovery information only works for UFS2 filesystems.
+ * For UFS1, zero out the area to ensure that an old UFS2
+ * recovery block is not accidentally found.
*/
- if (sblock.fs_magic == FS_UFS2_MAGIC) {
- if ((fsrbuf = malloc(realsectorsize)) == NULL || bread(&disk,
- part_ofs + (SBLOCK_UFS2 - realsectorsize) / disk.d_bsize,
- fsrbuf, realsectorsize) == -1)
- err(1, "can't read recovery area: %s", disk.d_error);
- fsr =
- (struct fsrecovery *)&fsrbuf[realsectorsize - sizeof *fsr];
+ if ((fsrbuf = malloc(realsectorsize)) == NULL || bread(&disk,
+ part_ofs + (SBLOCK_UFS2 - realsectorsize) / disk.d_bsize,
+ fsrbuf, realsectorsize) == -1)
+ err(1, "can't read recovery area: %s", disk.d_error);
+ fsr = (struct fsrecovery *)&fsrbuf[realsectorsize - sizeof *fsr];
+ if (sblock.fs_magic != FS_UFS2_MAGIC) {
+ memset(fsr, 0, sizeof *fsr);
+ } else {
fsr->fsr_magic = sblock.fs_magic;
fsr->fsr_fpg = sblock.fs_fpg;
fsr->fsr_fsbtodb = sblock.fs_fsbtodb;
fsr->fsr_sblkno = sblock.fs_sblkno;
fsr->fsr_ncg = sblock.fs_ncg;
- wtfs((SBLOCK_UFS2 - realsectorsize) / disk.d_bsize,
- realsectorsize, fsrbuf);
- free(fsrbuf);
}
+ wtfs((SBLOCK_UFS2 - realsectorsize) / disk.d_bsize,
+ realsectorsize, fsrbuf);
+ free(fsrbuf);
/*
* Update information about this partition in pack
* label, to that it may be updated on disk.
diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8
index 5213e4109363..a5b850c54675 100644
--- a/sbin/newfs/newfs.8
+++ b/sbin/newfs/newfs.8
@@ -314,7 +314,7 @@ than the historical defaults
This large fragment size may lead to much wasted space
on file systems that contain many small files.
.Sh SEE ALSO
-.Xr fdformat 1 ,
+.Xr fdformat 8 ,
.Xr geom 4 ,
.Xr disktab 5 ,
.Xr fs 5 ,
diff --git a/sbin/nvmecontrol/modules/wdc/wdc.c b/sbin/nvmecontrol/modules/wdc/wdc.c
index 050458a8812f..1cae15a1e54c 100644
--- a/sbin/nvmecontrol/modules/wdc/wdc.c
+++ b/sbin/nvmecontrol/modules/wdc/wdc.c
@@ -268,7 +268,7 @@ static void
wdc_get_dui_log_size(int fd, uint32_t opcode, uint8_t data_area,
uint64_t *log_size, int len_off)
{
- uint8_t *hdr;
+ uint8_t *hdr, *tofree;
uint8_t max_sections;
int i, j;
uint16_t hdr_ver;
@@ -277,7 +277,7 @@ wdc_get_dui_log_size(int fd, uint32_t opcode, uint8_t data_area,
dui_size = 0;
len = 1024;
- hdr = (uint8_t*)malloc(len);
+ tofree = hdr = (uint8_t*)malloc(len);
if (hdr == NULL)
errx(EX_OSERR, "Can't get buffer to read header");
wdc_get_data_dui(fd, opcode, len, 0, hdr, len);
@@ -315,7 +315,7 @@ wdc_get_dui_log_size(int fd, uint32_t opcode, uint8_t data_area,
errx(EX_PROTOCOL, "ERROR : No valid header ");
*log_size = dui_size;
- free(hdr);
+ free(tofree);
}
static void
@@ -783,7 +783,6 @@ static void
print_hgst_info_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused)
{
uint8_t *walker, *end, *subpage;
- int pages;
uint16_t len;
uint8_t subtype, res;
@@ -791,8 +790,7 @@ print_hgst_info_log(const struct nvme_controller_data *cdata __unused, void *buf
printf("===================\n");
walker = buf;
- pages = *walker++;
- walker++;
+ walker += 2; /* Page count */
len = le16dec(walker);
walker += 2;
end = walker + len; /* Length is exclusive of this header */
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 506716bca689..eea9f89782be 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -891,7 +891,12 @@ pfa_anchor : '{'
pf->asd++;
pf->bn++;
- /* create a holding ruleset in the root */
+ /*
+ * Anchor contents are parsed before the anchor rule
+ * production completes, so we don't know the real
+ * location yet. Create a holding ruleset in the root;
+ * contents will be moved afterwards.
+ */
snprintf(ta, PF_ANCHOR_NAME_SIZE, "_%d", pf->bn);
rs = pf_find_or_create_ruleset(ta);
if (rs == NULL)
@@ -928,7 +933,14 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto
memset(&r, 0, sizeof(r));
if (pf->astack[pf->asd + 1]) {
- /* move inline rules into relative location */
+ if ($2 && strchr($2, '/') != NULL) {
+ free($2);
+ yyerror("anchor paths containing '/' "
+ "cannot be used for inline anchors.");
+ YYERROR;
+ }
+
+ /* Move inline rules into relative location. */
pfctl_anchor_setup(&r,
&pf->astack[pf->asd]->ruleset,
$2 ? $2 : pf->alast->name);
@@ -1264,7 +1276,14 @@ etheranchorrule : ETHER ANCHOR anchorname dir quick interface etherproto etherfr
memset(&r, 0, sizeof(r));
if (pf->eastack[pf->asd + 1]) {
- /* move inline rules into relative location */
+ if ($3 && strchr($3, '/') != NULL) {
+ free($3);
+ yyerror("anchor paths containing '/' "
+ "cannot be used for inline anchors.");
+ YYERROR;
+ }
+
+ /* Move inline rules into relative location. */
pfctl_eth_anchor_setup(pf, &r,
&pf->eastack[pf->asd]->ruleset,
$3 ? $3 : pf->ealast->name);
@@ -4466,7 +4485,7 @@ pool_opt : BITMASK {
pool_opts.staticport = 1;
}
| STICKYADDRESS {
- if (filter_opts.marker & POM_STICKYADDRESS) {
+ if (pool_opts.marker & POM_STICKYADDRESS) {
yyerror("sticky-address cannot be redefined");
YYERROR;
}
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 93d26e53d71d..37c9625492b1 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -99,8 +99,8 @@ int pfctl_get_pool(int, struct pfctl_pool *, u_int32_t, u_int32_t, int,
char *);
void pfctl_print_eth_rule_counters(struct pfctl_eth_rule *, int);
void pfctl_print_rule_counters(struct pfctl_rule *, int);
-int pfctl_show_eth_rules(int, char *, int, enum pfctl_show, char *, int);
-int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int);
+int pfctl_show_eth_rules(int, char *, int, enum pfctl_show, char *, int, int);
+int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int, int);
int pfctl_show_nat(int, char *, int, char *, int);
int pfctl_show_src_nodes(int, int);
int pfctl_show_states(int, const char *, int);
@@ -1020,8 +1020,8 @@ pfctl_print_eth_rule_counters(struct pfctl_eth_rule *rule, int opts)
char timestr[30];
if (rule->last_active_timestamp != 0) {
- time_t last_active = rule->last_active_timestamp;
- bcopy(ctime(&last_active), timestr, sizeof(timestr));
+ bcopy(ctime(&rule->last_active_timestamp), timestr,
+ sizeof(timestr));
*strchr(timestr, '\n') = '\0';
} else {
snprintf(timestr, sizeof(timestr), "N/A");
@@ -1070,8 +1070,8 @@ pfctl_print_rule_counters(struct pfctl_rule *rule, int opts)
if (opts & PF_OPT_VERBOSE2) {
char timestr[30];
if (rule->last_active_timestamp != 0) {
- time_t last_active = rule->last_active_timestamp;
- bcopy(ctime(&last_active), timestr, sizeof(timestr));
+ bcopy(ctime(&rule->last_active_timestamp), timestr,
+ sizeof(timestr));
*strchr(timestr, '\n') = '\0';
} else {
snprintf(timestr, sizeof(timestr), "N/A");
@@ -1091,20 +1091,73 @@ pfctl_print_title(char *title)
int
pfctl_show_eth_rules(int dev, char *path, int opts, enum pfctl_show format,
- char *anchorname, int depth)
+ char *anchorname, int depth, int wildcard)
{
char anchor_call[MAXPATHLEN];
struct pfctl_eth_rules_info info;
struct pfctl_eth_rule rule;
+ int brace;
int dotitle = opts & PF_OPT_SHOWALL;
int len = strlen(path);
- int brace;
- char *p;
+ char *npath, *p;
- if (path[0])
- snprintf(&path[len], MAXPATHLEN - len, "/%s", anchorname);
- else
- snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname);
+ /*
+ * Truncate a trailing / and * on an anchorname before searching for
+ * the ruleset, this is syntactic sugar that doesn't actually make it
+ * to the kernel.
+ */
+ if ((p = strrchr(anchorname, '/')) != NULL &&
+ p[1] == '*' && p[2] == '\0') {
+ p[0] = '\0';
+ }
+
+ if (anchorname[0] == '/') {
+ if ((npath = calloc(1, MAXPATHLEN)) == NULL)
+ errx(1, "pfctl_rules: calloc");
+ snprintf(npath, MAXPATHLEN, "%s", anchorname);
+ } else {
+ if (path[0])
+ snprintf(&path[len], MAXPATHLEN - len, "/%s", anchorname);
+ else
+ snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname);
+ npath = path;
+ }
+
+ /*
+ * If this anchor was called with a wildcard path, go through
+ * the rulesets in the anchor rather than the rules.
+ */
+ if (wildcard && (opts & PF_OPT_RECURSE)) {
+ struct pfctl_eth_rulesets_info ri;
+ u_int32_t mnr, nr;
+
+ if (pfctl_get_eth_rulesets_info(dev, &ri, npath)) {
+ if (errno == EINVAL) {
+ fprintf(stderr, "Anchor '%s' "
+ "not found.\n", anchorname);
+ } else {
+ warn("DIOCGETETHRULESETS");
+ return (-1);
+ }
+ }
+ mnr = ri.nr;
+
+ pfctl_print_eth_rule_counters(&rule, opts);
+ for (nr = 0; nr < mnr; ++nr) {
+ struct pfctl_eth_ruleset_info rs;
+
+ if (pfctl_get_eth_ruleset(dev, npath, nr, &rs))
+ err(1, "DIOCGETETHRULESET");
+ INDENT(depth, !(opts & PF_OPT_VERBOSE));
+ printf("anchor \"%s\" all {\n", rs.name);
+ pfctl_show_eth_rules(dev, npath, opts,
+ format, rs.name, depth + 1, 0);
+ INDENT(depth, !(opts & PF_OPT_VERBOSE));
+ printf("}\n");
+ }
+ path[len] = '\0';
+ return (0);
+ }
if (pfctl_get_eth_rules_info(dev, &info, path)) {
warn("DIOCGETETHRULES");
@@ -1123,13 +1176,11 @@ pfctl_show_eth_rules(int dev, char *path, int opts, enum pfctl_show format,
(p == anchor_call ||
*(--p) == '/')) || (opts & PF_OPT_RECURSE))) {
brace++;
- if ((p = strrchr(anchor_call, '/')) !=
- NULL)
- p++;
- else
- p = &anchor_call[0];
- } else
- p = &anchor_call[0];
+ int aclen = strlen(anchor_call);
+ if (anchor_call[aclen - 1] == '*')
+ anchor_call[aclen - 2] = '\0';
+ }
+ p = &anchor_call[0];
if (dotitle) {
pfctl_print_title("ETH RULES:");
dotitle = 0;
@@ -1143,7 +1194,7 @@ pfctl_show_eth_rules(int dev, char *path, int opts, enum pfctl_show format,
pfctl_print_eth_rule_counters(&rule, opts);
if (brace) {
pfctl_show_eth_rules(dev, path, opts, format,
- p, depth + 1);
+ p, depth + 1, rule.anchor_wildcard);
INDENT(depth, !(opts & PF_OPT_VERBOSE));
printf("}\n");
}
@@ -1155,7 +1206,7 @@ pfctl_show_eth_rules(int dev, char *path, int opts, enum pfctl_show format,
int
pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
- char *anchorname, int depth)
+ char *anchorname, int depth, int wildcard)
{
struct pfctl_rules_info ri;
struct pfctl_rule rule;
@@ -1163,15 +1214,65 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
u_int32_t nr, header = 0;
int rule_numbers = opts & (PF_OPT_VERBOSE2 | PF_OPT_DEBUG);
int numeric = opts & PF_OPT_NUMERIC;
- int len = strlen(path);
- int brace;
- int ret;
- char *p;
+ int len = strlen(path), ret = 0;
+ char *npath, *p;
- if (path[0])
- snprintf(&path[len], MAXPATHLEN - len, "/%s", anchorname);
- else
- snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname);
+ /*
+ * Truncate a trailing / and * on an anchorname before searching for
+ * the ruleset, this is syntactic sugar that doesn't actually make it
+ * to the kernel.
+ */
+ if ((p = strrchr(anchorname, '/')) != NULL &&
+ p[1] == '*' && p[2] == '\0') {
+ p[0] = '\0';
+ }
+
+ if (anchorname[0] == '/') {
+ if ((npath = calloc(1, MAXPATHLEN)) == NULL)
+ errx(1, "pfctl_rules: calloc");
+ snprintf(npath, MAXPATHLEN, "%s", anchorname);
+ } else {
+ if (path[0])
+ snprintf(&path[len], MAXPATHLEN - len, "/%s", anchorname);
+ else
+ snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname);
+ npath = path;
+ }
+
+ /*
+ * If this anchor was called with a wildcard path, go through
+ * the rulesets in the anchor rather than the rules.
+ */
+ if (wildcard && (opts & PF_OPT_RECURSE)) {
+ struct pfioc_ruleset prs;
+ u_int32_t mnr, nr;
+
+ memset(&prs, 0, sizeof(prs));
+ memcpy(prs.path, npath, sizeof(prs.path));
+ if (ioctl(dev, DIOCGETRULESETS, &prs)) {
+ if (errno == EINVAL)
+ fprintf(stderr, "Anchor '%s' "
+ "not found.\n", anchorname);
+ else
+ err(1, "DIOCGETRULESETS");
+ }
+ mnr = prs.nr;
+
+ pfctl_print_rule_counters(&rule, opts);
+ for (nr = 0; nr < mnr; ++nr) {
+ prs.nr = nr;
+ if (ioctl(dev, DIOCGETRULESET, &prs))
+ err(1, "DIOCGETRULESET");
+ INDENT(depth, !(opts & PF_OPT_VERBOSE));
+ printf("anchor \"%s\" all {\n", prs.name);
+ pfctl_show_rules(dev, npath, opts,
+ format, prs.name, depth + 1, 0);
+ INDENT(depth, !(opts & PF_OPT_VERBOSE));
+ printf("}\n");
+ }
+ path[len] = '\0';
+ return (0);
+ }
if (opts & PF_OPT_SHOWALL) {
ret = pfctl_get_rules_info(dev, &ri, PF_PASS, path);
@@ -1262,32 +1363,30 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
break;
}
case PFCTL_SHOW_RULES:
- brace = 0;
if (rule.label[0] && (opts & PF_OPT_SHOWALL))
labels = 1;
INDENT(depth, !(opts & PF_OPT_VERBOSE));
+ print_rule(&rule, anchor_call, rule_numbers, numeric);
+
+ /*
+ * If this is a 'unnamed' brace notation
+ * anchor, OR the user has explicitly requested
+ * recursion, print it recursively.
+ */
if (anchor_call[0] &&
- ((((p = strrchr(anchor_call, '_')) != NULL) &&
- ((void *)p == (void *)anchor_call ||
- *(--p) == '/')) || (opts & PF_OPT_RECURSE))) {
- brace++;
- int aclen = strlen(anchor_call);
- if (anchor_call[aclen - 1] == '*')
- anchor_call[aclen - 2] = '\0';
- }
- p = &anchor_call[0];
-
- print_rule(&rule, p, rule_numbers, numeric);
- if (brace)
+ (((p = strrchr(anchor_call, '/')) ?
+ p[1] == '_' : anchor_call[0] == '_') ||
+ opts & PF_OPT_RECURSE)) {
printf(" {\n");
- else
- printf("\n");
- pfctl_print_rule_counters(&rule, opts);
- if (brace) {
- pfctl_show_rules(dev, path, opts, format,
- p, depth + 1);
+ pfctl_print_rule_counters(&rule, opts);
+ pfctl_show_rules(dev, npath, opts, format,
+ anchor_call, depth + 1,
+ rule.anchor_wildcard);
INDENT(depth, !(opts & PF_OPT_VERBOSE));
printf("}\n");
+ } else {
+ printf("\n");
+ pfctl_print_rule_counters(&rule, opts);
}
break;
case PFCTL_SHOW_NOTHING:
@@ -1295,12 +1394,10 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
}
pfctl_clear_pool(&rule.rpool);
}
- path[len] = '\0';
- return (0);
error:
path[len] = '\0';
- return (-1);
+ return (ret);
}
int
@@ -1911,7 +2008,7 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pfctl_rule *r, int depth)
if (pf->opts & PF_OPT_VERBOSE) {
INDENT(depth, !(pf->opts & PF_OPT_VERBOSE2));
- print_rule(r, r->anchor ? r->anchor->name : "",
+ print_rule(r, name,
pf->opts & PF_OPT_VERBOSE2,
pf->opts & PF_OPT_NUMERIC);
if (was_present)
@@ -2910,12 +3007,12 @@ main(int argc, char *argv[])
case 'r':
pfctl_load_fingerprints(dev, opts);
pfctl_show_rules(dev, path, opts, PFCTL_SHOW_RULES,
- anchorname, 0);
+ anchorname, 0, 0);
break;
case 'l':
pfctl_load_fingerprints(dev, opts);
pfctl_show_rules(dev, path, opts, PFCTL_SHOW_LABELS,
- anchorname, 0);
+ anchorname, 0, 0);
break;
case 'n':
pfctl_load_fingerprints(dev, opts);
@@ -2944,21 +3041,23 @@ main(int argc, char *argv[])
pfctl_show_limits(dev, opts);
break;
case 'e':
- pfctl_show_eth_rules(dev, path, opts, 0, anchorname, 0);
+ pfctl_show_eth_rules(dev, path, opts, 0, anchorname, 0,
+ 0);
break;
case 'a':
opts |= PF_OPT_SHOWALL;
pfctl_load_fingerprints(dev, opts);
- pfctl_show_eth_rules(dev, path, opts, 0, anchorname, 0);
+ pfctl_show_eth_rules(dev, path, opts, 0, anchorname, 0,
+ 0);
pfctl_show_nat(dev, path, opts, anchorname, 0);
- pfctl_show_rules(dev, path, opts, 0, anchorname, 0);
+ pfctl_show_rules(dev, path, opts, 0, anchorname, 0, 0);
pfctl_show_altq(dev, ifaceopt, opts, 0);
pfctl_show_states(dev, ifaceopt, opts);
pfctl_show_src_nodes(dev, opts);
pfctl_show_status(dev, opts);
- pfctl_show_rules(dev, path, opts, 1, anchorname, 0);
+ pfctl_show_rules(dev, path, opts, 1, anchorname, 0, 0);
pfctl_show_timeouts(dev, opts);
pfctl_show_limits(dev, opts);
pfctl_show_tables(anchorname, opts);
@@ -2979,9 +3078,9 @@ main(int argc, char *argv[])
if ((opts & PF_OPT_CLRRULECTRS) && showopt == NULL) {
pfctl_show_eth_rules(dev, path, opts, PFCTL_SHOW_NOTHING,
- anchorname, 0);
+ anchorname, 0, 0);
pfctl_show_rules(dev, path, opts, PFCTL_SHOW_NOTHING,
- anchorname, 0);
+ anchorname, 0, 0);
}
if (clearopt != NULL) {
diff --git a/sbin/pfctl/pfctl_altq.c b/sbin/pfctl/pfctl_altq.c
index 6d35ae77240f..66075258f106 100644
--- a/sbin/pfctl/pfctl_altq.c
+++ b/sbin/pfctl/pfctl_altq.c
@@ -1227,7 +1227,7 @@ char *
rate2str(double rate)
{
char *buf;
- static char r2sbuf[R2S_BUFS][RATESTR_MAX]; /* ring bufer */
+ static char r2sbuf[R2S_BUFS][RATESTR_MAX]; /* ring buffer */
static int idx = 0;
int i;
static const char unit[] = " KMG";
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index a05683f0cbce..260c754f7209 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -74,7 +74,7 @@ void print_fromto(struct pf_rule_addr *, pf_osfp_t,
struct pf_rule_addr *, u_int8_t, u_int8_t, int, int);
int ifa_skip_if(const char *filter, struct node_host *p);
-struct node_host *host_if(const char *, int);
+struct node_host *host_if(const char *, int, int *);
struct node_host *host_v4(const char *, int);
struct node_host *host_v6(const char *, int);
struct node_host *host_dns(const char *, int, int);
@@ -811,6 +811,7 @@ print_rule(struct pfctl_rule *r, const char *anchor_call, int verbose, int numer
"anchor", "nat-anchor", "nat-anchor", "binat-anchor",
"binat-anchor", "rdr-anchor", "rdr-anchor" };
int i, opts;
+ char *p;
if (verbose)
printf("@%d ", r->nr);
@@ -819,9 +820,10 @@ print_rule(struct pfctl_rule *r, const char *anchor_call, int verbose, int numer
else if (r->action > PF_NORDR)
printf("action(%d)", r->action);
else if (anchor_call[0]) {
- if (anchor_call[0] == '_') {
+ p = strrchr(anchor_call, '/');
+ if (p ? p[1] == '_' : anchor_call[0] == '_')
printf("%s", anchortypes[r->action]);
- } else
+ else
printf("%s \"%s\"", anchortypes[r->action],
anchor_call);
} else {
@@ -1695,7 +1697,7 @@ host(const char *s)
/* interface with this name exists? */
/* expensive with thousands of interfaces - prioritze IPv4/6 check */
- if (cont && (h = host_if(ps, mask)) != NULL)
+ if (cont && (h = host_if(ps, mask, &cont)) != NULL)
cont = 0;
/* dns lookup */
@@ -1711,7 +1713,7 @@ host(const char *s)
}
struct node_host *
-host_if(const char *s, int mask)
+host_if(const char *s, int mask, int *cont)
{
struct node_host *n, *h = NULL;
char *p, *ps;
@@ -1733,6 +1735,7 @@ host_if(const char *s, int mask)
return (NULL);
}
*p = '\0';
+ *cont = 0;
}
if (flags & (flags - 1) & PFI_AFLAG_MODEMASK) { /* Yep! */
fprintf(stderr, "illegal combination of interface modifiers\n");
diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c
index 5d71a4e6ac89..95407ccae261 100644
--- a/sbin/pfctl/pfctl_radix.c
+++ b/sbin/pfctl/pfctl_radix.c
@@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$");
extern int dev;
-static int pfr_next_token(char buf[], FILE *);
+static int pfr_next_token(char buf[BUF_SIZE], FILE *);
static void
pfr_report_error(struct pfr_table *tbl, struct pfioc_table *io,
diff --git a/sbin/pfctl/tests/files/pf0100.ok b/sbin/pfctl/tests/files/pf0100.ok
index 6d1740f308bc..9f4427379bc7 100644
--- a/sbin/pfctl/tests/files/pf0100.ok
+++ b/sbin/pfctl/tests/files/pf0100.ok
@@ -1,14 +1,14 @@
pass all flags S/SA keep state
-anchor "/b" all
-anchor "/3" all
+anchor "a/b" all
+anchor "1/2/3" all
anchor "relative" all {
pass in on lo0 all flags S/SA keep state label "TEST1"
}
-anchor "/*" all
-anchor "/*" all
+anchor "camield/*" all
+anchor "relayd/*" all
anchor "foo" in on lo0 all {
anchor "bar" in all {
- anchor "/3" all
+ anchor "/1/2/3" all
anchor "/relative" all
pass in on lo0 all flags S/SA keep state label "FOO"
}
diff --git a/sbin/pfctl/tests/files/pf1010.in b/sbin/pfctl/tests/files/pf1010.in
new file mode 100644
index 000000000000..2baf4dc360af
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1010.in
@@ -0,0 +1,2 @@
+pass inet proto icmp icmp-type {unreach}
+pass in route-to (if0 127.0.0.1/8) sticky-address inet
diff --git a/sbin/pfctl/tests/files/pf1010.ok b/sbin/pfctl/tests/files/pf1010.ok
new file mode 100644
index 000000000000..b960dbfc50b8
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1010.ok
@@ -0,0 +1,2 @@
+pass inet proto icmp all icmp-type unreach keep state
+pass in route-to (if0 127.0.0.0/8) sticky-address inet all flags S/SA keep state
diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc
index aa3f625e905f..0b6d5110034d 100644
--- a/sbin/pfctl/tests/pfctl_test_list.inc
+++ b/sbin/pfctl/tests/pfctl_test_list.inc
@@ -120,3 +120,4 @@ PFCTL_TEST(1006, "pfctl crashes with certain fairq configurations")
PFCTL_TEST(1007, "Basic ethernet rule")
PFCTL_TEST(1008, "Ethernet rule with mask length")
PFCTL_TEST(1009, "Ethernet rule with mask")
+PFCTL_TEST(1010, "POM_STICKYADDRESS test")
diff --git a/sbin/ping/ping6.c b/sbin/ping/ping6.c
index e780129c928d..74d36f0357f8 100644
--- a/sbin/ping/ping6.c
+++ b/sbin/ping/ping6.c
@@ -1515,7 +1515,7 @@ mynireply(const struct icmp6_nodeinfo *nip)
*
* Return value:
* Pointer to an octet immediately following the ending zero octet
- * of the decoded label, or NULL if an error occured.
+ * of the decoded label, or NULL if an error occurred.
*/
static const char *
dnsdecode(const u_char *sp, const u_char *ep, const u_char *base, char *buf,
diff --git a/sbin/quotacheck/quotacheck.c b/sbin/quotacheck/quotacheck.c
index 9a01be11d9d0..1e656d2a5811 100644
--- a/sbin/quotacheck/quotacheck.c
+++ b/sbin/quotacheck/quotacheck.c
@@ -321,7 +321,7 @@ chkquota(char *specname, struct quotafile *qfu, struct quotafile *qfg)
}
}
sync();
- if ((ret = sbget(fi, &fs, STDSB)) != 0) {
+ if ((ret = sbget(fi, &fs, UFS_STDSB, UFS_NOCSUM)) != 0) {
switch (ret) {
case ENOENT:
warn("Cannot find file system superblock");
diff --git a/sbin/setkey/setkey.8 b/sbin/setkey/setkey.8
index 79e28b99f950..ff36c53a2f7f 100644
--- a/sbin/setkey/setkey.8
+++ b/sbin/setkey/setkey.8
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 27, 2022
+.Dd September 13, 2022
.Dt SETKEY 8
.Os
.\"
@@ -455,17 +455,18 @@ is expressed in one of the following three formats:
.Pp
The direction of a policy must be specified as
one of:
-.Li out ,
-.Li in ,
+.Li out
+or
+.Li in .
+The direction is followed by one of the following policy levels:
.Li discard ,
.Li none ,
or
.Li ipsec .
The
.Li discard
-direction
-means that packets matching the supplied indices will be discarded
-while
+policylevel means that packets matching the supplied indices will
+be discarded while
.Li none
means that IPsec operations will not take place on the packet and
.Li ipsec
@@ -535,7 +536,7 @@ level is the same as
but, in addition, it allows the policy to bind with the unique out-bound SA.
For example, if you specify the policy level
.Li unique ,
-.Xr racoon 8
+.Xr racoon 8 Pq Pa ports/security/ipsec-tools
will configure the SA for the policy.
If you configure the SA by manual keying for that policy,
you can put the decimal number as the policy identifier after
@@ -688,7 +689,7 @@ add 10.1.10.36 10.1.10.34 tcp 0x1001 -A tcp-md5 "TCP-MD5 BGP secret" ;
.Sh SEE ALSO
.Xr ipsec_set_policy 3 ,
.Xr if_ipsec 4 ,
-.Xr racoon 8 ,
+.Xr racoon 8 Pq Pa ports/security/ipsec-tools ,
.Xr sysctl 8
.Rs
.%T "Changed manual key configuration for IPsec"
diff --git a/sbin/tunefs/tunefs.8 b/sbin/tunefs/tunefs.8
index 065844a831cd..b9a581df6784 100644
--- a/sbin/tunefs/tunefs.8
+++ b/sbin/tunefs/tunefs.8
@@ -28,7 +28,7 @@
.\" @(#)tunefs.8 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
-.Dd January 29, 2019
+.Dd August 16, 2022
.Dt TUNEFS 8
.Os
.Sh NAME
@@ -95,6 +95,46 @@ this parameter should be set higher.
Specify the expected average file size.
.It Fl j Cm enable | disable
Turn on/off soft updates journaling.
+.Pp
+Enabling journaling reduces the time spent by
+.Xr fsck_ffs 8
+cleaning up a filesystem after a crash to a few seconds from minutes to hours.
+Without journaling, the time to recover after a crash is a function
+of the number of files in the filesystem and the size of the filesystem.
+With journaling, the time to recover after a crash is a function of the
+amount of activity in the filesystem in the minute before the crash.
+Journaled recovery time is usually only a few seconds and never
+exceeds a minute.
+.Pp
+The drawback to using journaling is that the writes to its log adds
+an extra write load to the media containing the filesystem.
+Thus a write-intensive workload will have reduced throughput on a
+filesystem running with journaling.
+.Pp
+Like all journaling filesystems, the journal recovery will only fix
+issues known to the journal.
+Specifically if a media error occurs,
+the journal will not know about it and hence will not fix it.
+Thus when using journaling, it is still necessary to run a full fsck
+every few months or after a filesystem panic to check for and fix
+any errors brought on by media failure.
+A full fsck can be done by running a background fsck on a live
+filesystem or by running with the
+.Fl f
+flag on an unmounted filesystem.
+When running
+.Xr fsck_ffs 8
+in background on a live filesystem the filesystem performance
+will be about half of normal during the time that the background
+.Xr fsck_ffs 8
+is running.
+Running a full fsck on a UFS filesystem is the equivalent of
+running a scrub on a ZFS filesystem.
+.Pp
+Presently it is not possible to take a snapshot on a UFS filesystem
+running with journaled soft updates.
+Thus it is not possible to reliably dump mounted filesystems or
+to run background fsck on filesystems enabled for journaling.
.It Fl J Cm enable | disable
Turn on/off gjournal flag.
.It Fl k Ar held-for-metadata-blocks
diff --git a/sbin/veriexec/veriexec.8 b/sbin/veriexec/veriexec.8
index 161406ae6de2..d191f5175074 100644
--- a/sbin/veriexec/veriexec.8
+++ b/sbin/veriexec/veriexec.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 14, 2022
+.Dd July 8, 2022
.Dt VERIEXEC 8
.Os
.Sh NAME
@@ -34,6 +34,7 @@
.Nm
.Op Fl v
.Op Fl C Ar directory
+.Op Fl S
.Pa manifest
.Nm
.Fl z Ar state
@@ -53,6 +54,11 @@ The first form is for loading a
first verifies a digital signature of the
.Ar manifest
and if successful, parses it and feeds its content to kernel.
+The
+.Fl S
+flag indicates that certificate validity should be checked.
+Without this, a valid signature with an expired certificate
+will still be accepted.
.Pp
The second form with
.Fl z
diff --git a/sbin/veriexec/veriexec.c b/sbin/veriexec/veriexec.c
index aff514b1cac5..0162eeda5347 100644
--- a/sbin/veriexec/veriexec.c
+++ b/sbin/veriexec/veriexec.c
@@ -148,7 +148,7 @@ main(int argc, char *argv[])
dev_fd = open(_PATH_DEV_VERIEXEC, O_WRONLY, 0);
- while ((c = getopt(argc, argv, "hC:i:xvz:")) != -1) {
+ while ((c = getopt(argc, argv, "hC:i:Sxvz:")) != -1) {
switch (c) {
case 'h':
/* Print usage info */
@@ -174,6 +174,10 @@ main(int argc, char *argv[])
exit((x & state) == 0);
break;
+ case 'S':
+ /* Strictly enforce certificate validity */
+ ve_enforce_validity_set(1);
+ break;
case 'v':
/* Increase the verbosity */