Переглянути джерело

app: create /var/lib/qubes as file-reflink if supported

Use the file-reflink storage driver if /var/lib/qubes is on a filesystem
that supports reflinks, e.g. when the btrfs layout was selected in
Anaconda. If it doesn't support reflinks (or if detection fails, e.g. in
an unprivileged test environment), use 'file' as before.
Rusty Bird 5 роки тому
батько
коміт
8d1913a8cc
3 змінених файлів з 16 додано та 5 видалено
  1. 11 1
      qubes/app.py
  2. 1 2
      qubes/config.py
  3. 4 2
      qubes/tests/storage.py

+ 11 - 1
qubes/app.py

@@ -61,6 +61,7 @@ import qubes
 import qubes.ext
 import qubes.ext
 import qubes.utils
 import qubes.utils
 import qubes.storage
 import qubes.storage
+import qubes.storage.reflink
 import qubes.vm
 import qubes.vm
 import qubes.vm.adminvm
 import qubes.vm.adminvm
 import qubes.vm.qubesvm
 import qubes.vm.qubesvm
@@ -553,7 +554,7 @@ def _default_pool(app):
 
 
     1. If there is one named 'default', use it.
     1. If there is one named 'default', use it.
     2. Check if root fs is on LVM thin - use that
     2. Check if root fs is on LVM thin - use that
-    3. Look for file-based pool pointing /var/lib/qubes
+    3. Look for file(-reflink)-based pool pointing to /var/lib/qubes
     4. Fail
     4. Fail
     '''
     '''
     if 'default' in app.pools:
     if 'default' in app.pools:
@@ -1079,6 +1080,15 @@ class Qubes(qubes.PropertyHolder):
             pool_configs[lvm_config['name']] = lvm_config
             pool_configs[lvm_config['name']] = lvm_config
 
 
         for name, config in pool_configs.items():
         for name, config in pool_configs.items():
+            if 'driver' not in config and 'dir_path' in config:
+                config['driver'] = 'file'
+                try:
+                    os.makedirs(config['dir_path'], exist_ok=True)
+                    if qubes.storage.reflink.is_supported(config['dir_path']):
+                        config['driver'] = 'file-reflink'
+                        config['setup_check'] = 'no'  # don't check twice
+                except PermissionError:  # looks like a testing environment
+                    pass  # stay with 'file'
             self.pools[name] = self._get_pool(**config)
             self.pools[name] = self._get_pool(**config)
 
 
         self.default_pool_kernel = 'linux-kernel'
         self.default_pool_kernel = 'linux-kernel'

+ 1 - 2
qubes/config.py

@@ -76,9 +76,8 @@ defaults = {
     'root_img_size': 10*1024*1024*1024,
     'root_img_size': 10*1024*1024*1024,
 
 
     'pool_configs': {
     'pool_configs': {
-        # create file pool even when the default one is LVM
+        # create file(-reflink) pool even when the default one is LVM
         'varlibqubes': {'dir_path': qubes_base_dir,
         'varlibqubes': {'dir_path': qubes_base_dir,
-                    'driver': 'file',
                     'name': 'varlibqubes'},
                     'name': 'varlibqubes'},
         'linux-kernel': {
         'linux-kernel': {
             'dir_path': os.path.join(qubes_base_dir,
             'dir_path': os.path.join(qubes_base_dir,

+ 4 - 2
qubes/tests/storage.py

@@ -22,6 +22,7 @@ import qubes.storage
 from qubes.exc import QubesException
 from qubes.exc import QubesException
 from qubes.storage import pool_drivers
 from qubes.storage import pool_drivers
 from qubes.storage.file import FilePool
 from qubes.storage.file import FilePool
+from qubes.storage.reflink import ReflinkPool
 from qubes.tests import SystemTestCase
 from qubes.tests import SystemTestCase
 
 
 # :pylint: disable=invalid-name
 # :pylint: disable=invalid-name
@@ -107,10 +108,11 @@ class TC_00_Pool(SystemTestCase):
             pool_drivers())
             pool_drivers())
 
 
     def test_002_get_pool_klass(self):
     def test_002_get_pool_klass(self):
-        """ Expect the default pool to be `FilePool` """
+        """ Expect the default pool to be `FilePool` or `ReflinkPool` """
         # :pylint: disable=protected-access
         # :pylint: disable=protected-access
         result = self.app.get_pool('varlibqubes')
         result = self.app.get_pool('varlibqubes')
-        self.assertIsInstance(result, FilePool)
+        self.assertTrue(isinstance(result, FilePool)
+                        or isinstance(result, ReflinkPool))
 
 
     def test_003_pool_exists_default(self):
     def test_003_pool_exists_default(self):
         """ Expect the default pool to exists """
         """ Expect the default pool to exists """