Dear Martin,

On 11/09/16 00:45, Martin K. Petersen wrote:
"Paul" == Paul Menzel <[email protected]> writes:

Paul> Updating from Linux 4.4.X to Linux 4.8.4, we noticed that the
Paul> 3ware devices under `/dev` – `/dev/twa0`, `/dev/twa1`, … – map to
Paul> the controllers differently.

Paul> This unfortunately breaks quite a lot of our scripts, as we depend
Paul> on the fact that the first controller is also in the front.

It's not the 3ware drivers since they have not been updated in a long
time (since way before 4.4).

Yes, that’s what made me wonder too.

Linux does not provide device discovery ordering guarantees. You need to
fix your scripts to use UUIDs, filesystem labels, or DM devices to get
stable naming.

Indeed. But it worked for several years, so that *something* must have changed that the ordering of the result of `getdents64` is different now.

Fixing the scripts is unfortunately not that easy, as `tw_cli` is a proprietary tool [1], and we do not have the sources. It does a `readdir()`.

open("/proc/scsi/3w-9xxx", O_RDONLY|O_NONBLOCK|O_DIRECTORY) = -1 ENOENT (No 
such file or directory)
open("/sys/class/scsi_host", O_RDONLY|O_NONBLOCK|O_DIRECTORY) = 3
fstat(3, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
getdents64(3, /* 12 entries */, 4096)   = 368
stat("/sys/class/scsi_host/host0/stats", 0x7fffafd05290) = -1 ENOENT (No such 
file or directory)
stat("/sys/class/scsi_host/host9/stats", {st_mode=S_IFREG|0444, st_size=4096, 
...}) = 0
open("/sys/class/scsi_host/host9/stats", O_RDONLY) = 4
read(4, "3w-9xxx Driver v", 16)         = 16
close(4)                                = 0
open("/dev/twa0", O_RDWR)               = 4
close(4)                                = 0
stat("/sys/class/scsi_host/host7/stats", 0x7fffafd05290) = -1 ENOENT (No such 
file or directory)
stat("/sys/class/scsi_host/host5/stats", 0x7fffafd05290) = -1 ENOENT (No such 
file or directory)
stat("/sys/class/scsi_host/host3/stats", 0x7fffafd05290) = -1 ENOENT (No such 
file or directory)
stat("/sys/class/scsi_host/host1/stats", 0x7fffafd05290) = -1 ENOENT (No such 
file or directory)
stat("/sys/class/scsi_host/host8/stats", {st_mode=S_IFREG|0444, st_size=4096, 
...}) = 0
open("/sys/class/scsi_host/host8/stats", O_RDONLY) = 4
read(4, "3w-9xxx Driver v", 16)         = 16
close(4)                                = 0
open("/dev/twa1", O_RDWR)               = 4
close(4)                                = 0
stat("/sys/class/scsi_host/host6/stats", 0x7fffafd05290) = -1 ENOENT (No such 
file or directory)
stat("/sys/class/scsi_host/host4/stats", 0x7fffafd05290) = -1 ENOENT (No such 
file or directory)
stat("/sys/class/scsi_host/host2/stats", 0x7fffafd05290) = -1 ENOENT (No such 
file or directory)
getdents64(3, /* 0 entries */, 4096)    = 0
close(3)                                = 0
open("/proc/devices", O_RDONLY) = 3

Please find attached a wrapper from my colleague, using name spaces to ensure the ordering, that `tw_cli` expects.


Kind regards,

Paul


[1] https://wiki.hetzner.de/index.php/3Ware_RAID_Controller/en
#! /usr/bin/perl
use strict;
use warnings;

sub sort_host {
        my ($n1,$n2);
        ($n1)=$a=~/^host(\d+)$/ and ($n2)=$b=~/^host(\d+)$/ and return $n1 <=> 
$n2;
        return $a cmp $b;
}


our $SYS_unshare=272;      # /usr/include/asm/unistd_64.h
our $CLONE_NEWNS=0x20000;  # /usr/include/linux/sched.h

my $pid=fork;
defined $pid or die "$!\n";
unless ($pid) {
        opendir my $d,"/sys/class/scsi_host";
        my @names=sort sort_host grep !/^\.\.?$/,readdir $d;

        syscall($SYS_unshare,$CLONE_NEWNS) and die "$!\n";
        -d '/tmp/sysfs' or mkdir("/tmp/sysfs") or die "/tmp/sysfs: $!\n";
        system 'mount','-tsysfs','BLA','/tmp/sysfs' and exit 1;
        system 'mount','-ttmpfs','BLA','/sys/class/scsi_host' and exit 1;

        for my $name (reverse @names) {
                
symlink("/tmp/sysfs/class/scsi_host/$name","/sys/class/scsi_host/$name") or die 
"/sys/class/scsi_host/$name: $!\n";
        }
        exec '/root/bin/tw_cli.exe',@ARGV;
        die "$!\n";
}
wait;
$? and exit 1;

Reply via email to