The safety review of the first version found it safe for the pool's data and asked for these fixes before it goes on the home server: - zfs_snapshot: no recursive. Every answer gives the dataset's free space and the pool's capacity, and says that the snapshot holds every block deleted or overwritten until it is destroyed by hand. - A command that runs out of time is ended with its whole process group. An act that timed out is answered from the list, or as "outcome unknown", never as "NOT DONE". - The watch runs as the operator account. - The event follower reads ZFS's queue from its start, with a cursor per boot, so the pool's import and any downtime reach the journal once. It writes "dropped N events", kills zpool before waiting for it, and exits non-zero after five failed follows in a row. - Past error counts are a warning, and counts that rise are unhealthy. - The guard test catches .Run(, exec.Command(, exec.CommandContext( and process starts. - The fixtures and the parser follow OpenZFS 2.4.4's own printers: human scan sizes under -p, no iostat section lines, error scrubs, per-vdev rebuild resilvers, paused scrubs. The operator also asked the module to own the scrub. A timer and a service of the module's own run zpool scrub -w -- <pool> from the scrub-pool, scrub-cadence, scrub-day and scrub-time settings. In the same declaration, the distribution's weekly and monthly timers for that pool are held stopped and disabled, so exactly one schedule scrubs it. zfs_scrub shows the schedule and the next run, with any resilver's progress. zfs_scrub_start, zfs_scrub_pause and zfs_scrub_stop act with why. The health check warns of a late or failed scrub and of a running resilver, and is unhealthy for a resilver that finished with errors.
216 lines
6.7 KiB
JSON
216 lines
6.7 KiB
JSON
{
|
|
"module": "zfs",
|
|
"version": "1",
|
|
"capabilities": [
|
|
"service-manager"
|
|
],
|
|
"emits": [
|
|
"snapshot.taken",
|
|
"scrub.requested"
|
|
],
|
|
"settings": {
|
|
"scrub-cadence": {
|
|
"kind": "preference",
|
|
"default": "weekly",
|
|
"why": "how often the pool named by scrub-pool is scrubbed, weekly or monthly: weekly is what the distribution's timer did on the home server before the module, so taking it over changes nothing; a pool whose scrub takes days may want monthly"
|
|
},
|
|
"scrub-day": {
|
|
"kind": "preference",
|
|
"default": "Mon",
|
|
"why": "the weekday the scrub starts (Mon to Sun); for a monthly scrub, the first such day of the month. Monday is when the distribution's weekly timer fired"
|
|
},
|
|
"scrub-time": {
|
|
"kind": "preference",
|
|
"default": "00:00",
|
|
"why": "the time the scrub starts, HH:MM in the machine's time zone; midnight is when the distribution's weekly timer fired"
|
|
}
|
|
},
|
|
"tools": [
|
|
"zfs_datasets",
|
|
"zfs_snapshots",
|
|
"zfs_snapshot",
|
|
"zfs_pools",
|
|
"zfs_space",
|
|
"zfs_pool_layout",
|
|
"zfs_scrub",
|
|
"zfs_scrub_start",
|
|
"zfs_scrub_pause",
|
|
"zfs_scrub_stop",
|
|
"zfs_io",
|
|
"zfs_arc",
|
|
"zfs_events",
|
|
"zfs_properties",
|
|
"zfs_health"
|
|
],
|
|
"replaces": {
|
|
"zfs_datasets": [
|
|
"zfs list"
|
|
],
|
|
"zfs_snapshots": [
|
|
"zfs list -t snapshot"
|
|
],
|
|
"zfs_snapshot": [
|
|
"zfs snapshot"
|
|
],
|
|
"zfs_pools": [
|
|
"zpool list",
|
|
"zpool status -x"
|
|
],
|
|
"zfs_space": [
|
|
"zfs list -o space",
|
|
"zpool list -v"
|
|
],
|
|
"zfs_pool_layout": [
|
|
"zpool status",
|
|
"zpool status -v"
|
|
],
|
|
"zfs_scrub": [
|
|
"zpool history -i"
|
|
],
|
|
"zfs_io": [
|
|
"zpool iostat",
|
|
"zpool iostat -v"
|
|
],
|
|
"zfs_arc": [
|
|
"arcstat",
|
|
"arc_summary",
|
|
"cat /proc/spl/kstat/zfs/arcstats"
|
|
],
|
|
"zfs_events": [
|
|
"zpool events",
|
|
"zpool events -v"
|
|
],
|
|
"zfs_properties": [
|
|
"zfs get all",
|
|
"zfs get"
|
|
],
|
|
"zfs_scrub_start": [
|
|
"zpool scrub"
|
|
],
|
|
"zfs_scrub_pause": [
|
|
"zpool scrub -p"
|
|
],
|
|
"zfs_scrub_stop": [
|
|
"zpool scrub -s"
|
|
]
|
|
},
|
|
"resources": [
|
|
{
|
|
"id": "watch",
|
|
"type": "process",
|
|
"name": "zfs-watch",
|
|
"artifact": "tools",
|
|
"run": [
|
|
"./zfs-tools",
|
|
"watch"
|
|
],
|
|
"user": "${machine:account}",
|
|
"health": {
|
|
"kind": "tool",
|
|
"tool": "zfs_health",
|
|
"interval": "60s",
|
|
"timeout": "20s",
|
|
"looks": 2,
|
|
"grace": "60s"
|
|
}
|
|
},
|
|
{
|
|
"id": "cursor-dir",
|
|
"type": "directory",
|
|
"path": "/run/zfs-events",
|
|
"mode": "0700"
|
|
},
|
|
{
|
|
"id": "events",
|
|
"type": "process",
|
|
"name": "zfs-events",
|
|
"artifact": "tools",
|
|
"run": [
|
|
"./zfs-tools",
|
|
"events"
|
|
],
|
|
"health": {
|
|
"kind": "unit"
|
|
}
|
|
},
|
|
{
|
|
"id": "config-dir",
|
|
"type": "directory",
|
|
"path": "/etc/zfs-tools",
|
|
"mode": "0755"
|
|
},
|
|
{
|
|
"id": "scrub-config",
|
|
"type": "file",
|
|
"path": "/etc/zfs-tools/scrub.conf",
|
|
"mode": "0644",
|
|
"content": "# Written by the mesh (module zfs) from this machine's assignment. Replaced on every push; change the\n# settings scrub-pool, scrub-cadence, scrub-day and scrub-time, never this file. The module's tools read it.\npool=${setting:scrub-pool}\ncadence=${setting:scrub-cadence}\nday=${setting:scrub-day}\ntime=${setting:scrub-time}\n"
|
|
},
|
|
{
|
|
"id": "scrub-service",
|
|
"type": "file",
|
|
"path": "/etc/systemd/system/zfs-mesh-scrub@.service",
|
|
"mode": "0644",
|
|
"content": "# Written by the mesh (module zfs). Replaced on every push; change the module's scrub settings, never this file.\n# The scrub of one pool, started by the module's timer: zpool with fixed arguments and no shell. Stopping the\n# unit while a scrub runs pauses it, as the distribution's own scrub unit does; a later start resumes it.\n[Unit]\nDescription=zpool scrub of %i (the mesh's zfs module)\nDocumentation=man:zpool-scrub(8)\nRequires=zfs.target\nAfter=zfs.target\nConditionPathIsDirectory=/sys/module/zfs\n\n[Service]\nExecStart=/usr/bin/zpool scrub -w -- %i\nExecStop=-/usr/bin/zpool scrub -p -- %i\n"
|
|
},
|
|
{
|
|
"id": "scrub-weekly",
|
|
"type": "file",
|
|
"path": "/etc/systemd/system/zfs-mesh-scrub-weekly@.timer",
|
|
"mode": "0644",
|
|
"content": "# Written by the mesh (module zfs). Replaced on every push; change the module's scrub settings, never this file.\n# The weekly scrub schedule. The mesh enables it for the pool its scrub-pool setting names, and holds the\n# distribution's own scrub timers for that pool stopped and disabled, so one schedule scrubs the pool.\n[Unit]\nDescription=Weekly zpool scrub of %i (the mesh's zfs module)\nDocumentation=man:zpool-scrub(8)\n\n[Timer]\nOnCalendar=${setting:scrub-day} *-*-* ${setting:scrub-time}:00\nPersistent=true\nUnit=zfs-mesh-scrub@%i.service\n\n[Install]\nWantedBy=timers.target\n"
|
|
},
|
|
{
|
|
"id": "scrub-monthly",
|
|
"type": "file",
|
|
"path": "/etc/systemd/system/zfs-mesh-scrub-monthly@.timer",
|
|
"mode": "0644",
|
|
"content": "# Written by the mesh (module zfs). Replaced on every push; change the module's scrub settings, never this file.\n# The monthly scrub schedule. The mesh enables it for the pool its scrub-pool setting names, and holds the\n# distribution's own scrub timers for that pool stopped and disabled, so one schedule scrubs the pool.\n[Unit]\nDescription=Monthly zpool scrub of %i (the mesh's zfs module)\nDocumentation=man:zpool-scrub(8)\n\n[Timer]\nOnCalendar=${setting:scrub-day} *-*-01..07 ${setting:scrub-time}:00\nPersistent=true\nUnit=zfs-mesh-scrub@%i.service\n\n[Install]\nWantedBy=timers.target\n"
|
|
},
|
|
{
|
|
"id": "distribution-weekly",
|
|
"type": "service",
|
|
"unit": "zfs-scrub-weekly@${setting:scrub-pool}.timer",
|
|
"state": "stopped",
|
|
"boot": "disabled"
|
|
},
|
|
{
|
|
"id": "distribution-monthly",
|
|
"type": "service",
|
|
"unit": "zfs-scrub-monthly@${setting:scrub-pool}.timer",
|
|
"state": "stopped",
|
|
"boot": "disabled"
|
|
},
|
|
{
|
|
"id": "scrub-schedule",
|
|
"type": "service",
|
|
"unit": "zfs-mesh-scrub-${setting:scrub-cadence}@${setting:scrub-pool}.timer",
|
|
"state": "running",
|
|
"boot": "enabled",
|
|
"restart-on": [
|
|
"scrub-service",
|
|
"scrub-weekly",
|
|
"scrub-monthly"
|
|
],
|
|
"health": {
|
|
"kind": "unit"
|
|
}
|
|
}
|
|
],
|
|
"build": {
|
|
"artifacts": [
|
|
{
|
|
"name": "tools",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/zfs-tools",
|
|
"binary": "zfs-tools",
|
|
"loads": [
|
|
"zfs-tools"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|