"Kann keinen Speicher zuweisen" beim Lesen vom SCSI-Band


7

Ich experimentiere mit einigen alten SCSI-Bandlaufwerken und habe einige Daten erfolgreich auf ein Band geschrieben, aber ich habe Probleme, sie wieder zurückzulesen.

# tar tvf /dev/st0
tar: /dev/st0: Cannot read: Cannot allocate memory
tar: At beginning of tape, quitting now
tar: Error is not recoverable: exiting now

# dd if=/dev/st0 of=test
dd: error reading '/dev/st0': Cannot allocate memory
0+0 records in
0+0 records out
0 bytes copied, 3.20155 s, 0.0 kB/s

Nach diesen Befehlen dmesgsagt:

st 10:0:3:0: [st0] Block limits 1 - 16777215 bytes.
st 10:0:3:0: [st0] Failed to read 65536 byte block with 512 byte transfer.
st 10:0:3:0: [st0] Failed to read 131072 byte block with 65536 byte transfer.
st 10:0:3:0: [st0] Failed to read 65536 byte block with 10240 byte transfer.
st 10:0:3:0: [st0] Failed to read 94208 byte block with 69632 byte transfer.
st 10:0:3:0: [st0] Failed to read 65536 byte block with 10240 byte transfer.
st 10:0:3:0: [st0] Failed to read 65536 byte block with 512 byte transfer.

Die meisten davon waren, weil ich verschiedene Blockgrößen mit der tar -bOption getestet habe , aber keine davon hatte einen Effekt.

Gelegentlich kann ich einige kB Daten vom ersten Block auf dem Band lesen (die Teer extrahieren kann, bis die Daten abgeschnitten werden), aber normalerweise schlägt dies fehl, wenn überhaupt keine Daten gelesen werden.

Ich habe (anscheinend) erfolgreich Daten auf Band geschrieben, das Band auf das andere Laufwerk verschoben, bis zum Ende der Daten gesucht und dann mehr geschrieben, sodass es keine Schwierigkeiten zu geben scheint, Daten auf das Laufwerk zu schreiben, nur sie zurückzulesen nochmal.

Ich verwende zwei LTO-3-Laufwerke. Einer ist ein HP Ultrium 920 mit halber Höhe und der andere ist ein HP Ultrium 960 mit voller Höhe. Beide haben dieses Problem. Ich habe es mit zwei verschiedenen SCSI-Karten versucht (einer LSI Logic Ultra320-Karte und einer Adaptec Ultra2 / SE 40 MB / s-Karte), die beide die gleichen Fehler verursachen.

Ich habe ein Kabel mit einem angeschlossenen Abschlusswiderstand ausprobiert (gab mir sogar auf der Ultra320-Karte 40 MB / s), dann ein Kabel mit zwei Anschlüssen, was bedeutete, dass ich nur ein Laufwerk anschließen konnte, sodass ich den "Term Power" -Jumper auf dem Laufwerk aktivierte Ich bin zu Ultra160 gekommen (obwohl sowohl das Laufwerk als auch der Controller Ultra320 sind), aber nichts davon hat etwas geändert, und währenddessen habe ich immer noch die gleichen Fehler beim Versuch, vom Laufwerk zu lesen.

Ich habe ein Downgrade von Linux-Kernel 4.10.13 auf 4.4.3 (die vorherige Version auf diesem Computer) durchgeführt und die Fehlermeldung ändert sich von "Speicher kann nicht zugeordnet werden" zu "Eingabe- / Ausgabefehler", aber das Problem bleibt das gleiche.

Irgendwelche Ideen, was diesen Fehler verursachen könnte?

BEARBEITEN : Das 40 MB / s-Problem wurde verursacht, weil ich einen aktiven SE-Terminator verwendet habe. Nachdem ich dies durch einen LVD-Terminator ersetzt hatte, stiegen die Geschwindigkeiten auf Ultra160. Ich glaube, ich brauche neue Kabel, um Ultra320 zu erreichen, aber das ist jetzt die doppelte Bandbandbreite (max. 80 MB / s), also ist es für mich vorerst in Ordnung. Es machte jedoch keinen Unterschied mit den Fehlermeldungen.

Antworten:


11

Ok, ich denke ich habe das herausgefunden.

TL; DR

Verwenden Sie ddstattdessen eine große Blockgröße, um vom Band zu lesen:

dd if=/dev/nst0 bs=1M | tar tvf -

Hintergrund

Wenn Sie auf Bänder schreiben, werden die Daten in Einheiten geschrieben, die als Blöcke bezeichnet werden. Dies sind wie Sektoren auf einer Festplatte. Während Festplattenblöcke viele Jahre lang auf 512 Byte festgelegt und erst kürzlich auf 4096 Byte-Blöcke verschoben wurden, können Bandblöcke auf eine beliebige Größe eingestellt werden.

Die Blockgröße, die Sie verwenden möchten, wird mit dem setblkUnterbefehl in festgelegt mt-st:

