संपूर्ण डिस्क पर dd, लेकिन खाली भाग नहीं चाहिए


33

मेरे पास एक डिस्क है, कहते हैं / देव / sda।

यहाँ fdisk -l है:

 Disk /dev/sda: 64.0 GB, 64023257088 bytes
255 heads, 63 sectors/track, 7783 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0000e4b5

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          27      209920   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              27         525     4000768    5  Extended
Partition 2 does not end on cylinder boundary.
/dev/sda5              27         353     2621440   83  Linux
/dev/sda6             353         405      416768   83  Linux
/dev/sda7             405         490      675840   83  Linux
/dev/sda8             490         525      282624   83  Linux

मुझे हमारे फ़ाइल सर्वर पर स्टोर करने के लिए एक छवि बनाने की आवश्यकता है जो हम अन्य उपकरणों को चमकाने में उपयोग कर रहे हैं इसलिए मैं केवल इस्तेमाल की गई जगह (केवल 4 जीबी के बारे में) चाहता हूं। मैं मलबे आदि को रखना चाहता हूं ... जैसे ही यह उपकरण कॉपी तैयार होते ही बूट तैयार हो जाना चाहिए।

कोई विचार? मैं पहले उपयोग कर रहा था dd if=/dev/sda of=[//fileserver/file], लेकिन उस समय, मेरी मास्टर कॉपी 4 जीबी फ्लैश आइडी पर थी।


2
नीचे दिए गए सभी उत्तर गलत हैं सिवाय @sudoer के। सही उत्तर का उपयोग करना है dd conv=sparse
बहमट

@bahamat, नहीं, gzip बेहतर है क्योंकि यह डेटा को संपीड़ित करेगा।
psusi

1
यह विरल के समान नहीं है।
बहमट

@ नौबत, सवाल विशेष रूप से छिड़काव के लिए नहीं पूछ रहा है; बस कैसे छवि बनाने के लिए कम जगह ले लो।
psusi

जवाबों:


37

दिन में वापस मैं एम्बेडेड लिनक्स वितरण के साथ एक समान समस्या में भाग गया - छवि को संपीड़ित करने से पहले सभी कबाड़ से छुटकारा पाएं।

dd if=/dev/zero of=asdf.txt। जब तक यह मर नहीं जाता तब तक प्रतीक्षा करें। Asdf.txt हटाएं।

आपने डिवाइस पर सभी खाली जगह पर सिर्फ शून्य लिखा है।

अब एक डिस्क छवि लें और इसे gzip के माध्यम से चलाएं। वोइला, विरल छवि।

संभवतः बहुत अच्छी तरह से पैमाना नहीं है और समस्याओं का कारण बन सकता है यदि आपको वास्तव में डिस्क पर लिखने की आवश्यकता है, लेकिन हे।

आप डिस्क के rsync स्नैपशॉट को दूसरे वॉल्यूम पर ले जा सकते हैं, शून्य, और फिर उस डिस्क छवि को ले सकते हैं।

नोट: SSD के लिए खतरनाक हो सकता है, उपयोगकर्ता को इस ऑपरेशन के लिए प्रतिबद्ध होना चाहिए।


अगर मैं इसे gzip के माध्यम से चलाता हूं, तो क्या मुझे इसका उपयोग करने से पहले इसे अनज़िप करना होगा? और इसे gzip के माध्यम से चलाकर, क्या मैं इसे dd प्रक्रिया के दौरान पाइप करता हूँ?
जोनाथन हेंसन

3
हाँ। dd if=sda2.gz | gunzip > /dev/sda2औरdd if=/dev/sda2 | gzip > sda2.gz
रोब बॉश

3
"आपने डिवाइस पर सभी खाली जगह पर सिर्फ शून्य लिखा है"। मेरा मतलब है कि विभाजन, डिवाइस नहीं, मुझे लगता है। इसलिए आपको ofप्रत्येक विभाजन के लिए एक पथ के साथ उस कमांड को चलाने की आवश्यकता होगी ।
जिगगंजर

यदि भौतिक मीडिया एक एसएसडी है, तो अब यह सोच सकता है कि डिवाइस पर प्रत्येक क्षेत्र का उपयोग किया गया है। यह एसएसडी को कम अतिरिक्त क्षेत्रों के साथ काम करने और संभवतः परिणाम के रूप में प्रदर्शन को कम करने के लिए देगा। यदि ड्राइवर और फर्मवेयर के पास TRIM सपोर्ट है तो वह शर्त केवल तब तक लागू होगी जब तक आप फ़ाइल को फिर से डिलीट नहीं करते। यदि आप छवि बनाते समय फ़ाइल को रखते हैं, तो आपको छवि को पुनर्स्थापित करने के बाद फ़ाइल को फिर से हटाना होगा। यह उपयोगी हो सकता है यदि छवि को SSD में पुनर्स्थापित किया जाता है।
कैस्परल्ड

कुछ अतिरिक्त चिंताओं को ध्यान में रखना है। चूँकि इस पद्धति के लिए फाइल सिस्टम को रीड-राइट माउंट किया जाना आवश्यक है, इसलिए एक जोखिम है जो अंतर्निहित फ़ाइल सिस्टम में बदल जाता है जबकि कॉपी प्रगति पर है एक असंगत छवि को जन्म देगा। एक अवसर पर मैंने देखा है कि परिणामी प्रतिलिपि इतनी असंगत है कि कॉपी पर विसंगतियों को ठीक करने की कोशिश करते समय fsck वास्तव में segfault होगा। इसके अलावा डिवाइस को भरने से मीडिया को लिखने के लिए अन्य प्रक्रियाओं को विफल होने का कारण हो सकता है।
कैस्परल्ड

17

मान लिया जाये कि आप सहेजना चाहते हैं /dev/sdXNकरने के लिए /tgtfs/image.rawऔर आप रूट हैं:

  1. mkdir /srcfs && mount /dev/sdXN /srcfs

  2. ज़ीरोफिल या बस का उपयोग करें: dd if=/dev/zero of=/srcfs/tmpzero.txtशून्य के साथ अप्रयुक्त ब्लॉकों को भरने के लिए (पूरी तरह से फ़ाइल सिस्टम को भरने के लिए प्रतीक्षा करें rm /srcfs/tmpzero.txt)

  3. Dd के साथ चित्र लें और conv = sparse to punch zeros on-the-fly का उपयोग करें: dd conv=sparse if=/dev/sdxn of=/tgtfs/image.raw

यदि आप संपीड़न का उपयोग करना चाहते हैं, तो आपको शून्य के साथ शून्य को छिद्र करने की आवश्यकता नहीं है क्योंकि शून्य ब्लॉक अत्यधिक संकुचित हैं:

dd if=/dev/sdxn | gz -c | dd of=/tgtfs/image.raw

पुनश्च: आपको ध्यान रखना चाहिए कि यह फ्लैश मेमोरी आधारित स्टोरेज मीडिया पर अच्छा विचार नहीं है (अर्थात आपका सोर्स फाइल सिस्टम SSD हो)


5
यह सही जवाब है। का उपयोग करें dd conv=sparse
बहमट

1
फ्लैश स्टोरेज पर ऐसा करने में क्या गलत है?
दान

2
@ (हार्डवेयर और सॉफ़्टवेयर डिज़ाइन और कॉन्फ़िगरेशन के आधार पर) यह आपके SSD के लिए व्यापक लेखन और उसके जीवनकाल को कम कर सकता है। और सामान्य तौर पर, पुराने डिस्क से डेटा को नए (या ओपी क्या करना चाहता था) के लिए स्थानांतरित करना ठीक है, लेकिन नियमित बैकअप और डिस्क को पुनर्स्थापित करने के लिए डिस्क / विभाजन स्तर बैकअप एक अच्छा समाधान नहीं है, यहां तक ​​कि एचडीडी पर भी। फ़ाइल स्तर बैकअप (यानी एक फ़ाइल-सिस्टम से दूसरे में फाइल कॉपी करना), या फ़ाइल-सिस्टम स्तर बैकअप (BTRFS जैसे फ़ाइल-सिस्टम के साथ btrfs snapshotऔर btrfs sendउपकरण) एक बेहतर समाधान IMHO है।
सुदोअर

सुझाव: आप नहीं है, तो gzपर अपने PATH(जैसे मैंने नहीं किया, GParted लाइव पर), आप उपयोग कर सकते हैं gzip -cबजाय।
XtraSimplicity

11

गिनती विकल्प के साथ dd का प्रयोग करें।

आपके मामले में आप fdisk का उपयोग कर रहे थे इसलिए मैं वह तरीका अपनाऊंगा। आपके "sudo fdisk -l" निर्मित:

    Disk /dev/sda: 64.0 GB, 64023257088 bytes
    255 heads, 63 sectors/track, 7783 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x0000e4b5

    Device Boot      Start         End      Blocks   Id  System
    /dev/sda1   *           1          27      209920   83  Linux
    Partition 1 does not end on cylinder boundary.
    /dev/sda2              27         525     4000768    5  Extended
    Partition 2 does not end on cylinder boundary.
    /dev/sda5              27         353     2621440   83  Linux
    /dev/sda6             353         405      416768   83  Linux
    /dev/sda7             405         490      675840   83  Linux
    /dev/sda8             490         525      282624   83  Linux

जिन दो चीजों पर आपको ध्यान देना चाहिए वे हैं 1) यूनिट का आकार, और 2) "एंड" कॉलम। आपके मामले में आपके पास सिलेंडर हैं जो 8225280 बाइट्स के बराबर हैं। "अंत" कॉलम में sda8 525 पर समाप्त होता है (जो 525 [इकाइयां] * 16065 * 512 = ~ 4.3GB)

dd बहुत सी चीजें कर सकता है, जैसे किसी ऑफसेट के बाद शुरू करना, या किसी विशिष्ट संख्या के ब्लॉक के बाद रुकना। हम dd में काउंट विकल्प का उपयोग करके उत्तरार्द्ध करेंगे। आदेश निम्नानुसार दिखाई देगा:

    sudo dd if=/dev/sda of=/your_directory/image_name.iso bs=8225280 count=526

जहां-जहां ब्लॉक का आकार होता है (यह उस इकाई का उपयोग करना सबसे आसान है जो fdisk का उपयोग करता है, लेकिन कोई भी इकाई ऐसा तब तक करेगी जब तक कि इन इकाइयों में गिनती विकल्प घोषित नहीं हो जाता), और गिनती उन इकाइयों की संख्या है जिन्हें हम कॉपी करना चाहते हैं (नोट हम आखिरी ब्लॉक पर कब्जा करने के लिए 1 से गिनती बढ़ाते हैं)।


FYI करें: सिलिंडर में यूनिट दिखाने के लिए, उपयोग करेंfdisk -l -u=cylinders /dev/sda
xinthose

3
यह स्वीकृत उत्तर क्यों नहीं है? यह कम से कम घुसपैठ विकल्प लगता है क्योंकि यह स्रोत को संशोधित नहीं करता है।
user33326

