Skip to content

Commit

Permalink
Merge pull request #1898 from phillxnet/1894_inconsistent_balance_beh…
Browse files Browse the repository at this point in the history
…aviour_on_single_raid_pool

inconsistent balance behaviour on single raid pool. Fixes #1894
  • Loading branch information
schakrava authored Mar 4, 2018
2 parents e8272e0 + d520aa7 commit 6fc293d
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 12 deletions.
13 changes: 7 additions & 6 deletions src/rockstor/fs/btrfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def pool_raid(mnt_pt):
if (len(fields) > 1):
block = fields[0][:-1].lower()
raid = fields[1][:-1].lower()
if block not in raid_d and raid is not 'DUP':
if block not in raid_d:
raid_d[block] = raid
if (raid_d['metadata'] == 'single'):
raid_d['data'] = raid_d['metadata']
Expand Down Expand Up @@ -1225,22 +1225,23 @@ def scrub_status(pool):
@task()
def start_balance(mnt_pt, force=False, convert=None):
cmd = ['btrfs', 'balance', 'start', mnt_pt]
# TODO: Confirm -f is doing what is intended, man states for reducing
# TODO: metadata from say raid1 to single.
# With no filters we also get a warning that block some balances due to
# expected long execution time, in this case "--full-balance" is required.
# N.B. currently force in Web-UI does not mean force here.
if (force):
if force:
cmd.insert(3, '-f')
if (convert is not None):
if convert is not None:
cmd.insert(3, '-dconvert=%s' % convert)
# Override metadata on single pools to be dup, as per btrfs default.
if convert == 'single':
convert = 'dup'
cmd.insert(3, '-mconvert=%s' % convert)
else:
# As we are running with no convert filters a warning and 10 second
# countdown with ^C prompt will result unless we use "--full-balance".
# This warning is now present in the Web-UI "Start a new balance"
# button tooltip.
cmd.insert(3, '--full-balance')
logger.debug('Balance command ({}).'.format(cmd))
run_command(cmd)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ AddPoolView = Backbone.View.extend({
this.$('#raid_level').tooltip({
html: true,
placement: 'right',
title: 'Desired RAID level of the pool<br><strong>Single</strong>: No software raid. (Recommended while using hardware raid).<br><strong>Raid0</strong>, <strong>Raid1</strong>, <strong>Raid10</strong>, <strong>Raid5</strong>, and <strong>Raid6</strong> are similar to conventional raid levels. See documentation for more information.<br><strong>WARNING: Raid5 and Raid6 are not production-ready</strong>'
title: 'Software RAID level<br><strong>Single</strong>: No RAID - one or more devices (-m dup enforced).<br><strong>Raid0</strong>, <strong>Raid1</strong>, <strong>Raid10</strong>, and the parity based <strong>Raid5</strong> & <strong>Raid6</strong> levels are all similar to conventional raid but chunk based, not device based. See docs for more info.<br><strong>WARNING: Raid5 and Raid6 are not production-ready</strong>'
});

this.$('#compression').tooltip({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ PoolAddDisks = RockstorWizardPage.extend({
Handlebars.registerHelper('display_raid_levels', function(){
var html = '';
var _this = this;
var levels = ['raid0', 'raid1', 'raid10', 'raid5', 'raid6'];
var levels = ['single', 'raid0', 'raid1', 'raid10', 'raid5', 'raid6'];
_.each(levels, function(level) {
if (_this.raidLevel != level) {
html += '<option value="' + level + '">' + level + '</option>';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ PoolRaidChange = RockstorWizardPage.extend({
Handlebars.registerHelper('display_raid_levels', function() {
var html = '';
var _this = this;
var levels = ['raid0', 'raid1', 'raid10', 'raid5', 'raid6'];
var levels = ['single', 'raid0', 'raid1', 'raid10', 'raid5', 'raid6'];
_.each(levels, function(level) {
if (_this.raidLevel != level) {
html += '<option value="' + level + '">' + level + '</option>';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,12 @@ PoolDetailsLayoutView = RockstorLayoutView.extend({
this.$('#ph-pool-usage').html(this.subviews['pool-usage'].render().el);
this.$('#ph-pool-scrubs').html(this.subviews['pool-scrubs'].render().el);
this.$('#ph-pool-rebalances').html(this.subviews['pool-rebalances'].render().el);
this.renderDataTables();
// Sort all SubView tables in descending order by initial column.
// This way we see the latest Scrub / Balance items at the top.
var customs = {
'order': [[0, 'desc']]
};
this.renderDataTables(customs);


this.$('#ph-compression-info').html(this.compression_info_template({
Expand Down
18 changes: 16 additions & 2 deletions src/rockstor/storageadmin/views/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ def _remount(cls, request, pool):

def _balance_start(self, pool, force=False, convert=None):
mnt_pt = mount_root(pool)
if convert is None and pool.raid == 'single':
# Btrfs balance without convert filters will convert dup level
# metadata on a single level data pool to raid1 on multi disk
# pools. Avoid by explicit convert in this instance.
logger.info('Preserve single data, dup metadata by explicit '
'convert.')
convert = 'single'
start_balance.async(mnt_pt, force=force, convert=convert)
tid = 0
count = 0
Expand Down Expand Up @@ -375,7 +382,9 @@ def put(self, request, pid, command):
'web-ui' % d.name)
handle_exception(Exception(e_msg), request)

if (pool.raid != 'single' and new_raid == 'single'):
if pool.raid == 'single' and new_raid == 'raid10':
# TODO: Consider removing once we have better space calc.
# Avoid extreme raid level change upwards (space issues).
e_msg = ('Pool migration from %s to %s is not supported.'
% (pool.raid, new_raid))
handle_exception(Exception(e_msg), request)
Expand Down Expand Up @@ -404,7 +413,12 @@ def put(self, request, pid, command):
handle_exception(Exception(e_msg), request)

resize_pool(pool, dnames)
tid = self._balance_start(pool, convert=new_raid)
# During dev add we also offer raid level change, if selected
# blanket apply '-f' to allow for reducing metadata integrity.
force = False
if new_raid != pool.raid:
force = True
tid = self._balance_start(pool, force=force, convert=new_raid)
ps = PoolBalance(pool=pool, tid=tid)
ps.save()

Expand Down

0 comments on commit 6fc293d

Please sign in to comment.