Wie bekomme ich eine Karte zur Festplattennutzung unter Linux?

0

Ich möchte eine Karte erstellen, welche Dateien wo auf die Festplatte geschrieben werden. Es sollte so etwas wie einen Verzeichnisbaum ausgeben und für jede Datei eine Liste von Sektoren ([10-20], [80-90], [60-70]), die zusammen die gesamte Datei bilden. zB um eine Visualisierung wie den alten Windows-Defragmentierer zu erstellen:

Windows defragmentieren

Gibt es dafür Tools?

Scott
quelle
1
Das Standardwerkzeug für Debian-Ableitungen ist Disk Usage Analyser( baobab). Dabei wird keine Fragmentierung angezeigt. Für einzelne Dateien (keine Verzeichnisse) können Sie jedoch die Sektoren anzeigen, die sie mit einem der in dieser Antwort beschriebenen Tools belegen . Ich kenne kein GUI-Tool.
AFH
"zeige die Sektoren, die es belegt" ... Angenommen, ich habe zum Erstellen meiner Visualisierung eine Datei, die einen Sektor belegt, aber nicht den gesamten Sektor (z. B. eine 8114-Byte-Datei, die über zwei 4096-Byte-Sektoren geschrieben wurde); Ist es sicher anzunehmen, dass der erste Sektor voll belegt ist, der zweite Sektor die ersten (8114 - 4096) Bytes belegt hat und die verbleibenden (4096 * 2-8114) Bytes des zweiten Sektors "Müll" sind, im Gegensatz zu eine andere Datei?
Scott
1
Ja, ich denke das ist der Fall. Ich habe in den 80er Jahren etwas über Dateisysteme gelernt, als das Betriebssystem Unix und nicht Linux war. Ich erinnere mich, dass eine der Optionen für kleine Dateien aus Platzgründen darin bestand, mehrere Dateien in einen physischen Sektor zu packen, obwohl ich mich jetzt nicht erinnern kann, was eine kleine Datei ausmachte (wahrscheinlich bis zu 128 oder 256 Byte), aber sie taten es nicht. Verwenden Sie nicht den freien Speicherplatz von Dateien mit mehreren Sektoren für kleine Dateien. Ich weiß nicht, ob moderne extN-Dateisysteme eine ähnliche Struktur verwenden, aber es wäre schade, wenn sie sie unter Linux verloren hätten. Große Dateien hatten wieder eine andere Struktur, sodass TB-Dateien auch in den 80er Jahren noch möglich waren!
AFH
Die Sprache, die Sie in Ihrem Kommentar verwendet haben, hat mir bei der Suche geholfen! Hier ist die Antwort auf meine Kommentarfrage: stackoverflow.com/questions/30133149/…
Scott
1
Interessanter Link. Zurück zu Ihrer ursprünglichen Frage, das meiste, was ich gelesen habe, deutet darauf hin, dass Fragmentierung normalerweise kein Problem auf extN-Dateisystemen ist, obwohl meine Tests die seltsame Datei mit Fragmenten in den Tausenden gefunden haben. Ich habe ein Skript geschrieben, das jede Datei findet, die Anzahl der Fragmente in jeder Datei zählt und dann in der Reihenfolge der Fragmentanzahl in einem Bericht sortiert: Um die Größe zu verwalten, lassen Sie alle nicht fragmentierten Dateien weg. Wenn dies wie eine Lösung erscheint, werde ich das Skript in einer Antwort einreichen, da es für einen Kommentar zu komplex ist.
AFH

Antworten:

2

Das Standardwerkzeug für Debian-Ableitungen ist Disk Usage Analyser( baobab), dies zeigt jedoch keine Fragmentierung.

Die einzige Möglichkeit, Fragmentierung anzuzeigen, besteht darin, einen Befehlszeilenprozess Datei für Datei mit einem der in dieser Antwort beschriebenen Tools zu verwenden .

Zu diesem Zweck schrieb ich ein Skript mit hdparm --fibmap:

#!/bin/bash
#
# frags MountPoint SkipFrags    Reports all files under MountPoint with more than SkipFrags fragments
#       MountPoint defaults to / (root file system)
#       SkipFrags  defaults to 1 (report all files with more than one fragment)
#                  (setting to 0 will report all files, including unfragmanted)
#
# The report is sorted in fragment count order and must be run as root 
#
[ "${1:0:1}" == "-" ] && \
    echo 'frags MountPoint SkipFrags    Reports all files under MountPoint with more than SkipFrags fragments' && \
    echo '      MountPoint defaults to / (root file system)' && \
    echo '      SkipFrags  defaults to 1 (report all files with more than one fragment)' && \
    echo '                 (setting to 0 will report all files, including unfragmanted)' && \
    echo 'The report is sorted in fragment count order and must be run as root' && \
    { return 1 2>/dev/null; exit 1; }
