pve-storage-hitachiblock (1.2.0~alpha39-1) stable; urgency=medium

  * Ship the qemu-pr-helper systemd units for SCSI-3 PR (GitHub #2, follow-up to
    alpha37). On PVE the qemu-pr-helper binary ships with pve-qemu-kvm but Proxmox
    does not package its systemd units (and Debian's qemu-system-common conflicts
    with pve-qemu-kvm), so `systemctl enable --now qemu-pr-helper.socket` failed on
    a stock node. The package now installs qemu-pr-helper.socket + .service to
    /lib/systemd/system/, DISABLED (PR is opt-in: dh_installsystemd --no-enable
    --no-start). Enabling the socket now works out of the box. Recommends
    pve-qemu-kvm. Docs updated; new drift-guard test ties the unit socket path to
    the plugin's readiness check. 196/196 unit tests. Found via live validation on
    the VSP E590H (the .socket unit was absent on the lab nodes).

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Mon, 29 Jun 2026 20:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha38-1) stable; urgency=medium

  * Fix `hitachiblock-repl pr-check` requiring --storeid (GitHub #2, follow-up to
    alpha37). The host-side PR readiness diagnostic hit the global "storeid is
    required" gate (and the array/credentials/RestClient setup) before dispatch,
    so it printed usage instead of running. It is now dispatched early — before any
    storeid/array setup — so `hitachiblock-repl pr-check` (and --json) runs
    standalone on any node with no storeid and no array connection, as intended.
    Found by live validation on the VSP E590H; the activate_volume validate-and-warn
    path itself was already confirmed working live. 187/187 unit tests.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Mon, 29 Jun 2026 19:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha37-1) stable; urgency=medium

  * Opt-in SCSI-3 Persistent Reservation readiness for clustered/shared guest
    disks (GitHub #2). New default-off `persistent_reservations` storage property.
    SCSI-3 PR travels guest -> QEMU -> qemu-pr-helper -> dm-multipath (the array
    already honours LU-wide PR), so the plugin's role is host-side validate-and-warn:
    - When enabled, activate_volume runs a READ-ONLY readiness check on the LUN's
      multipath device (qemu-pr-helper socket present + a multipath reservation_key
      configured) and WARNS once, non-fatally, if it is not ready. It never edits
      multipath.conf, never registers keys, never calls the array, and never blocks
      activation. Off by default with zero effect on normal single-owner volumes.
    - New `hitachiblock-repl pr-check` read-only operator diagnostic (no array
      login) reports node PR readiness; --json supported.
    - New docs/clustered-disks.md runbook: host prerequisites (qemu-pr-helper.socket
      + multipath reservation_key), the storage toggle, and the guest-side per-disk
      recipe (scsi-hd/scsi-block on virtio-scsi + a pr-manager-helper bound via
      args:), plus verification. Multi-writer DATA safety remains the guest's
      cluster FS/app responsibility.
    Architect-reviewed; 187/187 unit tests.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Mon, 29 Jun 2026 18:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha36-1) stable; urgency=medium

  * Behaviour-preserving refactor: collapse the duplicated snapshot-pair-by-group
    lookups onto shared helpers (GitHub #35). No functional change.
    - New _find_snapshot_id_by_group is the single owner of the legacy/volume-
      specific snapshot-group naming table, which had been duplicated between
      _resolve_snapshot_id and volume_snapshot_delete (a silent-drift hazard).
      The delete fallback calls it directly (not _resolve_snapshot_id) so the
      drifted-registry recovery path is preserved exactly.
    - New _find_pair_by_group centralises the exact-group-name pair lookup;
      routed through volume_snapshot, clone_image (+ its rollback) and the
      consistency-group registration. free_image's OR-clause and the CG-rollback
      delete-all loop are deliberately left inline (not equivalent).
    - Added real-helper unit coverage. 185/185 unit tests; architect-reviewed.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Mon, 29 Jun 2026 15:30:00 +0000

pve-storage-hitachiblock (1.2.0~alpha35-1) stable; urgency=medium

  * Behaviour-preserving refactors and dead-code/test-quality cleanup (GitHub
    #37 + #36; also folds in the prior deslop pass). No functional change.
    - HitachiBlockPlugin.pm: extract _resolve_target (the snapname-vs-volname
      LDEV/WWID resolution ladder shared by activate_volume / deactivate_volume /
      filesystem_path; an $on_missing 'die'|'soft' selector preserves
      deactivate's idempotent return-1) and _wwid_for (the stored-or-synthesised
      WWID idiom, 5 sites). Every die message, fallback and array-call order is
      preserved verbatim.
    - RestClient.pm: extract _objects_url / _apply_auth / _short_path; the
      session/job URLs, both auth sites and the three log-redaction sites now
      funnel through one owner each. Same bytes on the wire and in logs.
    - hitachiblock-repl: one emit_json() (canonical, sorted-key) for the --json
      output of all subcommands, plus a %DISPATCH table replacing the hand-synced
      command chain. Human output is byte-identical; the reconcile-maps --apply
      ldev_range fail-closed fence (#28) is unchanged.
    - Removed dead code (Config save_registry, Multipath $RESCAN_TIMEOUT) and
      migrated the mirror-logic unit tests (plugin.t / multipath.t / taint.t) to
      exercise the real modules. 184/184 unit tests pass; architect-reviewed.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Mon, 29 Jun 2026 13:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha34-1) stable; urgency=medium

  * Fix the reconcile-maps ldev_range safety fence failing open on a HEX
    ldev_range (GitHub #28, follow-up to alpha33). The REPL parsed only decimal
    ranges, so a documented hex range (e.g. 0x3E8-0x7CF) yielded an undefined
    fence — and on a multi-storeid array sharing target ports (same host group,
    matched by the node's fixed WWN) `reconcile-maps --apply` could classify and
    unmap another storeid's LIVE volumes. New
    LunPaths->parse_ldev_range() accepts decimal AND hex (single source of truth,
    rejects reversed ranges), and reconcile-maps now FAILS CLOSED: --apply is
    refused unless the ldev_range parses, so a fence-less unmap is structurally
    impossible (dry-run still works for visibility). New unit tests cover hex/
    decimal/invalid/reversed parsing and a hex-derived reconcile fence; minor
    deslop (shared budget/orphan-print helpers). 188/188 unit tests pass.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Mon, 29 Jun 2026 00:30:00 +0000

pve-storage-hitachiblock (1.2.0~alpha33-1) stable; urgency=medium

  * Surface per-node LU-path / host-group counts and add a guarded orphan-map
    reconcile pass (GitHub #28). New module PVE::Storage::HitachiBlock::LunPaths:
    scan() reports, for this node's host group on each target port, the LU-path
    count (headroom vs the per-FE-port budget, default 2048), host-groups-on-port
    (vs the 255/port cap), the total mapped LU paths on the node, any orphan LU
    paths (mapped here but whose LDEV is no longer in the registry — the signature
    of a leaked unmap), and a soft over-budget warning at 80%. reconcile() unmaps
    ONLY those orphans and ONLY within ldev_range — never a registered/live volume,
    out-of-range LDEVs are skipped with a reason — and is dry-run by default.
    hitachiblock-repl gains `lun-paths` (read-only report, --json,
    --lun-path-budget) and `reconcile-maps` (dry-run unless --apply); the
    diagnostics bundle gains an LU-path/host-group section. Reconcile is an explicit
    operator action, intentionally not auto-run on deactivate_storage. Makes the
    scalability story falsifiable and alerts before a silent per-port budget breach.
    New t/unit/lunpaths.t (scan counts/orphans/budget; reconcile dry-run/apply/
    out-of-range/failure). 186/186 unit tests pass.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 28 Jun 2026 23:55:00 +0000

pve-storage-hitachiblock (1.2.0~alpha32-1) stable; urgency=medium

  * Add a configurable `debug` storage property (0=off..3=trace) with a logging
    helper routed to syslog (GitHub #33). Levels: 0 off (default); 1 basic
    high-level operations (alloc/free/clone/snapshot/rollback start + result);
    2 + per-request REST method, bare path, HTTP status and elapsed time (the
    management endpoint is intrinsically slow, so per-call latency is a primary
    troubleshooting signal); 3 trace (+ request/response bodies). Output goes to
    syslog/journal under the tag 'HitachiBlock' (journalctl -t HitachiBlock), so
    it never pollutes task output at level 0. Credentials and session tokens are
    NEVER logged at any level: the Authorization header and basic-auth are never
    emitted, and at level 3 any password/token/auth/credential/secret field in a
    body is redacted. The plugin's _debug() and RestClient's level/redaction are
    unit-tested; the level is threaded from $scfg into RestClient. Exposed in the
    Web UI (Advanced) and documented in docs/configuration.md. This adds the
    threshold/level logging layer on top of the REST timing introduced for the
    diagnostics bundle (#18).

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 28 Jun 2026 21:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha31-1) stable; urgency=medium

  * Add a read-only `diagnostics` support-bundle subcommand to hitachiblock-repl
    (GitHub #18). One command captures a coherent, secret-free snapshot for bug
    reports (no mutations): plugin + array model/serial/microcode versions; the
    effective storage config with credentials redacted (username masked, password
    never emitted); REST/management-endpoint health (reachability, login probe
    time, and per-call response-time stats); registry-vs-array drift (array/registry
    orphans over the ldev_range); and host device state per registered volume
    (resolved /dev/mapper path, present/block). Supports --json. The orphan scan is
    shared with the existing `orphans` command. Documented in docs/operations.md as
    the first step for bug reports.
  * Instrument REST response times in RestClient: _request() now records per-call
    latency (Time::HiRes) into rolling per-client stats (count/avg/max/last + the
    slowest method+path), exposed via rest_timing_stats() and surfaced in the
    diagnostics bundle. The GUM is intrinsically slow, so per-call latency is a key
    troubleshooting signal; threshold logging is deferred to the debug-level work
    (#33). New get_storage_info() (lightweight reachability + version probe).
    Validated live on the E590H (login ~1.7s, slowest call ~4.1s = the /ldevs range
    scan). New unit tests for the timing accumulator. 176/176 unit tests pass.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 28 Jun 2026 18:25:00 +0000

pve-storage-hitachiblock (1.2.0~alpha30-1) stable; urgency=medium

  * Add randomized jitter to REST retry backoff to de-synchronize retries
    (GitHub #11). The two retry sites (login, _request) used a deterministic linear
    backoff (RETRY_DELAY * attempt), so many nodes hitting the same array-side fault
    (e.g. the GUM returning 503 under load, with no Retry-After) retried in lockstep
    and re-saturated the shared management endpoint. Factored both into a new
    _retry_delay() helper: linear base + a random fraction of RETRY_DELAY, bounded
    by RETRY_MAX_DELAY (30s). A numeric Retry-After still takes precedence and is
    honored exactly (no jitter). The idempotency-aware retryable classifier is
    unchanged. New unit test asserts the delay is non-constant per attempt, within
    [base, base+RETRY_DELAY), honors/ignores Retry-After correctly, and is capped.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 28 Jun 2026 14:30:00 +0000

pve-storage-hitachiblock (1.2.0~alpha29-1) stable; urgency=medium

  * Fix silent wrong-data on snapshot rollback in branch/sibling scenarios on
    large volumes (GitHub #12). Root cause: restore_snapshot()/split_snapshot()
    return when the array JOB is accepted, but the underlying Thin Image copy
    continues in the background (restore runs RCPY before settling to PAIR). On a
    large volume the copy outlasts the job, so the post-restore re-split ran against
    an RCPY pair and was a no-op — the snapshot was left non-PSUS, and a later
    rollback to it silently did nothing (the LDEV kept the current/branch data).
    A 48 MB efidisk dodged this (its copy finished within ~2s); a 60 GB boot disk
    did not. Fix: volume_snapshot_rollback now waits for the pair to reach PAIR
    after restore (before re-splitting) and PSUS after the split, via new
    _wait_snapshot_status() polling. Found by a guest-level combination test
    (full-clone VM, nested + same-level/branch snapshots) and isolated with
    virt-cat (LDEV read) vs the booted-guest read. New unit test covers the
    settle/timeout behavior. 174/174 unit tests pass.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 28 Jun 2026 10:05:00 +0000

pve-storage-hitachiblock (1.2.0~alpha28-1) stable; urgency=medium

  * Fix split_snapshot sending an unsupported operationType attribute. The
    single-pair split action body carried {"parameters":{"operationType":"split"}},
    which this microcode (E590H 93-07-23) rejects with KART40038-E — the same quirk
    already fixed for restore in #22. The body is now an empty parameters object
    ({"parameters":{}}, matching the REST API Reference's "Body: None"). split was
    previously unused (pairs are created with autoSplit=true); the #12 rollback
    re-split path is its first caller, so the stale body only surfaced now. Without
    this, the post-rollback re-split failed and left the pair in PAIR, so a
    subsequent rollback to the same snapshot was a silent no-op (caught by the live
    snapshot combination test). Added a split body-shape unit test. (GitHub #12)

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 28 Jun 2026 02:50:00 +0000

pve-storage-hitachiblock (1.2.0~alpha27-1) stable; urgency=medium

  * Snapshot rollback: feasibility predicate, post-restore re-split, and registry
    reconcile (GitHub #12), plus Nimble-parity items (GitHub #34).
    - Implement volume_rollback_is_possible as a SIBLING-PRESERVING predicate:
      Thin Image keeps every snapshot as an independent pair, so restoring the
      P-VOL from one snapshot does NOT delete newer snapshots (confirmed live on
      the VSP E590H). Rollback to ANY existing snapshot is allowed; newer
      snapshots are NOT blockers (unlike ZFS/LVM-thin). A snapshot with dependent
      linked clones is blocked, mirroring the deletion guards.
    - volume_snapshot_rollback now RE-SPLITS the pair after the restore job
      completes. A restore lands the pair in PAIR (snapshot data merged into the
      P-VOL); without a re-split the snapshot is left non-re-restorable (verified
      live). It then reconciles the registry against the array's pairs.
    - volume_snapshot_info now reports a monotonic `order` per snapshot, matching
      the base/reference plugins.
    - rename_snapshot implemented (registry-key rename via new
      Config->rename_snapshot; the array group label is cosmetic and resolved via
      the recorded snapshot_id). (#34)
    - Add `none` to the advertised content types. (#34)
    New t/unit/snapshots.t (predicate, order, rename, resolve/reconcile via a fake
    client) and a Config rename_snapshot test. 172/172 unit tests pass.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 28 Jun 2026 01:30:00 +0000

pve-storage-hitachiblock (1.2.0~alpha26-1) stable; urgency=medium

  * Support per-volume attributes: protected flag and notes passthrough. Implement
    get_volume_attribute / update_volume_attribute (protected, notes) plus the
    get_volume_notes / update_volume_notes entry points, persisting both in the
    cluster-replicated LDEV registry (new Config->update_meta() merges metadata
    without touching ldev_id). free_image now refuses to delete a volume marked
    protected, failing fast before any array session is opened (free_image also
    reordered so all local checks run before connecting). protected reads back as
    1/0; notes round-trip and clear on empty. State persists across nodes via the
    registry. New t/unit/attributes.t (real plugin methods + free_image guard) and
    a Config update_meta test. (GitHub #15)

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 27 Jun 2026 23:55:00 +0000

pve-storage-hitachiblock (1.2.0~alpha25-1) stable; urgency=medium

  * Validate/untaint array-sourced values before they reach host tools. Added
    central Multipath helpers _dm_wwid() (normalise + validate a WWID to the
    multipath '3<hex>' form) and _assert_ldev_id() (non-negative integer), and
    applied them at every boundary: get_device_path, whitelist_wwid,
    remove_device, resize_device, flush_device (WWID), ldev_to_wwid,
    discover_wwid (LDEV id), plus a strict /dev/mapper/3<hex> guard in
    get_device_size. A malformed/unexpected value (microcode quirk, partial REST
    response, future field change) is now rejected with an actionable error
    instead of being passed to multipath/multipathd/blockdev. This also removes
    five copies of the ad-hoc '3'-prefix normalisation. _run_cmd() remains the
    final argv-untaint backstop. New t/unit/validate.t exercises the real helpers
    (accept valid, reject malformed); behaviour for valid inputs is unchanged
    (verified live). (GitHub #19)

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 27 Jun 2026 23:15:00 +0000

pve-storage-hitachiblock (1.2.0~alpha24-1) stable; urgency=medium

  * Clamp the reported storage API version to a tested range instead of
    hard-coding it. api() now reports the running host's PVE::Storage::APIVER
    capped at HB_MAX_APIVER (14, validated live on PVE 9.2.3), falling back to
    HB_MAX_APIVER when the host version is unreadable. This loads warning-free on
    any PVE whose APIVER is within range and degrades to PVE's recommended-upgrade
    warning (never a load failure) on a newer PVE, instead of the previous
    hard-coded 14 which would fail to load on an older host (api() > host APIVER
    is refused) or warn whenever the host moved. We never report higher than the
    host's APIVER (HB_MIN_APIVER documents the validated floor but is never forced
    up, which would be refused). Adds an in-code compatibility map documenting
    each APIVER's impact on our overridden methods. New t/unit/api.t asserts the
    clamp above, below, within range, and on an unreadable host. (GitHub #17)

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 27 Jun 2026 22:45:00 +0000

pve-storage-hitachiblock (1.2.0~alpha23-1) stable; urgency=medium

  * Implement qemu_blockdev_options() for the PVE 9 -blockdev disk-attachment
    interface (APIVER 14). Our volumes are always raw block devices exposed at
    /dev/mapper/<wwid> (live LDEV) or the snapshot S-VOL's own mapper device, so
    the method resolves the device via path() (honouring the snapshot name) and
    attaches it directly as { driver => 'host_device', filename => <path> }.
    Previously we inherited the base default, which path()s then stat()s the
    result to guess host_device-vs-file and carries qcow2/qed snapshot-chain
    handling irrelevant to raw block volumes; declaring host_device explicitly is
    always correct for us and decouples us from that heuristic across PVE point
    releases. A non-absolute/undef path is now rejected with a clear error.
    Validated live on PVE 9.2.3 (host_device descriptors resolve to existing
    block devices for live and base volumes); new t/unit/blockdev.t loads the
    real plugin and covers the live, snapshot, and rejection paths. (GitHub #14)

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 27 Jun 2026 22:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha22-1) stable; urgency=medium

  * Fix the Web UI <script> cache-buster never refreshing on upgrade. The
    postinst inject() returned early when the tag was already present, so the
    ?ver= query string stayed frozen at the version first injected (e.g.
    1.2.0~alpha13-1) while the JS on disk kept changing — browsers then served
    stale cached JS and new GUI fields (e.g. the alpha21 skip_unmap_io_check /
    rest_keepalive / lock_timeout controls) did not appear without a manual
    hard refresh. inject() now rewrites the existing tag's ?ver= to the current
    package version on every configure/triggered run. The Makefile source-install
    path got the same fix (refresh in place instead of skipping). No-op for fresh
    installs. (GitHub issue #9 follow-up)

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 27 Jun 2026 21:15:00 +0000

pve-storage-hitachiblock (1.2.0~alpha21-1) stable; urgency=medium

  * Expose the three remaining backend properties in the manager6 Web UI
    create/edit dialog so it stays a complete front-end for the schema:
    skip_unmap_io_check (HMO 91 teardown optimization) and rest_keepalive as
    Advanced checkboxes, and lock_timeout as an Advanced integer field. The first
    is the recommended fix for the array's host-I/O unmap interlock blocking
    teardown. (GitHub issue #9)
  * Add a GUI/schema drift guard unit test (t/unit/gui_schema.t) that diffs the
    keys accepted by options() against the name: fields referenced in the GUI and
    fails when a backend property has no GUI control (allow-list: nodes/disable,
    provided by PVE.panel.StorageBase). Prevents the GUI and schema drifting
    apart as new options are added (the original gap that hid skip_unmap_io_check,
    rest_keepalive, and lock_timeout). (GitHub issue #9)

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 27 Jun 2026 20:30:00 +0000

pve-storage-hitachiblock (1.2.0~alpha20-1) stable; urgency=medium

  * Add lock_timeout storage property (default 120s) overriding
    cluster_lock_storage to extend the per-storage cluster-lock ACQUISITION
    timeout for alloc/free/clone, which PVE core takes with no explicit timeout
    (pmxcfs default ~10s). Fixes spurious "got lock request timeout" when several
    disks are provisioned concurrently and serialize on the lock. Scope: extends
    only the wait to ACQUIRE; pmxcfs hard-caps the in-lock work at 60s, which this
    cannot change (for slow free/teardown enable skip_unmap_io_check / HMO 91).
    Reviewed externally (Codex) + verified against PVE::Cluster. (GitHub issue #10)

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 27 Jun 2026 19:45:00 +0000

pve-storage-hitachiblock (1.2.0~alpha19-1) stable; urgency=medium

  * Make linked clones work on VSP One Block / Thin Image Advanced (E590H).
    Rewrite clone_image to the workflow the array requires (confirmed live):
    S-VOL as Thin Image virtual volume (poolId -1), data-only autoSplit pair on
    the source, map the S-VOL, then assign-volume to the snapshot data -> a
    persistent host-R/W copy-on-write S-VOL. The old path supplied svolLdevId at
    pair creation, which the microcode rejects. New assign_snapshot_volume;
    create_ldev gains poolId -1 + blockCapacity. (GitHub #24)
  * Allocate the linked-clone S-VOL inside ldev_range (explicit in-range id) so
    the teardown fence accepts it. (GitHub #20)
  * Release the backing Thin Image pair when freeing a linked clone (the clone is
    the pair's S-VOL, not its P-VOL), so the S-VOL can be deleted instead of
    wedging the clone and its parent. (GitHub #23)
    Validated live end-to-end: clone create (CoW S-VOL, PSUS, in-range), boot
    host-R/W, and free with pairs released and no orphan.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 27 Jun 2026 18:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha18-1) stable; urgency=medium

  * Validate snap_pool_id is Thin Image-capable (single-tier HDP), failing fast
    with an actionable error instead of the array's cryptic mid-operation
    "multi-tier pool" rejection. Checks poolType/tiers/dataDirectMappingEnabled/
    isMainframe at volume_snapshot, clone_image, and the consistency-group path,
    and warns at activate_storage. The default snap_pool_id inherits pool_id,
    which is often an HDT data pool. Addresses GitHub issue #21.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 27 Jun 2026 12:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha17-1) stable; urgency=medium

  * Default to session-less Configuration Manager REST auth (HTTP basic auth per
    request) instead of a kept-alive session per worker process. The old model
    accumulated sessions as workers x cluster-nodes and exhausted the per-array
    CM session cap (~64), failing auth cluster-wide and stalling status()/
    pvestatd. Session-less auth holds no persistent session, so nothing
    accumulates; controller-endpoint failover still works. Opt back in with
    `rest_keepalive 1`. Verified live on the E590H that the GUM accepts basic
    auth across the full REST surface. Addresses GitHub issue #26.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Tue, 23 Jun 2026 12:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha16-1) stable; urgency=medium

  * Fix snapshot rollback (qm rollback) on the array. restore_snapshot sent
    {"parameters":{"operationType":"restore"}}; the Thin Image restore action
    rejects operationType (KART40038-E on E590H microcode 93-07-23), so rollback
    failed on both the direct and fallback paths and left a stale lock:rollback.
    The body is now an empty {"parameters":{}} (verified live on the E590H).
    Addresses GitHub issue #22.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 21 Jun 2026 19:30:00 +0000

pve-storage-hitachiblock (1.2.0~alpha15-1) stable; urgency=medium

  * Complete the alpha14 fix: pass scfg into _client at every call site so each
    volume operation can re-establish a REST session on its own. alpha14 kept
    scfg in a process-global stash, but PVE generates the cloud-init ISO in a
    separate forked process at VM start, leaving the start worker's stash empty
    so activate_volume still died "Storage 'X' is not activated". Every storage
    method already receives scfg, so _client($storeid, $scfg) now logs in
    independently of prior in-process activation (robust across the fork).
    Addresses GitHub issue #13.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 21 Jun 2026 15:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha14-1) stable; urgency=medium

  * Fix VM-start failure "Storage 'X' is not activated" when the cloud-init drive
    lives on the array (exposed by the alpha13 cloud-init feature). At VM start
    PVE activates the storage to generate the cloud-init ISO, deactivates it,
    then activates the boot volume; PVE's own $cache->{activated} makes it skip
    the second activate_storage, so our cleared client cache left activate_volume
    with no session and the start died. _client now remembers the scfg
    (activate_storage / check_connection) and lazily re-logins when its cache was
    cleared mid-process instead of dying. Found during the live VSP E590H retest.
    Addresses GitHub issue #13.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 21 Jun 2026 14:30:00 +0000

pve-storage-hitachiblock (1.2.0~alpha13-1) stable; urgency=medium

  * Support cloud-init drive volumes (vm-<vmid>-cloudinit). parse_volname now
    recognises the vm-<vmid>-cloudinit name (vtype images, format raw), so the
    full lifecycle (alloc/map/path/activate/free) accepts it. Previously
    alloc_image trusted the PVE-supplied name and created an LDEV while every
    later call rejected it ("unable to parse volume name"), so qm set --delete
    could not free the volume and the array LDEV leaked (manual REST cleanup
    required). A cloud-init disk is a regular tiny raw LUN once the name parses;
    the existing 48 MiB minimum-LDEV floor already covers its ~4 MiB request.
    The cloud-init drive can now live on the array
    (qm set <vmid> --ide2 <storage>:cloudinit). Found during the live VSP E590H
    bring-up. Fixes GitHub issue #6.
  * Test: add parse_volname_cloudinit regression subtest (name/vtype/vmid/format,
    vmid_from_volname prefix match, rejection of malformed -cloudinit variants).

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sun, 21 Jun 2026 12:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha12-1) stable; urgency=medium

  * Web UI (manager6) integration. Ships a JS module installed to
    /usr/share/pve-manager/js/pve-storage-hitachiblock.js that registers the
    hitachiblock type with the PVE manager UI: it now renders as "Hitachi Block"
    in Datacenter -> Storage (instead of the raw hitachiblock token) and appears
    in the Add storage drop-down with a full create/edit dialog (endpoint,
    device ID, DP pool, target FC ports, credentials, content, plus advanced
    platform/QoS/host-mode/LDEV-range/TLS options). The <script> include is
    injected into index.html.tpl from postinst and re-applied via a dpkg trigger
    (interest-noawait on the template), so it survives pve-manager upgrades;
    prerm removes it on package removal.
  * Docs: require installing the plugin on all cluster nodes (storage.cfg is
    cluster-wide; a node without the module silently drops the storage from its
    GUI and pvesm status). nodes= scopes activation to SAN-connected nodes.
    installation.md/configuration.md updated with a troubleshooting note and a
    pvesm add hitachiblock CLI example. Addresses GitHub issue #5.
  * Teardown hardening (complements skip_unmap_io_check / HMO 91 for the default,
    HMO-91-off path): increase the free_image unmap retry tolerance from 6 to 15
    (x3s backoff ~45s) so a just-stopped, recently-busy guest's LUN unmaps even
    while the array still reports "executing host I/O"; udevadm settle after
    deleting the SCSI paths in remove_device to shrink that I/O-draining window;
    and prune /etc/multipath/wwids on free (multipath -w only comments entries,
    so repeated activate/free cycles accumulated duplicate "#<wwid>" lines).

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 20 Jun 2026 15:30:00 +0000

pve-storage-hitachiblock (1.2.0~alpha11-1) stable; urgency=medium

  * Add skip_unmap_io_check storage option (boolean, default off): optional
    LUN-path teardown optimization. When set, HMO 91 ([OpenStack/OpenShift(K8s)]
    Skip I/O check when LUN path is deleted) is added to the plugin's host groups,
    so the array unmaps a LUN path immediately instead of returning "the LU is
    executing host I/O" while multipathd's path checker still probes the
    just-removed device. Safe because the plugin already removes the host-side
    multipath/SCSI device before unmapping; HMO 91 only drops the now-redundant
    interlock and skips free_image's retry/backoff. Host mode 00 on VSP One Block
    20 / E series.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 20 Jun 2026 13:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha10-1) stable; urgency=medium

  * Default host_mode_options is now 2,22,25,68 (was 68): Hitachi's best-practice
    HMO set for the LINUX/IRIX (00 Standard) host mode, verified against the
    Open-Systems Host Attachment Guide for VSP Family (A3-04-2x, v10.4.x) for both
    VSP One Block 20 and VSP E series.
    - 68 = WRITE SAME / SCSI ANSI v5 support (Page Reclamation for Linux: SCSI
      UNMAP/discard so thin pools reclaim on fstrim).
    - 2/22/25 = VERITAS DB-Adv Cluster / Veritas Cluster Server / SPC-3 Persistent
      Reservation. Default-on on VSP One Block, but set explicitly to cover older
      arrays (VSP E series, VSP 5000) where they are not.
    Added idempotently to existing host groups on activation (never removed).
    Corrected the HMO 68 name in code/docs. Closes #7.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 20 Jun 2026 12:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha9-1) stable; urgency=medium

  * Taint-mode safety, part 2 (completes LXC container provisioning). After the
    alpha8 fixes, CT creation still failed because the device PATH the plugin
    returns to PVE was tainted: PVE runs mkfs.ext4/mount on it via exec, which
    died "Insecure dependency in exec" under pct's taint mode.
    - get_device_path: untaint the /dev/mapper/3<wwid> path (a WWID is hex only)
      before returning it; reject a non-hex wwid.
    - ldev_to_wwid: untaint the synthesized WWID (built from the storage serial
      in storage.cfg).
    Extended t/unit/taint.t to assert get_device_path returns an UNTAINTED path.
    Verified live: an Alpine CT now provisions and boots with its ext4 rootfs on
    an array LUN over multipath (mkfs + mount + template extract all succeed).

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 20 Jun 2026 06:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha8-1) stable; urgency=medium

  * Taint-mode safety (fixes LXC container provisioning). pct runs the storage
    layer in Perl taint mode (-T); the Multipath module used tainted data in
    sensitive operations and died "Insecure dependency in open while running
    with -T switch", so CT rootfs allocation on the storage failed (VMs via qm,
    not taint-mode, were unaffected).
    - rescan_scsi_hosts: untaint the glob()-derived /sys/class/scsi_host/hostN
      path before the write-open.
    - rescan_scsi_targeted: untaint the host number parsed from the hctl.
    - _run_cmd: set a known-good $ENV{PATH}, drop IFS/CDPATH/ENV/BASH_ENV, and
      untaint argv against a conservative charset before exec.
    Added a taint-mode regression test (t/unit/taint.t).

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 20 Jun 2026 05:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha7-1) stable; urgency=medium

  * Advertise the `rootdir` content type in addition to `images`, so LXC
    containers can be placed on the storage (PVE formats and mounts the raw
    LUN for the container rootfs, like the LVM-thin block model). Default
    content remains `images`. Enables the container half of the PVE storage
    acceptance matrix (one VM + one CT).

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 20 Jun 2026 04:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha6-1) stable; urgency=medium

  * Live VSP E590H bring-up (Phase D, thin/discard). Enable SCSI UNMAP/discard
    so thin pools reclaim space on in-guest fstrim / blkdiscard:
    - Found live: the array advertised lbpme=0 (no UNMAP) on the plugin's LUNs,
      so blkdiscard/fstrim failed ("Operation not supported") and used capacity
      never dropped. Root cause: host groups were created with host mode
      LINUX/IRIX and NO host mode options. Hitachi gates Linux page reclamation
      behind Host Mode Option 68 ("Support Page Reclamation for Linux").
    - New `host_mode_options` storage option (default "68"); create_host_group
      now sends hostModeOptions, and _ensure_host_groups idempotently ADDS the
      configured options to pre-existing groups at activation (set_host_group_mode
      PATCHes with hostMode, which the CM REST requires alongside the options).
    - Verified live: with HMO 68 + a fresh device discovery the LUN reports
      lbpme=1 and discard_max=256 MiB (42 MiB granularity = DP page); after
      writing 4 GiB then blkdiscard, the LDEV's numOfUsedBlock returned to 0
      (array reclaimed all pages, asynchronously over a few minutes).

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 20 Jun 2026 02:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha5-1) stable; urgency=medium

  * Live VSP E590H bring-up hardening (Phase D — PVE functional acceptance).
    Two bugs only a real array + real guest creation could surface:
    - Tiny-volume allocation (PVE vTPM = fixed 4 MiB, EFI vars) failed with
      "It cannot create because the capacity is invalid." — the array refuses
      DP-VOLs below a hard minimum. Probed live: byteFormatCapacity <= 46 MiB
      fails the async job, >= 47 MiB succeeds. alloc_image now floors
      sub-minimum requests to 48 MiB (_alloc_size_mb); DP-VOLs are thin so the
      floored logical size costs ~0 real capacity. Volumes >= 48 MiB unchanged
      and still sized exactly.
    - list_ldevs() only returned LDEV slots 0-99 (GET /ldevs is a 100-slot
      window from headLdevId; count=16384 makes the GUM 503). A scan of any
      high ldev_range therefore saw NONE of the plugin's own LDEVs, which broke
      array orphan detection for the range and let `orphans --auto-cleanup`
      unregister a LIVE in-range volume (its id was absent from the window).
      Added RestClient::list_defined_ldevs_in_range (pages the range in safe
      chunks, drops NOT DEFINED empty slots); _next_ldev_in_range and the
      hitachiblock-repl orphan scan now use it, scoped to ldev_range.
    Verified live: 8 GiB disk = exactly 8589934592 bytes on the array
    (size-unit gate); online resize +4G grows LDEV + multipath map to 12 GiB.
  * Per-CU ldev_range awareness: an LDEV id is a CU:LDEV pair (256 LDEVs/CU;
    256-511 == CU 0x01). _next_ldev_in_range now scans the range one CU-sized
    window at a time and returns the first free id (early termination), so
    allocation is ~1 REST call when the low end is free instead of paging the
    whole range — relevant for wide multi-CU ranges. The add/update hooks warn
    (non-fatal) when ldev_range is not CU-aligned.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Sat, 20 Jun 2026 00:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha4-1) stable; urgency=medium

  * Live VSP E590H bring-up hardening (Phase C) — many bugs that only real
    hardware + a real PVE cluster could surface:
    - Host-group/WWN provisioning: resolve host group by name + idempotent reuse
      (the create response's resource id is a composite portId,num we don't parse);
      add_wwn sends hostGroupNumber; drop hostWwnNickname (rejected, KART40038-E);
      list_host_wwns uses /host-wwns?portId=..&hostGroupNumber=.. (the subresource 404s).
    - CRITICAL deadlock: the registry lock used cfs_lock_storage($storeid), the same
      lock PVE core holds around vdisk_alloc/free/activate — re-acquiring it
      self-deadlocked, stalling every alloc/free and the GUI for the lock timeout.
      Now uses a dedicated cfs_lock_domain.
    - LDEV create: don't combine an explicit ldevId with isParallelExecutionEnabled
      (KART40046-E).
    - free: tear down host paths before the array unmap (else "executing host I/O");
      unmap via the LDEV's own GET /ldevs/<id>.ports[] instead of scanning host groups.
    - SAFETY: GET /luns IGNORES the ldevId selector (verified live), so filter
      client-side; add an ldev_range fence (_ldev_in_range) that refuses to
      unmap/delete any LDEV outside the configured range.
    Validated on hardware: alloc -> LDEV in ldev_range, host-group LUN map, multipath
    device over both fabrics; free -> targeted unmap + delete + clean registry.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Fri, 19 Jun 2026 16:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha3-1) stable; urgency=medium

  * Adopt the current PVE storage plugin API (APIVER 14):
    - api() now returns 14 (was 10); the "older storage API" advisory is gone.
    - Handle credentials via sensitive properties: plugindata declares
      `password` sensitive, and on_add_hook/on_update_hook receive it via
      %sensitive instead of $scfg. This also fixes credential capture, which was
      already broken on PVE 9 (password is sensitive-by-default, so it never
      arrived in $scfg). username stays a normal storage.cfg property.
    - Implement on_update_hook (was missing) so `pvesm set` updates/clears creds.
    - Declare volume_qemu_snapshot_method => 'storage' (array Thin Image is
      transparent to the guest). qemu_blockdev_options relies on the base default,
      correct for our /dev/mapper block path.
    Verified live on PVE 9.2: plugin loads with no advisory, sensitive_properties
    reports `password`, daemons restart clean.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Fri, 19 Jun 2026 13:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha2-1) stable; urgency=medium

  * Live-PVE bring-up fixes (VSP E590H, PVE 9.2):
    - CRITICAL: stop redefining the `username`/`password` properties — PVE's
      base/CIFS/PBS plugins already define them, so PVE::SectionConfig died with
      "duplicate property" and broke pvesm and the PVE daemons on plugin install.
      They are now only referenced in options(). Regression-guarded in plugin.t.
    - status(): derive pool used capacity when `usedPoolCapacity` is null (as the
      E590H microcode returns) from total - availableVolumeCapacity / usedCapacityRate;
      previously reported the pool as 0% used.

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Fri, 19 Jun 2026 12:00:00 +0000

pve-storage-hitachiblock (1.2.0~alpha1-1) stable; urgency=medium

  * Alpha pre-release: not yet validated against a live array or cluster.
    The ~alpha1 version sorts below a future stable 1.2.0; do not use against
    production data until verified on hardware (see INTEGRATION_CHECKLIST.md).
  * Hardening release from a multi-model review (no features removed)
  * Cluster-wide registry lock via corosync-backed cfs_lock_storage (true cross-node
    serialization; plain flock on pmxcfs is only node-local), atomic commit
  * Refuse deletion of volumes/snapshots with dependent linked clones (data-safety)
  * Enforce volname<->ldev identity (no silent retarget / double-import / dup volid)
  * Orphan scan covers all pools so cleanup cannot unregister live volumes
  * alloc/clone/manage now fail loudly with rollback instead of leaving ghost volumes
  * filesystem_path returns the volume type per the PVE contract; api() now reports 10
  * POST create/map/expand no longer retried on 5xx/409 (only 429); login retries too
  * Consistency-group snapshots roll back partial pairs on failure
  * Async jobs returning only a Location header are now polled
  * Implemented base/template images (create_base) and volume_size_info
  * Deterministic per-LDEV port selection (replaces resettable round-robin counter)
  * Opt-in TLS verification (tls_verify/tls_ca_file); 429/Retry-After handling
  * True CoW linked clones (split Thin Image pair, autoSplit=true/isClone unset ->
    host-R/W PSUS S-VOL sharing blocks; source must be a base image or snapshot);
    full copies handled by PVE core via the device path
  * Use array-reported naaId (GET /ldevs/{id}) for the multipath WWID, with the
    synthesized/sysfs WWID as fallback
  * docs/reference/: Markdown extracts of the vendor PDFs (REST API, VSP user guide,
    Ops Center) that confirmed the clone/capacity/label/naaId/job assumptions
  * volume_has_feature reworked to the LVM-thin base/current/snap model; exposes rename
  * Implemented map_volume/unmap_volume (PVE 8 explicit map hooks)
  * Management-plane redundancy: mgmt_ip accepts a comma-separated list of
    per-controller REST endpoints with sticky failover + re-auth (data plane was
    already redundant via multipath over target_ports)
  * Multipath: auto-whitelist LUN WWIDs (multipath -a) so devices assemble under the
    default find_multipaths strict; de-whitelist (multipath -w) on free
  * Implemented rename_volume (PVE disk reassignment: relabel LDEV + rename entry)
  * Volume export/import (raw+size) so storage_migrate works: offline qm migrate to
    a non-shared target, qm remote-migrate, pvesm export/import (snapshots excluded)
  * VSP E series (e.g. E590H) support via new vsp_e platform (embedded REST, port 443)
  * Self-correcting WWID discovery from sysfs; long-storeid label hashing
  * Replication CLI reads storage.cfg, adds orphans (with --auto-cleanup) and --volume
  * Shell-free command execution in Multipath

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Tue, 17 Jun 2026 00:00:00 +0000

pve-storage-hitachiblock (1.1.0-1) stable; urgency=medium

  * Manage/unmanage volumes (LDEV import and release)
  * Zero page reclamation (discard_zero_page) for thin pool space recovery
  * QoS lower bounds (qos_lower_iops, qos_lower_mbps) and I/O priority (qos_priority)
  * LDEV range restriction (ldev_range) for multi-tenant environments
  * Storage-assisted volume migration between pools (volume_migrate_pool)
  * Consistency group snapshots (volume_snapshot_consistency_group)
  * Port scheduler: round-robin LUN mapping across target ports
  * Copy speed control for array-side clone/snapshot operations
  * Host group auto-delete on storage deactivation (group_delete)
  * Multi-attach support (concurrent LUN mappings to multiple nodes)

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Fri, 07 Mar 2026 00:00:00 +0000

pve-storage-hitachiblock (1.0.0-1) stable; urgency=medium

  * Replication CLI tool (TrueCopy, Universal Replicator, GAD)
  * RestClient replication operations (create/delete/split/resync pairs)
  * Remote storage registration
  * Full mocked test suite for RestClient
  * Plugin logic unit tests
  * GitHub Actions CI/CD pipeline

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Fri, 07 Mar 2026 00:00:00 +0000

pve-storage-hitachiblock (0.3.0-1) stable; urgency=medium

  * QoS support (per-LDEV IOPS/throughput limits)
  * Session auto-reconnect on expiry
  * Orphan detection and registry cleanup
  * Volume resize hardening (array size verification, buffer flush)
  * Partial failure cleanup in alloc_image

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Fri, 07 Mar 2026 00:00:00 +0000

pve-storage-hitachiblock (0.2.0-1) stable; urgency=medium

  * Snapshot metadata tracking and S-VOL lifecycle management
  * Snapshot-aware volume activation, path resolution, and cloning
  * volume_snapshot_info for PVE UI snapshot tree display
  * Parent tracking for linked clones
  * RestClient: get_snapshot, split_snapshot methods

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Fri, 07 Mar 2026 00:00:00 +0000

pve-storage-hitachiblock (0.1.0-1) stable; urgency=medium

  * Initial release
  * Core lifecycle: alloc/free/list/activate/status
  * REST API client for Hitachi Configuration Manager
  * Linux FC multipath management
  * Snapshot, clone, and resize support

 -- Ciro Iriarte <ciro.iriarte+software@gmail.com>  Fri, 07 Mar 2026 00:00:00 +0000
