Fixed kernel sources path for 'smp' kernels.
[lufs.git] / kernel / Linux / prepmod.in
index 3d62d37..8acdf0f 100755 (executable)
@@ -42,10 +42,16 @@ $kernel_gcc_args="";
 
 sub modext { my($uname_r)=@_; ($uname_r lt "2.5" ? "o" : "ko"); }
 
+# mount(8) will util-linux/lib/env.c/sanitize_env()
+# including the clearance our $PATH:
+$ENV{"PATH"}=join(":",qw(/usr/local/bin /usr/bin /bin),($ENV{"PATH"} || ()));
+
+my $lufsd_base='lufsd';
+do { eval '$lufsd_base=~'.$_.';' if !/^@/; } for ('@program_transform_name@');
 my $lufsd_bin;
-if ($0 eq "lufsd" || $0=~m#/lufsd$#) {
+if ($0 eq $lufsd_base || $0=~m#/\Q$lufsd_base\E$#) {
        $quiet=1;
-       $lufsd_bin='@bindir@/lufsd-bin';
+       $lufsd_bin='@bindir@/'.$lufsd_base.'-bin';
        $lufsd_bin=~s#\$\Q{exec_prefix}\E#'@exec_prefix@';#ge;
        $lufsd_bin=~s#\$\Q{prefix}\E#'@prefix@';#ge;
        }
@@ -112,6 +118,8 @@ my $modules=_readfile "/proc/modules";      # 'lufs' may be already loaded
 _pass if $modules=~/^lufs\b/m;
 _pass if !_system "/sbin/modprobe lufs 2>/dev/null";
 
+print STDERR "Preparing LUFS kernel module... Run $basedir/prepmod if problems occur.\n";      # if !$quiet;
+
 my $proc_version=_readfile "/proc/version";
 my $uname_r=($proc_version=~/^Linux version (\S+)/)[0] || _readfile "uname -r|";
 chomp $uname_r;
@@ -126,7 +134,7 @@ my $moduledir="/lib/modules/$uname_r$uname_smp/kernel/fs/lufs";
 print STDERR "Destination module directory: $moduledir\n" if !$quiet;
 
 my @kernel_paths=(
-                               "/lib/modules/$uname_r/build",
+                               "/lib/modules/$uname_r$uname_smp/build",
                                "/usr/src/kernel-headers-$uname_r",
                                "/usr/src/linux-$uname_r",
                                "/usr/src/linux-$uname_r_base",
@@ -148,6 +156,12 @@ else {
                if (build($kernel,$uname_r,$_)) {
                        do { cluck "Failed to symlink $_"; next; }
                                        if _system "/bin/rm -rf $moduledir; /bin/mkdir -p $moduledir; /bin/ln -s $_ $moduledir/$lufs_o";
+                       # Check if the compiled module matches the currently running kernel.
+                       # We may found some unspecific sources ('/usr/src/linux/'?) not matching the current kernel.
+                       # It still may be worth to try precompiled modules and/or give suggestive error messages.
+                       # Do not: /sbin/insmod -o lufs -p $_ 2>/dev/null
+                       # as 2.6 insmod has no options at all.
+                       next if _system "/sbin/rmmod lufs 2>/dev/null; /sbin/insmod $moduledir/$lufs_o 2>/dev/null";
                        _pass 1;
                        }
                }
@@ -168,7 +182,7 @@ confess "Failed to prepare $lufs_o module for your Linux kernel $uname_r.\n"
                .($kernel ? "Detected Linux kernel sources \"$kernel\" do not appear to be valid.\n"
                                : "No Linux kernel sources for your running kernel were found.\n")
                ."Please install kernel-source-x.y.z.i386.rpm or kernel-headers_x.y.z_i386.deb.\n"
-               ."The following directory paths were search (first existing directory used):\n"
+               ."The following directory paths were searched (first existing directory used):\n"
                .join("",map("\t\t$_\n",@kernel_paths));
 
 
@@ -245,8 +259,13 @@ my($kernel,$uname_r,$destmodule,%args)=@_;
        return $r if $r;
        # Rebuild existing '$kernel/tmp_include_depends' or '$kernel/.depend'
        # as it may contain non-existing pathnames:
-       _system "make -C $kernel dep"
-                               .($quiet ? ' &>/dev/null' : '');
+       _system "find $kernel -name .depend|xargs rm -f;"
+                       # Red Hat 2.4.18-14 contains precompiled .so-dependent 'mkdep'
+                       ." rm -f $kernel/scripts/mkdep;"
+                       # SuSE 2.4.21-144 contains precompiled .so-dependent 'split-include'
+                       ." rm -f $kernel/scripts/split-include;"
+                       ." make -C $kernel dep"
+                                   .($quiet ? ' &>/dev/null' : '');
        return !_system $cmdline;
 }
 
@@ -292,41 +311,84 @@ sub prebuild_rpm
 my($rpm)=@_;
 
        my $vendor=_readfile "rpm 2>/dev/null --qf '%{VENDOR}' -qp '$rpm' |";
-       $vendor=~s/,.*//;
+       $vendor="unknown" if $vendor eq "(none)";       # TurboLinux 2.4.18-14
+       $vendor=~s/[,<].*//;
        $vendor=~tr/ //d;
        my $uname_r;
        $uname_r||=($rpm=~m#/kernel-source-([^-]+-[^-]+)[.][^.]+[.]rpm$#)[0];
        my $uname_r_base=($uname_r=~/^([^-]+)/)[0];
+       # Do not: rpm -i ...
+       # as SuSE kernels require 1.5GB of VM during later 'rpm -e' in Shrike.
+       _system "rm -rf modbin-tmp;mkdir modbin-tmp;rpm2cpio '$rpm'|(cd modbin-tmp;cpio -id)"
+                       and confess "RPM extraction of $rpm";
        my $dir;
-       do { $dir||=$_ if -d $_; } for ("/usr/src/linux-$uname_r");
-       do { $dir||=$_ if -d $_; } for ("/usr/src/linux-$uname_r_base");        # older RedHat kernels
-       confess "Kernel sources already found in $dir" if $dir;
-       # '--nodeps' to prevent: error: Failed dependencies: perl-base is needed by *mdk
-       _system "rpm -i --nodeps '$rpm'" and confess "RPM installation of $rpm";
-       do { $dir||=$_ if -d $_; } for ("/usr/src/linux-$uname_r");
-       do { $dir||=$_ if -d $_; } for ("/usr/src/linux-$uname_r_base");        # older RedHat kernels
+       # Do not: -f $_
+       # as we are satisfied with symlink
+       # (such as base 'linux' used for some SuSE kernels with weird directory name).
+       do { $dir||=$_ if -e $_; } for ($ENV{"PWD"}."/modbin-tmp/usr/src/linux-$uname_r-include");      # new SuSE kernels
+       do { $dir||=$_ if -e $_; } for ($ENV{"PWD"}."/modbin-tmp/usr/src/linux-$uname_r");
+       do { $dir||=$_ if -e $_; } for ($ENV{"PWD"}."/modbin-tmp/usr/src/linux-$uname_r_base"); # older RedHat kernels
+       do { $dir||=$_ if -e $_; } for ($ENV{"PWD"}."/modbin-tmp/usr/src/linux");
        $dir or confess "Kernel source tree not found in: $rpm";
+       _system "chmod -R u+w $dir" and confess "Make kernel source writable in $dir";
        _system "cp -p $dir/include/linux/rhconfig.h $dir/include/linux/rhconfig.h-orig"
                                if -f "$dir/include/linux/rhconfig.h";
-       for my $smp ("","smp") {
-               my @archs=qw(i386 i586 i686 athlon);
-               for my $arch (@archs) {
-                       my %boot=(
-                                       "__BOOT_KERNEL_SMP"=>$smp,
-                                       map({ ("__MODULE_KERNEL_$_"=>($arch eq $_)); } @archs),
-                                       "__BOOT_KERNEL_BOOT"=>0,
-                                       "__BOOT_KERNEL_BOOTSMP"=>0,
-                                       "__BOOT_KERNEL_ENTERPRISE"=>0,
-                                       "__BOOT_KERNEL_BIGMEM"=>0,
-                                       "__BOOT_KERNEL_DEBUG"=>0,
-                                       );
-                       if (-f "$dir/include/linux/rhconfig.h") {
-                               my $defines="";
-                               for (keys(%boot)) {
-                                       $defines.="+#define $_ ".($boot{$_} ? 1 : 0)."\n";
-                                       }
-                               _system "cp -p -f $dir/include/linux/rhconfig.h-orig $dir/include/linux/rhconfig.h";
-                               _writefile "| patch $dir/include/linux/rhconfig.h",<<"RHCONFIG_H_NOBOOT_EOF";
+       my $built_total=0;
+       if (-d "$dir/default" && -d "$dir/smp") {
+               # new SuSE kernels
+               for my $arch_d (glob "$dir/*") {
+                       (my $arch=$arch_d)=~s#^.*/##;
+                       prebuild_kernel $arch_d,$vendor,$uname_r.".".$arch;
+                       $built_total++;
+                       }
+               }
+       elsif (-e "$dir/SetupKernelSource.sh") {
+               # TurboLinux
+               if (! -e "$dir/include") {
+                       (my $kheaders=$rpm)=~s#/kernel-source-([^/]*)$#/kernel-headers-$1#
+                                       or confess "Invalid RPM basename of: $rpm";
+                       _system "rpm2cpio '$kheaders'|(cd modbin-tmp;cpio -id)"
+                                       and confess "RPM kheaders extraction of $rpm";
+                       }
+               for my $TYPE ("","smp","smp64G") {
+                       for my $ARCH (qw(i386 i586 i686 athlon)) {
+                               # Use even 'A-Z' for the 'release' for TurboLinux 2.4.9-3D
+                               next if !glob "$dir/configs/kernel-*-*[0-9A-Z]$TYPE-$ARCH.config";
+                               _system "set -ex; cd '$dir';"
+                                                               # Forbid 'cd /usr/src/linux' in './SetupKernelSource.sh'
+                                                               # but permit later 'cd's by make(1) subprocesses.
+                                                               # Therefore do not 'export -f cd;' but 'source ./SetupKernelSource.sh'.
+                                                               .' function cd { :; };' # Do not: 'export -f cd;'
+#                                                              .' function make {(set -ex;unset make; make "$@"; make symlinks; );}; export -f make;'
+                                                               # Permit 'errors' for 'grep smp' in TurboLinux 2.4.5-0.5
+                                                               ." set +e; source ./SetupKernelSource.sh $ARCH$TYPE;"
+                                               and confess "SetupKernelSource.sh $ARCH$TYPE in $dir";
+                               prebuild_kernel $dir,$vendor,$uname_r.".".$ARCH.$TYPE;
+                               $built_total++;
+                               }
+                       }
+               }
+       else {
+               # RedHat/Mandrake/old-SuSE kernels
+               for my $smp ("","smp") {
+                       my @archs=qw(i386 i586 i686 athlon);
+                       for my $arch (@archs) {
+                               my %boot=(
+                                               "__BOOT_KERNEL_SMP"=>$smp,
+                                               map({ ("__MODULE_KERNEL_$_"=>($arch eq $_)); } @archs),
+                                               "__BOOT_KERNEL_BOOT"=>0,
+                                               "__BOOT_KERNEL_BOOTSMP"=>0,
+                                               "__BOOT_KERNEL_ENTERPRISE"=>0,
+                                               "__BOOT_KERNEL_BIGMEM"=>0,
+                                               "__BOOT_KERNEL_DEBUG"=>0,
+                                               );
+                               if (-f "$dir/include/linux/rhconfig.h") {
+                                       my $defines="";
+                                       for (keys(%boot)) {
+                                               $defines.="+#define $_ ".($boot{$_} ? 1 : 0)."\n";
+                                               }
+                                       _system "cp -p -f $dir/include/linux/rhconfig.h-orig $dir/include/linux/rhconfig.h";
+                                       _writefile "| patch $dir/include/linux/rhconfig.h",<<"RHCONFIG_H_NOBOOT_EOF";
 --- ./include/linux/rhconfig.h-orig    Thu Aug 21 14:50:16 2003
 +++ ./include/linux/rhconfig.h Thu Aug 21 14:59:22 2003
 \@\@ -10,7 +10,@{[ 7+keys(%boot) ]} \@\@
@@ -339,21 +401,24 @@ $defines
  #if defined(__BOOT_KERNEL_SMP) && (__BOOT_KERNEL_SMP == 1)
  #define __module__smp
 RHCONFIG_H_NOBOOT_EOF
+                                       }
+                               # Mandrake packages have no configs/ and they have just that '.config' file.
+                               my $single_config=-f "$dir/.config";
+                               if (!$single_config) {
+                                       my $spec_config="$dir/configs/kernel-$uname_r_base-$arch".($smp ? "-smp" : "").".config";
+                                       next if ! -f $spec_config;
+                                       _system "ln -s $spec_config $dir/.config";
+                                       }
+                               prebuild_kernel $dir,$vendor,$uname_r.$smp.".".$arch;
+                               $built_total++;
+                               _system "rm -f $dir/.config"
+                                               if !$single_config;
                                }
-                       # Mandrake packages have no configs/ and they have just that '.config' file.
-                       my $single_config=-f "$dir/.config";
-                       if (!$single_config) {
-                               my $spec_config="$dir/configs/kernel-$uname_r_base-$arch".($smp ? "-smp" : "").".config";
-                               next if ! -f $spec_config;
-                               _system "ln -s $spec_config $dir/.config";
-                               }
-                       prebuild_kernel $dir,$vendor,$uname_r.$smp.".".$arch;
-                       _system "rm -f $dir/.config"
-                                       if !$single_config;
                        }
                }
-       _system "rpm -e kernel-source-$uname_r" and confess "Remove of kernel-source-$uname_r";
-       _system "rm -rf $dir";
+       # Old SuSE kernels have no '.config' or 'configs/'.
+       confess "Not a buildable kernel: $rpm" if !$built_total;
+       _system "rm -rf modbin-tmp" and confess "Remove of extracted kernel-source-$uname_r";
 }
 
 sub prebuild_dir