Holen Sie sich den Geräteknoten nach Haupt- / Nebenzahlpaar

12

Jeder Geräteknoten unter /devhat ein eigenes Haupt- / Nebennummernpaar. Ich weiß, dass wir dieses Zahlenpaar wie folgt vom Geräteknoten abrufen können stat:

stat -c 'major: %t minor: %T' <file>

Oder ls -lzeigt auch diese Zahlen.

Aber wie können wir Geräteknoten durch gegebene Haupt- und Nebenzahlen erhalten? Der einzige Weg, den ich kenne, ist eine Art ls -l+ awkTrick, aber ich hoffe wirklich, dass es eine bessere Lösung gibt.

Dmitry Frank
quelle
@mikeserv, ja, ich weiß, dass einige Geräte diese Nummern gemeinsam nutzen können. In meiner ersten Frage habe ich erwähnt: "Geräteknoten abrufen". Idealerweise möchte ich eine Liste mit allen Geräteknoten erhalten, deren Haupt- / Nebennummern übereinstimmen, ein Knoten pro Zeile. Das ist seltsam, dass wir dafür kein Werkzeug haben. Danke übrigens für die Antwort!
Dmitry Frank

Antworten:

7

Ich habe einen einfacheren Ansatz mit dem Pseudofilesystem sys gefunden. Unter / sys / dev haben Sie die Geräte nach Typ und dann nach Major / Minor sortiert. Die Datei uevent enthält den Gerätenamen und eine Reihe weiterer Informationen.

So zum Beispiel

  for file in $(find /sys/dev/ -name 7:0); do  
      source ${file}/uevent; echo $DEVNAME;
  done;

Echos,

loop0
vcs

Hinweis: Dies wurde in Debian Wheezy getestet

xae
quelle
Rückwärts vom Entwicklernamen zu finden:for file in $(ls /sys/dev/block/ ); do source /sys/dev/block/${file}/uevent; if [ "$DEVNAME" == "sda1" ] ; then echo ${file}; fi done;
BBK
5

Nicht sicher was du meinst.

mknod foo b 8 0

Erstellt die fooals Blockgerät bezeichnete Gerätedatei mit Major 8 und Minor 0. Wenn Sie eine oder mehrere der Dateien /devmit demselben Typ, Major und Minor, suchen möchten, können Sie (mit zsh) Folgendes tun :

  • Für Blockgerät 8:0:

    $ zmodload zsh/stat
    $ ls -ld /dev/**/*(-D%be:'zstat -H s $REPLY && (($s[rdev] == 8<<8+0))':)
    lrwxrwxrwx 1 root root    6 Aug 23 05:28 /dev/block/8:0 -> ../sda
    lrwxrwxrwx 1 root root    9 Aug 23 05:28 /dev/disk/by-id/ata-KINGSTON_SNV455S234GB_07MA10014418 -> ../../sda
    brw-rw---- 1 root disk 8, 0 Aug 23 05:28 /dev/sda
    
  • für char Gerät 226:0:

    $ ls -ld /dev/**/*(-D%ce:'zstat -H s $REPLY && (($s[rdev] == 226<<8+0))':)
    lrwxrwxrwx  1 root root      12 Aug 23 05:28 /dev/char/226:0 -> ../dri/card0
    crw-rw----+ 1 root video 226, 0 Aug 23 05:28 /dev/dri/card0
    

Beachten Sie, dass alles Dateien in erstellen kann /dev. Früher war es ein Skript, das dort statische Dateien erstellte. Irgendwann hatten Sie sogar ein spezielles Dateisystem à la /proc.

In modernen Linux-Versionen udevbasiert es normalerweise auf Eingaben des Kernels.

Der Name, den es für die Basisgerätedatei wählt, basiert auf dem DEVNAMEvom Kernel bereitgestellten. udevRegeln können dies ändern, tun dies jedoch im Allgemeinen nicht, und einige udevRegeln fügen der Einfachheit halber weitere Symlinks hinzu (wie die anderen /dev/disk/by...).

Sie können von Dur: Moll zu Kernel wechseln, DEVNAMEindem Sie Folgendes betrachten:

$ sed -n 's/^DEVNAME=//p' /sys/dev/block/8:0/uevent
sda
$ sed -n 's/^DEVNAME=//p' /sys/dev/char/226:0/uevent
dri/card0

Sie können diese Informationen auch aus der udevDatenbank abrufen, wie mikeserv gezeigt hat.

Stéphane Chazelas
quelle
5

Anscheinend kann es einfacher gemacht werden udevadm, und ich habe gerade herausgefunden, wie.

Um das DEVNAMEvon udevadmIhnen zu bekommen , müssen Sie nur Folgendes tun:

udevadm info -rq name $PATH

Wenn Sie beispielsweise den /devNamen wissen möchten, für den /sys/dev/char/5:1Sie Folgendes tun würden:

udevadm info -rq name /sys/dev/char/5:1

AUSGABE

/dev/console

Die -rOption besteht darin, einen --rooted-Pfad anzugeben - ohne diesen wäre das obige Ergebnis schreibgeschützt console. Die -qOption gibt eine Datenbank an --queryund nimmt hier den Operanden name- weil wir das wollen DEVNAME.

Ein sehr einfaches Mittel, um den Pfad zu einem Zeichen- und / oder Blockgerät zu finden, wenn nur die Haupt-: Nebenzahlen wie folgt aussehen:

mmdev() for d in /sys/dev/[cb]*/$1:$2
        do  [ -e "$d" ] || return
            printf %c:%s: "${d#/*/*/}" "${d##*/}"
            udevadm info -rq name "$d"
        done

