uts (2.10+6) unstable; urgency=low

* Added illumos-3359-hostid-generation-should-be-more-predictable.patch
  * Added illumos-3518-incorrect-hostid-calculation.patch
  * illumos-kernel depends on driverdb
  * illumos-kernel does not ship or configure drivers database (aliases,
    classes, etc.)
This commit is contained in:
Igor Pashev 2013-09-21 20:35:48 +04:00
parent 2bd3cf565d
commit 2c9afe36eb
13 changed files with 237 additions and 339 deletions

View File

@ -1,3 +1,13 @@
uts (2.10+6) unstable; urgency=low
* Added illumos-3359-hostid-generation-should-be-more-predictable.patch
* Added illumos-3518-incorrect-hostid-calculation.patch
* illumos-kernel depends on driverdb
* illumos-kernel does not ship or configure drivers database (aliases,
classes, etc.)
-- Igor Pashev <pashev.igor@gmail.com> Sat, 21 Sep 2013 20:35:37 +0400
uts (2.10+5) unstable; urgency=low
* Don't ship usr/include/sys/iscsit/iscsit_common.h

View File

@ -25,7 +25,7 @@ Architecture: illumos-any
Section: kernel
Priority: optional
Pre-Depends: bootadm (>= 2.10-3)
Depends: ${misc:Depends}
Depends: ${misc:Depends}, driverdb
Description: illumos kernel and modules
Package: uts-dev

View File

