Repository: archlinux/archinstall

Issue:
BTRFS not working in Virt-Manager
I'm testing out the latest version of archinstall in Virt-Manager (version 2.4.3rc1) by git cloning the archinstall repo while in the live environment and have noticed that it doesn't seem to like BTRFS. EXT4 works as expected. 

It gets to mounting the partitions, hits some kind of bug, and spits out a bunch of text that ends with "TypeError: cannot pickle 'generator' object"

I've only been testing through Virt-Manager so I dont know if 2.4.3rc1 acts any differently on bare metal. 

Anyone encounter this? Any guidance is appreciated

Originally posted on Reddit - https://www.reddit.com/r/archlinux/comments/uxetf4/archinstall_btrfs_not_working_on_virtmanager/?utm_medium=android_app&utm_source=share


Discussion:
Can you try on the master development iso? @Torxed just pushed a commit that probably fixes this
No luck on my end! The msg indicating where to find the error log was really helpful though! Tried installing on Virt-Manager using 2.4.3rc1 as of 6:50pm EST. Here is my  install log

[install.log](https://github.com/archlinux/archinstall/files/8782632/install.log)



You would need to try with `master` instead of RC1 because i havent been able to tag a new version yet.
How to I do that?
Or is that the version included in the May ISO?
Every time a commit is made against master (https://github.com/archlinux/archinstall/commits/master) an ISO is generated. Click the check mark, click details near Build Arch ISO with ArchInstall Commit, click summary. For example, https://github.com/archlinux/archinstall/actions/runs/2392251445. Then click the "[Arch Live ISO](https://github.com/archlinux/archinstall/suites/6675421827/artifacts/252908790)" link.
There's also a list of ISOs built at https://github.com/archlinux/archinstall/actions/workflows/iso-build.yaml
Thank you so much! So after downloading the master development isos, i would just run archinstall as normal?
Exactly. It's a special Arch Linux install build with the EXACT commit that you download the ISO for built-in. You just run it as usual. Fair warning, it might have bugs, as it is unreleased software. ;) 

We do usually try not to break the builds in master, but they're not nearly as tested as right before we tag a final release.
Here is the install log I pulled after trying two installations with the Master ISO. 1 unsuccessful run and 1 successful run.

TL;DR : The default subvolume layout when using BTRFS (no encryption) works as intended but adding @root mounted at /root did not work. So I don't know if this issue should be marked closed?

[install.log](https://github.com/archlinux/archinstall/files/8783347/install.log)

v2.4.2 - @root mounted at /root can be add to the disk layout json file and the installer runs. Manually creating the subvol and mount point causes the installer to crash.
|
|
v2.4.3rc1 - btrfs causes the installer to crash regardless of whether ran with or with declarative json file.
|
|
Master ISO - Creating @root mounted at /root using the installer causes it to crash. I haven't tried tried from a declarative file yet. I will try that asap and report back.

^^ Hope this helps!
3-run install log and Konsole output from the third install.

1 unsuccessful and 2 successful runs

[install.log](https://github.com/archlinux/archinstall/files/8783796/install.log)

[vm-konsole-output.log](https://github.com/archlinux/archinstall/files/8783794/vm-konsole-output.log)
One thing stands out that is a bit strange:
```
Could not retrieve subvolume information from /mnt/archinstall/@root: ['/usr/bin/btrfs', 'subvolume', 'show', '/mnt/archinstall/@root'] exited with abnormal exit code [256]: b"ERROR: cannot find real path for '/mnt/archinstall/@root': No such file or directory\r\n"
```
I'm not sure why it's trying to call `btrfs subvolume show /mnt/archinstall/@root`, it should be `btrfs subvolume show /mnt/archinstall/root`.

I'll investigate this today.

Resolving patch:
diff --git a/archinstall/lib/disk/btrfs/btrfspartition.py b/archinstall/lib/disk/btrfs/btrfspartition.py
--- a/archinstall/lib/disk/btrfs/btrfspartition.py
+++ b/archinstall/lib/disk/btrfs/btrfspartition.py
@@ -108,9 +108,13 @@ def create_subvolume(self, subvolume :pathlib.Path, installation :Optional['Inst
 
 		if glob.glob(str(subvolume / '*')):
 			raise DiskError(f"Cannot create subvolume at {subvolume} because it contains data (non-empty folder target is not supported by BTRFS)")
-		elif subvolinfo := subvolume_info_from_path(subvolume):
-			raise DiskError(f"Destination {subvolume} is already a subvolume: {subvolinfo}")
+		# Ideally we would like to check if the destination is already a subvolume.
+		# But then we would need the mount-point at this stage as well.
+		# So we'll comment out this check:
+		# elif subvolinfo := subvolume_info_from_path(subvolume):
+		# 	raise DiskError(f"Destination {subvolume} is already a subvolume: {subvolinfo}")
 
+		# And deal with it here:
 		SysCommand(f"btrfs subvolume create {subvolume}")
 
 		return subvolume_info_from_path(subvolume)
\ No newline at end of file
diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py
--- a/archinstall/lib/disk/partition.py
+++ b/archinstall/lib/disk/partition.py
@@ -310,8 +310,9 @@ def subvolumes(self) -> Iterator[BtrfsSubvolume]:
 		def iterate_children_recursively(information):
 			for child in information.get('children', []):
 				if target := child.get('target'):
-					if subvolume := subvolume_info_from_path(pathlib.Path(target)):
-						yield subvolume
+					if child.get('fstype') == 'btrfs':
+						if subvolume := subvolume_info_from_path(pathlib.Path(target)):
+							yield subvolume
 
 					if child.get('children'):
 						for subchild in iterate_children_recursively(child):
@@ -320,8 +321,9 @@ def iterate_children_recursively(information):
 		for mountpoint in self.mount_information:
 			if result := findmnt(pathlib.Path(mountpoint['target'])):
 				for filesystem in result.get('filesystems', []):
-					if subvolume := subvolume_info_from_path(pathlib.Path(mountpoint['target'])):
-						yield subvolume
+					if mountpoint.get('fstype') == 'btrfs':
+						if subvolume := subvolume_info_from_path(pathlib.Path(mountpoint['target'])):
+							yield subvolume
 
 					for child in iterate_children_recursively(filesystem):
 						yield child


Test patch: