dd sur tout le disque, mais ne veulent pas de partie vide

33

J'ai un disque, disons / dev / sda.

Voici 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

Je dois faire une image à stocker sur notre serveur de fichiers pour l'utiliser dans les autres appareils que nous fabriquons, donc je ne veux que l'espace utilisé (seulement environ 4 Go). Je veux garder le mbr etc ... car cet appareil doit être prêt à démarrer dès que la copie est terminée.

Des idées? J'avais précédemment utilisé dd if=/dev/sda of=[//fileserver/file], mais à ce moment-là, ma copie principale était sur une idée flash de 4 Go.

Jonathan Henson
la source
2
Toutes les réponses ci-dessous sont fausses à l'exception de @sudoer. La bonne réponse est d'utiliser dd conv=sparse.
bahamat
@bahamat, non, gzip est meilleur car il compressera les données.
psusi
1
Ce n'est pas la même chose que clairsemée.
bahamat
@bahamat, la question ne demande pas spécifiquement pour sprase; comment faire pour que l'image occupe moins d'espace.
psusi

Réponses:

37

À l'époque, je rencontrais un problème similaire avec les distributions Linux intégrées - débarrassez-vous de tous les fichiers indésirables avant de compresser l'image.

dd if=/dev/zero of=asdf.txt. Attendez qu'il meure. Supprimez asdf.txt.

Vous venez d'écrire des zéros sur tout l'espace libre de l'appareil.

Maintenant, prenez une image disque et exécutez-la via gzip. Voila, image clairsemée.

N'évolue probablement pas très bien et pourrait causer des problèmes si vous avez réellement besoin d'écrire sur le disque, mais bon.

Vous pouvez prendre un instantané rsync du disque vers un autre volume, le mettre à zéro, puis prendre cette image disque.

Remarque: pourrait être dangereux pour le SSD, l'utilisateur doit considérer cette opération avant de s'engager.

Rob Bos
la source
si je l'exécute via gzip, dois-je le décompresser avant de l'utiliser? Et en l'exécutant via gzip, dois-je simplement le diriger pendant le processus dd?
Jonathan Henson
3
Oui. dd if=sda2.gz | gunzip > /dev/sda2etdd if=/dev/sda2 | gzip > sda2.gz
Rob Bos
3
"Vous venez d'écrire des zéros sur tout l'espace libre de l'appareil". Vous voulez dire partition, pas appareil, je pense. Vous devez donc exécuter cette commande avec un ofchemin pour chaque partition.
jiggunjer
Si le support physique est un SSD, il peut désormais penser que tous les secteurs de l'appareil ont été utilisés. Cela permettra au SSD de travailler avec moins de secteurs de rechange et, par conséquent, de diminuer les performances. Si le pilote et le micrologiciel prennent en charge TRIM, cette condition s'applique uniquement jusqu'à ce que vous supprimiez à nouveau le fichier. Si vous gardez le fichier en place pendant que vous créez l'image, vous devrez à nouveau supprimer le fichier après avoir restauré l'image. Cela peut être utile si l'image est restaurée sur SSD.
kasperd
Il y a quelques préoccupations supplémentaires à garder à l'esprit. Étant donné que cette méthode nécessite que le système de fichiers soit monté en lecture-écriture, il existe un risque que des modifications du système de fichiers sous-jacent pendant la copie aboutissent à une image incohérente. À une occasion, j'ai vu que la copie résultante était si incohérente que fsck serait en fait un défaut de segmentation en essayant de réparer les incohérences sur la copie. Le remplissage de l'appareil peut également entraîner l'échec d'autres processus devant écrire sur le support.
kasperd
17

En supposant que vous souhaitez enregistrer /dev/sdXNà /tgtfs/image.rawet vous êtes root:

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

  2. Utilisez zerofill ou simplement: dd if=/dev/zero of=/srcfs/tmpzero.txtpour remplir les blocs inutilisés avec zéro (attendez qu'il remplisse complètement le système de fichiers alors rm /srcfs/tmpzero.txt)

  3. Prenez l'image avec dd et utilisez conv = sparse pour pointer des zéros à la volée: dd conv=sparse if=/dev/sdxn of=/tgtfs/image.raw

Si vous souhaitez utiliser la compression, vous n'avez pas besoin de perforer les zéros avec dd car les blocs zéro sont hautement compressibles:

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

PS: Vous devez noter que ce n'est pas une bonne idée sur un support de stockage à mémoire flash (c'est-à-dire que votre système de fichiers source est SSD)

Sudoer
la source
5
C'est la bonne réponse. Utilisez dd conv=sparse.
bahamat
1
Quel est le problème avec cela sur le stockage flash?
Dan
2
@Dan (en fonction de la conception et de la configuration matérielle et logicielle), cela peut entraîner une écriture importante sur votre SSD et réduire sa durée de vie. et globalement, c'est OK pour déplacer des données de l'ancien disque vers le nouveau (ou ce que l'OP voulait faire), mais la sauvegarde au niveau du disque / de la partition n'est pas une bonne solution pour la sauvegarde et la restauration régulières, même sur les disques durs. la sauvegarde au niveau des fichiers (c'est-à-dire la copie de fichiers d'un système de fichiers à un autre), ou la sauvegarde au niveau du système de fichiers (avec des systèmes de fichiers comme BTRFS avec btrfs snapshotet des btrfs sendoutils) est une meilleure solution à mon humble avis .
Sudoer
Astuce: Si vous n'avez pas gzsur votre PATH(comme je ne l' ai pas, sur GParted Live), vous pouvez utiliser à la gzip -cplace.
XtraSimplicity
11

