[master 8/13] Do not teardown partition when resizing encrypted
partition
by dashea
From: Vojtech Trefny <vtrefny(a)redhat.com>
Running teardown on luks encrypted partition would close the LUKS
device on it. Making it impossible to resize. Teardown only the
filesystem on the LUKS device instead.
---
blivet/devices/partition.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/blivet/devices/partition.py b/blivet/devices/partition.py
index 5033c45..6487625 100644
--- a/blivet/devices/partition.py
+++ b/blivet/devices/partition.py
@@ -663,7 +663,11 @@ def _pre_resize(self):
if not self.exists:
raise errors.DeviceError("device has not been created", self.name)
- self.teardown()
+ # don't teardown when resizing luks
+ if self.format.type == "luks" and self.children:
+ self.children[0].format.teardown()
+ else:
+ self.teardown()
if not self.sysfs_path:
return
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/a9e6ab369d4876e165cf54f421e7...
8 years, 4 months
[master 7/13] Make partitions with children resizable
by dashea
From: Vojtech Trefny <vtrefny(a)redhat.com>
---
blivet/devices/partition.py | 3 ---
1 file changed, 3 deletions(-)
diff --git a/blivet/devices/partition.py b/blivet/devices/partition.py
index ce358e3..5033c45 100644
--- a/blivet/devices/partition.py
+++ b/blivet/devices/partition.py
@@ -663,9 +663,6 @@ def _pre_resize(self):
if not self.exists:
raise errors.DeviceError("device has not been created", self.name)
- if not self.isleaf and not self.is_extended:
- raise errors.DeviceError("Cannot destroy non-leaf device", self.name)
-
self.teardown()
if not self.sysfs_path:
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/3ca29c93dc00e297dd7ee336fab1...
8 years, 4 months
[master 6/13] Make LUKS format resizable
by dashea
From: Vojtech Trefny <vtrefny(a)redhat.com>
---
blivet/formats/luks.py | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/blivet/formats/luks.py b/blivet/formats/luks.py
index 4d9347d..d71b7d5 100644
--- a/blivet/formats/luks.py
+++ b/blivet/formats/luks.py
@@ -33,7 +33,8 @@
from . import DeviceFormat, register_device_format
from ..flags import flags
from ..i18n import _, N_
-from ..tasks import availability
+from ..tasks import availability, lukstasks
+from ..size import Size
import logging
log = logging.getLogger("blivet")
@@ -50,8 +51,13 @@ class LUKS(DeviceFormat):
_linux_native = True # for clearpart
_packages = ["cryptsetup"] # required packages
_min_size = crypto.LUKS_METADATA_SIZE
+ _max_size = Size("16 EiB")
_plugin = availability.BLOCKDEV_CRYPTO_PLUGIN
+ _size_info_class = lukstasks.LUKSSize
+ _resize_class = lukstasks.LUKSResize
+ _resizable = True
+
def __init__(self, **kwargs):
"""
:keyword device: the path to the underlying device
@@ -85,6 +91,10 @@ def __init__(self, **kwargs):
"""
log_method_call(self, **kwargs)
DeviceFormat.__init__(self, **kwargs)
+
+ self._size_info = self._size_info_class(self)
+ self._resize = self._resize_class(self)
+
self.cipher = kwargs.get("cipher")
self.key_size = kwargs.get("key_size")
self.map_name = kwargs.get("name")
@@ -111,6 +121,10 @@ def __init__(self, **kwargs):
elif not self.map_name and self.device:
self.map_name = "luks-%s" % os.path.basename(self.device)
+ if flags.installer_mode and self._resize.available:
+ # if you want current/min size you have to call update_size_info
+ self.update_size_info()
+
def __repr__(self):
s = DeviceFormat.__repr__(self)
if self.__passphrase:
@@ -179,6 +193,21 @@ def status(self):
return False
return os.path.exists("/dev/mapper/%s" % self.map_name)
+ def update_size_info(self):
+ """ Update this format's current size. """
+
+ self._resizable = False
+
+ if not self.status:
+ return
+
+ try:
+ self._size = self._size_info.do_task()
+ except LUKSError as e:
+ log.warning("Failed to obtain current size for device %s: %s", self.device, e)
+ else:
+ self._resizable = True
+
def _pre_setup(self, **kwargs):
if not self.configured:
raise LUKSError("luks device not configured")
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/c48a5e7ebb8977d27ad0d0822d61...
8 years, 4 months
[master 5/13] Make LUKSDevice resizable
by dashea
From: Vojtech Trefny <vtrefny(a)redhat.com>
---
blivet/devices/luks.py | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/blivet/devices/luks.py b/blivet/devices/luks.py
index 1fee1b8..027c766 100644
--- a/blivet/devices/luks.py
+++ b/blivet/devices/luks.py
@@ -22,6 +22,8 @@
# device backend modules
from ..devicelibs import crypto
+from ..storage_log import log_method_call
+
import logging
log = logging.getLogger("blivet")
@@ -33,6 +35,7 @@ class LUKSDevice(DMCryptDevice):
""" A mapped LUKS device. """
_type = "luks/dm-crypt"
+ _resizable = True
_packages = ["cryptsetup"]
def __init__(self, name, fmt=None, size=None, uuid=None,
@@ -69,6 +72,31 @@ def size(self):
size = self.current_size
return size
+ @property
+ def min_size(self):
+ """ The minimum size this device can be. """
+ return self.align_target_size(self.format.min_size) if self.resizable else self.current_size
+
+ def _set_target_size(self, newsize):
+ super()._set_target_size(newsize)
+
+ self.slave.format.target_size = newsize
+
+ @property
+ def resizable(self):
+ """ Can this device be resized? """
+ return (self._resizable and self.exists and self.format.resizable and
+ self.slave.resizable)
+
+ def _pre_resize(self):
+ self.format.teardown()
+
+ def resize(self):
+ log_method_call(self, self.name, status=self.status)
+ self._pre_resize()
+
+ self.slave.format.do_resize()
+
def _post_create(self):
self.name = self.slave.format.map_name
StorageDevice._post_create(self)
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/3c637f39c8d503b2d9a6329fb04e...
8 years, 4 months
[master 4/13] Make lukstasks and dfresize task pep8 compliant
by dashea
From: Vojtech Trefny <vtrefny(a)redhat.com>
---
blivet/tasks/dfresize.py | 2 ++
blivet/tasks/fsresize.py | 3 ++-
blivet/tasks/lukstasks.py | 8 ++++++--
3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/blivet/tasks/dfresize.py b/blivet/tasks/dfresize.py
index 856707b..2390a8d 100644
--- a/blivet/tasks/dfresize.py
+++ b/blivet/tasks/dfresize.py
@@ -25,12 +25,14 @@
from . import task
+
@add_metaclass(abc.ABCMeta)
class DFResizeTask(task.Task):
""" The abstract properties that any resize task must have. """
unit = abc.abstractproperty(doc="Resize unit.")
+
class UnimplementedDFResize(task.UnimplementedTask, DFResizeTask):
def __init__(self, a_df):
diff --git a/blivet/tasks/fsresize.py b/blivet/tasks/fsresize.py
index 417cafc..e7e2698 100644
--- a/blivet/tasks/fsresize.py
+++ b/blivet/tasks/fsresize.py
@@ -29,11 +29,12 @@
from . import availability
from . import task
+from . import fstask
from . import dfresize
@add_metaclass(abc.ABCMeta)
-class FSResizeTask(dfresize.DFResizeTask):
+class FSResizeTask(fstask.FSTask):
""" The abstract properties that any resize task must have. """
size_fmt = abc.abstractproperty(doc="Size format string.")
diff --git a/blivet/tasks/lukstasks.py b/blivet/tasks/lukstasks.py
index 27920c1..0fa59d7 100644
--- a/blivet/tasks/lukstasks.py
+++ b/blivet/tasks/lukstasks.py
@@ -19,6 +19,9 @@
#
# Red Hat Author(s): Anne Mulhern <amulhern(a)redhat.com>
+import gi
+gi.require_version("BlockDev", "1.0")
+
from gi.repository import BlockDev as blockdev
from .. import util
@@ -31,6 +34,7 @@
from . import task
from . import dfresize
+
class LUKSResize(task.BasicApplication, dfresize.DFResizeTask):
""" Handle resize of LUKS device. """
@@ -48,9 +52,9 @@ def __init__(self, a_luks):
"""
self.luks = a_luks
- def doTask(self):
+ def do_task(self):
""" Resizes the LUKS format. """
try:
- blockdev.crypto.luks_resize(self.luks.mapName, self.luks.targetSize.convertTo(self.unit))
+ blockdev.crypto.luks_resize(self.luks.map_name, self.luks.target_size.convert_to(self.unit))
except blockdev.CryptoError as e:
raise LUKSError(e)
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/a207baa57f802f84a2896f99e198...
8 years, 4 months
[master 3/13] Make a top level device format resizing task class.
by dashea
From: mulhern <amulhern(a)redhat.com>
Adjust the task class heirarchy accordingly.
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
blivet/tasks/dfresize.py | 45 +++++++++++++++++++++++++++++++++++++++++++++
blivet/tasks/fsresize.py | 12 +++---------
2 files changed, 48 insertions(+), 9 deletions(-)
create mode 100644 blivet/tasks/dfresize.py
diff --git a/blivet/tasks/dfresize.py b/blivet/tasks/dfresize.py
new file mode 100644
index 0000000..856707b
--- /dev/null
+++ b/blivet/tasks/dfresize.py
@@ -0,0 +1,45 @@
+# dfresize.py
+# DeviceFormat resizing classes.
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Anne Mulhern <amulhern(a)redhat.com>
+
+import abc
+
+from six import add_metaclass
+
+from . import task
+
+(a)add_metaclass(abc.ABCMeta)
+class DFResizeTask(task.Task):
+ """ The abstract properties that any resize task must have. """
+
+ unit = abc.abstractproperty(doc="Resize unit.")
+
+class UnimplementedDFResize(task.UnimplementedTask, DFResizeTask):
+
+ def __init__(self, a_df):
+ """ Initializer.
+
+ :param DeviceFormat a_df: a device format object
+ """
+ self.df = a_df
+
+ @property
+ def unit(self):
+ raise NotImplementedError()
diff --git a/blivet/tasks/fsresize.py b/blivet/tasks/fsresize.py
index 343acaf..417cafc 100644
--- a/blivet/tasks/fsresize.py
+++ b/blivet/tasks/fsresize.py
@@ -28,16 +28,14 @@
from ..import util
from . import availability
-from . import fstask
from . import task
+from . import dfresize
@add_metaclass(abc.ABCMeta)
-class FSResizeTask(fstask.FSTask):
-
+class FSResizeTask(dfresize.DFResizeTask):
""" The abstract properties that any resize task must have. """
- unit = abc.abstractproperty(doc="Resize unit.")
size_fmt = abc.abstractproperty(doc="Size format string.")
@@ -135,11 +133,7 @@ def args(self):
return ['-o', ",".join(options), self.fs._type, self.fs.system_mountpoint]
-class UnimplementedFSResize(task.UnimplementedTask, FSResizeTask):
-
- @property
- def unit(self):
- raise NotImplementedError()
+class UnimplementedFSResize(dfresize.UnimplementedDFResize, FSResizeTask):
@property
def size_fmt(self):
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/57e239da203fb6dcb69a97ed2c5b...
8 years, 4 months
[master 2/13] Add a LUKS resize task.
by dashea
From: mulhern <amulhern(a)redhat.com>
Signed-off-by: mulhern <amulhern(a)redhat.com>
---
blivet/devicelibs/crypto.py | 1 +
blivet/tasks/lukstasks.py | 56 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+)
create mode 100644 blivet/tasks/lukstasks.py
diff --git a/blivet/devicelibs/crypto.py b/blivet/devicelibs/crypto.py
index 7d3bc15..fbef943 100644
--- a/blivet/devicelibs/crypto.py
+++ b/blivet/devicelibs/crypto.py
@@ -25,5 +25,6 @@
LUKS_METADATA_SIZE = Size("2 MiB")
MIN_CREATE_ENTROPY = 256 # bits
+SECTOR_SIZE = Size("512 B")
EXTERNAL_DEPENDENCIES = [availability.BLOCKDEV_CRYPTO_PLUGIN]
diff --git a/blivet/tasks/lukstasks.py b/blivet/tasks/lukstasks.py
new file mode 100644
index 0000000..27920c1
--- /dev/null
+++ b/blivet/tasks/lukstasks.py
@@ -0,0 +1,56 @@
+# lukstasks.py
+# Tasks for a LUKS format.
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Anne Mulhern <amulhern(a)redhat.com>
+
+from gi.repository import BlockDev as blockdev
+
+from .. import util
+
+from ..devicelibs import crypto
+from ..errors import LUKSError
+from ..size import Size
+
+from . import availability
+from . import task
+from . import dfresize
+
+class LUKSResize(task.BasicApplication, dfresize.DFResizeTask):
+ """ Handle resize of LUKS device. """
+
+ description = "resize luks device"
+
+ ext = availability.BLOCKDEV_CRYPTO_PLUGIN
+
+ # units for specifying new size
+ unit = crypto.SECTOR_SIZE
+
+ def __init__(self, a_luks):
+ """ Initializer.
+
+ :param :class:`~.formats.luks.LUKS` a_luks: a LUKS format object
+ """
+ self.luks = a_luks
+
+ def doTask(self):
+ """ Resizes the LUKS format. """
+ try:
+ blockdev.crypto.luks_resize(self.luks.mapName, self.luks.targetSize.convertTo(self.unit))
+ except blockdev.CryptoError as e:
+ raise LUKSError(e)
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/149a9dcb1416d91e68e9a9f76aae...
8 years, 4 months
[master 1/13] Move resize related methods from FS to DeviceFormat
by dashea
From: Vojtech Trefny <vtrefny(a)redhat.com>
This includes update_min_size, do_resize, current_size,
target_size, _get_target_size, _set_target_size, _get_size methods
and properties.
---
blivet/formats/__init__.py | 176 +++++++++++++++++++++++++++++++++++++++++----
blivet/formats/fs.py | 149 ++------------------------------------
2 files changed, 168 insertions(+), 157 deletions(-)
diff --git a/blivet/formats/__init__.py b/blivet/formats/__init__.py
index d67d6f4..1c26ed4 100644
--- a/blivet/formats/__init__.py
+++ b/blivet/formats/__init__.py
@@ -36,8 +36,17 @@
from ..storage_log import log_method_call
from ..errors import DeviceFormatError, FormatCreateError, FormatDestroyError, FormatSetupError
from ..i18n import N_
-from ..size import Size
+from ..size import Size, ROUND_DOWN, unit_str
from ..threads import SynchronizedMeta
+from ..flags import flags
+
+from ..errors import FSError, FSResizeError #FIXME
+
+from ..tasks import fsinfo
+from ..tasks import fsresize
+from ..tasks import fssize
+from ..tasks import fsck
+from ..tasks import fsminsize
import logging
log = logging.getLogger("blivet")
@@ -175,6 +184,11 @@ class DeviceFormat(ObjectID, metaclass=SynchronizedMeta):
_hidden = False # hide devices with this formatting?
_ks_mountpoint = None
+ _resize_class = fsresize.UnimplementedFSResize
+ _size_info_class = fssize.UnimplementedFSSize
+ _info_class = fsinfo.UnimplementedFSInfo
+ _minsize_class = fsminsize.UnimplementedFSMinSize
+
def __init__(self, **kwargs):
"""
:keyword device: The path to the device node.
@@ -203,6 +217,22 @@ def __init__(self, **kwargs):
self.options = kwargs.get("options")
self._create_options = kwargs.get("create_options")
+ # Create task objects
+ self._info = self._info_class(self)
+ self._resize = self._resize_class(self)
+ # These two may depend on info class, so create them after
+ self._minsize = self._minsize_class(self)
+ self._size_info = self._size_info_class(self)
+
+ # format size does not necessarily equal device size
+ self._size = kwargs.get("size", Size(0))
+ self._target_size = self._size
+ self._min_instance_size = Size(0) # min size of this DeviceFormat instance
+
+ # Resize operations are limited to error-free formats whose current
+ # size is known.
+ self._resizable = False
+
def __repr__(self):
s = ("%(classname)s instance (%(id)s) object id %(object_id)d--\n"
" type = %(type)s name = %(name)s status = %(status)s\n"
@@ -380,6 +410,139 @@ def notify_kernel(self):
except (ValueError, IOError) as e:
log.warning("failed to notify kernel of change: %s", e)
+ def _set_target_size(self, newsize):
+ """ Set the target size for this filesystem.
+
+ :param :class:`~.size.Size` newsize: the newsize
+ """
+ if not isinstance(newsize, Size):
+ raise ValueError("new size must be of type Size")
+
+ if not self.exists:
+ raise FSError("filesystem has not been created")
+
+ if not self.resizable:
+ raise FSError("filesystem is not resizable")
+
+ if newsize < self.min_size:
+ raise ValueError("requested size %s must be at least minimum size %s" % (newsize, self.min_size))
+
+ if self.max_size and newsize >= self.max_size:
+ raise ValueError("requested size %s must be less than maximum size %s" % (newsize, self.max_size))
+
+ self._target_size = newsize
+
+ def _get_target_size(self):
+ """ Get this filesystem's target size. """
+ return self._target_size
+
+ target_size = property(_get_target_size, _set_target_size,
+ doc="Target size for this filesystem")
+
+ def _get_size(self):
+ """ Get this filesystem's size. """
+ return self.target_size if self.resizable else self._size
+
+ size = property(_get_size, doc="This filesystem's size, accounting "
+ "for pending changes")
+
+ @property
+ def min_size(self):
+ # If self._min_instance_size is not 0, then it should be no less than
+ # self._min_size, by definition, and since a non-zero value indicates
+ # that it was obtained, it is the preferred value.
+ # If self._min_instance_size is less than self._min_size,
+ # but not 0, then there must be some mistake, so better to use
+ # self._min_size.
+ return max(self._min_instance_size, self._min_size)
+
+ def update_size_info(self):
+ """ Update this format's current and minimum size (for resize). """
+ pass
+
+ def do_resize(self):
+ """ Resize this filesystem based on this instance's target_size attr.
+
+ :raises: FSResizeError, FSError
+ """
+ if not self.exists:
+ raise FSResizeError("filesystem does not exist", self.device)
+
+ if not self.resizable:
+ raise FSResizeError("filesystem not resizable", self.device)
+
+ if self.target_size == self.current_size:
+ return
+
+ if not self._resize.available:
+ return
+
+ # tmpfs mounts don't need an existing device node
+ if not self.device == "tmpfs" and not os.path.exists(self.device):
+ raise FSResizeError("device does not exist", self.device)
+
+ # The first minimum size can be incorrect if the fs was not
+ # properly unmounted. After do_check the minimum size will be correct
+ # so run the check one last time and bump up the size if it was too
+ # small.
+ self.update_size_info()
+
+ # Check again if resizable is True, as update_size_info() can change that
+ if not self.resizable:
+ raise FSResizeError("filesystem not resizable", self.device)
+
+ if self.target_size < self.min_size:
+ self.target_size = self.min_size
+ log.info("Minimum size changed, setting target_size on %s to %s",
+ self.device, self.target_size)
+
+ # Bump target size to nearest whole number of the resize tool's units.
+ # We always round down because the fs has to fit on whatever device
+ # contains it. To round up would risk quietly setting a target size too
+ # large for the device to hold.
+ rounded = self.target_size.round_to_nearest(self._resize.unit,
+ rounding=ROUND_DOWN)
+
+ # 1. target size was between the min size and max size values prior to
+ # rounding (see _set_target_size)
+ # 2. we've just rounded the target size down (or not at all)
+ # 3. the minimum size is already either rounded (see _get_min_size) or is
+ # equal to the current size (see update_size_info)
+ # 5. the minimum size is less than or equal to the current size (see
+ # _get_min_size)
+ #
+ # This, I think, is sufficient to guarantee that the rounded target size
+ # is greater than or equal to the minimum size.
+
+ # It is possible that rounding down a target size greater than the
+ # current size would move it below the current size, thus changing the
+ # direction of the resize. That means the target size was less than one
+ # unit larger than the current size, and we should do nothing and return
+ # early.
+ if self.target_size > self.current_size and rounded < self.current_size:
+ log.info("rounding target size down to next %s obviated resize of "
+ "filesystem on %s", unit_str(self._resize.unit), self.device)
+ return
+ else:
+ self.target_size = rounded
+
+ try:
+ self._resize.do_task()
+ except FSError as e:
+ raise FSResizeError(e, self.device)
+
+ self._post_resize()
+
+ def _post_resize(self):
+ # XXX must be a smarter way to do this
+ self._size = self.target_size
+ self.notify_kernel()
+
+ @property
+ def current_size(self):
+ """ The filesystem's current actual size. """
+ return self._size if self.exists else Size(0)
+
def create(self, **kwargs):
""" Write the formatting to the specified block device.
@@ -609,17 +772,6 @@ def max_size(self):
return self._max_size
@property
- def min_size(self):
- """ Minimum size for this format instance.
-
- :returns: the minimum size for this format instance
- :rtype: :class:`~.size.Size`
-
- A value of 0 indicates an unknown size.
- """
- return self._min_size
-
- @property
def hidden(self):
""" Whether devices with this formatting should be hidden in UIs. """
return self._hidden
diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py
index f69ac90..ba2a1f1 100644
--- a/blivet/formats/fs.py
+++ b/blivet/formats/fs.py
@@ -40,14 +40,14 @@
from ..tasks import fssync
from ..tasks import fswritelabel
from ..errors import FormatCreateError, FSError, FSReadLabelError
-from ..errors import FSWriteLabelError, FSResizeError
+from ..errors import FSWriteLabelError
from . import DeviceFormat, register_device_format
from .. import util
from .. import platform
from ..flags import flags
from ..storage_log import log_exception_info, log_method_call
from .. import arch
-from ..size import Size, ROUND_UP, ROUND_DOWN, unit_str
+from ..size import Size, ROUND_UP
from ..i18n import N_
from .. import udev
from ..mounts import mounts_cache
@@ -66,13 +66,9 @@ class FS(DeviceFormat):
_modules = [] # kernel modules required for support
_labelfs = None # labeling functionality
_fsck_class = fsck.UnimplementedFSCK
- _info_class = fsinfo.UnimplementedFSInfo
- _minsize_class = fsminsize.UnimplementedFSMinSize
_mkfs_class = fsmkfs.UnimplementedFSMkfs
_mount_class = fsmount.FSMount
_readlabel_class = fsreadlabel.UnimplementedFSReadLabel
- _resize_class = fsresize.UnimplementedFSResize
- _size_info_class = fssize.UnimplementedFSSize
_sync_class = fssync.UnimplementedFSSync
_writelabel_class = fswritelabel.UnimplementedFSWriteLabel
# This constant is aquired by testing some filesystems
@@ -109,19 +105,13 @@ def __init__(self, **kwargs):
DeviceFormat.__init__(self, **kwargs)
# Create task objects
- self._info = self._info_class(self)
self._fsck = self._fsck_class(self)
self._mkfs = self._mkfs_class(self)
self._mount = self._mount_class(self)
self._readlabel = self._readlabel_class(self)
- self._resize = self._resize_class(self)
self._sync = self._sync_class(self)
self._writelabel = self._writelabel_class(self)
- # These two may depend on info class, so create them after
- self._minsize = self._minsize_class(self)
- self._size_info = self._size_info_class(self)
-
self._current_info = None # info obtained by _info task
self.mountpoint = kwargs.get("mountpoint")
@@ -129,13 +119,6 @@ def __init__(self, **kwargs):
self.label = kwargs.get("label")
self.fsprofile = kwargs.get("fsprofile")
- # filesystem size does not necessarily equal device size
- self._size = kwargs.get("size", Size(0))
- self._min_instance_size = Size(0) # min size of this FS instance
-
- # Resize operations are limited to error-free filesystems whose current
- # size is known.
- self._resizable = False
if flags.installer_mode and self._resize.available:
# if you want current/min size you have to call update_size_info
try:
@@ -216,42 +199,6 @@ def label_format_ok(self, label):
label = property(lambda s: s._get_label(), lambda s, l: s._set_label(l),
doc="this filesystem's label")
- def _set_target_size(self, newsize):
- """ Set the target size for this filesystem.
-
- :param :class:`~.size.Size` newsize: the newsize
- """
- if not isinstance(newsize, Size):
- raise ValueError("new size must be of type Size")
-
- if not self.exists:
- raise FSError("filesystem has not been created")
-
- if not self.resizable:
- raise FSError("filesystem is not resizable")
-
- if newsize < self.min_size:
- raise ValueError("requested size %s must be at least minimum size %s" % (newsize, self.min_size))
-
- if self.max_size and newsize >= self.max_size:
- raise ValueError("requested size %s must be less than maximum size %s" % (newsize, self.max_size))
-
- self._target_size = newsize
-
- def _get_target_size(self):
- """ Get this filesystem's target size. """
- return self._target_size
-
- target_size = property(_get_target_size, _set_target_size,
- doc="Target size for this filesystem")
-
- def _get_size(self):
- """ Get this filesystem's size. """
- return self.target_size if self.resizable else self._size
-
- size = property(_get_size, doc="This filesystem's size, accounting "
- "for pending changes")
-
def update_size_info(self):
""" Update this filesystem's current and minimum size (for resize). """
@@ -315,16 +262,6 @@ def update_size_info(self):
except (FSError, NotImplementedError) as e:
log.warning("Failed to obtain minimum size for device %s: %s", self.device, e)
- @property
- def min_size(self):
- # If self._min_instance_size is not 0, then it should be no less than
- # self._min_size, by definition, and since a non-zero value indicates
- # that it was obtained, it is the preferred value.
- # If self._min_instance_size is less than self._min_size,
- # but not 0, then there must be some mistake, so better to use
- # self._min_size.
- return max(self._min_instance_size, self._min_size)
-
def _pad_size(self, size):
""" Return a size padded according to some inflating rules.
@@ -346,11 +283,6 @@ def _pad_size(self, size):
return padded
@property
- def current_size(self):
- """ The filesystem's current actual size. """
- return self._size if self.exists else Size(0)
-
- @property
def free(self):
""" The amount of space that can be gained by resizing this
filesystem to its minimum size.
@@ -390,82 +322,9 @@ def _post_create(self, **kwargs):
except FSError as e:
log.warning("Failed to write label (%s) for filesystem %s: %s", self.label, self.type, e)
- def do_resize(self):
- """ Resize this filesystem based on this instance's target_size attr.
-
- :raises: FSResizeError, FSError
- """
- if not self.exists:
- raise FSResizeError("filesystem does not exist", self.device)
-
- if not self.resizable:
- raise FSResizeError("filesystem not resizable", self.device)
-
- if self.target_size == self.current_size:
- return
-
- if not self._resize.available:
- return
-
- # tmpfs mounts don't need an existing device node
- if not self.device == "tmpfs" and not os.path.exists(self.device):
- raise FSResizeError("device does not exist", self.device)
-
- # The first minimum size can be incorrect if the fs was not
- # properly unmounted. After do_check the minimum size will be correct
- # so run the check one last time and bump up the size if it was too
- # small.
- self.update_size_info()
-
- # Check again if resizable is True, as update_size_info() can change that
- if not self.resizable:
- raise FSResizeError("filesystem not resizable", self.device)
-
- if self.target_size < self.min_size:
- self.target_size = self.min_size
- log.info("Minimum size changed, setting target_size on %s to %s",
- self.device, self.target_size)
-
- # Bump target size to nearest whole number of the resize tool's units.
- # We always round down because the fs has to fit on whatever device
- # contains it. To round up would risk quietly setting a target size too
- # large for the device to hold.
- rounded = self.target_size.round_to_nearest(self._resize.unit,
- rounding=ROUND_DOWN)
-
- # 1. target size was between the min size and max size values prior to
- # rounding (see _set_target_size)
- # 2. we've just rounded the target size down (or not at all)
- # 3. the minimum size is already either rounded (see _get_min_size) or is
- # equal to the current size (see update_size_info)
- # 5. the minimum size is less than or equal to the current size (see
- # _get_min_size)
- #
- # This, I think, is sufficient to guarantee that the rounded target size
- # is greater than or equal to the minimum size.
-
- # It is possible that rounding down a target size greater than the
- # current size would move it below the current size, thus changing the
- # direction of the resize. That means the target size was less than one
- # unit larger than the current size, and we should do nothing and return
- # early.
- if self.target_size > self.current_size and rounded < self.current_size:
- log.info("rounding target size down to next %s obviated resize of "
- "filesystem on %s", unit_str(self._resize.unit), self.device)
- return
- else:
- self.target_size = rounded
-
- try:
- self._resize.do_task()
- except FSError as e:
- raise FSResizeError(e, self.device)
-
+ def _post_resize(self):
self.do_check()
-
- # XXX must be a smarter way to do this
- self._size = self.target_size
- self.notify_kernel()
+ super(FS, self)._post_resize()
def do_check(self):
""" Run a filesystem check.
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/d664e9f9711229b1c6031af9db3b...
8 years, 4 months
Updated: [rhinstaller/blivet/pulls/308 master] LUKS resize
by dashea
LUKS encrypted partitions resize support.
Known issues:
- `LUKSFormat` has "wrong" `min_size` -- because minimal size depends on minimal size of LUKS device's format, it's not possible to set it for LUKS format. Slave device, LUKS device and filesystem have correct min_size.
- Both `LUKSFormat` and `LUKSDevice` don't have `max_size` -- it depends on the slave device. We don't set max_size for formats (just limits), so it probably makes sense to set the max size correctly just for the slave device. But it would be easy to set the max_size correctly for the LUKS device.
- Tasks -- I just took code from mulhern's original pull request and made changes to make pep8 and pylint happy. It works, but I don't have idea how :)
- `FSError` and `FSResizeError` -- original `do_resize` and `_set_target_size` raised only these exceptions but it doesn't make sense for "non-filesystems". I've tried to change it to raise `DeviceFormatError` and `FormatResizeError` where it makes sense. Not sure if this is the best way.
- There are no tests. I will add some next week.
--
To view this pull request on github, visit https://github.com/rhinstaller/blivet/pull/308
8 years, 4 months