1 |
From 73f108fb3ae02f6dff552d16a37a41ba8c5ea707 Mon Sep 17 00:00:00 2001 |
2 |
From: Shad L. Lords <slords@mail.com> |
3 |
Date: Mon, 26 Oct 2009 17:21:07 -0600 |
4 |
Subject: [PATCH] Allow creating/mounting degraded raid arrays |
5 |
|
6 |
--- |
7 |
fsset.py | 32 ++++++++++++++++++++++++++++++-- |
8 |
raid.py | 18 ++++++++++++++---- |
9 |
2 files changed, 44 insertions(+), 6 deletions(-) |
10 |
|
11 |
diff --git a/fsset.py b/fsset.py |
12 |
index cee9ef7..b249172 100644 |
13 |
--- a/fsset.py |
14 |
+++ b/fsset.py |
15 |
@@ -2007,11 +2007,20 @@ class RAIDDevice(Device): |
16 |
self.minor) |
17 |
|
18 |
def raidTab (self, devPrefix='/dev'): |
19 |
+ if self.level == 1: |
20 |
+ nDisks = max(2, self.numDisks) |
21 |
+ elif self.level == 5: |
22 |
+ nDisks = max(3, self.numDisks) |
23 |
+ elif self.level == 6: |
24 |
+ nDisks = max(4, self.numDisks) |
25 |
+ else: |
26 |
+ nDisks = self.numDisks |
27 |
+ |
28 |
entry = "" |
29 |
entry = entry + "raiddev %s/%s\n" % (devPrefix, |
30 |
self.device,) |
31 |
entry = entry + "raid-level %d\n" % (self.level,) |
32 |
- entry = entry + "nr-raid-disks %d\n" % (self.numDisks,) |
33 |
+ entry = entry + "nr-raid-disks %d\n" % (nDisks,) |
34 |
entry = entry + "chunk-size %s\n" %(self.chunksize,) |
35 |
entry = entry + "persistent-superblock 1\n" |
36 |
entry = entry + "nr-spare-disks %d\n" % (self.spares,) |
37 |
@@ -2021,6 +2030,10 @@ class RAIDDevice(Device): |
38 |
device) |
39 |
entry = entry + " raid-disk %d\n" % (i,) |
40 |
i = i + 1 |
41 |
+ while i < nDisks: |
42 |
+ entry = entry + " device dev/null\n" |
43 |
+ entry = entry + " failed-disk %d\n" % (i,) |
44 |
+ i = i + 1 |
45 |
i = 0 |
46 |
for device in self.members[self.numDisks:]: |
47 |
entry = entry + " device %s/%s\n" % (devPrefix, |
48 |
@@ -2032,6 +2045,15 @@ class RAIDDevice(Device): |
49 |
def setupDevice (self, chroot="/", devPrefix='/dev'): |
50 |
def devify(x): |
51 |
return "/dev/%s" %(x,) |
52 |
+ |
53 |
+ if self.level == 1: |
54 |
+ nDisks = max(2, self.numDisks) |
55 |
+ elif self.level == 5: |
56 |
+ nDisks = max(3, self.numDisks) |
57 |
+ elif self.level == 6: |
58 |
+ nDisks = max(4, self.numDisks) |
59 |
+ else: |
60 |
+ nDisks = self.numDisks |
61 |
|
62 |
node = "%s/%s" % (devPrefix, self.device) |
63 |
isys.makeDevInode(self.device, node) |
64 |
@@ -2044,12 +2066,18 @@ class RAIDDevice(Device): |
65 |
args = ["/usr/sbin/mdadm", "--create", "/dev/%s" %(self.device,), |
66 |
"--run", "--chunk=%s" %(self.chunksize,), |
67 |
"--level=%s" %(self.level,), |
68 |
- "--raid-devices=%s" %(self.numDisks,)] |
69 |
+ "--raid-devices=%s" %(nDisks,)] |
70 |
|
71 |
if self.spares > 0: |
72 |
args.append("--spare-devices=%s" %(self.spares,),) |
73 |
|
74 |
args.extend(map(devify, self.members)) |
75 |
+ |
76 |
+ i = 0 |
77 |
+ while self.numDisks + i < nDisks: |
78 |
+ args.append("missing") |
79 |
+ i = i + 1 |
80 |
+ |
81 |
log("going to run: %s" %(args,)) |
82 |
iutil.execWithRedirect (args[0], args, |
83 |
stderr="/dev/tty5", stdout="/dev/tty5") |
84 |
diff --git a/raid.py b/raid.py |
85 |
index 3e99911..e210bf5 100644 |
86 |
--- a/raid.py |
87 |
+++ b/raid.py |
88 |
@@ -90,7 +90,17 @@ def scanForRaid(drives): |
89 |
raidList = [] |
90 |
for key in raidSets.keys(): |
91 |
(level, totalDisks, mdMinor, devices) = raidSets[key] |
92 |
- if len(devices) < totalDisks: |
93 |
+ if len(devices) == totalDisks - 1 and level in (1, 5, 6): |
94 |
+ log("missing components of raid device md%d. The " |
95 |
+ "raid device needs %d drive(s) and only %d (was/were) found. " |
96 |
+ "This raid device will be started in degraded mode.", mdMinor, |
97 |
+ totalDisks, len(devices)) |
98 |
+ elif len(devices) == totalDisks - 2 and level == 6: |
99 |
+ log("missing components of raid device md%d. The " |
100 |
+ "raid device needs %d drive(s) and only %d (was/were) found. " |
101 |
+ "This raid device will be started in degraded mode.", mdMinor, |
102 |
+ totalDisks, len(devices)) |
103 |
+ elif len(devices) < totalDisks: |
104 |
log("missing components of raid device md%d. The " |
105 |
"raid device needs %d drive(s) and only %d (was/were) found. " |
106 |
"This raid device will not be started.", mdMinor, |
107 |
@@ -160,11 +170,11 @@ def get_raid_min_members(raidlevel): |
108 |
if isRaid0(raidlevel): |
109 |
return 2 |
110 |
elif isRaid1(raidlevel): |
111 |
- return 2 |
112 |
+ return 1 |
113 |
elif isRaid5(raidlevel): |
114 |
- return 3 |
115 |
+ return 2 |
116 |
elif isRaid6(raidlevel): |
117 |
- return 4 |
118 |
+ return 2 |
119 |
else: |
120 |
raise ValueError, "invalid raidlevel in get_raid_min_members" |
121 |
|
122 |
-- |
123 |
1.5.5.6 |
124 |
|