git: c596dc64da6d - main - net/ucx: Improve FreeBSD ucx_vfs support
Laurent Chardon <[email protected]> Thu, 06 Aug 2026 11:21:08 +0000
| Newsgroups | gmane.os.freebsd.devel.cvs.ports |
|---|---|
| Message-ID | <6a746e24.30923.15bff24e__27563.9246728801$1786015308$gmane$org@gitrepo.freebsd.org> |
The branch main has been updated by laurent: URL: https://cgit.FreeBSD.org/ports/commit/?id=c596dc64da6d3142ba5c9a6ea1fdbebc4e9bf3e1 commit c596dc64da6d3142ba5c9a6ea1fdbebc4e9bf3e1 Author: GenericRikka <[email protected]> AuthorDate: 2026-08-06 11:09:06 +0000 Commit: Laurent Chardon <[email protected]> CommitDate: 2026-08-06 11:19:32 +0000 net/ucx: Improve FreeBSD ucx_vfs support - replace Linux-specific fusermount3 with mount_fusefs/umount - use FreeBSD-compatible FUSE capability detection - fix UNIX socket ancillary data handling for SCM_RIGHTS and peer credentials on FreeBSD This allows ucx_vfs to start and communicate correctly on FreeBSD. PR: 297093 Reported-by: Laurent Chardon <[email protected]> Reviewed by: thierry (mentor) Approved by: thierry (mentor) --- net/ucx/Makefile | 4 +- net/ucx/files/patch-src_tools_vfs_vfs__daemon.h | 17 +++ net/ucx/files/patch-src_tools_vfs_vfs__main.c | 75 ++++++++++ net/ucx/files/patch-src_ucs_vfs_sock_vfs__sock.c | 178 ++++++++++++++++++----- net/ucx/files/patch-src_ucs_vfs_sock_vfs__sock.h | 14 ++ 5 files changed, 245 insertions(+), 43 deletions(-) diff --git a/net/ucx/Makefile b/net/ucx/Makefile index 6c67495d9c7e..e1b35a6a76ec 100644 --- a/net/ucx/Makefile +++ b/net/ucx/Makefile @@ -1,6 +1,6 @@ PORTNAME= ucx DISTVERSION= 1.20.1 -PORTREVISION= 3 +PORTREVISION= 4 CATEGORIES= net MASTER_SITES= https://github.com/openucx/ucx/releases/download/v${DISTVERSION}/ @@ -59,8 +59,6 @@ UMAD_CONFIGURE_OFF= --with-mad=no post-patch: ${REINPLACE_CMD} 's|^examplesdir = $$(pkgdatadir)/examples$$|examplesdir = ${EXAMPLESDIR}|' \ ${WRKSRC}/examples/Makefile.am - ${REINPLACE_CMD} 's|/run/user|/var/run/user|' \ - ${WRKSRC}/src/ucs/vfs/sock/vfs_sock.h post-install: ${MV} ${STAGEDIR}${ETCDIR}/ucx.conf ${STAGEDIR}${ETCDIR}/ucx.conf.sample diff --git a/net/ucx/files/patch-src_tools_vfs_vfs__daemon.h b/net/ucx/files/patch-src_tools_vfs_vfs__daemon.h new file mode 100644 index 000000000000..eb7b0ef92f9a --- /dev/null +++ b/net/ucx/files/patch-src_tools_vfs_vfs__daemon.h @@ -0,0 +1,17 @@ +--- src/tools/vfs/vfs_daemon.h.orig 2026-08-01 18:29:37 UTC ++++ src/tools/vfs/vfs_daemon.h +@@ -17,7 +17,13 @@ + + + #define VFS_DEFAULT_MOUNTPOINT_DIR "/tmp/ucx" +-#define VFS_FUSE_MOUNT_PROG "fusermount3" ++#ifdef __FreeBSD__ ++# define VFS_FUSE_MOUNT_PROG "/sbin/mount_fusefs" ++# define VFS_FUSE_UNMOUNT_PROG "/sbin/umount" ++#else ++# define VFS_FUSE_MOUNT_PROG "fusermount3" ++# define VFS_FUSE_UNMOUNT_PROG "fusermount3" ++#endif + + + enum { diff --git a/net/ucx/files/patch-src_tools_vfs_vfs__main.c b/net/ucx/files/patch-src_tools_vfs_vfs__main.c new file mode 100644 index 000000000000..1af1720cf5be --- /dev/null +++ b/net/ucx/files/patch-src_tools_vfs_vfs__main.c @@ -0,0 +1,75 @@ +--- src/tools/vfs/vfs_main.c.orig 2026-08-04 01:14:50 UTC ++++ src/tools/vfs/vfs_main.c +@@ -37,7 +37,7 @@ static struct sockaddr_un g_sockaddr; + static struct sockaddr_un g_sockaddr; + + +-static int vfs_run_fusermount(char **extra_argv) ++static int vfs_run_fusermount(const char *program, char **extra_argv, int add_quiet_option) + { + char command[128]; + pid_t child_pid; +@@ -48,8 +48,8 @@ static int vfs_run_fusermount(char **extra_argv) + int i, argc; + + argc = 0; +- argv[argc++] = VFS_FUSE_MOUNT_PROG; +- if (!g_opts.verbose) { ++ argv[argc++] = (char*)program; ++ if (add_quiet_option && !g_opts.verbose) { + argv[argc++] = "-q"; + } + while (*extra_argv != NULL) { +@@ -223,7 +223,11 @@ int vfs_unmount(int pid) + int vfs_unmount(int pid) + { + char *mountpoint; ++#ifdef __FreeBSD__ ++ char *argv[2]; ++#else + char *argv[5]; ++#endif + int ret; + + /* Unmount FUSE file system */ +@@ -233,12 +237,19 @@ int vfs_unmount(int pid) + goto out; + } + ++#ifdef __FreeBSD__ ++ argv[0] = mountpoint; ++ argv[1] = NULL; ++ ++ ret = vfs_run_fusermount(VFS_FUSE_UNMOUNT_PROG, argv, 0); ++#else + argv[0] = "-u"; + argv[1] = "-z"; + argv[2] = "--"; + argv[3] = mountpoint; + argv[4] = NULL; +- ret = vfs_run_fusermount(argv); ++ ret = vfs_run_fusermount(VFS_FUSE_UNMOUNT_PROG, argv, 1); ++#endif + if (ret < 0) { + goto out_free_mountpoint; + } +@@ -505,8 +516,18 @@ static int vfs_test_fuse() + + static int vfs_test_fuse() + { ++#ifdef __FreeBSD__ ++ if (access(VFS_FUSE_MOUNT_PROG, X_OK) < 0) { ++ vfs_error("cannot execute '%s': %m", VFS_FUSE_MOUNT_PROG); ++ return -errno; ++ } ++ ++ return 0; ++#else + char *argv[] = {"-V", NULL}; +- return vfs_run_fusermount(argv); ++ ++ return vfs_run_fusermount(VFS_FUSE_MOUNT_PROG, argv, 0); ++#endif + } + + int main(int argc, char **argv) diff --git a/net/ucx/files/patch-src_ucs_vfs_sock_vfs__sock.c b/net/ucx/files/patch-src_ucs_vfs_sock_vfs__sock.c index 03e48c699cb6..f4f945f79f4d 100644 --- a/net/ucx/files/patch-src_ucs_vfs_sock_vfs__sock.c +++ b/net/ucx/files/patch-src_ucs_vfs_sock_vfs__sock.c @@ -1,6 +1,12 @@ ---- src/ucs/vfs/sock/vfs_sock.c.orig 2026-02-04 09:52:46 UTC +--- src/ucs/vfs/sock/vfs_sock.c.orig 2026-08-04 01:14:50 UTC +++ src/ucs/vfs/sock/vfs_sock.c -@@ -24,6 +24,9 @@ +@@ -19,11 +19,15 @@ + #include <sys/stat.h> + #include <string.h> + #include <assert.h> ++#include <stdlib.h> + #include <unistd.h> + #include <stdio.h> #include <errno.h> #include <pwd.h> #include <libgen.h> @@ -10,71 +16,163 @@ typedef struct { -@@ -76,7 +79,13 @@ int ucs_vfs_sock_setopt_passcred(int sockfd) +@@ -33,8 +37,29 @@ void ucs_vfs_sock_get_address(struct sockaddr_un *un_a + + void ucs_vfs_sock_get_address(struct sockaddr_un *un_addr) + { ++#ifdef __FreeBSD__ ++ const char *xdg_runtime_dir; ++ int ret; ++#endif + memset(un_addr, 0, sizeof(*un_addr)); + un_addr->sun_family = AF_UNIX; ++#ifdef __FreeBSD__ ++ /* ++ * Preserve an explicit UCX_VFS_SOCK_PATH override. When the default ++ * remains selected, prefer the runtime directory provided by the ++ * user's login session. ++ */ ++ xdg_runtime_dir = getenv("XDG_RUNTIME_DIR"); ++ if ((xdg_runtime_dir != NULL) && (xdg_runtime_dir[0] != '\0') && ++ !strcmp(ucs_global_opts.vfs_sock_path, ++ UCX_VFS_SOCK_DEFAULT_PATH)) { ++ ret = snprintf(un_addr->sun_path, sizeof(un_addr->sun_path), ++ "%s/ucx/vfs.sock", xdg_runtime_dir); ++ if ((ret >= 0) && ((size_t)ret < sizeof(un_addr->sun_path))) { ++ return; ++ } ++ } ++#endif + ucs_fill_filename_template(ucs_global_opts.vfs_sock_path, un_addr->sun_path, + sizeof(un_addr->sun_path)); + } +@@ -43,6 +68,7 @@ int ucs_vfs_sock_mkdir(const char *sock_path, ucs_log_ + { + const char *dirname; + char *sock_path_dir; ++ struct stat st; + int ret; + ucs_status_t status; + +@@ -57,8 +83,22 @@ int ucs_vfs_sock_mkdir(const char *sock_path, ucs_log_ + ret = mkdir(dirname, S_IRWXU); + if (ret < 0) { + if (errno == EEXIST) { +- /* Directory already exists */ +- ret = 0; ++ if (lstat(dirname, &st) < 0) { ++ ret = -errno; ++ ucs_log(log_level, "failed to stat directory '%s': %m", ++ dirname); ++ } else if (!S_ISDIR(st.st_mode) || ++ (st.st_uid != geteuid()) || ++ ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0)) { ++ ret = -EPERM; ++ ucs_log(log_level, ++ "unsafe VFS socket directory '%s': " ++ "expected a directory owned by uid %u without " ++ "group or world write permissions", ++ dirname, (unsigned)geteuid()); ++ } else { ++ ret = 0; ++ } + } else { + ucs_log(log_level, "failed to create directory '%s': %m", + sock_path_dir); +@@ -73,6 +113,7 @@ int ucs_vfs_sock_setopt_passcred(int sockfd) + + int ucs_vfs_sock_setopt_passcred(int sockfd) + { ++#if defined(__linux__) int optval, ret; optval = 1; -+#if defined(__linux__) - ret = setsockopt(sockfd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)); -+#elif defined(__FreeBSD__) -+ ret = setsockopt(sockfd, SOL_LOCAL, LOCAL_CREDS, &optval, sizeof(optval)); -+#else -+ ret = 0; /* no-op on other platforms for now */ -+#endif +@@ -80,6 +121,11 @@ int ucs_vfs_sock_setopt_passcred(int sockfd) if (ret < 0) { return -errno; } -@@ -106,6 +115,8 @@ int ucs_vfs_sock_send(int sockfd, const ucs_vfs_sock_m ++#else ++ /* FreeBSD retrieves credentials from connected local sockets using ++ * LOCAL_PEERCRED. Other platforms are currently a no-op. */ ++ (void)sockfd; ++#endif - memset(cbuf, 0, sizeof(cbuf)); - memset(&msgh, 0, sizeof(msgh)); -+ msgh.msg_control = cbuf; -+ msgh.msg_controllen = sizeof(cbuf); - msg.action = vfs_msg->action; - iov.iov_base = &msg; - iov.iov_len = sizeof(msg); -@@ -114,8 +125,6 @@ int ucs_vfs_sock_send(int sockfd, const ucs_vfs_sock_m + return 0; + } +@@ -97,7 +143,7 @@ int ucs_vfs_sock_send(int sockfd, const ucs_vfs_sock_m - if (vfs_msg->action == UCS_VFS_SOCK_ACTION_MOUNT_REPLY) { - /* send file descriptor */ -- msgh.msg_control = cbuf; -- msgh.msg_controllen = sizeof(cbuf); - cmsgp = CMSG_FIRSTHDR(&msgh); - cmsgp->cmsg_level = SOL_SOCKET; - cmsgp->cmsg_len = CMSG_LEN(sizeof(vfs_msg->fd)); -@@ -132,7 +141,11 @@ int ucs_vfs_sock_recv(int sockfd, ucs_vfs_sock_message + int ucs_vfs_sock_send(int sockfd, const ucs_vfs_sock_message_t *vfs_msg) + { +- char cbuf[CMSG_SPACE(sizeof(*vfs_msg))] UCS_V_ALIGNED(sizeof(size_t)); ++ char cbuf[CMSG_SPACE(sizeof(vfs_msg->fd))] UCS_V_ALIGNED(sizeof(size_t)); + struct cmsghdr *cmsgp; + struct msghdr msgh; + ucs_vfs_msg_t msg; +@@ -132,7 +178,12 @@ int ucs_vfs_sock_recv(int sockfd, ucs_vfs_sock_message int ucs_vfs_sock_recv(int sockfd, ucs_vfs_sock_message_t *vfs_msg) { char cbuf[CMSG_SPACE(sizeof(*vfs_msg))] UCS_V_ALIGNED(sizeof(size_t)); -+#if defined(__FreeBSD__) -+ const struct cmsgcred *cred; -+#else ++#if defined(__linux__) const struct ucred *cred; ++#elif defined(__FreeBSD__) ++ struct xucred cred; ++ socklen_t cred_len; +#endif struct cmsghdr *cmsgp; struct msghdr msgh; ucs_vfs_msg_t msg; -@@ -178,12 +191,30 @@ int ucs_vfs_sock_recv(int sockfd, ucs_vfs_sock_message +@@ -163,27 +214,54 @@ int ucs_vfs_sock_recv(int sockfd, ucs_vfs_sock_message + + vfs_msg->action = msg.action; + +- cmsgp = CMSG_FIRSTHDR(&msgh); +- if ((cmsgp == NULL) || (cmsgp->cmsg_level != SOL_SOCKET)) { +- return -EINVAL; +- } +- + if (msg.action == UCS_VFS_SOCK_ACTION_MOUNT_REPLY) { + /* expect file descriptor */ +- if ((cmsgp->cmsg_type != SCM_RIGHTS) || ++ cmsgp = CMSG_FIRSTHDR(&msgh); ++ if ((cmsgp == NULL) || ++ (cmsgp->cmsg_level != SOL_SOCKET) || ++ (cmsgp->cmsg_type != SCM_RIGHTS) || + (cmsgp->cmsg_len != CMSG_LEN(sizeof(vfs_msg->fd)))) { + return -EINVAL; + } + memcpy(&vfs_msg->fd, CMSG_DATA(cmsgp), sizeof(vfs_msg->fd)); } else { - /* expect credentials */ +- /* expect credentials */ ++ /* expect peer credentials */ +#if defined(__FreeBSD__) -+ if ((cmsgp->cmsg_level != SOL_SOCKET) || -+ (cmsgp->cmsg_type != SCM_CREDS) || -+ (cmsgp->cmsg_len != CMSG_LEN(sizeof(*cred)))) { -+ return -EINVAL; ++ cred_len = sizeof(cred); ++ if (getsockopt(sockfd, SOL_LOCAL, LOCAL_PEERCRED, &cred, ++ &cred_len) < 0) { ++ return -errno; + } + -+ cred = (const struct cmsgcred*)CMSG_DATA(cmsgp); ++ if ((cred_len != sizeof(cred)) || ++ (cred.cr_version != XUCRED_VERSION)) { ++ return -EINVAL; ++ } + -+ if ((cred->cmcred_euid != geteuid()) || (cred->cmcred_gid != getegid())) { ++ if ((cred.cr_uid != geteuid()) || ++ (cred.cr_ngroups < 1) || ++ (cred.cr_groups[0] != getegid())) { + return -EPERM; + } + + if (msg.action == UCS_VFS_SOCK_ACTION_MOUNT) { -+ vfs_msg->pid = cred->cmcred_pid; ++ vfs_msg->pid = cred.cr_pid; + } +#else ++ cmsgp = CMSG_FIRSTHDR(&msgh); ++ if ((cmsgp == NULL) || ++ (cmsgp->cmsg_level != SOL_SOCKET)) { ++ return -EINVAL; ++ } ++ if ((cmsgp->cmsg_type != SCM_CREDENTIALS) || - (cmsgp->cmsg_len != CMSG_LEN(sizeof(*cred)))) { + (cmsgp->cmsg_len != CMSG_LEN(sizeof(*cred)))) { @@ -86,7 +184,7 @@ if ((cred->uid != getuid()) || (cred->gid != getgid())) { return -EPERM; } -@@ -191,6 +222,7 @@ int ucs_vfs_sock_recv(int sockfd, ucs_vfs_sock_message +@@ -191,6 +269,7 @@ int ucs_vfs_sock_recv(int sockfd, ucs_vfs_sock_message if (msg.action == UCS_VFS_SOCK_ACTION_MOUNT) { vfs_msg->pid = cred->pid; } diff --git a/net/ucx/files/patch-src_ucs_vfs_sock_vfs__sock.h b/net/ucx/files/patch-src_ucs_vfs_sock_vfs__sock.h new file mode 100644 index 000000000000..443c2bbc6489 --- /dev/null +++ b/net/ucx/files/patch-src_ucs_vfs_sock_vfs__sock.h @@ -0,0 +1,14 @@ +--- src/ucs/vfs/sock/vfs_sock.h.orig 2026-08-04 15:13:35 UTC ++++ src/ucs/vfs/sock/vfs_sock.h +@@ -15,7 +15,11 @@ + /* This header file defines socket operations for communicating between UCS + * library and VFS daemon */ + ++#ifdef __FreeBSD__ ++#define UCX_VFS_SOCK_DEFAULT_PATH "/tmp/ucx-%i/vfs.sock" ++#else + #define UCX_VFS_SOCK_DEFAULT_PATH "/run/user/%i/ucx/vfs.sock" ++#endif + + + /**