diff options
Diffstat (limited to 'lib9p')
-rw-r--r-- | lib9p/include/lib9p/9p.generated.h | 2 | ||||
-rw-r--r-- | lib9p/include/lib9p/9p.h | 2 | ||||
-rw-r--r-- | lib9p/include/lib9p/linux-errno.h | 2 | ||||
-rw-r--r-- | lib9p/include/lib9p/srv.h | 2 | ||||
-rwxr-xr-x | lib9p/linux-errno.txt.gen | 17 | ||||
-rw-r--r-- | lib9p/protogen/h.py | 2 | ||||
-rw-r--r-- | lib9p/srv.c | 3 | ||||
-rw-r--r-- | lib9p/tables.c | 8 | ||||
-rwxr-xr-x | lib9p/tests/runtest | 6 | ||||
-rw-r--r-- | lib9p/tests/test_server/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_shutdown.c | 93 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_shutdown.h | 23 | ||||
-rw-r--r-- | lib9p/tests/test_server/main.c | 102 |
13 files changed, 160 insertions, 103 deletions
diff --git a/lib9p/include/lib9p/9p.generated.h b/lib9p/include/lib9p/9p.generated.h index 7e901a3..afd89ed 100644 --- a/lib9p/include/lib9p/9p.generated.h +++ b/lib9p/include/lib9p/9p.generated.h @@ -7,7 +7,7 @@ #include <stdint.h> /* for uint{n}_t types */ #include <libfmt/fmt.h> /* for fmt_formatter */ -#include <libhw/generic/net.h> /* for struct iovec */ +#include <libhw/generic/io.h> /* for struct iovec */ /* config *********************************************************************/ diff --git a/lib9p/include/lib9p/9p.h b/lib9p/include/lib9p/9p.h index 5919260..42381cf 100644 --- a/lib9p/include/lib9p/9p.h +++ b/lib9p/include/lib9p/9p.h @@ -166,7 +166,7 @@ static inline void lib9p_stat_assert(struct lib9p_stat stat) { * @return whether there was an error */ bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, - uint32_t *ret_net_size, ssize_t *ret_host_size); + uint32_t *ret_net_size, size_t *ret_host_size); /** * Unmarshal the 9P `net_bytes` into the C struct `ret_obj`. diff --git a/lib9p/include/lib9p/linux-errno.h b/lib9p/include/lib9p/linux-errno.h index e7c74f5..e864fb6 100644 --- a/lib9p/include/lib9p/linux-errno.h +++ b/lib9p/include/lib9p/linux-errno.h @@ -1,5 +1,5 @@ /* lib9p/linux-errno.h - Generated by `lib9p/include/lib9p/linux-errno.h.gen 3rd-party/linux-errno.txt`. DO NOT EDIT! */ -/* 3rd-party/linux-errno.txt - Generated from build-aux/linux-errno.txt.gen and linux.git v6.7. DO NOT EDIT! */ +/* 3rd-party/linux-errno.txt - Generated from lib9p/linux-errno.txt.gen and linux.git v6.14. DO NOT EDIT! */ #ifndef _LIB9P_LINUX_ERRNO_H_ #define _LIB9P_LINUX_ERRNO_H_ diff --git a/lib9p/include/lib9p/srv.h b/lib9p/include/lib9p/srv.h index ec47142..7ad1b19 100644 --- a/lib9p/include/lib9p/srv.h +++ b/lib9p/include/lib9p/srv.h @@ -33,7 +33,7 @@ struct lib9p_srv_ctx { bool lib9p_srv_flush_requested(struct lib9p_srv_ctx *ctx); -int lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx); +void lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx); /* interface definitions ******************************************************/ diff --git a/lib9p/linux-errno.txt.gen b/lib9p/linux-errno.txt.gen new file mode 100755 index 0000000..687e58b --- /dev/null +++ b/lib9p/linux-errno.txt.gen @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# lib9p/linux-errno.txt.gen - Generate a listing of Linux kernel errnos +# +# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> +# SPDX-License-Identifier: AGPL-3.0-or-later + +set -e +linux_git=${1:?} +outfile=${2:?} + +( + cd "${linux_git}" + echo "# ${outfile} - Generated from $0 and linux.git $(git describe). DO NOT EDIT!" + git ls-files include/uapi/ | grep errno | + xargs sed -nE 's,#\s*define\s+(E[A-Z0-9]+)\s+([0-9]+)\s+/\* (.*) \*/,\2 \1 \3,p' | + sort --numeric-sort +) >"${outfile}" diff --git a/lib9p/protogen/h.py b/lib9p/protogen/h.py index 3b33419..8f7fba2 100644 --- a/lib9p/protogen/h.py +++ b/lib9p/protogen/h.py @@ -166,7 +166,7 @@ def gen_h(versions: set[str], typs: list[idl.UserType]) -> str: #include <stdint.h> /* for uint{{n}}_t types */ #include <libfmt/fmt.h> /* for fmt_formatter */ -#include <libhw/generic/net.h> /* for struct iovec */ +#include <libhw/generic/io.h> /* for struct iovec */ """ id2typ: dict[int, idl.Message] = {} diff --git a/lib9p/srv.c b/lib9p/srv.c index 60a1bb0..b3b9c4c 100644 --- a/lib9p/srv.c +++ b/lib9p/srv.c @@ -57,12 +57,11 @@ bool lib9p_srv_flush_requested(struct lib9p_srv_ctx *ctx) { return _lib9p_srv_flushch_can_send(&ctx->_flushch); } -int lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx) { +void lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx) { assert(ctx); assert(_lib9p_srv_flushch_can_send(&ctx->_flushch)); lib9p_error(&ctx->basectx, LINUX_ECANCELED, "request canceled by flush"); _lib9p_srv_flushch_send(&ctx->_flushch, true); - return -1; } /* structs ********************************************************************/ diff --git a/lib9p/tables.c b/lib9p/tables.c index 271b17b..86e3298 100644 --- a/lib9p/tables.c +++ b/lib9p/tables.c @@ -96,6 +96,7 @@ void _lib9p_unmarshal(const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0 enum lib9p_msg_type typ = net_bytes[4]; *ret_typ = typ; struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2]; + assert(tentry.unmarshal); tentry.unmarshal(ctx, net_bytes, ret_body); } @@ -124,8 +125,9 @@ bool _lib9p_marshal(const struct _lib9p_send_tentry xxx_table[LIB9P_VER_NUM][0x8 .net_copied_size = 0, .net_copied = ret_copied, }; - struct _lib9p_send_tentry tentry = xxx_table[ctx->version][typ/2]; + assert(tentry.marshal); + bool ret_erred = tentry.marshal(ctx, body, &ret); if (ret_iov[ret.net_iov_cnt-1].iov_len == 0) ret.net_iov_cnt--; @@ -154,12 +156,12 @@ bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *bo /* `struct lib9p_stat` helpers ************************************************/ bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, - uint32_t *ret_net_size, ssize_t *ret_host_size) { + uint32_t *ret_net_size, size_t *ret_host_size) { ssize_t host_size = _lib9p_stat_validate(ctx, net_size, net_bytes, ret_net_size); if (host_size < 0) return true; if (ret_host_size) - *ret_host_size = host_size; + *ret_host_size = (size_t)host_size; return false; } diff --git a/lib9p/tests/runtest b/lib9p/tests/runtest index 379ea6d..fb66a43 100755 --- a/lib9p/tests/runtest +++ b/lib9p/tests/runtest @@ -7,8 +7,10 @@ set -euE -o pipefail set -x +build_aux=$(realpath --canonicalize-missing -- "${BASH_SOURCE[0]}/../../../build-aux") + port=$(python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()') -valgrind --error-exitcode=2 ./tests/test_server/test_server "$port" & +"${build_aux}/valgrind" ./tests/test_server/test_server "$port" & server_pid=$! # shellcheck disable=SC2064 trap "kill $server_pid || true; wait $server_pid || true" EXIT @@ -22,7 +24,7 @@ expect_lines() ( diff -u <(printf '%s\n' "$@") <(printf '%s\n' "$out") ) -while [[ -d /proc/$server_pid && "$(readlink /proc/$server_pid/fd/4 2>/dev/null)" != socket:* ]]; do sleep 0.1; done +while [[ -d /proc/$server_pid ]] && ! (readlink /proc/$server_pid/fd/* 2>/dev/null | grep -q ^socket:); do sleep 0.1; done out=$("${client[@]}" ls -l '') expect_lines \ diff --git a/lib9p/tests/test_server/CMakeLists.txt b/lib9p/tests/test_server/CMakeLists.txt index 5313917..19c8edb 100644 --- a/lib9p/tests/test_server/CMakeLists.txt +++ b/lib9p/tests/test_server/CMakeLists.txt @@ -9,6 +9,7 @@ if (PICO_PLATFORM STREQUAL "host") add_library(test_server_objs OBJECT main.c + fs_shutdown.c ) target_include_directories(test_server_objs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/config) target_include_directories(test_server_objs PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/lib9p/tests/test_server/fs_shutdown.c b/lib9p/tests/test_server/fs_shutdown.c new file mode 100644 index 0000000..3f88985 --- /dev/null +++ b/lib9p/tests/test_server/fs_shutdown.c @@ -0,0 +1,93 @@ +/* lib9p/tests/test_server/fs_shutdown.c - /shutdown API endpoint + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include "fs_shutdown.h" + +LO_IMPLEMENTATION_C(lib9p_srv_file, struct shutdown_file, shutdown_file, static); + +LO_IMPLEMENTATION_H(lib9p_srv_fio, struct shutdown_file, shutdown_file); +LO_IMPLEMENTATION_C(lib9p_srv_fio, struct shutdown_file, shutdown_file, static); + +/* srv_file *******************************************************************/ + +static void shutdown_file_free(struct shutdown_file *self) { + assert(self); +} +static struct lib9p_qid shutdown_file_qid(struct shutdown_file *self) { + assert(self); + return (struct lib9p_qid){ + .type = LIB9P_QT_FILE, + .vers = 1, + .path = self->pathnum, + }; +} + +static struct lib9p_stat shutdown_file_stat(struct shutdown_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + return (struct lib9p_stat){ + .kern_type = 0, + .kern_dev = 0, + .file_qid = shutdown_file_qid(self), + .file_mode = 0222, + .file_atime = UTIL9P_ATIME, + .file_mtime = UTIL9P_MTIME, + .file_size = 0, + .file_name = lib9p_str(self->name), + .file_owner_uid = lib9p_str("root"), + .file_owner_gid = lib9p_str("root"), + .file_last_modified_uid = lib9p_str("root"), + .file_extension = lib9p_str(NULL), + .file_owner_n_uid = 0, + .file_owner_n_gid = 0, + .file_last_modified_n_uid = 0, + }; +} +static void shutdown_file_wstat(struct shutdown_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_stat) { + assert(self); + assert(ctx); + lib9p_error(&ctx->basectx, LINUX_EROFS, "cannot wstat API file"); +} +static void shutdown_file_remove(struct shutdown_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + lib9p_error(&ctx->basectx, LINUX_EROFS, "cannot remove API file"); +} + +LIB9P_SRV_NOTDIR(struct shutdown_file, shutdown_file) + +static lo_interface lib9p_srv_fio shutdown_file_fopen(struct shutdown_file *self, struct lib9p_srv_ctx *ctx, bool, bool, bool) { + assert(self); + assert(ctx); + return lo_box_shutdown_file_as_lib9p_srv_fio(self); +} + +/* srv_fio ********************************************************************/ + +static void shutdown_file_iofree(struct shutdown_file *self) { + assert(self); +} + +static uint32_t shutdown_file_iounit(struct shutdown_file *self) { + assert(self); + return 0; +} + +static uint32_t shutdown_file_pwrite(struct shutdown_file *self, struct lib9p_srv_ctx *ctx, void *buf, uint32_t byte_count, uint64_t LM_UNUSED(offset)) { + assert(self); + assert(ctx); + assert(buf); + if (byte_count == 0) + return 0; + for (size_t i = 0; i < self->nlisteners; i++) + LO_CALL(lo_box_hostnet_tcplist_as_net_stream_listener(&self->listeners[i]), close); + return byte_count; +} +static void shutdown_file_pread(struct shutdown_file *LM_UNUSED(self), struct lib9p_srv_ctx *LM_UNUSED(ctx), + uint32_t LM_UNUSED(byte_count), uint64_t LM_UNUSED(byte_offset), + struct iovec *LM_UNUSED(ret)) { + assert_notreached("not readable"); +} diff --git a/lib9p/tests/test_server/fs_shutdown.h b/lib9p/tests/test_server/fs_shutdown.h new file mode 100644 index 0000000..65956db --- /dev/null +++ b/lib9p/tests/test_server/fs_shutdown.h @@ -0,0 +1,23 @@ +/* lib9p/tests/test_server/fs_shutdown.h - /shutdown API endpoint + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIB9P_TESTS_TEST_SERVER_FS_SHUTDOWN_H_ +#define _LIB9P_TESTS_TEST_SERVER_FS_SHUTDOWN_H_ + +#include <util9p/static.h> +#include <libhw/host_net.h> + +struct shutdown_file { + char *name; + uint64_t pathnum; + + struct hostnet_tcp_listener *listeners; + size_t nlisteners; +}; +LO_IMPLEMENTATION_H(lib9p_srv_file, struct shutdown_file, shutdown_file); +#define lo_box_shutdown_file_as_lib9p_srv_file(obj) util9p_box(shutdown_file, obj) + +#endif /* _LIB9P_TESTS_TEST_SERVER_FS_SHUTDOWN_H_ */ diff --git a/lib9p/tests/test_server/main.c b/lib9p/tests/test_server/main.c index a31c083..8d22a04 100644 --- a/lib9p/tests/test_server/main.c +++ b/lib9p/tests/test_server/main.c @@ -17,6 +17,7 @@ #include <util9p/static.h> #include "static.h" +#include "fs_shutdown.h" /* configuration **************************************************************/ @@ -42,96 +43,6 @@ struct { }, }; -/* api ************************************************************************/ - -struct api_file { - uint64_t pathnum; -}; -LO_IMPLEMENTATION_H(lib9p_srv_file, struct api_file, api); -LO_IMPLEMENTATION_H(lib9p_srv_fio, struct api_file, api); - -LO_IMPLEMENTATION_C(lib9p_srv_file, struct api_file, api, static); -LO_IMPLEMENTATION_C(lib9p_srv_fio, struct api_file, api, static); - -static void api_free(struct api_file *self) { - assert(self); -} -static struct lib9p_qid api_qid(struct api_file *self) { - assert(self); - return (struct lib9p_qid){ - .type = LIB9P_QT_FILE, - .vers = 1, - .path = self->pathnum, - }; -} - -static struct lib9p_stat api_stat(struct api_file *self, struct lib9p_srv_ctx *ctx) { - assert(self); - assert(ctx); - return (struct lib9p_stat){ - .kern_type = 0, - .kern_dev = 0, - .file_qid = api_qid(self), - .file_mode = 0222, - .file_atime = UTIL9P_ATIME, - .file_mtime = UTIL9P_MTIME, - .file_size = 0, - .file_name = lib9p_str("shutdown"), - .file_owner_uid = lib9p_str("root"), - .file_owner_gid = lib9p_str("root"), - .file_last_modified_uid = lib9p_str("root"), - .file_extension = lib9p_str(NULL), - .file_owner_n_uid = 0, - .file_owner_n_gid = 0, - .file_last_modified_n_uid = 0, - }; -} -static void api_wstat(struct api_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_stat) { - assert(self); - assert(ctx); - lib9p_error(&ctx->basectx, LINUX_EROFS, "cannot wstat API file"); -} -static void api_remove(struct api_file *self, struct lib9p_srv_ctx *ctx) { - assert(self); - assert(ctx); - lib9p_error(&ctx->basectx, LINUX_EROFS, "cannot remove API file"); -} - -LIB9P_SRV_NOTDIR(struct api_file, api) - -static lo_interface lib9p_srv_fio api_fopen(struct api_file *self, struct lib9p_srv_ctx *ctx, bool, bool, bool) { - assert(self); - assert(ctx); - return lo_box_api_as_lib9p_srv_fio(self); -} - -static void api_iofree(struct api_file *self) { - assert(self); -} - -static uint32_t api_iounit(struct api_file *self) { - assert(self); - return 0; -} - -static uint32_t api_pwrite(struct api_file *self, struct lib9p_srv_ctx *ctx, void *buf, uint32_t byte_count, uint64_t LM_UNUSED(offset)) { - assert(self); - assert(ctx); - assert(buf); - if (byte_count == 0) - return 0; - for (int i = 0; i < CONFIG_SRV9P_NUM_CONNS; i++) - LO_CALL(lo_box_hostnet_tcplist_as_net_stream_listener(&globals.listeners[i]), close); - return byte_count; -} -static void api_pread(struct api_file *LM_UNUSED(self), struct lib9p_srv_ctx *LM_UNUSED(ctx), - uint32_t LM_UNUSED(byte_count), uint64_t LM_UNUSED(byte_offset), - struct iovec *LM_UNUSED(ret)) { - assert_notreached("not readable"); -} - -#define lo_box_api_as_lib9p_srv_file(obj) util9p_box(api, obj) - /* file tree ******************************************************************/ enum { PATH_BASE = __COUNTER__ }; @@ -144,13 +55,22 @@ enum { PATH_BASE = __COUNTER__ }; #define STATIC_DIR(STRNAME, ...) \ UTIL9P_STATIC_DIR(PATH_COUNTER, STRNAME, __VA_ARGS__) +#define API_FILE(STRNAME, SYMNAME, ...) \ + lo_box_##SYMNAME##_file_as_lib9p_srv_file(&((struct SYMNAME##_file){ \ + .name = STRNAME, \ + .pathnum = PATH_COUNTER \ + __VA_OPT__(,) __VA_ARGS__ \ + })) + struct lib9p_srv_file root = STATIC_DIR("", STATIC_DIR("Documentation", STATIC_FILE("x", Documentation_x_txt), ), STATIC_FILE("README.md", README_md), - lo_box_api_as_lib9p_srv_file(&(struct api_file){.pathnum = PATH_COUNTER}), + API_FILE("shutdown", shutdown, + .listeners = globals.listeners, + .nlisteners = LM_ARRAY_LEN(globals.listeners)), ); static lo_interface lib9p_srv_file get_root(struct lib9p_srv_ctx *LM_UNUSED(ctx), struct lib9p_s LM_UNUSED(treename)) { |