Rev 48 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
# ZFS_Utils Module Documentation
Perl module providing utilities for ZFS management, GELI encryption, and sneakernet-based replication on FreeBSD systems.
**Version:** 1.0
**Copyright:** 2024–2025 Daily Data Inc.
**License:** Simplified BSD License (FreeBSD License)
---
## Exported Functions & Variables
Functions and variables listed in `@EXPORT_OK` and available via `use ZFS_Utils qw(...)`
### Functions
#### `runCmd(@args)`
Execute a shell command and return output.
**Parameters:**
- `@args` - Command and arguments (joined with spaces)
**Returns:**
- In scalar context: full command output as a string
- In list context: output split into lines
### Full API (functions & exported variables)
The table below lists all public functions defined in `ZFS_Utils.pm` and whether they are available for import via `@EXPORT_OK`. Private/internal helper functions are also listed for completeness.
| Symbol | Type | Exported? | Description |
|---|---:|:---:|---|
| `loadConfig($filename, $default?)` | function | Yes | Load a YAML config file into a HASHREF. If file missing and `$default` is a HASHREF, writes the default to disk using `YAML::XS` or `YAML::Tiny` and returns the default. Returns hashref on success. |
| `runCmd(@cmd_parts)` | function | Yes | Run a shell command (joined with spaces). Captures exit status in `$lastRunError`. Returns scalar output or list of lines depending on context. Honors `$merge_stderr`. |
| `logMsg($message, $filename?, $time_fmt?)` | function | Yes | Timestamped logging helper. Writes to `$filename` (defaults to `$logFileName`) and optionally to console if `$displayLogsOnConsole` is true. |
| `shredFile($path)` | function | Yes | Calls `/usr/local/bin/gshred -u -f -s 32 $path` to attempt secure deletion. Note: ineffective on ZFS due to COW. |
| `mountDriveByLabel($driveInfo)` | function | Yes | Find a device by GPT/msdos label and mount it. `$driveInfo` is a HASHREF with keys `label`, `fstype` (ufs/msdos), `mountPath`, `timeout`, `check_interval`. Returns mount path or empty string. |
| `unmountDriveByLabel($driveInfo)` | function | Yes | Unmount a drive previously mounted by label and remove the mountpoint if empty. Returns mount path on success or empty string. |
| `mountGeli($geliConfig)` | function | Yes | High-level orchestrator: mounts key disk, creates combined GELI key (via `makeGeliKey`), then decrypts disks and imports/mounts the zpool via `decryptAndMountGeli`. Returns pool name on success. |
| `makeReplicateCommands($sourceSnapsRef,$targetSnapsRef,$dataset,$sourceParent,$targetParent,$newStatusRef)` | function | Yes | Build zfs send command strings based on source and target snapshot lists and prior status. Returns HASHREF of dataset -> send command. |
| `sendReport($reportConfig, $message, $logFile)` | function | Yes | High-level report sender. Can save report to a target drive (via `mountDriveByLabel`) and/or email it. Delegates to `copyReportToDrive` and `sendEmailReport`. |
| `fatalError($message,$config?,$cleanupRoutine?)` | function | Yes | Log a fatal error, optionally run a cleanup CODE ref, and die. |
| `getDirectoryList($dirname)` | function | Yes | Return ARRAYREF of regular files (non-recursive) under `$dirname`. Returns 0 on error. |
| `cleanDirectory($dirname)` | function | Yes | Remove all regular files from `$dirname` (non-recursive). Returns 1. |
| `$logFileName` | scalar | Yes | Path to default log file (default: `/tmp/zfs_utils.log`). Can be overridden by caller. |
| `$displayLogsOnConsole` | scalar | Yes | If true (non-zero), `logMsg` also prints to STDOUT. |
| `$lastRunError` | scalar | Yes | Contains the last command exit code set by `runCmd` (Perl `$?` value). |
| `$verboseLoggingLevel` | scalar | Yes | Determines the verbosity of logging for package functions. 0 is none, 3 is many |
### Internal / non-exported helpers (not in `@EXPORT_OK`)
| Symbol | Type | Exported? | Description |
|---|---:|:---:|---|
| `findGeliDisks()` | function | No | Discover disks that appear free for GELI/ZFS use (excludes disks with partitions and those referenced by zpools). Returns list of device names. |
| `decryptAndMountGeli($geliConfig)` | function | No | Attach (`geli attach`) encrypted devices using the combined key and import the specified zpool, then run `zfs mount -a`. Returns pool name or empty string. |
| `makeGeliKey($geliConfig)` | function | No | Create the combined 32-byte GELI key by XOR'ing the remote binary keyfile and the local 256-bit hex key. Writes the binary key to `$geliConfig->{target}` with mode 0600. Returns 1 on success; dies on unrecoverable errors. |
| `copyReportToDrive($logFile,$mountPoint)` | function | No | Helper used by `sendReport` to copy the log file to a mounted drive using `File::Copy`. |
| `sendEmailReport($to,$subject,$message,$logFile)` | function | No | Helper to send plain-text email via `/usr/sbin/sendmail -t` including the message and appended log contents. |
## Notes about exporting
- The module uses `our @EXPORT_OK = qw(...)` so callers must explicitly import symbols they need, e.g.:
```perl
use ZFS_Utils qw(loadConfig runCmd logMsg);
```
- `$merge_stderr` is an internal variable controlling whether `runCmd` merges stderr into stdout; it is not exported by default. If you need to change it, modify it in the module or add an explicit export.
## Example usage
```perl
use FindBin;
use lib "$FindBin::Bin/..";
use ZFS_Utils qw(loadConfig runCmd logMsg);
my $cfg = loadConfig('/usr/local/etc/sneakernet.yaml', { dryrun => 1 });
logMsg("Loaded config");
my @out = runCmd('zpool', 'list');
```
## Dependencies (summary)
- Perl core modules: strict, warnings, Exporter, Data::Dumper, POSIX, File::Path
- Optional CPAN: YAML::XS (preferred) or YAML::Tiny (fallback) for `loadConfig`
- System utilities (FreeBSD): `geli`, `zfs`, `zpool`, `geom`, `gpart`, `mount`, `/usr/sbin/sendmail`
---
Update notes: This document describes the API as implemented in `ZFS_Utils.pm` (v1.0). If you add new exported symbols, please update `@EXPORT_OK` in the module and this documentation accordingly.
## Dependencies
- **Core:** Perl 5.10+, strict, warnings, Exporter, Data::Dumper, POSIX, File::Path
- **External (optional):** YAML::XS or YAML::Tiny (at least one required for `loadConfig()`)
- **System (FreeBSD):** gshred, geli, zfs, zpool, geom, gpart, mount
---
## Notes
- All functions use `logMsg()` for diagnostics; configure logging before use
- Functions prefer returning empty strings or undef over dying (except `makeGeliKey`)
- `mountGeli()` and `decryptAndMountGeli()` require FreeBSD with GELI and ZFS
- Binary key operations use raw `:raw` mode for safe byte handling
- XOR operations assume 256-bit (32-byte) keys
---
## License
Simplified BSD License (FreeBSD License) – see module header for full text.