(options: {
backend?: FUSEBackend;
mountPoint: string;
vfs: NodeVirtualFileSystem;
})
| 957 | } |
| 958 | |
| 959 | export async function mountFuse(options: { |
| 960 | backend?: FUSEBackend; |
| 961 | mountPoint: string; |
| 962 | vfs: NodeVirtualFileSystem; |
| 963 | }): Promise<FuseMount> { |
| 964 | // biome-ignore lint/suspicious/noExplicitAny: fuse-native ships no types |
| 965 | const fuseModule: any = await import("fuse-native"); |
| 966 | const Fuse = fuseModule.default ?? fuseModule; |
| 967 | // Optional op tracing. `COMPUTERD_FUSE_TRACE=summary` records per-op call |
| 968 | // counts and timings; the summary is emitted on SIGUSR2 and on |
| 969 | // unmount, to stderr by default or to `COMPUTERD_FUSE_TRACE_FILE` when set. |
| 970 | // Disabled means zero wrapping overhead — the unwrapped ops object |
| 971 | // is handed to fuse-native directly. |
| 972 | const traceMode = process.env.COMPUTERD_FUSE_TRACE; |
| 973 | const tracer: FuseTracer | undefined = traceMode === "summary" ? createFuseTracer() : undefined; |
| 974 | const baseOps = makeFUSEOps(options.vfs, options.mountPoint); |
| 975 | const { getBufferStats: _getBufferStats, ...fuseOps } = baseOps; |
| 976 | const ops = |
| 977 | tracer === undefined |
| 978 | ? fuseOps |
| 979 | : wrapFuseOpsWithTracer(fuseOps as unknown as Record<string, unknown>, tracer); |
| 980 | const fuse = new Fuse(options.mountPoint, ops, { |
| 981 | autoUnmount: true, |
| 982 | debug: false, |
| 983 | }) as FuseNativeInstance; |
| 984 | |
| 985 | const emitTrace = (reason: string): void => { |
| 986 | if (tracer === undefined) return; |
| 987 | const json = tracer.formatJson(); |
| 988 | const target = process.env.COMPUTERD_FUSE_TRACE_FILE; |
| 989 | if (target !== undefined && target !== "") { |
| 990 | try { |
| 991 | nodeWriteFileSync(target, `${json}\n`); |
| 992 | } catch (error) { |
| 993 | process.stderr.write( |
| 994 | `computerd: failed to write FUSE trace to ${target} (${reason}): ${String(error)}\n${json}\n`, |
| 995 | ); |
| 996 | } |
| 997 | return; |
| 998 | } |
| 999 | process.stderr.write(`computerd: FUSE trace (${reason})\n${json}\n`); |
| 1000 | }; |
| 1001 | |
| 1002 | if (tracer !== undefined) { |
| 1003 | process.on("SIGUSR2", () => emitTrace("SIGUSR2")); |
| 1004 | } |
| 1005 | |
| 1006 | // fuse-native (libfuse 2.9) doesn't expose big_writes/max_write/max_read |
| 1007 | // through opts, so monkey-patch _fuseOptions() to append them. big_writes |
| 1008 | // lets the kernel batch up to max_write bytes per FUSE op instead of the |
| 1009 | // default 4 KiB, cutting per-op round-trips ~32x on large sequential I/O. |
| 1010 | // buildFuseOptionString reads COMPUTERD_FUSE_* env vars; with none set it |
| 1011 | // emits the production-safe profile (auto_cache plus one-second |
| 1012 | // metadata timeouts) backed by the auto_cache contract tests. |
| 1013 | const origFuseOptions = fuse._fuseOptions.bind(fuse); |
| 1014 | const extraOpts = buildFuseOptionString(process.env); |
| 1015 | fuse._fuseOptions = (): string => { |
| 1016 | const base = origFuseOptions(); |
no test coverage detected