From d537f12b889835df055a2053e37686b77545834d Mon Sep 17 00:00:00 2001 From: Antoine Ginies Date: Wed, 19 Jan 2011 15:01:20 +0000 Subject: backport more stuff from 2010.1 --- mdk-stage1/modules.c | 36 ++++++++----- mdk-stage1/modules.h | 6 +-- mdk-stage1/probing.c | 21 ++++++-- mdk-stage1/stage1.c | 2 +- perl-install/detect_devices.pm | 118 +++++++++++++++++++++++++---------------- 5 files changed, 116 insertions(+), 67 deletions(-) diff --git a/mdk-stage1/modules.c b/mdk-stage1/modules.c index 53bc87d4c..5f02d2a6d 100644 --- a/mdk-stage1/modules.c +++ b/mdk-stage1/modules.c @@ -1,7 +1,7 @@ /* - * Guillaume Cottenceau (gc@mandrakesoft.com) + * Guillaume Cottenceau (gc@mandriva.com) * - * Copyright 2000 Mandrakesoft + * Copyright 2000 Mandriva * * This software may be freely redistributed under the terms of the GNU * public license. @@ -39,8 +39,8 @@ #include "modules.h" -#define FIRMWARE_TIMEOUT_FILE "/sys/class/firmware/timeout" -#define FIRMWARE_TIMEOUT_VALUE "1" +#define UEVENT_HELPER_FILE "/sys/kernel/uevent_helper" +#define UEVENT_HELPER_VALUE "/sbin/hotplug" static char modules_directory[100]; static struct module_deps_elem * modules_deps = NULL; @@ -156,12 +156,12 @@ static int load_modules_dependencies(void) while (*ptr && (*ptr == ' ')) ptr++; /* sort of a good line */ - modules_deps[line].filename = strdup(start); + modules_deps[line].filename = start[0] == '/' ? strdup(start) : asprintf_("%s/%s", modules_directory, start); modules_deps[line].modname = filename2modname(start); start = ptr; i = 0; - while (start && *start) { + while (start && *start && i < sizeof(tmp_deps)/sizeof(char *)) { ptr = strchr(start, ' '); if (ptr) *ptr = '\0'; tmp_deps[i++] = filename2modname(start); @@ -172,6 +172,12 @@ static int load_modules_dependencies(void) while (start && *start && *start == ' ') start++; } + if(i >= sizeof(tmp_deps)/sizeof(char *)-1) { + log_message("warning, more than %zu dependencies for module %s", + sizeof(tmp_deps)/sizeof(char *)-1, + modules_deps[line].modname); + i = sizeof(tmp_deps)/sizeof(char *)-1; + } tmp_deps[i++] = NULL; modules_deps[line].deps = memdup(tmp_deps, sizeof(char *) * i); @@ -229,14 +235,14 @@ static int load_modules_descriptions(void) return 0; } -void init_firmware_timeout(void) +void init_firmware_loader(void) { - int fd = open(FIRMWARE_TIMEOUT_FILE, O_WRONLY|O_TRUNC, 0666); + int fd = open(UEVENT_HELPER_FILE, O_WRONLY|O_TRUNC, 0666); if (!fd) { - log_message("warning, unable to set firmware timeout"); + log_message("warning, unable to set firmware loader"); return; } - write(fd, FIRMWARE_TIMEOUT_VALUE, strlen(FIRMWARE_TIMEOUT_VALUE)); + write(fd, UEVENT_HELPER_VALUE, strlen(UEVENT_HELPER_VALUE)); close(fd); } @@ -247,7 +253,7 @@ void init_modules_insmoding(void) fatal_error("warning, error initing modules stuff, modules loading disabled"); } if (load_modules_descriptions()) { - log_message("warning, error initing modules stuff, modules loading disabled"); + log_message("warning, error initing modules stuff"); } } @@ -420,6 +426,11 @@ static enum return_type insmod_with_options(char * mod, enum driver_type type) return RETURN_OK; } +static int strsortfunc(const void *a, const void *b) +{ + return strcmp(* (char * const *) a, * (char * const *) b); +} + enum return_type ask_insmod(enum driver_type type) { enum return_type results; @@ -431,11 +442,12 @@ enum return_type ask_insmod(enum driver_type type) char ** p_modules = modules; char ** p_descrs = descrs; + qsort(dlist, string_array_length(dlist), sizeof(char *), strsortfunc); + unset_automatic(); /* we are in a fallback mode */ while (p_dlist && *p_dlist) { struct module_descr_elem * descr; - if (!strstr(*p_dlist, kernel_module_extension())) { p_dlist++; continue; diff --git a/mdk-stage1/modules.h b/mdk-stage1/modules.h index 8a57b9e41..4bddb2452 100644 --- a/mdk-stage1/modules.h +++ b/mdk-stage1/modules.h @@ -1,7 +1,7 @@ /* - * Guillaume Cottenceau (gc@mandrakesoft.com) + * Guillaume Cottenceau (gc@mandriva.com) * - * Copyright 2000 Mandrakesoft + * Copyright 2000 Mandriva * * This software may be freely redistributed under the terms of the GNU * public license. @@ -21,7 +21,7 @@ enum insmod_return { INSMOD_OK, INSMOD_FAILED, INSMOD_FAILED_FILE_NOT_FOUND }; void init_modules_insmoding(void); -void init_firmware_timeout(void); +void init_firmware_loader(void); int insmod_local_file(char * path, char * options); enum insmod_return my_insmod(const char * mod_name, enum driver_type type, char * options, int allow_modules_floppy); enum return_type ask_insmod(enum driver_type); diff --git a/mdk-stage1/probing.c b/mdk-stage1/probing.c index fd0f39c50..0db75ffbd 100644 --- a/mdk-stage1/probing.c +++ b/mdk-stage1/probing.c @@ -1,7 +1,7 @@ /* - * Guillaume Cottenceau (gc@mandrakesoft.com) + * Guillaume Cottenceau (gc@mandriva.com) * - * Copyright 2000 Mandrakesoft + * Copyright 2000 Mandriva * * This software may be freely redistributed under the terms of the GNU * public license. @@ -768,10 +768,23 @@ void find_media(enum media_bus bus) while (fgets(buf, sizeof(buf), f)) { char name[100]; int major, minor, blocks; + struct stat statbuf; + char *ptr; memset(name, 0, sizeof(name)); - sscanf(buf, " %d %d %d %s", &major, &minor, &blocks, name); - if (streq(name, tmp_name) && tmp[count].type == DISK && ((blocks == 1048575) || (blocks == 1440))) + strcpy(name, "/dev/"); + sscanf(buf, " %d %d %d %s", &major, &minor, &blocks, &name[5]); + if (streq(&name[5], tmp_name) && tmp[count].type == DISK && ((blocks == 1048575) || (blocks == 1440))) tmp[count].type = FLOPPY; + /* Try to create all devices while we have major/minor */ + if ((ptr = strchr(&name[5], '/'))) { + *ptr = '\0'; + if (stat(name, &statbuf)) + mkdir(name, 0755); + *ptr = '/'; + } + if (stat(name, &statbuf) && mknod(name, S_IFBLK | 0600, makedev(major, minor))) { + log_perror(name); + } } fclose(f); } diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c index 63f9d2ed2..80961d426 100644 --- a/mdk-stage1/stage1.c +++ b/mdk-stage1/stage1.c @@ -410,7 +410,7 @@ int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)) spawn_shell(); #endif init_modules_insmoding(); - init_firmware_timeout(); +// init_firmware_timeout(); init_frontend("Welcome to " DISTRIB_DESCR ", " __DATE__ " " __TIME__); probe_that_type(VIRTIO_DEVICES, BUS_ANY); diff --git a/perl-install/detect_devices.pm b/perl-install/detect_devices.pm index 2b0266e37..42f14aff6 100644 --- a/perl-install/detect_devices.pm +++ b/perl-install/detect_devices.pm @@ -1,4 +1,4 @@ -package detect_devices; # $Id: detect_devices.pm 260571 2009-09-17 14:51:24Z pterjan $ +package detect_devices; # $Id: detect_devices.pm 267151 2010-03-30 14:27:41Z blino $ use diagnostics; use strict; @@ -121,10 +121,11 @@ sub complete_usb_storage_info { if (my $e = find { !$_->{found} && $_->{usb_vendor} == $usb->{vendor} && $_->{usb_id} == $usb->{id} } @usb) { my $host = get_sysfs_usbpath_for_block($e->{device}); if ($host) { - $e->{info} = chomp_(cat_("/sys/block/$e->{device}/$host/../serial")); + my $file = "/sys/block/$host/../serial"; + $e->{info} = chomp_(cat_($file)) if -e $file; $e->{usb_description} = join('|', - chomp_(cat_("/sys/block/$e->{device}/$host/../manufacturer")), - chomp_(cat_("/sys/block/$e->{device}/$host/../product"))); + chomp_(cat_("/sys/block/$host/../manufacturer")), + chomp_(cat_("/sys/block/$host/../product"))); } local $e->{found} = 1; $e->{"usb_$_"} ||= $usb->{$_} foreach keys %$usb; @@ -170,7 +171,7 @@ sub get_sysfs_field_from_link { sub get_sysfs_usbpath_for_block { my ($device) = @_; - my $host = readlink("/sys/block/$device/device"); + my $host = readlink("/sys/block/$device"); $host =~ s!/host.*!!; $host; } @@ -181,7 +182,8 @@ sub get_scsi_driver { foreach (@l) { next if $_->{driver}; my $host = get_sysfs_usbpath_for_block($_->{device}); - $_->{driver} = get_sysfs_field_from_link("/sys/block/$_->{device}/$host", 'driver'); + require list_modules; + $_->{driver} = list_modules::filename2modname(get_sysfs_field_from_link("/sys/block/$host", 'driver')); } } @@ -203,7 +205,9 @@ sub getSCSI() { my @l; foreach (all($dev_dir)) { - my ($host, $channel, $id, $lun) = split ':' or log::l("bad entry in $dev_dir: $_"), next; + my ($host, $channel, $id, $lun) = split ':'; + defined $lun or next; + my $dir = "$dev_dir/$_"; # handle both old and new kernels: @@ -214,7 +218,7 @@ sub getSCSI() { } warn("cannot get info for device ($_)"), next if !$device; - my $usb_dir = readlink("$node/device") =~ m!/usb! && "$node/device/../../../.."; + my $usb_dir = readlink($dir) =~ m!/usb! && "$dir/../../../.."; my $get_usb = sub { chomp_(cat_("$usb_dir/$_[0]")) }; my $get = sub { @@ -230,8 +234,13 @@ sub getSCSI() { my $media_type = ${{ st => 'tape', sr => 'cdrom', sd => 'hd', sg => 'generic' }}{substr($device, 0, 2)} || $raw_type =~ /Scanner|Processor/ && 'scanner'; - push @l, { info => $get->('vendor') . ' ' . $get->('model'), host => $host, channel => $channel, id => $id, lun => $lun, - description => join('|', $get->('vendor'), $get->('model')), + my ($vendor, $model) = ($get->('vendor'), $get->('model')); + my ($v, $m) = _get_hd_vendor($model); + if ($v && $v) { + ($vendor, $model) = ($v, $m); + } + push @l, { info => $vendor . ' ' . $model, host => $host, channel => $channel, id => $id, lun => $lun, + description => join('|', $vendor, $model), bus => 'SCSI', media_type => $media_type, device => $device, $usb_dir ? ( usb_vendor => hex($get_usb->('idVendor')), usb_id => hex($get_usb->('idProduct')), @@ -253,8 +262,9 @@ sub getSCSI() { } -my %eide_hds = ( +my %hd_vendors = ( "ASUS" => "Asus", + "ATA Maxtor" => "Maxtor", "CD-ROM CDU" => "Sony", "CD-ROM Drive/F5D" => "ASUSTeK", "Compaq" => "Compaq", @@ -280,6 +290,16 @@ my %eide_hds = ( "WDC" => "Western Digital Corp.", ); +# return ($vendor, $model) +sub _get_hd_vendor { + my ($info) = @_; + foreach my $name (keys %hd_vendors) { + next if !$name; + return ($hd_vendors{$name}, $2) if $info =~ /^$name(-|\s)*(.*)/; + } + return ("Hitachi", $info) if $info =~ /^HD[ST][0-9]/; +} + sub getIDE() { my @idi; @@ -295,9 +315,7 @@ sub getIDE() { my $info = chomp_(cat_("$d/model")) || "(none)"; my $num = ord(($d =~ /(.)$/)[0]) - ord 'a'; - my ($vendor, $model) = map { - if_($info =~ /^$_(-|\s)*(.*)/, $eide_hds{$_}, $2); - } keys %eide_hds; + my ($vendor, $model) = _get_hd_vendor($info); my $host = $num; ($host, my $id) = divide($host, 2); @@ -370,11 +388,9 @@ sub getATARAID() { sub getVirtIO() { -d '/sys/bus/virtio/devices' or return; map { - my $dev = basename($_); - $dev =~ s/block://; - { device => $dev, info => "VirtIO block device", media_type => 'hd', bus => 'virtio' } + { device => basename($_), info => "VirtIO block device", media_type => 'hd', bus => 'virtio' }; } - glob("/sys/bus/virtio/devices/*/block:*"); + glob("/sys/bus/virtio/devices/*/block/*"); } # cpu_name : arch() =~ /^alpha/ ? "cpu " : @@ -493,6 +509,7 @@ sub getInputDevices() { $device->{Synaptics} = $descr eq 'SynPS/2 Synaptics TouchPad'; $device->{ALPS} = $descr =~ m!^AlpsPS/2 ALPS!; + $device->{Elantech} = $descr eq 'ETPS/2 Elantech Touchpad'; } elsif (/H: Handlers=(.*)/) { my @l = split(' ', $1); @@ -543,6 +560,11 @@ sub getInputDevices_and_usb() { @l; } +sub serialPorts() { map { "ttyS$_" } 0..7 } +sub serialPort2text { + $_[0] =~ /ttyS(\d+)/ ? "$_[0] / COM" . ($1 + 1) : $_[0]; +} + sub getSerialModem { my ($modules_conf, $o_mouse) = @_; my $mouse = $o_mouse || {}; @@ -553,7 +575,7 @@ sub getSerialModem { my @modems; probeSerialDevices(); - foreach my $port (map { "ttyS$_" } (0..7)) { + foreach my $port (serialPorts()) { next if $mouse->{device} =~ /$port/; my $device = "/dev/$port"; next if !-e $device || !hasModem($device); @@ -569,9 +591,10 @@ sub getSerialModem { @modems; } +our $detect_serial_modem = 1; sub getModem { my ($modules_conf) = @_; - getSerialModem($modules_conf, {}), get_winmodems(); + ($detect_serial_modem ? getSerialModem($modules_conf, {}) : ()), get_winmodems(); } sub get_winmodems() { @@ -684,7 +707,6 @@ sub get_ids_from_sysfs_device { my $usb_root = -f "$dev_path/bInterfaceNumber" && "../" || -f "$dev_path/idVendor" && ""; my $is_pcmcia = -f "$dev_path/card_id"; my $sysfs_ids; - #my $bus = get_sysfs_field_from_link($dev_path, "bus"); my $bus = get_sysfs_field_from_link($dev_path, "subsystem"); #- FIXME: use $bus if ($is_pcmcia) { @@ -703,7 +725,7 @@ sub get_ids_from_sysfs_device { if ($bus eq 'pci') { my $device = basename(readlink $dev_path); my @ids = $device =~ /^(.{4}):(.{2}):(.{2})\.(.+)$/; - @{$sysfs_ids}{qw(pci_domain pci_bus pci_device pci_function)} = map { hex($_) } @ids if @ids; + @$sysfs_ids{qw(pci_domain pci_bus pci_device pci_function)} = map { hex($_) } @ids if @ids; } } $sysfs_ids; @@ -796,22 +818,22 @@ sub add_addons { sub get_pci_sysfs_path { my ($l) = @_; - sprintf('%04x:%02x:%02x.%d', $l->{pci_domain}, $l->{pci_bus}, $l->{pci_device}, $l->{pci_function}); + sprintf('%04x:%02x:%02x.%d', $l->{pci_domain}, $l->{pci_bus}, $l->{pci_device}, $l->{pci_function}); } my (@pci, @usb); + sub pci_probe__real() { add_addons($pcitable_addons, map { my %l; - @l{qw(vendor id subvendor subid pci_domain pci_bus pci_device pci_function pci_revision is_pciexpress media_type nice_media_type driver description)} = split "\t"; + @l{qw(vendor id subvendor subid pci_domain pci_bus pci_device pci_function pci_revision is_pciexpress media_type nice_media_type driver description)} = split "\t"; $l{$_} = hex $l{$_} foreach qw(vendor id subvendor subid); $l{bus} = 'PCI'; $l{sysfs_device} = '/sys/bus/pci/devices/' . get_pci_sysfs_path(\%l); \%l; } c::pci_probe()); } - sub pci_probe() { state $done; if (!$done) { @@ -828,10 +850,10 @@ sub usb_probe__real() { add_addons($usbtable_addons, map { my %l; - @l{qw(vendor id media_type driver description pci_bus pci_device)} = split "\t"; + @l{qw(vendor id media_type driver description pci_bus pci_device usb_port)} = split "\t"; $l{media_type} = join('|', grep { $_ ne '(null)' } split('\|', $l{media_type})); $l{$_} = hex $l{$_} foreach qw(vendor id); - $l{sysfs_device} = "/sys/class/usb_device/usbdev$l{pci_bus}.$l{pci_device}/device"; + $l{sysfs_device} = "/sys/bus/usb/devices/$l{pci_bus}-" . ($l{usb_port} + 1); $l{bus} = 'USB'; \%l; } c::usb_probe()); @@ -899,8 +921,8 @@ sub pcmcia_probe() { map { my $dir = "$dev_dir/$_"; my $get = sub { chomp_(cat_("$dir/$_[0]")) }; - my $class_dev = first(glob_("$dir/tty*")); - my $device = $class_dev && get_sysfs_field_from_link($dir, basename($class_dev)); + my $class_dev = first(glob_("$dir/tty/tty*")); + my $device = $class_dev && basename($class_dev); my $modalias = $get->('modalias'); my $driver = get_sysfs_field_from_link($dir, 'driver'); #- fallback on modalias result @@ -1026,7 +1048,10 @@ sub dmidecode() { my ($ver, @l) = run_program::get_stdout('dmidecode'); my $tab = "\t"; - if ($ver =~ /(\d+\.\d+)/ && $1 >= 2.7) { + + my ($major, $minor) = $ver =~ /(\d+)\.(\d+)/; + + if ($major > 2 || $major == 2 && $minor > 7) { #- new dmidecode output is less indented $tab = ''; #- drop header @@ -1055,9 +1080,7 @@ sub dmidecode_category { #- size in MB sub dmi_detect_memory() { my @l1 = map { $_->{'Enabled Size'} =~ /(\d+) MB/ && $1 } dmidecode_category('Memory Module'); -# my @l2 = map { $_->{'Form Factor'} =~ /^(SIMM|SIP|DIP|DIMM|RIMM|SODIMM|SRIMM)$/ && - my @l2 = map { $_->{'Form Factor'} =~ /^(SIMM|SIP|DIP|DIMM|FB-DIMM|RIMM|SODIMM|SRIMM)$/ && - + my @l2 = map { $_->{'Form Factor'} =~ /^(SIMM|SIP|DIP|DIMM|FB-DIMM|RIMM|SODIMM|SRIMM)$/ && ($_->{Size} =~ /(\d+) MB/ && $1 || $_->{Size} =~ /(\d+) kB/ && $1 * 1024); } dmidecode_category('Memory Device'); max(sum(@l1), sum(@l2)); @@ -1077,17 +1100,6 @@ sub computer_info() { }; } -sub isServer() { - computer_info()->{isServer} - || (any { $_->{Type} =~ /ECC/ } dmidecode_category('Memory Module')) - || dmidecode_category('System Information')->{Manufacturer} =~ /Supermicro/i - || dmidecode_category('System Information')->{'Product Name'} =~ /NetServer|Proliant|PowerEdge|eServer|IBM System x|ThinkServer/i - || matching_desc__regexp('LSI Logic.*SCSI') - || matching_desc__regexp('MegaRAID') - || matching_desc__regexp('NetServer') - || (any { $_->{'model name'} =~ /(Xeon|Opteron)/i } getCPUs()); -} - #- try to detect a laptop, we assume pcmcia service is an indication of a laptop or #- the following regexp to match graphics card apparently only used for such systems. sub isLaptop() { @@ -1106,6 +1118,17 @@ sub isLaptop() { || (any { member($_->{driver}, qw(ipw2100 ipw2200 ipw3945)) } pci_probe()); } +sub isServer() { + computer_info()->{isServer} + || (any { $_->{Type} =~ /ECC/ } dmidecode_category('Memory Module')) + || dmidecode_category('System Information')->{Manufacturer} =~ /Supermicro/i + || dmidecode_category('System Information')->{'Product Name'} =~ /NetServer|Proliant|PowerEdge|eServer|IBM System x|ThinkServer/i + || matching_desc__regexp('LSI Logic.*SCSI') + || matching_desc__regexp('MegaRAID') + || matching_desc__regexp('NetServer') + || (any { $_->{'model name'} =~ /(Xeon|Opteron)/i } getCPUs()); +} + sub BIGMEM() { arch() !~ /x86_64|ia64/ && $> == 0 && dmi_detect_memory() > 4 * 1024; } @@ -1149,7 +1172,7 @@ sub has_cpu_flag { } sub matching_types() { - { + +{ laptop => isLaptop(), 'touchpad' => hasTouchpad(), '64bit' => to_bool(arch() =~ /64/), @@ -1158,8 +1181,9 @@ sub matching_types() { } sub hasWacom() { find { $_->{vendor} == 0x056a || $_->{driver} =~ /wacom/ } usb_probe() } -sub usbWacom() { grep { $_->{vendor} eq '056a' } getInputDevices() } sub hasTouchpad() { any { $_->{Synaptics} || $_->{ALPS} || $_->{Elantech} } getInputDevices() } + +sub usbWacom() { grep { $_->{vendor} eq '056a' } getInputDevices() } sub usbKeyboards() { grep { $_->{media_type} =~ /\|Keyboard/ } usb_probe() } sub usbStorage() { grep { $_->{media_type} =~ /Mass Storage\|/ } usb_probe() } sub has_mesh() { find { /mesh/ } all_files_rec("/proc/device-tree") } @@ -1233,7 +1257,7 @@ sub probeall_unavailable_modules() { } probeall(); } -sub probeall_dkms_modules { +sub probeall_dkms_modules() { my @unavailable_modules = probeall_unavailable_modules() or return; require modalias; my $dkms_modules = modalias::parse_file_modules($::prefix . "/usr/share/ldetect-lst/dkms-modules.alias"); -- cgit v1.2.1