summaryrefslogtreecommitdiffstats
path: root/lib/MDV/Draklive/Initrd.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MDV/Draklive/Initrd.pm')
-rw-r--r--lib/MDV/Draklive/Initrd.pm314
1 files changed, 0 insertions, 314 deletions
diff --git a/lib/MDV/Draklive/Initrd.pm b/lib/MDV/Draklive/Initrd.pm
deleted file mode 100644
index a2e8ee1..0000000
--- a/lib/MDV/Draklive/Initrd.pm
+++ /dev/null
@@ -1,314 +0,0 @@
-package MDV::Draklive::Initrd;
-
-use MDK::Common;
-use common;
-use list_modules;
-use MDV::Draklive::Utils;
-use MDV::Draklive::StorageFS;
-use MDV::Draklive::Loopback;
-use MDV::Draklive::Overlay;
-use File::Basename;
-
-my %module_to_config = (
- ext3 => 'EXT3_FS',
- sd_mod => 'BLK_DEV_SD',
-);
-
-sub require_module_in_chroot {
- my ($live, $module) = @_;
- my $chroot_module = cat_($live->get_system_root . "/usr/lib/libDrakX/$module.pm");
- $chroot_module =~ s/^package $module;\B/package ${module}_chroot;/;
- my $tmp_module = $live->get_system_root . "/tmp/${module}_chroot.pm";
- output_p($tmp_module, $chroot_module);
- require $tmp_module;
- unlink $tmp_module;
-}
-
-sub nls_modules {
- my ($live) = @_;
- my $fs = $live->{media}->get_media_setting('fs');
- if_($fs eq 'vfat', 'nls_cp437'), #- default FAT codepage
- if_($fs !~ /^ext/, map { "nls_$_" } (map { "iso8859_$_" } 1..7, 9, 13..15), 'utf8');
-}
-
-sub create_media_initrd {
- my ($live) = @_;
- create_initrd_for_media($live, $live->{media});
- cp_f($live->get_builddir . $live->{prefix}{build}{boot} . $live->{media}->get_initrd_path,
- $live->{copy_initrd}) if $live->{copy_initrd};
-}
-
-sub inst_initrd_file {
- my ($root, $initrd_tree, $file) = @_;
- if ($file =~ m|/s?bin/|) {
- inst_initrd_bin($root, $initrd_tree, $file);
- } else {
- mkdir_p($initrd_tree . dirname($file));
- inst_initrd_dso_deps($root, $initrd_tree, $file) if $file =~ m|/lib[^/]*/|;
- cp_f($root . $file, $initrd_tree . $file) or die "unable to copy $file from system chroot\n";
- }
-}
-
-sub inst_initrd_dso_deps {
- my ($root, $initrd_tree, $dso) = @_;
- foreach my $file (`chroot $root ldd $dso | awk '/\\// {if(\$2 == "=>") {print \$3} else {print \$1}}'`) {
- chomp $file;
- $file =~ s!^(/lib[^/]*)/(?:i686|tls)!$1!;
- my ($lib_prefix, $filename) = $file =~ m|(/lib[^/]*).*/([^/]+)$| or next;
- my $dest = $initrd_tree . $lib_prefix . '/' . $filename;
- mkdir_p($initrd_tree . $lib_prefix);
- -f $dest || cp_f($root . $file, $dest) or die "unable to copy $filename from system chroot\n";
- }
-}
-sub inst_initrd_bin {
- my ($root, $initrd_tree, $bin) = @_;
- cp_f($root . $bin, $initrd_tree . '/bin/');
- inst_initrd_dso_deps($root, $initrd_tree, $bin);
-}
-
-sub create_initrd_for_media {
- my ($live, $media) = @_;
- my $initrd = $live->get_builddir . $live->{prefix}{build}{boot} . $media->get_initrd_path;
- create_media_specific_initrd($live, $media, $live->get_system_root, $initrd, $live->find_kernel->{version});
-}
-
-sub create_media_specific_initrd {
- my ($live, $media, $root, $initrd, $kernel) = @_;
-
- require_module_in_chroot($live, "list_modules");
-
- my $lib_prefix = $live->get_lib_prefix;
- my $initrd_tree = $live->get_builddir . $live->{prefix}{build}{initrd} . '/' . $media->{storage};
- rm_rf($initrd_tree) if -e $initrd_tree;
-
- mkdir_p($initrd_tree . $_) foreach
- qw(/bin /dev /proc /sys /tmp),
- map { $live->{prefix}{live}{mnt} . $_ }
- $live->{prefix}{media}{mnt},
- $live->{mount}{root},
- map { $_->{mountpoint} } grep { !$loop_types{$_->{type}}{skip_mkdir} } @{$live->{mount}{dirs} || []};
-
- #- use nash with label support
- inst_initrd_bin($root, $initrd_tree, '/sbin/nash');
- inst_initrd_bin($root, $initrd_tree, '/usr' . $lib_prefix . '/drakx-installer-binaries/probe-modules');
- inst_initrd_bin($root, $initrd_tree, '/sbin/blockdev')
- if $media->get_media_setting('rereadpt');
- inst_initrd_bin($root, $initrd_tree, '/usr/bin/strace')
- if $live->{debug};
-
- #- busybox is required to:
- #- detect usb-storage process (we need sh/while/ps/grep)
- #- mount loopbacks read-only with losetup (useful over NFS)
- my $busybox = '/usr/bin/busybox';
- my $busybox_static = '/bin/busybox.static';
- $busybox = $busybox_static if -e $root . $busybox_static;
-
- inst_initrd_bin($root, $initrd_tree, $busybox);
- my @l = map { /functions:/ .. /^$/ ? do { s/\s//g; split /,/ } : () } run_program::rooted_get_stdout($root, $busybox);
- shift @l;
- symlink(basename($busybox), $initrd_tree . "/bin/$_") foreach @l;
-
- my $fs = $media->get_media_setting('fs');
- my @used_loop_types = uniq(map { $_->{type} } @{$live->{mount}{dirs}});
- inst_initrd_bin($root, $initrd_tree, $_) foreach
- MDV::Draklive::StorageFS::get_files($fs),
- (map { @{$loop_types{$_} && $loop_types{$_}{files} || []} } @used_loop_types);
-
- output_p($initrd_tree . '/etc/fstab', '');
- output_p($initrd_tree . '/etc/mtab', '');
-
- my $loop_nb = 254;
- my $rrpt_dev = $media->get_media_setting('rereadpt');
- require devices;
- devices::make($initrd_tree . "/dev/$_") foreach
- if_($rrpt_dev, $rrpt_dev),
- qw(console initrd null ram systty tty tty1),
- (map { "tty$_" } 0..8),
- (map { "loop$_" } 0 .. $loop_nb);
- syscall_('mknod', $initrd_tree . "/dev/ptmx", c::S_IFCHR(), makedev(5, 2)) or die "mknod failed (dev $_): $!";
- syscall_('mknod', $initrd_tree . "/dev/fb", c::S_IFCHR(), makedev(29, 0)) or die "mknod failed (dev $_): $!";
- #- pre-create devfsd compatibility loop devices (since busybox is still built with devfsd support)
- mkdir_p($initrd_tree . "/dev/loop");
- cp_af($initrd_tree . "/dev/loop$_", $initrd_tree . "/dev/loop/$_") foreach 0 .. $loop_nb;
-
- print "using kernel $kernel\n";
- my $kernel_root = "/lib/modules/" . $kernel;
- list_modules::load_dependencies($kernel_root . "/modules.dep", $root);
-
- my ($storage_modules, $skipped) = partition { list_modules::modname2filename($_) }
- uniq(map { modules::cond_mapping_24_26($_) } list_modules_chroot::category2modules($media->get_media_setting('modules')));
- my ($extra_modules, $extra_missing) = partition { list_modules::modname2filename($_) }
- list_modules_chroot::category2modules($media->get_media_setting('media_modules')),
- nls_modules($live),
- $media->get_media_fs_module,
- @{$media->get_media_setting('extra_modules') || []},
- (map { MDV::Draklive::Loopback::get_loop_modules($live, $_) } uniq(map { $_->{type} } @{$live->{mount}{dirs} || []})),
- ($live->{mount}{overlay} ? @{$MDV::Draklive::Overlay::overlay{$live->{mount}{overlay}}{modules} || []} : ());
-
- my @additional_modules = map { if_(m!([^/]+)\.ko(?:\.gz)?!, list_modules::filename2modname($1)) } @{$live->{system}{additional_modules}};
- @$extra_modules = difference2($extra_modules, \@additional_modules);
- if (@{$live->{system}{exclude_modules} || []}) {
- print STDERR "excluding modules: " . join(' ', @{$live->{system}{exclude_modules}}) . "\n";
- @$_ = difference2($_, $live->{system}{exclude_modules}) foreach $storage_modules, $extra_modules, $extra_missing;
- }
-
- my @missing = sort(difference2($extra_missing, \@additional_modules));
- if (@missing) {
- my @config = map { if_(/^CONFIG_(.*)=y$/, $1) } cat_($root . "/boot/config-" . $kernel);
- my @really_missing = grep { !member($module_to_config{$_}, @config) } @missing;
- @really_missing and die "missing mandatory modules:\n" . join("\n", @really_missing, '');
- }
-
- mkdir_p($initrd_tree . $kernel_root . "/kernel");
- my @modules = (@$storage_modules, @$extra_modules);
- my @modules_closure = uniq(map { list_modules::dependencies_closure($_) } @modules);
- foreach my $m (@modules_closure) {
- my $full = list_modules::modname2path($m);
- mkdir_p(dirname($initrd_tree . $full));
- cp_f($root . $full, $initrd_tree . $full);
- }
- foreach my $f (@{$live->{system}{additional_modules}}) {
- my $destdir = $initrd_tree . $kernel_root . "/kernel";
- if ($f =~ /.gz$/) {
- cp_f($live->{settings}{config_root} . '/' . $f, $destdir);
- } else {
- my $m = basename($f);
- run_program::run('gzip', '>', "$destdir/$m.gz", '-c', $live->{settings}{config_root} . '/' . $f);
- }
- }
- run_('depmod', '-b', $initrd_tree, $kernel);
-
- mkdir_p($initrd_tree . "/etc/blkid"); #- for nash and showlabels cache
- mkdir_p($initrd_tree . "/lib/module-init-tools");
- cp_f($root . "/lib/module-init-tools/ldetect-lst-modules.alias", $initrd_tree . "/lib/module-init-tools");
- mkdir_p($initrd_tree . "/usr/share/ldetect-lst");
- cp_f($root . "/usr/share/pci.ids", $initrd_tree . "/usr/share");
- cp_f($root . "/usr/share/ldetect-lst/" . $_, $initrd_tree . "/usr/share/ldetect-lst")
- foreach qw(fallback-modules.alias pcitable.gz usbtable.gz);
-
- @$skipped and print STDERR "skipped modules: " . join(' ', sort(@$skipped)) . "\n";
-
- my @extra_modules_closure = map { list_modules::modname2filename($_) }
- uniq(map { list_modules::dependencies_closure($_) } @$extra_modules);
- create_initrd_scriptlet($live, $media, @extra_modules_closure, @additional_modules);
-
- print "Compressing initrd\n";
- compress_initrd_tree($live, $initrd_tree, $initrd);
- add_splash($live, $initrd);
-}
-
-sub create_initrd_scriptlet {
- my ($live, $media, @modules) = @_;
- my $target = $live->{prefix}{live}{mnt} . ($live->{mount}{root} || $live->{prefix}{media}{mnt});
- my $pre = $media->get_media_setting('pre');
- my $fs = $media->get_media_setting('fs');
- my $rrpt_dev = $media->get_media_setting('rereadpt');
- my $debug_shell = "sh -c 'if grep -q initrd_debug /proc/cmdline; then plymouth --quit; exec sh </dev/console >/dev/console 2>/dev/console; fi'";
- my ($mount_first, $mount_last) = partition { !$loop_types{$_->{type}}{delay_mount} }
- grep { exists $loop_types{$_->{type}}{mount} } @{$live->{mount}{dirs} || []};
- my $initrdroot = "/initrd";
-
- output_with_perm($live->get_builddir . $live->{prefix}{build}{initrd} . '/' . $media->{storage} . '/linuxrc', 0755,
- join("\n",
- "#!/bin/nash",
- #- required for labels and ps
- "nash-mount -t proc /proc /proc",
- #- required for cdrom labels
- "nash-mount -t sysfs /sys /sys",
- "/bin/plymouthd",
- "plymouth --show-splash",
- (map { join(" ", "probe-modules", list_modules::filename2modname($_), grep { $_ } $live->{system}{module_options}{$_}) } @modules),
- "probe-modules --$media->{storage}",
- if_($rrpt_dev,
- "echo *** Waiting for new partitions on device ${rrpt_dev} ***",
- "sh -c 'while ! ls /sys/block/${rrpt_dev}/${rrpt_dev}* >/dev/null 2>&1; do sleep 3; blockdev --rereadpt /dev/${rrpt_dev} >/dev/null 2>&1; done'"),
- $debug_shell,
- if_($pre, deref_array($pre)),
- "showlabels --removable",
- MDV::Draklive::StorageFS::get_mount($fs)->($live, $media),
- (map { $loop_types{$_->{type}}{mount}->($live, $_) } @$mount_first, @$mount_last),
- ($live->{mount}{overlay} ? $MDV::Draklive::Overlay::overlay{$live->{mount}{overlay}}{mount}->($live) : ()),
- if_($live->{system}{initrd_pre_pivot}, deref_array($live->{system}{initrd_pre_pivot})),
- "plymouth --newroot=$target",
- "echo 0x0100 > /proc/sys/kernel/real-root-dev",
- "umount /sys",
- "sh -c 'umount /sys/kernel/debug/usb 2>/dev/null'",
- "umount /sys/kernel/debug/usb",
- "pivot_root $target $target$initrdroot",
- if_($live->{mount}{root}, "sh -c 'rmdir $initrdroot$live->{prefix}{live}{mnt}$live->{mount}{root}'"),
- (map { $loop_types{$_->{type}}{pivot_clean}->($live, $_, $initrdroot) } grep { $loop_types{$_->{type}}{pivot_clean} } @{$live->{mount}{dirs} || []}),
- "sh -c 'cd $initrdroot$live->{prefix}{live}{mnt}; for i in `ls -1`; do [ -d \$i ] || continue; mkdir -p $live->{prefix}{live}{mnt}/\$i; mount -n --move \$i $live->{prefix}{live}{mnt}/\$i; rmdir \$i; done'",
- "rmdir $initrdroot$live->{prefix}{live}{mnt}",
- "nash-mount -o mode=0755 -t tmpfs /dev /dev",
- "sh -c 'rm -rf /dev/loop'", #- not needed after initrd
- "sh -c 'mv $initrdroot/dev/* /dev/'",
- if_($live->{system}{initrd_post}, deref_array($live->{system}{initrd_post})),
- ""));
-}
-
-sub compress_initrd_tree {
- my ($live, $initrd_tree, $initrd) = @_;
-
- my $size = chomp_(run_program::get_stdout("du -ks $initrd_tree | awk '{print \$1}'"));
- my $inodes = chomp_(run_program::get_stdout("find $initrd_tree | wc -l")) + 100;
- my $initrd_size = $size + 350 + int($inodes / 10); #- 10 inodes needs 1K
- $initrd_size += 1350; # plymouth
-
- $initrd =~ s/.gz$//;
-
- mkdir_p(dirname($initrd));
- run_('dd', 'if=/dev/zero', "of=$initrd", 'bs=1k', "count=$initrd_size");
- run_('mke2fs', '-q', '-m', 0, '-F', '-N', $inodes, '-s', 1, $initrd);
- mkdir_p($live->{mnt});
- run_('mount', '-o', 'loop', '-t', 'ext2', $initrd, $live->{mnt});
- cp_af(glob("$initrd_tree/*"), $live->{mnt});
- rm_rf($live->{mnt} . "/lost+found");
- my $left = chomp_(run_program::get_stdout("df -Pk $live->{mnt} | tail -n 1 | awk '{ print \$4 }'"));
- run_('umount', $live->{mnt});
- $left < 200 and die "not enough room to create initrd (only ${left}K left)\n";
- run_('gzip', '-f', '-9', $initrd);
-}
-
-sub add_splash {
- my ($live, $initrd) = @_;
- if ($live->{system}{vga_mode} && $live->{system}{splash} ne 'no') {
- my $chroot_initrd;
- if ($initrd !~ m,^/boot/,) {
- $chroot_initrd = '/tmp/initrd.gz';
- cp_f($initrd, $live->get_system_root . $chroot_initrd);
- } else {
- $chroot_initrd = $initrd;
- }
-
- {
- local $::prefix = $live->get_system_root;
- #- also calls switch-themes -u (through make-boot-splash)
- #- which will regenerate gfxboot current link
- require bootloader;
- bootloader::add_boot_splash($chroot_initrd, $live->{system}{vga_mode});
- }
-
- if ($chroot_initrd ne $initrd) {
- cp_f($live->get_system_root . $chroot_initrd, $initrd);
- unlink($live->get_system_root . $chroot_initrd);
- }
- }
-}
-
-sub create_classical_initrd {
- my ($live) = @_;
- my $root = $live->get_system_root;
- my $kernel = $live->find_kernel;
- print "using kernel $kernel->{version}\n";
-
- my $initrd_file = $root . '/boot/' . $live->get_initrd_name;
- unlink($initrd_file);
-
- {
- my $bootloader = {};
- local $::prefix = $root;
- bootloader::add_kernel($bootloader, $kernel, { label => 'linux', vga => $live->{system}{vga_mode} }, '', $live->{system}{no_initrd});
- }
-}
-
-1;