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

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

 



Joel Andres Granados wrote:
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.

------------------------------------------------------------------------

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
Here is the new stuff :)

I'm specially worried about the following piece of code :

<snip>
       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

</snip>

The way that the size is handled here is somewhat hacky, to say the least :). What I want to accomplish with this way of handling things is to inform the rest of the LVM stuff that this mirrored LVM will take N*(size)
of space in the LVM system.  N being the number of areas in the mirror.
Comments greatly appreciated. :)

--
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	31 Aug 2007 13:17:17 -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, MirroredLogicalVolumeDevice):
+                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):
@@ -2194,6 +2204,28 @@
         return
             
     
+class MirroredLogicalVolumeDevice(LogicalVolumeDevice):
+    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.
+        """
+        LogicalVolumeDevice.__init__(self,vgname, size, lvname, vg, existing=existing)
+        self.mirrors = mirrors #If mirrors is set to 0 mirroring is ignored.
+        self.devs = devs
+        self.corelog = corelog
+
+    def setupDevice(self, chroot="/", devPrefix='/tmp', vgdevice = None):
+        if not self.isSetup:
+            lvm.mirroredlvcreate(self.name, self.vgname, self.size, mirrors=self.mirrors, corelog=self.corelog, devs=self.devs)
+            self.isSetup = 1
+
+            if vgdevice and vgdevice.isNetdev():
+                self.setAsNetdev()
+
+        return "/dev/%s" % (self.getDevice(),)
+
 class PartitionDevice(Device):
     def __init__(self, partition):
         Device.__init__(self)
Index: kickstart.py
===================================================================
RCS file: /usr/local/CVS/anaconda/kickstart.py,v
retrieving revision 1.386
diff -u -r1.386 kickstart.py
--- kickstart.py	27 Aug 2007 20:15:55 -0000	1.386
+++ kickstart.py	31 Aug 2007 13:17:17 -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,46 @@
         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 +734,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	31 Aug 2007 13:17:17 -0000
@@ -179,6 +179,31 @@
         raise LVCreateError(vgname, lvname, size)
     unlinkConf()
 
+def mirroredlvcreate(lvname, vgname, size, mirrors=0, corelog=True, devs=[]):
+    """Creates mirrored 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:
+        return
+    writeForceConf()
+    vgscan()
+
+    args = ["lvcreate", "-v", "-L", "%dM" %(size,), "-m", "%s"%mirrors]+\
+            (corelog and ["--corelog"] or [])+["-n", lvname, "-An", vgname]
+    try:
+        rc = lvmExec(*args)
+    except:
+        rc = 1
+    if rc:
+        raise LVCreateError(vgname, lvname, size)
+    unlinkConf()
+
 def lvremove(lvname, vgname):
     """Removes a logical volume.
 
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	31 Aug 2007 13:17:17 -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, "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.MirroredLogicalVolumeDevice(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.
+                #Change 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	31 Aug 2007 13:17:17 -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 []:
diff -ur --exclude=partition.py pykickstart-1.8/pykickstart/commands/logvol.py pykickstart-1.8-Mirroring/pykickstart/commands/logvol.py
--- 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-31 15:04:41.000000000 +0200
@@ -89,6 +89,30 @@
 
         return retval + "\n"
 
+class F8_LogVolData(FC4_LogVolData):
+    def __init__(self, bytesPerInode=4096, fsopts="", fstype="", grow=False,
+                 maxSizeMB=0, name="", format=True, percent=0,
+                 recommended=False, size=None, preexist=False, vgname="",
+                 mountpoint="", mirrors=0, devs=[], nocorelog=True):
+        FC4_LogVolData.__init__(self, bytesPerInode=bytesPerInode, fsopts=fsopts, fstype=fstype, grow=grow,
+                        maxSizeMB=maxSizeMB, name=name, format=format, percent=percent, recommended=recommended,
+                        size=size, preexist=preexist, vgname=vgname, mountpoint=mountpoint)
+        self.mirrors = mirrors
+        self.devs = devs
+        self.nocorelog = nocorelog
+
+    def __str__(self):
+        retval = FC4_LogVolData.__str__(self).strip()
+
+        if self.mirrors > 0:
+            retval += " --mirrors=%d" % self.mirrors
+        if self.nocorelog:
+            retval += " --nocorelog"
+        if self.devs > 0:
+            retval += " --devs=%s"%",".join(self.devs)
+
+        return retval + "\n"
+
 class FC3_LogVol(KickstartCommand):
     def __init__(self, writePriority=132, lvList=None):
         KickstartCommand.__init__(self, writePriority)
@@ -183,3 +207,54 @@
         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("--nocorelog", dest="nocorelog",  action="store_true", default=False)
+
+        (opts, extra) = op.parse_args(args=args)
+
+        if len(extra) == 0:
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Mount point required for %s") % "logvol")
+
+        lvd = F8_LogVolData()
+        self._setToObj(op, opts, lvd)
+        lvd.mountpoint=extra[0]
+        lvd.corelog = not lvd.nocorelog
+        self.add(lvd)
diff -ur --exclude=partition.py pykickstart-1.8/pykickstart/handlers/control.py pykickstart-1.8-Mirroring/pykickstart/handlers/control.py
--- pykickstart-1.8/pykickstart/handlers/control.py	2007-08-09 20:51:38.000000000 +0200
+++ pykickstart-1.8-Mirroring/pykickstart/handlers/control.py	2007-08-31 14:00:07.000000000 +0200
@@ -321,7 +321,7 @@
         "keyboard": keyboard.FC3_Keyboard,
         "lang": lang.FC3_Lang,
         "logging": logging.FC6_Logging,
-        "logvol": logvol.FC4_LogVol,
+        "logvol": logvol.F8_LogVol,
         "mediacheck": mediacheck.FC4_MediaCheck,
         "monitor": monitor.FC6_Monitor,
         "multipath": multipath.FC6_MultiPath,

[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