storage: move and generalize RootThinPool helper class

This is a class for finding thin pool containing root filesytem.
Generalize it to work for other filesystems too and rename to
DirectoryThinPool.
This commit is contained in:
Marek Marczykowski-Górecki 2018-03-19 22:26:54 +01:00
parent a0723a9e32
commit 99f430511a
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 46 additions and 56 deletions

View File

@ -24,21 +24,19 @@ import collections
import errno import errno
import functools import functools
import grp import grp
import itertools
import logging import logging
import os import os
import random import random
import subprocess
import sys import sys
import tempfile import tempfile
import time import time
import traceback import traceback
import uuid import uuid
import itertools
import lxml.etree
import jinja2 import jinja2
import libvirt import libvirt
import lxml.etree
try: try:
import xen.lowlevel.xs # pylint: disable=wrong-import-order import xen.lowlevel.xs # pylint: disable=wrong-import-order
@ -548,54 +546,6 @@ class VMCollection(object):
'https://xkcd.com/221/', 'https://xkcd.com/221/',
'http://dilbert.com/strip/2001-10-25')[random.randint(0, 1)]) 'http://dilbert.com/strip/2001-10-25')[random.randint(0, 1)])
# pylint: disable=too-few-public-methods
class RootThinPool:
'''The thin pool containing the rootfs device'''
_inited = False
_volume_group = None
_thin_pool = None
@classmethod
def _init(cls):
'''Find out the thin pool containing the root device'''
if not cls._inited:
cls._inited = True
try:
rootfs = os.stat('/')
root_major = (rootfs.st_dev & 0xff00) >> 8
root_minor = rootfs.st_dev & 0xff
root_table = subprocess.check_output(["dmsetup",
"-j", str(root_major), "-m", str(root_minor),
"table"])
_start, _sectors, target_type, target_args = \
root_table.decode().split(" ", 3)
if target_type == "thin":
thin_pool_devnum, _thin_pool_id = target_args.split(" ")
with open("/sys/dev/block/{}/dm/name"
.format(thin_pool_devnum), "r") as thin_pool_tpool_f:
thin_pool_tpool = thin_pool_tpool_f.read().rstrip('\n')
if thin_pool_tpool.endswith("-tpool"):
volume_group, thin_pool, _tpool = \
thin_pool_tpool.rsplit("-", 2)
cls._volume_group = volume_group
cls._thin_pool = thin_pool
except: # pylint: disable=bare-except
pass
@classmethod
def volume_group(cls):
'''Volume group of the thin pool containing the rootfs device'''
cls._init()
return cls._volume_group
@classmethod
def thin_pool(cls):
'''Thin pool name containing the rootfs device'''
cls._init()
return cls._thin_pool
def _default_pool(app): def _default_pool(app):
''' Default storage pool. ''' Default storage pool.
@ -616,8 +566,8 @@ def _default_pool(app):
if pool.config['thin_pool'] == thin_pool: if pool.config['thin_pool'] == thin_pool:
return pool return pool
# no DEFAULT_LVM_POOL, or pool not defined # no DEFAULT_LVM_POOL, or pool not defined
root_volume_group = RootThinPool.volume_group() root_volume_group, root_thin_pool = \
root_thin_pool = RootThinPool.thin_pool() qubes.storage.DirectoryThinPool.thin_pool('/')
if root_thin_pool: if root_thin_pool:
for pool in app.pools.values(): for pool in app.pools.values():
if pool.config.get('driver', None) != 'lvm_thin': if pool.config.get('driver', None) != 'lvm_thin':
@ -1114,8 +1064,8 @@ class Qubes(qubes.PropertyHolder):
} }
assert max(self.labels.keys()) == qubes.config.max_default_label assert max(self.labels.keys()) == qubes.config.max_default_label
root_volume_group = RootThinPool.volume_group() root_volume_group, root_thin_pool = \
root_thin_pool = RootThinPool.thin_pool() qubes.storage.DirectoryThinPool.thin_pool('/')
if root_thin_pool: if root_thin_pool:
self.add_pool( self.add_pool(

View File

@ -883,3 +883,43 @@ class VmCreationManager(object):
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
pass pass
os.rmdir(self.vm.dir_path) os.rmdir(self.vm.dir_path)
# pylint: disable=too-few-public-methods
class DirectoryThinPool:
'''The thin pool containing the device of given filesystem'''
_thin_pool = {}
@classmethod
def _init(cls, dir_path):
'''Find out the thin pool containing given filesystem'''
if dir_path not in cls._thin_pool:
cls._thin_pool[dir_path] = None, None
try:
fs_stat = os.stat(dir_path)
fs_major = (fs_stat.st_dev & 0xff00) >> 8
fs_minor = fs_stat.st_dev & 0xff
root_table = subprocess.check_output(["dmsetup",
"-j", str(fs_major), "-m", str(fs_minor),
"table"])
_start, _sectors, target_type, target_args = \
root_table.decode().split(" ", 3)
if target_type == "thin":
thin_pool_devnum, _thin_pool_id = target_args.split(" ")
with open("/sys/dev/block/{}/dm/name"
.format(thin_pool_devnum), "r") as thin_pool_tpool_f:
thin_pool_tpool = thin_pool_tpool_f.read().rstrip('\n')
if thin_pool_tpool.endswith("-tpool"):
volume_group, thin_pool, _tpool = \
thin_pool_tpool.rsplit("-", 2)
cls._thin_pool[dir_path] = volume_group, thin_pool
except: # pylint: disable=bare-except
pass
@classmethod
def thin_pool(cls, dir_path):
'''Thin tuple (volume group, pool name) containing given filesystem'''
cls._init(dir_path)
return cls._thin_pool[dir_path]