Fedora installer support of dmraid ?

Lin, Weichuan weichuan.lin at intel.com
Tue Aug 23 01:58:19 UTC 2005


Hi All

I have a machine with chips of silicon image 3114 and ICH7R on the
motherboard [I can choose one of them to connect the hard disk], and two
SATA hard disks, I am going to enable one of this chips at Fedora
installation stage. What I have done is copy the dmraid static link
version to stage2.img of anaconda, and patched the patch below to
anaconda. This patch is gotten from the mail list of anaconda; I just
changed the regular expression match [parameter of re.match()] to meet
the actual output of the dmraid on my machine. After done this, I can
choose the device of /dev/mapper/sil* to slice partition for
installation. But the operation of parted always fails, I have trace
into the program, and find that ped_disk_commit_to_os() failed due to
failure of ioctl with BLKPG request. The error is reported as Invalid
argument, then an exception is thrown in function of
_blkpg_add_partition(). The installation procedure has to hang due to
this failure. 

On the other hand, if I use parted on an installed system to slice
partition on /dev/mapper/sil* created by dmraid, parted also complains
that he can't notify to the system about the change of the disk
partition. If I connect the hard disks to the ICH7R chips, the dmraid
even can't create /dev/mapper/isw*. With -tay option, dmraid told me
that the GROUP ok, but the device can't be seen under /dev/mapper.

I have interest on enabling raid support at fedora installer, and have
learned that the work is in progress through paper of Heinz on OLS 2005,
but I am not very clear about the stage of the progress. And from the
brief introduction at the end of the paper, the architecture is very
different from what I think; could anyone tell me where can I get more
detail about the current status of the installer support and the
software architecture? 

Here is the patch provided by Wormgoor, with a little change of regular
expression match and argument. 

+# dmraid.py - dmraid probing
+#
+# Mark Wormgoor <mark wormgoor com>
+#
+# Copyright 2004 Mark Wormgoor
+#
+# This software may be freely redistributed under the terms of the GNU
+# general public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import iutil
+import os
+import re
+
+from constants import *
+
+output = "/tmp/dmraidout"
+
+dmraidDevicePresent = 0
+
+def has_dmraid():
+    global dmraidDevicePresent
+
+    if not (os.access("/usr/sbin/dmraid", os.X_OK) or
+            os.access("/sbin/dmraid", os.X_OK)):
+        return
+    
+    rc = iutil.execWithRedirect("dmraid",
+                                ["dmraid", "-ay"],
+                                stdout = output,
+                                stderr = output,
+                                searchPath = 1)
+    if rc:
+        dmraidDevicePresent = 0
+    else:
+	dmraidDevicePresent = 1
+
+    return dmraidDevicePresent
+# now check to see if dmraid is available
+has_dmraid()
+        
+
+def disklist():
+    global dmraidDevicePresent
+    if dmraidDevicePresent == 0:
+        return []
+
+    disks = []
+    args = ["dmraid", "-vay"]
+    dmraidscanout = iutil.execWithCapture(args[0], args, searchPath =
1,
+                                      stderr = "/dev/tty6")
+    for line in dmraidscanout.split("\n"):
+        try:
+	    found = re.match("/dev/(\S+)", line)
+	    disks.append (found.group(1))
+        except:
+            pass
+
+    return disks
+
+def setlist():
+    global dmraidDevicePresent
+    if dmraidDevicePresent == 0:
+        return []
+
+    sets = []
+    args = ["dmraid", "-vay"]
+    dmraidscanout = iutil.execWithCapture(args[0], args, searchPath =
1,
+                                      stderr = "/dev/tty6")
+    for line in dmraidscanout.split("\n"):
+        try:
+	    found = re.match("INFO: added /dev/(\S+) to RAID set
\"(\S+)\"", line)
+	    sets.append (found.group(2))
+        except:
+	    pass
+
+    return sets
diff -ruN mnt/usr/lib/anaconda/isys.py new/usr/lib/anaconda/isys.py
--- mnt/usr/lib/anaconda/isys.py	1970-01-01 01:00:00.000000000
+0100
+++ new/usr/lib/anaconda/isys.py	2004-10-10 21:06:58.000000000
+0200
@@ -20,6 +20,7 @@
 import os
 import os.path
 import posix
+import dmraid
 import sys
 import kudzu
 
@@ -288,6 +289,20 @@
 
     dict = driveDict("disk")
 
