| 34 |
rodolico |
1 |
# ZFS_Utils Module Documentation
|
|
|
2 |
|
|
|
3 |
Perl module providing utilities for ZFS management, GELI encryption, and sneakernet-based replication on FreeBSD systems.
|
|
|
4 |
|
| 48 |
rodolico |
5 |
**Version:** 1.0
|
| 34 |
rodolico |
6 |
**Copyright:** 2024–2025 Daily Data Inc.
|
|
|
7 |
**License:** Simplified BSD License (FreeBSD License)
|
|
|
8 |
|
|
|
9 |
---
|
|
|
10 |
|
|
|
11 |
## Exported Functions & Variables
|
|
|
12 |
|
|
|
13 |
Functions and variables listed in `@EXPORT_OK` and available via `use ZFS_Utils qw(...)`
|
|
|
14 |
|
|
|
15 |
### Functions
|
|
|
16 |
|
|
|
17 |
#### `runCmd(@args)`
|
|
|
18 |
|
|
|
19 |
Execute a shell command and return output.
|
|
|
20 |
|
|
|
21 |
**Parameters:**
|
|
|
22 |
|
|
|
23 |
- `@args` - Command and arguments (joined with spaces)
|
|
|
24 |
|
|
|
25 |
**Returns:**
|
|
|
26 |
|
|
|
27 |
- In scalar context: full command output as a string
|
|
|
28 |
- In list context: output split into lines
|
|
|
29 |
|
| 48 |
rodolico |
30 |
### Full API (functions & exported variables)
|
| 34 |
rodolico |
31 |
|
| 48 |
rodolico |
32 |
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.
|
| 34 |
rodolico |
33 |
|
| 48 |
rodolico |
34 |
| Symbol | Type | Exported? | Description |
|
|
|
35 |
|---|---:|:---:|---|
|
|
|
36 |
| `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. |
|
|
|
37 |
| `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`. |
|
|
|
38 |
| `logMsg($message, $filename?, $time_fmt?)` | function | Yes | Timestamped logging helper. Writes to `$filename` (defaults to `$logFileName`) and optionally to console if `$displayLogsOnConsole` is true. |
|
|
|
39 |
| `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. |
|
|
|
40 |
| `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. |
|
|
|
41 |
| `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. |
|
|
|
42 |
| `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. |
|
|
|
43 |
| `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. |
|
|
|
44 |
| `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`. |
|
|
|
45 |
| `fatalError($message,$config?,$cleanupRoutine?)` | function | Yes | Log a fatal error, optionally run a cleanup CODE ref, and die. |
|
|
|
46 |
| `getDirectoryList($dirname)` | function | Yes | Return ARRAYREF of regular files (non-recursive) under `$dirname`. Returns 0 on error. |
|
|
|
47 |
| `cleanDirectory($dirname)` | function | Yes | Remove all regular files from `$dirname` (non-recursive). Returns 1. |
|
|
|
48 |
| `$logFileName` | scalar | Yes | Path to default log file (default: `/tmp/zfs_utils.log`). Can be overridden by caller. |
|
|
|
49 |
| `$displayLogsOnConsole` | scalar | Yes | If true (non-zero), `logMsg` also prints to STDOUT. |
|
|
|
50 |
| `$lastRunError` | scalar | Yes | Contains the last command exit code set by `runCmd` (Perl `$?` value). |
|
| 51 |
rodolico |
51 |
| `$verboseLoggingLevel` | scalar | Yes | Determines the verbosity of logging for package functions. 0 is none, 3 is many |
|
| 34 |
rodolico |
52 |
|
| 48 |
rodolico |
53 |
### Internal / non-exported helpers (not in `@EXPORT_OK`)
|
| 34 |
rodolico |
54 |
|
| 48 |
rodolico |
55 |
| Symbol | Type | Exported? | Description |
|
|
|
56 |
|---|---:|:---:|---|
|
|
|
57 |
| `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. |
|
|
|
58 |
| `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. |
|
|
|
59 |
| `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. |
|
|
|
60 |
| `copyReportToDrive($logFile,$mountPoint)` | function | No | Helper used by `sendReport` to copy the log file to a mounted drive using `File::Copy`. |
|
|
|
61 |
| `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. |
|
| 34 |
rodolico |
62 |
|
| 48 |
rodolico |
63 |
## Notes about exporting
|
| 34 |
rodolico |
64 |
|
| 48 |
rodolico |
65 |
- The module uses `our @EXPORT_OK = qw(...)` so callers must explicitly import symbols they need, e.g.:
|
| 34 |
rodolico |
66 |
|
|
|
67 |
```perl
|
| 48 |
rodolico |
68 |
use ZFS_Utils qw(loadConfig runCmd logMsg);
|
| 34 |
rodolico |
69 |
```
|
|
|
70 |
|
| 48 |
rodolico |
71 |
- `$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.
|
| 34 |
rodolico |
72 |
|
| 48 |
rodolico |
73 |
## Example usage
|
| 34 |
rodolico |
74 |
|
|
|
75 |
```perl
|
| 48 |
rodolico |
76 |
use FindBin;
|
|
|
77 |
use lib "$FindBin::Bin/..";
|
|
|
78 |
use ZFS_Utils qw(loadConfig runCmd logMsg);
|
| 34 |
rodolico |
79 |
|
| 48 |
rodolico |
80 |
my $cfg = loadConfig('/usr/local/etc/sneakernet.yaml', { dryrun => 1 });
|
|
|
81 |
logMsg("Loaded config");
|
|
|
82 |
my @out = runCmd('zpool', 'list');
|
| 34 |
rodolico |
83 |
```
|
|
|
84 |
|
| 48 |
rodolico |
85 |
## Dependencies (summary)
|
|
|
86 |
- Perl core modules: strict, warnings, Exporter, Data::Dumper, POSIX, File::Path
|
|
|
87 |
- Optional CPAN: YAML::XS (preferred) or YAML::Tiny (fallback) for `loadConfig`
|
|
|
88 |
- System utilities (FreeBSD): `geli`, `zfs`, `zpool`, `geom`, `gpart`, `mount`, `/usr/sbin/sendmail`
|
| 34 |
rodolico |
89 |
|
|
|
90 |
---
|
|
|
91 |
|
| 48 |
rodolico |
92 |
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.
|
| 34 |
rodolico |
93 |
|
|
|
94 |
|
|
|
95 |
## Dependencies
|
|
|
96 |
|
|
|
97 |
- **Core:** Perl 5.10+, strict, warnings, Exporter, Data::Dumper, POSIX, File::Path
|
|
|
98 |
- **External (optional):** YAML::XS or YAML::Tiny (at least one required for `loadConfig()`)
|
|
|
99 |
- **System (FreeBSD):** gshred, geli, zfs, zpool, geom, gpart, mount
|
|
|
100 |
|
|
|
101 |
---
|
|
|
102 |
|
|
|
103 |
## Notes
|
|
|
104 |
|
|
|
105 |
- All functions use `logMsg()` for diagnostics; configure logging before use
|
|
|
106 |
- Functions prefer returning empty strings or undef over dying (except `makeGeliKey`)
|
|
|
107 |
- `mountGeli()` and `decryptAndMountGeli()` require FreeBSD with GELI and ZFS
|
|
|
108 |
- Binary key operations use raw `:raw` mode for safe byte handling
|
|
|
109 |
- XOR operations assume 256-bit (32-byte) keys
|
|
|
110 |
|
|
|
111 |
---
|
|
|
112 |
|
|
|
113 |
## License
|
|
|
114 |
|
|
|
115 |
Simplified BSD License (FreeBSD License) – see module header for full text.
|