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.
This commit is contained in:
Rusty Bird 2018-09-11 23:50:26 +00:00
parent 53ef5ed431
commit 8d1913a8cc
No known key found for this signature in database
GPG Key ID: 469D78F47AAF2ADF
3 changed files with 16 additions and 5 deletions

View File

@ -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'

View File

@ -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,

View File

@ -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 """