---------- Forwarded message ----------
Date: Thu, 14 Jun 2001 10:46:29 +0200 (MEST)
From: Marc SCHAEFER <[EMAIL PROTECTED]>
To: Félix Hauri <[EMAIL PROTECTED]>

On Wed, 13 Jun 2001, Félix Hauri wrote:

> $ cat vmlinuz.tst /dev/zero |dd of=truc28 bs=2048 count=336
> ne marche pas, tandis que
> $ cat vmlinuz.tst /dev/zero |dd of=truc28 ibs=1 obs=2048 \
     count=$((2048*336))
> marche mieux, mais consomme énhôrmement de proc et de temps:(

Problème: cat va vraisemblablement envoyer au plus des blocks de 4096
bytes (PIPES_SIZ), jusqu'à la fin du fichier, et là si le fichier n'a pas
une taille multiple de 4096, il y aura un bloc ``incomplet'', puis
ouverture de /dev/zero et envoi de blocks usuels. 

read(3, "n\376>\276\301\2744\276\327\\~+\342\214yY\374\272\271\374"...,
4096) = 2087
write(1, "n\376>\276\301\2744\276\327\\~+\342\214yY\374\272\271\374"...,
2087) = 2087
read(3, "", 4096)     
close(3)                                = 0
open("/dev/zero", O_RDONLY|0x8000)      = 3
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096)
= 4096
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
4096) = 4096

En bref il faut dire à dd d'accepter une taille quelconque d'I/O en entrée
(mais au plus 4096 bytes), et de rebufferiser le tout en sortie avec une
taille correcte spécifiée (multiple de 512 bytes si taille de I/O tape 512
fixe; sinon taille constante p.ex. 4096 bytes ou 32kbytes si mode
variable, ie setblk 0), avec au pire un bloc de taille inférieur pour le
DERNIER bloc de la taille (en mode variable), ou sinon, en mode fixe 512,
ajouter des NULs.

PS: ta question de la voiture:

       count=BLOCKS
              copy only BLOCKS *input* blocks

Reprenons un petit exemple avec 
-rw-r--r--    1 schaefer schaefer      387 Jun 14 10:29 test_file
-rw-r--r--    1 schaefer schaefer     4096 Jun 14 10:30 test_file_2
et strace -e 'read,write' cat test_file test_file_2 > /dev/null

read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\244\213"...,
4096) = 4096 --- lecture d'une bibliothèque, ne pas considérer.
read(3, "\270\300\7\216\330\270\0\220\216\300\271\0\1)\366)\377"..., 4096)
= 387
write(1, "\270\300\7\216\330\270\0\220\216\300\271\0\1)\366)\377"..., 387)
= 387
read(3, "", 4096)                       = 0
read(3, "\270\300\7\216\330\270\0\220\216\300\271\0\1)\366)\377"..., 4096)
= 4096
write(1, "\270\300\7\216\330\270\0\220\216\300\271\0\1)\366)\377"...,
4096) = 4096
read(3, "", 4096)                       = 0

Donc lecture de 387 bytes, puis écriture de ces bytes, lecture de 4096,
écriture idem, puis EOF. (le code de retour, = truc, sur la droite est le
nombre de bytes réellement lus; la valeur dans la parenthèse le max du
buffer).

Pour bien comprendre, expérimente un peu avec:

   cat test_file test_file_2 | strace -e 'read,write' dd of=/dev/null

et ensuite ajoute un bs=1024: tu verras que les I/Os font au plus 1024,
mais quand un I/O de 387 arrive, il sort en write de 387. Maintenant, si
tu mets obs=1024, tu remarques qu'un nombre certains de read() sont
nécessaires afin de remplir le buffer write().

Maintenant, à travers un pipe, compare avec obs=4096 et obs=8192, avec un
fichier test_file_2 p.ex. 16384 bytes p.ex.  (sur ix86, car sur Alpha,
PIP_SIZE est probablement 8k, taille de page MMU de ce processeur).
Utiliser ulimit -p pour savoir (unité: spécifiée dans ulimit -a, 8 x 512 
bytes chez moi).

   cat test_file test_file_2 | strace -e 'read,write' dd obs=8192 \
      | cat > /dev/null

cat test_file test_file_2 | dd obs=8192 | strace -e 'read,write' cat > /dev/null

Conclusion: le dd a l'impression de pouvoir écrire 8kb, mais de l'autre
côté on voit 4kb seulement. Rappelons que toute écriture inférieure à
PIP_SIZE est garantie atomique sous UNIX -> écriture non atomique.
Donc si N processus sont connectés via un pipe UNIX à un processus
serveur, il y aura entremêlement des données pour taille > 4096 bytes.
Apache utilise cette propriété pour rendre ses écritures atomiques de
façon efficace.

Remarque qu'on n'a pas spécifié count, et d'ailleurs on a meilleur temps,
car c'est le input block count, pas en bytes, mais en blocks,
éventuellement partiels!

PS: tu peux poster mon mail, ou un résumé sur la ml.

(ndfwdr: C'est fait;-)
--
 Félix Hauri  -  <[EMAIL PROTECTED]>  -  http://www.f-hauri.ch


--
http://www-internal.alphanet.ch/linux-leman/ avant de poser
une question. Ouais, pour se désabonner aussi.

Reply via email to