कैसे सत्यापित करें कि हार्ड ड्राइव लिनक्स में शून्य से भरा है?


16

मेरे पास जीरो से हार्ड ड्राइव है।

कैसे जांच करें कि हार्ड ड्राइव पर सभी बिट्स बैश का उपयोग कर रहे हैं?


क्या जीरो के साथ पूरी ड्राइव को ओवरराइट करना स्वीकार्य होगा? या क्या आपको वास्तव में वर्तमान सामग्रियों की पुष्टि करने की आवश्यकता है?
बॉब

मैं यह सत्यापित करना चाहता हूं कि हार्ड ड्राइव शून्य से भरा है।
gkfvbnhjh2

1
सिद्धांत रूप में डेटा स्वच्छता उपकरणों में बग हो सकता है जो कुछ डेटा को बरकरार रखता है। मुझे यकीन नहीं है कि हर बिट शून्य है। तो मैं कैसे जांच करूं कि क्या hdd जीरो से भरा है?
gkfvbnhjh2

शून्य क्यों? क्या आप ज़ीरो और 1s को कई बार अनियमित रूप से नहीं लिखेंगे?

13
क्योंकि 1s 0s की तुलना में संकरे होते हैं - आप उनके बीच पुराने डेटा को अधिक आसानी से देख सकते हैं।
क्रिस

जवाबों:


29

odउसी चीज़ के रनों को प्रतिस्थापित करेगा *, ताकि आप इसे नॉनज़रो बाइट्स के लिए स्कैन करने के लिए आसानी से उपयोग कर सकें:

$ sudo od /dev/disk2 | head
0000000    000000  000000  000000  000000  000000  000000  000000  000000
*
234250000

8
मैं उसके | headअंत में जोड़ दूंगा , ताकि अगर यह पता चले कि ड्राइव शून्य नहीं है, तो यह पूरी ड्राइव को स्क्रीन पर डंप करने के बजाय, तथ्य दिखाने के लिए पर्याप्त उत्पादन के बाद बंद हो जाता है।
वायज़र्ड

2
@Wyzard: उत्कृष्ट विचार; मैं इसे अपने उत्तर में जोड़ूंगा।
गॉर्डन डेविसन

8

मैंने ऐसा करने के लिए एक छोटा C ++ प्रोग्राम लिखा है, जो यहाँ उपलब्ध है

इसे बनाने के लिए:

wget -O iszero.cpp https://gist.github.com/BobVul/5070989/raw/2aba8075f8ccd7eb72a718be040bb6204f70404a/iszero.cpp
g++ -o iszero iszero.cpp

इसे चलाने के लिए:

dd if=/dev/sdX 2>/dev/null | ./iszero

यह किसी भी नॉनजरो बाइट्स की स्थिति और मूल्य को आउटपुट करेगा। आप इस आउटपुट को किसी फ़ाइल के साथ रीडायरेक्ट कर सकते हैं >, जैसे:

dd if=/dev/sdX 2>/dev/null | ./iszero >nonzerochars.txt

आप BUFFER_SIZEबेहतर दक्षता के लिए बदलाव की कोशिश कर सकते हैं । मुझे यकीन नहीं है कि एक इष्टतम मूल्य क्या हो सकता है। ध्यान दें कि यह भी प्रभावित करता है कि यह कितनी बार प्रगति को प्रिंट करता है, जो कुछ हद तक गति को प्रभावित करेगा (कंसोल में मुद्रण धीमा है )। 2>/dev/nullप्रगति आउटपुट से छुटकारा पाने के लिए जोड़ें ।

मुझे पता है कि यह मानक बैश का उपयोग नहीं कर रहा है, न ही बिलिन भी, लेकिन इसके लिए किसी अतिरिक्त विशेषाधिकार की आवश्यकता नहीं है। @ हेन्स का समाधान अभी भी तेज है (मैंने वास्तव में कुछ भी अनुकूलित नहीं किया है - यह भोला समाधान है); हालाँकि, यह छोटा सा कार्यक्रम आपको एक बेहतर विचार दे सकता है कि आपके वाइपर से कितने बाइट छूट गए हैं, और किस स्थान पर हैं। यदि आप प्रगति आउटपुट को अक्षम करते हैं, तो यह अभी भी सबसे तेज होगा क्योंकि अधिकांश उपभोक्ता हार्ड ड्राइव (> 150 एमबी / एस) पढ़ सकते हैं, इसलिए यह एक बड़ा मुद्दा नहीं है।

कम वर्बोज़ आउटपुट वाला तेज़ संस्करण यहां उपलब्ध है । हालांकि, यह अभी भी @Hennes समाधान की तुलना में थोड़ा धीमा है। यह एक, हालांकि, पहले नॉनज़ेरो चरित्र पर छोड़ देगा, जिससे उसका सामना होता है, यदि यह स्ट्रीम की शुरुआत में नॉनज़रो है तो संभवतः यह बहुत तेज़ है।


उत्तर को बेहतर रखने के लिए पोस्ट करने के लिए स्रोत जोड़ना

#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इसे किसी चीज़ के साथ पाइप करने की आवश्यकता के बजाय उपयोग करना iszero < /dev/sda?
हाशिम

1
@ हाशिम यह काफी पहले कमोबेश एक थका देने वाले कार्यक्रम के रूप में लिखा गया था (आजकल मैं कम से कम इसे स्क्रिप्टिंग भाषा में करूँगा जैसे कि संकलित सी के बजाय पायथन) ... उन्होंने कहा, अगर आप तर्क लेना चाहते थे। सबसे सरल तरीका है, यह कहीं int main(int argc, char *argv[])और इसे बनाने की तर्ज पर होगा FILE* file = fopen(argv[1], "r");। ठीक से यह ferrorजाँचना शामिल होगा कि क्या तर्क वास्तव में मौजूद है, त्रुटि की जाँच सफल खुला (के बाद एक अतिरिक्त जाँच करें fopen), आदि, लेकिन एक विचलित कार्यक्रम के लिए बहुत अधिक परेशानी।
बॉब

1
@ हाशिम को संदेह है कि सिम्पी में सिमड वेक्टरड ऑपरेशंस सी में वेक्टराइज्ड निर्देशों के करीब होंगे और यह मानकर कि सी कंपाइलर भोले सी प्रोग्राम में लूप को वेक्टर करने के लिए काफी स्मार्ट है। सुनिश्चित करने के लिए बेंचमार्क करना होगा; दुर्भाग्य से मेरे पास वास्तव में अभी ऐसा करने का समय नहीं है। पायथन का मुख्य लाभ (एट अल।) यह आम तौर पर उपलब्ध है और संकलक के बिना चलाने योग्य है, जबकि gccअतिरिक्त पैकेज नीचे खींचने के बिना सभी लिनक्स डिस्ट्रो पर आवश्यक रूप से उपलब्ध नहीं है। फिर फिर से खस्ता नहीं है मानक पायथन पैकेजों का हिस्सा ...
Bob

1
@ हाशिम यदि आप के साथ संकलन करते हैं -O3और -march=nativeआप कुछ स्पीडअप देख सकते हैं; यह सुनिश्चित करना चाहिए कि जीसीसी ऑटो-वेक्टराइजेशन को सक्षम बनाता है और आपके वर्तमान सीपीयू (एवीएक्स, एसएसई 2 / एसएसई 3, आदि) के लिए सबसे अच्छा उपलब्ध है। इसके साथ ही आप बफर आकार के साथ खेल सकते हैं; विभिन्न बफर आकार वेक्टराइज़्ड लूप के साथ अधिक इष्टतम हो सकते हैं (मैं 1 एमबी + के साथ खेलूंगा, वर्तमान एक 1kB है)।
बॉब

1
@ हाशिम ऊपर टिप्पणी संपादित, मामले में आप नहीं देखा था। इसके अलावा, यदि आप आगे चर्चा करना चाहें, तो आप मुझसे @Bobचैट में ( ) चैट कर सकते हैं: chat.stackexchange.com/rooms/118/root-access
Bob

7

गॉर्डन के जवाब पर विस्तार करते हुए, pvयह संकेत देता है कि प्रक्रिया कितनी दूर है:

$ 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

यह एक बड़ी हार्ड ड्राइव के साथ बहुत उपयोगी है!
मार्टिन हैनसेन

5

यह एक बदसूरत अक्षम समाधान लगता है, लेकिन अगर आपको केवल एक बार जांचना है:

dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"

डिस्क से पढ़ने के लिए dd का उपयोग करना sdX। (एक्स को उस ड्राइव से बदलें जिसे आप पढ़ना चाहते हैं),
फिर सभी अनचाहे ज़ीरो बाइट्स को किसी ऐसी चीज़ में ट्रांसलेट करना, जिसे हम संभाल सकते हैं।

आगे हम या तो उन बाइट्स को गिनते हैं जिन्हें हम संभाल सकते हैं और जांच सकते हैं कि क्या यह सही संख्या है (इसके लिए उपयोग करें wc -c), या हम गिनती को छोड़ दें -sया --squeeze-repeatsएक ही बार में सभी कई घटनाओं को निचोड़ने के लिए उपयोग करें ।

इस प्रकार dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"केवल एक ही टी प्रिंट करना चाहिए।

यदि आप इसे नियमित रूप से करना चाहते हैं तो आप कुछ अधिक कुशल चाहते हैं।
यदि आप इसे केवल एक बार करना चाहते हैं तो यह कीचड़ यह सत्यापित कर सकता है कि आपका सामान्य वाइपर काम कर रहा है और आप इस पर भरोसा कर सकते हैं।


आप इस समाधान को अक्षम क्यों मानते हैं? क्या कुछ बफरिंग है जो पहले गैर-एनयूएल स्थान से बहुत पहले पढ़ने की आवश्यकता है?
डैनियल बेक

क्या एक संभावित समस्या है जहां एक शाब्दिक 'टी' केवल गैर-अक्षीय चरित्र के रूप में भाप में मौजूद है?
बॉब

सच। यह डिजाइन में एक दोष है। मैं बैश (स्वयं शेल) का भी उपयोग नहीं कर रहा हूं, लेकिन मैंने यह माना कि "बैश" के साथ आपका मतलब "बैश से नहीं, किसी शेल प्रॉम्प्ट और स्टैंडर्ड टेक्स्ट मोड टूल्स का उपयोग करने से है"।
हेन्स

3
@ डैनियल: एक साधारण सी प्रोग्राम को हर रीड बाइट को बदले बिना सभी डेटा को पढ़ने में सक्षम होना चाहिए। जो अधिक कुशल और सौंदर्यपूर्ण रूप से मनभावन होगा। इस तरह के कार्यक्रम को लिखने के लिए एक अक्षम तरीके से उपलब्ध उपकरणों का उपयोग करने की तुलना में बहुत अधिक समय लग सकता है।
हेन्स

3

केवल जाँच करने के लिए, आप किसी भी ब्लॉक को देखेंगे जो सूचीबद्ध से मेल नहीं खाते

sudo badblocks -sv -t 0x00 /dev/sdX

या उन्हें लिखने के लिए बैडब्लॉक का उपयोग करें:

sudo badblocks -svw -t 0x00 /dev/sdX

डिफ़ॉल्ट विनाशकारी परीक्षण मेरी पसंद का सुरक्षित मिटा है

sudo badblocks -svw /dev/sdX

यदि कोई भी 0 और 1s के साथ ड्राइव को भरने के बाद कुछ भी प्राप्त कर सकता है, तो उनका पूरक, फिर सभी 1s, फिर सभी 0s, हर पास के साथ यह काम किया, उन्हें शुभकामनाएँ!

नई ड्राइव पर एक अच्छी प्री-परिनियोजन जाँच भी बनाता है

man badblocks

अन्य विकल्पों के लिए

यह नहीं कह रहा है कि यह तेज़ है, लेकिन यह काम करता है ...


2

दोनों ओर से लाभदायक। यह आदेश खराब क्षेत्रों को छोड़ देगा:

sudo dd if=/dev/sdX conv=noerror,sync | od | head

kill -USR1 <pid of dd>प्रगति देखने के लिए उपयोग करें ।


0

कुछ समय पहले मैं उत्सुक था AIO। परिणाम एक नमूना परीक्षण कार्यक्रम था जो सेक्टरों (512 बाइट ब्लॉक) के लिए जाँच करने के लिए होता है जो हैं NUL। आप इसे विरल फ़ाइल-रीजन डिटेक्टर के एक संस्करण के रूप में देख सकते हैं । मुझे लगता है कि स्रोत यह सब कहता है।

  • यदि संपूर्ण फ़ाइल / ड्राइव NULआउटपुट जैसा दिखता है 0000000000-eof। ध्यान दें कि कार्यक्रम में एक चाल है, fin()दिखाए गए आउटपुट को देने के उद्देश्य से फ़ंक्शन को लाइन 107 पर नहीं बुलाया गया है।
  • भारी परीक्षण नहीं किया गया है, इसलिए इसमें कीड़े हो सकते हैं
  • कोड थोड़ा लंबा है, जैसा AIOकि अन्य तरीकों से सीधा आगे नहीं है,
  • हालाँकि AIO, संभवतः ड्राइव को व्यस्त रखने का सबसे तेज़ तरीका है , क्योंकि NULअगला डेटा ब्लॉक पढ़ने के दौरान तुलना की जाती है; (हम ओवरलैपिंग करके कुछ और मिलीसेकंड निचोड़ सकते हैं AIO, लेकिन मुझे नहीं लगता कि यह इस लायक है। प्रयास है।)
  • यह हमेशा रिटर्न करता है trueयदि फ़ाइल पठनीय है और सब कुछ काम किया है। falseयदि फ़ाइल गैर है तो यह वापस नहीं आती है NUL
  • यह मानता है कि फ़ाइल का आकार 512 का गुणक है। अंतिम क्षेत्र पर एक बग है, हालांकि पूरी तरह से एक फ़ाइल पर NULयह अभी भी काम करता है, क्योंकि मेमोरी बफ़र्स पहले से ही हैं NUL। अगर किसी को लगता है कि यह एक ठीक करने की जरूरत है, लाइन 95 में memcmp(nullblock, buf+off, SECTOR)पढ़ सकता है memcmp(nullblock, buf+off, len-off<SECTOR : len-off : SECTOR)। लेकिन एकमात्र अंतर यह है, कि "एंड रिपोर्टिंग" शायद थोड़ा यादृच्छिक है (एक फ़ाइल के लिए नहीं जो पूरी तरह से है NUL)।
  • परिवर्तित memcmp()प्लेटफ़ॉर्म पर एक अन्य समस्या को भी ठीक करता है, जो NUL alloc()मेमोरी को एड नहीं करता है, क्योंकि कोड ऐसा नहीं करता है। लेकिन यह केवल 4 MiB से कम की फाइलों को देखा जा सकता है, लेकिन checknulशायद इतने छोटे काम के लिए सादे ओवरकिल है;)

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;
}

0

इस चतुर समाधान को एक समान लेकिन पहले के प्रश्न से पोस्ट करना चाहता था, जो उस उपयोगकर्ता द्वारा पोस्ट किया गया है जिसने कुछ समय के लिए लॉग इन नहीं किया है:

/dev/zeroलिनक्स सिस्टम पर एक उपकरण है जो हमेशा पढ़ने पर शून्य देता है।

तो, इस डिवाइस के साथ अपनी हार्ड ड्राइव की तुलना कैसे करें:

cmp /dev/sdX /dev/zero

यदि आपकी हार्ड ड्राइव को शून्य करने के साथ सब कुछ ठीक है, तो यह समाप्त हो जाएगा:

cmp: EOF on /dev/sdb

आपको बता रहा है कि दो फाइलें एक समान हैं जब तक कि यह हार्ड ड्राइव के अंत तक नहीं मिला। यदि हार्ड ड्राइव पर एक गैर-शून्य बिट है, cmpतो आपको बताएगा कि यह फ़ाइल में कहां है।

यदि आपके पास pvपैकेज स्थापित है तो:

pv /dev/sdX | cmp /dev/zero

एक प्रगति पट्टी के साथ एक ही बात करेंगे आप को खुश रखने के लिए, जबकि यह आपके ड्राइव की जांच करता है (EOF अब sdX के बजाय STDIN पर होगा)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.