From 73f108fb3ae02f6dff552d16a37a41ba8c5ea707 Mon Sep 17 00:00:00 2001 From: Shad L. Lords Date: Mon, 26 Oct 2009 17:21:07 -0600 Subject: [PATCH] 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 cee9ef7..b249172 100644 --- a/fsset.py +++ b/fsset.py @@ -2007,11 +2007,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,) @@ -2021,6 +2030,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 self.members[self.numDisks:]: entry = entry + " device %s/%s\n" % (devPrefix, @@ -2032,6 +2045,15 @@ class RAIDDevice(Device): def setupDevice (self, chroot="/", devPrefix='/dev'): 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) @@ -2044,12 +2066,18 @@ class RAIDDevice(Device): args = ["/usr/sbin/mdadm", "--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(map(devify, self.members)) + + i = 0 + while self.numDisks + i < nDisks: + args.append("missing") + i = i + 1 + log("going to run: %s" %(args,)) iutil.execWithRedirect (args[0], args, stderr="/dev/tty5", stdout="/dev/tty5") diff --git a/raid.py b/raid.py index 3e99911..e210bf5 100644 --- a/raid.py +++ b/raid.py @@ -90,7 +90,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("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("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("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, @@ -160,11 +170,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 else: raise ValueError, "invalid raidlevel in get_raid_min_members" -- 1.5.5.6