Files
mars-nwe/AI.md
2026-06-20 08:53:56 +02:00

40 KiB

AI working notes for mars-nwe

This file is the handoff and assistant-rule document. It should keep the next chat on the current track without forcing it to reconstruct old patch history. Keep it short enough to read before touching code.

Start of a new chat

  1. Treat mars-nwe-master as the root/superproject. The other mars-* bundles are submodules or sibling component sources needed by the root build.
  2. Read the root *.md files and doc/*.md before changing namespace, salvage, transport or dependency code. The most important active files are TODO.md, REDESIGN.md, ENDPOINTS.md, this file, and:
    • doc/NSS_IMPORT_NOTES.md
    • doc/NWFS_SALVAGE_COMPRESSION_TOOLS.md
    • doc/HANDOFF_AUDIT.md
    • doc/TOOLBOX_PLAN.md
  3. Do not assume an older bundle is current. Use the latest applied user state or the latest bundle/patch explicitly accepted by the user.
  4. For a fresh build in a new chat, check whether prepare-local-deps.sh is present in the root and run/use it before trying to build; it stages the uploaded offline third-party tarballs and local-only headers needed by the current dependency layout.
  5. Default language with the user is German; repository documentation remains English unless the existing file is German.

Documentation ownership

  • TODO.md is the active backlog. The top implementation dashboard is allowed and should stay. Unfinished long-running tracks stay in TODO.md until real implementation/test work closes them.
  • REDESIGN.md is the durable architecture/design record. Put stable plans, rationale and completed design decisions there, not patch chronology.
  • AI.md is for working rules, current handoff state, rejected patches and next action guidance. Keep it concise; do not append duplicate historic handoff dumps forever.
  • ENDPOINTS.md is the decimal/hex NCP audit table.
  • doc/*.md files are focused topic audits/roadmaps. Keep namespace, NSS public-core and salvage/compression/tool details in their matching doc files.

When a TODO is finished, remove it from TODO.md in the same patch and record its stable outcome in REDESIGN.md or the focused doc/*.md file. Do not move unfinished work out of TODO.md merely because its architecture is documented.

Current accepted patch line

Latest commit after this handoff refresh in an up-to-date tree:

  • docs: record NSS salvage repair import milestone

Compare git log -1 --format="%s" with this subject. If the tree is older, check which documentation/import-boundary commits are missing and replay them before starting new work.

Current patch handoff block

Last completed work block: NSS Salvage/ZLSS/Repair userspace runtime import

The code line through 0783 nwnss: use generic NSS runtime naming is accepted. The recent runtime-helper patches added shared NSS page/uaccess helpers and then removed Mars-specific names from the imported NSS path. Inside NSS source and private NSS compat code, use generic NSS-facing names such as NSS_USERSPACE, NSS_VIRTUAL_IO, NSS_BLOCK_IO, NSS_DEFAULT_CODEPAGE, NSS_UNITABLE_DIRS, NSS_UNICODE and NSS_MPK_*. Do not add new MARS_NWE_NWNSS_* guards, nwnss* helper file names or Nwnss* helper symbols in the NSS import itself.

The build/library container is still named nwnss: paths such as src/nwnss/ and include/nwnss/, the CMake target, the mars_nwe::nwnss alias and CTest names like nwnss.unicode may keep that name because this project builds the official NSS code as a MARS-NWE library. The imported code and helper layers inside that container should look like NSS, not like Mars-specific forks.

The companion-file rule remains role-based, not a blanket *Userspace rule: keep original NSS source files as original-like as possible, add only small dispatch points, use *Userspace.c / *Userspace.h for libnwfs/Mars/OtherFS- facing adapter boundaries, use *Io.c / *Io.h for concrete NSS-volume block/image I/O, use *Fuse.c / *Fuse.h for FUSE-facing provider callbacks, and use *Runtime.c / *Runtime.h for NSS runtime/cache/workqueue semantics that replace former kernel helpers inside the library. Shared helpers use Nss* file/symbol names, for example NssPageRuntime and NssUaccessRuntime.

The *Fuse.c / *Fuse.h layer must stay explicit in the tree. It is the place where an NSS provider shape is translated into nwnssmount/FUSE callbacks such as lookup, getattr, readdir, open/read/write and xattr. It must not be folded into *Userspace.c because *Userspace is also used by direct libnwfs/Mars/OtherFS adapter calls that do not mount through FUSE. It must not be folded into *Io.c either: FUSE is the VFS/frontend role; *Io is the lower NSS-volume block/image I/O role.

Ownership boundaries are current: nwserv is the process governor, nwconn is the NCP server, libnwfs is the Mars/NCP file wrapper, libnwnss is the NSS provider and future FUSE/block-I/O/HostFS/OtherFS boundary owner, and future NDS/eDirectory compatibility belongs in libnwnds over libnwdirectory / nwdirectory.

Roadmap staging is explicit: the current product line remains a MARS-NWE 3.x compatibility cleanup. nwfs/Mars continues to handle NetWare metadata, trustees, effective rights, quotas, salvage and namespace behaviour directly while the old NetWare 3.x semantics are made correct and testable. For this line, libnwnss is consumed only through narrow *Userspace.c / *Userspace.h helper APIs and xattr/Netatalk-EA storage helpers. nwnssmount, nwnssadminvol, *Fuse.c callbacks, *Io.c block/image I/O and real NSS-volume provider ownership remain documented 4.x-era rewrite direction, not an active dependency for the 3.x cleanup.

Concrete FUSE-facing binaries are maintainer-only while the 3.x line is active. Do not build, install, auto-start or require nwnssmount, nwnssumount, standalone adminvol drivers or related FUSE helpers in a default build. If such targets exist before the 4.x rewrite, gate them behind MAINTAINER_BUILD and the explicit MARS_NWE_BUILD_NWNSS_FUSE_TOOLS CMake option.

Build/test expectation: the uploaded ncpfs-2.2.7.tar.gz is part of the local dependency set and can be built when full build targets need libncp. Separate build/link success and offline NSS unit tests from server-dependent integration CTests; the latter require a running configured Mars server and should not be reported as ordinary offline unit-test failures.

Salvage/ZLSS/Repair import milestone through 0812

The code line through 0812 imports the first large real-NSS Salvage/Purge/ZLSS runtime slice into libnwnss without link stubs. It includes the original NSS Salvage/Purge logs and trees, ZLSS transaction/log/pool/volume/file-map/free- tree dependencies, VolumeDB/UserTree/DirTree/NameTree/SuperBlock/LogicalVolume helpers, and the first Repair/Maintenance/RAV/ZIOP runtime dependencies. The modern-compiler fixes in this block are intentionally limited to include fixes, NSS_USERSPACE/runtime guards, page/uaccess/runtime routing, and old-style voidfunc_t/statusfunc_t callback casts.

No new NSS dependency stubs were added for this block. When an undefined NSS symbol appears, continue importing the real original source file or public_core/sharedsrc/*.c.h provider before considering any local boundary. Only genuine platform/runtime edges may get local code.

The imported ZLSS code is currently a userspace-runtime compile/link foundation, not an enabled host storage backend. Real NSS disk/block I/O remains behind the existing NSS_BLOCK_IO gate and will use the original zlssBioIO* entry points with a userspace pread/pwrite implementation underneath. Do not add an I/O backend switcher for now: Linux userspace NSS-volume I/O is pread/pwrite, always through the NSS I/O boundary. FUSE remains the future nwnssmount surface for mountable real NSS volumes. OtherFS/HostFS must continue to work directly through the userspace provider path with host xattrs and Netatalk-compatible EAs; do not require FUSE for OtherFS in the current MARS-NWE 3.x line.

Mario's first full test after 0812 reported 71 CTests total, 63 passed and the 8 expected server-dependent *.ncpfs.* tests skipped. Treat this as the current offline green baseline for the import track.

Next import/use-case direction

With the Salvage/ZLSS/Repair runtime buildable and the first XAttr/quota/AFP provider boundaries tested, the next import direction is the source-ordered NSS_VOLUME path rather than another isolated semantic shortcut:

  1. block/file I/O boundary using pread/pwrite against an image or blockdevice, wired under the original zlssBioIO* calls;
  2. ZLSS/ZIO/SBI startup and storage-image access;
  3. LSA super/pool/volume binding;
  4. COMN file, namespace and data-stream operations on that mounted context;
  5. nwnssmount FUSE data-plane surface;
  6. management/list APIs, then create/modify/RAID/snapshot/AdminFS features.

For each area, keep original NSS source semantics in the imported files and put Mars/NWFS/OtherFS/HostFS/FUSE/I/O adaptation in role-specific companion files. Use netware.metadata / netware.userquota.* NSS-shaped xattrs and Netatalk EAs for OtherFS where applicable. Current I/O audit result: BST_read itself is still the original macro in include/nwnss/include/comnBeasts.h and still dispatches through VOLcomnVolOps.VOL_getBeastFromVolume. The current userspace import only prevents disk-backed beast misses while NSS_BLOCK_IO is absent: beastHash.c keeps cache-only behavior and returns zERR_INVALID_BEAST_ID instead of reading a beast from disk, and zlog.c disables flush/barrier writes when no block I/O is present. The real lower I/O choke point is zlssBioIOSync, zlssBioIOData, zlssBioIOBuffer, zlssBioIOPages and zlssBioIOBufferAsync in zlssDev.c; those currently fail under NSS_USERSPACE. When NSS-volume I/O is enabled, keep BST_read and higher ZLSS/COMN flow intact and implement the userspace side of those zlssBioIO* functions with pread/pwrite/fsync. Do not globally macro libc read/write, fread/fwrite or config/table-loader file I/O: only NSS block/image I/O entry points are intercepted.

FUSE is a presentation/mount layer: in real NSS mode it must sit above the explicit I/O backend, and in OtherFS overlay mode it must store metadata on the lower host objects rather than becoming a private side database.

Directory/NDS work order

  • Do not combine LDAPv2/LDAPv3 compatibility work with the FLAIM storage-engine swap. Keep TinyLDAP/nwdirectory on its existing flatfile/mmap/journal backend and add behaviour tests first.
  • LDAP CTests should start nwdirectory on 127.0.0.1:<free-port> with a temporary flatfile workdir and test LDAPv2/LDAPv3 bind/search/unbind.
  • Add libnwnds and console-only nwsetup together after LDAPv2/schema flatfile behaviour is testable. Do not make the first setup path depend on the TUI.
  • Later, add FLAIM storage as CMake-selected parallel backend source files that export the same function names as the flatfile files. Do not break upstreamable flatfile TinyLDAP code.

Rejected or superseded patches that must not be reused as-is:

  • 0380
  • 0398
  • 0403
  • 0677 (ncpNdpUserspace.c collector — rejected; search real NSS sources instead)
  • 0671 (superseded by 0673; virtualIOUserspace.c removed, real sharedsrc/virtualIO.c.h used)

Current immediate direction

The COMN import/audit chain is complete and the current design boundary is the libnwnss userspace backend split. The XAttr/LSA import is now active inside libnwnss; this is not an nwfs migration yet:

  • extAttrBeast.h is at include/nwnss/include/extAttrBeast.h and lsa.h is at include/nwnss/include/lsa.h.

  • 0786 imported the first real NSS XAttr/EA runtime block: include/nwnss/public/zXattr.h, src/nwnss/lsa/lsaXattr.c, include/nwnss/lsa/lsaPrivate.h and src/nwnss/comn/common/extAttrBeast.c.

  • 0788 imported the first real LSA dependency block: src/nwnss/lsa/lsaComn.c, src/nwnss/lsa/lsaErr.c, src/nwnss/lsa/lsaUser.c and include/nwnss/lsa/lsaStartup.h.

  • 0788 also added src/nwnss/lsa/lsaSuperXattr.c as a narrow extraction of the lsaSuper.c helpers needed by lsaXattr.c (getMode, getUid, LSACtimeIsMetadataModTime) without importing the full kernel VFS/superblock module yet. Keep this aligned with the original lsaSuper.c bodies until the full VFS/FUSE/backend boundary is designed.

  • 0790 adds the first explicit XAttr userspace boundary: include/nwnss/internal/lsaXattrUserspace.h and src/nwnss/lsa/lsaXattrUserspace.c. This boundary owns only the kernel-shaped dentry/inode/super-block adapter needed to call the original netware_*xattr entry points from libnwnss. It uses the generic NssUserspaceProvider boundary for provider selection. That provider decision is deliberately not XAttr-specific: it is the shared future decision point for XAttr, trustees, quota, salvage, namespace helpers and real NSS I/O. OtherFS/HostFS must be usable directly through host xattrs or later sidecar metadata; FUSE is not the OtherFS data path. FUSE is reserved for a future mountable real-NSS-volume view, with disk I/O below it going through the original zlssBioIO* path backed by pread/pwrite.

  • Any remaining XAttr/LSA unresolved symbols should be resolved from the real nss.tar.bz2 / nss-common.tar.bz2 NSS sources first. Do not add fake XAttr semantics or Mars-only storage policy to original NSS files.

  • Use Novell/Micro Focus/NDK packages only as documentation/reference, not as code/header provenance.

  • Keep original NSS files original-like. Do not use *Userspace.c / *.h as a catch-all companion name. Use role-specific companion files instead: *Userspace.c / *.h for libnwfs/Mars/OtherFS/HostFS adapter boundaries, *Fuse.c / *.h for FUSE/nwnssmount-facing provider callbacks, *Io.c / *.h for concrete Linux pread/pwrite block/image I/O, and *Runtime.c / *.h for NSS runtime semantics such as cache state, dirty tracking, wait barriers, timers, work queues, HMC/page-cache substitutes and commit/flush coordination. Keep HostFS, OtherFS, FUSE, block I/O and runtime policy out of imported original files. Current imported runtime candidates are: hmc.c (page/slab/highmem/inode-pagecache shim), comnIO.c (kmap/copy-from-user helpers), zAPI.c (uaccess/address-limit helpers), and comnCmdline.c (kernel-style si_meminfo). The current tree routes those through shared NssPageRuntime / NssUaccessRuntime helpers. Reuse these helpers for later imports instead of adding fresh local kernel shims.

  • virtualIO is _ADMIN/management virtual-file and XML datastream I/O, not a disk/block backend. Do not route real NSS block/image I/O through virtualIO or generic libc read/write macros.

  • FUSE has two future roles and must not be treated as the lower block I/O implementation. NSS_FUSE_VOLUME is the Linux VFS mount surface for a real NSS image/blockdevice and therefore depends on the lower pread/pwrite block/image path under zlssBioIO*. OTHERFS_FUSE_OVERLAY is a passthrough/metadata overlay over an existing host filesystem. It stores NSS metadata directly on the lower objects through NSS-shaped xattrs, including Netatalk-compatible AFP EAs, not through a .pxovl-style sidecar tree by default. Both FUSE modes use NSS capability names, but only the real NSS volume path owns native pool/volume/on-disk NSS semantics. Each FUSE mode should have a concrete *Fuse.c / *Fuse.h companion beside the original NSS area it exposes, so the mount callback contract is visible without reading the direct userspace adapter or the lower pread/pwrite block I/O path.

  • Do not touch or migrate the existing local nwfs XAttr code in this phase; for MARS-NWE 3.x, Mars remains the behaviour owner and uses only the narrow *Userspace.c / *Userspace.h helper APIs from libnwnss. Do not activate nwnssmount, nwnssadminvol, *Fuse.c callbacks or real NSS-volume I/O as a prerequisite for the 3.x cleanup.

  • Treat the XAttr/LSA import as the metadata storage/lookup foundation for later quota and salvage userspace boundaries, not as their semantic owner. Quota and salvage remain separate NSS semantic areas, but their valid OtherFS state should be found through NSS-shaped xattrs or NSS metadata. libnwnss owns those provider operations; libnwfs only translates Mars/NCP requests to them.

  • Treat the imported XAttr/LSA block as the first user of the generic userspace provider boundary. For OtherFS, do not require FUSE: read/write NetWare/NSS metadata directly through host xattrs first, and later sidecar metadata where host xattrs are unavailable or insufficient. FUSE is reserved for a future mountable real-NSS-volume view; that path should use the explicit real-NSS *Io.c / zlssBioIO* block/image boundary below the NSS core.

  • For namespace, keep libnwnss as the NSS provider and put Mars/NWFS compatibility wrappers in nwfs later. Most namespace helpers are pure string/provider operations; *_generateUniqueName() needs the same generic userspace companion-file pattern because HostFS/OtherFS directory collision lookup may need NSS-shaped xattrs or NSS metadata and must not be added directly to the original NSS namespace files.

  • Quota, salvage, namespace unique-name handling and future backend-sensitive NSS functions all follow the same ownership split. libnwnss is the NSS provider for semantics imported from nss/nss-common; nwfs is the later Mars wrapper/adapter. Existing nwfs quota and salvage code is only an implementation inventory and must not be treated as provenance or moved wholesale into libnwnss.

  • OtherFS/HostFS quota policy such as Linux quotactl(), project-quota or metadata-only accounting belongs in parallel userspace boundary files such as lsaQuotaUserspace.c or dirQuotasUserspace.c, not inline in original NSS files.

  • Salvage follows the same rule: .salvage JSON is legacy migration/debug state only and should not remain authoritative. .recycle remains the OtherFS payload directory, while valid NetWare salvage metadata should come from NSS-shaped xattrs or later imported NSS salvage metadata through a salvageUserspace.c style boundary.

Before namespace code changes, keep the legacy logging audit in mind: old MARS accepts numeric debug thresholds from 0 to 99, but the actual source mostly uses 1..5. The future nwlog facade should give those normal levels clear semantic names instead of preserving the old overloaded buckets: 1=error, 2=warn, 3=info, 4=debug and 5=trace. debug is local diagnostic detail; trace is packet/message/handoff path following across process or provider boundaries. New config should expose the cumulative numeric masks 0, 1, 12, 123, 1234 and 12345 as synonyms for off, error, warn, info, debug and trace, and use one global [logging] level plus optional [logging.process.<name>] level overrides; the old numeric 100..106 process entries stay accepted for compatibility. Useful legacy 6..99 traces should map to nwlog_detail() later. nwlog_detail() is not part of the normal 1..5 threshold ladder: normal builds return 0, while MAINTAINER_BUILD builds may emit detail whenever such a call site is reached. No INI option may enable it in a normal build. nwlog is the facade/backend plan. Do not add zlog calls or reintroduce a zlog build dependency; zlog is Apache-2.0 and is not compatible with the repository's GPL-2.0-only core policy. See include/nwlog.h and doc/LOG_LEVEL_AUDIT.md.

Before namespace code changes, keep the terminal-tooling decision in mind when touching FLAIM tests or admin tools: do not add new direct curses.h users. Future interactive tools should go through the planned nwtui/nwi18n stack and the multi-call nwtoolbox applet model documented in doc/TOOLBOX_PLAN.md. Configuration parsing/editing is covered in the same file: use the planned shared libnwcore nw_ini_* reader/writer so server code and tools share one policy. Production daemons must not depend on the TUI stack.

Before namespace code changes, use the handoff audit rules in doc/HANDOFF_AUDIT.md. New namespace/NWFS work must not add new magic return(-1) / return(-2) paths. Use the provider names in include/ncp_endpoint.h for audits and future endpoint tables, but do not wire the enum into runtime dispatch until the current nwconn to nwbind handoff sites are annotated.

Then continue the NSS namespace track inside libnwnss:

  1. libnwnss is the single userspace library for imported NSS functions and semantics. Do not create a separate namespace/AdminVol NSS library. The library should grow from the existing imported runtime into the real NSS components needed by Mars NWE: namespace, trustee/effective-rights helpers, XATTR/EA/metadata helpers and later AdminVol semantics.
  2. Work bottom-up from the original NSS Linux sources. Use the files in nss.tar.bz2 and nss-common.tar.bz2; inspect NSS Makefiles/Kbuild-style source lists as well as includes. If a compile or link error reports an unresolved NSS symbol, search for and import the matching real NSS .c and header before considering anything else.
  3. Do not write semantic wrappers or local replacement models for NSS namespace, XATTR, trustee or AdminVol logic. Trustees are serialized through netware.metadata / zNW_metadata_s.nwm_trustee[]; do not invent an active netware.trustees or user.netware.trustees xattr. The only acceptable wrappers/adaptations are narrow userspace ports for kernel/OS boundaries such as spinlocks, allocation, wait/schedule hooks, WIO/console output and similar platform plumbing.
  4. For namespace, target the real public_core/comn/namespace code and its real dependencies under public_core/comn/common, public_core/nss/lib, shared/sdk/include, shared/sdk/internal, shared/sdk/public and shared/sdk/comnSA. Keep the src/nwnss layout aligned with the original public_core tree, and keep the include/nwnss layout aligned with the original shared/sdk tree.
  5. AdminVol is a later target because nameSpace.c reaches AdminVol and AdminVol reaches Beast/common code. Before AdminVol cleanup, import the XATTR/EA/ metadata side into libnwnss from the original NSS archives so later nwfs can consume real NSS structures and functions instead of keeping local semantic copies.
  6. libnwnss must become a userspace NSS semantics library, not a hidden NSS disk implementation. Do not import block-device, VFS or NSS-disk-layout I/O blindly. Preserve original disk/VFS-shaped code where possible, but place HostFS, OtherFS, sidecar, FUSE and block-I/O policy in explicit parallel *Userspace.c / *Userspace.h boundary files. Public userspace APIs should use libnwnss handles or backend contexts, not real Linux-kernel struct dentry, struct inode or struct super_block as ABI.
  7. _ADMIN is expected to become virtual/in-memory semantics in libnwnss and later a userspace nwadminvol process served via IPC from nwconn/nwfs, with the volume-numbering rule SYS = 0, _ADMIN = 1, further volumes from 2.
  8. Keep src/namspace.c as NCP glue over the future namespace engine. Do not expand old MARS namedos/nameos2 as the long-term solution; they are replacement targets.
  9. Namespace pure helpers can stay provider-shaped in libnwnss: compare, wildcard match/replace, ASCII/Unicode conversion, legal-name checks and component scan for DOS, LONG/OS2, UNIX/NFS, MAC, DATASTREAM and EA. *_generateUniqueName() is not a pure string helper; it needs directory uniqueness lookup. Preserve the original NSS namespace files and put HostFS, OtherFS, sidecar or Mars directory-collision policy in a parallel nameSpaceUserspace.c / nameSpaceUserspace.h boundary when that path is implemented.

NCP notation rule

Always write NCP groups/selectors with both decimal and wire/code hex when recording protocol details. Examples:

  • decimal 87 == wire/code 0x57
  • decimal 90/12 == wire/code 0x5a/0x0c
  • decimal 123/70 == wire/code 0x7b/0x46

Use ENDPOINTS.md, the NDK Core Protocols PDF, WebSDK docs and SDK includes as references. NetWare 3.x/default compatibility has priority over broad 4.x/NDS work.

Patch workflow

  • Make small, reviewable patches with one clear subject.
  • Inspect current sources before editing; no speculative patching.
  • Run at least git diff --check before exporting a patch.
  • Also run syntax/build/test checks that match the touched files when feasible.
  • Export only the .patch file by default when producing repository changes. Do not create or link a bundle unless the user explicitly asks for one.
  • Every repository patch must update this AI.md with the new final commit subject in the current patch marker before exporting the patch. If the user later uploads a bundle from their repository, the marker makes that bundle self-identifying even when old chat downloads have expired or are unavailable.
  • Every repository patch must also replace the single Current patch handoff block in this file with a short description of what the patch was meant to do. Replace the old block; do not append a new one for every patch.
  • Always include a copy/paste git am <patch-name>.patch command in the user response next to the patch download link. This is part of the handoff contract, not an optional nicety.
  • Generate patch mail headers with Mario Fetka <mario.fetka@disconnected-by-peer.at> as the author identity, not an AI/OpenAI identity.
  • Do not claim a build/test passed unless it actually ran in the current work tree.

Source/layout rules

  • Keep imported NSS sources in libnwnss, not libnwcore. libnwcore is Mars-core only and must not link against libnwnss merely because NSS runtime code exists. NSS tests should be named nwnss.*; core tests should only cover real Mars core helpers such as INI/logging.
  • Preserve original NSS API names and original filenames wherever possible. Import real NSS files from their provenance paths and keep the new layout recognizable: public_core/library/... -> src/nwnss/library/..., public_core/nss/... -> src/nwnss/nss/..., public_core/comn/... -> src/nwnss/comn/...; shared/sdk/include/... -> include/nwnss/include/..., shared/sdk/internal/... -> include/nwnss/internal/..., shared/sdk/public/... -> include/nwnss/public/..., and shared/sdk/comnSA/... -> include/nwnss/comnSA/....
  • GPL-2.0-only source imports are allowed when the imported source permits GPLv2 use and the original provenance/license headers are preserved. For Linux kernel reference material, record that mars-nwe selects GPL-2.0-only.
  • Clean NSS staging incrementally. Staging/reference copies under nwfs should not remain just because they are confusing; keep only active Mars adaptation code there. When a file is needed, import the real NSS source/header into libnwnss in the provenance-preserving layout.
  • Do not import broad NSS/OES subsystems blindly, but also do not replace missing NSS symbols with local semantic wrappers. Use unresolved symbols and original Makefile object lists to find the next real bottom-up dependency. Only kernel, VFS, memory-tracking and platform hooks may get small userspace glue.
  • include/nwnss/library must not be exported as a PUBLIC CMake include directory. Doing so shadows host headers such as <stdlib.h> and <ctype.h>, breaking tests that depend on include_next or libc symbols. NSS sources inside the build use the private dir; external users reference headers through explicit sub-paths such as <library/xString.h> or <include/omni.h>.
  • include/nwnss/internal/ holds Mars-private NSS compat headers that must not become public API: spinlock.h, nssSourceCompat.h, nssZosCompat.h.
  • src/nwnss/sharedsrc/*.c.h are NSS shared-source implementation fragments. They must stay in the source tree; do not move them to include/.
  • Ports (files not from original NSS archives) must be labeled PORT in nwnss-audit.md with a reason. Known ports: rbpTree.c, rand.c, strtol.c, utcUserland.c, allocator wrappers, wio.c userspace boundary, nebEventPort.c, Unicode TAB data (GENERATED PORT DATA from Unicode.org, not Novell blobs). When a PORT entry is found during audit, search for original .c or sharedsrc/*.c.h before accepting the port as final.
  • For LSA/XAttr/COMN I/O backend work, and for every future NSS function that needs a companion layer, keep imported original files focused on original control flow and small dispatch points. Choose the companion suffix by role: *Userspace.c / *.h is only for libnwfs/Mars-NCP/OtherFS/HostFS-facing adapter boundaries; *Fuse.c / *.h is for FUSE/nwnssmount-facing callbacks; *Io.c / *.h is for concrete Linux pread/pwrite block/image I/O execution; *Runtime.c / *.h is for NSS runtime semantics that replace former kernel helpers inside the library. If both policy selection and direct I/O are needed, the Userspace/Fuse boundary chooses the path and the Io companion performs only the pread/pwrite-specific work. Shared helper files should use Nss* names such as NssBlockIo.c, NssFuse.c or NssRuntime.c, not nwnss* file names. Preprocessor/CMake switches inside the NSS path must also use generic NSS_* names, not MARS_NWE_NWNSS_*. virtualIO is already the NSS _ADMIN/management virtual-file layer; do not reuse that name for future disk/block I/O helpers.
  • *Userspace.c / *Userspace.h companion files are ALLOWED only when they sit alongside the matching imported original and carry libnwfs/Mars-NCP/OtherFS/ HostFS adaptation that must not go inline, for example nameSpaceUserspace.c, lsaXattrUserspace.c, dirQuotasUserspace.c or salvageUserspace.c. Collector/stub-filler files such as the rejected ncpNdpUserspace.c or the superseded virtualIOUserspace.c are FORBIDDEN: a *Userspace.c that exists only to provide symbols that should come from a real original .c or sharedsrc/*.c.h is a stub depot. Always search the original archives first.
  • Default libnwnss may use: AdminVol, AdminFS, VirtualIO (management/template/ function data streams), in-memory/callback streams, and pure NSS management callbacks. Real NSS disk-layout I/O, block-device I/O, Kernel VFS I/O, and cache/file-handle paths that go directly to disk/block/kernel FS require the NSS_BLOCK_IO guard and the pread/pwrite userspace zlssBioIO* implementation. Do not route backend storage through virtualIO; that name is taken. Do not use NOT_SUPPORTED to silence Virtual/AdminVol/Callback-IO paths; guard only real block/disk paths.
  • libnwfs is the Mars/NCP file compatibility wrapper, not the NSS provider and not the owner of future storage backends. It translates Mars/NCP file, namespace, quota, salvage, stream and XAttr operations into libnwnss provider calls, then adapts the result to Mars wire/reply and host persistence rules. Existing half-finished nwfs staging remains ignored during libnwnss import work and should later be removed, replaced or adapted as wrapper code.
  • libnwnss owns NSS provider semantics and the future real NSS backend boundaries. Keep their companion roles distinct: *Userspace.c / *.h for libnwfs/Mars/OtherFS/HostFS adaptation, *Fuse.c / *.h for nwnssmount/FUSE callbacks, *Io.c / *.h for concrete pread/pwrite block/image I/O, and *Runtime.c / *.h for NSS cache/workqueue/wait/dirty runtime semantics. nwnssmount is the future FUSE mount consumer of libnwnss; nwnssmu is the future TUI management utility for admin, inspect, repair, quota, salvage, namespace and XAttr operations.
  • libnwbind is for bindery identity/storage. NDS/eDirectory compatibility belongs in a future libnwnds, backed by libnwdirectory; nwdirectory is the LDAP/TinyLDAP-based directory server. An nwnds process may be added later only when cross-process NDS state, caching, auth brokering, events or background jobs need a supervised service.

Service and provider ownership rules

  • nwserv is the governor/control-plane supervisor for the Mars process tree. It starts and monitors processes such as nwconn, nwdirectory and later optional provider services. It is not the NCP server and should not become the normal data-plane router for decoded NCP payloads.

  • nwconn is the NCP server process. It owns client NCP request parsing and NCP reply construction. For file/volume operations it should call libnwfs; for future NDS/eDirectory identity, authentication, trustee and security equivalence work it should call libnwnds.

  • libnwfs is the Mars/NCP file wrapper around libnwnss. Keep Mars wire parsing, NCP reply packing, Mars volume options and HostFS/OtherFS adaptation there; keep NSS semantics in libnwnss.

  • libnwnds is the planned NDS/eDirectory compatibility library. It translates NetWare concepts such as DN, GUID, UserID, Security Equivalence Vector, tree context, object/class/attribute mapping and trustee identity lookup to libnwdirectory. Do not hide LDAP/eDirectory policy in libnwnss or libnwfs.

  • libnwdirectory is the library/client layer for nwdirectory; nwdirectory is the LDAP/TinyLDAP-based directory server.

  • NSS headers such as eDir.h, ncpIDAPI.h and ndp_idbroker.h are boundary references for GUID/DN/UserID/SEV mapping. They are not a full eDirectory backend and should point toward libnwnds, not toward new directory policy in libnwnss.

  • NSS encp.h is useful as an NCP wire/layout reference for Mars header convergence, especially namespace, quota, trustee and salvage layouts. Do not cast Mars byte buffers directly to imported NSS structs; use byte-safe parser/builder wrappers or compatibility aliases.

  • _ADMIN / AdminVolume is a Mars-NWE/NCP server service, not a side effect of an individual data-volume mount. The planned nwnssadminvol service is started and owned by nwserv; it publishes the visible _ADMIN view for that Mars-NWE instance and collects provider/volume registrations from nwnssmount processes. A volume mounted from /etc/fstab must work before nwserv is running: nwnssmount records a runtime mount descriptor and optional control socket under /run/nwnss/, then nwnssadminvol discovers and binds it later when nwserv starts.

  • There must be only one visible AdminVolume owner for one Mars-NWE/NCP server namespace. Do not publish a nwnss FUSE _ADMIN and an original Kernel-NSS _ADMIN as competing roots. A later nwnssadminvol may read the Kernel-NSS admin volume and expose those pools/volumes as imported read-only or explicit proxy records, but it must keep owner=KERNEL_NSS metadata and must not treat them as native nwnss volumes.

Namespace rules

  • Do not expand old MARS namedos/nameos2 as the long-term solution. They are replacement targets.
  • Import/adapt the NSS namespace engine directly in libnwnss, then retire old MARS namespace logic after tests cover DOS/LONG behaviour. Missing namespace dependencies must be resolved from the original NSS sources, not by adding replacement wrappers.
  • Stable namespace state belongs in netware.metadata: file ID, parent file ID, DOS name, LONG/OS2 name, MAC name, UNIX/backend name, casefold/hash fields and namespace flags. *_generateUniqueName() must use the generic userspace companion-file pattern when it needs HostFS/OtherFS directory collision lookup or metadata/xattr-backed namespace state; do not put that lookup directly into the original NSS namespace source files.
  • Existing Linux files created by Samba, rsync or local admin tools must be reconciled by libnwfs watcher/scanner work, not by a private side database.
  • MAC namespace is a namespace/stream/metadata problem, not a transport problem. Resource forks and Finder info belong in streams/metadata later.

Salvage/recycle rules

  • Keep .recycle as the Samba-compatible deleted-payload backend.
  • Make netware.metadata on the recycled payload authoritative for deleted state.
  • Treat .salvage JSON as legacy migration/debug data only; do not make it a second long-term authority.
  • Samba vfs_recycle normally uses rename, so xattrs remain attached to the recycled inode. Manually copied files in .recycle without netware.metadata are not valid NetWare salvage objects unless an explicit admin repair tool marks them.
  • If a compressed file is recycled, the .recycle payload should be a normal uncompressed Linux file; keep previous compression state in netware.metadata.

Compression and stream rules

  • Compression belongs in libnwfs, not libnwcore.
  • Future private stream/compression data belongs under .nwfs_streams/<stable-file-id>/....
  • The stable file ID comes from MARS/NWFS/NSS-shaped metadata, not from Linux inode numbers and not from visible filenames.
  • Do not encode compression state in visible names such as compressed_*.

Transport rules

  • TCP/IP is implemented in libnwtransport, a library that nwconn links against; it is not a new daemon.
  • Planned files: src/nwtransport.c, src/nwipx.c, later src/nwtcp.c.
  • NCP providers stay transport-neutral: IPX/TCP -> nwtransport -> nwconn -> dispatcher -> providers.
  • Use audited libowfat API names from the bundled mars-libowfat source: socket_tcp4(), socket_tcp6(), socket_bind4_reuse(), socket_bind6_reuse(), socket_listen(), nonblocking accept helpers and io_* readiness helpers.
  • IPX config sections use frame tokens without dots: 8022, 8023, etherii, snap, tr8022, auto.
  • [transport.ipx.local] is the internal network; explicit routes use [transport.ipx.route.<target>].
  • If IPX is requested but socket(AF_IPX, ...) fails, report that AF_IPX is unavailable instead of silently falling back.
  • A future L2 IPX backend is allowed, but it is an additional backend below nwtransport, not a replacement for the kernel path. Start with Ethernet_II IPX, SAP/RIP, and NCP socket 0x0451.
  • Do not vendor a capability library for L2 IPX. Open the packet socket and report missing CAP_NET_RAW/CAP_NET_ADMIN; root, setcap, or systemd capabilities are deployment policy.
  • Do not copy GPL-3.0-or-later code from the Rust nwserver reference. Use only the observed architecture: userland Ethernet/IPX packet handling, SAP/RIP, and NCP socket dispatch.
  • SPX, if needed, is a later userland layer above IPX. Do not rely on kernel SPX and do not make namespace work wait for SPX.
  • Linux 2.4.37.9 SPX is imported only as reference material in src/kernel/af_spx.c and include/kernel/spx.h; do not build it as-is.

Dependency/source bundle rules

  • mars-nwe-master is the root repository.
  • Uploaded mars-* bundles are submodules/sibling components needed in the configured locations.
  • Offline point-release tarballs are staged by prepare-local-deps.sh. In a new chat or clean checkout, use this script as the first dependency/bootstrap step before CMake/build attempts:
    • yyjson-0.12.0 into third_party/yyjson
    • libsodium-1.0.20 into the nested libsodium snapshot path
    • gdbm-1.26 built locally under .local-deps/prefix
    • PAM and ncurses headers staged while linking to system libraries
  • Do not vendor random system headers directly into endpoint/provider code.

Reference archives

The following archives were used for the NSS import/audit work and are available for further namespace implementation and NCP structure verification:

  • nss-common.tar.bz2
  • nss.tar.bz2
  • ncp__enu.pdf
  • websdk.tar.gz
  • include.tar.gz

Networked CTest skip policy

Server-dependent NCPFS/AFP/salvage/quota smokes must be visible in CTest but must not fail ordinary offline builds. Register them with the networked;integration labels and SKIP_RETURN_CODE 77. The test launcher prints SKIP/WARN and exits 77 unless MARS_NWE_RUN_NETWORKED_TESTS=1 and the required MARS_NWE_TEST_* environment variables are present. Use ctest -LE networked for offline unit coverage and ctest -L networked for server-backed integration runs. When the TCP/IP transport test harness lands, these CTest entries become the path for real local execution.