[Patch] Adding mirroring in anaconda installer. (kickstart)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi list:

Anybody interested in testing my take on mirroring for anaconda installer is more than welcome to take a big wack at this path. I will attach the updates images Im using for testing
is at http://jgranado.fedorapeople.org/updates.img.  I tested against f8t1.
comments greatly appreciated :)
Regards.

--
Joel Andres Granados

Index: fsset.py
===================================================================
RCS file: /usr/local/CVS/anaconda/fsset.py,v
retrieving revision 1.334
diff -u -r1.334 fsset.py
--- fsset.py	17 Aug 2007 14:20:44 -0000	1.334
+++ fsset.py	27 Aug 2007 18:18:05 -0000
@@ -1505,7 +1505,17 @@
                 vgs[entry.device.name] = entry.device
 
         # then set up the logical volumes
+        nonLVMirrors = []
         for entry in self.entries:
+            #We should do the mirrored stuff first :)
+            if isinstance(entry.device, LogicalVolumeDevice) and entry.device.mirrors > 0:
+                vg = None
+                if vgs.has_key(entry.device.vgname):
+                    vg = vgs[entry.device.vgname]
+                entry.device.setupDevice(chroot, vgdevice = vg)
+            else:
+                nonLVMirrors.append(entry)
+        for nonMirrors in nonLVMirrors:
             if isinstance(entry.device, LogicalVolumeDevice):
                 vg = None
                 if vgs.has_key(entry.device.vgname):
@@ -2160,7 +2170,12 @@
 
 class LogicalVolumeDevice(Device):
     # note that size is in megabytes!
-    def __init__(self, vgname, size, lvname, vg, existing = 0):
+    def __init__(self, vgname, size, lvname, vg, existing = 0, mirrors = 0, devs = [], corelog = True):
+        """
+        mirrors - The number of mirrors.
+        devs - Specific devices to use for mirrors.
+        corelog - Wether to use corelog or not.
+        """
         Device.__init__(self)
         self.vgname = vgname
         self.size = size
@@ -2169,6 +2184,9 @@
         self.isSetup = existing
         self.doLabel = None
         self.vg = vg
+        self.mirrors = mirrors #If mirrors is set to 0 mirroring is ignored.
+        self.devs = devs
+        self.corelog = corelog
 
         # these are attributes we might want to expose.  or maybe not.
         # self.chunksize
@@ -2179,7 +2197,7 @@
 
     def setupDevice(self, chroot="/", devPrefix='/tmp', vgdevice = None):
         if not self.isSetup:
-            lvm.lvcreate(self.name, self.vgname, self.size)
+            lvm.lvcreate(self.name, self.vgname, self.size, mirrors=self.mirrors, corelog=self.corelog, devs=self.devs)
             self.isSetup = 1
 
             if vgdevice and vgdevice.isNetdev():
Index: kickstart.py
===================================================================
RCS file: /usr/local/CVS/anaconda/kickstart.py,v
retrieving revision 1.385
diff -u -r1.385 kickstart.py
--- kickstart.py	23 Aug 2007 19:38:51 -0000	1.385
+++ kickstart.py	27 Aug 2007 18:18:05 -0000
@@ -217,9 +217,9 @@
         self.handler.id.instClass.setLanguage(self.handler.id, self.lang)
         self.handler.skipSteps.append("language")
 
-class LogVol(commands.logvol.FC4_LogVol):
+class LogVol(commands.logvol.F8_LogVol):
     def parse(self, args):
-        commands.logvol.FC4_LogVol.parse(self, args)
+        commands.logvol.F8_LogVol.parse(self, args)
 
         lvd = self.lvList[-1]
 
@@ -264,7 +264,47 @@
         elif (lvd.percent <= 0 or lvd.percent > 100) and not lvd.preexist:
             raise KickstartValueError, formatErrorMsg(self.lineno, msg="Percentage must be between 0 and 100")
 
