{"id":50614309,"url":"https://github.com/pbs-plus/go-blksnap","last_synced_at":"2026-06-06T07:01:08.745Z","repository":{"id":357240766,"uuid":"1235880446","full_name":"pbs-plus/go-blksnap","owner":"pbs-plus","description":"Pure Go ioctl-based client for the blksnap Linux kernel module","archived":false,"fork":false,"pushed_at":"2026-05-11T23:58:12.000Z","size":83,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-12T01:19:27.233Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pbs-plus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-11T18:39:38.000Z","updated_at":"2026-05-11T23:56:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pbs-plus/go-blksnap","commit_stats":null,"previous_names":["pbs-plus/go-blksnap"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/pbs-plus/go-blksnap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pbs-plus%2Fgo-blksnap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pbs-plus%2Fgo-blksnap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pbs-plus%2Fgo-blksnap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pbs-plus%2Fgo-blksnap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pbs-plus","download_url":"https://codeload.github.com/pbs-plus/go-blksnap/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pbs-plus%2Fgo-blksnap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33972398,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-06T07:01:07.743Z","updated_at":"2026-06-06T07:01:08.719Z","avatar_url":"https://github.com/pbs-plus.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-blksnap — Pure Go Block Device Snapshot Library\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/pbs-plus/go-blksnap.svg)](https://pkg.go.dev/github.com/pbs-plus/go-blksnap)\n[![Go Version](https://img.shields.io/badge/Go-1.26+-00ADD8?logo=go)](https://go.dev/dl/)\n[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)\n\nPure Go [ioctl](https://man7.org/linux/man-pages/man2/ioctl.2.html)-based client for the\n[veeamblksnap](https://github.com/veeam/blksnap) standalone kernel module.\nSupports both API generations (VAL-6.x and VAL-13.x) with automatic\nversion detection. No cgo, no C bindings.\n\n\u003e **Important**: This library auto-detects the loaded kernel module version:\n\u003e - **v2** (VAL-13.0 / VAL-13.0.1): `/dev/veeamblksnap` + `/dev/bdevfilter`\n\u003e - **v1** (VAL-6.0 through VAL-6.3.2): `/dev/veeamblksnap` only\n\n- [Features](#features)\n- [Requirements](#requirements)\n- [Kernel module installation](#kernel-module-installation)\n- [Installation](#installation)\n- [Quick start](#quick-start)\n- [Architecture](#architecture)\n- [Type reference](#type-reference)\n- [License](#license)\n\n## Features\n\n- **Multi-version**: Auto-detects v1 (VAL-6.x) or v2 (VAL-13.x) API\n- **Snapshot lifecycle**: Create, Take, Destroy, Collect via `/dev/veeamblksnap`\n- **Change Block Tracking**: Attach filter, read CBT bitmap, mark dirty blocks\n- **Snapshot events**: Wait for corrupted / low-free-space events with timeout\n- **Session management**: goroutine-based event monitor, automatic cleanup\n- **Zero cgo**: Only depends on `golang.org/x/sys/unix`\n\n## Requirements\n\n- **Linux** (amd64 or arm64)\n- **Go 1.26+**\n- **veeamblksnap** kernel module loaded (and **bdevfilter** for v2)\n- Root privileges (or `CAP_SYS_ADMIN`) for most operations\n\n## Kernel module installation\n\nThe veeamblksnap module must be installed and loaded before this library can\nbe used. There are two ways to obtain it, depending on your distribution.\n\n### Option 1: Pre-built packages (recommended)\n\nVeeam distributes pre-built blksnap packages through the\n[Veeam software repository](https://helpcenter.veeam.com/docs/agentforlinux/userguide/installation_val.html)\nas part of Veeam Agent for Linux (free community edition available).\n\n#### Add the repository\n\n1. Download the `veeam-release` package from the\n   [Veeam Agent for Linux download page](https://www.veeam.com/linux-backup-download.html)\n   (requires a free veeam.com account).\n\n2. Install the repository package:\n\n   ```bash\n   # Debian / Ubuntu\n   sudo dpkg -i ./veeam-release* \u0026\u0026 sudo apt-get update\n\n   # RHEL / Rocky / Alma\n   sudo rpm -ivh ./veeam-release* \u0026\u0026 sudo dnf check-update\n\n   # SLES / openSUSE\n   sudo zypper in ./veeam-release* \u0026\u0026 sudo zypper refresh\n   ```\n\n\u003e **Alternative**: If you can't use the release package, add the key manually:\n\u003e ```bash\n\u003e # Debian/Ubuntu\n\u003e sudo curl -fsSL https://repository.veeam.com/keys/DEB-9BB5AC67.gpg \\\n\u003e   -o /usr/share/keyrings/veeam.gpg\n\u003e echo \"deb [signed-by=/usr/share/keyrings/veeam.gpg] https://repository.veeam.com/backup/linux/agent/dpkg/debian/public stable veeam\" | \\\n\u003e   sudo tee /etc/apt/sources.list.d/veeam.list\n\u003e sudo apt-get update\n\u003e # RHEL/Rocky/Alma\n\u003e sudo rpm --import https://repository.veeam.com/keys/RPM-EFDCEA77\n\u003e ```\n\n#### Install the module\n\n```bash\n# Debian 11–13 / Ubuntu 22.04 / 24.04\nsudo apt-get install blksnap\n\n# RHEL 9 / Rocky 9 / Alma 9 — pre-built kmod\nsudo dnf install kmod-blksnap\n\n# RHEL 9 / Rocky 9 / Alma 9 — DKMS (builds from source for your kernel)\nsudo dnf install epel-release dkms\nsudo dnf install blksnap\n\n# RHEL 8 / Rocky 8 / Alma 8 — pre-built kmod (veeamsnap)\nsudo dnf install kmod-veeamsnap\n\n# SLES 15 SP3–SP7 / SLES 16\nsudo zypper install blksnap-kmp-default\n```\n\n#### Verify\n\n```bash\nlsmod | grep -E 'veeamblksnap|bdevfilter'\nsudo modprobe veeamblksnap     # if not auto-loaded\nsudo modprobe bdevfilter       # v2 only\nls -la /dev/veeamblksnap /dev/bdevfilter\n```\n\n#### Secure Boot\n\nIf Secure Boot is enabled, enroll the Veeam key:\n\n```bash\nsudo mokutil --import /path/to/blksnap.der\n# Reboot and follow the MOK Manager prompt\n```\n\n### Option 2: Build from source\n\nFor development or if pre-built packages don't support your kernel:\n\n```bash\ngit clone https://github.com/veeam/blksnap.git -b VAL-13.0.1\ncd blksnap/module\nmake -C /lib/modules/$(uname -r)/build M=$(pwd) modules\nsudo mkdir -p /lib/modules/$(uname -r)/extra\nsudo install -m 0644 veeamblksnap.ko bdevfilter.ko /lib/modules/$(uname -r)/extra/\nsudo depmod -a\nsudo modprobe veeamblksnap bdevfilter\n```\n\n\u003e **Note**: Ensure `linux-headers-$(uname -r)` is installed. For kernel ≥ 6.17,\n\u003e use the VAL-13.0.1 branch.\n\n### Troubleshooting\n\n| Symptom | Cause | Solution |\n|---------|-------|----------|\n| `modprobe: FATAL: Module veeamblksnap not found` | Not installed | Install package or build from source |\n| DKMS build fails (kernel ≥ 6.17) | Package too old | Build from VAL-13.0.1 source |\n| `Failed to load module` | Kernel/headers mismatch | `kernel-devel`/`linux-headers` must match `uname -r` |\n| Secure Boot blocks module | Unsigned | Enroll key via `mokutil` or disable Secure Boot |\n\n## Installation\n\n```bash\ngo get github.com/pbs-plus/go-blksnap@latest\n```\n\n## Quick start\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\n\t\"github.com/pbs-plus/go-blksnap\"\n)\n\nfunc main() {\n\tsession, err := blksnap.CreateSession(\n\t\t[]string{\"/dev/sda1\", \"/dev/sda2\"},\n\t\t\"/var/lib/blksnap/diff_storage\",\n\t\t1024*1024*1024, // 1 GB diff storage limit\n\t)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer session.Close()\n\n\tcbt, _ := session.CBTHandle(\"/dev/sda1\")\n\tinfo, _ := cbt.Info()\n\tlog.Printf(\"device=%d blocks, block_size=%d\", info.BlockCount, info.BlockSize)\n\n\tdata, _ := cbt.Data()\n\tlog.Printf(\"CBT map: %d bytes\", len(data))\n\n\timg, _ := cbt.Image()\n\tlog.Printf(\"snapshot image: %s\", img)\n\n\tif errs, ok := session.Errors(); ok {\n\t\tfor _, e := range errs {\n\t\t\tlog.Printf(\"snapshot error: %s\", e)\n\t\t}\n\t}\n}\n```\n\n## Architecture\n\nThe library auto-detects the API version on first use:\n\n```go\nv, _ := blksnap.Detect() // returns APIV1 or APIV2\n```\n\nTwo kernel interfaces are used depending on the version:\n\n| Interface | API | Go types | Purpose |\n|-----------|-----|----------|---------|\n| `/dev/veeamblksnap` | v1 + v2 | `Service`, `Snapshot` | Snapshot lifecycle |\n| `/dev/bdevfilter` | v2 only | `Tracker` | CBT via path-based device IDs |\n| `/dev/veeamblksnap` | v1 only | `Tracker` | CBT via major:minor device IDs |\n\n### Low-level API\n\n```go\n// Version query (works on both v1 and v2)\nsvc, _ := blksnap.OpenService()\nver, _ := svc.Version()\nfmt.Println(ver) // \"7.0.0.0\"\n\n// List active snapshots\nids, _ := svc.Collect()\n\n// CBT on v2 (path-based)\nt, _ := blksnap.OpenTracker(\"/dev/sda1\")\nt.Attach()\ninfo, _ := t.CBTInfo()\nbuf := make([]byte, info.BlockCount)\nt.ReadCBTMap(0, info.BlockCount, buf)\nt.Detach()\nt.Close()\n\n// Create and take a snapshot (v2)\nsnap, _ := blksnap.CreateSnapshot(\"/tmp/diff_storage\", 1\u003c\u003c30)\nt.SnapshotAdd(snap.ID())\nsnap.Take()\n\n// Wait for events\nfor {\n    ev, ok, _ := snap.WaitEvent(100)\n    if !ok { continue }\n    switch ev.Code {\n    case blksnap.EventCorrupted:\n        log.Printf(\"corrupted: dev=%d:%d code=%d\",\n            ev.Corrupted.OrigDevIDMajor,\n            ev.Corrupted.OrigDevIDMinor,\n            ev.Corrupted.ErrorCode)\n    case blksnap.EventLowFreeSpace:\n        log.Printf(\"low space: requested=%d sectors\",\n            ev.NoSpace.RequestedSectors)\n    }\n}\n\nsnap.Destroy()\nsnap.Close()\n```\n\n### v1-specific API\n\nIn v1, devices are identified by major:minor numbers and added at snapshot\ncreation time:\n\n```go\nsnap, _, _ := blksnap.CreateSnapshotV1([]blksnap.DevID{\n    {Major: 8, Minor: 1},  // /dev/sda1\n    {Major: 8, Minor: 2},  // /dev/sda2\n})\n\n// Get image device mappings\nimages, _ := snap.CollectImages()\nfor orig, img := range images {\n    fmt.Printf(\"%d:%d → %d:%d\\n\", orig.Major, orig.Minor, img.Major, img.Minor)\n}\n```\n\n### High-level Session API\n\n```go\nsession, _ := blksnap.CreateSession(\n    []string{\"/dev/sda1\"},\n    \"/tmp/diff_storage\",\n    1\u003c\u003c30,\n    blksnap.WithLogger(slog.Default()),\n    blksnap.WithEventTimeout(50*time.Millisecond),\n)\ndefer session.Close()\n```\n\n## Type reference\n\n| C struct (v2) | Go type |\n|---------------|---------|\n| `struct blksnap_version` | `ModuleVersion` |\n| `struct blksnap_uuid` | `UUID` |\n| `struct blksnap_cbtinfo` | `CBTInfo` |\n| `struct blksnap_sectors` | `SectorRange` |\n| `struct blksnap_snapshotinfo` | `SnapshotImageInfo` |\n| `struct blksnap_snapshot_event` | `SnapshotEvent` |\n| `struct blksnap_event_corrupted` | `SnapshotEventCorrupted` |\n| `struct blksnap_event_no_space` | `SnapshotEventLowFreeSpace` |\n| `enum blksnap_event_codes` | `SnapshotEventCode` |\n| `struct blk_snap_dev_t` (v1) | `DevID` |\n| `enum blk_snap_ioctl` (v1) | (internal) |\n| `struct bdevfilter_attach/ctl` (v2) | (internal) |\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n---\n\nBased on the [blksnap](https://github.com/veeam/blksnap) kernel module UAPI\nby Veeam Software Group GmbH. The ioctl protocol derives from kernel UAPI\nheaders (`veeamblksnap.h`, `bdevfilter.h`, `blk_snap.h`) which are licensed\nunder GPL-2.0 WITH Linux-syscall-note, permitting independent userspace\nimplementations under any license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpbs-plus%2Fgo-blksnap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpbs-plus%2Fgo-blksnap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpbs-plus%2Fgo-blksnap/lists"}