From f30ff7ceafecf40503059f4aaa67c87382b065f2 Mon Sep 17 00:00:00 2001 From: Arvin Schnell Date: Tue, 2 Sep 2025 15:08:03 +0200 Subject: [PATCH] - added generic plugin action used when setting snapshot read-only --- client/proxy/proxy-dbus.cc | 4 ++-- client/proxy/proxy-dbus.h | 4 ++-- client/proxy/proxy-lib.h | 2 +- client/proxy/proxy.h | 6 +++--- client/snapper/cmd-modify.cc | 4 ++-- doc/snapper.xml.in | 16 ++++++++++++++-- package/snapper.changes | 6 ++++++ server/Client.cc | 2 +- snapper/Bcachefs.cc | 10 +++++++--- snapper/Bcachefs.h | 4 ++-- snapper/Btrfs.cc | 8 ++++++-- snapper/Btrfs.h | 4 ++-- snapper/Filesystem.h | 4 ++-- snapper/Lvm.cc | 9 +++++++-- snapper/Lvm.h | 4 ++-- snapper/PluginsImpl.cc | 20 ++++++++++++++++++++ snapper/PluginsImpl.h | 5 ++++- snapper/Snapshot.cc | 4 ++-- snapper/Snapshot.h | 6 +++--- 19 files changed, 88 insertions(+), 34 deletions(-) diff --git a/client/proxy/proxy-dbus.cc b/client/proxy/proxy-dbus.cc index 743e705e..2f4768f0 100644 --- a/client/proxy/proxy-dbus.cc +++ b/client/proxy/proxy-dbus.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) [2016-2024] SUSE LLC + * Copyright (c) [2016-2025] SUSE LLC * * All Rights Reserved. * @@ -64,7 +64,7 @@ ProxySnapshotDbus::isReadOnly() const void -ProxySnapshotDbus::setReadOnly(bool read_only) +ProxySnapshotDbus::setReadOnly(bool read_only, Plugins::Report& report) { command_set_snapshot_read_only(conn(), configName(), num, read_only); } diff --git a/client/proxy/proxy-dbus.h b/client/proxy/proxy-dbus.h index 1b0cd8a3..030bc036 100644 --- a/client/proxy/proxy-dbus.h +++ b/client/proxy/proxy-dbus.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2016-2024] SUSE LLC + * Copyright (c) [2016-2025] SUSE LLC * * All Rights Reserved. * @@ -59,7 +59,7 @@ public: virtual time_t getDate() const override { return date; } virtual uid_t getUid() const override { return uid; } virtual bool isReadOnly() const override; - virtual void setReadOnly(bool read_only) override; + virtual void setReadOnly(bool read_only, Plugins::Report& report) override; virtual unsigned int getPreNum() const override { return pre_num; } virtual const string& getDescription() const override { return description; } virtual const string& getCleanup() const override { return cleanup; } diff --git a/client/proxy/proxy-lib.h b/client/proxy/proxy-lib.h index a3baa485..8d34fdd2 100644 --- a/client/proxy/proxy-lib.h +++ b/client/proxy/proxy-lib.h @@ -47,7 +47,7 @@ public: virtual time_t getDate() const override { return it->getDate(); } virtual uid_t getUid() const override { return it->getUid(); } virtual bool isReadOnly() const override { return it->isReadOnly(); } - virtual void setReadOnly(bool read_only) override { it->setReadOnly(read_only); } + virtual void setReadOnly(bool read_only, Plugins::Report& report) override { it->setReadOnly(read_only, report); } virtual unsigned int getPreNum() const override { return it->getPreNum(); } virtual const string& getDescription() const override { return it->getDescription(); } virtual const string& getCleanup() const override { return it->getCleanup(); } diff --git a/client/proxy/proxy.h b/client/proxy/proxy.h index 3f24358f..65c7a45b 100644 --- a/client/proxy/proxy.h +++ b/client/proxy/proxy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2016-2024] SUSE LLC + * Copyright (c) [2016-2025] SUSE LLC * * All Rights Reserved. * @@ -102,7 +102,7 @@ public: time_t getDate() const { return impl->getDate(); } uid_t getUid() const { return impl->getUid(); } bool isReadOnly() const { return impl->isReadOnly(); } - void setReadOnly(bool read_only) { impl->setReadOnly(read_only); } + void setReadOnly(bool read_only, Plugins::Report& report) { impl->setReadOnly(read_only, report); } unsigned int getPreNum() const { return impl->getPreNum(); } const string& getDescription() const { return impl->getDescription(); } const string& getCleanup() const { return impl->getCleanup(); } @@ -134,7 +134,7 @@ public: virtual time_t getDate() const = 0; virtual uid_t getUid() const = 0; virtual bool isReadOnly() const = 0; - virtual void setReadOnly(bool read_only) = 0; + virtual void setReadOnly(bool read_only, Plugins::Report& report) = 0; virtual unsigned int getPreNum() const = 0; virtual const string& getDescription() const = 0; virtual const string& getCleanup() const = 0; diff --git a/client/snapper/cmd-modify.cc b/client/snapper/cmd-modify.cc index e9304c55..0c9d7e9a 100644 --- a/client/snapper/cmd-modify.cc +++ b/client/snapper/cmd-modify.cc @@ -1,6 +1,6 @@ /* * Copyright (c) [2011-2015] Novell, Inc. - * Copyright (c) [2016-2023] SUSE LLC + * Copyright (c) [2016-2025] SUSE LLC * * All Rights Reserved. * @@ -135,7 +135,7 @@ namespace snapper if (set_read_only) { - snapshot->setReadOnly(read_only); + snapshot->setReadOnly(read_only, report); } if (set_default) diff --git a/doc/snapper.xml.in b/doc/snapper.xml.in index c9b33ddd..613e07d0 100644 --- a/doc/snapper.xml.in +++ b/doc/snapper.xml.in @@ -2,13 +2,13 @@ - 2025-07-23 + 2025-09-02 snapper 8 - 2025-07-23 + 2025-09-02 @VERSION@ Filesystem Snapshot Management @@ -954,6 +954,18 @@ Executed after a snapshot was removed + + + + Executed before a snapshot is set read-only or read-write + + + + + + Executed after a snapshot is set read-only or read-write + + diff --git a/package/snapper.changes b/package/snapper.changes index 3fd6a250..ae3ead15 100644 --- a/package/snapper.changes +++ b/package/snapper.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Sep 02 14:29:41 CEST 2025 - aschnell@suse.com + +- added generic plugin action used when setting snapshot read-only + (bsc#1246172) + ------------------------------------------------------------------- Mon Aug 04 17:00:45 CEST 2025 - Arvin Schnell diff --git a/server/Client.cc b/server/Client.cc index eec19dd2..538b38da 100644 --- a/server/Client.cc +++ b/server/Client.cc @@ -1199,7 +1199,7 @@ Client::set_snapshot_read_only(DBus::Connection& conn, DBus::Message& msg) if (snap == snapshots.end()) SN_THROW(IllegalSnapshotException()); - snap->setReadOnly(read_only); + snap->setReadOnly(read_only, report); DBus::MessageMethodReturn reply(msg); diff --git a/snapper/Bcachefs.cc b/snapper/Bcachefs.cc index 6ea886dc..e83f6f76 100644 --- a/snapper/Bcachefs.cc +++ b/snapper/Bcachefs.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SUSE LLC + * Copyright (c) [2024-2025] SUSE LLC * * All Rights Reserved. * @@ -35,7 +35,7 @@ #include "snapper/Snapper.h" #include "snapper/SnapperTmpl.h" #include "snapper/SnapperDefines.h" - +#include "snapper/PluginsImpl.h" #include "snapper/Acls.h" #include "snapper/Exception.h" #ifdef ENABLE_SELINUX @@ -292,10 +292,14 @@ namespace snapper void - Bcachefs::setSnapshotReadOnly(unsigned int num, bool read_only) const + Bcachefs::setSnapshotReadOnly(unsigned int num, bool read_only, Plugins::Report& report) const { + Plugins::set_read_only(Plugins::Stage::PRE_ACTION, subvolume, this, num, report); + SDir snapshot_dir = openSnapshotDir(num); set_subvolume_read_only(snapshot_dir.fd(), read_only); + + Plugins::set_read_only(Plugins::Stage::POST_ACTION, subvolume, this, num, report); } diff --git a/snapper/Bcachefs.h b/snapper/Bcachefs.h index 30696ece..119a9bc7 100644 --- a/snapper/Bcachefs.h +++ b/snapper/Bcachefs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SUSE LLC + * Copyright (c) [2024-2025] SUSE LLC * * All Rights Reserved. * @@ -59,7 +59,7 @@ namespace snapper virtual void umountSnapshot(unsigned int num) const override; virtual bool isSnapshotReadOnly(unsigned int num) const override; - virtual void setSnapshotReadOnly(unsigned int num, bool read_only) const override; + virtual void setSnapshotReadOnly(unsigned int num, bool read_only, Plugins::Report& report) const override; virtual bool checkSnapshot(unsigned int num) const override; diff --git a/snapper/Btrfs.cc b/snapper/Btrfs.cc index e10053dc..9513c136 100644 --- a/snapper/Btrfs.cc +++ b/snapper/Btrfs.cc @@ -1,6 +1,6 @@ /* * Copyright (c) [2011-2015] Novell, Inc. - * Copyright (c) [2016-2024] SUSE LLC + * Copyright (c) [2016-2025] SUSE LLC * * All Rights Reserved. * @@ -460,10 +460,14 @@ namespace snapper void - Btrfs::setSnapshotReadOnly(unsigned int num, bool read_only) const + Btrfs::setSnapshotReadOnly(unsigned int num, bool read_only, Plugins::Report& report) const { + Plugins::set_read_only(Plugins::Stage::PRE_ACTION, subvolume, this, num, report); + SDir snapshot_dir = openSnapshotDir(num); set_subvolume_read_only(snapshot_dir.fd(), read_only); + + Plugins::set_read_only(Plugins::Stage::POST_ACTION, subvolume, this, num, report); } diff --git a/snapper/Btrfs.h b/snapper/Btrfs.h index 4357ef04..21dc759c 100644 --- a/snapper/Btrfs.h +++ b/snapper/Btrfs.h @@ -1,6 +1,6 @@ /* * Copyright (c) [2011-2015] Novell, Inc. - * Copyright (c) [2016-2023] SUSE LLC + * Copyright (c) [2016-2025] SUSE LLC * * All Rights Reserved. * @@ -77,7 +77,7 @@ namespace snapper virtual void umountSnapshot(unsigned int num) const override; virtual bool isSnapshotReadOnly(unsigned int num) const override; - virtual void setSnapshotReadOnly(unsigned int num, bool read_only) const override; + virtual void setSnapshotReadOnly(unsigned int num, bool read_only, Plugins::Report& report) const override; virtual bool checkSnapshot(unsigned int num) const override; diff --git a/snapper/Filesystem.h b/snapper/Filesystem.h index 42ebd6ef..3b14df06 100644 --- a/snapper/Filesystem.h +++ b/snapper/Filesystem.h @@ -1,6 +1,6 @@ /* * Copyright (c) [2011-2015] Novell, Inc. - * Copyright (c) [2016-2023] SUSE LLC + * Copyright (c) [2016-2025] SUSE LLC * * All Rights Reserved. * @@ -81,7 +81,7 @@ namespace snapper virtual void umountSnapshot(unsigned int num) const = 0; virtual bool isSnapshotReadOnly(unsigned int num) const = 0; - virtual void setSnapshotReadOnly(unsigned int num, bool read_only) const = 0; + virtual void setSnapshotReadOnly(unsigned int num, bool read_only, Plugins::Report& report) const = 0; virtual bool checkSnapshot(unsigned int num) const = 0; diff --git a/snapper/Lvm.cc b/snapper/Lvm.cc index c6276a7f..339de482 100644 --- a/snapper/Lvm.cc +++ b/snapper/Lvm.cc @@ -1,6 +1,6 @@ /* * Copyright (c) [2011-2014] Novell, Inc. - * Copyright (c) [2020-2023] SUSE LLC + * Copyright (c) [2020-2025] SUSE LLC * * All Rights Reserved. * @@ -43,6 +43,7 @@ #include "snapper/SystemCmd.h" #include "snapper/SnapperDefines.h" #include "snapper/LvmCache.h" +#include "snapper/PluginsImpl.h" #ifdef ENABLE_SELINUX #include "snapper/Selinux.h" #endif @@ -383,11 +384,15 @@ namespace snapper void - Lvm::setSnapshotReadOnly(unsigned int num, bool read_only) const + Lvm::setSnapshotReadOnly(unsigned int num, bool read_only, Plugins::Report& report) const { try { + Plugins::set_read_only(Plugins::Stage::PRE_ACTION, subvolume, this, num, report); + cache->set_read_only(vg_name, snapshotLvName(num), read_only); + + Plugins::set_read_only(Plugins::Stage::POST_ACTION, subvolume, this, num, report); } catch (const LvmCacheException& e) { diff --git a/snapper/Lvm.h b/snapper/Lvm.h index bb6da1c8..5fcccb3e 100644 --- a/snapper/Lvm.h +++ b/snapper/Lvm.h @@ -1,6 +1,6 @@ /* * Copyright (c) [2011-2014] Novell, Inc. - * Copyright (c) 2023 SUSE LLC + * Copyright (c) [2023-2025] SUSE LLC * * All Rights Reserved. * @@ -107,7 +107,7 @@ namespace snapper virtual void umountSnapshot(unsigned int num) const override; virtual bool isSnapshotReadOnly(unsigned int num) const override; - virtual void setSnapshotReadOnly(unsigned int num, bool read_only) const override; + virtual void setSnapshotReadOnly(unsigned int num, bool read_only, Plugins::Report& report) const override; virtual bool checkSnapshot(unsigned int num) const override; diff --git a/snapper/PluginsImpl.cc b/snapper/PluginsImpl.cc index ad1dc2f3..aff46dd9 100644 --- a/snapper/PluginsImpl.cc +++ b/snapper/PluginsImpl.cc @@ -208,6 +208,26 @@ namespace snapper } + void + Plugins::set_read_only(Stage stage, const string& subvolume, const Filesystem* filesystem, + unsigned int num, Report& report) + { + switch (stage) + { + case Stage::PRE_ACTION: + run_scripts({ "set-read-only-pre", subvolume, filesystem->fstype(), + std::to_string(num) }, report); + break; + + case Stage::POST_ACTION: + grub(subvolume, filesystem, "--enable", report); + run_scripts({ "set-read-only-post", subvolume, filesystem->fstype(), + std::to_string(num) }, report); + break; + } + } + + void Plugins::set_default_snapshot(Stage stage, const string& subvolume, const Filesystem* filesystem, unsigned int num, Report& report) diff --git a/snapper/PluginsImpl.h b/snapper/PluginsImpl.h index fff5eddd..40b5f6c9 100644 --- a/snapper/PluginsImpl.h +++ b/snapper/PluginsImpl.h @@ -1,6 +1,6 @@ /* * Copyright (c) [2011-2015] Novell, Inc. - * Copyright (c) [2022-2023] SUSE LLC + * Copyright (c) [2022-2025] SUSE LLC * * All Rights Reserved. * @@ -52,6 +52,9 @@ namespace snapper void delete_snapshot(Stage stage, const string& subvolume, const Filesystem* filesystem, const Snapshot& snapshot, Report& report); + void set_read_only(Stage stage, const string& subvolume, const Filesystem* filesystem, + unsigned int num, Report& report); + void set_default_snapshot(Stage stage, const string& subvolume, const Filesystem* filesystem, unsigned int num, Report& report); diff --git a/snapper/Snapshot.cc b/snapper/Snapshot.cc index fbfbb1e6..dde63b40 100644 --- a/snapper/Snapshot.cc +++ b/snapper/Snapshot.cc @@ -134,7 +134,7 @@ namespace snapper void - Snapshot::setReadOnly(bool read_only) + Snapshot::setReadOnly(bool read_only, Plugins::Report& report) { if (isCurrent()) SN_THROW(IllegalSnapshotException()); @@ -144,7 +144,7 @@ namespace snapper Snapshot::read_only = read_only; - snapper->getFilesystem()->setSnapshotReadOnly(num, read_only); + snapper->getFilesystem()->setSnapshotReadOnly(num, read_only, report); if (!read_only) deleteFilelists(); diff --git a/snapper/Snapshot.h b/snapper/Snapshot.h index 9f8c2e49..a1739a89 100644 --- a/snapper/Snapshot.h +++ b/snapper/Snapshot.h @@ -107,14 +107,14 @@ namespace snapper SDir openSnapshotDir() const; /** - * Determine iff snapshot is read-only (only for btrfs). + * Determine iff snapshot is read-only (may not be supported by all file system types). */ bool isReadOnly() const; /** - * Set snapshot read-only or read-write (only for btrfs). + * Set snapshot read-only or read-write (may not be supported by all file system types). */ - void setReadOnly(bool read_only); + void setReadOnly(bool read_only, Plugins::Report& report); /** * Determine iff snapshot is default (will be activated on next boot time). -- 2.47.3