Documentation
¶
Overview ¶
Package confinedfs provides held-root, root-relative filesystem operations. It deliberately accepts only portable relative paths and plain directories or regular files at governed boundaries.
Index ¶
- Variables
- func OutputLockRootsEqual(left, right string) (bool, error)
- func ValidatePortablePath(value string) (string, error)
- type AtomicWriteResult
- type Error
- type ErrorCode
- type Identity
- type OutputLock
- type OutputLockBusyError
- type OutputLockLease
- type Root
- type Transaction
- func (t *Transaction) Close() error
- func (t *Transaction) CreatePrivateDirectory(prefix string) (string, error)
- func (t *Transaction) Exists(relative string) (bool, os.FileInfo, error)
- func (t *Transaction) Lstat(relative string) (os.FileInfo, error)
- func (t *Transaction) MkdirAll(relative string, mode os.FileMode) error
- func (t *Transaction) Name() string
- func (t *Transaction) ReadStable(relative string) ([]byte, os.FileInfo, error)
- func (t *Transaction) ReadStableBounded(relative string, maxBytes int64) ([]byte, os.FileInfo, error)
- func (t *Transaction) RemoveRegularFile(relative string, expected os.FileInfo) error
- func (t *Transaction) RemoveTree(relative string) error
- func (t *Transaction) Rename(oldRelative, newRelative string) (installed bool, returnErr error)
- func (t *Transaction) RenameHeld(oldRelative, newRelative string) (installed bool, returnErr error)
- func (t *Transaction) SyncDirectory(relative string) (supported bool, returnErr error)
- func (t *Transaction) TryAcquireOutputLock(outputRoot string) (*OutputLock, error)
- func (t *Transaction) VerifyPathIdentity() error
- func (t *Transaction) Walk(relative string) ([]TreeEntry, error)
- func (t *Transaction) WriteFileExclusive(relative string, data []byte, mode os.FileMode) error
- func (t *Transaction) WriteFileExclusiveStream(relative string, mode os.FileMode, write func(io.Writer) error) error
- type TreeEntry
- type View
- func (v View) Identity(relative string) (Identity, error)
- func (v View) Lstat(relative string) (os.FileInfo, error)
- func (v View) Open(relative string) (*os.File, error)
- func (v View) Prefix() string
- func (v View) Sub(relative string) (View, error)
- func (v View) WriteAtomic0600(relative string, data []byte) (result AtomicWriteResult, returnErr error)
- func (v View) WriteAtomic0600NoReplace(relative string, data []byte) (result AtomicWriteResult, returnErr error)
Constants ¶
This section is empty.
Variables ¶
var ErrOutputLockBusy = errors.New("output lock busy")
ErrOutputLockBusy is matched by OutputLockBusyError when another process or transaction already owns the lock for the same held workspace and output root. Acquisition is deliberately non-blocking.
Functions ¶
func OutputLockRootsEqual ¶
OutputLockRootsEqual reports whether two portable output-root spellings map to the same platform lock identity. Recovery admission must use this same comparison so a filesystem alias cannot acquire the shared lock and then bypass the journal belonging to that physical output.
func ValidatePortablePath ¶
ValidatePortablePath returns the canonical spelling of a slash-separated relative path that is safe on every supported platform.
Types ¶
type AtomicWriteResult ¶
type AtomicWriteResult struct {
Installed bool
FileSynced bool
DirectorySynced bool
PermissionsVerified bool
}
AtomicWriteResult distinguishes a pre-install failure from a failure after rename. DirectorySynced is false without error on platforms/filesystems that cannot durably flush directory metadata.
type Error ¶
Error is returned for every package-level validation or I/O failure. Installed is set only when an atomic write completed its rename before a later durability or root-identity check failed.
type ErrorCode ¶
type ErrorCode string
ErrorCode classifies a fail-closed confined filesystem decision.
type Identity ¶
type Identity struct {
Scheme string `json:"scheme"`
Volume uint64 `json:"volume"`
File uint64 `json:"file"`
}
Identity is a same-filesystem identity for a directory or regular file while a surrounding operation still holds and revalidates the object. Filesystems may reuse it after handle close, so it is neither a durable journal key nor an authorization credential.
type OutputLock ¶
type OutputLock struct {
// contains filtered or unexported fields
}
OutputLock owns one operating-system advisory lock. Lock files are retained after release: unlinking a lock file can split future contenders across different file objects while an existing owner still holds the old one.
func (*OutputLock) Borrow ¶
func (l *OutputLock) Borrow(transaction *Transaction, expectedOutputRoot string) (*OutputLockLease, error)
Borrow proves that transaction belongs to the same held workspace object and expected output root as this still-live lock. The lease holds a read borrow on the lock until Close, so concurrent Release cannot invalidate an authorization between verification and consumption.
func (*OutputLock) Close ¶
func (l *OutputLock) Close() error
Close is an alias for Release and is also idempotent.
func (*OutputLock) OutputRoot ¶
func (l *OutputLock) OutputRoot() string
OutputRoot returns the canonical portable output root guarded by the lock.
func (*OutputLock) Release ¶
func (l *OutputLock) Release() error
Release unlocks and closes the underlying file handle. It is safe to call concurrently or more than once; every call observes the same result.
type OutputLockBusyError ¶
OutputLockBusyError reports non-blocking lock contention without collapsing it into an I/O failure.
func (*OutputLockBusyError) Error ¶
func (e *OutputLockBusyError) Error() string
func (*OutputLockBusyError) Is ¶
func (e *OutputLockBusyError) Is(target error) bool
Is permits errors.Is(err, ErrOutputLockBusy).
type OutputLockLease ¶
type OutputLockLease struct {
// contains filtered or unexported fields
}
OutputLockLease is a copy-safe proof that one exact held transaction still owns the advisory lock for one output root. Copies share close state; closing any copy invalidates all of them and unblocks OutputLock.Release.
func (*OutputLockLease) Close ¶
func (l *OutputLockLease) Close() error
Close releases only the in-process borrow. The caller that acquired the OutputLock still owns and must release the operating-system advisory lock.
func (*OutputLockLease) OutputRoot ¶
func (l *OutputLockLease) OutputRoot() string
func (*OutputLockLease) Verify ¶
func (l *OutputLockLease) Verify(transaction *Transaction, expectedOutputRoot string) error
Verify re-proves the transaction path identity and exact output root while the underlying advisory lock remains borrowed.
type Root ¶
type Root struct {
// contains filtered or unexported fields
}
Root owns one held os.Root for the lifetime of a governed filesystem operation. Relative Views borrow this root and never open a weaker path-based security boundary.
func Open ¶
Open validates and opens an existing plain-directory root. The before/open/ after identity checks detect replacement of the named root while it is opened. Every ancestor must also be a plain directory; Windows junctions are therefore rejected even when Go reports them as ModeIrregular rather than ModeSymlink.
func (*Root) BeginTransaction ¶
func (r *Root) BeginTransaction() (*Transaction, error)
BeginTransaction borrows the held root until Transaction.Close. The named root must still identify the held directory when the borrow begins.
func (*Root) RootIdentity ¶
RootIdentity returns the platform identity captured from the held root.
func (*Root) VerifyPathIdentity ¶
VerifyPathIdentity proves that the original root name still resolves through plain ancestors to the exact directory held by this Root. Operations remain confined to the held object even if this check fails; callers receive a typed failure rather than treating a renamed workspace as committed.
type Transaction ¶
type Transaction struct {
// contains filtered or unexported fields
}
Transaction is a borrowed, handle-relative mutation boundary beneath one held Root. It never exposes the underlying os.Root or converts governed operations back to the Root's original pathname. Close releases the borrow; it does not close the owning Root.
The named root may be checked explicitly with VerifyPathIdentity. Other methods deliberately continue to address the held directory object after a rename so rollback and cleanup cannot be redirected into a replacement at the old pathname. TryAcquireOutputLock provides the cross-process primitive, but callers must acquire it explicitly; other Transaction methods do not implicitly serialize an uncooperative writer inside the same held root.
func (*Transaction) Close ¶
func (t *Transaction) Close() error
Close ends the transaction borrow. It is safe to call more than once.
func (*Transaction) CreatePrivateDirectory ¶
func (t *Transaction) CreatePrivateDirectory(prefix string) (string, error)
CreatePrivateDirectory creates a unique 0700 directory directly beneath the held root. Prefix must be one portable path segment.
func (*Transaction) Exists ¶
Exists reports whether a plain directory or regular file exists. Unsafe entries are errors rather than successful existence observations.
func (*Transaction) Lstat ¶
func (t *Transaction) Lstat(relative string) (os.FileInfo, error)
Lstat observes a plain directory or regular file without following the final component. Parent components must be plain directories.
func (*Transaction) MkdirAll ¶
func (t *Transaction) MkdirAll(relative string, mode os.FileMode) error
MkdirAll creates a portable directory chain beneath the held root and rejects links or non-directory components before and after each creation.
func (*Transaction) Name ¶
func (t *Transaction) Name() string
Name returns the original absolute display name of the held root. It is never used as an operating-system input by Transaction methods.
func (*Transaction) ReadStable ¶
ReadStable reads one plain regular file and proves that both its held handle and root-relative name remained bound to the same object for the read.
func (*Transaction) ReadStableBounded ¶
func (t *Transaction) ReadStableBounded(relative string, maxBytes int64) ([]byte, os.FileInfo, error)
ReadStableBounded preserves ReadStable's held-file identity checks while rejecting files larger than maxBytes before reading their content. The read itself is also bounded if an uncooperative writer grows the file after open.
func (*Transaction) RemoveRegularFile ¶
func (t *Transaction) RemoveRegularFile(relative string, expected os.FileInfo) error
RemoveRegularFile removes one previously observed regular entry. It never recursively removes a replacement directory. Callers serialize governed writers with the existing output lock; this observation is not a lock against arbitrary filesystem writers.
func (*Transaction) RemoveTree ¶
func (t *Transaction) RemoveTree(relative string) error
RemoveTree removes a private plain tree beneath the held root. It never follows links and verifies each directory handle against its name before removing that name. The root itself (.) cannot be removed.
func (*Transaction) Rename ¶
func (t *Transaction) Rename(oldRelative, newRelative string) (installed bool, returnErr error)
Rename moves one plain entry between two root-relative names. The destination must not exist, and the platform operation enforces that constraint atomically. installed is true once the confined rename succeeded, including when a later identity check fails. Rename finally re-proves that the original root pathname still names the held directory, so a caller that publishes with this rename observes a replaced root.
func (*Transaction) RenameHeld ¶
func (t *Transaction) RenameHeld(oldRelative, newRelative string) (installed bool, returnErr error)
RenameHeld applies Rename's handle-relative, no-replace and entry identity guarantees but does not re-prove the root pathname. Multi-step transactions use it so journal, rollback and cleanup renames keep operating on the held directory after its pathname was replaced; such callers must perform their own explicit VerifyPathIdentity at the commit point.
func (*Transaction) SyncDirectory ¶
func (t *Transaction) SyncDirectory(relative string) (supported bool, returnErr error)
SyncDirectory flushes one held root-relative directory after a metadata mutation. Supported is false, without weakening confinement, when the platform/filesystem cannot provide a directory durability primitive.
func (*Transaction) TryAcquireOutputLock ¶
func (t *Transaction) TryAcquireOutputLock(outputRoot string) (*OutputLock, error)
TryAcquireOutputLock acquires an exclusive advisory lock for outputRoot without waiting. Its identity is derived from both the held workspace object and the canonical output root, so different output roots remain independent.
The persistent lock file lives beneath a fixed private workspace control directory, never beneath the output tree that an installer may swap.
func (*Transaction) VerifyPathIdentity ¶
func (t *Transaction) VerifyPathIdentity() error
VerifyPathIdentity proves that the original pathname still identifies the held root. A failure does not weaken the handle boundary: callers can still use the transaction to perform rollback and cleanup before Close.
func (*Transaction) Walk ¶
func (t *Transaction) Walk(relative string) ([]TreeEntry, error)
Walk returns a deterministic point-in-time traversal rooted at relative. It rejects symlinks, reparse-like irregular entries, devices, and sockets.
func (*Transaction) WriteFileExclusive ¶
WriteFileExclusive creates, writes, syncs, chmods, and closes one new plain regular file beneath an existing directory chain. It never truncates or replaces an existing entry.
func (*Transaction) WriteFileExclusiveStream ¶
func (t *Transaction) WriteFileExclusiveStream(relative string, mode os.FileMode, write func(io.Writer) error) error
WriteFileExclusiveStream applies the same held-root and exclusive-file guarantees to streamed data, without buffering an archive in memory. The callback must return only after all encoders have been closed.
type TreeEntry ¶
TreeEntry is one point-in-time observation from Walk. Path is portable and relative to the held root. Info always describes a plain directory or plain regular file; links and irregular entries fail the walk closed.
type View ¶
type View struct {
// contains filtered or unexported fields
}
View is a portable relative prefix borrowed from one held Root.
func (View) Identity ¶
Identity returns a diagnostic, short-lived platform identity for a plain directory or regular file. The target handle is closed before return, so the value must not become a journal, CAS, or authorization identity.
func (View) Lstat ¶
Lstat returns a point-in-time observation without following the final link. It is not a tree snapshot or authorization proof. All parent components must be plain directories while this operation holds its root lease.
func (View) WriteAtomic0600 ¶
func (v View) WriteAtomic0600(relative string, data []byte) (result AtomicWriteResult, returnErr error)
WriteAtomic0600 writes bytes through an exclusive temporary file, syncs and closes its handle, and replaces the target relative to one held parent. The parent must already exist. Until the transaction layer adds locking and CAS recovery, callers may use this only in a private staging tree without concurrent writers.
func (View) WriteAtomic0600NoReplace ¶
func (v View) WriteAtomic0600NoReplace(relative string, data []byte) (result AtomicWriteResult, returnErr error)
WriteAtomic0600NoReplace publishes a fully written 0600 file through a same-parent hard link. The link is the atomic commit point and fails if the destination appeared concurrently; an existing file is never replaced.