+    # first, figure out the dmraid devices
+    if dmraid.has_dmraid():
+	disks = dmraid.disklist()
+	if len(disks) > 0:
+	    for disk in disks:
+		try:
+		    del dict[disk]
+		except:
+		    pass
+	sets = dmraid.setlist()
+	if len (sets) > 0:
+	    for set in sets:
+		dict["mapper/" + set] = "DMRAID"
+
     # this is kind of ugly, but it's much easier to do this from python
     for (dev, descr) in dict.items():
         # the only raid devs like this are ide, so only worry about
them
@@ -391,14 +406,28 @@
 
 def makeDevInode(name, fn=None):
     if fn:
-        _isys.mkdevinode(name, fn)
-        return fn
+        if name[:7] == "mapper/":
+            try:
+                os.makedirs(os.path.dirname(fn))
+            except:
+                pass
+            os.symlink("/dev/" + name, fn)
+        else:
+            _isys.mkdevinode(name, fn)
+            return fn
     path = '/dev/%s' % (name,)
     try:
         os.stat(path)
     except OSError:
         path = '/tmp/%s' % (name,)
-        _isys.mkdevinode(name, path)
+        if name[:7] == "mapper/":
+            try:
+                os.makedirs(os.path.dirname(path))
+            except:
+                pass
+            os.symlink("/dev/" + name, path)
+        else:
+            _isys.mkdevinode(name, path)
     return path
 
 def makedev(major, minor):
@@ -674,9 +703,12 @@
         os.unlink("/tmp/cdrom")
 
 def driveIsRemovable(device):
+    # DMRaid is always non-removable
     # assume ide if starts with 'hd', and we don't have to create
     # device beforehand since it just reads /proc/ide
-    if device[:2] == "hd":
+    if device[:7] == "mapper/":
+        rc = 0
+    elif device[:2] == "hd":
         rc = (_isys.isIdeRemovable("/dev/"+device) == 1)
     else:
         makeDevInode(device, "/tmp/disk")
diff -ruN mnt/usr/lib/anaconda/mknod-stub
new/usr/lib/anaconda/mknod-stub
--- mnt/usr/lib/anaconda/mknod-stub	1970-01-01 01:00:00.000000000
+0100
+++ new/usr/lib/anaconda/mknod-stub	2004-10-10 21:06:58.000000000
+0200
@@ -25,8 +25,9 @@
         # inode
         while (drive.find('/') != -1):
             if (drive.startswith("cciss") or drive.startswith("ida") or
-                drive.startswith("rd") or drive.startswith("ataraid")
-                or drive.startswith("iseries") or
drive.startswith("i2o")):
+                drive.startswith("rd") or drive.startswith("ataraid")
or
+                drive.startswith("mapper") or
drive.startswith("iseries") or 
+                drive.startswith("i2o")):
                 break
             drive = drive[drive.find('/') + 1:]
         isys.makeDevInode(drive, path)
diff -ruN mnt/usr/lib/anaconda/partedUtils.py
new/usr/lib/anaconda/partedUtils.py
--- mnt/usr/lib/anaconda/partedUtils.py	1970-01-01 01:00:00.000000000
+0100
+++ new/usr/lib/anaconda/partedUtils.py	2004-10-10 21:06:58.000000000
+0200
@@ -117,6 +117,9 @@
         or partition.geom.dev.type == parted.DEVICE_CPQARRAY):
         return "%sp%d" % (partition.geom.dev.path[5:],
                           partition.num)
+    elif partition.geom.dev.path[5:12] == "mapper/":
+        return "%s_p%d" % (partition.geom.dev.path[5:],
+                          partition.num)
     return "%s%d" % (partition.geom.dev.path[5:],
                      partition.num)
 
diff -ruN mnt/usr/lib/anaconda/raid.py new/usr/lib/anaconda/raid.py
--- mnt/usr/lib/anaconda/raid.py	1970-01-01 01:00:00.000000000
+0100
+++ new/usr/lib/anaconda/raid.py	2004-10-10 21:06:58.000000000
+0200
@@ -38,6 +38,9 @@
     raidDevices = {}
 
     for d in drives:
+	# Assume dmraid is not part of a md raidset
+	if d[:7] == "mapper/":
+	    continue
         parts = []
 	isys.makeDevInode(d, "/tmp/" + d)
         try:




More information about the Ataraid-list mailing list