fix: populate ctime from platform-specific syscall data
All checks were successful
check / check (pull_request) Successful in 4m19s
All checks were successful
check / check (pull_request) Successful in 4m19s
The scanner was setting CTime to info.ModTime() as a placeholder since afero's FileInfo interface doesn't expose ctime directly. This change extracts the actual ctime from the underlying syscall.Stat_t via platform-specific build files: - macOS (Darwin): uses Birthtimespec (file creation/birth time) - Linux: uses Ctim (inode change time) - Other platforms: falls back to mtime Also adds: - Documentation of ctime semantics in README.md (new 'file metadata' section) - Platform differences table (macOS birth time vs Linux inode change time) - Note that ctime is recorded but not restored (not settable via standard APIs) - Updated README schema to match actual schema (adds ctime, source_path, link_target) - Doc comment on CTime field in database model closes #13
This commit is contained in:
46
README.md
46
README.md
@@ -194,8 +194,11 @@ vaultik [--config <path>] store info
|
||||
* Requires `VAULTIK_AGE_SECRET_KEY` environment variable with age private key
|
||||
* Optional path arguments to restore specific files/directories (default: all)
|
||||
* Downloads and decrypts metadata, fetches required blobs, reconstructs files
|
||||
* Preserves file permissions, timestamps, and ownership (ownership requires root)
|
||||
* Preserves file permissions, timestamps (mtime), and ownership (ownership requires root)
|
||||
* Handles symlinks and directories
|
||||
* Note: ctime is recorded in the snapshot for informational purposes but is not
|
||||
restored, as setting ctime is not possible through standard system calls on
|
||||
most platforms
|
||||
|
||||
**prune**: Remove unreferenced blobs from remote storage
|
||||
* Scans all snapshots for referenced blobs
|
||||
@@ -207,6 +210,42 @@ vaultik [--config <path>] store info
|
||||
|
||||
---
|
||||
|
||||
## file metadata
|
||||
|
||||
vaultik records the following metadata for each file: path, size, mode
|
||||
(permissions), uid, gid, mtime (modification time), ctime, and symlink
|
||||
target.
|
||||
|
||||
### ctime semantics (platform-specific)
|
||||
|
||||
The `ctime` field has different meanings depending on the operating system:
|
||||
|
||||
| Platform | ctime value | Source |
|
||||
|----------|-------------|--------|
|
||||
| **macOS** | File birth (creation) time | `syscall.Stat_t.Birthtimespec` |
|
||||
| **Linux** | Inode change time | `syscall.Stat_t.Ctim` |
|
||||
| **Other** | Falls back to mtime | `os.FileInfo.ModTime()` |
|
||||
|
||||
**macOS (Darwin):** HFS+ and APFS filesystems natively track file creation
|
||||
time. The `ctime` field contains the true file birth time — when the file was
|
||||
first created on disk.
|
||||
|
||||
**Linux:** Most Linux filesystems do not expose file creation time through
|
||||
standard Go APIs. The `ctime` field contains the inode change time, which is
|
||||
updated whenever file metadata (permissions, ownership, link count) or content
|
||||
changes. Linux ext4 (kernel 4.11+) and btrfs do track birth time via the
|
||||
`statx()` syscall, but this is not exposed through Go's `os.FileInfo.Sys()`.
|
||||
|
||||
**Restore:** ctime is stored in the snapshot database for informational and
|
||||
forensic purposes but is not restored to the filesystem. Setting ctime is not
|
||||
possible through standard system calls on most Unix platforms — the kernel
|
||||
manages ctime automatically.
|
||||
|
||||
When using in-memory filesystems (e.g. afero `MemMapFs` in tests), ctime falls
|
||||
back to mtime since there is no underlying `syscall.Stat_t`.
|
||||
|
||||
---
|
||||
|
||||
## architecture
|
||||
|
||||
### s3 bucket layout
|
||||
@@ -247,11 +286,14 @@ Snapshot IDs follow the format `<hostname>_<snapshot-name>_<timestamp>` (e.g., `
|
||||
CREATE TABLE files (
|
||||
id TEXT PRIMARY KEY,
|
||||
path TEXT NOT NULL UNIQUE,
|
||||
source_path TEXT NOT NULL DEFAULT '',
|
||||
mtime INTEGER NOT NULL,
|
||||
ctime INTEGER NOT NULL,
|
||||
size INTEGER NOT NULL,
|
||||
mode INTEGER NOT NULL,
|
||||
uid INTEGER NOT NULL,
|
||||
gid INTEGER NOT NULL
|
||||
gid INTEGER NOT NULL,
|
||||
link_target TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE file_chunks (
|
||||
|
||||
Reference in New Issue
Block a user