Utilisez dd, avec l'option count.

Dans votre cas, vous utilisiez fdisk, je vais donc adopter cette approche. Votre "sudo fdisk -l" a produit:

    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

Les deux choses à noter sont 1) la taille de l'unité et 2) la colonne "Fin". Dans votre cas, vous disposez de cylindres équivalents à 8225280 octets. Dans la colonne "Fin", sda8 se termine à 525 (soit 525 [unités] * 16065 * 512 = ~ 4,3 Go)

dd peut faire beaucoup de choses, comme démarrer après un décalage ou s'arrêter après un nombre spécifique de blocs. Nous ferons ce dernier en utilisant l'option count dans dd. La commande apparaîtrait comme suit:

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

Où -bs est la taille du bloc (il est plus facile d'utiliser l'unité utilisée par fdisk, mais n'importe quelle unité le fera tant que l'option count est déclarée dans ces unités), et count est le nombre d'unités que nous voulons copier (note que nous incrémentons le compte de 1 pour capturer le dernier bloc).

Tom Looby
la source
Pour info: pour afficher les unités en cylindres, utilisezfdisk -l -u=cylinders /dev/sda
xinthose
3
Pourquoi n'est-ce pas la réponse acceptée? Cela semble être l'option la moins intrusive car elle ne modifie pas la source.
user33326
@ user33326 car cette réponse est bonne pour ne pas copier d'espace non partitionné sur un lecteur, pas d'espace inutilisé dans les partitions, ce qui est important pour l'OP.
GDorn
8

Bien /dev/zeroque l'utilisation de l'espace disque libre et l'utilisation de dd conv=sparse/ gz -csoient possibles, sur des disques énormes avec un espace vide fonctionnant dans des centaines de Go, /dev/zeroing est douloureusement lent - sans parler de ce que, comme d'autres réponses l'ont noté, /dev/zeroing un SDD jusqu'à EOF.

Voici ce que j'ai fait lorsque j'ai rencontré cette situation:

  • Sur un CD live lubuntu, utilisé gpartedpour «réduire» le disque à la taille minimale possible, en laissant le reste de l'espace non alloué

  • Utilisé
    dd bs=1M count=<size_in_MBs> if=/dev/sdX | gzip -c --fast| dd of=/path/to/image.gz pour créer l'image compressée rapidement (il va sans dire que vous souhaiterez peut-être ignorer la compression si vous avez suffisamment d'espace pour stocker les données brutes (ou si vous êtes autrement enclin à réduire la charge du processeur)

  • Utilisé
    dd if=/path/to/image.gz | gunzip -c | dd bs=1M of=/dev/sdY pour copier les données sur un autre disque
  • Utilisé à gpartednouveau pour «étendre» la partition

Je ne l'ai pas essayé pour plusieurs partitions, mais je pense que le processus ci-dessus peut être adapté pour copier des `` partitions '' si la table de partition sur le disque de destination est créée en premier et que seules les données contenues dans la partition sont copiées via dd- lecture / écriture des décalages ( skip/ seekoption de dd, respectivement) serait requis, le cas échéant.

Ashish Chopra
la source
1
c'est la vraie réponse, utilisez simplement le countparamètre
Gordy
7

Tu ne peux pas. ddest un outil de très bas niveau et il n'a aucun moyen de faire la distinction entre les fichiers et l'espace vide.

D'un autre côté, l'espace vide se compressera très, très bien, donc si vous ne vous souciez que de l'espace de stockage, pas par exemple du temps d'écriture, alors dirigez-le simplement via gzip.

c2h5oh
la source
7
En supposant que l'espace libre n'a pas été utilisé auparavant. Vous pouvez tout d'abord remplir l'espace libre pour vous assurer que la compression fonctionne comme prévu.
Sirex
1
Vrai. Et cela ne fait que compliquer le processus et le rend encore plus long.
c2h5oh
6

En supposant que le reste du lecteur est vide (tous les zéros), vous pouvez diriger votre DD via gzip, ce qui devrait compresser assez bien l'espace vide. Vous pouvez utiliser un outil comme zerofree pour vous assurer que votre espace vide est réellement vide afin qu'il se comprime bien.

Si vous utilisez un outil comme partimage , clonezilla ou certains des autres outils de clonage linux, ils géreraient la plupart de cela automatiquement pour vous.

Zoredache
la source
partimage et clonezilla sont en fait assez intelligents pour ignorer la lecture de l'espace libre, plutôt que de compter sur vous pour y écrire des zéros, puis faire dd ou gzip supprimer ou compresser les zéros après les avoir lus.
psusi
2

La réponse acceptée n'est pas correcte. Je suis d'accord avec le commentaire ci-dessus. J'utilise dd avec le paramètre count pour sauvegarder mon disque sur une base régulière. Remplacez simplement le BACKUP_FOLDER et la lettre de votre appareil par "X":

Définissez le dernier bloc utilisé du disque:

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

Puis clonage du disque (à l'exclusion de son espace vide):

dd if=/dev/sdX bs=512 count=$ct | gzip > BACKUP_FOLDER/sdX_$(date +"%Y-%m-%d").img.gz >>"$LOG"
Aloha D
la source