From 35eb88ecb4eae75ce553682b6487f008db21881e Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sun, 21 Dec 2025 16:23:16 +0100 Subject: [PATCH 1/7] [fix] add SunOS C structs --- mfusepy.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/mfusepy.py b/mfusepy.py index 88b55b9..75ac0d2 100644 --- a/mfusepy.py +++ b/mfusepy.py @@ -588,6 +588,47 @@ def get_fuse_version(libfuse): ('st_gen', ctypes.c_uint32), ('st_spare', ctypes.c_uint32 * 2), ] +elif _system == 'SunOS': + ENOTSUP = 48 + c_dev_t = ctypes.c_uint64 + c_uid_t = ctypes.c_uint32 + c_gid_t = ctypes.c_uint32 + c_mode_t = ctypes.c_uint32 + c_off_t = ctypes.c_int64 + c_pid_t = ctypes.c_int32 + setxattr_t = ctypes.CFUNCTYPE( + ctypes.c_int, + ctypes.c_char_p, + ctypes.c_char_p, + c_byte_p, + ctypes.c_size_t, + ctypes.c_int, + ) + getxattr_t = ctypes.CFUNCTYPE( + ctypes.c_int, + ctypes.c_char_p, + ctypes.c_char_p, + c_byte_p, + ctypes.c_size_t, + ) + c_fsblkcnt_t = ctypes.c_uint64 + c_fsfilcnt_t = ctypes.c_uint64 + _c_stat__fields_ = [ + ('st_dev', c_dev_t), + ('st_ino', ctypes.c_uint64), + ('st_mode', c_mode_t), + ('st_nlink', ctypes.c_uint32), + ('st_uid', c_uid_t), + ('st_gid', c_gid_t), + ('st_rdev', c_dev_t), + ('st_size', c_off_t), + ('st_atimespec', c_timespec), + ('st_mtimespec', c_timespec), + ('st_ctimespec', c_timespec), + ('st_blksize', ctypes.c_int32), + ('st_blocks', ctypes.c_int64), + ('st_fstype', ctypes.c_char * 16), + ] else: raise NotImplementedError(_system + ' is not supported.') @@ -677,6 +718,23 @@ class c_statvfs(ctypes.Structure): ('f_mntfromname', ctypes.c_char * 1024), ('f_mntfromlabel', ctypes.c_char * 1024), ] + elif _system == 'SunOS': + # Source: /usr/include/sys/statvfs.h + _fields_ = [ + ('f_bsize', ctypes.c_ulong), + ('f_frsize', ctypes.c_ulong), + ('f_blocks', c_fsblkcnt_t), + ('f_bfree', c_fsblkcnt_t), + ('f_bavail', c_fsblkcnt_t), + ('f_files', c_fsfilcnt_t), + ('f_ffree', c_fsfilcnt_t), + ('f_favail', c_fsfilcnt_t), + ('f_fsid', ctypes.c_ulong), + ('f_basetype', ctypes.c_char * 16), + ('f_flag', ctypes.c_ulong), + ('f_namemax', ctypes.c_ulong), + ('f_fstr', ctypes.c_char * 32), + ] else: # https://sourceware.org/git?p=glibc.git;a=blob;f=bits/statvfs.h;h=ea89d9004d834c81874de00b5e3f5617d3096ccc;hb=HEAD#l33 _fields_ = [ From a31138bc97305caaa78dad278713006cc98e193e Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sun, 21 Dec 2025 20:48:05 +0100 Subject: [PATCH 2/7] [fix] find libfuse on omniOS --- mfusepy.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/mfusepy.py b/mfusepy.py index 75ac0d2..0900e1b 100644 --- a/mfusepy.py +++ b/mfusepy.py @@ -125,6 +125,22 @@ def reg32_get_value(rootkey, keyname, valname): arch = "x64" if sys.maxsize > 0xFFFFFFFF else "x86" _libfuse_path += f"bin\\winfsp-{arch}.dll" # pytype: enable=module-attr + elif _system == 'SunOS': + _libfuse_path = find_library('fuse') or find_library('fuse3') + if not _libfuse_path: + for path in [ + '/usr/gnu/lib/amd64/libfuse.so', + '/usr/gnu/lib/libfuse.so', + '/usr/lib/amd64/libfuse.so.2', + '/usr/lib/libfuse.so.2', + '/usr/lib/amd64/libfuse.so', + '/usr/lib/libfuse.so', + '/lib/amd64/libfuse.so.2', + '/lib/libfuse.so.2', + ]: + if os.path.exists(path): + _libfuse_path = path + break elif _libfuse_name := os.environ.get('FUSE_LIBRARY_NAME'): _libfuse_path = find_library(_libfuse_name) else: From caa062b1a71bdcf654496503c26489753c99e1bc Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Mon, 22 Dec 2025 03:28:51 +0100 Subject: [PATCH 3/7] [fix] find fuse.h on OmniOS --- tests/test_struct_layout.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_struct_layout.py b/tests/test_struct_layout.py index 142a92a..c986485 100644 --- a/tests/test_struct_layout.py +++ b/tests/test_struct_layout.py @@ -178,6 +178,7 @@ def c_run(name: str, source: str) -> str: '/usr/local/include/osxfuse/fuse', '/usr/local/include/macfuse/fuse', '/usr/include/libfuse', + '/usr/gnu/include/fuse', ] if mfusepy.fuse_version_major == 3: include_paths += ['/usr/local/include/fuse3', '/usr/include/fuse3'] From e4bc010ac8b52e4c85d367c29ace7c385af20675 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 24 Dec 2025 21:41:22 +0100 Subject: [PATCH 4/7] [fix] fuse_context struct size fix for fuse < 2.8 --- mfusepy.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/mfusepy.py b/mfusepy.py index 0900e1b..ced779a 100644 --- a/mfusepy.py +++ b/mfusepy.py @@ -954,12 +954,16 @@ class fuse_context(ctypes.Structure): ('gid', c_gid_t), ('pid', c_pid_t), ('private_data', ctypes.c_void_p), - # Added in 2.8. Note that this is an ABI break because programs compiled against 2.7 - # will allocate a smaller struct leading to out-of-bound accesses when used for a 2.8 - # shared library! It shouldn't hurt the other way around to have a larger struct than - # the shared library expects. The newer members will simply be ignored. - ('umask', c_mode_t), ] + # OpenBSD announces 2.6, but still has the umask struct member. + if fuse_version_major == 3 or (fuse_version_major == 2 and fuse_version_minor >= 8) or _system == 'OpenBSD': + _fields_ += [ + # Added in 2.8. Note that this is an ABI break because programs compiled against 2.7 + # will allocate a smaller struct leading to out-of-bound accesses when used for a 2.8 + # shared library! It shouldn't hurt the other way around to have a larger struct than + # the shared library expects. The newer members will simply be ignored. + ('umask', c_mode_t), + ] _libfuse.fuse_get_context.restype = ctypes.POINTER(fuse_context) From 548e1729efd468598aa18ea80022fd33b06ea353 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sun, 21 Dec 2025 15:11:35 +0100 Subject: [PATCH 5/7] [tests] test on OmniOS r151056 --- .github/workflows/tests.yml | 47 +++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e4582c7..1c57889 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -216,7 +216,9 @@ jobs: - os: netbsd version: '10.1' display_name: NetBSD - + - os: omnios + version: r151056 + display_name: OmniOS steps: - name: Check out repository @@ -225,7 +227,7 @@ jobs: fetch-tags: true - name: Test on ${{ matrix.display_name }} - uses: cross-platform-actions/action@v0.29.0 + uses: cross-platform-actions/action@v0.32.0 with: operating_system: ${{ matrix.os }} version: ${{ matrix.version }} @@ -320,4 +322,45 @@ jobs: sudo -E python3 -m pytest -s -v -rs tests || rc=$? exit "$rc" ;; + omnios) + # Ensure a proper hostname/FQDN is set (VMs may not have one by default) + sudo -E /bin/sh -c 'grep -q "omnios\.local" /etc/hosts || echo "127.0.0.1 omnios.local omnios" >> /etc/hosts' + sudo -E hostname omnios.local + hostname + + # Packages + pfexec pkg install developer/versioning/git + pfexec pkg install developer/gcc14 + pfexec pkg set-mediator -V 14 gcc + + # driver + libfuse + pfexec pkg set-publisher -p https://sfe.opencsw.org/localhostomnios localhostomnios + pfexec pkg refresh localhostomnios + pfexec pkg install --accept system/file-system/fusefs + pfexec pkg install --accept system/file-system/libfuse + pfexec pkg install --accept system/file-system/libfuse/src + pkg list system/file-system/fusefs + pkg list system/file-system/libfuse + pkg list system/file-system/libfuse/src + pkg contents system/file-system/fusefs + pkg contents system/file-system/libfuse + pkg contents system/file-system/libfuse/src + + # Install pip Dependencies + python3 -m pip install pytest pytest-order ioctl-opt + + # Fix PATH + export PATH="/home/runner/.local/bin:$PATH" + echo $PATH + + # Test Installation From Source + python3 -m pip install . + + # Unit Tests (FUSE 2) + python3 -c 'import mfusepy; assert mfusepy.fuse_version_major == 2' + # preserve pytest exit status, always show logs + rc=0 + pfexec python3 -m pytest -v -rs tests || rc=$? + exit "$rc" + ;; esac From 849606230765694bb6b3cf4d91a221553e3f2e50 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Thu, 25 Dec 2025 20:09:09 +0100 Subject: [PATCH 6/7] temp: adapt struct layout test --- tests/test_struct_layout.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_struct_layout.py b/tests/test_struct_layout.py index c986485..f63baee 100644 --- a/tests/test_struct_layout.py +++ b/tests/test_struct_layout.py @@ -85,6 +85,31 @@ if platform.system() != 'NetBSD': STRUCT_NAMES['fuse_file_info'] = ['flags', 'fh', 'lock_owner'] +if platform.system() == 'SunOS': + STRUCT_NAMES['statvfs'] = [ + 'f_bavail', + 'f_bfree', + 'f_blocks', + 'f_bsize', + 'f_favail', + 'f_ffree', + 'f_files', + 'f_flag', + 'f_frsize', + 'f_fsid', + 'f_namemax', + 'f_basetype', # SunOS only + 'f_fstr', # SunOS only + ] + STRUCT_NAMES['fuse_context'] = ['fuse', 'uid', 'gid', 'pid'] # no 'umask' on SunOS + STRUCT_NAMES['fuse_conn_info'] = [ + 'proto_major', + 'proto_minor', + 'max_write', + 'max_readahead', + # 4 attrs not present on SunOS + ] + if mfusepy.fuse_version_major == 3: STRUCT_NAMES['fuse_config'] = [ 'set_gid', From 723420de953c4e5633d69d814e5647e058b4c81e Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sat, 10 Jan 2026 22:09:33 +0100 Subject: [PATCH 7/7] try tar from tom --- .github/workflows/tests.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1c57889..5fd1c5c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -324,8 +324,8 @@ jobs: ;; omnios) # Ensure a proper hostname/FQDN is set (VMs may not have one by default) - sudo -E /bin/sh -c 'grep -q "omnios\.local" /etc/hosts || echo "127.0.0.1 omnios.local omnios" >> /etc/hosts' - sudo -E hostname omnios.local + pfexec /bin/sh -c 'grep -q "omnios\.local" /etc/hosts || echo "127.0.0.1 omnios.local omnios" >> /etc/hosts' + pfexec hostname omnios.local hostname # Packages @@ -338,13 +338,19 @@ jobs: pfexec pkg refresh localhostomnios pfexec pkg install --accept system/file-system/fusefs pfexec pkg install --accept system/file-system/libfuse - pfexec pkg install --accept system/file-system/libfuse/src pkg list system/file-system/fusefs pkg list system/file-system/libfuse - pkg list system/file-system/libfuse/src pkg contents system/file-system/fusefs pkg contents system/file-system/libfuse - pkg contents system/file-system/libfuse/src + + # Fetch custom build from Tom and install it + modinfo | grep fuse | awk '{print $1}' | while read id; do pfexec modunload -i $id; done + modinfo | grep fuse || true + curl -L https://www.wagner-net.com/~tom/fuse-files-sfe-omnios-r151054-f66c95f374.tar.bz2 -o /tmp/fuse-files.tar.bz2 + pushd / + pfexec tar xvjf /tmp/fuse-files.tar.bz2 + popd + ls -l /usr/gnu/lib/amd64/libfuse.so.2.7.1 /usr/gnu/lib/libfuse.so.2.7.1 /usr/kernel/drv/amd64/fuse # Install pip Dependencies python3 -m pip install pytest pytest-order ioctl-opt