Add bluestore support for OSD's

Add highly experimental support for bluestore storage format for
OSD devices; this is disabled by default and should only be enabled
in deployments where loss of data does not present a problem!

Change-Id: I67323e26a4698de4e08c8c755db232399f7fed02
Depends-On: I36f7aa9d7b96ec5c9eaa7a3a970593f9ca14cb34
This commit is contained in:
James Page 2017-07-07 09:57:14 +01:00
parent 9d6e6b40c6
commit e2fc2e3bd9
6 changed files with 66 additions and 10 deletions

View File

@ -42,7 +42,8 @@ def add_device(request, device_path, bucket=None):
ceph.osdize(dev, config('osd-format'),
get_journal_devices(), config('osd-reformat'),
config('ignore-device-errors'),
config('osd-encrypt'))
config('osd-encrypt'),
config('bluestore'))
# Make it fast!
if config('autotune'):
ceph.tune_dev(dev)

View File

@ -98,6 +98,12 @@ options:
btrfs (experimental and not recommended)
.
Only supported with ceph >= 0.48.3.
bluestore:
type: boolean
default: false
description: |
Use experimental bluestore storage format for OSD devices; only supported
in Ceph Jewel (10.2.0) or later.
osd-reformat:
type: string
default:

View File

@ -207,6 +207,7 @@ def get_ceph_context():
'loglevel': config('loglevel'),
'dio': str(config('use-direct-io')).lower(),
'short_object_len': use_short_objects(),
'bluestore': config('bluestore'),
}
if config('prefer-ipv6'):
@ -308,7 +309,8 @@ def storage_changed():
if ceph.is_bootstrapped():
for dev in get_devices():
ceph.osdize(dev, config('osd-format'), get_osd_journal(),
reformat_osd(), config('ignore-device-errors'))
reformat_osd(), config('ignore-device-errors'),
bluestore=config('bluestore'))
ceph.start_osds(get_devices())
@ -404,7 +406,8 @@ def mon_relation():
ceph.wait_for_bootstrap()
for dev in get_devices():
ceph.osdize(dev, config('osd-format'), get_osd_journal(),
reformat_osd(), config('ignore-device-errors'))
reformat_osd(), config('ignore-device-errors'),
bluestore=config('bluestore'))
ceph.start_osds(get_devices())
ceph.wait_for_quorum()
notify_osds()

View File

@ -1355,16 +1355,17 @@ def find_least_used_journal(journal_devices):
def osdize(dev, osd_format, osd_journal, reformat_osd=False,
ignore_errors=False, encrypt=False):
ignore_errors=False, encrypt=False, bluestore=False):
if dev.startswith('/dev'):
osdize_dev(dev, osd_format, osd_journal,
reformat_osd, ignore_errors, encrypt)
reformat_osd, ignore_errors, encrypt,
bluestore)
else:
osdize_dir(dev, encrypt)
def osdize_dev(dev, osd_format, osd_journal, reformat_osd=False,
ignore_errors=False, encrypt=False):
ignore_errors=False, encrypt=False, bluestore=False):
if not os.path.exists(dev):
log('Path {} does not exist - bailing'.format(dev))
return
@ -1392,9 +1393,16 @@ def osdize_dev(dev, osd_format, osd_journal, reformat_osd=False,
if osd_format:
cmd.append('--fs-type')
cmd.append(osd_format)
if reformat_osd:
cmd.append('--zap-disk')
# NOTE(jamespage): enable experimental bluestore support
if cmp_pkgrevno('ceph', '10.2.0') >= 0 and bluestore:
cmd.append('--bluestore')
cmd.append(dev)
if osd_journal:
least_used = find_least_used_journal(osd_journal)
cmd.append(least_used)

View File

@ -37,6 +37,10 @@ cluster addr = {{ cluster_addr }}
{% endfor %}
{% endif %}
{% if bluestore -%}
enable experimental unrecoverable data corrupting features = bluestore rocksdb
{%- endif %}
[mon]
keyring = /var/lib/ceph/mon/$cluster-$id/keyring
{% if mon -%}

View File

@ -30,7 +30,8 @@ CHARM_CONFIG = {'config-flags': '',
'use-direct-io': True,
'osd-format': 'ext4',
'prefer-ipv6': False,
'customize-failure-domain': False}
'customize-failure-domain': False,
'bluestore': False}
class CephHooksTestCase(unittest.TestCase):
@ -60,7 +61,38 @@ class CephHooksTestCase(unittest.TestCase):
'osd_journal_size': 1024,
'public_addr': '10.0.0.1',
'short_object_len': True,
'use_syslog': 'true'}
'use_syslog': 'true',
'bluestore': False}
self.assertEqual(ctxt, expected)
@patch.object(ceph_hooks, 'get_public_addr', lambda *args: "10.0.0.1")
@patch.object(ceph_hooks, 'get_cluster_addr', lambda *args: "10.1.0.1")
@patch.object(ceph_hooks, 'cmp_pkgrevno', lambda *args: 1)
@patch.object(ceph_hooks, 'get_mon_hosts', lambda *args: ['10.0.0.1',
'10.0.0.2'])
@patch.object(ceph_hooks, 'get_networks', lambda *args: "")
@patch.object(ceph, 'config')
@patch.object(ceph_hooks, 'config')
def test_get_ceph_context_bluestore(self, mock_config, mock_config2):
config = copy.deepcopy(CHARM_CONFIG)
config['bluestore'] = True
mock_config.side_effect = lambda key: config[key]
mock_config2.side_effect = lambda key: config[key]
ctxt = ceph_hooks.get_ceph_context()
expected = {'auth_supported': False,
'ceph_cluster_network': '',
'ceph_public_network': '',
'cluster_addr': '10.1.0.1',
'dio': 'true',
'fsid': '1234',
'loglevel': 1,
'mon_hosts': '10.0.0.1 10.0.0.2',
'old_auth': False,
'osd_journal_size': 1024,
'public_addr': '10.0.0.1',
'short_object_len': True,
'use_syslog': 'true',
'bluestore': True}
self.assertEqual(ctxt, expected)
@patch.object(ceph_hooks, 'get_public_addr', lambda *args: "10.0.0.1")
@ -90,7 +122,8 @@ class CephHooksTestCase(unittest.TestCase):
'osd_journal_size': 1024,
'public_addr': '10.0.0.1',
'short_object_len': True,
'use_syslog': 'true'}
'use_syslog': 'true',
'bluestore': False}
self.assertEqual(ctxt, expected)
@patch.object(ceph_hooks, 'get_public_addr', lambda *args: "10.0.0.1")
@ -122,7 +155,8 @@ class CephHooksTestCase(unittest.TestCase):
'osd_journal_size': 1024,
'public_addr': '10.0.0.1',
'short_object_len': True,
'use_syslog': 'true'}
'use_syslog': 'true',
'bluestore': False}
self.assertEqual(ctxt, expected)
def test_nrpe_dependency_installed(self):