Ho il disco rigido pieno di zero.
Come verificare se tutti i bit sul disco rigido sono zeri usando bash?
Ho il disco rigido pieno di zero.
Come verificare se tutti i bit sul disco rigido sono zeri usando bash?
Risposte:
od
sostituirà le esecuzioni della stessa cosa con *
, quindi puoi facilmente usarlo per scansionare i byte diversi da zero:
$ sudo od /dev/disk2 | head
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
234250000
| head
alla fine quello, in modo che se si scopre che l'unità non è azzerata, si arresta dopo aver prodotto l'output sufficiente per mostrare il fatto, invece di scaricare l'intero disco sullo schermo.
Ho scritto un breve programma C ++ per farlo, fonte disponibile qui .
Per costruirlo:
wget -O iszero.cpp https://gist.github.com/BobVul/5070989/raw/2aba8075f8ccd7eb72a718be040bb6204f70404a/iszero.cpp
g++ -o iszero iszero.cpp
Per eseguirlo:
dd if=/dev/sdX 2>/dev/null | ./iszero
Produrrà la posizione e il valore di tutti i byte diversi da zero. È possibile reindirizzare questo output su un file con >
, ad esempio:
dd if=/dev/sdX 2>/dev/null | ./iszero >nonzerochars.txt
Potresti provare a cambiare BUFFER_SIZE
per una migliore efficienza. Non sono sicuro di quale possa essere un valore ottimale. Notare che ciò influisce anche sulla frequenza con cui stampa l'avanzamento, il che influirà in qualche modo sulla velocità (la stampa dell'output sulla console è lenta ). Aggiungi 2>/dev/null
per eliminare l'output dei progressi.
Sono consapevole che questo non utilizza bash standard, né incorpora, ma non dovrebbe richiedere alcun privilegio aggiuntivo. La soluzione di @Hennes è ancora più veloce (non ho davvero ottimizzato nulla - questa è la soluzione ingenua); tuttavia, questo piccolo programma può darti un'idea di quanti byte ha perso il tuo tergicristallo e in quale posizione. Se disabiliti l'output di avanzamento, sarà comunque più veloce di quanto la maggior parte dei dischi rigidi consumer possa leggere (> 150 MB / s), quindi non è un grosso problema.
Una versione più veloce con output meno dettagliato è disponibile qui . Tuttavia, è ancora un po 'più lento della soluzione di @Hennes. Questo, tuttavia, si chiuderà sul primo carattere diverso da zero che incontra, quindi è potenzialmente molto più veloce se c'è un diverso da zero vicino all'inizio del flusso.
Aggiunta della fonte ai post per mantenere una risposta più autonoma:
#include <cstdio>
#define BUFFER_SIZE 1024
int main() {
FILE* file = stdin;
char buffer[BUFFER_SIZE];
long long bytes_read = 0;
long long progress = 0;
long long nonzero = 0;
while (bytes_read = fread(buffer, 1, BUFFER_SIZE, file)) {
for (long long i = 0; i < bytes_read; i++) {
progress++;
if (buffer[i] != 0) {
nonzero++;
printf("%lld: %x\n", progress, buffer[i]);
}
}
fprintf(stderr, "%lld bytes processed\r", progress);
}
fprintf(stderr, "\n");
int error = 0;
if (error = ferror(file)) {
fprintf(stderr, "Error reading file, code: %d\n", error);
return -1;
}
printf("%lld nonzero characters encountered.\n", nonzero);
return nonzero;
}
iszero /dev/sda
anziché richiedere che sia convogliato con qualcosa del genere iszero < /dev/sda
?
int main(int argc, char *argv[])
e poi FILE* file = fopen(argv[1], "r");
. Fatto correttamente includerebbe il controllo se l'argomento esiste realmente, il controllo degli errori si è aperto correttamente (fare un ferror
controllo aggiuntivo dopo il fopen
), ecc., Ma troppi problemi per un programma usa e getta.
gcc
non è necessariamente disponibile su tutte le distribuzioni Linux senza estrarre pacchetti aggiuntivi. Quindi di nuovo numpy non fa parte dei pacchetti standard di Python ...
-O3
e -march=native
potresti vedere alcune accelerazioni; ciò dovrebbe assicurarsi che GCC abiliti l'auto-vettorializzazione e utilizzi il meglio disponibile per la CPU corrente (AVX, SSE2 / SSE3, ecc.). Insieme a questo puoi giocare con la dimensione del buffer; diverse dimensioni del buffer potrebbero essere più ottimali con loop vettoriali (giocherei con 1 MB +, quello attuale è 1 KB).
@Bob
) nella chat: chat.stackexchange.com/rooms/118/root-access
Espandendo la risposta di Gordon, pv
fornisce un'indicazione di quanto è lungo il processo:
$ sudo pv -tpreb /dev/sda | od | head
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
9.76GiB 0:06:30 [25.3MiB/s] [=================> ] 59% ETA 0:04:56
Questa sembra una brutta soluzione inefficiente, ma se devi controllare solo una volta:
dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
Utilizzando dd per leggere dal disco sdX
. (sostituisci la X con l'unità da cui vuoi leggere),
quindi traduci tutti i byte zero non stampabili in qualcosa che possiamo gestire.
Successivamente contiamo i byte che possiamo gestire e controlliamo se è il numero giusto (usare wc -c
per quello), oppure saltiamo il conteggio e usiamo -s
o --squeeze-repeats
per comprimere tutte le ricorrenze multiple su un singolo carattere.
Quindi dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
dovrebbe stampare solo un singolo T.
Se vuoi farlo regolarmente, allora vuoi qualcosa di più efficiente.
Se vuoi farlo solo una volta, questo kludge può verificare che il tuo normale tergicristallo funzioni e che ti puoi fidare.
Per verificare solo, vedrai tutti i blocchi che non corrispondono elencati
sudo badblocks -sv -t 0x00 /dev/sdX
Oppure usa i badblock per scriverli e controllare:
sudo badblocks -svw -t 0x00 /dev/sdX
Il test distruttivo predefinito è la mia cancellazione sicura della scelta
sudo badblocks -svw /dev/sdX
Se qualcuno riesce a recuperare qualcosa dopo aver riempito l'unità con 0 e 1 alternati, quindi il loro complemento, quindi tutti gli 1, quindi tutti gli 0, con ogni passaggio verificato funzionava, buona fortuna a loro!
Esegue un buon controllo pre-implementazione anche su nuove unità
man badblocks
per altre opzioni
Non dire che è veloce, ma funziona ...
Il meglio di entrambi i mondi. Questo comando salterà i settori danneggiati:
sudo dd if=/dev/sdX conv=noerror,sync | od | head
Usa kill -USR1 <pid of dd>
per vedere i progressi.
Qualche tempo fa ero curioso AIO
. Il risultato è stato un programma di test di esempio che verifica la presenza di settori (blocchi da 512 byte) NUL
. Puoi vederlo come una variante di un rilevatore di regioni di file sparse . Penso che la fonte dica tutto.
NUL
emesso appare come 0000000000-eof
. Si noti che c'è un trucco nel programma, funzionefin()
non viene chiamata apposta alla linea 107 per fornire l'output mostrato.AIO
non è semplice come altri modi,AIO
è probabilmente il modo più veloce per tenere occupata la lettura di un'unità , perché il NUL
confronto viene eseguito mentre viene letto il blocco di dati successivo.AIO
, ma davvero non pensiamo questo vale il sforzo.)true
se il file è leggibile e tutto ha funzionato. Non restituisce false
se il file non èNUL
.NUL
funziona ancora completamente , poiché i buffer di memoria già contengono NUL
. Se qualcuno pensa che questo abbia bisogno di una correzione, nella riga 95 memcmp(nullblock, buf+off, SECTOR)
potrebbe leggere memcmp(nullblock, buf+off, len-off<SECTOR : len-off : SECTOR)
. Ma l'unica differenza è che il "end reporting" è forse un po 'casuale (non per un file che è interamente NUL
).memcmp()
risolve anche un altro problema sulle piattaforme, che non modificano la NUL
alloc()
memoria, perché il codice non lo fa. Ma questo potrebbe essere visto solo da file inferiori a 4 MiB, ma checknul
probabilmente è semplicemente eccessivo per un compito così piccolo;)HTH
/* Output offset of NUL sector spans on disk/partition/file
*
* This uses an AIO recipe to speed up reading,
* so "processing" can take place while data is read into the buffers.
*
* usage: ./checknul device_or_file
*
* This Works is placed under the terms of the Copyright Less License,
* see file COPYRIGHT.CLL. USE AT OWN RISK, ABSOLUTELY NO WARRANTY.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <aio.h>
#define SECTOR 512
#define SECTORS 40960
#define BUFFERLEN (SECTOR*SECTORS)
static void
oops(const char *s)
{
perror(s);
exit(1);
}
static void *
my_memalign(size_t len)
{
void *ptr;
static size_t pagesize;
if (!pagesize)
pagesize = sysconf(_SC_PAGESIZE);
if (len%pagesize)
oops("alignment?");
ptr = memalign(pagesize, len);
if (!ptr)
oops("OOM");
return ptr;
}
static struct aiocb aio;
static void
my_aio_read(void *buf)
{
int ret;
aio.aio_buf = buf;
ret = aio_read(&aio);
if (ret<0)
oops("aio_read");
}
static int
my_aio_wait(void)
{
const struct aiocb *cb;
int ret;
cb = &aio;
ret = aio_suspend(&cb, 1, NULL);
if (ret<0)
oops("aio_suspend");
if (aio_error(&aio))
return -1;
return aio_return(&aio);
}
static unsigned long long nul_last;
static int nul_was;
static void
fin(void)
{
if (!nul_was)
return;
printf("%010llx\n", nul_last);
fflush(stdout);
nul_was = 0;
}
static void
checknul(unsigned long long pos, unsigned char *buf, int len)
{
static unsigned char nullblock[SECTOR];
int off;
for (off=0; off<len; off+=SECTOR)
if (memcmp(nullblock, buf+off, SECTOR))
fin();
else
{
if (!nul_was)
{
printf("%010llx-", pos+off);
fflush(stdout);
nul_was = 1;
}
nul_last = pos+off+SECTOR-1;
}
}
int
main(int argc, char **argv)
{
unsigned char *buf[2];
int fd;
int io, got;
buf[0] = my_memalign(BUFFERLEN);
buf[1] = my_memalign(BUFFERLEN);
if (argc!=2)
oops("Usage: checknul file");
if ((fd=open(argv[1], O_RDONLY))<0)
oops(argv[1]);
aio.aio_nbytes = BUFFERLEN;
aio.aio_fildes = fd;
aio.aio_offset = 0;
io = 0;
my_aio_read(buf[io]);
while ((got=my_aio_wait())>0)
{
unsigned long long pos;
pos = aio.aio_offset;
aio.aio_offset += got;
my_aio_read(buf[1-io]);
checknul(pos, buf[io], got);
io = 1-io;
}
if (got<0)
oops("read error");
printf("eof\n");
close(fd);
return 0;
}
Volevo pubblicare questa soluzione intelligente da una domanda simile ma precedente, pubblicata da un utente che non ha effettuato l'accesso per un po ':
C'è un dispositivo
/dev/zero
su un sistema Linux che dà sempre zero quando viene letto.Quindi, che ne dici di confrontare il tuo disco rigido con questo dispositivo:
cmp /dev/sdX /dev/zero
Se tutto va bene con l'azzeramento del disco rigido, terminerà con:
cmp: EOF on /dev/sdb
dicendoti che i due file sono uguali fino a quando non arriva alla fine del disco rigido. Se sul disco rigido è presente un bit diverso da zero
cmp
verrà indicato dove si trova nel file.Se il
pv
pacchetto è installato, allora:pv /dev/sdX | cmp /dev/zero
farà la stessa cosa con una barra di avanzamento per farti divertire mentre controlla il tuo disco (l'EOF sarà ora su STDIN anziché su sdX).