Also rennen:

mmdev 8 0

druckt ...

b:8:0:/dev/sda

Hier ist der erste, den ich geschrieben habe.

majminpath() {
    set -- ${1##*[!0-9]*} ${2##*[!0-9]*}
    udevadm info --export-db |
    sed 's|^[^=]*DEVNAME=||
         \|^[^/]|!h;/MAJOR=/N
         \|='"$1\n.*=${2?}"'$|!d;g'
}

Dadurch wird nur die udevadm info --export-dbAusgabe nach übereinstimmenden Nummern durchsucht . Die Ausgabe sieht aus wie:

P: /devices/virtual/vc/vcsa4
N: vcsa4
E: DEVNAME=/dev/vcsa4
E: DEVPATH=/devices/virtual/vc/vcsa4
E: MAJOR=7
E: MINOR=132
E: SUBSYSTEM=vc

P: /devices/virtual/vc/vcsa5
N: vcsa5
E: DEVNAME=/dev/vcsa5
E: DEVPATH=/devices/virtual/vc/vcsa5
E: MAJOR=7
E: MINOR=133
E: SUBSYSTEM=vc

#...and so on

Der Workflow ist wie folgt:

  • Versuchen Sie, die [^=]*DEVNAME=Zeichenfolge vom Kopf jeder Zeile zu entfernen

  • Wenn eine Zeile kein erstes Zeichen enthält oder das erste Zeichen /diese Zeile über das halte Leerzeichen kopiert

  • Wenn eine Zeile übereinstimmt, MAJOR=fügen Sie die Next-Eingabezeile an den Musterbereich an

  • Wenn der Musterraum zwei Zeilen enthält, die übereinstimmen, =$1\n.*=$2$kopieren Sie den halten Raum über den Musterraum und drucken Sie ihn automatisch. Andernfalls löschen Sie den Musterbereich

Also wenn ich das tue:

majminpath 7 133 ; majminpath 8 0 ; majminpath 8 1

AUSGABE

/dev/vcsa5
/dev/sda
/dev/sda1

Wie @xae hervorhebt, können Geräte vom Typ Block / Char Maj: Min-Kombinationen gemeinsam nutzen, sodass möglicherweise mehr als ein Pfad pro Aufruf gedruckt wird.

mikeserv
quelle
1
Leider ist es nicht so einfach, ein Block und ein Zeichengerät können dieselbe Hauptnummer haben. Schauen Sie sich die Datei / proc / Geräte an.
Xae
Ich muss das Subsystem überprüfen - das stimmt. Danke, @xae.
Mikeserv
1

Leider wurde die /sys/devHierarchie erst in 2.6.27 zum Kernel hinzugefügt ( vgl. Das relevante Commit für die Kernel-Codebasis), daher benötigen wir einen „gegabelten“ Ansatz.

Lassen $Mund $mjeweils die Haupt- und Neben Anzahl unserer Gerätedatei sein.

Post 2.6.27 Kernel

Wie von anderen vorgeschlagen, setzt der einfachste Ansatz die Leistung des sysfs„virtuellen“ Dateisystems frei, indem direkt nach Dateien gesucht wird, die $M:$munter dem Ordner benannt sind /sys/dev(mehr als eine Datei ist zu erwarten, wenn wir nicht wissen, ob unser Gerät ein Zeichen ist). oder eine blockbasierte) und dann Beschaffung der ueventDatei (in einer Unterschale, um eine Verschmutzung des Namespace zu verhindern):

for file in $(find /sys/dev/ -name $M:$m)
do
    (
        source ${file}/uevent
        echo $DEVNAME
    )
done

Kernel vor 2.6.27

Nehmen wir der Einfachheit halber an, dass unsere Datei ein Blockgerät ist (ein ähnlicher Ansatz gilt für Zeichengeräte). Wir werden in der $M:$mgesamten /sys/blockHierarchie nach der Zeichenfolge suchen , indem wir (unter diesem Ordner) den Inhalt jeder Datei untersuchen, deren Name zufällig lautet dev. Wenn /sys/block/<...>/<DEV>/deves sich um eine solche Datei DEVhandelt, muss dies der Name unseres Geräts sein:

dirname "$(find "/sys/block" -name dev | xargs -r grep -l ^$M:$m$)"
Roberto Reale
quelle
0

Unter Linux ist es möglich, bestimmte Dateien im /procvirtuellen Dateisystem zu nutzen.

$ grep '8[[:blank:]]\+1[[:blank:]]\+' /proc/partitions 
   8        1   29309568 sda1

$ grep '8:1[[:blank:]]' /proc/self/mountinfo 
28 0 8:1 / / rw,relatime shared:1 - ext4 /dev/sda1 rw,data=ordered

Die einfache Form des Musters liefert bereits Informationen über das gewünschte Gerät in der Ausgabe, es ist jedoch auch eine zusätzliche Filterung möglich, um nur eine bestimmte Zeichenfolge zu extrahieren.

Sergiy Kolodyazhnyy
quelle
0

Es gibt eine Bibliotheksfunktion: makedev()

#include <sys/sysmacros.h>
dev_t makedev(unsigned int maj, unsigned int min);

Bei gegebenen Haupt- und Nebengeräte-IDs kombiniert makedev () diese, um eine Geräte-ID zu erstellen, die als Funktionsergebnis zurückgegeben wird.

Weitere Informationen finden Sie unter: http://man7.org/linux/man-pages/man3/major.3.html

Krishna Kanth Yenumula
quelle