@ -1,240 +0,0 @@
#!/usr/bin/perl
# Extract data from IPS manifests
# and write driver configuration files:
# /etc/driver_aliases,
# /etc/driver_classes,
# /etc/minor_perm,
# /etc/devlink.tab,
# /etc/name_to_major,
# /etc/security/device_policy,
# /etc/security/extra_privs.
use strict;
use warnings FATAL => 'all';
use Getopt::Long qw(:config no_ignore_case);
# All these array contain strings ending with "\n":
my @driver_aliases = (); # strings like 'e1000g "pci8086,1010"'
my @driver_classes = (); # strings like 'adpu320<tab>scsi'
my @minor_perm = (); # strings like 'devinfo:devinfo,ro 0444 root sys'
my @device_policy =
(); # strings like 'mm:* read_priv_set=none write_priv_set=none'
my @devlink_tab =
(); # strings like 'type=ddi_pseudo;minor1=cpqary3<tab>cpqary3\M2'
my @extra_privs = (); # strings like 'nskern:sys_devices'
my @name_to_major = (); # strings like 'mm 16'
# Drivers' major numbers:
my %major2name = (); # id => name
my %name2major = (); # name => id
# Default open privileges, must be first entry in the file:
push @device_policy, "* read_priv_set=none write_priv_set=none\n";
# -D i386_ONLY=
my %defs = ();
my $rootdir = '/tmp';
my $majors = 'debian/name_to_major';
my $arch = 'i386';
my @archs = qw/i386 sparc/;
sub usage() {
print <<USAGE;
Usage: $0 [options] [manifests] ...
or: cat manifest | $0 [options]
Options:
-D var=value Define a variable to substitute in manifests
E. g. if you want x86 drivers, set i386_ONLY
to empty string: -D i386_ONLY=
-r directory Create file tree under this directory ($rootdir)
This script will create all required directories,
including /etc. Every file will be overwritten.
-m file initial name2major file with predefined
major numbers ($majors)
-a arch Consider drivers for this architecture only ($arch),
supported values: @archs
--help, -h Show this message
USAGE
exit 1;
}
GetOptions(
'r=s' => \$rootdir,
'D=s' => \%defs,
'm=s' => \$majors,
'a=s' => \$arch,
'help|h' => sub { usage() },
) or usage();
sub set_major($$) {
my ( $name, $id ) = @_;
die "`$name' already defined ($name2major{$name})"
if exists $name2major{$name};
die "`$id' already defined ($major2name{$id})" if exists $major2name{$id};
$name2major{$name} = $id;
$major2name{$id} = $name;
}
sub new_major($) {
my ($name) = @_;
return if exists $name2major{$name};
my $newid = 1;
$newid++ while exists $major2name{$newid};
set_major( $name, $newid );
}
sub collect($) {
my $drv = $_[0];
my $name = '';
# For the case when name= does not go first:
if ( $drv =~ m/\bname=([a-zA-Z0-9_-]+)\b/ ) {
$name = $1;
}
else {
die "could not get a driver name from line `$drv'";
}
# http://stackoverflow.com/questions/168171/regular-expression-for-parsing-name-value-pairs
while (
$drv =~ s/((?:\\.|[^= ]+)*)=("(?:\\.|[^"\\]+)*"|(?:\\.|[^ "\\]+)*)// )
{
my ( $k, $v ) = ( $1, $2 );
$v =~ s/^"(.+)"$/$1/;
$v =~ s/^'(.+)'$/$1/;
if ( $k eq 'name' ) {
$name eq $v
or die
"We've read name= again and it differs from the previous: `$name' != `$v'";
}
elsif ( $k eq "alias" ) {
push @driver_aliases, qq($name "$v"\n);
}
elsif ( $k eq "perms" ) {
push @minor_perm, qq($name:$v\n);
}
elsif ( $k eq "clone_perms" ) {
push @minor_perm, qq(clone:$v\n); # Fuck you, IPS.
}
elsif ( $k eq "class" ) {
push @driver_classes, qq($name\t$v\n);
}
elsif ( $k eq "policy" ) {
my ($first_token) = split( /\s+/, $v );
$v = "* $v" if $first_token =~ /=/;
push @device_policy, qq($name:$v\n);
}
elsif ( $k eq "devlink" ) {
$v =~ s/\\t/\t/g;
push @devlink_tab, qq($v\n);
}
elsif ( $k eq "privs" ) {
push @extra_privs, qq($name:$v\n);
}
else {
die "Do not know what to do with `$k=$v'";
}
}
# Do it here to ensure $name is correct:
new_major($name);
}
sub read_manifest($) {
open( MF, '<', $_[0] ) or die "Could not open `$_[0]' for reading: $!";
# http://stackoverflow.com/questions/12799907/how-to-read-multi-line-values-from-a-file-using-perl
while (<MF>) {
# Maybe multiline:
$_ .= <MF> while s/\\\n// and not eof;
# Substitute variables:
foreach my $k ( keys %defs ) {
s/\Q$($k)\E/$defs{$k}/g;
}
# Ignore comments:
next if /^#/;
# Skip sparc drivers on i386 and vice versa.
# For common drivers variable ARCH must be defined
# (i386 or sparc, e. g. -D ARCH=i386)
if (/^set\s+name=variant\.arch\s+value=(\S+)/) {
$1 ~~ @archs
or die "arch `$1' is not within supported list: @archs";
last if $1 ne $arch;
}
if (/^driver/) {
chomp;
collect($_);
}
}
close(MF);
}
$arch ~~ @archs or die "Architecture `$arch' is not supported";
-d "$rootdir" or die "`$rootdir': not such directory.";
open( N2M, '<', $majors ) or die "Could not open `$majors' for reading: $!";
while (<N2M>) {
my ( $n, $m ) = split( /\s+/, $_ );
set_major( $n, $m );
}
close(N2M);
# Reading IPS manifests given in command line:
if (@ARGV) {
read_manifest($_) foreach (@ARGV);
}
else { # or from stdin:
while (<STDIN>) {
chomp;
read_manifest($_);
}
}
-d "$rootdir/etc"
or mkdir "$rootdir/etc"
or die "Could not mkdir `$rootdir/etc': $!";
-d "$rootdir/etc/security"
or mkdir "$rootdir/etc/security"
or die "Could not mkdir `$rootdir/etc/security': $!";
sub write_file($$) {
my ( $fname, $array_ref ) = @_;
open( DA, ">$fname" ) or die "Could not open `$fname' for writing: $!";
print DA foreach @{$array_ref};
close(DA);
}
# Asterisk (*) will go first. It is important for device_policy.
@device_policy = sort { $a cmp $b } @device_policy;
@devlink_tab = sort { $a cmp $b } @devlink_tab;
@driver_aliases = sort { $a cmp $b } @driver_aliases;
@driver_classes = sort { $a cmp $b } @driver_classes;
@extra_privs = sort { $a cmp $b } @extra_privs;
@minor_perm = sort { $a cmp $b } @minor_perm;
@name_to_major =
map { "$major2name{$_} $_\n" } sort { $a <=> $b } keys %major2name;
write_file( "$rootdir/etc/driver_aliases", \@driver_aliases );
write_file( "$rootdir/etc/driver_classes", \@driver_classes );
write_file( "$rootdir/etc/minor_perm", \@minor_perm );
write_file( "$rootdir/etc/name_to_major", \@name_to_major );
write_file( "$rootdir/etc/devlink.tab", \@devlink_tab );
write_file( "$rootdir/etc/security/device_policy", \@device_policy );
write_file( "$rootdir/etc/security/extra_privs", \@extra_privs );
exit(0);

