डेटा ब्लॉकों को राइट-शिफ्ट करने के लिए `dd` का उपयोग कैसे किया जा सकता है?


10

एक साधारण उदाहरण के रूप में 100MB कच्चे ब्लॉक डिवाइस पर विचार करें। कि कुल 102760448 बाइट्स के लिए 512 बाइट्स के 204800 ब्लॉक हैं।

पहली 98MB (200704 ब्लॉक) को स्थानांतरित करने की चुनौती है, इसलिए इसके सामने 2MB (4096 ब्लॉक) का अंतर है। ऐसा करने के लिए इन-प्लेस की आवश्यकता है कि कुछ भी उस सेक्टर को नहीं लिखा गया है जिसे पढ़ा नहीं गया है। इसे प्राप्त करने का एक तरीका बफर शुरू करना है:

$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 | dd of=/dev/sdj2 seek=4096

उम्मीद यह है कि mbufferलेखक के लिए कुछ भी पारित करने से पहले 4096 ब्लॉक संग्रहीत करेगा, इस प्रकार यह सुनिश्चित करना कि कुछ भी उस क्षेत्र को नहीं लिखा गया है जिसे पढ़ा नहीं गया है और यह कि लेखक बफर के आकार से पाठक को परेशान करता है। बफर को पाठक और लेखक को उन अवरोधों के भीतर जितनी जल्दी हो सके संचालित करने की अनुमति देनी चाहिए।

हालाँकि, यह मज़बूती से काम नहीं करता है। मैंने वास्तविक उपकरणों का उपयोग करने की कोशिश की है, लेकिन यह उन पर कभी काम नहीं करता है, जबकि एक फ़ाइल के साथ प्रयोगों ने मेरे 64-बिट बॉक्स पर काम किया, लेकिन मेरे 32-बिट बॉक्स पर नहीं।

सबसे पहले, कुछ तैयारी:

$ dd if=/dev/sdj2 count=200704 | md5sum
0f0727f6644dac7a6ec60ea98ffc6da9
$ dd if=/dev/sdj2 count=200704 of=testfile

यह काम नहीं करता है:

$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 -H | dd of=/dev/sdj2 seek=4096
summary: 98.0 MiByte in  4.4sec - average of 22.0 MiB/s
md5 hash: 3cbf1ca59a250d19573285458e320ade

यह 64-बिट सिस्टम पर काम करता है, लेकिन 32-बिट सिस्टम पर नहीं:

$ dd if=testfile count=200704 | mbuffer -s 512 -b 4096 -P 100 -H | dd of=testfile seek=4096 conv=notrunc
summary: 98.0 MiByte in  0.9sec - average of  111 MiB/s
md5 hash: 0f0727f6644dac7a6ec60ea98ffc6da9

यह मज़बूती से कैसे किया जा सकता है?


टिप्पणियाँ

मैंने बफरिंग के बारे में अन्य प्रश्नों को पढ़ा है और देखा है pv, bufferऔर mbuffer। मैं केवल आवश्यक बफर आकार के साथ काम करने के लिए उत्तरार्द्ध प्राप्त कर सकता हूं।

इंटरमीडिएट स्टोरेज का उपयोग उस समस्या का एक स्पष्ट समाधान है जो हमेशा काम करता है लेकिन यह तब व्यावहारिक नहीं होता है जब पर्याप्त अतिरिक्त क्षमता उपलब्ध न हो।

mbuffer20140302 संस्करण के साथ आर्क लिनक्स चलाने वाले टेस्ट प्लेटफ़ॉर्म ।


मुझे नहीं लगता कि यह समस्या को हल करेगा, लेकिन जिज्ञासा से बाहर क्यों उपयोग करें mbuffer? इसके बजाय ddब्लॉक डिवाइस की पूरी सामग्री को एक बार उपयोग करने के लिए क्यों न बनाएं dd bs=102760448? बेशक, एक तरीका या दूसरा यह रैम में बफर है।
सेलडा

@ कैलाडा - 100MB उदाहरण मात्र एक उदाहरण था। उदाहरण के लिए, 1TB पढ़ना, एक बार में इतना अच्छा विचार नहीं होगा।
स्टारफ्री

2
आह, मैं अब समझ गया, धन्यवाद। mbufferवास्तव में दूसरे के लिए मजबूर करना चाहिए ddपहले के लिए पीछे करने के लिए और आप केवल बदलाव के आकार बफ़र करने के लिए पर्याप्त रैम की जरूरत है। बहुत बुरा ddपढ़ने और पिछड़े क्रम में ब्लॉक लिखने का समर्थन नहीं करता है क्योंकि इससे समस्या खत्म हो जाएगी!
सेलडा

आपने यह नहीं बताया कि आपने दूसरे md5sum
psusi

@psusi, mduffer द्वारा दूसरा md5 आउटपुट है (इसका -Hतर्क इस सुविधा को सक्षम करता है)।
स्टार

जवाबों:


2

एक बफर के बिना, आप एक समय में एक ब्लॉक, पीछे की ओर जा सकते थे।

