Hi, I created a patch to adopt timeshift to typical Debian system installed by d-i.
Thiis is FYI. This is rather a big patch set. I am not going to maintain this but as a proof-of- concept. Now I can make snapshot for /. (I have separate subvolum for /home/<user> so snapshot of /home is useless.) The best fix may be work with upstream to make @rootfs and @home configurable parameter. But this may help identify where you need to refactor. I am not going to label as + patch Osamu
From 579ad52e500b38ed176a071e99e62ae5f2483709 Mon Sep 17 00:00:00 2001 From: Osamu Aoki <os...@debian.org> Date: Fri, 15 Jul 2022 22:26:09 +0900 Subject: [PATCH] @ -> @rootfs Signed-off-by: Osamu Aoki <os...@debian.org> --- src/Console/AppConsole.vala | 2 +- src/Core/Main.vala | 68 ++++++++++++++++----------------- src/Core/Snapshot.vala | 8 ++-- src/Core/SnapshotRepo.vala | 12 +++--- src/Core/Subvolume.vala | 4 +- src/Gtk/RestoreDeviceBox.vala | 2 +- src/Gtk/SnapshotBackendBox.vala | 2 +- src/Gtk/SnapshotListBox.vala | 8 ++-- 8 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/Console/AppConsole.vala b/src/Console/AppConsole.vala index 3084e87..12fcc1a 100644 --- a/src/Console/AppConsole.vala +++ b/src/Console/AppConsole.vala @@ -688,7 +688,7 @@ public class AppConsole : GLib.Object { if (App.btrfs_mode && !App.check_device_for_backup(dev, true)){ log_error(_("Selected snapshot device is not a system disk")); - log_error(_("Select BTRFS system disk with root subvolume (@)")); + log_error(_("Select BTRFS system disk with root subvolume (@rootfs)")); dev = null; } } diff --git a/src/Core/Main.vala b/src/Core/Main.vala index bb53e38..38a2ba1 100644 --- a/src/Core/Main.vala +++ b/src/Core/Main.vala @@ -373,14 +373,14 @@ public class Main : GLib.Object{ log_debug("check_btrfs_layout_system()"); - bool supported = sys_subvolumes.has_key("@"); + bool supported = sys_subvolumes.has_key("@rootfs"); if (include_btrfs_home_for_backup){ supported = supported && sys_subvolumes.has_key("@home"); } if (!supported){ string msg = _("The system partition has an unsupported subvolume layout.") + " "; - msg += _("Only ubuntu-type layouts with @ and @home subvolumes are currently supported.") + "\n\n"; + msg += _("Only Debian-type layouts with @rootfs and @home subvolumes are currently supported.") + "\n\n"; msg += _("Application will exit.") + "\n\n"; string title = _("Not Supported"); @@ -406,7 +406,7 @@ public class Main : GLib.Object{ if (dev_home != dev_root){ - supported = supported && check_btrfs_volume(dev_root, "@", unlock); + supported = supported && check_btrfs_volume(dev_root, "@rootfs", unlock); if (include_btrfs_home_for_backup){ supported = supported && check_btrfs_volume(dev_home, "@home", unlock); @@ -414,10 +414,10 @@ public class Main : GLib.Object{ } else{ if (include_btrfs_home_for_backup){ - supported = supported && check_btrfs_volume(dev_root, "@,@home", unlock); + supported = supported && check_btrfs_volume(dev_root, "@rootfs,@home", unlock); } else{ - supported = supported && check_btrfs_volume(dev_root, "@", unlock); + supported = supported && check_btrfs_volume(dev_root, "@rootfs", unlock); } } } @@ -1452,7 +1452,7 @@ public class Main : GLib.Object{ log_msg(_("Creating new backup...") + "(BTRFS)"); - log_msg(_("Saving to device") + ": %s".printf(repo.device.device) + ", " + _("mounted at path") + ": %s".printf(repo.mount_paths["@"])); + log_msg(_("Saving to device") + ": %s".printf(repo.device.device) + ", " + _("mounted at path") + ": %s".printf(repo.mount_paths["@rootfs"])); if ((repo.device_home != null) && (repo.device_home.uuid != repo.device.uuid)){ log_msg(_("Saving to device") + ": %s".printf(repo.device_home.device) + ", " + _("mounted at path") + ": %s".printf(repo.mount_paths["@home"])); } @@ -1471,11 +1471,11 @@ public class Main : GLib.Object{ // create subvolume snapshots - var subvol_names = new string[] { "@" }; + var subvol_names = new string[] { "@rootfs" }; if (include_btrfs_home_for_backup){ - subvol_names = new string[] { "@","@home" }; + subvol_names = new string[] { "@rootfs","@home" }; } foreach(var subvol_name in subvol_names){ @@ -1489,8 +1489,8 @@ public class Main : GLib.Object{ string dst_path = path_combine(snapshot_path, subvol_name); // Dirty hack to fix the nested subvilumes issue (cause of issue is unknown) - if (dst_path.has_suffix("/@/@")){ - dst_path = dst_path.replace("/@/@", "/@"); + if (dst_path.has_suffix("/@rootfs/@rootfs")){ + dst_path = dst_path.replace("/@rootfs/@rootfs", "/@rootfs"); } else if (dst_path.has_suffix("/@home/@home")){ dst_path = dst_path.replace("/@home/@home", "/@home"); @@ -1518,7 +1518,7 @@ public class Main : GLib.Object{ //log_msg(_("Writing control file...")); - snapshot_path = path_combine(repo.mount_paths["@"], "timeshift-btrfs/snapshots/%s".printf(snapshot_name)); + snapshot_path = path_combine(repo.mount_paths["@rootfs"], "timeshift-btrfs/snapshots/%s".printf(snapshot_name)); string initial_tags = (tag == "ondemand") ? "" : tag; @@ -2053,8 +2053,8 @@ public class Main : GLib.Object{ // final check - check if target root device is mounted if (btrfs_mode){ - if (repo.mount_paths["@"].length == 0){ - log_error(_("BTRFS device is not mounted") + ": @"); + if (repo.mount_paths["@rootfs"].length == 0){ + log_error(_("BTRFS device is not mounted") + ": @rootfs"); return false; } if (include_btrfs_home_for_restore && (repo.mount_paths["@home"].length == 0)){ @@ -2896,9 +2896,9 @@ public class Main : GLib.Object{ string snapshot_path = ""; /* Note: - * The @ and @home subvolumes need to be backed-up only if they are in use by the system. + * The @rootfs and @home subvolumes need to be backed-up only if they are in use by the system. * If user restores a snapshot and then tries to restore another snapshot before the next reboot - * then the @ and @home subvolumes are the ones that were previously restored and need to be deleted. + * then the @rootfs and @home subvolumes are the ones that were previously restored and need to be deleted. * */ bool create_pre_restore_backup = false; @@ -2920,9 +2920,9 @@ public class Main : GLib.Object{ if (found){ //delete system subvolumes - if (sys_subvolumes.has_key("@") && snapshot_to_restore.subvolumes.has_key("@")){ - sys_subvolumes["@"].remove(); - log_msg(_("Deleted subvolume") + ": @"); + if (sys_subvolumes.has_key("@rootfs") && snapshot_to_restore.subvolumes.has_key("@rootfs")){ + sys_subvolumes["@rootfs"].remove(); + log_msg(_("Deleted subvolume") + ": @rootfs"); } if (include_btrfs_home_for_restore && sys_subvolumes.has_key("@home") && snapshot_to_restore.subvolumes.has_key("@home")){ sys_subvolumes["@home"].remove(); @@ -2953,9 +2953,9 @@ public class Main : GLib.Object{ var subvol_list = new Gee.ArrayList<Subvolume>(); - var subvol_names = new string[] { "@" }; + var subvol_names = new string[] { "@rootfs" }; if (include_btrfs_home_for_restore){ - subvol_names = new string[] { "@","@home" }; + subvol_names = new string[] { "@rootfs","@home" }; } foreach(string subvol_name in subvol_names){ @@ -2984,7 +2984,7 @@ public class Main : GLib.Object{ return false; } else{ - var subvol_dev = (subvol_name == "@") ? repo.device : repo.device_home; + var subvol_dev = (subvol_name == "@rootfs") ? repo.device : repo.device_home; subvol_list.add(new Subvolume(subvol_name, dst_path, subvol_dev.uuid, repo)); log_msg(_("Moved system subvolume to snapshot directory") + ": %s".printf(subvol_name)); @@ -2998,11 +2998,11 @@ public class Main : GLib.Object{ else{ // write control file ----------- - snapshot_path = path_combine(repo.mount_paths["@"], "timeshift-btrfs/snapshots/%s".printf(snapshot_name)); + snapshot_path = path_combine(repo.mount_paths["@rootfs"], "timeshift-btrfs/snapshots/%s".printf(snapshot_name)); var snap = Snapshot.write_control_file( snapshot_path, dt_created, repo.device.uuid, - LinuxDistro.get_dist_info(path_combine(snapshot_path,"@")).full_name(), + LinuxDistro.get_dist_info(path_combine(snapshot_path,"@rootfs")).full_name(), "ondemand", "", 0, true, false, repo); snap.description = "Before restoring '%s'".printf(snapshot_to_restore.date_formatted); @@ -3220,7 +3220,7 @@ public class Main : GLib.Object{ // load some defaults for first-run based on user's system type - bool supported = sys_subvolumes.has_key("@") && cmd_exists("btrfs"); // && sys_subvolumes.has_key("@home") + bool supported = sys_subvolumes.has_key("@rootfs") && cmd_exists("btrfs"); // && sys_subvolumes.has_key("@home") if (supported || (cmd_btrfs_mode == true)){ log_msg(_("Selected default snapshot type") + ": %s".printf("BTRFS")); btrfs_mode = true; @@ -3441,7 +3441,7 @@ public class Main : GLib.Object{ foreach(var mp in dev_mounted.mount_points){ if ((mp.mount_point == mount_point_restore) - && (mp.mount_options == "subvol=@")){ + && (mp.mount_options == "subvol=@rootfs")){ = true; return; //already_mounted @@ -3461,7 +3461,7 @@ public class Main : GLib.Object{ if (!supported && snapshot_to_restore.has_subvolumes()){ string msg = _("The target partition has an unsupported subvolume layout.") + "\n"; - msg += _("Only ubuntu-type layouts with @ and @home subvolumes are currently supported."); + msg += _("Only ubuntu-type layouts with @rootfs and @home subvolumes are currently supported."); if (app_mode == ""){ string title = _("Unsupported Subvolume Layout"); @@ -3510,7 +3510,7 @@ public class Main : GLib.Object{ if (mnt.device.fstype == "btrfs"){ if (mnt.mount_point == "/"){ - mount_options = "subvol=@"; + mount_options = "subvol=@rootfs"; } if (include_btrfs_home_for_restore){ if (mnt.mount_point == "/home"){ @@ -3639,8 +3639,8 @@ public class Main : GLib.Object{ update_partitions(); // In BTRFS mode, select the system disk if system disk is BTRFS - if (btrfs_mode && sys_subvolumes.has_key("@")){ - var subvol_root = sys_subvolumes["@"]; + if (btrfs_mode && sys_subvolumes.has_key("@rootfs")){ + var subvol_root = sys_subvolumes["@rootfs"]; repo = new SnapshotRepo.from_device(subvol_root.get_device(), parent_win, btrfs_mode); return; } @@ -3663,7 +3663,7 @@ public class Main : GLib.Object{ if (dev.has_children()) { return false; } if (btrfs_mode && ((dev.fstype == "btrfs")||(dev.fstype == "luks"))){ - if (check_btrfs_volume(dev, "@", unlock)){ + if (check_btrfs_volume(dev, "@rootfs", unlock)){ return true; } } @@ -3845,7 +3845,7 @@ public class Main : GLib.Object{ } public bool query_subvolume_ids(){ - bool ok = query_subvolume_id("@"); + bool ok = query_subvolume_id("@rootfs"); if ((repo.device_home != null) && (repo.device.uuid != repo.device_home.uuid)){ ok = ok && query_subvolume_id("@home"); } @@ -3873,7 +3873,7 @@ public class Main : GLib.Object{ /* Sample Output: * - ID 257 gen 56 top level 5 path timeshift-btrfs/snapshots/2014-09-26_23-34-08/@ + ID 257 gen 56 top level 5 path timeshift-btrfs/snapshots/2014-09-26_23-34-08/@rootfs ID 258 gen 52 top level 5 path timeshift-btrfs/snapshots/2014-09-26_23-34-08/@home * */ @@ -3885,8 +3885,8 @@ public class Main : GLib.Object{ Subvolume subvol = null; - if ((sys_subvolumes.size > 0) && line.has_suffix(sys_subvolumes["@"].path.replace(repo.mount_paths["@"] + "/"," "))){ - subvol = sys_subvolumes["@"]; + if ((sys_subvolumes.size > 0) && line.has_suffix(sys_subvolumes["@rootfs"].path.replace(repo.mount_paths["@rootfs"] + "/"," "))){ + subvol = sys_subvolumes["@rootfs"]; } else if ((sys_subvolumes.size > 0) && sys_subvolumes.has_key("@home") diff --git a/src/Core/Snapshot.vala b/src/Core/Snapshot.vala index cae83d4..c49af5b 100644 --- a/src/Core/Snapshot.vala +++ b/src/Core/Snapshot.vala @@ -237,7 +237,7 @@ public class Snapshot : GLib.Object{ foreach(string subvol_name in subvols.get_members()){ - if ((subvol_name != "@")&&(subvol_name != "@home")){ continue; } + if ((subvol_name != "@rootfs")&&(subvol_name != "@home")){ continue; } paths[subvol_name] = path.replace(repo.mount_path, repo.mount_paths[subvol_name]); @@ -319,7 +319,7 @@ public class Snapshot : GLib.Object{ string fstab_path = path_combine(path, "/localhost/etc/fstab"); if (btrfs_mode){ - fstab_path = path_combine(path, "/@/etc/fstab"); + fstab_path = path_combine(path, "/@rootfs/etc/fstab"); } fstab_list = FsTabEntry.read_file(fstab_path); @@ -330,7 +330,7 @@ public class Snapshot : GLib.Object{ string crypttab_path = path_combine(path, "/localhost/etc/crypttab"); if (btrfs_mode){ - crypttab_path = path_combine(path, "/@/etc/crypttab"); + crypttab_path = path_combine(path, "/@rootfs/etc/crypttab"); } cryttab_list = CryptTabEntry.read_file(crypttab_path); @@ -437,7 +437,7 @@ public class Snapshot : GLib.Object{ public bool has_subvolumes(){ foreach(FsTabEntry en in fstab_list){ - if (en.options.contains("subvol=@")){ + if (en.options.contains("subvol=@rootfs")){ return true; } } diff --git a/src/Core/SnapshotRepo.vala b/src/Core/SnapshotRepo.vala index 4879107..d538ea5 100755 --- a/src/Core/SnapshotRepo.vala +++ b/src/Core/SnapshotRepo.vala @@ -192,18 +192,18 @@ public class SnapshotRepo : GLib.Object{ } // rsync - mount_paths["@"] = ""; + mount_paths["@rootfs"] = ""; mount_paths["@home"] = ""; if (btrfs_mode){ - mount_paths["@"] = mount_path; + mount_paths["@rootfs"] = mount_path; mount_paths["@home"] = mount_path; //default device_home = device; //default // mount @home if on different disk ------- - var repo_subvolumes = Subvolume.detect_subvolumes_for_system_by_path(path_combine(mount_path,"@"), this, parent_window); + var repo_subvolumes = Subvolume.detect_subvolumes_for_system_by_path(path_combine(mount_path,"@rootfs"), this, parent_window); if (repo_subvolumes.has_key("@home")){ @@ -493,13 +493,13 @@ public class SnapshotRepo : GLib.Object{ log_debug("SnapshotRepo: has_btrfs_system()"); - var root_path = path_combine(mount_paths["@"],"@"); + var root_path = path_combine(mount_paths["@rootfs"],"@rootfs"); log_debug("root_path=%s".printf(root_path)); log_debug("btrfs_mode=%s".printf(btrfs_mode.to_string())); if (btrfs_mode){ if (!dir_exists(root_path)){ status_message = _("Selected snapshot device is not a system disk"); - status_details = _("Select BTRFS system disk with root subvolume (@)"); + status_details = _("Select BTRFS system disk with root subvolume (@rootfs)"); status_code = SnapshotLocationStatus.NO_BTRFS_SYSTEM; log_debug(status_message); return false; @@ -994,7 +994,7 @@ public enum SnapshotLocationStatus{ 3 - first snapshot not taken, disk space sufficient 4 - path is readonly 5 - hardlinks not supported - 6 - btrfs device does not have @ subvolume + 6 - btrfs device does not have @rootfs subvolume */ NOT_SELECTED = -2, NOT_AVAILABLE = -1, diff --git a/src/Core/Subvolume.vala b/src/Core/Subvolume.vala index 3331c50..ef8a9cf 100755 --- a/src/Core/Subvolume.vala +++ b/src/Core/Subvolume.vala @@ -124,8 +124,8 @@ public class Subvolume : GLib.Object{ public bool remove(){ if (is_system_subvolume){ - if (name == "@"){ - path = path_combine(App.mount_point_app + "/backup", "@"); + if (name == "@rootfs"){ + path = path_combine(App.mount_point_app + "/backup", "@rootfs"); } else if (name == "@home"){ path = path_combine(App.mount_point_app + "/backup-home", "@home"); diff --git a/src/Gtk/RestoreDeviceBox.vala b/src/Gtk/RestoreDeviceBox.vala index 4a45723..0fdcc44 100644 --- a/src/Gtk/RestoreDeviceBox.vala +++ b/src/Gtk/RestoreDeviceBox.vala @@ -508,7 +508,7 @@ class RestoreDeviceBox : Gtk.Box{ var title = _("Unsupported Subvolume Layout") + " (%s)".printf(App.dst_root.device); var msg = _("Partition has an unsupported subvolume layout.") + " "; - msg += _("Only ubuntu-type layouts with @ and @home subvolumes are currently supported.") + "\n\n"; + msg += _("Only ubuntu-type layouts with @rootfs and @home subvolumes are currently supported.") + "\n\n"; gtk_messagebox(title, msg, parent_window, true); return false; } diff --git a/src/Gtk/SnapshotBackendBox.vala b/src/Gtk/SnapshotBackendBox.vala index 09bbd0f..fa3b652 100755 --- a/src/Gtk/SnapshotBackendBox.vala +++ b/src/Gtk/SnapshotBackendBox.vala @@ -177,7 +177,7 @@ class SnapshotBackendBox : Gtk.Box{ txt += bullet + _("Size of BTRFS snapshots are initially zero. As system files gradually change with time, data gets written to new data blocks which take up disk space (copy-on-write). Files in the snapshot continue to point to original data blocks.") + "\n\n"; - txt += bullet + _("OS must be installed on a BTRFS partition with Ubuntu-type subvolume layout (@ and @home subvolumes). Other layouts are not supported.") + "\n\n"; + txt += bullet + _("OS must be installed on a BTRFS partition with Debian-type subvolume layout (@rootfs and @home subvolumes). Other layouts are not supported.") + "\n\n"; lbl_description.label = txt; } diff --git a/src/Gtk/SnapshotListBox.vala b/src/Gtk/SnapshotListBox.vala index a8e121c..b75b57b 100644 --- a/src/Gtk/SnapshotListBox.vala +++ b/src/Gtk/SnapshotListBox.vala @@ -378,8 +378,8 @@ class SnapshotListBox : Gtk.Box{ int64 size = 0; - if (bak.subvolumes.has_key("@")){ - size += bak.subvolumes["@"].total_bytes; + if (bak.subvolumes.has_key("@rootfs")){ + size += bak.subvolumes["@rootfs"].total_bytes; } if (bak.subvolumes.has_key("@home")){ @@ -414,8 +414,8 @@ class SnapshotListBox : Gtk.Box{ int64 size = 0; - if (bak.subvolumes.has_key("@")){ - size += bak.subvolumes["@"].unshared_bytes; + if (bak.subvolumes.has_key("@rootfs")){ + size += bak.subvolumes["@rootfs"].unshared_bytes; } if (bak.subvolumes.has_key("@home")){ size += bak.subvolumes["@home"].unshared_bytes; -- 2.35.1