Hi,

The attached patch (code only) adds support for external log devices for
XFS and ext3/4 to setup-storage.

External log devices can improve performance a lot when they reside on a
different physical device than the filesystem itself.

Due to the way mkfs commands are ordered in setup-storage, the commands
fire as soon as possible, so the mkfs command can run before all the
physical devices have been partitioned, make it impossible to just use
createargs to enable an external log device.

There are two approaches to this issue:
 - delay all mkfs commands until all the devices have been set up
   (physical devices, RAID, LVM, cryptsetup ...)
 - integrate external journals into setup-storage

I went with the latter because the former requires more profound changes
in setup-storage and I think it's not worth it/better this way.

If the patch is accepted, I'll resend a patch including documentation.

Config example:

disk_config /dev/sda fstabkey:uuid
primary    -         256    ext3_journal              -
primary    -         256    ext4_journal              -
primary    -         256    xfs_journal               -
logical    /        2000    ext4:journal=/dev/sda2    defaults
logical    /home    2000    xfs:journal=/dev/sda3     defaults

disk_config /dev/sdb fstabkey:uuid
primary    /foo      10-    ext3:journal=/dev/sda1    defaults


Thoughts?

JB.

-- 
 Julien BLACHE <[email protected]>  |  Debian, because code matters more 
 Debian & GNU/Linux Developer        |       <http://www.debian.org>
 Public key available on <http://www.jblache.org> - KeyID: F5D6 5169 
 GPG Fingerprint : 935A 79F1 C8B3 3521 FD62 7CC7 CD61 4FD7 F5D6 5169 

diff -ru a/lib/setup-storage/Commands.pm b/lib/setup-storage/Commands.pm
--- a/lib/setup-storage/Commands.pm	2010-04-05 14:39:33.000000000 +0200
+++ b/lib/setup-storage/Commands.pm	2010-05-10 11:17:42.000000000 +0200
@@ -54,6 +54,7 @@
   defined ($partition->{filesystem})
     or &FAI::internal_error("filesystem is undefined");
   my $fs = $partition->{filesystem};
+  my $journal = $partition->{journal_dev};
 
   return if ($fs eq "-");
 
@@ -66,13 +67,45 @@
   print "$partition->{mountpoint} FS create_options: $create_options\n" if ($FAI::debug && $create_options);
   print "$partition->{mountpoint} FS tune_options: $tune_options\n" if ($FAI::debug && $tune_options);
 
-  # create the file system with options
-  my $create_tool = "mkfs.$fs";
-  ($fs eq "swap") and $create_tool = "mkswap";
-  ($fs eq "xfs") and $create_options = "$create_options -f" unless ($create_options =~ m/-f/);
-  ($fs eq "reiserfs") and $create_options = "$create_options -q" unless ($create_options =~ m/-(f|q|y)/);
-  &FAI::push_command( "$create_tool $create_options $device", "exist_$device",
-    "has_fs_$device" );
+  my $prereqs = "exist_$device";
+  my $provides;
+  my $create_tool;
+
+  # create filesystem journal
+  if ($fs =~ m/.*_journal$/) {
+      $provides = "journal_preped_$device";
+      undef($tune_options);
+
+      if ($fs =~ /ext[34]_journal/) {
+	  $create_tool = "mke2fs";
+	  $create_options = "-O journal_dev";
+      } elsif ($fs eq "xfs_journal") {
+	  $create_tool = "/bin/true";
+	  $create_options = "";
+      } else {
+	  &FAI::internal_error("unsupported journal type $fs");
+      }
+  } else {
+      # create regular filesystem
+      $provides = "has_fs_$device";
+      $create_tool = "mkfs.$fs";
+
+      ($fs eq "swap") and $create_tool = "mkswap";
+      ($fs eq "xfs") and $create_options = "$create_options -f" unless ($create_options =~ m/-f/);
+      ($fs eq "reiserfs") and $create_options = "$create_options -q" unless ($create_options =~ m/-(f|q|y)/);
+
+      # adjust options for filesystem with external journal
+      if (defined($journal)) {
+	  $journal =~ s/^journal=//;
+	  $prereqs = "$prereqs,journal_preped_$journal";
+
+	  ($fs eq "xfs") and $create_options = "$create_options -l logdev=$journal";
+	  ($fs eq "ext3") and $create_options = "$create_options -J device=$journal";
+	  ($fs eq "ext4") and $create_options = "$create_options -J device=$journal";
+      }
+  }
+
+  &FAI::push_command( "$create_tool $create_options $device", $prereqs, $provides);
 
   # possibly tune the file system - this depends on whether the file system
   # supports tuning at all
@@ -887,10 +920,12 @@
 
     my $fs = $part->{filesystem};
     $fs = "" unless defined($fs);
+    ($fs) = split(/:/, $fs);
     $fs = "linux-swap" if ($fs eq "swap");
     $fs = "fat32" if ($fs eq "vfat");
     $fs = "fat16" if ($fs eq "msdos");
     $fs = "ext3" if ($fs eq "ext4");
+    $fs = "" if ($fs =~ m/.*_journal$/);
     $fs = $FAI::current_config{$disk}{partitions}{$mapped_id}{filesystem}
       if ($part->{size}->{preserve} || $part->{size}->{resize});
     $fs = "" if ($fs eq "-");
diff -ru a/lib/setup-storage/Parser.pm b/lib/setup-storage/Parser.pm
--- a/lib/setup-storage/Parser.pm	2010-04-05 14:39:33.000000000 +0200
+++ b/lib/setup-storage/Parser.pm	2010-05-10 11:15:24.000000000 +0200
@@ -764,16 +764,24 @@
         }
         | /^\S+/
         {
-          $FAI::partition_pointer->{filesystem} = $item[ 1 ];
+          my ($fs, $journal) = split(/:/, $item[1]);
           my $to_be_preserved = 0;
+
+          $FAI::partition_pointer->{filesystem} = $fs;
+
+          defined($journal) and $journal =~ s/journal=//;
+          $FAI::partition_pointer->{journal_dev} = $journal;
+
           if ($FAI::device eq "RAID" or $FAI::device eq "CRYPT") {
             $to_be_preserved = $FAI::partition_pointer->{preserve};
           } else {
             $to_be_preserved = $FAI::partition_pointer->{size}->{preserve};
           }
           if (0 == $to_be_preserved) {
-            &FAI::in_path("mkfs.$item[1]") or
-              die "unknown/invalid filesystem type $item[1] (mkfs.$item[1] not found in PATH)\n";
+            $fs =~ s/_journal$//;
+
+            &FAI::in_path("mkfs.$fs") or
+              die "unknown/invalid filesystem type $fs (mkfs.$fs not found in PATH)\n";
           }
         }
 

Reply via email to