for i in $(seq 100 -1 0)
do
    dd if=/dev/thing of=/dev/thing \
       bs=1M skip=$i seek=$(($i+2)) count=1
done

कृपया ध्यान दें कि त्रुटि जाँच में कमी के कारण यह उदाहरण खतरनाक है।

यह ddकॉल की मात्रा के कारण भी धीमा है । यदि आपके पास स्पेयर करने के लिए मेमोरी है, तो आप एक बड़े ब्लॉक का उपयोग कर सकते हैं।

एक बफर के साथ, सावधान रहना । यह है नहीं एक 100% Prefill गारंटी करने के लिए पर्याप्त है। पूरी प्रक्रिया के दौरान आपको जो चाहिए वह न्यूनतम है। बफ़र को कभी भी नीचे नहीं गिरना चाहिए 2Mक्योंकि अन्यथा आपने अपना अभी तक पढ़ा जाने वाला डेटा फिर से लिख लिया होगा।

इसलिए जब सिद्धांत में आप किसी भी तरह के बफर और सिर्फ चेन के बिना कर सकते हैं dd:

dd if=/dev/thing bs=1M | \
dd bs=1M iflag=fullblock | \
dd bs=1M iflag=fullblock | \
dd of=/dev/thing bs=1M seek=2

व्यवहार में यह मज़बूती से काम नहीं करता है क्योंकि ddरीडिंग डेटा रखने के लिए पहले प्रबंधन की कोई गारंटी नहीं है , जबकि आखिरी dd( 2Mबीच में "बफर" के साथ ) पहले से ही लिख रहा है।

आप बफर के बीच में काफी बड़ा करके अपने अवसरों को बढ़ा सकते हैं, लेकिन फिर भी, यह विश्वसनीय नहीं है।

दुर्भाग्य से मुझे न्यूनतम भरण संपत्ति के साथ एक अच्छा बफर कार्यक्रम नहीं पता है। आपको एक की आवश्यकता है जो आउटपुट को बंद कर देता है जब तक कि बफर के भीतर आपके सुरक्षा मार्जिन से कम नहीं है।


मैंने इसे स्वीकार कर लिया क्योंकि यह मूल प्रश्न का उत्तर देता है कि ddइसका उपयोग कैसे किया जा सकता है। हालांकि, मुझे लगता है कि असली समाधान का उपयोग नहीं करना है, ddबल्कि इसके लिए कुछ चुनना है जिसे पीछे की तरफ चलाने के लिए डिज़ाइन किया गया है ddrescue। मैंने एक उत्तर में ऐसा करने का तरीका बताया है।
स्टार

1
@starfry: यकीन है, एक प्रोग्राम जो बस करता है वह एक अच्छा समाधान होगा। हालाँकि मैं ddrescueयहाँ बिल्कुल निश्चित नहीं हूँ । नहीं अगर यह विभिन्न उपकरणों पर काम करने की उम्मीद करता है, और आपको इसे अपने तर्कों को स्वीकार करने की कोशिश करनी होगी। इसमें आंतरिक रूप से या तो "न्यूनतम बफर भरण" संपत्ति नहीं हो सकती है (क्योंकि विभिन्न उपकरणों की आवश्यकता नहीं है), इसलिए फिर से यह आपके डेटा को दूषित कर सकता है। आपको सोर्सकोड में जांचना होगा कि क्या यह वास्तव में आपके उपयोग के मामले के लिए डिज़ाइन किया गया है।
१०:१० पर फ्रॉस्टचुट्ज़

1

आप 4096 ब्लॉक पढ़ रहे हैं, और फिर उन 4096 ब्लॉक को डिस्क के अगले 4096 ब्लॉक पर लिख रहे हैं, इस प्रकार दूसरे 4096 ब्लॉक को ओवरराइट करने से पहले उन्हें पढ़ा जा सकता है। आपको किसी भी लेखन को शुरू करने से पहले उन दूसरे 4096 को प्राप्त करने के लिए 8129 ब्लॉक पढ़ने की आवश्यकता है, और फिर आपको अगले 4096 को पढ़ने से पहले केवल 4096 ब्लॉक लिखने की आवश्यकता है।

आपने यह उल्लेख नहीं किया कि यह किस तरह की फाइलसिस्टम है। यदि यह ext [234] है, और आपके पास e2fsprogs का हालिया संस्करण है, तो आप इसका उपयोग कर सकते हैं e2image -ra -O 512 /dev/sdj2। इससे वॉल्यूम में मुक्त स्थान को छोड़ने के लिए पर्याप्त स्मार्ट होने का अतिरिक्त लाभ भी है।


इसे पढ़ते समय समझ में आता है और मैं इसके आधार पर एक और रूप लेने जा रहा हूं। लेकिन यह स्पष्ट नहीं करता है कि इसने टेस्ट फाइल पर काम क्यों किया।
स्टार