View File

@ -1,13 +1,4 @@
usr/share/illumos-kernel/etc/*
boot/solaris/devicedb/master
debian/sock2path/default etc/sock2path.d/
debian/iu.ap /etc/
debian/mach /etc/
etc/dacf.conf
etc/name_to_sysnum
etc/security/priv_names
kernel/amd64/genunix

View File

@ -2,25 +2,7 @@
set -e
drv=/usr/share/illumos-kernel
install_file () {
if ! [ -e "$1" ]; then
echo "Installing new default file \`$1'"
gzip -d -c "$drv/$1" > "$1"
fi
}
do_configure() {
install_file /etc/devlink.tab
install_file /etc/driver_aliases
install_file /etc/driver_classes
install_file /etc/minor_perm
install_file /etc/name_to_major
install_file /etc/security/device_policy
install_file /etc/security/extra_privs
if ! [ -e /etc/path_to_inst ]; then
echo "Creating initial /etc/path_to_inst"
echo '#path_to_inst_bootstrap_1' > /etc/path_to_inst

View File

@ -1,17 +0,0 @@
# /dev/console and /dev/contty autopush setup
#
# major minor lastminor modules
wc -1 0 ldterm ttcompat
asy -1 0 ldterm ttcompat
xencons 0 0 ldterm ttcompat
ptsl 0 47 ldterm ttcompat
usbsacm -1 0 ldterm ttcompat
usbser_edge -1 0 ldterm ttcompat
usbsprl -1 0 ldterm ttcompat
usbsksp -1 0 ldterm ttcompat
usbftdi -1 0 ldterm ttcompat
ipsecesp -1 0 ipsecesp
ipsecah -1 0 ipsecah
pcser 0 255 ldterm ttcompat

View File

@ -1,9 +0,0 @@
# Load platform specific modules
# Order is reversed and is important
# Without pcplusmp only one CPU will be used
# (via module "uppc")
# XXX No more is known about this file and these modules
pcplusmp
apix
xpv_psm

View File

@ -1,4 +0,0 @@
md 85
devinfo 88
asy 106
did 239

View File

@ -0,0 +1,186 @@
commit 9e3e4df2a0f62bab8e8eb305949e7d35c55e9864
Author: Garrett D'Amore <garrett@dey-sys.com>
Date: Sat Nov 17 00:50:53 2012 -0800
3359 hostid generation should be more "predictable"
Reviewed by: Andy Giles <andy.giles@dey-sys.com>
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Reviewed by: Richard Elling <richard.elling@dey-sys.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
diff --git a/usr/src/uts/i86pc/os/startup.c b/usr/src/uts/i86pc/os/startup.c
index d8facc9..2495390 100644
--- a/usr/src/uts/i86pc/os/startup.c
+++ b/usr/src/uts/i86pc/os/startup.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
*/
/*
* Copyright (c) 2010, Intel Corporation.
@@ -1586,23 +1587,6 @@ startup_modules(void)
dispinit();
- /*
- * This is needed here to initialize hw_serial[] for cluster booting.
- */
- if ((h = set_soft_hostid()) == HW_INVALID_HOSTID) {
- cmn_err(CE_WARN, "Unable to set hostid");
- } else {
- for (v = h, cnt = 0; cnt < 10; cnt++) {
- d[cnt] = (char)(v % 10);
- v /= 10;
- if (v == 0)
- break;
- }
- for (cp = hw_serial; cnt >= 0; cnt--)
- *cp++ = d[cnt] + '0';
- *cp = 0;
- }
-
/* Read cluster configuration data. */
clconf_init();
@@ -1631,6 +1615,26 @@ startup_modules(void)
/*
+ * Originally clconf_init() apparently needed the hostid. But
+ * this no longer appears to be true - it uses its own nodeid.
+ * By placing the hostid logic here, we are able to make use of
+ * the SMBIOS UUID.
+ */
+ if ((h = set_soft_hostid()) == HW_INVALID_HOSTID) {
+ cmn_err(CE_WARN, "Unable to set hostid");
+ } else {
+ for (v = h, cnt = 0; cnt < 10; cnt++) {
+ d[cnt] = (char)(v % 10);
+ v /= 10;
+ if (v == 0)
+ break;
+ }
+ for (cp = hw_serial; cnt >= 0; cnt--)
+ *cp++ = d[cnt] + '0';
+ *cp = 0;
+ }
+
+ /*
* Set up the CPU module subsystem for the boot cpu in the native
* case, and all physical cpu resource in the xpv dom0 case.
* Modifies the device tree, so this must be done after
@@ -2721,6 +2725,11 @@ pat_sync(void)
* /etc/hostid does not exist, we will attempt to get a serial number
* using the legacy method (/kernel/misc/sysinit).
*
+ * If that isn't present, we attempt to use an SMBIOS UUID, which is
+ * a hardware serial number. Note that we don't automatically trust
+ * all SMBIOS UUIDs (some older platforms are defective and ship duplicate
+ * UUIDs in violation of the standard), we check against a blacklist.
+ *
* In an attempt to make the hostid less prone to abuse
* (for license circumvention, etc), we store it in /etc/hostid
* in rot47 format.
@@ -2728,6 +2737,67 @@ pat_sync(void)
extern volatile unsigned long tenmicrodata;
static int atoi(char *);
+/*
+ * Set this to non-zero in /etc/system if you think your SMBIOS returns a
+ * UUID that is not unique. (Also report it so that the smbios_uuid_blacklist
+ * array can be updated.)
+ */
+int smbios_broken_uuid = 0;
+
+/*
+ * List of known bad UUIDs. This is just the lower 32-bit values, since
+ * that's what we use for the host id. If your hostid falls here, you need
+ * to contact your hardware OEM for a fix for your BIOS.
+ */
+static unsigned char
+smbios_uuid_blacklist[][16] = {
+
+ { /* Reported bad UUID (Google search) */
+ 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05,
+ 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09,
+ },
+ { /* Known bad DELL UUID */
+ 0x4C, 0x4C, 0x45, 0x44, 0x00, 0x00, 0x20, 0x10,
+ 0x80, 0x20, 0x80, 0xC0, 0x4F, 0x20, 0x20, 0x20,
+ },
+ { /* Uninitialized flash */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ },
+ { /* All zeros */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+};
+
+static int32_t
+uuid_to_hostid(const uint8_t *uuid)
+{
+ /*
+ * Although the UUIDs are 128-bits, they may not distribute entropy
+ * evenly. We would like to use SHA or MD5, but those are located
+ * in loadable modules and not available this early in boot. As we
+ * don't need the values to be cryptographically strong, we just
+ * generate 32-bit vaue by xor'ing the various sequences together,
+ * which ensures that the enire UUID contributes to the hostid.
+ */
+ int32_t id = 0;
+
+ /* first check against the blacklist */
+ for (int i = 0; i < (sizeof (smbios_uuid_blacklist) / 16); i++) {
+ if (bcmp(smbios_uuid_blacklist[0], uuid, 16) == 0) {
+ cmn_err(CE_CONT, "?Broken SMBIOS UUID. "
+ "Contact BIOS manufacturer for repair.\n");
+ return ((int32_t)HW_INVALID_HOSTID);
+ }
+ }
+
+ for (int i = 0; i < 16; i++)
+ id ^= ((uuid[i]) << (8 * (i % sizeof (id))));
+
+ return (id);
+}
+
static int32_t
set_soft_hostid(void)
{
@@ -2740,6 +2810,7 @@ set_soft_hostid(void)
int32_t hostid = (int32_t)HW_INVALID_HOSTID;
unsigned char *c;
hrtime_t tsc;
+ smbios_system_t smsys;
/*
* If /etc/hostid file not found, we'd like to get a pseudo
@@ -2763,6 +2834,24 @@ set_soft_hostid(void)
hostid = (int32_t)atoi(hw_serial);
(void) modunload(i);
}
+
+ /*
+ * We try to use the SMBIOS UUID. But not if it is blacklisted
+ * in /etc/system.
+ */
+ if ((hostid == HW_INVALID_HOSTID) &&
+ (smbios_broken_uuid == 0) &&
+ (ksmbios != NULL) &&
+ (smbios_info_system(ksmbios, &smsys) != SMB_ERR) &&
+ (smsys.smbs_uuidlen >= 16)) {
+ hostid = uuid_to_hostid(smsys.smbs_uuid);
+ }
+
+ /*
+ * Generate a "random" hostid using the clock. These
+ * hostids will change on each boot if the value is not
+ * saved to a persistent /etc/hostid file.
+ */
if (hostid == HW_INVALID_HOSTID) {
tsc = tsc_read();
if (tsc == 0) /* tsc_read can return zero sometimes */

View File

@ -0,0 +1,37 @@
commit 2df37efa12a69b067c7197296dd802eb4b8a9e85
Author: Garrett D'Amore <garrett@dey-sys.com>
Date: Fri Feb 1 12:04:34 2013 -0800
3518 Incorrect hostid calculation
Reviewed by: Gordon Ross <gordon.w.ross@gmail.com>
Reviewed by: Richard Elling <richard.elling@dey-sys.com>
Reviewed by: Andy Giles <andy.giles@dey-sys.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>
Approved by: Dan McDonald <danmcd@nexenta.com>
diff --git a/usr/src/uts/i86pc/os/startup.c b/usr/src/uts/i86pc/os/startup.c
index eed0c80..ac3538f 100644
--- a/usr/src/uts/i86pc/os/startup.c
+++ b/usr/src/uts/i86pc/os/startup.c
@@ -2779,9 +2779,9 @@ uuid_to_hostid(const uint8_t *uuid)
* in loadable modules and not available this early in boot. As we
* don't need the values to be cryptographically strong, we just
* generate 32-bit vaue by xor'ing the various sequences together,
- * which ensures that the enire UUID contributes to the hostid.
+ * which ensures that the entire UUID contributes to the hostid.
*/
- int32_t id = 0;
+ uint32_t id = 0;
/* first check against the blacklist */
for (int i = 0; i < (sizeof (smbios_uuid_blacklist) / 16); i++) {
@@ -2795,7 +2795,8 @@ uuid_to_hostid(const uint8_t *uuid)
for (int i = 0; i < 16; i++)
id ^= ((uuid[i]) << (8 * (i % sizeof (id))));
- return (id);
+ /* Make sure return value is positive */
+ return (id & 0x7fffffff);
}
static int32_t

View File

@ -72,3 +72,5 @@ illumos-3667-ixgbe-unsupported-SFP-modules.patch
msghdr-xpg42.patch
sys_signal.h_sigset_t.patch
sys-socket.h-no-redefine-extname-in-kernel.patch
illumos-3359-hostid-generation-should-be-more-predictable.patch
illumos-3518-incorrect-hostid-calculation.patch

View File

@ -142,21 +142,13 @@ headers-stamp: patch-stamp fix-x-stamp
ln -sf /usr/include/thread.h debian/tmp/usr/include/thread.h
touch $@
drivers-stamp: debian/drivers.pl
mkdir -p debian/tmp/usr/share/illumos-kernel
rm -rf debian/tmp/usr/share/illumos-kernel/etc*
find usr/src/pkg/manifests/ -type f -name \*.mf | \
debian/drivers.pl $(mf-define) -r debian/tmp/usr/share/illumos-kernel
find debian/tmp/usr/share/illumos-kernel -type f -exec gzip -f -9 {} \;
touch $@
install: install-stamp
install-stamp: build-stamp
touch $@
binary binary-arch binary-indep: binary-stamp
binary-stamp: install-stamp drivers-stamp
binary-stamp: install-stamp
dh_testdir
dh_testroot
dh_installdirs

View File

@ -1,32 +0,0 @@
# See soconfig(1M) and sock2path.d(4)
#
# <family> <type> <protocol> <modules name or path (/dev/foo)>
#
1 1 0 /dev/ticlts
1 2 0 /dev/ticotsord
1 6 0 /dev/ticotsord
2 1 0 udp
2 1 17 udp
2 2 0 tcp
2 2 132 socksctp
2 2 257 socksdp
2 2 6 tcp
2 4 0 icmp
2 6 132 socksctp
24 4 0 rts
26 1 0 udp
26 1 17 udp
26 2 0 tcp
26 2 132 socksctp
26 2 257 socksdp
26 2 6 tcp
26 4 0 icmp
26 6 132 socksctp
27 4 2 /dev/keysock
28 2 0 /dev/nca
29 4 1 /dev/spdsock
30 1 0 /dev/rds
30 6 0 sockrds
31 1 0 trill
32 1 0 sockpfp
32 4 0 sockpfp