[ "$(whoami)" != "root" ] && { echo 'Must be run from "root"' >&2; return 13 2>/dev/null; exit 13; }
eof='***EOF***'    ; # End-of-file marker
{ find "$1"/ -mount -type f; echo "$eof"; } | \
    while read -r f; \
        do  [ "$f" == "$eof" ] && { echo -ne "\e[K" >&2; continue; }; \
            r=$(hdparm --fibmap "$f" | grep -E "^[ 0-9]+$" | wc -l); \
            [ $r -gt "${2:-1}" ] && { echo -ne "\e[K--- $r: ${f::$(($COLUMNS-${#r}-6))}\r" >&2; echo "$r: $f"; } \
        done | \
sort -nt :

Beachten Sie, dass Sie, obwohl ich das Skript so dokumentiert habe, dass es eine ganze Disc von ihrem Einhängepunkt aus scannt, die sortierten Ergebnisse für ein bestimmtes Verzeichnis erhalten können. Ich empfehle, dies zunächst in einem kleinen Verzeichnis zu tun, um sicherzustellen, dass es sinnvolle Ergebnisse liefert.

Der Prozess ist ziemlich langsam und die Sortierung bedeutet, dass Sie keine Ergebnisse erhalten, bis jede Datei gescannt wurde. Ich habe daher eine Diagnose hinzugefügt, sobald jede zu meldende Datei stderrgefunden wurde. Die Escape-Sequenz ist für xtermund setzt voraus, $COLUMNSdass sie von shopt -s checkwinsize; export COLUMNSin ~/.bashrc(oder einer anderen Initialisierungsdatei) festgelegt wird. Durch das Vermeiden von Zeilenumbrüchen wird das Skript durch Scrollen verlangsamt.

Ich habe [ ... ] &&statt if [ ... ]; thenverwendet, um die Verschachtelung zu reduzieren und das Skript abzukürzen. Die return 1 2>/dev/null; exit 1;Sequenz ist ein Trick, mit dem ich einen Fehlercode zurückgegeben habe, unabhängig davon, ob das Skript normal oder von einem ./ source-Befehl aufgerufen wird .

AFH
quelle
Ich habe dem findBefehl gerade einen wichtigen Parameter hinzugefügt : -mountStoppt das Durchlaufen anderer gemounteter Dateisysteme, was insbesondere auf gemounteten Netzwerkfreigaben zu Fehlern führt.
AFH
Weitere Tests haben ergeben, dass das Skript auf /und auf anderen physischen Bereitstellungen, z. B. /boot/efiauf Netzwerkfreigaben oder auf bestimmten Dateisystemtypen, z. B., einwandfrei funktioniert tmpfs. Ich weiß nicht, wie ich damit umgehen soll, oder gebe zumindest eine Fehlermeldung aus, dass das Dateisystem nicht unterstützt wird.
AFH
0

Normalerweise schreibe ich in Python. Wenn also jemand an einer Python-Version der Antwort von AFH interessiert ist. Meins hängt vom filefragBefehl ab. Dabei wird der Verzeichnisbaum beginnend mit dem Argument cli durchlaufen rootund der Dateiname, die Dateigröße und die Blockgröße erfasst. Es kann nützlich sein, Argumente hinzuzufügen, um die Blockgröße und dergleichen anzugeben, falls erforderlich.

import subprocess
import os
import re
import argparse

size = re.compile("(\d+) \(\d+ block")

def get_extents(root):
    for root, dirs, files in os.walk(root):
        for f in files:
            fullpath = os.path.abspath(os.path.join(root, f))
            output = subprocess.check_output(["filefrag", "-e", "-v", fullpath]).decode("utf-8")
            lines = output.splitlines()
            sizeline = lines[1]
            extentlines = lines[3:-1]
            print(fullpath)
            print("size in bytes:", size.search(sizeline).group(1))
            extents = []
            for extentline in extentlines:
                stuff = extentline.split()
                lower = stuff[3].strip(".")
                upper = stuff[4].strip(":")
                extents.append((lower, upper))
            print("extents:", extents)

if __name__ == "__main__":
    parser = argparse.ArgumentParser("get the extents of all the files")
    parser.add_argument("root", type=os.path.expanduser, help="the root folder to examine recursively on")

    args = parser.parse_args()
    get_extents(args.root)
Scott
quelle