फाइलसिस्टम को पुनः प्राप्त करें, क्या आप मेरी टेस्ट फाइल वाली फाइलसिस्टम का जिक्र कर रहे हैं? बात यह है कि ext4लेकिन ब्लॉक डिवाइस प्रति के लिए, किसी भी फाइल सिस्टम अप्रासंगिक होना चाहिए।
स्टार

@starfry, जिस तरह से मैं एक सामान्य तरीके से ऐसा करना जानता हूं वह है एल्गोरिथ्म इमैनुएल द्वारा सुझाए गए एल्गोरिदम (अंत से पीछे की ओर काम करना) का उपयोग करना, जो कि gparted है।
Psusi

ब्लॉक आकार को फिर से, मैंने बड़े ब्लॉकों की कोशिश की थी (मुझे प्रश्न में यह लिखना चाहिए था)। मैंने पाया कि यह 64K सेक्टर के बफर के मुकाबले ज्यादा विश्वसनीय नहीं था। विश्वसनीय समाधान पीछे की ओर भागना है, ऐसा कुछ जो ddनहीं करता है।
स्टार

1

एक विश्वसनीय समाधान के लिए आवश्यक है कि आप यह सुनिश्चित करें कि कुछ भी ऐसे क्षेत्र में न लिखा जाए जो शायद पढ़ा नहीं गया है और इसे प्राप्त करने का एकमात्र वास्तविक तरीका यह है कि कॉपी को उल्टी दिशा में करना है।

ddrescueउपकरण एक विपरीत दिशा में काम कर सकते हैं, लेकिन यह इनपुट और आउटपुट एक ही होने के साथ चलाने के लिए मना कर दिया। हालाँकि डिवाइस नोड को डुप्लिकेट करके इसे ट्रिक करना संभव है।

मैंने कुछ त्वरित प्रयोग किए हैं और यह काम करता दिखाई देता है। कमांड लाइन है:

$ ddrescue -f -R -s 200704s -o 4096s /dev/sdj11 /dev/sdj11_copy

तर्क हैं

  • -f इसे किसी मौजूदा आउटपुट डिवाइस पर लिखने के लिए बाध्य करना आवश्यक है
  • -R इसे उल्टी दिशा में काम करने के लिए कहता है
  • -sयह बताता है कि कॉपी करने के लिए कितना इनपुट है (मैंने sसेक्टरों की संख्या निर्दिष्ट करने के लिए प्रत्यय का उपयोग किया है )
  • -oयह लिखने से पहले आउटपुट डिवाइस में फॉरवर्ड करने के लिए कहता है ( sप्रत्यय के साथ फिर से क्षेत्रों में निर्दिष्ट )
  • /dev/sdj11 पढ़ने के लिए ब्लॉक डिवाइस है
  • /dev/sdj11_copy लिखने के लिए ब्लॉक डिवाइस है

मैं बनाया /dev/sdj11_copyके साथ mknodके मापदंडों से मेल करने के /dev/sdj11

मैंने केवल कुछ बहुत ही तेज परीक्षण किए हैं, लेकिन यह एक कच्चे उपकरण की नकल करने के लिए ठीक काम करता है। यह एक फ़ाइल पर काम नहीं करता है (मैं इसे एक ही होने वाली फ़ाइलों से परे जाने में ट्रिक नहीं कर सकता)

यह मेरे मूल प्रश्न का उत्तर नहीं देता है जिसमें पूछा गया था कि इसे कैसे प्राप्त किया जा सकता ddहै, लेकिन मुझे लगता है कि अन्य उत्तरों को पढ़ने के बाद, इसका उत्तर यह है कि ddयह नहीं कर सकता।


यदि ddrescueइस परिदृश्य में ख़राब ब्लॉक का पता चलता है तो क्या होता है? यदि यह डिस्क के दूसरे क्षेत्र (खराब ब्लॉकों से बचने के लिए) पर कूदता है, और वहां से कॉपी करना जारी रखता है, तो यह फिर से आपके डेटा के कुछ हिस्सों को कॉपी नहीं करेगा। यदि यह एक ही डिवाइस के साथ काम करने की उम्मीद नहीं करता है, तो इसके पास विभिन्न संभावित भ्रष्टाचार के मामलों को रोकने के लिए कोई विशेष उपाय करने का कोई कारण नहीं है।
फ्रॉस्टचुट्ज़

मैं मानता हूं कि यह एक संभावित मुद्दा है, लेकिन मैंने किनारे के मामलों को नहीं देखा है, क्योंकि मैं इसका उपयोग करने में सक्षम था कि मुझे क्या चाहिए। ddrescueखराब डेटा को पुनर्प्राप्त करने के लिए इसके प्रयासों को सीमित करने के विकल्प हैं, लेकिन मैंने उनका उपयोग करने पर ध्यान नहीं दिया है।
स्टार

तथ्य यह है कि अगर यह इनपुट और आउटपुट समान हैं तो संचालित करने से इनकार करते हैं, शायद यह एक अच्छा संकेत है कि यह सुरक्षित नहीं है।
Psusi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.