mt-st -f /dev/nst0 setblk 512    # Use 512-byte blocks
mt-st -f /dev/nst0 setblk 64k    # Use 65536-byte blocks

Wenn Sie einen Lesevorgang für das Laufwerk ausführen, werden Daten in blockgroßen Blöcken zurückgegeben. Sie können keinen halben Block lesen - die kleinste Datenmenge, die Sie von einem Band lesen können, ist ein Block. Dies kann natürlich eine beliebige Anzahl von tatsächlichen Bytes sein, abhängig von der Blockgröße.

Das heißt, wenn das von Ihnen verwendete Programm einen 16-KB-Speicherpuffer bereitstellt, können Sie mit 512-Byte-Blöcken bis zu 32 Blöcke gleichzeitig vom Band lesen, da diese genau in den 16-KB-Puffer passen. Sie können jedoch mit 64-KB-Blöcken nichts vom Band lesen, da Sie nicht einmal einen davon in den 16-KB-Puffer einpassen können, und denken Sie daran, dass Sie nicht weniger als einen ganzen Block gleichzeitig lesen können.

Wenn Sie dies versuchen, indem Sie einen Puffer verwenden, der für einen Block zu klein ist, gibt der Treiber (in diesem Fall der stSCSI-Bandtreiber) einen Speicherzuordnungsfehlercode zurück, um Sie darauf hinzuweisen, dass Ihr Lesepuffer zu klein ist, um auch nur einen zu speichern einzelner Block.

Um die Sache noch weiter zu verkomplizieren, unterstützen einige Bandlaufwerke (anscheinend die von mir verwendeten LTO-Laufwerke) auch Blöcke mit variabler Größe. Dies bedeutet, dass die Blockgröße durch die Größe jeder Schreiboperation bestimmt wird und jeder Block eine andere Größe als die letzte haben kann.

Dieser Modus wird mit einer Blockgröße von Null eingestellt:

mt-st -f /dev/nst0 setblk 0    # Use variable-sized blocks

Dies ist auch die Standardoption, da - vermutlich vermute ich hier - mit einem falsch konfigurierten Programm weniger Speicherplatz verschwendet wird. Wenn Sie beispielsweise 4 KB-Blöcke festgelegt haben, Ihr Programm jedoch nur Daten in Einheiten von jeweils 512 Byte geschrieben hat, besteht das Risiko, dass jeder 512-Byte-Datenblock 4 KB auf dem Band beansprucht.

Ursache

Wenn Sie jetzt alles zusammenfügen, werden Sie feststellen, dass ein Band hypothetisch einen 512-Byte-Block gefolgt von einem 64-KB-Block haben kann. Wenn das Programm das Band mit einem 16-KB-Puffer liest, liest es erfolgreich den ersten Block. Wenn es jedoch versucht, mehr zu lesen, kann es den folgenden 64-KB-Block nicht in seinen Puffer einfügen, sodass der Treiber einen zurückgibt Error.

Dies erklärt, warum ich die Cannot allocate memorymeiste Zeit Fehler bekam und gelegentlich konnte ich tar dazu bringen, die ersten paar Dateien zu extrahieren, aber dann bekam ich den Fehler erneut. Ich hatte die Blockgröße nicht mit festgelegt, mt-stdaher wurden beim Schreiben des Bandes standardmäßig Blöcke mit variabler Größe verwendet, und jetzt tarwurde ein zu kleiner Puffer zum Einlesen einiger dieser Blöcke verwendet.

tarEs gibt einige Optionen zum Festlegen der eigenen internen Blockgrößen, nämlich --blocking-factor, --read-full-recordsund --record-sizediese funktionieren jedoch nur, wenn tarsie zum direkten Lesen und Schreiben auf das Band verwendet werden.

Da ich über das mbufferProgramm auf das Band geschrieben habe, um das Glänzen des Bandes zu verringern, tarstimmte die Blockgröße im Archiv nicht mehr mit der Blockgröße auf dem Band überein. Dies --blocking-factorhatte nur geringe Auswirkungen - es würde das Lesen des ersten Blocks auf dem Band ermöglichen, der einen Header enthält, der angibt, tarwie hoch der Blockierungsfaktor sein soll , wobei er darauf umschaltet und den in der Befehlszeile angegebenen Wert ignoriert. Dies bedeutet, dass der zweite und die folgenden Blöcke nicht mehr gelesen werden können!

Lösung

Die Lösung besteht darin, ein anderes Programm zum Lesen vom Band zu verwenden - eines, bei dem die Größe des Lesepuffers auf einen Wert eingestellt werden kann, der groß genug ist, um den größten Block aufzunehmen, den wir wahrscheinlich sehen werden.

dd funktioniert dafür, und zur Not funktioniert das:

dd if=/dev/nst0 bs=256k | tar tvf -

Sie müssen möglicherweise erhöhen, 256kwenn Ihr Band größere Blöcke enthält, aber das hat bei mir funktioniert. 1Mfunktioniert auch gut, so dass es nicht wichtig zu sein scheint, wenn der Wert innerhalb des vernünftigen Rahmens zu groß ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.