From 673422da37ce9f96b44a182addd1aa922a9b047f Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Mon, 24 Oct 2016 14:41:47 -0700 Subject: [PATCH] Handle mdadm --examine output during migration If a RAID set is undergoing any operation considered to be a 'migration' - which includes initialization of a new set at any RAID level that includes redundancy - mdadm --examine will have lines like this: RAID Level : 5 <-- 5 Members : 3 <-- 3 Map State : normal <-- uninitialized At present we don't understand this at all. This is a fairly minimal fix which just has parse_mdadm_vars notice such lines, split the 'value' on "<--", and stuff the first value (the one being migrated *to*, which is usually what we care about, I think) into the table. We could do something more elaborate like store both values and make `get_examine_data_from_table` understand that, but it's more complicated and this should be all we truly need for now. (cherry picked from commit 07aec87385e2fdbe3f0855d697facf04b9ea6521) Signed-off-by: Vratislav Podzimek --- src/plugins/mdraid.c | 13 +++++- tests/md_test.py | 8 ++++ tests/mdadm_fw_RAID_examine_migrate/mdadm | 69 +++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100755 tests/mdadm_fw_RAID_examine_migrate/mdadm diff --git a/src/plugins/mdraid.c b/src/plugins/mdraid.c index 9cb0cc7..c4780eb 100644 --- a/src/plugins/mdraid.c +++ b/src/plugins/mdraid.c @@ -155,6 +155,7 @@ static GHashTable* parse_mdadm_vars (gchar *str, gchar *item_sep, gchar *key_val gchar **items = NULL; gchar **item_p = NULL; gchar **key_val = NULL; + gchar **vals = NULL; table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); *num_items = 0; @@ -165,8 +166,16 @@ static GHashTable* parse_mdadm_vars (gchar *str, gchar *item_sep, gchar *key_val if (g_strv_length (key_val) == 2) { /* we only want to process valid lines (with the separator) */ /* only use the first value for the given key */ - if (!g_hash_table_contains (table, g_strstrip (key_val[0]))) - g_hash_table_insert (table, g_strstrip (key_val[0]), g_strstrip (key_val[1])); + if (!g_hash_table_contains (table, g_strstrip (key_val[0]))) { + if (strstr (key_val[1], "<--")) { + /* mdadm --examine output for a set being migrated */ + vals = g_strsplit (key_val[1], "<--", 2); + g_hash_table_insert (table, g_strstrip (key_val[0]), g_strstrip (vals[0])); + g_free (vals[1]); + } else { + g_hash_table_insert (table, g_strstrip (key_val[0]), g_strstrip (key_val[1])); + } + } (*num_items)++; } else /* invalid line, just free key_val */ diff --git a/tests/md_test.py b/tests/md_test.py index d7e007a..926d0c5 100644 --- a/tests/md_test.py +++ b/tests/md_test.py @@ -415,6 +415,14 @@ class FakeMDADMutilTest(unittest.TestCase): self.assertIs(ex_data.metadata, None) + def test_fw_raid_migrating(self): + """Verify that md_examine works when array is migrating ("foo <-- bar" values in output) """ + + with fake_utils("tests/mdadm_fw_RAID_examine_migrate"): + ex_data = BlockDev.md_examine("fake_dev") + + self.assertEqual(ex_data.chunk_size, 128 * 1024) + class MDUnloadTest(unittest.TestCase): def setUp(self): diff --git a/tests/mdadm_fw_RAID_examine_migrate/mdadm b/tests/mdadm_fw_RAID_examine_migrate/mdadm new file mode 100755 index 0000000..36ab0ca --- /dev/null +++ b/tests/mdadm_fw_RAID_examine_migrate/mdadm @@ -0,0 +1,69 @@ +#!/bin/bash + +echo "$@"|grep -- "--brief" &>/dev/null +is_brief=$? + +echo "$@"|grep -- "--export" &>/dev/null +is_export=$? + +if [ $is_brief -eq 0 ]; then + cat <