Geoffroy,

Here is the latest version of my patch for IA.pm against 
systeminstaller-oscar-2.4.8-1 rpm
It adds full support for GPT partition table in *.disk files (label_type=gpt in 
the header of *.disk file)
It works with /dev/hd* /dev/sd* and /dev/cciss/c#d#p# partition naming scheme.
It adds more checks for bad msdos partitions layout.

I've successfully tested so far the following configurations:
- ide.disk, scsi.disk, cciss.disk with and without label_type=gpt
- *.disk with:
        - 4 primary and at least one logical partitions (hda1 hda2 hda3 hda4 
and hda5 => not possible: correctly detected)
        - 4 primary with no logical or extended => works
        - extended partitions in non ascending order (hda6 hda5 hda7) => 
created in correct order with correct parameters
        - extended partitions that are not contiguous (hda5 hda7, no hda6) => 
correctly detected => die
        - more than one partition with size set to "*"

One potential problem that is remaining, but not related to oscar: case were 
hda6 size=* and hda7 size=512. i think that si_mkautoinstallscript from 
systeminstaller may be not enough sophisticated to handle size(hda6) = 
freespace(disk)-size(hda7) [I may be  wrong on that point]
(hda7 cannot be created before hda6 as it is an extended partition).

Regards,

Olivier.

Le samedi 28 novembre 2009 00:21:12, vous avez écrit :
> Olivier,
> 
> The idea is very interesting, can you tell me which cases you actually tested 
> (at least CCISS i guess)? I do not have the time to do any testing right now 
> so i just want to know what is the actually status of the patch before to 
> check in it (i hope it is ok with you).
> 
> Thanks,
> 
> ----- "Olivier LAHAYE" <olivier.lah...@cea.fr> a écrit :
> 
> > Hi,
> > 
> > I've modified IA.pm from systeminstaller-oscar-2.4.8-1 to as support
> > for GPT partition tables and fix CCISS HP Raid Array as well.
> > 
> > After a few tests, it seems that it works realy well.:-)
> > 
> > As I'm a perl newbee, there is a strangeness that I don't understand,
> > it seems that the 3 last parameters recieved by do_partition are
> > references. Thus I need to address them using $$, and I don't
> > understand why, aside that, every thing seems good.
> > 
> > Regards,
> > 
> 

-- 
        Olivier LAHAYE
        CEA Saclay
        DRT-LIST-DETECS-SSTM
--- /usr/lib/systeminstaller/SystemInstaller/Partition/IA.pm.orig	2009-11-25 17:24:28.000000000 +0100
+++ /usr/lib/systeminstaller/SystemInstaller/Partition/IA.pm	2009-11-30 14:02:51.000000000 +0100
@@ -99,16 +99,38 @@
     return $flags;
 }
 
