[PATCH 02/13] Account for active mounts in normal mode. (#914898)
David Lehman
dlehman at redhat.com
Fri Mar 1 22:13:20 UTC 2013
Also adds support for representing the system's nodev filesystem mounts.
The include_nodev flag must be set to True prior to calling
Blivet.getActiveMounts, which is called from within Blivet.reset (if
flags.installer_mode is False).
There can be multiple mounts of any given nodev filesystem type, which
presents a problem in terms of looking up devices by name. The chosen
solution is to add a unique identifier to each NoDevice instance's name.
---
blivet/__init__.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++-
blivet/devices.py | 5 +++--
blivet/devicetree.py | 2 ++
blivet/flags.py | 4 ++++
blivet/formats/fs.py | 30 +++++++++++++++++++++-------
5 files changed, 86 insertions(+), 10 deletions(-)
diff --git a/blivet/__init__.py b/blivet/__init__.py
index 7958eb1..6456311 100644
--- a/blivet/__init__.py
+++ b/blivet/__init__.py
@@ -55,6 +55,7 @@ from deviceaction import *
from formats import getFormat
from formats import get_device_format_class
from formats import get_default_filesystem_type
+from formats.fs import nodev_filesystems
import devicefactory
from devicelibs.dm import name_from_dm_node
from devicelibs.crypto import generateBackupPassphrase
@@ -406,6 +407,9 @@ class Blivet(object):
if flags.installer_mode:
self.roots = findExistingInstallations(self.devicetree)
+ if not flags.installer_mode:
+ self.getActiveMounts()
+
self.dumpState("initial")
self.updateBootLoaderDiskList()
@@ -1870,6 +1874,56 @@ class Blivet(object):
return new
+ def getActiveMounts(self):
+ """ Reflect active mounts in the appropriate devices' formats. """
+ log.info("collecting information about active mounts")
+ for _line in open("/proc/mounts").readlines():
+ (line, pound, comment) = _line.partition("#")
+ try:
+ (devspec, mountpoint, fstype, options, rest) = line.split(None, 4)
+ except IndexError:
+ blivet_log.error("failed to parse /proc/mounts line: %s" % _line)
+ continue
+
+ if fstype == "btrfs":
+ # get the subvol name from /proc/self/mountinfo
+ for line in open("/proc/self/mountinfo").readlines():
+ fields = line.split()
+ _subvol = fields[3]
+ _mountpoint = fields[4]
+ _devspec = fields[9]
+ if _mountpoint == mountpoint and _devspec == devspec:
+ log.debug("subvol %s" % _subvol)
+ options += ",subvol=%s" % _subvol[1:]
+
+ if fstype in nodev_filesystems:
+ if not flags.include_nodev:
+ continue
+
+ log.info("found nodev %s filesystem mounted at %s"
+ % (fstype, mountpoint))
+ # nodev filesystems require some special handling.
+ # For now, a lot of this is based on the idea that it's a losing
+ # battle to require the presence of an FS class for every type
+ # of nodev filesystem. Based on that idea, we just instantiate
+ # NoDevFS directly and then hack in the fstype as the device
+ # attribute.
+ fmt = getFormat("nodev")
+ fmt.device = fstype
+
+ # NoDevice also needs some special works since they don't have
+ # per-instance names in the kernel.
+ device = NoDevice(format=fmt)
+ n = len([d for d in self.devices if d.format.type == fstype])
+ device._name += ".%d" % n
+ self.devicetree._addDevice(device)
+ devspec = device.name
+
+ device = self.devicetree.resolveDevice(devspec, options=options)
+ if device is not None:
+ device.format.mountpoint = mountpoint # for future mounts
+ device.format._mountpoint = mountpoint # active mountpoint
+
def mountExistingSystem(fsset, rootDevice,
allowDirty=None, dirtyCB=None,
@@ -2656,7 +2710,6 @@ class FSSet(object):
return fstab
-
def getReleaseString():
relName = None
relVer = None
diff --git a/blivet/devices.py b/blivet/devices.py
index 791084a..19885bf 100644
--- a/blivet/devices.py
+++ b/blivet/devices.py
@@ -3415,7 +3415,7 @@ class NoDevice(StorageDevice):
format -- a DeviceFormat instance
"""
if format:
- name = format.type
+ name = format.device
else:
name = "none"
@@ -3424,7 +3424,8 @@ class NoDevice(StorageDevice):
@property
def path(self):
""" Device node representing this device. """
- return self.name
+ # the name may have a '.%d' suffix to make it unique
+ return self.name.split(".")[0]
def setup(self, orig=False):
""" Open, or set up, a device. """
diff --git a/blivet/devicetree.py b/blivet/devicetree.py
index 88ba130..026dda6 100644
--- a/blivet/devicetree.py
+++ b/blivet/devicetree.py
@@ -2142,6 +2142,8 @@ class DeviceTree(object):
if edd_number == spec:
device = self.getDeviceByName(edd_name)
break
+ elif options and "nodev" in options.split(","):
+ device = self.getDeviceByName(devspec)
else:
if not devspec.startswith("/dev/"):
device = self.getDeviceByName(devspec)
diff --git a/blivet/flags.py b/blivet/flags.py
index ed0e5dc..e892b74 100644
--- a/blivet/flags.py
+++ b/blivet/flags.py
@@ -54,6 +54,10 @@ class Flags(object):
self.gpt = False
+ # whether to include nodev filesystems in the devicetree (only
+ # meaningful when flags.installer_mode is False)
+ self.include_nodev = False
+
self.boot_cmdline = {}
self.update_from_boot_cmdline()
diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py
index de94ff4..840adb3 100644
--- a/blivet/formats/fs.py
+++ b/blivet/formats/fs.py
@@ -57,14 +57,19 @@ mib = 1024 * 1024.0
fs_configs = {}
-def get_kernel_filesystems():
- fs_list = []
+kernel_filesystems = []
+nodev_filesystems = []
+
+def update_kernel_filesystems():
+ global kernel_filesystems
+ global nodev_filesystems
for line in open("/proc/filesystems").readlines():
- fs_list.append(line.split()[-1])
- return fs_list
+ fields = line.split()
+ kernel_filesystems.append(fields[-1])
+ if fields[0] == "nodev":
+ nodev_filesystems.append(fields[-1])
-global kernel_filesystems
-kernel_filesystems = get_kernel_filesystems()
+update_kernel_filesystems()
def fsConfigFromFile(config_file):
""" Generate a set of attribute name/value pairs with which a
@@ -485,7 +490,7 @@ class FS(DeviceFormat):
# If we successfully loaded a kernel module, for this filesystem, we
# also need to update the list of supported filesystems.
- kernel_filesystems = get_kernel_filesystems()
+ update_kernel_filesystems()
def testMount(self, options=None):
""" Try to mount the fs and return True if successful. """
@@ -1370,6 +1375,17 @@ class NoDevFS(FS):
def _setDevice(self, devspec):
self._device = devspec
+ @property
+ def type(self):
+ if self.device != self._type:
+ return self.device
+ else:
+ return self._type
+
+ @property
+ def mountType(self):
+ return self.device # this is probably set to the real/specific fstype
+
def _getExistingSize(self):
pass
--
1.8.1
More information about the anaconda-patches
mailing list