Documentation
¶
Overview ¶
Package squashfs is a pure-Go, read-only driver for the SquashFS 4.0 on-disk format produced by mksquashfs. It parses the superblock, metadata-backed inode and directory tables, file data blocks and tail-end fragments, and decompresses gzip/zlib-compressed (and uncompressed) metadata and data. SquashFS is an inherently read-only archive format; every mutating method of filesystem.Filesystem returns ErrReadOnly.
Index ¶
- Constants
- Variables
- func BuildFromDir(imgPath, srcDir string, opts BuildOptions) error
- func OpenReader(r io.ReaderAt, size int64) (filesystem.Filesystem, error)
- type BuildOptions
- type Compressor
- type FS
- func (fs *FS) Close() error
- func (fs *FS) DeleteDir(string) error
- func (fs *FS) DeleteFile(string) error
- func (fs *FS) ListDir(path string) ([]filesystem.DirEntry, error)
- func (fs *FS) MkDir(string, os.FileMode) error
- func (fs *FS) OpenFile(path string) (filesystem.File, error)
- func (fs *FS) ReadFile(path string) ([]byte, error)
- func (fs *FS) ReadFileLimit(path string, max int64) ([]byte, error)
- func (fs *FS) ReadLink(path string) (string, error)
- func (fs *FS) Rename(string, string) error
- func (fs *FS) Stat(path string) (filesystem.Stat, error)
- func (fs *FS) Superblock() *Superblock
- func (fs *FS) WriteFile(string, []byte, os.FileMode) error
- func (fs *FS) Xattrs(path string) (map[string][]byte, error)
- type Superblock
Constants ¶
const DefaultMaxReadFile int64 = 1 << 30
DefaultMaxReadFile is the largest file ReadFile will assemble in memory, 1 GiB. A SquashFS file can legitimately expand a very long way (a sparse block costs 4 bytes of block list, and the block list itself is compressed), so no structural bound relates the image's size to the file's; a ceiling is the only protection. Larger files stream through OpenFile and ReadAt, or raise the ceiling with ReadFileLimit.
const Magic = 0x73717368
Magic is the SquashFS superblock magic, "hsqs" in little-endian.
Variables ¶
var ( // ErrReadOnly is returned by every mutating method (WriteFile, MkDir, // DeleteFile, DeleteDir, Rename). SquashFS is a read-only archive. ErrReadOnly = errors.New("squashfs: filesystem is read-only") // ErrBadMagic is returned when the superblock magic is not "hsqs". ErrBadMagic = errors.New("squashfs: bad superblock magic") // ErrUnsupportedVersion is returned for any on-disk version other than 4.0. ErrUnsupportedVersion = errors.New("squashfs: unsupported version (only 4.0)") // ErrUnsupportedCompression is returned when the image uses a compressor // this driver cannot yet decode. ErrUnsupportedCompression = errors.New("squashfs: unsupported compression") // ErrNotFound is returned when a path component cannot be located. ErrNotFound = fmt.Errorf("squashfs: path not found: %w", iofs.ErrNotExist) // ErrNotDirectory is returned when ListDir targets a non-directory. ErrNotDirectory = errors.New("squashfs: not a directory") // ErrNotRegular is returned when ReadFile targets a non-regular file. ErrNotRegular = errors.New("squashfs: not a regular file") // ErrNotSymlink is returned when ReadLink targets a non-symlink. ErrNotSymlink = errors.New("squashfs: not a symbolic link") // ErrTooManyLinks is returned when path resolution exceeds the symlink hop // limit, indicating a loop. ErrTooManyLinks = errors.New("squashfs: too many symbolic link traversals") // ErrTooLarge is returned when a structure the image declares (a file's // contents for ReadFile, a directory listing, an attribute list) would // exceed a configured or built-in ceiling. It is returned before the // memory is allocated. Use OpenFile / ReadAt to stream a large file, or // ReadFileLimit to choose the ceiling. ErrTooLarge = errors.New("squashfs: declared size exceeds the limit") // ErrCorrupt is returned when an on-disk structure fails a sanity check. ErrCorrupt = errors.New("squashfs: corrupt image") )
Sentinel errors returned by the SquashFS driver. Compare with errors.Is so wrapped errors continue to match.
Functions ¶
func BuildFromDir ¶
func BuildFromDir(imgPath, srcDir string, opts BuildOptions) error
BuildFromDir creates a SquashFS image at imgPath from the directory tree rooted at srcDir. It is the write-side counterpart of the reader: the result is a standard SquashFS 4.0 image that unsquashfs (and this package) can read.
func OpenReader ¶ added in v0.3.0
func OpenReader(r io.ReaderAt, size int64) (filesystem.Filesystem, error)
OpenReader opens the SquashFS filesystem at the start of r, exactly as Open does, and returns it as a filesystem.Filesystem.
It exists so every driver in go-filesystems answers to ONE name for the same thing. github.com/go-filesystems/detect's Opener is func(io.ReaderAt, int64) (filesystem.Filesystem, error): Open here is the right shape but returns a concrete *FS, which is a different type and does not fit. The drivers that could only be opened from a PATH have grown this function; this one is that same function, so a caller can write
detect.Register(detect.T, driver.OpenReader)
for every driver instead of a closure per driver.
The concrete type is still there for a caller that wants what it has beyond the common interface: Open returns it.
Types ¶
type BuildOptions ¶
type BuildOptions struct {
// Uncompressed stores metadata and data blocks without compression.
// When set it overrides Compressor.
Uncompressed bool
// Compressor selects the block compressor. The zero value is gzip
// (zlib), matching mksquashfs's default. Ignored when Uncompressed is set.
Compressor Compressor
// NoFragments disables fragment packing, reverting to the legacy behaviour
// where every regular file is stored as full data blocks. When false
// (default) the tails of files smaller than one block, and whole sub-block
// files, are packed into shared fragment blocks to shrink the image.
NoFragments bool
}
BuildOptions configures image creation.
type Compressor ¶
type Compressor uint16
Compressor selects the block compressor used by BuildFromDir. It mirrors the compression ids stored in the superblock. Only encoders the package can also decode are offered; LZO is read-only (no Go encoder available) and LZMA (legacy) is not produced.
const ( CompressGZIP Compressor = compGZIP // raw zlib stream (mksquashfs default) CompressZSTD Compressor = compZSTD CompressXZ Compressor = compXZ CompressLZ4 Compressor = compLZ4 )
Supported write compressors.
type FS ¶
type FS struct {
// contains filtered or unexported fields
}
FS is an opened, read-only SquashFS 4.0 filesystem.
The struct holds an io.ReaderAt, the decoded superblock and the block decompressor. All traversal is recomputed per call from the on-disk tables — no caches, no locks — which keeps the reader trivially safe for concurrent use against a frozen image.
func Open ¶
Open parses the SquashFS superblock at offset 0 and returns a read-only handle. The caller retains ownership of rs unless it also implements io.Closer, in which case Close is forwarded. Pass size = -1 if unknown.
func OpenFile ¶
OpenFile opens path read-only and wires it into Open. The returned FS owns the file handle and closes it on Close.
func (*FS) DeleteFile ¶
func (*FS) ListDir ¶
func (fs *FS) ListDir(path string) ([]filesystem.DirEntry, error)
ListDir enumerates the entries of the directory at path. SquashFS does not store "." or ".." entries, so they are absent from the result.
func (*FS) OpenFile ¶ added in v0.2.0
func (fs *FS) OpenFile(path string) (filesystem.File, error)
OpenFile opens the regular file at path for random access, following symlinks exactly as ReadFile does.
It decodes the inode and computes the prefix sum of the block list — the map — but reads and decompresses no file data.
func (*FS) ReadFile ¶
ReadFile returns the full contents of the regular file at path. Symlinks, including a final-component symlink, are followed.
A file larger than DefaultMaxReadFile (1 GiB) is refused with ErrTooLarge before any memory is allocated: the image declares the size, and a few kilobytes of sparse block list can declare terabytes. Use ReadFileLimit to choose the ceiling, or OpenFile to stream.
func (*FS) ReadFileLimit ¶ added in v0.5.0
ReadFileLimit is ReadFile with a caller-chosen ceiling on the file's size, in bytes; a file the inode declares larger returns ErrTooLarge without allocating. A negative max disables the ceiling.
func (*FS) ReadLink ¶
ReadLink returns the target of the symbolic link at path; the final component is not followed.
func (*FS) Stat ¶
func (fs *FS) Stat(path string) (filesystem.Stat, error)
Stat resolves path (following symlinks) and returns mode, size and inode.
func (*FS) Superblock ¶
func (fs *FS) Superblock() *Superblock
Superblock returns the decoded superblock. The pointer is owned by FS.
func (*FS) Xattrs ¶
Xattrs resolves path (following symlinks) and returns its extended attributes, keyed by fully-qualified name (with the namespace prefix, e.g. "user.comment") and mapped to the raw value bytes.
A nil map (and nil error) is returned when the node has no attributes or the image carries no xattr table. Only the extended inode variants store an xattr index, so basic inodes always report none.
type Superblock ¶
type Superblock struct {
Magic uint32 // 0x00
InodeCount uint32 // 0x04
ModTime uint32 // 0x08 (unix seconds)
BlockSize uint32 // 0x0C
FragCount uint32 // 0x10
Compression uint16 // 0x14
BlockLog uint16 // 0x16 (log2 BlockSize)
Flags uint16 // 0x18
IDCount uint16 // 0x1A
VersionMajor uint16 // 0x1C
VersionMinor uint16 // 0x1E
RootInode uint64 // 0x20 (inode reference)
BytesUsed uint64 // 0x28
IDTableStart uint64 // 0x30
XattrTableStart uint64 // 0x38
InodeTableStart uint64 // 0x40
DirTableStart uint64 // 0x48
FragTableStart uint64 // 0x50
LookupTableStart uint64 // 0x58
}
Superblock is the decoded SquashFS 4.0 superblock (little-endian on disk). Field order and offsets mirror struct squashfs_super_block.
