From e5ca9b110954900f30bf32d66ea3440a4203e84c Mon Sep 17 00:00:00 2001
From: Lukas Czerner <lczerner@redhat.com>
Date: Wed, 15 Jan 2014 13:59:44 +0100
Subject: [PATCH 03/10] ssm: force btrfs device add
Btrfs is broken. It does not recognize the btrfs signature properly and
even when the device has been wiped with wipefs btrfs would still claim
that the device actually is 'btrfs' device which it is not!
We've already fixed the case for mkfs.btrfs, howeve btrfs recently added
the check for 'btrfs device add' as well, so we need to do the same
thing. So make _can_btrfs_force() more generic and use it in extend()
method as well.
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
---
ssmlib/backends/btrfs.py | 19 +++++---
tests/unittests/test_btrfs.py | 102 +++++++++++++++++++++---------------------
2 files changed, 65 insertions(+), 56 deletions(-)
diff --git a/ssmlib/backends/btrfs.py b/ssmlib/backends/btrfs.py
index 750a517..b238d52 100644
--- a/ssmlib/backends/btrfs.py
+++ b/ssmlib/backends/btrfs.py
@@ -411,14 +411,13 @@ class BtrfsPool(Btrfs, template.BackendPool):
else:
self.data = self._pool
- def _can_btrfs_force(self):
+ def _can_btrfs_force(self, command):
"""
This is just ridiculous. Unfortunately btrfs tools usually change
behaviour and options without bumping version number. So we have
to check whether btrfs allows to 'force' file system creation.
"""
- command=['mkfs.btrfs', '-f']
- output = misc.run(command, can_fail=True)[1]
+ output = misc.run(command + ['--force'], can_fail=True)[1]
found = re.search('invalid option', output)
if found:
return False
@@ -456,8 +455,8 @@ class BtrfsPool(Btrfs, template.BackendPool):
# have tried to remove the device from the respective pool already.
# So at this point there should not be any useful signatures to
# speak of. However as I mentioned btrfs is broken, so force it.
- if self._can_btrfs_force():
- command.extend(['-f'])
+ if self._can_btrfs_force(command):
+ command.extend(['--force'])
command.extend(devs)
misc.run(command, stdout=True)
misc.send_udev_event(devs[0], "change")
@@ -499,6 +498,16 @@ class BtrfsPool(Btrfs, template.BackendPool):
if type(devices) is not list:
devices = [devices]
command = ['device', 'add']
+ # This might seem weird, but btrfs is mostly broken when it comes to
+ # checking existing signatures because it will for example check for
+ # backup superblocks as well, which is wrong. Also we have check for
+ # existing file system signatures in the ssm itself. Other things
+ # than file system should be covered by the backend and we should
+ # have tried to remove the device from the respective pool already.
+ # So at this point there should not be any useful signatures to
+ # speak of. However as I mentioned btrfs is broken, so force it.
+ if self._can_btrfs_force(['btrfs', 'device', 'add']):
+ command.extend(['--force'])
command.extend(devices)
command.append(pool['mount'])
self.run_btrfs(command)
diff --git a/tests/unittests/test_btrfs.py b/tests/unittests/test_btrfs.py
index d1f8135..2fb04bc 100644
--- a/tests/unittests/test_btrfs.py
+++ b/tests/unittests/test_btrfs.py
@@ -91,48 +91,48 @@ class BtrfsFunctionCheck(MockSystemDataSource):
# Create volume using single device from non existent default pool
self._checkCmd("ssm create", ['/dev/sda'],
- "mkfs.btrfs -L {0} -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L {0} --force /dev/sda".format(default_pool))
# Specify default backend
self._checkCmd("ssm -b btrfs create", ['/dev/sda'],
- "mkfs.btrfs -L {0} -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L {0} --force /dev/sda".format(default_pool))
main.SSM_DEFAULT_BACKEND = 'lvm'
self._checkCmd("ssm --backend btrfs create", ['/dev/sda'],
- "mkfs.btrfs -L {0} -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L {0} --force /dev/sda".format(default_pool))
main.SSM_DEFAULT_BACKEND = 'btrfs'
- self._checkCmd("ssm -f create", ['/dev/sda'],
- "mkfs.btrfs -L {0} -f /dev/sda".format(default_pool))
+ self._checkCmd("ssm --force create", ['/dev/sda'],
+ "mkfs.btrfs -L {0} --force /dev/sda".format(default_pool))
self._checkCmd("ssm -v create", ['/dev/sda'],
- "mkfs.btrfs -L {0} -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L {0} --force /dev/sda".format(default_pool))
- self._checkCmd("ssm -f -v create", ['/dev/sda'],
- "mkfs.btrfs -L {0} -f /dev/sda".format(default_pool))
+ self._checkCmd("ssm --force -v create", ['/dev/sda'],
+ "mkfs.btrfs -L {0} --force /dev/sda".format(default_pool))
self._checkCmd("ssm create", ['-s 2.6T', '/dev/sda'],
- "mkfs.btrfs -L {0} -b 2858730232217 -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L {0} -b 2858730232217 --force /dev/sda".format(default_pool))
self._checkCmd("ssm create", ['-r 0', '-s 2.6T', '/dev/sda'],
- "mkfs.btrfs -L btrfs_pool -m raid0 -d raid0 -b 2858730232217 -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L btrfs_pool -m raid0 -d raid0 -b 2858730232217 --force /dev/sda".format(default_pool))
self._checkCmd("ssm create", ['-r 0', '-s 2.6T', '/dev/sda'],
- "mkfs.btrfs -L btrfs_pool -m raid0 -d raid0 -b 2858730232217 -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L btrfs_pool -m raid0 -d raid0 -b 2858730232217 --force /dev/sda".format(default_pool))
self._checkCmd("ssm create", ['-r 1', '-s 512k', '/dev/sda /dev/sdb'],
- "mkfs.btrfs -L btrfs_pool -m raid1 -d raid1 -b 524288 -f /dev/sda /dev/sdb".format(default_pool))
+ "mkfs.btrfs -L btrfs_pool -m raid1 -d raid1 -b 524288 --force /dev/sda /dev/sdb".format(default_pool))
self._checkCmd("ssm create", ['-r 10', '-s 10M', '/dev/sda'],
- "mkfs.btrfs -L btrfs_pool -m raid10 -d raid10 -b 10485760 -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L btrfs_pool -m raid10 -d raid10 -b 10485760 --force /dev/sda".format(default_pool))
# Create volume using single device from non existent my_pool
self._checkCmd("ssm create", ['--pool my_pool', '/dev/sda'],
- "mkfs.btrfs -L my_pool -f /dev/sda")
+ "mkfs.btrfs -L my_pool --force /dev/sda")
self._checkCmd("ssm create", ['-p my_pool', '-r 0', '-s 2.6T', '/dev/sda'],
- "mkfs.btrfs -L my_pool -m raid0 -d raid0 -b 2858730232217 -f /dev/sda")
+ "mkfs.btrfs -L my_pool -m raid0 -d raid0 -b 2858730232217 --force /dev/sda")
# Create volume using multiple devices
self._checkCmd("ssm create /dev/sda /dev/sdb", [],
- "mkfs.btrfs -L {0} -f /dev/sda /dev/sdb".format(default_pool))
+ "mkfs.btrfs -L {0} --force /dev/sda /dev/sdb".format(default_pool))
# Create volume using single device from existing pool
self._addPool(default_pool, ['/dev/sdb', '/dev/sdd'])
@@ -151,15 +151,15 @@ class BtrfsFunctionCheck(MockSystemDataSource):
# in the pool
self._checkCmd("ssm create", ['-n myvolume', '/dev/sda /dev/sdb'],
"btrfs subvolume create /tmp/mount/myvolume")
- self._cmdEq("btrfs device add /dev/sda /tmp/mount", -2)
+ self._cmdEq("btrfs device add --force /dev/sda /tmp/mount", -2)
self._checkCmd("ssm create", ['-p my_pool', '-n myvolume', '/dev/sdc2 /dev/sda'],
"btrfs subvolume create /tmp/mount/myvolume")
- self._cmdEq("btrfs device add /dev/sda /mnt/test", -2)
+ self._cmdEq("btrfs device add --force /dev/sda /mnt/test", -2)
self._checkCmd("ssm create", ['-n myvolume', '/dev/sda /dev/sdb /dev/sde'],
"btrfs subvolume create /tmp/mount/myvolume")
- self._cmdEq("btrfs device add /dev/sda /dev/sde /tmp/mount", -2)
+ self._cmdEq("btrfs device add --force /dev/sda /dev/sde /tmp/mount", -2)
def test_btrfs_remove(self):
# Generate some storage data
@@ -267,17 +267,17 @@ class BtrfsFunctionCheck(MockSystemDataSource):
"btrfs filesystem resize 11723608063K /tmp/mount")
main.SSM_DEFAULT_BACKEND = 'btrfs'
- self._cmdNotEq("btrfs device add /dev/sde /tmp/mount", -2)
+ self._cmdNotEq("btrfs device add --force /dev/sde /tmp/mount", -2)
# Resize with enough space in the pool
self._checkCmd("ssm resize --size +1g", ['my_pool /dev/sde'],
"btrfs filesystem resize 1073052017K /mnt/test1")
- self._cmdNotEq("btrfs device add /dev/sde /mnt/test1", -2)
+ self._cmdNotEq("btrfs device add --force /dev/sde /mnt/test1", -2)
# Resize without enough space in the pool
self._checkCmd("ssm resize --size +1t", ['my_pool /dev/sde'],
"btrfs filesystem resize 2145745265K /mnt/test1")
- self._cmdEq("btrfs device add /dev/sde /mnt/test1", -2)
+ self._cmdEq("btrfs device add --force /dev/sde /mnt/test1", -2)
# Shrink volume
self._checkCmd("ssm resize", ['-s-100G', 'default_pool'],
@@ -285,7 +285,7 @@ class BtrfsFunctionCheck(MockSystemDataSource):
self._checkCmd("ssm resize -s-500G", ['my_pool /dev/sde'],
"btrfs filesystem resize 547715441K /mnt/test1")
self.assertNotEqual(self.run_data[-2],
- "btrfs device add /dev/sde /mnt/test1")
+ "btrfs device add --force /dev/sde /mnt/test1")
# Set volume size
self._checkCmd("ssm resize", ['-s 10M', 'default_pool'],
@@ -297,32 +297,32 @@ class BtrfsFunctionCheck(MockSystemDataSource):
self._checkCmd("ssm resize -s 20T default_pool /dev/sdc1 /dev/sde",
[], "btrfs filesystem resize 21474836480K /tmp/mount")
self.assertNotEqual(self.run_data[-2],
- "btrfs device add /dev/sdc1 /dev/sde /tmp/mount")
+ "btrfs device add --force /dev/sdc1 /dev/sde /tmp/mount")
self._checkCmd("ssm resize -s 22T default_pool /dev/sdc1 /dev/sde",
[], "btrfs filesystem resize 23622320128K /tmp/mount")
self.assertEqual(self.run_data[-2],
- "btrfs device add /dev/sdc1 /dev/sde /tmp/mount")
+ "btrfs device add --force /dev/sdc1 /dev/sde /tmp/mount")
self._checkCmd("ssm resize -s 3T my_pool /dev/sdc1 /dev/sde",
[], "btrfs filesystem resize 3221225472K /mnt/test1")
self.assertEqual(self.run_data[-2],
- "btrfs device add /dev/sdc1 /dev/sde /mnt/test1")
+ "btrfs device add --force /dev/sdc1 /dev/sde /mnt/test1")
self._checkCmd("ssm resize -s 3T my_pool /dev/sde /dev/sdc2",
[], "btrfs filesystem resize 3221225472K /mnt/test1")
self.assertEqual(self.run_data[-2],
- "btrfs device add /dev/sde /mnt/test1")
+ "btrfs device add --force /dev/sde /mnt/test1")
# Set volume in without the need adding more devices
self._checkCmd("ssm resize -s 10G default_pool /dev/sdc1 /dev/sde",
[], "btrfs filesystem resize 10485760K /tmp/mount")
self.assertNotEqual(self.run_data[-2],
- "btrfs device add /dev/sdc1 /dev/sde /tmp/mount")
+ "btrfs device add --force /dev/sdc1 /dev/sde /tmp/mount")
self._checkCmd("ssm resize -s 10G my_pool /dev/sdd /dev/sde",
[], "btrfs filesystem resize 10485760K /mnt/test1")
self.assertNotEqual(self.run_data[-2],
- "btrfs device add /dev/sdc1 /dev/sde /mnt/test1")
+ "btrfs device add --force /dev/sdc1 /dev/sde /mnt/test1")
self._checkCmd("ssm list",
[], "btrfs filesystem resize 12247891967K /tmp/mount")
@@ -330,23 +330,23 @@ class BtrfsFunctionCheck(MockSystemDataSource):
self._checkCmd("ssm resize -s +500G default_pool /dev/sdc1 /dev/sde",
[], "btrfs filesystem resize 12247891967K /tmp/mount")
self.assertEqual(self.run_data[-2],
- "btrfs device add /dev/sdc1 /dev/sde /tmp/mount")
+ "btrfs device add --force /dev/sdc1 /dev/sde /tmp/mount")
# Extend volume in without the need adding more devices
self._checkCmd("ssm resize -s 1k default_pool /dev/sdc1 /dev/sde",
[], "btrfs filesystem resize 1K /tmp/mount")
self.assertNotEqual(self.run_data[-2],
- "btrfs device add /dev/sdc1 /dev/sde /tmp/mount")
+ "btrfs device add --force /dev/sdc1 /dev/sde /tmp/mount")
self.assertNotEqual(self.run_data[-2],
- "btrfs device add /dev/sdc1 /dev/sde /tmp/mount")
+ "btrfs device add --force /dev/sdc1 /dev/sde /tmp/mount")
# Shrink volume with devices provided
self._checkCmd("ssm resize -s-10G default_pool /dev/sdc1 /dev/sde",
[], "btrfs filesystem resize 11713118207K /tmp/mount")
self.assertNotEqual(self.run_data[-2],
- "btrfs device add /dev/sdc1 /dev/sde /tmp/mount")
+ "btrfs device add --force /dev/sdc1 /dev/sde /tmp/mount")
self.assertNotEqual(self.run_data[-2],
- "btrfs device add /dev/sdc1 /dev/sde /tmp/mount")
+ "btrfs device add --force /dev/sdc1 /dev/sde /tmp/mount")
def test_btrfs_add(self):
default_pool = btrfs.SSM_BTRFS_DEFAULT_POOL
@@ -354,39 +354,39 @@ class BtrfsFunctionCheck(MockSystemDataSource):
# Adding to non existent pool
# Add device into default pool
self._checkCmd("ssm add", ['/dev/sda'],
- "mkfs.btrfs -L {0} -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L {0} --force /dev/sda".format(default_pool))
# Specify backend
self._checkCmd("ssm --backend btrfs add", ['/dev/sda'],
- "mkfs.btrfs -L {0} -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L {0} --force /dev/sda".format(default_pool))
main.SSM_DEFAULT_BACKEND = 'lvm'
self._checkCmd("ssm -b btrfs add", ['/dev/sda'],
- "mkfs.btrfs -L {0} -f /dev/sda".format(default_pool))
+ "mkfs.btrfs -L {0} --force /dev/sda".format(default_pool))
main.SSM_DEFAULT_BACKEND = 'btrfs'
# Add more devices into default pool
self._checkCmd("ssm add", ['/dev/sda /dev/sdc1'],
- "mkfs.btrfs -L {0} -f /dev/sda /dev/sdc1".format(default_pool))
+ "mkfs.btrfs -L {0} --force /dev/sda /dev/sdc1".format(default_pool))
# Add device into defined pool
self._checkCmd("ssm add", ['-p my_pool', '/dev/sda'],
- "mkfs.btrfs -L my_pool -f /dev/sda")
+ "mkfs.btrfs -L my_pool --force /dev/sda")
self._checkCmd("ssm add", ['--pool my_pool', '/dev/sda'],
- "mkfs.btrfs -L my_pool -f /dev/sda")
+ "mkfs.btrfs -L my_pool --force /dev/sda")
# Add more devices into defined pool
self._checkCmd("ssm add", ['-p my_pool', '/dev/sda /dev/sdc1'],
- "mkfs.btrfs -L my_pool -f /dev/sda /dev/sdc1")
+ "mkfs.btrfs -L my_pool --force /dev/sda /dev/sdc1")
self._checkCmd("ssm add", ['--pool my_pool', '/dev/sda /dev/sdc1'],
- "mkfs.btrfs -L my_pool -f /dev/sda /dev/sdc1")
+ "mkfs.btrfs -L my_pool --force /dev/sda /dev/sdc1")
# Adding to existing default pool
self._addPool(default_pool, ['/dev/sdb', '/dev/sdd'])
# Add device into default pool
self._checkCmd("ssm add", ['/dev/sda'],
- "btrfs device add /dev/sda /tmp/mount")
+ "btrfs device add --force /dev/sda /tmp/mount")
# Add more devices into default pool
self._checkCmd("ssm add", ['/dev/sda /dev/sdc1'],
- "btrfs device add /dev/sda /dev/sdc1 /tmp/mount")
+ "btrfs device add --force /dev/sda /dev/sdc1 /tmp/mount")
# Adding to existing defined pool
self._addPool('my_pool', ['/dev/sdc2', '/dev/sdc3'])
@@ -394,25 +394,25 @@ class BtrfsFunctionCheck(MockSystemDataSource):
'/mnt/test1')
# Add device into defined pool
self._checkCmd("ssm add", ['-p my_pool', '/dev/sda'],
- "btrfs device add /dev/sda /mnt/test1")
+ "btrfs device add --force /dev/sda /mnt/test1")
self._checkCmd("ssm add", ['--pool my_pool', '/dev/sda'],
- "btrfs device add /dev/sda /mnt/test1")
+ "btrfs device add --force /dev/sda /mnt/test1")
# Add more devices into defined pool
self._checkCmd("ssm add", ['-p my_pool', '/dev/sda /dev/sdc1'],
- "btrfs device add /dev/sda /dev/sdc1 /mnt/test1")
+ "btrfs device add --force /dev/sda /dev/sdc1 /mnt/test1")
self._checkCmd("ssm add", ['--pool my_pool', '/dev/sda /dev/sdc1'],
- "btrfs device add /dev/sda /dev/sdc1 /mnt/test1")
+ "btrfs device add --force /dev/sda /dev/sdc1 /mnt/test1")
# Add verbose
self._checkCmd("ssm -v add", ['--pool {0}'.format(default_pool),
'/dev/sda /dev/sdc1'],
- "btrfs device add /dev/sda /dev/sdc1 /tmp/mount")
+ "btrfs device add --force /dev/sda /dev/sdc1 /tmp/mount")
# Add two devices into existing pool (one of the devices already is in
# the pool
self._checkCmd("ssm add", ['--pool my_pool', '/dev/sdc2 /dev/sda'],
- "btrfs device add /dev/sda /mnt/test1")
+ "btrfs device add --force /dev/sda /mnt/test1")
self._checkCmd("ssm add", ['/dev/sda /dev/sdb'],
- "btrfs device add /dev/sda /tmp/mount")
+ "btrfs device add --force /dev/sda /tmp/mount")
def test_btrfs_mount(self):
self._addDir("/mnt/test")
--
1.8.3.1