curtin-dev team mailing list archive
-
curtin-dev team
-
Mailing list archive
-
Message #02295
[Merge] ~dbungert/curtin:ntfs into curtin:master
Dan Bungert has proposed merging ~dbungert/curtin:ntfs into curtin:master.
Commit message:
block/v2: resize of ntfs
Requested reviews:
curtin developers (curtin-dev)
For more details, see:
https://code.launchpad.net/~dbungert/curtin/+git/curtin/+merge/420513
--
Your team curtin developers is requested to review the proposed merge of ~dbungert/curtin:ntfs into curtin:master.
diff --git a/curtin/commands/block_meta_v2.py b/curtin/commands/block_meta_v2.py
index c1e3630..2efff25 100644
--- a/curtin/commands/block_meta_v2.py
+++ b/curtin/commands/block_meta_v2.py
@@ -60,6 +60,10 @@ def resize_ext(path, size):
util.subp(['resize2fs', path, f'{size_k}k'])
+def resize_ntfs(path, size):
+ util.subp(['ntfsresize', '-s', str(size), path])
+
+
def perform_resize(kname, size, direction):
path = block.kname_to_path(kname)
fstype = _get_volume_fstype(path)
@@ -73,6 +77,7 @@ resizers = {
'ext2': resize_ext,
'ext3': resize_ext,
'ext4': resize_ext,
+ 'ntfs': resize_ntfs,
}
diff --git a/doc/topics/storage.rst b/doc/topics/storage.rst
index e6dd13a..aa5ad13 100644
--- a/doc/topics/storage.rst
+++ b/doc/topics/storage.rst
@@ -445,7 +445,7 @@ If the ``preserve`` flag is set to true, curtin will adjust the size of the
partition to the new size. When adjusting smaller, the size of the contents
must permit that. When adjusting larger, there must already be a gap beyond
the partition in question.
-Resize is supported on filesystems of types ext2, ext3, ext4.
+Resize is supported on filesystems of types ext2, ext3, ext4, ntfs.
**name**: *<name>*
diff --git a/tests/integration/test_block_meta.py b/tests/integration/test_block_meta.py
index be69bc0..76a974b 100644
--- a/tests/integration/test_block_meta.py
+++ b/tests/integration/test_block_meta.py
@@ -6,9 +6,11 @@ import json
import sys
import yaml
import os
+import re
from curtin import block, udev, util
+from curtin.commands.block_meta import _get_volume_fstype
from curtin.commands.block_meta_v2 import ONE_MIB_BYTES
from tests.unittests.helpers import CiTestCase
@@ -35,9 +37,7 @@ def loop_dev(image, sector_size=512):
PartData = namedtuple("PartData", ('number', 'offset', 'size'))
-def _get_filesystem_size(dev, part_action, fstype='ext4'):
- if fstype not in ('ext2', 'ext3', 'ext4'):
- raise Exception(f'_get_filesystem_size: no support for {fstype}')
+def _get_ext_size(dev, part_action):
num = part_action['number']
cmd = ['dumpe2fs', '-h', f'{dev}p{num}']
out = util.subp(cmd, capture=True)[0]
@@ -49,6 +49,37 @@ def _get_filesystem_size(dev, part_action, fstype='ext4'):
return int(block_count) * int(block_size)
+def _get_ntfs_size(dev, part_action):
+ num = part_action['number']
+ cmd = ['ntfsresize',
+ '--no-action',
+ '--force', # needed post-resize, which otherwise demands a CHKDSK
+ '--info', f'{dev}p{num}']
+ out = util.subp(cmd, capture=True)[0]
+ # Sample input:
+ # Current volume size: 41939456 bytes (42 MB)
+ volsize_matcher = re.compile(r'^Current volume size: ([0-9]+) bytes')
+ for line in out.splitlines():
+ m = volsize_matcher.match(line)
+ if m:
+ return int(m.group(1))
+ raise Exception('ntfs volume size not found')
+
+
+_get_fs_sizers = {
+ 'ext2': _get_ext_size,
+ 'ext3': _get_ext_size,
+ 'ext4': _get_ext_size,
+ 'ntfs': _get_ntfs_size,
+}
+
+
+def _get_filesystem_size(dev, part_action, fstype='ext4'):
+ if fstype not in _get_fs_sizers.keys():
+ raise Exception(f'_get_filesystem_size: no support for {fstype}')
+ return _get_fs_sizers[fstype](dev, part_action)
+
+
def _get_extended_partition_size(dev, num):
# sysfs reports extended partitions as having 1K size
# sfdisk seems to have a better idea
@@ -139,6 +170,17 @@ class TestBlockMeta(IntegrationTestCase):
with self.open_file_on_part(dev, part_action, 'r') as fp:
self.assertEqual(self.data, fp.read())
+ def check_fssize(self, dev, part_action, fstype, expected):
+ tolerance = 0
+ if fstype == 'ntfs':
+ # Per ntfsresize manpage, the actual fs size is at least one sector
+ # less than requested.
+ # In these tests it has been consistently 7 sectors fewer.
+ tolerance = 512 * 10
+ actual_fssize = _get_filesystem_size(dev, part_action, fstype)
+ diff = expected - actual_fssize
+ self.assertTrue(0 <= diff <= tolerance, f'difference of {diff}')
+
def run_bm(self, config, *args, **kwargs):
config_path = self.tmp_path('config.yaml')
with open(config_path, 'w') as fp:
@@ -481,13 +523,13 @@ class TestBlockMeta(IntegrationTestCase):
fstype=fstype)
self.run_bm(config.render())
with loop_dev(img) as dev:
+ self.assertEqual(fstype, _get_volume_fstype(f'{dev}p1'))
self.create_data(dev, p1)
self.assertEqual(
summarize_partitions(dev), [
PartData(number=1, offset=1 << 20, size=start),
])
- fs_size = _get_filesystem_size(dev, p1, fstype)
- self.assertEqual(start, fs_size)
+ self.check_fssize(dev, p1, fstype, start)
config.set_preserve()
p1['resize'] = True
@@ -499,8 +541,7 @@ class TestBlockMeta(IntegrationTestCase):
summarize_partitions(dev), [
PartData(number=1, offset=1 << 20, size=end),
])
- fs_size = _get_filesystem_size(dev, p1, fstype)
- self.assertEqual(end, fs_size)
+ self.check_fssize(dev, p1, fstype, end)
def test_resize_up_ext2(self):
self._do_test_resize(40, 80, 'ext2')
@@ -520,6 +561,12 @@ class TestBlockMeta(IntegrationTestCase):
def test_resize_down_ext4(self):
self._do_test_resize(80, 40, 'ext4')
+ def test_resize_up_ntfs(self):
+ self._do_test_resize(40, 80, 'ntfs')
+
+ def test_resize_down_ntfs(self):
+ self._do_test_resize(80, 40, 'ntfs')
+
def test_resize_logical(self):
img = self.tmp_path('image.img')
config = StorageConfigBuilder(version=2)
Follow ups