-sub get_extended_partition_id ($) {
-    my $disk = @_;
-
+# Bad work around to handle /dev/ccis/c#d#p# (handle the "p")
+sub get_partition_device ($$) {
+    my ($disk, $partnum) = @_;
     if ($disk =~ /\/dev\/cciss\/c[0-9]+d[0-9][0-9]*$/) {
-        return "p5";
+        return $disk."p".$partnum;
     } else {
-        return "5";
+        return $disk.$partnum;
     }
 }
-
+# Create <part= tag.
+# pnum: partition numer
+# psize: partition size (string) or "\*"
+# ptype: eiter "primary", "logical" "extended" or "41"
+# pflag: flags
+sub do_partition ($$$$) {
+	my ($pnum, $psize, $ptype, $pflags) = @_ ;
+	my $pid;
+	if ($$ptype eq "41") {
+		$pid = 41;
+		$ptype = "primary";
+	}
+	print AICONF "\t\t<part num=\"$pnum\" ";
+	print AICONF "size=\"$$psize\" ";
+	print AICONF "p_type=\"$$ptype\" ";
+	if($pid == 41) {
+		print AICONF "id=\"41\"";
+	}
+	if(defined($$pflags) && !($$pflags eq "")) {
+	        print AICONF "flags=\"$$pflags\" ";
+	}
+        print AICONF "/>\n";
+}
 
 # Create an autoinstallscript.conf file to be used
 # be used by SystemImager's mkautoinstallscript.
@@ -154,53 +176,85 @@
         print AICONF "\t<disk dev=\"$disk\" ";
         print AICONF "label_type=\"$DISKS{LABEL_TYPE}\" ";
         print AICONF "unit_of_measurement=\"$DISKS{UNITS}\">\n";
-        my $extparcreated=0;
-        my $extpartid = get_extended_partition_id ($disk);
-        # First do the primary partitions
-        # TODO: This will not work with gpt partitions.
-        foreach my $parnum (1..4) {
-            my $parname=$disk.$parnum;
-            if (defined $DISKS{PARTITIONS}{$parname}) {
-                print AICONF "\t\t<part num=\"$DISKS{PARTITIONS}{$parname}{PNUM}\" ";
-                print AICONF "size=\"$DISKS{PARTITIONS}{$parname}{SIZE}\" ";
-                if ($DISKS{PARTITIONS}{$parname}{TYPE} == 5) {
-                    print AICONF "p_type=\"extended\" ";
-                    $extparcreated++;
-                } else {
-                    print AICONF "p_type=\"primary\" ";
-                }
-                if ($DISKS{PARTITIONS}{$parname}{TYPE} == 41) {
-                    print AICONF "id=\"$DISKS{PARTITIONS}{$parname}{TYPE}\" ";
-                }
-                $flags = get_partition_flags ($parname, %DISKS);
-                if ($flags) {
-                    print AICONF "flags=\"$flags\" ";
-                }
-                print AICONF "/>\n";
-            } elsif ((! $extparcreated ) 
-                    && (defined $DISKS{PARTITIONS}{$disk.$extpartid}) ){
-                print AICONF "\t\t<part num=\"$parnum\" size=\"\*\" ";
-                print AICONF "p_type=\"extended\" ";
-                print AICONF "/>\n";
-                $extparcreated++;
-            }
-        }
-        # Now the logical partitions
-        foreach my $parname (@{$DISKS{DRIVES}{$disk}}) {
-            if ($DISKS{PARTITIONS}{$parname}{PNUM} > 4) {
-                print AICONF "\t\t<part num=\"$DISKS{PARTITIONS}{$parname}{PNUM}\" ";
-                print AICONF "size=\"$DISKS{PARTITIONS}{$parname}{SIZE}\" ";
-                print AICONF "p_type=\"logical\" ";
-                $flags = get_partition_flags ($parname, %DISKS);
-                if ($flags) {
-                    print AICONF "flags=\"$flags\" ";
-                }
-                print AICONF "/>\n";
-            }
-        }
-        print AICONF "\t</disk>\n";
-    }
+	my $has_logicals = 0;
+	my $extended_part_num;
+	my $highest_logical = 0;
+	# 1st, check for incompatible layouts if we use msdos partition table.
+        if ($DISKS{LABEL_TYPE} eq "msdos")
+	{
+	    my $primary_count = 0;
+	    # Cycle thru partitions,; count primaries and see if we have logicals
+	    foreach my $partname ( @{$DISKS{DRIVES}{$disk}} ) {
+	        if ($DISKS{PARTITIONS}{$partname}{PNUM} > 4) {
+		    $has_logicals++;
+		    if ( $DISKS{PARTITIONS}{$partname}{PNUM} > $highest_logical) {
+			$highest_logical = $DISKS{PARTITIONS}{$partname}{PNUM};
+		    }
+		} else {
+		    $primary_count++;
+		}
+	    }
 
+	    # Check if we have room for extended partition (if required)
+	    if ($has_logicals > 0) {
+		    # check 4 primary + extended impossible layout.
+		    if ($primary_count == 4) {
+			carp "ERROR: $DISKS{FILENAME} layout incompatible with label_type=msdos. Use gpt or use less primary partitions"; 
+        		return 1;
+		    }
+		    # Check that all logical partitions are contiguous or die.
+		    if ($highest_logical != ($has_logicals + 4)) {
+			carp "ERROR: $DISKS{FILENAME} layout incompatible with label_type=msdos. Logical partitions (Part id > 4) must be contiguous";
+			return 1;
+		    }
+		    # Determine which partition device name is available for extended partition (if required)
+		    # cycle thru ids 1 to 4 and see if a slot is available.
+		    foreach my $parnum (1..4) {
+			my $partname = get_partition_device ($disk,$parnum);
+			if (! defined ($DISKS{PARTITIONS}{$partname})) { # We found a slot
+			    $extended_part_num = $parnum ;
+			    last ;
+			}
+		    }
+	    }
+	} elsif (scalar @{$DISKS{DRIVES}{$disk}} > 128) { # Handle non probable case that could become probable in a long long future ;-)
+		carp "ERROR: $DISKS{FILENAME} layout incompatible with label_type=$DISKS{LABEL_TYPE}: partition count exceeded: max = 128 (gpt)";
+		return 1;
+	}
+
+	# Do all partitions at once. Be carefull when PNUM becomes > 4
+	my $partition_type;
+	my $size_star = 0;
+	foreach my $parname ( sort @{$DISKS{DRIVES}{$disk}} ) {
+	    if (($DISKS{LABEL_TYPE} eq "msdos") && $DISKS{PARTITIONS}{$parname}{PNUM} > 4) {
+		# on msdos partition table, if pnum >4 we need to be carefull
+		if (defined($extended_part_num)) {
+		    # We need to create $extended_part_num (not yet created)
+		    do_partition ( $extended_part_num,\
+				   "\*",\
+				   "extended",\
+				   undef );
+		    undef $extended_part_num; # Done, we won't go here again.
+		}
+		$partition_type = "logical" ; # msdos & PNUM > 4
+	    } else {
+	        $partition_type = "primary" ; # PNUM <= 4 or not msdos
+	    }
+            if ("$DISKS{PARTITIONS}{$parname}{SIZE}" eq "\*") {
+		$size_star++;
+	    }
+	    if ($size_star > 1) {
+		carp "ERROR: $DISKS{FILENAME} layout problem: You cannot have more than one partition size set to \"\*\"";
+		return 1;
+	    }
+	    $flags = get_partition_flags ($parname, %DISKS);
+	    do_partition ( $DISKS{PARTITIONS}{$parname}{PNUM},\
+			   $DISKS{PARTITIONS}{$parname}{SIZE},\
+			   $partition_type,\
+			   $flags );
+    	}
+        print AICONF "\t</disk>\n";
+    } # end foreach $disk
     # Write RAID structures - EF -
     for my $rlevel ("0", "1", "5", "6") {
         my $rraid = "RAID$rlevel";
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Oscar-devel mailing list
Oscar-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oscar-devel

Reply via email to