summaryrefslogtreecommitdiff
path: root/lib9p
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p')
-rw-r--r--lib9p/include/lib9p/9p.generated.h2
-rw-r--r--lib9p/include/lib9p/9p.h2
-rw-r--r--lib9p/include/lib9p/linux-errno.h2
-rw-r--r--lib9p/include/lib9p/srv.h2
-rwxr-xr-xlib9p/linux-errno.txt.gen17
-rw-r--r--lib9p/protogen/h.py2
-rw-r--r--lib9p/srv.c3
-rw-r--r--lib9p/tables.c8
-rwxr-xr-xlib9p/tests/runtest6
-rw-r--r--lib9p/tests/test_server/CMakeLists.txt1
-rw-r--r--lib9p/tests/test_server/fs_shutdown.c93
-rw-r--r--lib9p/tests/test_server/fs_shutdown.h23
-rw-r--r--lib9p/tests/test_server/main.c102
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)) {