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

Reply via email to