Rendre le disque / copy de disque plus lent

Existe-t-il une méthode pour ralentir le process de copy sous Linux?

J'ai un gros file, disons 10 Go, et je voudrais le copyr dans un autre directory, mais je ne veux pas le copyr à pleine vitesse. Disons que je voudrais le copyr avec la vitesse de 1mb / s, pas plus rapide. J'aimerais utiliser une command cp Linux standard.

Est-ce possible? (Si oui, comment?)

Edit : donc, j'appendai plus de context à ce que j'essaie d'accomplir.

J'ai un problème sur le système ArchLinux lors de la copy de files volumineux sur USB (vers une key USB, un disque USB, etc.). Après avoir rempli le cache du tampon USB, mon système cesse de répondre (même la souris s'arrête, elle ne se déplace que sporadiquement). L'opération de copy est toujours en cours, mais il faut 100% de ressources de la boîte. Lorsque l'opération de copy se termine, tout revient à la normale – tout est parfaitement réactif.

Peut-être que c'est une erreur matérielle, je ne sais pas, mais je sais que j'ai deux machines avec ce problème (les deux sont sur ArchLinux, l'une est une boîte de bureau, la seconde est un ordinateur portable).

La solution la plus simple et la plus rapide (je conviens que ce n'est pas la solution «réelle», juste un «hack» laide) serait d'empêcher ce tampon de se remplir en copiant le file avec une vitesse d'écriture moyenne du lecteur USB, moi ce serait suffisant.

Vous pouvez throttle un tuyau

 tar -cf - . | throttle -M 1 | tar -C /your/usb -xvf - 

-b -k -m limites sont en bits
-B -K -M sont des octets

Au lieu de cp -a /foo /bar vous pouvez également utiliser rsync et limiter la bande passante selon vos besoins.

Du manuel de rsync :

 --bwlimit=KBPS 

limiter la bande passante d'E / S; KBytes par seconde

Ainsi, la command actuall, montrant également la progression, ressemblerait à ceci:

 rsync -av --bwlimit=100 --progress /foo /bar 

Je suppose que vous essayez de ne pas perturber les autres activités. Les versions récentes de Linux incluent ionice qui vous permet de contrôler la programmation d'IO.

En plus de permettre différentes priorités, il existe une option supplémentaire pour limiter les E / S aux fois où le disque est inactif. La command man ionice affichera la documentation.

Essayez de copyr le file en utilisant une command comme:

 ionice -c 3 cp largefile /new/directory 

Si les deux directorys se trouvent sur le même périphérique, vous pouvez find que le lien fait ce que vous voulez. Si vous copyz à des fins de sauvegarde, n'utilisez pas cette option. ln est extrêmement rapide car le file lui-même n'est pas copié. Essayer:

 ln largefile /new/directory 

Ou si vous voulez simplement y accéder à partir d'un directory sur un autre appareil, essayez:

 ln -s largefile /new/directory 

Si la solution ionique ne suffit pas (pourquoi) et que vous voulez vraiment limiter les E / S à une valeur absolue, il existe plusieurs possibilités:

  1. le plus probablement le plus facile: ssh . Il a une limite de bande passante embeddede. Vous utiliserez par exemple tar (au lieu de cp ) ou scp (si c'est suffisant, je ne sais pas comment il gère les liens symboliques et les liens rsync ) ou rsync . Ces commands peuvent canaliser leurs données sur ssh . En cas de tar écrivez dans /dev/stdout (ou - ) et insérez-le dans le client ssh qui exécute un autre tar du côté "remote".

  2. élégant mais pas dans le kernel de vanille (AFAIK): L'appareil mapper cible ioband . Ceci, bien sûr, ne fonctionne que si vous pouvez monter le volume source ou cible.

  3. un peu de plaisir auto-écrit: grep "^write_bytes: " /proc/$PID/io vous donne la quantité de données qu'un process a écrit. Vous pouvez écrire un script qui démarre cp en arrière-plan, dort par exemple 1 / 10ème de seconde, arrête le process cp arrière-plan ( kill -STOP $PID ), vérifie la quantité qui a été écrite case), calcule combien de time cp doit faire une pause afin de ramener le taux de transfert moyen à la valeur prévue, dort pour cette période, réveille cp ( kill -CONT $PID ), etc.

Votre problème n'est probablement pas avec votre ordinateur, en soi, c'est probablement bien. Mais cette couche de transition flash USB a un processeur qui doit cartographier toutes vos écritures pour compenser ce qui pourrait être autant qu'une puce flash défectueuse à 90%, qui sait? Vous l'inondez, puis vous inondez vos tampons puis vous inonder tout le bus, puis vous êtes coincé, l'homme – après tout, c'est là que toutes vos affaires sont. Cela peut sembler contre-intuitif, mais ce dont vous avez vraiment besoin, c'est de bloquer les E / S – vous devez laisser le FTL régler le rythme et ensuite continuer.

(Sur le piratage des microcontrollers FTL: http://www.bunniestudios.com/blog/?p=3554 )

Toutes les réponses ci-dessus devraient fonctionner donc c'est plus un "moi aussi!" que n'importe quoi d'autre: j'ai totalement été là, mec. J'ai résolu mes propres problèmes avec l'argument –bwlimit arg de rsync (2.5mbs semblait être le bon endroit pour une seule exécution sans erreur – rien de plus et je me refindais avec des erreurs de protection en écriture). rsync était particulièrement adapté à mon but car je travaillais avec des filesystems entiers – donc il y avait beaucoup de files – et simplement exécuter rsync une deuxième fois corrigeait tous les problèmes de la première exécution (ce qui était nécessaire quand je devenais impatient et essayais pour dépasser 2.5mbs).

Pourtant, je suppose que ce n'est pas aussi pratique pour un seul file. Dans votre cas, vous pouvez simplement placer un file dd dans raw-write – vous pouvez gérer n'importe quelle input de cette façon, mais seulement un file cible à la fois (bien que ce file puisse être un bloc entier bien sûr).

 ## OBTAIN OPTIMAL IO VALUE FOR TARGET HOST DEV ## ## IT'S IMPORTANT THAT YOUR "bs" VALUE IS A MULTIPLE ## ## OF YOUR TARGET DEV'S SECTOR SIZE (USUALLY 512b) ## % bs=$(blockdev --getoptio /local/target/dev) ## START LISTENING; PIPE OUT ON INPUT ## % nc -l -p $PORT | lz4 |\ ## PIPE THROUGH DECOMPRESSOR TO DD ## > dd bs=$bs of=/mnt/local/target.file \ ## AND BE SURE DD'S FLAGS DECLARE RAW IO ## > conv=fsync oflag=direct,sync,nocache ## OUR RECEIVER'S WAITING; DIAL REMOTE TO BEGIN ## % ssh user@remote.host <<-REMOTECMD ## JUST REVERSED; NO RAW IO FLAGS NEEDED HERE, THOUGH ## > dd if=/remote/source.file bs=$bs |\ > lz4 -9 | nc local.target.domain $PORT > REMOTECMD 

Vous pourriez find netcat être un peu plus rapide que ssh pour le transport de données si vous lui donnez un coup de feu. Quoi qu'il en soit, les autres idées ont déjà été sockets, alors pourquoi pas?

[EDIT]: J'ai remarqué les mentions de lftp, scp et ssh dans l'autre post et pensais que nous parlions d'une copy distante. La section locale est beaucoup plus facile:

 % bs=$(blockdev --getoptio /local/target/dev) % dd if=/src/fi.le bs=$bs iflag=fullblock of=/tgt/fi.le \ > conv=fsync oflag=direct,sync,nocache 

[EDIT2]: Crédit où c'est dû: juste remarqué ptman m'a battu à ceci par comme cinq heures dans les commentaires.

Certainement vous pourriez accorder $ bs pour la performance ici avec un multiplicateur – mais certains filesystems peuvent exiger qu'il soit un multiple de la taille de la cible fs donc gardez cela à l'esprit.

Le problème est que la copy remplit votre memory avec des blocs «en vol», évincer datatables «utiles». Un bogue connu (et très difficile à corriger) dans le kernel Linux manipulant des E / S pour ralentir les périphériques (USB dans ce cas).

Peut-être pourriez-vous essayer de répartir la copy, par exemple par un script comme celui-ci (croquis de preuve de concept, totalement non testé!):

 while true do dd if=infile of=outfile bs=4096 count=... seek=... skip=... sleep 5 done 

ajuster seek et skip par count chaque tour. Besoin de régler le count afin qu'il ne remplisse pas (trop) la memory, et 5 pour lui permettre de drainer.

Ce problème n'a rien à voir avec les erreurs ou les pannes matérielles ou logicielles, c'est juste que votre kernel essaie d'être gentil avec vous et renvoie votre message en arrière-plan (il utilise un cache dans le kernel: plus de RAM, mais vous pouvez le limiter en écrivant quelque part dans / proc – non recommandé cependant). Les lecteurs Flash sont trop lents et pendant que le kernel écrit dessus, d'autres opérations d'E / S ne peuvent pas être exécutées assez rapidement. ionice mentionné plusieurs fois dans d'autres réponses est ok. Mais avez-vous essayé de monter le lecteur avec -o sync pour éviter la mise en memory tampon du operating system? C'est probablement la solution la plus simple.

Baissez la limite de page sale. La limite par défaut est folle.

Créez /etc/sysctl.d/99-sysctl.conf avec:

 vm.dirty_background_ratio = 3 vm.dirty_ratio = 10 

Exécutez ensuite sysctl -p ou redémarrez.

Ce qui se passe, c'est que datatables sont lues plus rapidement qu'elles ne peuvent être écrites sur le disque de destination. Quand linux copy des files, ce qu'il fait est de les lire dans la RAM, puis de marquer les pages comme sales pour écrire sur la destination. Les pages sales ne peuvent pas être échangées. Donc, si le disque source est plus rapide que le disque de destination et que vous copyz plus de données que la RAM libre, l'opération de copy dévorera toute la RAM disponible (ou au less quelle que soit la limite de pages, ce qui pourrait être plus que le RAM disponible) et causer la famine car les pages sales ne peuvent pas être permutées et les pages propres s'usent et marquées comme sales lorsqu'elles sont libérées.

Notez que son ne résoudra pas complètement le problème … ce que linux a vraiment besoin d'une façon d'arbitrer la création de pages sales, donc un grand transfert qui prend place ne dévore pas toutes les RAM disponibles / toutes les pages sales autorisées.