Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142722334
D54380.id168663.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D54380.id168663.diff
View Options
diff --git a/lib/libc/gen/err.c b/lib/libc/gen/err.c
--- a/lib/libc/gen/err.c
+++ b/lib/libc/gen/err.c
@@ -120,7 +120,7 @@
}
fprintf(err_file, "%s", strerror(code));
if (doexterr && extstatus == 0 && exterr[0] != '\0')
- fprintf(err_file, " (extended error %s)", exterr);
+ fprintf(err_file, " (%s)", exterr);
fprintf(err_file, "\n");
}
diff --git a/lib/libc/gen/exterr_cat_filenames.h b/lib/libc/gen/exterr_cat_filenames.h
new file mode 100644
--- /dev/null
+++ b/lib/libc/gen/exterr_cat_filenames.h
@@ -0,0 +1,17 @@
+/*
+ * Automatically @generated, use
+ * tools/build/make_libc_exterr_cat_filenames.sh
+ */
+ [EXTERR_CAT_FUSE_DEVICE] = "fs/fuse/fuse_device.c",
+ [EXTERR_CAT_FUSE_VFS] = "fs/fuse/fuse_vfsops.c",
+ [EXTERR_CAT_FUSE_VNOPS] = "fs/fuse/fuse_vnops.c",
+ [EXTERR_CAT_GEOM] = "geom/geom_subr.c",
+ [EXTERR_CAT_GEOMVFS] = "geom/geom_vfs.c",
+ [EXTERR_CAT_FILEDESC] = "kern/kern_descrip.c",
+ [EXTERR_CAT_INOTIFY] = "kern/vfs_inotify.c",
+ [EXTERR_CAT_GENIO] = "kern/sys_generic.c",
+ [EXTERR_CAT_VFSBIO] = "kern/vfs_bio.c",
+ [EXTERR_CAT_VFSSYSCALL] = "kern/vfs_syscalls.c",
+ [EXTERR_CAT_BRIDGE] = "net/if_bridge.c",
+ [EXTERR_CAT_SWAP] = "vm/swap_pager.c",
+ [EXTERR_CAT_MMAP] = "vm/vm_mmap.c",
diff --git a/lib/libc/gen/uexterr_format.c b/lib/libc/gen/uexterr_format.c
--- a/lib/libc/gen/uexterr_format.c
+++ b/lib/libc/gen/uexterr_format.c
@@ -8,28 +8,85 @@
* under sponsorship from the FreeBSD Foundation.
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/exterrvar.h>
#include <exterr.h>
+#include <stdbool.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
+static const char * const cat_to_filenames[] = {
+#include "exterr_cat_filenames.h"
+};
+
+static const char *
+cat_to_filename(int category)
+{
+ if (category < 0 || category >= nitems(cat_to_filenames) ||
+ cat_to_filenames[category] == NULL)
+ return ("unknown");
+ return (cat_to_filenames[category]);
+}
+
+static const char exterror_verbose_name[] = "EXTERROR_VERBOSE";
+enum exterr_verbose_state {
+ EXTERR_VERBOSE_UNKNOWN = 100,
+ EXTERR_VERBOSE_DEFAULT,
+ EXTERR_VERBOSE_ALLOW,
+};
+static enum exterr_verbose_state exterror_verbose = EXTERR_VERBOSE_UNKNOWN;
+
+static void
+exterr_verbose_init(void)
+{
+ /*
+ * No need to care about thread-safety, the result is
+ * idempotent.
+ */
+ if (exterror_verbose != EXTERR_VERBOSE_UNKNOWN)
+ return;
+ if (issetugid()) {
+ exterror_verbose = EXTERR_VERBOSE_DEFAULT;
+ } else if (getenv(exterror_verbose_name) != NULL) {
+ exterror_verbose = EXTERR_VERBOSE_ALLOW;
+ } else {
+ exterror_verbose = EXTERR_VERBOSE_DEFAULT;
+ }
+}
int
__uexterr_format(const struct uexterror *ue, char *buf, size_t bufsz)
{
+ bool has_msg;
+
if (bufsz > UEXTERROR_MAXLEN)
bufsz = UEXTERROR_MAXLEN;
if (ue->error == 0) {
strlcpy(buf, "", bufsz);
return (0);
}
- if (ue->msg[0] == '\0') {
- snprintf(buf, bufsz,
- "errno %d category %u (src line %u) p1 %#jx p2 %#jx",
- ue->error, ue->cat, ue->src_line,
- (uintmax_t)ue->p1, (uintmax_t)ue->p2);
+ exterr_verbose_init();
+ has_msg = ue->msg[0] != '\0';
+
+ if (has_msg) {
+ snprintf(buf, bufsz, ue->msg, (uintmax_t)ue->p1,
+ (uintmax_t)ue->p2);
} else {
- strlcpy(buf, ue->msg, bufsz);
+ strlcpy(buf, "", bufsz);
+ }
+
+ if (exterror_verbose == EXTERR_VERBOSE_ALLOW || !has_msg) {
+ char lbuf[128];
+
+ snprintf(lbuf, sizeof(lbuf),
+ "errno %d category %u (src %s:%u) p1 %#jx p2 %#jx",
+ ue->error, ue->cat, cat_to_filename(ue->cat),
+ ue->src_line, (uintmax_t)ue->p1, (uintmax_t)ue->p2);
+ if (has_msg)
+ strlcat(buf, " ", bufsz);
+ strlcat(buf, lbuf, bufsz);
}
return (0);
}
diff --git a/share/man/man9/exterror.9 b/share/man/man9/exterror.9
--- a/share/man/man9/exterror.9
+++ b/share/man/man9/exterror.9
@@ -90,6 +90,16 @@
.Fn EXTERROR
macro can take two optional 64-bit integer arguments,
whose meaning is specific to the subsystem.
+The format string may include up to two printf-like format
+specifiers to insert the optional argument values in the
+user output, which is done in userspace.
+.Pp
+The format specifier must be for an integer type, and include the
+.Dq j
+format modifier to accept only the types
+.Vt intmax_t
+or
+.Vt uintmax_t .
.El
.Pp
The strings passed as the second argument are only retained
diff --git a/sys/fs/fuse/fuse_device.c b/sys/fs/fuse/fuse_device.c
--- a/sys/fs/fuse/fuse_device.c
+++ b/sys/fs/fuse/fuse_device.c
@@ -82,7 +82,7 @@
#include <sys/sysctl.h>
#include <sys/poll.h>
#include <sys/selinfo.h>
-#define EXTERR_CATEGORY EXTERR_CAT_FUSE
+#define EXTERR_CATEGORY EXTERR_CAT_FUSE_DEVICE
#include <sys/exterrvar.h>
#include "fuse.h"
diff --git a/sys/fs/fuse/fuse_vfsops.c b/sys/fs/fuse/fuse_vfsops.c
--- a/sys/fs/fuse/fuse_vfsops.c
+++ b/sys/fs/fuse/fuse_vfsops.c
@@ -81,7 +81,7 @@
#include <sys/mount.h>
#include <sys/sysctl.h>
#include <sys/fcntl.h>
-#define EXTERR_CATEGORY EXTERR_CAT_FUSE
+#define EXTERR_CATEGORY EXTERR_CAT_FUSE_VFS
#include <sys/exterrvar.h>
#include "fuse.h"
diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c
--- a/sys/fs/fuse/fuse_vnops.c
+++ b/sys/fs/fuse/fuse_vnops.c
@@ -89,7 +89,7 @@
#include <sys/buf.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
-#define EXTERR_CATEGORY EXTERR_CAT_FUSE
+#define EXTERR_CATEGORY EXTERR_CAT_FUSE_VNOPS
#include <sys/exterrvar.h>
#include <vm/vm.h>
diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h
--- a/sys/sys/exterr_cat.h
+++ b/sys/sys/exterr_cat.h
@@ -8,6 +8,17 @@
* under sponsorship from the FreeBSD Foundation.
*/
+/*
+ * The category identifiers for the extended errors.
+ * The ids participate in ABI between kernel and libc, so they must
+ * never be reused or changed. Only new ids can be added.
+ *
+ * After adding a new category id, run
+ * tools/build//make_libc_exterr_cat_filenames.sh
+ * from the top of the source tree, and commit updated file
+ * lib/libc/gen/exterr_cat_filenames.h
+ */
+
#ifndef _SYS_EXTERR_CAT_H_
#define _SYS_EXTERR_CAT_H_
@@ -15,7 +26,7 @@
#define EXTERR_CAT_FILEDESC 2
#define EXTERR_KTRACE 3 /* To allow inclusion of this
file into kern_ktrace.c */
-#define EXTERR_CAT_FUSE 4
+#define EXTERR_CAT_FUSE_VNOPS 4
#define EXTERR_CAT_INOTIFY 5
#define EXTERR_CAT_GENIO 6
#define EXTERR_CAT_BRIDGE 7
@@ -24,6 +35,8 @@
#define EXTERR_CAT_VFSBIO 10
#define EXTERR_CAT_GEOMVFS 11
#define EXTERR_CAT_GEOM 12
+#define EXTERR_CAT_FUSE_VFS 13
+#define EXTERR_CAT_FUSE_DEVICE 14
#endif
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -197,12 +197,14 @@
check_fp_fn = mrp->mr_check_fp_fn;
if ((prot & ~(_PROT_ALL | PROT_MAX(_PROT_ALL))) != 0) {
- return (EXTERROR(EINVAL, "unknown PROT bits"));
+ return (EXTERROR(EINVAL, "unknown PROT bits %#jx", prot));
}
max_prot = PROT_MAX_EXTRACT(prot);
prot = PROT_EXTRACT(prot);
if (max_prot != 0 && (max_prot & prot) != prot) {
- return (EXTERROR(ENOTSUP, "prot is not subset of max_prot"));
+ return (EXTERROR(ENOTSUP,
+ "prot %#jx is not subset of max_prot %#jx",
+ prot, max_prot));
}
p = td->td_proc;
@@ -236,7 +238,7 @@
if ((len == 0 && p->p_osrel >= P_OSREL_MAP_ANON) ||
((flags & MAP_ANON) != 0 && (fd != -1 || pos != 0))) {
return (EXTERROR(EINVAL,
- "offset not zero/fd not -1 for MAP_ANON",
+ "offset %#jd not zero/fd %#jd not -1 for MAP_ANON",
fd, pos));
}
} else {
@@ -247,8 +249,8 @@
if (flags & MAP_STACK) {
if ((fd != -1) || ((prot & (PROT_READ | PROT_WRITE)) !=
(PROT_READ | PROT_WRITE))) {
- return (EXTERROR(EINVAL, "MAP_STACK with prot < rw",
- prot));
+ return (EXTERROR(EINVAL,
+ "MAP_STACK with prot %#jx < rw", prot));
}
flags |= MAP_ANON;
pos = 0;
@@ -257,18 +259,21 @@
MAP_STACK | MAP_NOSYNC | MAP_ANON | MAP_EXCL | MAP_NOCORE |
MAP_PREFAULT_READ | MAP_GUARD | MAP_32BIT |
MAP_ALIGNMENT_MASK)) != 0) {
- return (EXTERROR(EINVAL, "reserved flag set"));
+ return (EXTERROR(EINVAL, "reserved flag set (flags %#jx)",
+ flags));
}
if ((flags & (MAP_EXCL | MAP_FIXED)) == MAP_EXCL) {
- return (EXTERROR(EINVAL, "EXCL without FIXED"));
+ return (EXTERROR(EINVAL, "EXCL without FIXED (flags %#jx)",
+ flags));
}
if ((flags & (MAP_SHARED | MAP_PRIVATE)) == (MAP_SHARED |
MAP_PRIVATE)) {
- return (EXTERROR(EINVAL, "both SHARED and PRIVATE set"));
+ return (EXTERROR(EINVAL,
+ "both SHARED and PRIVATE set (flags %#jx)", flags));
}
if (prot != PROT_NONE &&
(prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) != 0) {
- return (EXTERROR(EINVAL, "invalid prot", prot));
+ return (EXTERROR(EINVAL, "invalid prot %#jx", prot));
}
if ((flags & MAP_GUARD) != 0 && (prot != PROT_NONE || fd != -1 ||
pos != 0 || (flags & ~(MAP_FIXED | MAP_GUARD | MAP_EXCL |
@@ -295,7 +300,7 @@
if (align != 0 && align != MAP_ALIGNED_SUPER &&
(align >> MAP_ALIGNMENT_SHIFT >= sizeof(void *) * NBBY ||
align >> MAP_ALIGNMENT_SHIFT < PAGE_SHIFT)) {
- return (EXTERROR(EINVAL, "bad alignment", align));
+ return (EXTERROR(EINVAL, "bad alignment %#jx", align));
}
/*
@@ -310,8 +315,8 @@
*/
addr -= pageoff;
if ((addr & PAGE_MASK) != 0) {
- return (EXTERROR(EINVAL, "fixed mapping not aligned",
- addr));
+ return (EXTERROR(EINVAL,
+ "fixed mapping at %#jx not aligned", addr));
}
/* Address range must be all in user VM space. */
@@ -321,7 +326,8 @@
}
if (flags & MAP_32BIT && addr + size > MAP_32BIT_MAX_ADDR) {
return (EXTERROR(EINVAL,
- "fixed 32bit mapping does not fit into 4G"));
+ "fixed 32bit mapping of [%#jx %#jx] does not fit into 4G",
+ addr, addr + size));
}
} else if (flags & MAP_32BIT) {
/*
@@ -1495,7 +1501,7 @@
handle, &foff, &object, &writecounted);
break;
default:
- error = EXTERROR(EINVAL, "unsupported backing obj type",
+ error = EXTERROR(EINVAL, "unsupported backing obj type %jd",
handle_type);
break;
}
@@ -1578,7 +1584,7 @@
* exec).
*/
if ((foff & PAGE_MASK) != 0) {
- return (EXTERROR(EINVAL, "offset not page-aligned", foff));
+ return (EXTERROR(EINVAL, "offset %#jx not page-aligned", foff));
}
if ((flags & MAP_FIXED) == 0) {
@@ -1587,7 +1593,8 @@
} else {
if (*addr != trunc_page(*addr)) {
return (EXTERROR(EINVAL,
- "non-fixed mapping address not aligned", *addr));
+ "non-fixed mapping address %#jx not aligned",
+ *addr));
}
fitit = false;
}
@@ -1599,7 +1606,7 @@
}
if (foff != 0) {
return (EXTERROR(EINVAL,
- "anon mapping with non-zero offset"));
+ "anon mapping with non-zero offset %#jx", foff));
}
docow = 0;
} else if (flags & MAP_PREFAULT_READ)
@@ -1702,6 +1709,6 @@
}
if ((curthread->td_pflags2 & (TDP2_UEXTERR | TDP2_EXTERR)) ==
TDP2_UEXTERR)
- EXTERROR(error, "mach error", rv);
+ EXTERROR(error, "mach error %jd", rv);
return (error);
}
diff --git a/tests/sys/kern/exterr_test.c b/tests/sys/kern/exterr_test.c
--- a/tests/sys/kern/exterr_test.c
+++ b/tests/sys/kern/exterr_test.c
@@ -51,7 +51,7 @@
ATF_CHECK_EQ(0, r);
printf("Extended error: %s\n", exterr);
/* Note: error string may need to be updated due to kernel changes */
- ATF_CHECK(strstr(exterr, "prot is not subset of max_prot") != 0);
+ ATF_CHECK(strstr(exterr, " is not subset of ") != 0);
}
ATF_TC(gettext_noextended);
diff --git a/tools/build/make_libc_exterr_cat_filenames.sh b/tools/build/make_libc_exterr_cat_filenames.sh
new file mode 100755
--- /dev/null
+++ b/tools/build/make_libc_exterr_cat_filenames.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+set -e
+
+check="lib/libc/gen/uexterr_format.c"
+target="lib/libc/gen/exterr_cat_filenames.h"
+
+if [ \! -f "${check}" ] ; then
+ echo "Script must be run from the top of the full source tree"
+ exit 1
+fi
+
+echo "/*" >"${target}"
+printf " * Automatically %sgenerated, use\\n" \@ >>"${target}"
+echo " * tools/build/make_libc_exterr_cat_filenames.sh" >>"${target}"
+echo " */" >>"${target}"
+
+(find sys -type f -name '*.c' | \
+ xargs grep -E '^#define[[:space:]]+EXTERR_CATEGORY[[:space:]]+EXTERR_CAT_' | \
+ sed -E 's/[[:space:]]+/:/g' | \
+ awk -F ':' '{filename = $1; sub(/^sys\//, "", filename);
+ printf("\t[%s] = \"%s\",\n", $4, filename)}') \
+ >>"${target}"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 23, 4:49 PM (10 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27887548
Default Alt Text
D54380.id168663.diff (12 KB)
Attached To
Mode
D54380: exterror: support %d in error messages
Attached
Detach File
Event Timeline
Log In to Comment