From 77e5886033097d9e51e6a9d47f95086f902bd8ce Mon Sep 17 00:00:00 2001 From: Shad L. Lords Date: Mon, 19 Oct 2009 08:08:43 -0600 Subject: [PATCH 04/16] Allow creating/mounting degraded raid arrays --- fsset.py | 32 ++++++++++++++++++++++++++++++-- raid.py | 18 ++++++++++++++---- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/fsset.py b/fsset.py index 54753a0..ea9ba66 100644 --- a/fsset.py +++ b/fsset.py @@ -2466,11 +2466,20 @@ class RAIDDevice(Device): self.minor) def raidTab (self, devPrefix='/dev'): + if self.level == 1: + nDisks = max(2, self.numDisks) + elif self.level == 5: + nDisks = max(3, self.numDisks) + elif self.level == 6: + nDisks = max(4, self.numDisks) + else: + nDisks = self.numDisks + entry = "" entry = entry + "raiddev %s/%s\n" % (devPrefix, self.device,) entry = entry + "raid-level %d\n" % (self.level,) - entry = entry + "nr-raid-disks %d\n" % (self.numDisks,) + entry = entry + "nr-raid-disks %d\n" % (nDisks,) entry = entry + "chunk-size %s\n" %(self.chunksize,) entry = entry + "persistent-superblock 1\n" entry = entry + "nr-spare-disks %d\n" % (self.spares,) @@ -2480,6 +2489,10 @@ class RAIDDevice(Device): device) entry = entry + " raid-disk %d\n" % (i,) i = i + 1 + while i < nDisks: + entry = entry + " device dev/null\n" + entry = entry + " failed-disk %d\n" % (i,) + i = i + 1 i = 0 for device in [m.getDevice() for m in self.members[self.numDisks:]]: entry = entry + " device %s/%s\n" % (devPrefix, @@ -2492,6 +2505,15 @@ class RAIDDevice(Device): def devify(x): return "/dev/%s" %(x,) + if self.level == 1: + nDisks = max(2, self.numDisks) + elif self.level == 5: + nDisks = max(3, self.numDisks) + elif self.level == 6: + nDisks = max(4, self.numDisks) + else: + nDisks = self.numDisks + node = "%s/%s" % (devPrefix, self.device) isys.makeDevInode(self.device, node) @@ -2504,12 +2526,18 @@ class RAIDDevice(Device): args = ["--create", "/dev/%s" %(self.device,), "--run", "--chunk=%s" %(self.chunksize,), "--level=%s" %(self.level,), - "--raid-devices=%s" %(self.numDisks,)] + "--raid-devices=%s" %(nDisks,)] if self.spares > 0: args.append("--spare-devices=%s" %(self.spares,),) args.extend(memberDevs) + + i = 0 + while self.numDisks + i < nDisks: + args.append("missing") + i = i + 1 + log.info("going to run: %s" %(["/usr/sbin/mdadm"] + args,)) iutil.execWithRedirect ("/usr/sbin/mdadm", args, stderr="/dev/tty5", stdout="/dev/tty5") diff --git a/raid.py b/raid.py index 28829ed..aecd762 100644 --- a/raid.py +++ b/raid.py @@ -125,7 +125,17 @@ def scanForRaid(drives): raidList = [] for key in raidSets.keys(): (level, totalDisks, mdMinor, devices) = raidSets[key] - if len(devices) < totalDisks: + if len(devices) == totalDisks - 1 and level in (1, 5, 6): + log.info("missing components of raid device md%d. The " + "raid device needs %d drive(s) and only %d (was/were) found. " + "This raid device will be started in degraded mode.", mdMinor, + totalDisks, len(devices)) + elif len(devices) == totalDisks - 2 and level == 6: + log.info("missing components of raid device md%d. The " + "raid device needs %d drive(s) and only %d (was/were) found. " + "This raid device will be started in degraded mode.", mdMinor, + totalDisks, len(devices)) + elif len(devices) < totalDisks: log.warning("missing components of raid device md%d. The " "raid device needs %d drive(s) and only %d (was/were) " "found. This raid device will not be started.", mdMinor, @@ -185,11 +195,11 @@ def get_raid_min_members(raidlevel): if isRaid0(raidlevel): return 2 elif isRaid1(raidlevel): - return 2 + return 1 elif isRaid5(raidlevel): - return 3 + return 2 elif isRaid6(raidlevel): - return 4 + return 2 elif isRaid10(raidlevel): return 2 else: -- 1.7.4.1