librbd: restore readonly image check in snap_remove()
The check preventing snapshot removal on read-only images was previously
commented out. This commit restores the original behavior to ensure that
snap_remove() correctly rejects operations on images that are not writable.
rbd-mirror: suppress unnecessary log message during snapshot unlink
remote snapshots without a mirror peer UUID are filtered out early. Once the
peer UUID is removed from a remote snapshot, it no longer appears in
m_remote_group_snaps locally. As a result, mirror_group_snapshot_unlink_peer()
will not find that snapshot in m_remote_group_snaps, and this condition is
most expected now.
avoid printing the log message that warns about the snapshot not being present,
as this is not the true case (as it is filtered) and can be misleading.
Moreover, the message would otherwise be printed repeatedly until the local
snapshot is eventually removed, creating unnecessary noise in the logs.
VinayBhaskar-V [Wed, 20 Aug 2025 18:30:09 +0000 (18:30 +0000)]
rbd-mirror: integration of the new GroupSnapshotNamespaceMirror::complete field
This commit introduces the new field **complete**, of type **MirrorGroupSnapshotCompleteState** enum,
to the GroupSnapshotNamespaceMirror structure. This change is necessary to align behavior of
mirror group snapshots with that of mirror image snapshots, allowing for a precise differentiation
between a group snapshot that has been created and one that has been fully synced.
**1. Handling Old-Style Snapshots**
Decoding Old Snapshots: The original GroupSnapshotNamespaceMirror structure lacked the complete field,
which implicitly defaulted to a bool value of false upon initialization.
When an old snapshot (lacking the complete field) is decoded by an upgraded client,
the implicit default value maps to MIRROR_GROUP_SNAPSHOT_COMPLETE_IF_CREATED.
Completion Check: A snapshot is determined old by checking it's complete filed i.e
complete == MIRROR_GROUP_SNAPSHOT_COMPLETE_IF_CREATED and if it's old the sync completion
for these group snapshots is determined by checking the state field
i.e state == GROUP_SNAPSHOT_STATE_CREATED.
During a upgrade where **OSDs have not yet been updated**, the new client will be forced to create
snapshots using the old style. These snapshots will be initialized with MIRROR_GROUP_SNAPSHOT_COMPLETE_IF_CREATED
and will stay on that to prevent immediate, incorrect cleanup by the old OSDs and in this case
state field is set to **GROUP_SNAPSHOT_STATE_CREATED** only after snapshot completed it's sync.
**2. Handling New-Style Snapshots**
New snapshots are initialized with complete == **MIRROR_GROUP_SNAPSHOT_INCOMPLETE**,
state == GROUP_SNAPSHOT_STATE_CREATING. The group snapshot's state is marked as GROUP_SNAPSHOT_STATE_CREATED
as soon as its metadata is fully available and stored.
Completion Check: The snapshot's sync is confirmed only when complete == MIRROR_GROUP_SNAPSHOT_COMPLETE
along with state check (state == GROUP_SNAPSHOT_STATE_CREATED) is satisfied.
This approach ensures seamless transition and compatibility, allowing the system to correctly interpret the
synchronization status of both old and newly created group snapshots.
librbd: fix incomplete group snapshot not being removed on creation failure
Problem:
GroupCreatePrimaryRequest doesn't remove group snapshot when group
snapshot creation encounters an error in notify_quiesce(). As a result,
INCOMPLETE snapshots from previous failed attempts remain uncleaned.
When snapshot creation fails, the remove snap path that cleans the snapshot is
skipped, leaving behind INCOMPLETE snapshot entries.
Solution:
Ensure remove_snap_metadata() is executed on failed to quience scenario like
above, allowing INCOMPLETE snapshot to be consistently cleaned up.
Note:
Another issue identified and fixed around GroupUnlinkPeerRequest::remove_peer_uuid(),
i.e in case of INCOMPLETE snapshot, group_snap_set() is expected to return
EEXIST error, and that is now handled.