diff options
Diffstat (limited to 'lib')
34 files changed, 305 insertions, 182 deletions
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index 50dbf3425964..26f638568efc 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -458,8 +458,6 @@ FBSD_1.8 { aio_read2; aio_write2; execvpe; - fscandir; - fscandir_b; fdscandir; fdscandir_b; fts_open_b; @@ -598,7 +596,6 @@ FBSDprivate_1.0 { __libc_tcdrain; - __pthread_distribute_static_tls; __pthread_map_stacks_exec; __fillcontextx; __fillcontextx2; diff --git a/lib/libc/gen/elf_utils.c b/lib/libc/gen/elf_utils.c index 330aa8f17f7e..3714a0dc42b5 100644 --- a/lib/libc/gen/elf_utils.c +++ b/lib/libc/gen/elf_utils.c @@ -41,7 +41,6 @@ #include "libc_private.h" void __pthread_map_stacks_exec(void); -void __pthread_distribute_static_tls(size_t, void *, size_t, size_t); int __elf_phdr_match_addr(struct dl_phdr_info *phdr_info, void *addr) @@ -105,28 +104,3 @@ __pthread_map_stacks_exec(void) ((void (*)(void))__libc_interposing[INTERPOS_map_stacks_exec])(); } - -void -__libc_distribute_static_tls(size_t offset, void *src, size_t len, - size_t total_len) -{ - char *tlsbase; - -#ifdef TLS_VARIANT_I - tlsbase = (char *)_tcb_get() + offset; -#else - tlsbase = (char *)_tcb_get() - offset; -#endif - memcpy(tlsbase, src, len); - memset(tlsbase + len, 0, total_len - len); -} - -#pragma weak __pthread_distribute_static_tls -void -__pthread_distribute_static_tls(size_t offset, void *src, size_t len, - size_t total_len) -{ - - ((void (*)(size_t, void *, size_t, size_t))__libc_interposing[ - INTERPOS_distribute_static_tls])(offset, src, len, total_len); -} diff --git a/lib/libc/gen/err.c b/lib/libc/gen/err.c index cdce20af5a91..16cbe27693e7 100644 --- a/lib/libc/gen/err.c +++ b/lib/libc/gen/err.c @@ -119,7 +119,7 @@ vexterr(bool doexterr, int code, const char *fmt, va_list ap) fprintf(err_file, ": "); } fprintf(err_file, "%s", strerror(code)); - if (doexterr && extstatus == 0) + if (doexterr && extstatus == 0 && exterr[0] != '\0') fprintf(err_file, " (extended error %s)", exterr); fprintf(err_file, "\n"); } diff --git a/lib/libc/gen/fdopendir.c b/lib/libc/gen/fdopendir.c index 67c0766b6d83..df6709fbcb85 100644 --- a/lib/libc/gen/fdopendir.c +++ b/lib/libc/gen/fdopendir.c @@ -30,14 +30,13 @@ */ #include "namespace.h" -#include <sys/param.h> +#include <sys/types.h> +#include <sys/stat.h> #include <dirent.h> #include <errno.h> #include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> +#include <stdbool.h> #include "un-namespace.h" #include "gen-private.h" diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3 index 5860d1be1a1e..ee558b892c8c 100644 --- a/lib/libc/gen/fts.3 +++ b/lib/libc/gen/fts.3 @@ -394,7 +394,7 @@ must be specified. The options are selected by .Em or Ns 'ing the following values: -.Bl -tag -width "FTS_PHYSICAL" +.Bl -tag -width "FTS_COMFOLLOWDIR" .It Dv FTS_COMFOLLOW This option causes any symbolic link specified as a root path to be followed immediately whether or not diff --git a/lib/libc/gen/gen-private.h b/lib/libc/gen/gen-private.h index 3792a61ff942..b6749b3435cd 100644 --- a/lib/libc/gen/gen-private.h +++ b/lib/libc/gen/gen-private.h @@ -43,8 +43,8 @@ struct pthread_mutex; */ struct _dirdesc { int dd_fd; /* file descriptor associated with directory */ - long dd_loc; /* offset in current buffer */ - long dd_size; /* amount of data returned by getdirentries */ + size_t dd_loc; /* offset in current buffer */ + size_t dd_size; /* amount of data returned by getdirentries */ char *dd_buf; /* data buffer */ int dd_len; /* size of data buffer */ off_t dd_seek; /* magic cookie returned by getdirentries */ diff --git a/lib/libc/gen/libc_interposing_table.c b/lib/libc/gen/libc_interposing_table.c index 8eae6c7f5d95..025a67ac3eac 100644 --- a/lib/libc/gen/libc_interposing_table.c +++ b/lib/libc/gen/libc_interposing_table.c @@ -42,7 +42,6 @@ interpos_func_t __libc_interposing[INTERPOS_MAX] = { SLOT(spinlock, __libc_spinlock_stub), SLOT(spinunlock, __libc_spinunlock_stub), SLOT(map_stacks_exec, __libc_map_stacks_exec), - SLOT(distribute_static_tls, __libc_distribute_static_tls), SLOT(uexterr_gettext, __libc_uexterr_gettext), }; #undef SLOT diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c index 956c92c321e8..08d9eb10eaa2 100644 --- a/lib/libc/gen/opendir.c +++ b/lib/libc/gen/opendir.c @@ -30,14 +30,7 @@ */ #include "namespace.h" -#include <sys/param.h> - #include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> #include "un-namespace.h" #include "gen-private.h" diff --git a/lib/libc/gen/opendir2.c b/lib/libc/gen/opendir2.c index b9ac23e6d9fd..c5c2e662efd8 100644 --- a/lib/libc/gen/opendir2.c +++ b/lib/libc/gen/opendir2.c @@ -30,11 +30,12 @@ */ #include "namespace.h" -#include <sys/param.h> +#include <sys/types.h> #include <dirent.h> #include <errno.h> #include <fcntl.h> +#include <stdbool.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -52,8 +53,7 @@ __opendir2(const char *name, int flags) if ((flags & (__DTF_READALL | __DTF_SKIPREAD)) != 0) return (NULL); - if ((fd = _open(name, - O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC)) == -1) + if ((fd = _open(name, O_DIRECTORY | O_RDONLY | O_CLOEXEC)) == -1) return (NULL); dir = __opendir_common(fd, flags, false); @@ -264,6 +264,7 @@ DIR * __opendir_common(int fd, int flags, bool use_current_pos) { DIR *dirp; + ssize_t ret; int incr; int saved_errno; bool unionstack; @@ -313,13 +314,11 @@ __opendir_common(int fd, int flags, bool use_current_pos) * to prime dd_seek. This also checks if the * fd passed to fdopendir() is a directory. */ - dirp->dd_size = _getdirentries(dirp->dd_fd, + ret = _getdirentries(dirp->dd_fd, dirp->dd_buf, dirp->dd_len, &dirp->dd_seek); - if (dirp->dd_size < 0) { - if (errno == EINVAL) - errno = ENOTDIR; + if (ret < 0) goto fail; - } + dirp->dd_size = (size_t)ret; dirp->dd_flags |= __DTF_SKIPREAD; } else { dirp->dd_size = 0; diff --git a/lib/libc/gen/readdir.c b/lib/libc/gen/readdir.c index 2a2fa999b7ce..32603c0b4677 100644 --- a/lib/libc/gen/readdir.c +++ b/lib/libc/gen/readdir.c @@ -48,8 +48,8 @@ struct dirent * _readdir_unlocked(DIR *dirp, int flags) { struct dirent *dp; - long initial_seek; - long initial_loc = 0; + off_t initial_seek; + size_t initial_loc = 0; for (;;) { if (dirp->dd_loc >= dirp->dd_size) { diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c index 8e62fe980868..fb589f4b36b6 100644 --- a/lib/libc/gen/scandir.c +++ b/lib/libc/gen/scandir.c @@ -252,9 +252,3 @@ scandir_thunk_cmp(const void *p1, const void *p2, void *thunk) return (dc((const struct dirent **)p1, (const struct dirent **)p2)); } #endif - -#ifdef I_AM_SCANDIR_B -__weak_reference(fdscandir_b, fscandir_b); -#else -__weak_reference(fdscandir, fscandir); -#endif diff --git a/lib/libc/gen/telldir.c b/lib/libc/gen/telldir.c index b751fafd975f..1731cc4d7a2c 100644 --- a/lib/libc/gen/telldir.c +++ b/lib/libc/gen/telldir.c @@ -118,7 +118,7 @@ _seekdir(DIR *dirp, long loc) struct dirent *dp; union ddloc_packed ddloc; off_t loc_seek; - long loc_loc; + size_t loc_loc; ddloc.l = loc; @@ -171,7 +171,7 @@ _seekdir(DIR *dirp, long loc) * fetching a new block to fix any such telldir locations. */ void -_fixtelldir(DIR *dirp, long oldseek, long oldloc) +_fixtelldir(DIR *dirp, off_t oldseek, size_t oldloc) { struct ddloc_mem *lp; diff --git a/lib/libc/gen/telldir.h b/lib/libc/gen/telldir.h index 6d113491e819..02fd52af9060 100644 --- a/lib/libc/gen/telldir.h +++ b/lib/libc/gen/telldir.h @@ -46,9 +46,9 @@ */ struct ddloc_mem { LIST_ENTRY(ddloc_mem) loc_lqe; /* entry in list */ - long loc_index; /* key associated with structure */ + size_t loc_index; /* key associated with structure */ off_t loc_seek; /* magic cookie returned by getdirentries */ - long loc_loc; /* offset of entry in buffer */ + size_t loc_loc; /* offset of entry in buffer */ }; #ifdef __LP64__ @@ -102,7 +102,7 @@ bool _filldir(DIR *, bool); struct dirent *_readdir_unlocked(DIR *, int); void _reclaim_telldir(DIR *); void _seekdir(DIR *, long); -void _fixtelldir(DIR *dirp, long oldseek, long oldloc); +void _fixtelldir(DIR *dirp, off_t oldseek, size_t oldloc); DIR *__opendir_common(int, int, bool); #define RDU_SKIP 0x0001 diff --git a/lib/libc/gen/uexterr_format.c b/lib/libc/gen/uexterr_format.c index 86ba40234ae4..e8ddfbd578e3 100644 --- a/lib/libc/gen/uexterr_format.c +++ b/lib/libc/gen/uexterr_format.c @@ -20,7 +20,7 @@ __uexterr_format(const struct uexterror *ue, char *buf, size_t bufsz) if (bufsz > UEXTERROR_MAXLEN) bufsz = UEXTERROR_MAXLEN; if (ue->error == 0) { - strlcpy(buf, "No error", bufsz); + strlcpy(buf, "", bufsz); return (0); } if (ue->msg[0] == '\0') { diff --git a/lib/libc/gen/wordexp.c b/lib/libc/gen/wordexp.c index f1437e30bbe2..f8080c20d121 100644 --- a/lib/libc/gen/wordexp.c +++ b/lib/libc/gen/wordexp.c @@ -265,7 +265,15 @@ cleanup: errno = serrno; return (error); } - if (wpid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) + /* + * Check process exit status, but ignore ECHILD as the child may have + * been automatically reaped if the process had set SIG_IGN or + * SA_NOCLDWAIT for SIGCHLD, and our reason for waitpid was just to + * reap our own child on behalf of the calling process. + */ + if (wpid < 0 && errno != ECHILD) + return (WRDE_NOSPACE); /* abort for unknown reason */ + if (wpid >= 0 && (!WIFEXITED(status) || WEXITSTATUS(status) != 0)) return (WRDE_NOSPACE); /* abort for unknown reason */ /* diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index 1bc22f3931a5..db4cbc32be35 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -249,7 +249,7 @@ enum { INTERPOS_map_stacks_exec, INTERPOS_fdatasync, INTERPOS_clock_nanosleep, - INTERPOS_distribute_static_tls, + INTERPOS__reserved0, /* was distribute_static_tls */ INTERPOS_pdfork, INTERPOS_uexterr_gettext, INTERPOS_MAX @@ -361,8 +361,6 @@ struct dl_phdr_info; int __elf_phdr_match_addr(struct dl_phdr_info *, void *); void __init_elf_aux_vector(void); void __libc_map_stacks_exec(void); -void __libc_distribute_static_tls(__size_t, void *, __size_t, __size_t); -__uintptr_t __libc_static_tls_base(__size_t); void _pthread_cancel_enter(int); void _pthread_cancel_leave(int); diff --git a/lib/libc/stdio/mktemp.3 b/lib/libc/stdio/mktemp.3 index 2b8b2d6c9e44..8d38dd2cd57e 100644 --- a/lib/libc/stdio/mktemp.3 +++ b/lib/libc/stdio/mktemp.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 29, 2019 +.Dd July 07, 2025 .Dt MKTEMP 3 .Os .Sh NAME @@ -101,9 +101,10 @@ The permitted flags are .Dv O_DIRECT , .Dv O_SHLOCK , .Dv O_EXLOCK , -.Dv O_SYNC +.Dv O_SYNC , +.Dv O_CLOEXEC and -.Dv O_CLOEXEC . +.Dv O_CLOFORK . .Pp The .Fn mkstemps diff --git a/lib/libc/stdio/mktemp.c b/lib/libc/stdio/mktemp.c index 8aff226acf14..a2f80ee7b0dd 100644 --- a/lib/libc/stdio/mktemp.c +++ b/lib/libc/stdio/mktemp.c @@ -121,7 +121,7 @@ _gettemp(int dfd, char *path, int *doopen, int domkdir, int slen, int oflags) if ((doopen != NULL && domkdir) || slen < 0 || (oflags & ~(O_APPEND | O_DIRECT | O_SHLOCK | O_EXLOCK | O_SYNC | - O_CLOEXEC)) != 0) { + O_CLOEXEC | O_CLOFORK)) != 0) { errno = EINVAL; return (0); } diff --git a/lib/libc/tests/gen/Makefile b/lib/libc/tests/gen/Makefile index a967ad5ddf91..8c2151105209 100644 --- a/lib/libc/tests/gen/Makefile +++ b/lib/libc/tests/gen/Makefile @@ -20,6 +20,7 @@ ATF_TESTS_C+= glob2_test ATF_TESTS_C+= glob_blocks_test .endif ATF_TESTS_C+= makecontext_test +ATF_TESTS_C+= opendir_test ATF_TESTS_C+= popen_test ATF_TESTS_C+= posix_spawn_test ATF_TESTS_C+= realpath2_test diff --git a/lib/libc/tests/gen/opendir_test.c b/lib/libc/tests/gen/opendir_test.c new file mode 100644 index 000000000000..89be2becc607 --- /dev/null +++ b/lib/libc/tests/gen/opendir_test.c @@ -0,0 +1,144 @@ +/*- + * Copyright (c) 2025 Klara, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/stat.h> + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> + +#include <atf-c.h> + +/* + * Create a directory with a single subdirectory. + */ +static void +opendir_prepare(const struct atf_tc *tc) +{ + ATF_REQUIRE_EQ(0, mkdir("dir", 0755)); + ATF_REQUIRE_EQ(0, mkdir("dir/subdir", 0755)); +} + +/* + * Assuming dirp represents the directory created by opendir_prepare(), + * verify that readdir() returns what we expected to see there. + */ +static void +opendir_check(const struct atf_tc *tc, DIR *dirp) +{ + struct dirent *ent; + + ATF_REQUIRE((ent = readdir(dirp)) != NULL); + ATF_CHECK_EQ(1, ent->d_namlen); + ATF_CHECK_STREQ(".", ent->d_name); + ATF_CHECK_EQ(DT_DIR, ent->d_type); + ATF_REQUIRE((ent = readdir(dirp)) != NULL); + ATF_CHECK_EQ(2, ent->d_namlen); + ATF_CHECK_STREQ("..", ent->d_name); + ATF_CHECK_EQ(DT_DIR, ent->d_type); + ATF_REQUIRE((ent = readdir(dirp)) != NULL); + ATF_CHECK_EQ(sizeof("subdir") - 1, ent->d_namlen); + ATF_CHECK_STREQ("subdir", ent->d_name); + ATF_CHECK_EQ(DT_DIR, ent->d_type); + ATF_CHECK(readdir(dirp) == NULL); +} + +ATF_TC(opendir_ok); +ATF_TC_HEAD(opendir_ok, tc) +{ + atf_tc_set_md_var(tc, "descr", "Open a directory."); +} +ATF_TC_BODY(opendir_ok, tc) +{ + DIR *dirp; + + opendir_prepare(tc); + ATF_REQUIRE((dirp = opendir("dir")) != NULL); + opendir_check(tc, dirp); + ATF_CHECK_EQ(0, closedir(dirp)); +} + +ATF_TC(opendir_fifo); +ATF_TC_HEAD(opendir_fifo, tc) +{ + atf_tc_set_md_var(tc, "descr", "Do not hang if given a named pipe."); +} +ATF_TC_BODY(opendir_fifo, tc) +{ + DIR *dirp; + int fd; + + ATF_REQUIRE((fd = mkfifo("fifo", 0644)) >= 0); + ATF_REQUIRE_EQ(0, close(fd)); + ATF_REQUIRE((dirp = opendir("fifo")) == NULL); + ATF_CHECK_EQ(ENOTDIR, errno); +} + +ATF_TC(fdopendir_ok); +ATF_TC_HEAD(fdopendir_ok, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Open a directory from a directory descriptor."); +} +ATF_TC_BODY(fdopendir_ok, tc) +{ + DIR *dirp; + int dd; + + opendir_prepare(tc); + ATF_REQUIRE((dd = open("dir", O_DIRECTORY | O_RDONLY)) >= 0); + ATF_REQUIRE((dirp = fdopendir(dd)) != NULL); + opendir_check(tc, dirp); + ATF_CHECK_EQ(dd, fdclosedir(dirp)); + ATF_CHECK_EQ(0, close(dd)); +} + +ATF_TC(fdopendir_ebadf); +ATF_TC_HEAD(fdopendir_ebadf, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Open a directory from an invalid descriptor."); +} +ATF_TC_BODY(fdopendir_ebadf, tc) +{ + DIR *dirp; + int dd; + + ATF_REQUIRE_EQ(0, mkdir("dir", 0755)); + ATF_REQUIRE((dd = open("dir", O_DIRECTORY | O_RDONLY)) >= 0); + ATF_CHECK_EQ(0, close(dd)); + ATF_REQUIRE((dirp = fdopendir(dd)) == NULL); + ATF_CHECK_EQ(EBADF, errno); +} + +ATF_TC(fdopendir_enotdir); +ATF_TC_HEAD(fdopendir_enotdir, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Open a directory from a non-directory descriptor."); +} +ATF_TC_BODY(fdopendir_enotdir, tc) +{ + DIR *dirp; + int fd; + + ATF_REQUIRE((fd = open("file", O_CREAT | O_RDWR, 0644)) >= 0); + ATF_REQUIRE((dirp = fdopendir(fd)) == NULL); + ATF_CHECK_EQ(ENOTDIR, errno); + ATF_CHECK_EQ(0, close(fd)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, opendir_ok); + ATF_TP_ADD_TC(tp, fdopendir_ok); + ATF_TP_ADD_TC(tp, fdopendir_ebadf); + ATF_TP_ADD_TC(tp, fdopendir_enotdir); + ATF_TP_ADD_TC(tp, opendir_fifo); + return (atf_no_error()); +} diff --git a/lib/libc/tests/gen/wordexp_test.c b/lib/libc/tests/gen/wordexp_test.c index 909097fbf51e..a8b9d5509633 100644 --- a/lib/libc/tests/gen/wordexp_test.c +++ b/lib/libc/tests/gen/wordexp_test.c @@ -292,6 +292,31 @@ ATF_TC_BODY(with_SIGCHILD_handler_test, tc) ATF_REQUIRE(r == 0); } +ATF_TC_WITHOUT_HEAD(with_SIGCHILD_ignore_test); +ATF_TC_BODY(with_SIGCHILD_ignore_test, tc) +{ + struct sigaction sa; + wordexp_t we; + int r; + + /* With SIGCHLD set to ignore so that the kernel auto-reaps zombies. */ + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_IGN; + r = sigaction(SIGCHLD, &sa, NULL); + ATF_REQUIRE(r == 0); + r = wordexp("hello world", &we, 0); + ATF_REQUIRE(r == 0); + ATF_REQUIRE(we.we_wordc == 2); + ATF_REQUIRE(strcmp(we.we_wordv[0], "hello") == 0); + ATF_REQUIRE(strcmp(we.we_wordv[1], "world") == 0); + ATF_REQUIRE(we.we_wordv[2] == NULL); + wordfree(&we); + sa.sa_handler = SIG_DFL; + r = sigaction(SIGCHLD, &sa, NULL); + ATF_REQUIRE(r == 0); +} + ATF_TC_WITHOUT_HEAD(with_unused_non_default_IFS_test); ATF_TC_BODY(with_unused_non_default_IFS_test, tc) { @@ -350,6 +375,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, WRDE_BADCHAR_test); ATF_TP_ADD_TC(tp, WRDE_SYNTAX_test); ATF_TP_ADD_TC(tp, with_SIGCHILD_handler_test); + ATF_TP_ADD_TC(tp, with_SIGCHILD_ignore_test); ATF_TP_ADD_TC(tp, with_unused_non_default_IFS_test); ATF_TP_ADD_TC(tp, with_used_non_default_IFS_test); diff --git a/lib/libnvmf/libnvmf.h b/lib/libnvmf/libnvmf.h index 9840e190a24f..7cdd7e433455 100644 --- a/lib/libnvmf/libnvmf.h +++ b/lib/libnvmf/libnvmf.h @@ -342,7 +342,8 @@ int nvmf_host_request_queues(struct nvmf_qpair *qp, u_int requested, */ int nvmf_handoff_host(const struct nvme_discovery_log_entry *dle, const char *hostnqn, struct nvmf_qpair *admin_qp, u_int num_queues, - struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata); + struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata, + uint32_t reconnect_delay, uint32_t controller_loss_timeout); /* * Disconnect an active host association previously handed off to the @@ -370,7 +371,8 @@ int nvmf_reconnect_params(int fd, nvlist_t **nvlp); */ int nvmf_reconnect_host(int fd, const struct nvme_discovery_log_entry *dle, const char *hostnqn, struct nvmf_qpair *admin_qp, u_int num_queues, - struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata); + struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata, + uint32_t reconnect_delay, uint32_t controller_loss_timeout); /* * Fetch connection status from an existing kernel host. diff --git a/lib/libnvmf/nvmf_host.c b/lib/libnvmf/nvmf_host.c index 89cdd5c6bb70..3266f8898296 100644 --- a/lib/libnvmf/nvmf_host.c +++ b/lib/libnvmf/nvmf_host.c @@ -792,7 +792,8 @@ static int prepare_queues_for_handoff(struct nvmf_ioc_nv *nv, const struct nvme_discovery_log_entry *dle, const char *hostnqn, struct nvmf_qpair *admin_qp, u_int num_queues, - struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata) + struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata, + uint32_t reconnect_delay, uint32_t controller_loss_timeout) { const struct nvmf_association *na = admin_qp->nq_association; nvlist_t *nvl, *nvl_qp, *nvl_rparams; @@ -820,6 +821,9 @@ prepare_queues_for_handoff(struct nvmf_ioc_nv *nv, nvlist_add_string(nvl_rparams, "hostnqn", hostnqn); nvlist_add_number(nvl_rparams, "num_io_queues", num_queues); nvlist_add_number(nvl_rparams, "kato", admin_qp->nq_kato); + nvlist_add_number(nvl_rparams, "reconnect_delay", reconnect_delay); + nvlist_add_number(nvl_rparams, "controller_loss_timeout", + controller_loss_timeout); nvlist_add_number(nvl_rparams, "io_qsize", io_queues[0]->nq_qsize); nvlist_add_bool(nvl_rparams, "sq_flow_control", na->na_params.sq_flow_control); @@ -842,6 +846,9 @@ prepare_queues_for_handoff(struct nvmf_ioc_nv *nv, nvl = nvlist_create(0); nvlist_add_number(nvl, "trtype", na->na_trtype); nvlist_add_number(nvl, "kato", admin_qp->nq_kato); + nvlist_add_number(nvl, "reconnect_delay", reconnect_delay); + nvlist_add_number(nvl, "controller_loss_timeout", + controller_loss_timeout); nvlist_move_nvlist(nvl, "rparams", nvl_rparams); /* First, the admin queue. */ @@ -872,7 +879,8 @@ prepare_queues_for_handoff(struct nvmf_ioc_nv *nv, int nvmf_handoff_host(const struct nvme_discovery_log_entry *dle, const char *hostnqn, struct nvmf_qpair *admin_qp, u_int num_queues, - struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata) + struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata, + uint32_t reconnect_delay, uint32_t controller_loss_timeout) { struct nvmf_ioc_nv nv; u_int i; @@ -885,7 +893,8 @@ nvmf_handoff_host(const struct nvme_discovery_log_entry *dle, } error = prepare_queues_for_handoff(&nv, dle, hostnqn, admin_qp, - num_queues, io_queues, cdata); + num_queues, io_queues, cdata, reconnect_delay, + controller_loss_timeout); if (error != 0) goto out; @@ -981,14 +990,16 @@ nvmf_reconnect_params(int fd, nvlist_t **nvlp) int nvmf_reconnect_host(int fd, const struct nvme_discovery_log_entry *dle, const char *hostnqn, struct nvmf_qpair *admin_qp, u_int num_queues, - struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata) + struct nvmf_qpair **io_queues, const struct nvme_controller_data *cdata, + uint32_t reconnect_delay, uint32_t controller_loss_timeout) { struct nvmf_ioc_nv nv; u_int i; int error; error = prepare_queues_for_handoff(&nv, dle, hostnqn, admin_qp, - num_queues, io_queues, cdata); + num_queues, io_queues, cdata, reconnect_delay, + controller_loss_timeout); if (error != 0) goto out; diff --git a/lib/libsys/fcntl.2 b/lib/libsys/fcntl.2 index 3cf8adc29f88..d67c38cfbc6c 100644 --- a/lib/libsys/fcntl.2 +++ b/lib/libsys/fcntl.2 @@ -577,7 +577,7 @@ A new file descriptor. A file descriptor equal to .Fa arg . .It Dv F_GETFD -Value of flag (only the low-order bit is defined). +Value of flags. .It Dv F_GETFL Value of flags. .It Dv F_GETOWN diff --git a/lib/libsys/getdirentries.2 b/lib/libsys/getdirentries.2 index 0e5840ce25cd..202ae133f548 100644 --- a/lib/libsys/getdirentries.2 +++ b/lib/libsys/getdirentries.2 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 5, 2023 +.Dd July 8, 2025 .Dt GETDIRENTRIES 2 .Os .Sh NAME @@ -178,9 +178,7 @@ or non-NULL .Fa basep point outside the allocated address space. .It Bq Er EINVAL -The file referenced by -.Fa fd -is not a directory, or +The value of .Fa nbytes is too small for returning a directory entry or block of entries, or the current position pointer is invalid. @@ -192,6 +190,10 @@ error occurred while reading from or writing to the file system. Corrupted data was detected while reading from the file system. .It Bq Er ENOENT Directory unlinked but still open. +.It Bq Er ENOTDIR +The file referenced by +.Fa fd +is not a directory. .El .Sh SEE ALSO .Xr lseek 2 , diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map index 1c8dde03367b..3a5353a32dc3 100644 --- a/lib/libthr/pthread.map +++ b/lib/libthr/pthread.map @@ -136,7 +136,6 @@ FBSDprivate_1.0 { __pthread_mutex_lock; __pthread_mutex_timedlock; __pthread_mutex_trylock; - __pthread_distribute_static_tls; _pthread_atfork; _pthread_barrier_destroy; _pthread_barrier_init; diff --git a/lib/libthr/thread/thr_list.c b/lib/libthr/thread/thr_list.c index 820766f6f5e0..cbf16179f619 100644 --- a/lib/libthr/thread/thr_list.c +++ b/lib/libthr/thread/thr_list.c @@ -363,41 +363,3 @@ _thr_find_thread(struct pthread *curthread, struct pthread *thread, THREAD_LIST_UNLOCK(curthread); return (ret); } - -static void -thr_distribute_static_tls(char *tlsbase, void *src, size_t len, - size_t total_len) -{ - - memcpy(tlsbase, src, len); - memset(tlsbase + len, 0, total_len - len); -} - -void -__pthread_distribute_static_tls(size_t offset, void *src, size_t len, - size_t total_len) -{ - struct pthread *curthread, *thrd; - char *tlsbase; - - if (!_thr_is_inited()) { -#ifdef TLS_VARIANT_I - tlsbase = (char *)_tcb_get() + offset; -#else - tlsbase = (char *)_tcb_get() - offset; -#endif - thr_distribute_static_tls(tlsbase, src, len, total_len); - return; - } - curthread = _get_curthread(); - THREAD_LIST_RDLOCK(curthread); - TAILQ_FOREACH(thrd, &_thread_list, tle) { -#ifdef TLS_VARIANT_I - tlsbase = (char *)thrd->tcb + offset; -#else - tlsbase = (char *)thrd->tcb - offset; -#endif - thr_distribute_static_tls(tlsbase, src, len, total_len); - } - THREAD_LIST_UNLOCK(curthread); -} diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index bca890829057..d7b889930365 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -986,8 +986,6 @@ void __pthread_cxa_finalize(struct dl_phdr_info *phdr_info); void _thr_tsd_unload(struct dl_phdr_info *phdr_info) __hidden; void _thr_sigact_unload(struct dl_phdr_info *phdr_info) __hidden; void _thr_stack_fix_protection(struct pthread *thrd); -void __pthread_distribute_static_tls(size_t offset, void *src, size_t len, - size_t total_len); int *__error_threaded(void) __hidden; void __thr_interpose_libc(void) __hidden; diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h index 0aad29aa4ecc..17d341d1b91c 100644 --- a/lib/libusb/libusb.h +++ b/lib/libusb/libusb.h @@ -243,17 +243,6 @@ enum libusb_log_level { LIBUSB_LOG_LEVEL_DEBUG }; -/* XXX */ -/* libusb_set_debug should take parameters from libusb_log_level - * above according to - * https://libusb.sourceforge.io/api-1.0/group__libusb__lib.html - */ -enum libusb_debug_level { - LIBUSB_DEBUG_NO=0, - LIBUSB_DEBUG_FUNCTION=1, - LIBUSB_DEBUG_TRANSFER=2, -}; - #define LIBUSB_HOTPLUG_MATCH_ANY -1 typedef enum { @@ -418,7 +407,10 @@ typedef struct libusb_bos_descriptor { uint8_t bLength; uint8_t bDescriptorType; uint16_t wTotalLength; - uint8_t bNumDeviceCapabilities; +#ifndef bNumDeviceCapabilities +#define bNumDeviceCapabilities bNumDeviceCaps +#endif + uint8_t bNumDeviceCaps; struct libusb_usb_2_0_device_capability_descriptor *usb_2_0_ext_cap; struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap; struct libusb_bos_dev_capability_descriptor **dev_capability; diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c index 3e81f234a735..173f51aa88b3 100644 --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -35,6 +35,7 @@ #include <poll.h> #include <pthread.h> #include <signal.h> +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -48,6 +49,7 @@ #endif #define libusb_device_handle libusb20_device +#define LIBUSB_LOG_BUFFER_SIZE 1024 #include "libusb20.h" #include "libusb20_desc.h" @@ -128,7 +130,7 @@ libusb_interrupt_event_handler(libusb_context *ctx) err = eventfd_write(ctx->event, 1); if (err < 0) { /* ignore error, if any */ - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "Waking up event loop failed!"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_ERROR, "Waking up event loop failed!"); } } @@ -253,7 +255,7 @@ libusb_init_context(libusb_context **context, if (context) *context = ctx; - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_init complete"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_INFO, "libusb_init complete"); signal(SIGPIPE, SIG_IGN); @@ -625,7 +627,7 @@ libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id, if (ctx == NULL) return (NULL); /* be NULL safe */ - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_with_vid_pid enter"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_open_device_with_vid_pid enter"); if ((i = libusb_get_device_list(ctx, &devs)) < 0) return (NULL); @@ -649,7 +651,7 @@ libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id, } libusb_free_device_list(devs, 1); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_with_vid_pid leave"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_open_device_with_vid_pid leave"); return (pdev); } @@ -1536,7 +1538,7 @@ libusb_submit_transfer(struct libusb_transfer *uxfer) dev = libusb_get_device(uxfer->dev_handle); - DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer enter"); + DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_submit_transfer enter"); sxfer = (struct libusb_super_transfer *)( (uint8_t *)uxfer - sizeof(*sxfer)); @@ -1571,7 +1573,7 @@ libusb_submit_transfer(struct libusb_transfer *uxfer) CTX_UNLOCK(dev->ctx); - DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer leave %d", err); + DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_submit_transfer leave %d", err); return (err); } @@ -1600,7 +1602,7 @@ libusb_cancel_transfer(struct libusb_transfer *uxfer) dev = libusb_get_device(devh); - DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter"); + DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_cancel_transfer enter"); sxfer = (struct libusb_super_transfer *)( (uint8_t *)uxfer - sizeof(*sxfer)); @@ -1661,7 +1663,7 @@ libusb_cancel_transfer(struct libusb_transfer *uxfer) CTX_UNLOCK(dev->ctx); - DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave"); + DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_cancel_transfer leave"); return (retval); } @@ -1811,3 +1813,32 @@ libusb_has_capability(uint32_t capability) return (0); } } + +void +libusb_log_va_args(struct libusb_context *ctx, enum libusb_log_level level, + const char *fmt, ...) +{ + static const char *log_prefix[5] = { + [LIBUSB_LOG_LEVEL_ERROR] = "LIBUSB_ERROR", + [LIBUSB_LOG_LEVEL_WARNING] = "LIBUSB_WARN", + [LIBUSB_LOG_LEVEL_INFO] = "LIBUSB_INFO", + [LIBUSB_LOG_LEVEL_DEBUG] = "LIBUSB_DEBUG", + }; + + char buffer[LIBUSB_LOG_BUFFER_SIZE]; + char new_fmt[LIBUSB_LOG_BUFFER_SIZE]; + va_list args; + + ctx = GET_CONTEXT(ctx); + + if (ctx->debug < level) + return; + + va_start(args, fmt); + + snprintf(new_fmt, sizeof(new_fmt), "%s: %s\n", log_prefix[level], fmt); + vsnprintf(buffer, sizeof(buffer), new_fmt, args); + fputs(buffer, stdout); + + va_end(args); +} diff --git a/lib/libusb/libusb10.h b/lib/libusb/libusb10.h index 70b5525df537..9ad08edf075b 100644 --- a/lib/libusb/libusb10.h +++ b/lib/libusb/libusb10.h @@ -29,6 +29,7 @@ #define __LIBUSB10_H__ #ifndef LIBUSB_GLOBAL_INCLUDE_FILE +#include <sys/cdefs.h> #include <sys/queue.h> #include <netlink/netlink.h> #include <netlink/netlink_generic.h> @@ -46,24 +47,11 @@ #define HOTPLUG_LOCK(ctx) pthread_mutex_lock(&(ctx)->hotplug_lock) #define HOTPLUG_UNLOCK(ctx) pthread_mutex_unlock(&(ctx)->hotplug_lock) -#define DPRINTF(ctx, dbg, format, ...) do { \ - switch (dbg) { \ - case LIBUSB_DEBUG_FUNCTION: \ - if ((ctx)->debug & LIBUSB_DEBUG_FUNCTION) { \ - printf("LIBUSB_FUNCTION: " \ - format "\n", ## __VA_ARGS__); \ - } \ - break; \ - case LIBUSB_DEBUG_TRANSFER: \ - if ((ctx)->debug & LIBUSB_DEBUG_TRANSFER) { \ - printf("LIBUSB_TRANSFER: " \ - format "\n", ## __VA_ARGS__); \ - } \ - break; \ - default: \ - break; \ - } \ -} while (0) +void libusb_log_va_args(struct libusb_context *ctx, enum libusb_log_level level, + const char *fmt, ...) __printflike(3, 4); + +#define DPRINTF(ctx, dbg, format, ...) \ + libusb_log_va_args(ctx, dbg, format, ##__VA_ARGS__) /* internal structures */ diff --git a/lib/libusb/libusb10_desc.c b/lib/libusb/libusb10_desc.c index 3e36009cbb3a..5f4c46740688 100644 --- a/lib/libusb/libusb10_desc.c +++ b/lib/libusb/libusb10_desc.c @@ -470,10 +470,11 @@ libusb_parse_bos_descriptor(const void *buf, int len, ptr->bDescriptorType = dtype; ptr->wTotalLength = ((const uint8_t *)buf)[2] | (((const uint8_t *)buf)[3] << 8); - ptr->bNumDeviceCapabilities = ((const uint8_t *)buf)[4]; + ptr->bNumDeviceCaps = ((const uint8_t *)buf)[4]; ptr->usb_2_0_ext_cap = NULL; ptr->ss_usb_cap = NULL; - ptr->dev_capability = calloc(ptr->bNumDeviceCapabilities, sizeof(void *)); + ptr->dev_capability = calloc(ptr->bNumDeviceCaps, + sizeof(void *)); if (ptr->dev_capability == NULL) { free(ptr); return (LIBUSB_ERROR_NO_MEM); @@ -485,7 +486,7 @@ libusb_parse_bos_descriptor(const void *buf, int len, if (dlen >= 3 && ptr != NULL && dtype == LIBUSB_DT_DEVICE_CAPABILITY) { - if (index != ptr->bNumDeviceCapabilities) { + if (index != ptr->bNumDeviceCaps) { ptr->dev_capability[index] = malloc(dlen); if (ptr->dev_capability[index] == NULL) { libusb_free_bos_descriptor(ptr); @@ -542,7 +543,7 @@ libusb_parse_bos_descriptor(const void *buf, int len, } if (ptr != NULL) { - ptr->bNumDeviceCapabilities = index; + ptr->bNumDeviceCaps = index; return (0); /* success */ } @@ -557,7 +558,7 @@ libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos) if (bos == NULL) return; - for (i = 0; i != bos->bNumDeviceCapabilities; i++) + for (i = 0; i != bos->bNumDeviceCaps; i++) free(bos->dev_capability[i]); free(bos->dev_capability); free(bos); diff --git a/lib/libusb/libusb10_io.c b/lib/libusb/libusb10_io.c index f1e31c2a7416..dd541b09caa6 100644 --- a/lib/libusb/libusb10_io.c +++ b/lib/libusb/libusb10_io.c @@ -108,7 +108,7 @@ libusb10_handle_events_sub(struct libusb_context *ctx, struct timeval *tv) int i; int err; - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb10_handle_events_sub enter"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb10_handle_events_sub enter"); nfds = 0; i = 0; @@ -230,7 +230,7 @@ do_done: /* Wakeup other waiters */ pthread_cond_broadcast(&ctx->ctx_cond); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb10_handle_events_sub complete"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb10_handle_events_sub complete"); return (err); } @@ -314,7 +314,7 @@ libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) int err; ctx = GET_CONTEXT(ctx); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_wait_for_event enter"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_wait_for_event enter"); if (tv == NULL) { pthread_cond_wait(&ctx->ctx_cond, @@ -358,7 +358,7 @@ libusb_handle_events_timeout_completed(libusb_context *ctx, ctx = GET_CONTEXT(ctx); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout_completed enter"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_handle_events_timeout_completed enter"); libusb_lock_events(ctx); @@ -374,7 +374,7 @@ libusb_handle_events_timeout_completed(libusb_context *ctx, libusb_unlock_events(ctx); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout_completed exit"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_handle_events_timeout_completed exit"); return (err); } @@ -523,7 +523,7 @@ libusb10_do_transfer_cb(struct libusb_transfer *transfer) ctx = libusb10_get_context_by_device_handle(transfer->dev_handle); - DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "sync I/O done"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "sync I/O done"); pdone = transfer->user_data; *pdone = 1; @@ -613,12 +613,12 @@ libusb_bulk_transfer(libusb_device_handle *devh, ctx = libusb10_get_context_by_device_handle(devh); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer enter"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_bulk_transfer enter"); ret = libusb10_do_transfer(devh, endpoint, data, length, transferred, timeout, LIBUSB_TRANSFER_TYPE_BULK); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer leave"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_bulk_transfer leave"); return (ret); } @@ -632,12 +632,12 @@ libusb_interrupt_transfer(libusb_device_handle *devh, ctx = libusb10_get_context_by_device_handle(devh); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer enter"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_interrupt_transfer enter"); ret = libusb10_do_transfer(devh, endpoint, data, length, transferred, timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT); - DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer leave"); + DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_interrupt_transfer leave"); return (ret); } diff --git a/lib/libusb/libusb20_desc.h b/lib/libusb/libusb20_desc.h index 017148a34b1c..0f7c9294ebc8 100644 --- a/lib/libusb/libusb20_desc.h +++ b/lib/libusb/libusb20_desc.h @@ -298,11 +298,15 @@ LIBUSB20_MAKE_STRUCT(LIBUSB20_USB_20_DEVCAP_DESC); LIBUSB20_MAKE_STRUCT(LIBUSB20_SS_USB_DEVCAP_DESC); +#ifndef bNumDeviceCapabilities +#define bNumDeviceCapabilities bNumDeviceCaps +#endif + #define LIBUSB20_BOS_DESCRIPTOR(m,n) \ m(n, UINT8_T, bLength, ) \ m(n, UINT8_T, bDescriptorType, ) \ m(n, UINT16_T, wTotalLength, ) \ - m(n, UINT8_T, bNumDeviceCapabilities, ) \ + m(n, UINT8_T, bNumDeviceCaps, ) \ LIBUSB20_MAKE_STRUCT(LIBUSB20_BOS_DESCRIPTOR); |