-        request = partRequests.LogicalVolumeRequestSpec(filesystem,
+        if lvd.mirrors > 0:# sanity checks for the mirror stuff.
+            if lvd.devs == []:
+                raise KickstartValueError, formatErrorMsg(self.lineno, \
+                        msg="When specifying a mirrored logical volume you must provide a list of devices.")
+            # For now we will ask the user to use only the minimum number of devices.
+            if lvd.corelog and len(lvd.devs) != lvd.mirrors+1:
+                raise KickstartValueError, formatErrorMsg(self.lineno, \
+                        msg="When mirroring with corelog the number of devices must be equal to the number of mirrors plus one. (devs=mirrors+1)")
+            if not lvd.corelog and len(lvd.devs) != lvd.mirrors+2:
+                raise KickstartValueError, formatErrorMsg(self.lineno, \
+                        msg="When mirroring without corelog the number of devices must be equal to the number of mirrors plus two. (devs=mirrors+2)")
+            #The calculations based on percentages will not apply to mirrored logical volumes for now.
+            if lvd.percent:
+                raise KickstartValueError, formatErrorMsg(self.lineno, \
+                        msg="When creating a logical volume use the --size option instead of the --percent.")
+            # get the unique ids of each of the physical volumes
+            pvs=[]
+            for pv in lvd.devs:
+                if pv not in self.handler.ksPVMapping.keys():
+                    raise KickstartValueError, formatErrorMsg(self.lineno, \
+                            msg="Tried to use undefined partition %s in Volume Group specification" % pv)
+                pvs.append(self.handler.ksPVMapping[pv])
+
+            request = partRequests.MirroredLogicalVolumeRequestSpec(filesystem,
+                                      format = lvd.format,
+                                      mountpoint = lvd.mountpoint,
+                                      size = lvd.size,
+                                      percent = lvd.percent,
+                                      volgroup = vgid,
+                                      lvname = lvd.name,
+                                      grow = lvd.grow,
+                                      maxSizeMB = lvd.maxSizeMB,
+                                      preexist = lvd.preexist,
+                                      bytesPerInode = lvd.bytesPerInode,
+                                      mirrors = lvd.mirrors,
+                                      corelog = lvd.corelog,
+                                      devs = pvs)
+
+
+        else:
+            request = partRequests.LogicalVolumeRequestSpec(filesystem,
                                       format = lvd.format,
                                       mountpoint = lvd.mountpoint,
                                       size = lvd.size,
@@ -695,7 +735,7 @@
         "poweroff": Reboot,
         "raid": Raid,
         "reboot": Reboot,
-        "repo": commands.repo.F8_Repo,
+        "repo": commands.repo.FC6_Repo,
         "rootpw": RootPw,
         "selinux": SELinux,
         "services": commands.services.FC6_Services,
Index: lvm.py
===================================================================
RCS file: /usr/local/CVS/anaconda/lvm.py,v
retrieving revision 1.48
diff -u -r1.48 lvm.py
--- lvm.py	21 May 2007 14:30:19 -0000	1.48
+++ lvm.py	27 Aug 2007 18:18:05 -0000
@@ -157,12 +157,15 @@
         log.error("running vgchange failed: %s" %(rc,))
 #        lvmDevicePresent = 0
 
-def lvcreate(lvname, vgname, size):
+def lvcreate(lvname, vgname, size, mirrors=0, corelog=True, devs=[]):
     """Creates a new logical volume.
 
     lvname - name of logical volume to create.
     vgname - name of volume group lv will be in.
     size - size of lv, in megabytes.
+    mirrors - the amount of mirrors to create
+    devs - a list of string representing valid devices of the form "/dev/deviceName
+    corelog - whether or not to use corelog.
     """
     global lvmDevicePresent
     if flags.test or lvmDevicePresent == 0:
@@ -171,6 +174,8 @@
     vgscan()
 
     args = ["lvcreate", "-v", "-L", "%dM" %(size,), "-n", lvname, "-An", vgname]
+    if mirrors > 0:
+        args = args[:4]+["-m","%s"%mirrors, corelog and "--corelog"]+args[4:]+devs
     try:
         rc = lvmExec(*args)
     except:
Index: partRequests.py
===================================================================
RCS file: /usr/local/CVS/anaconda/partRequests.py,v
retrieving revision 1.74
diff -u -r1.74 partRequests.py
--- partRequests.py	3 Aug 2007 19:32:24 -0000	1.74
+++ partRequests.py	27 Aug 2007 18:18:05 -0000
@@ -930,3 +930,84 @@
                      "group's physical extent size.")
 
         return RequestSpec.sanityCheckRequest(self, partitions, skipMntPtExistCheck)
+
+class MirroredLogicalVolumeRequestSpec(LogicalVolumeRequestSpec):
+    def __init__(self,fstype, format = None, mountpoint = None, size = None, volgroup = None,
+            lvname = None, preexist = 0, percent = None, grow=0, maxSizeMB=0, bytesPerInode = 4096,
+            fslabel = None, mirrors=1, corelog=True, devs=[]):
+        """
+        mirrors - This is the total amount of mirrors.  Not counting the main device.
+        corelog - If corelog was chosen or not.
+        devs - The list of devices that hold the mirrors and the main device
+
+        The lvm2 cml does not make the relation of each device with each logical volume, we are not
+        going to handle that relation either.
+        """
+        self.mirrors = mirrors
+        self.corelog = corelog
+        self.devs = devs
+        #This is the size of each side.  All sides have the same size.
+        self.mirroredSize = size
+        self.mirroredRequestSize = size
+        #This is what the rest of the code has to consider as size.  
+        #This is done so other lvs can be installed with the mirrored lv.
+        #FIXME: We don't consider the space that the log ocupies, it might be a problem!
+        #Be aware that the requestSize will also be the "totalSize".
+        #self.totalMirroredLVSize = self.mirroredSize * (self.mirrors + 1)
+
+        LogicalVolumeRequestSpec.__init__(self, fstype, format=format, mountpoint=mountpoint,
+             size=self.mirroredSize * (self.mirrors + 1), volgroup=volgroup, lvname=lvname, preexist=preexist,
+             percent=percent, grow=grow, maxSizeMB=maxSizeMB, bytesPerInode=bytesPerInode, fslabel=fslabel)
+
+        self.requestSize = self.mirroredSize
+
+    def __str__(self):
+        devices = ""
+        for dev in self.devs:
+            devices = "%s,%s"%(devices, dev)
+        devices = devices.strip(",")
+        str = (" %(lvstr)s \n"
+                " mirrors: %(mirrors) devices: %(devices)s corelog: %(corelog)s" %
+              { "lvstr": LogicalVolumeRequestSpec.__str__(self), "mirrors":self.mirrors, 
+                  "devices":devices, "corelog":self.corelog})
+        return str
+
+    def setSize(self, size):
+        # We will not allow size change for now.
+        raise RuntimeError, "Somehow the size of the mirrored lv was going to be changed.  This is not possible for now."
+
+
+    def getDevice(self, partitions):
+        """Return a device which can be solidified."""
+        devices = []
+        for dev in self.devs:
+            devices.append("/dev/%s"%partitions.getRequestByID(dev).device)
+        vg = partitions.getRequestByID(self.volumeGroup)
+        vgname = vg.volumeGroupName
+        self.dev = fsset.LogicalVolumeDevice(vgname, self.mirroredSize,
+                                             self.logicalVolumeName,
+                                             vg = vg,
+                                             existing = self.preexist,
+                                             mirrors=self.mirrors,
+                                             corelog=self.corelog,
+                                             devs=devices)
+        return self.dev
+
+    def sanityCheckMirroredRequest(self, partitions, diskset):
+        peSize = partitions.getRequestByID(self.volumeGroup).pesize
+        #We mainly check that the size stuff is ok.
+        for dev in self.devs:
+            devReq = partitions.getRequestByID(dev)
+            actualSize = devReq.getActualSize(partitions, diskset)
+            if devReq.grow and actualSize < self.mirroredSize:
+                # After the devices grew, it was still insuficient space to hold the lv.
+                return _("After growing one of the Physical Volumes it was still insuficient "
+                        "to hold %s Mirrored Logical Volume." % self.logicalVolumeName)
+            if not devReq.grow and devReq.requestSize < self.mirroredRequestSize:
+                # Must be a mistake in the ksfile
+                return _("All Physical Volumes must be greater than or equal to the size of "
+                        "the mirrored Logical Volume that will contain them.")
+            if not devReq.grow and lvm.clampPVSize(actualSize,peSize) < self.mirroredSize and devReq.requestSize >= actualSize:
+                #This basically means that the actual size of the pv was rounded up.
+                #Canget the self.mirroredSize and continue
+                self.mirroredSize = lvm.clampPVSize(actualSize,peSize)
Index: partitions.py
===================================================================
RCS file: /usr/local/CVS/anaconda/partitions.py,v
retrieving revision 1.108
diff -u -r1.108 partitions.py
--- partitions.py	23 Aug 2007 14:58:15 -0000	1.108
+++ partitions.py	27 Aug 2007 18:18:05 -0000
@@ -957,6 +957,10 @@
                     rc = request.sanityCheckRaid(self)
                     if rc:
                         errors.append(rc)
+            if isinstance(request, partRequests.MirroredLogicalVolumeRequestSpec):
+                rc = request.sanityCheckMirroredRequest(self, diskset)
+                if rc:
+                    errors.append(rc)
             if not hasattr(request,'drive'):
                 continue
             for x in request.drive or []:
--- pykickstart-1.8/pykickstart/commands/logvol.py	2007-08-09 20:51:38.000000000 +0200
+++ pykickstart-1.8-Mirroring/pykickstart/commands/logvol.py	2007-08-24 18:15:11.000000000 +0200
@@ -183,3 +183,53 @@
         self._setToObj(op, opts, lvd)
         lvd.mountpoint=extra[0]
         self.add(lvd)
+
+class F8_LogVol(FC4_LogVol):
+    def __init__(self, writePriority=132, lvList=None):
+        FC4_LogVol.__init__(self, writePriority, lvList)
+
+    def parse(self, args):
+        def lv_cb (option, opt_str, value, parser):
+            parser.values.format = False
+            parser.values.preexist = True
+
+        def dev_cb (option, opt_str, value, parser):
+            for d in value.split(','):
+                parser.values.ensure_value(option.dest, []).append(d)
+
+        op = KSOptionParser(lineno=self.lineno)
+        op.add_option("--bytes-per-inode", dest="bytesPerInode", action="store",
+                      type="int", nargs=1)
+        op.add_option("--fsoptions", dest="fsopts")
+        op.add_option("--fstype", dest="fstype")
+        op.add_option("--grow", dest="grow", action="store_true",
+                      default=False)
+        op.add_option("--maxsize", dest="maxSizeMB", action="store", type="int",
+                      nargs=1)
+        op.add_option("--name", dest="name", required=1)
+        op.add_option("--noformat", action="callback", callback=lv_cb,
+                      dest="format", default=True, nargs=0)
+        op.add_option("--percent", dest="percent", action="store", type="int",
+                      nargs=1)
+        op.add_option("--recommended", dest="recommended", action="store_true",
+                      default=False)
+        op.add_option("--size", dest="size", action="store", type="int",
+                      nargs=1)
+        op.add_option("--useexisting", dest="preexist", action="store_true",
+                      default=False)
+        op.add_option("--vgname", dest="vgname", required=1)
+        op.add_option("--mirrors", "-m", dest="mirrors", type="int", action="store",
+                      nargs=1, default=0)
+        op.add_option("--devs", dest="devs", type="string", action="callback",
+                      callback=dev_cb, nargs=1, default=[])
+        op.add_option("--corelog", dest="corelog",  action="store_true", default=True)
+
+        (opts, extra) = op.parse_args(args=args)
+
+        if len(extra) == 0:
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Mount point required for %s") % "logvol")
+
+        lvd = FC4_LogVolData()
+        self._setToObj(op, opts, lvd)
+        lvd.mountpoint=extra[0]
+        self.add(lvd)

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux