যে হার্ড ড্রাইভটি লিনাক্সে শূন্যে ভরা হয়েছে তা যাচাই করবেন?


16

আমার কাছে শূন্যে ভরা হার্ড ড্রাইভ আছে।

হার্ড ড্রাইভের সমস্ত বিট ব্যাশ ব্যবহার করে জিরো কিনা তা কীভাবে পরীক্ষা করবেন?


জিরো দিয়ে পুরো ড্রাইভটি ওভাররাইট করা কি গ্রহণযোগ্য হবে? বা আপনার আসলে বর্তমান বিষয়বস্তু নিশ্চিত করতে হবে?
বব

আমি যাচাই করতে চাই যে হার্ড ড্রাইভটি জিরো দিয়ে পূর্ণ।
gkfvbnhjh2

1
তত্ত্বগতভাবে ডেটা স্যানিটাইজেশন সরঞ্জামগুলিতে বাগ থাকতে পারে যা কিছু তথ্য অক্ষত রাখে। আমি নিশ্চিত হতে চাই না যে প্রতিটি বিট শূন্য। সুতরাং আমি কীভাবে চেক করব যে এইচডিডি জিরোতে পূর্ণ কিনা?
gkfvbnhjh2

জিরো কেন? আপনি কি এলোমেলোভাবে কয়েকবার জিরো এবং 1 এস লিখবেন না?

13
যেহেতু 1 গুলি 0 এর চেয়ে সংকীর্ণ - আপনি তাদের মধ্যে থাকা পুরানো ডেটা আরও সহজে দেখতে পারবেন।
ক্রিসএ 16

উত্তর:


29

odএকই জিনিসগুলির রানগুলি এর সাথে প্রতিস্থাপন করবে *, যাতে আপনি এটি সহজেই ননজারো বাইটগুলির জন্য স্ক্যান করতে ব্যবহার করতে পারেন:

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

8
আমি | headএর শেষে যুক্ত করব , যাতে ড্রাইভটি শূন্য নয় বলে যদি দেখা যায়, পুরো ড্রাইভটিকে স্ক্রিনে ফেলে দেওয়ার পরিবর্তে, সত্যটি দেখাতে যথেষ্ট আউটপুট তৈরি করার পরে এটি থামবে।
উইজার্ড

2
@ উইজার্ড: দুর্দান্ত ধারণা; আমি আমার উত্তরে এটি যুক্ত করব।
গর্ডন ডেভিসন

8

আমি এটি করার জন্য একটি সংক্ষিপ্ত সি ++ প্রোগ্রাম লিখেছি, উত্স এখানে উপলব্ধ ।

এটি তৈরি করতে:

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 এমবি / গুলি) পড়তে পারে তার চেয়ে তত দ্রুত হবে, সুতরাং এটি কোনও বড় সমস্যা নয়।

কম ভার্বোস আউটপুট সহ একটি দ্রুত সংস্করণ এখানে উপলভ্য । তবে এটি @ হেনেসের সমাধানের চেয়ে এখনও কিছুটা ধীর। যাইহোক, এটির প্রথম ননজারো চরিত্রটি তার মুখোমুখি হবে যা প্রবাহের শুরুর কাছাকাছি কোনও ননজারো না থাকলে এটি সম্ভবত খুব দ্রুত faster


উত্তরটি আরও ভাল স্ব-অন্তর্ভুক্ত রাখতে পোস্টে উত্স যুক্ত করা:

#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চালিত হয়, তবে অতিরিক্ত প্যাকেজগুলি না টানিয়ে সমস্ত লিনাক্স ডিস্ট্রোজে অগত্যা উপলব্ধ হয় না। তারপরে আবার নপি স্ট্যান্ডার্ড পাইথন প্যাকেজগুলির অংশ নয় ...
বব

1
@ হাশিম আপনি যদি সংকলন করেন -O3এবং -march=nativeআপনি কিছু স্পিডআপ দেখতে পান; এটি নিশ্চিত করা উচিত যে জিসিসি অটো-ভেক্টরাইজেশন সক্ষম করে এবং আপনার বর্তমান সিপিইউ (অ্যাভিএক্স, এসএসই 2 / এসএসই 3, ইত্যাদি) এর জন্য সর্বোত্তম উপলব্ধ ব্যবহার করে। পাশাপাশি আপনি বাফার আকারের সাথে খেলতে পারেন; বিভিন্ন বাফার আকারগুলি ভেক্টরিযুক্ত লুপগুলির সাথে আরও অনুকূল হতে পারে (আমি 1 এমবি + নিয়ে খেলি, বর্তমানেরটি 1 কেবি)।
বব

1
@ হাশিম উপরের মন্তব্য সম্পাদনা করেছেন, আপনি যদি না দেখে থাকেন তবে। এর বাইরে, আপনি আরও আলোচনা করতে চাইলে, আপনি আমাকে ( @Bob) চ্যাটে পিং করতে পারেন : chat.stackexchange.com/rooms/118/root-access
বব

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"

ডিস্ক থেকে পড়তে ডিডি ব্যবহার করে 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 টি এমআইবি-র কম ফাইল দ্বারা দেখা যেতে পারে, তবে 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

আপনার ড্রাইভ চেক করার সময় আপনাকে আনন্দিত রাখতে প্রগতি বারের সাহায্যে একই কাজ করবে (ইওফটি যদিও এখন এসডিএক্সের পরিবর্তে এসটিডিনে থাকবে)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.