@ user33326 क्योंकि यह उत्तर एक ड्राइव पर बिना स्पेस के कॉपी न करने के लिए अच्छा है, विभाजन के भीतर अप्रयुक्त स्थान नहीं है, जो कि ओपी की परवाह है।
GDorn

8

जबकि /dev/zeroफ्री-डिस्क-स्पेस और आईएनजी का उपयोग संभव है dd conv=sparse/ gz -c100 जीबी में चल रहे खाली स्थान के साथ विशाल डिस्क पर, /dev/zeroआईएनजी दर्दनाक रूप से धीमा है - यह उल्लेख करने के लिए नहीं कि अन्य उत्तरों के रूप में, /dev/zeroईओडी तक एसडीडी को संलग्न करें।

जब मैंने इस स्थिति में भाग लिया तो मैंने क्या किया:

  • एक लुबंटू लाइव सीडी पर, gpartedडिस्क को न्यूनतम संभव आकार में 'सिकोड़ने' के लिए इस्तेमाल किया जाता है, जिससे बाकी जगह खाली हो जाती है


  • dd bs=1M count=<size_in_MBs> if=/dev/sdX | gzip -c --fast| dd of=/path/to/image.gz तेजी से संपीड़ित छवि बनाने के लिए उपयोग किया जाता है (कहने की जरूरत नहीं है, आप संपीड़न को छोड़ सकते हैं यदि आपके पास कच्चा डेटा संग्रहीत करने के लिए पर्याप्त स्थान है (या अन्यथा सीपीयू लोडिंग को कम करने के लिए इच्छुक हैं)


  • dd if=/path/to/image.gz | gunzip -c | dd bs=1M of=/dev/sdY विभिन्न डिस्क पर डेटा वापस कॉपी करने के लिए उपयोग किया जाता है
  • gpartedविभाजन को 'विस्तारित' करने के लिए फिर से उपयोग किया जाता है

मैंने इसे कई विभाजनों के लिए आज़माया नहीं है, लेकिन मेरा मानना ​​है कि ऊपर की प्रक्रिया को 'विभाजन' की प्रतिलिपि बनाने के लिए अनुकूलित किया जा सकता है, यदि गंतव्य डिस्क पर विभाजन-तालिका पहले बनाई गई है और केवल विभाजन में निहित डेटा dd- पढ़ने / लिखने के माध्यम से कॉपी किया गया है ( skip( क्रमशः seekका विकल्प dd) उपयुक्त के रूप में आवश्यक होगा।


1
यह वास्तविक उत्तर है, बस countपैरामीटर का उपयोग करें
गॉर्डिनि

7

आप नहीं कर सकते। ddएक बहुत ही निम्न स्तर का उपकरण है और इसमें फाइलों और खाली जगह के बीच अंतर करने का कोई साधन नहीं है।

दूसरी ओर खाली स्थान बहुत अच्छी तरह से संपीड़ित करेगा, इसलिए यदि आप केवल भंडारण स्थान के बारे में चिंतित हैं, उदाहरण के लिए समय नहीं लिखते हैं, तो बस इसे gzip के माध्यम से पाइप करें।


7
यह मानते हुए कि पहले खाली जगह का उपयोग नहीं किया गया है। उम्मीद के मुताबिक संपीड़न कार्यों को सुनिश्चित करने के लिए आप पहले खाली स्थान को शून्य कर सकते हैं।
सेरेक्स

1
सच। और यह केवल प्रक्रिया को जटिल बनाता है और इसे अधिक समय भी लेता है।
c2h5oh

6

मान लें कि बाकी ड्राइव खाली है (सभी शून्य) आप अपने डीडी को गज़िप के माध्यम से पाइप कर सकते हैं, जिसे खाली स्थान को काफी अच्छी तरह से संपीड़ित करना चाहिए। आप यह सुनिश्चित करने के लिए कि आपका खाली स्थान वास्तव में खाली है, इसलिए यह अच्छी तरह से संपीड़ित करता है, ज़ीरोफ्री जैसे उपकरण का उपयोग कर सकता है ।

यदि आप पार्टिमेज , क्लोनज़िला या कुछ अन्य लिनक्स क्लोनिंग टूल जैसे टूल का उपयोग करते हैं , तो वे इसमें से अधिकांश को स्वचालित रूप से आपके लिए संभाल लेंगे।


पार्टिमेज और क्लोनज़िला वास्तव में स्मार्ट हैं जो खाली जगह को पढ़ने के लिए छोड़ देते हैं, बजाय इसके कि आप इसे लिखने के लिए जीरो पर भरोसा करते हैं, और फिर इन्हें पढ़ने के बाद dd या gzip ड्रॉप या जीरो को कंप्रेस करें।
psii

2

स्वीकृत उत्तर सही नहीं है। मैं ऊपर की टिप्पणी से सहमत हूं। मैं नियमित आधार पर अपनी डिस्क का बैकअप लेने के लिए काउंट पैरामीटर के साथ dd का उपयोग करता हूं । बस अपने डिवाइस के BACKUP_FOLDER और पत्र को "X" से बदलें:

डिस्क के अंतिम इस्तेमाल किए गए ब्लॉक को परिभाषित करें:

ct=$(fdisk -l | awk '$1 == "/dev/sdX" { print $3 }')

फिर डिस्क को क्लोन करना (खाली स्थान को छोड़कर):

dd if=/dev/sdX bs=512 count=$ct | gzip > BACKUP_FOLDER/sdX_$(date +"%Y-%m-%d").img.gz >>"$LOG"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.