Tarhon-Onu Victor scria la data de 27 Decembrie 2005: > On Tue, 27 Dec 2005, Liviu Daia wrote: [...] > > Este 4096 sub Linux si 65536 sub OpenBSD, cum spuneam in primul > > mesaj. Sub Linux asta coincide cu ce rezulta din "ulimit -p", sub > > OpenBSD nu. > > Pentru ca e alt buffer, omule!!! De ce nu intelegi?! Asta am > vrut sa-ti spun din prima cind am dat exemplu de o fila de pe un ext3 > si una de pe un reiser.
Unde am spus eu ca ar fi acelasi? Eu tocmai asta am afirmat de la inceput: ca rezultatul lui "ulimit -p" (de care tu ai adus vorba) nu are nici o legatura cu ce discutam. > ++La ulimit -p e dimensiunea bufferului la pipe-ul in bash > (chiar ar fi interesant de vazut daca in, sa zicem, tcsh, are aceeasi > dimensiune maxima) Nu exista un "pipe in Bash". Exista doar pipe-uri ale sistemului, buffer-e stdio(3) (controlate de Bash) si blocuri ale filesystem-urilor. Pipe-urile sistemului sunt buffer-ate, si buffer-eleĆ£ lor au doua dimensiuni caracteristice: un PIPE_BUF, care este lungimea minima garantata (atat se poate accesa atomic), si un PIPE_SIZE, care este lungimea alocata de fapt (o pagina). Ambele valori sunt definite in /usr/include/limits.h si sub Linux sunt 4096. In toate cazurile, "ulimit -p" iti arata valoarea fixa PIPE_BUF. Din sursele Bash 3.1, builtins/ulimit.def: 611 static int 612 pipesize (valuep) 613 RLIMTYPE *valuep; 614 { 615 #if defined (PIPE_BUF) 616 /* This is defined on Posix systems. */ 617 *valuep = (RLIMTYPE) PIPE_BUF; 618 return 0; 619 #else 620 # if defined (_POSIX_PIPE_BUF) 621 *valuep = (RLIMTYPE) _POSIX_PIPE_BUF; 622 return 0; 623 # else 624 # if defined (PIPESIZE) 625 /* This is defined by running a program from the Makefile. */ 626 *valuep = (RLIMTYPE) PIPESIZE; 627 return 0; 628 # else 629 errno = EINVAL; 630 return -1; 631 # endif /* PIPESIZE */ 632 # endif /* _POSIX_PIPE_BUF */ 633 #endif /* PIPE_BUF */ 634 } Insa acest tip de buffer-e (si dimensiunea lor) nu sunt relevante pentru problema in discutie, vezi in primul meu mesaj de ce. > iar dimensiunea maxima de 4096 pentru bufferele pe care le arati tu > este pentru stdout Eu folosesc programul asa: ./s >file caz in care obtin valoarea st_blksize pentru filesystem-ul pe care sta "file". > (daca aveai putina prezenta de spirit aici aratai ca dimensiunea > maxima a bufferului la stderr are "alta" valoare, si puteai sa mergi > pe varianta "cum ar merge tcpdump [args] >&2 de exemplu - si de ce?"). De fapt valoarea st_blksize pentru terminale (in particular pentru stderr neredirectat) este PIPE_SIZE, adica tot 4096 sub Linux, dar 64 KB sub OpenBSD (pentru TCP depinde de alti parametri). In particular, asta e intotdeauna mai mare, dar nu coincide neaparat cu valoarea rezultata din "ulimit -p" de mai sus. Daca redirectezi stdout sau stderr, valoarea se schimba in cea a fisierului catre care faci redirectarea. > Ca dimensiunea maxima implicita a bufferului la pipe-uri un bash > e 4k (ajustabila cu ulimit -p, atentie) Valoarea asta e read-only. Din acelasi fisier builtins/ulimit.def: 506 static int 507 set_limit (ind, newlim, mode) 508 int ind; 509 RLIMTYPE newlim; 510 int mode; 511 { [...] 518 switch (limits[ind].parameter) 519 { [...] 538 case RLIMIT_PIPESIZE: 539 case RLIMIT_VIRTMEM: 540 case RLIMIT_MAXUPROC: 541 default: 542 errno = EINVAL; 543 return -1; 544 } > iar la stdout e tot aia nu are nici o relevanta!!! Adevarat, asta am sustinut si eu de la inceput. > Daca te joci cu ulimit -p schimbi dimensiunea maxima a bufferului la > pipe, iar stdout-ul ca-l pipe-uiesti, ca-l dup2-esti, ca-l redirectezi > intr-un fisier de pe un filesystem pe care dimensiunea bufferului e > 128k el tot 4k va ramine! Aici amesteci al treilea tip de buffer, cel al stdio(3), modificabil (de catre Bash) cu setvbuf(3). Dimensiunea default a acestui buffer este BUFSIZ, definit in /usr/include/stdio.h, si care e 8192 sub Linux. Totusi, Bash-ul nu schimba aceasta dimensiune (nici intern, nici inghesuit de user). Initial si eu am crezut ca dimensiunea acestui buffer este cea care conteaza pentru dimensiunea chunk-urilor scrise pe disc. Nu este insa asa, chunk-urile au exact st_blksize, dependent de filesystem. Ar fi fost totusi de asteptat ca dimensiunea chunk-urilor scrise pe disc sa fie intotdeauna un multiplu intreg de BUFSIZ. Acest lucru nu se intampla insa, dupa cum se vede din situatia initiala (BUFSIZ = 8192, st_blksize = 4096). Cauza aici este un bug in glibc, care promite buffer-e de 8192 dar scrie pe disc in blocuri care pot fi mai mici. Acest bug nu are insa nici o consecinta practica, nici macar ca performanta (dimensiunea st_blksize este intotdeauna optima). > Vor fi buffere diferite (ala al filedescriptorului pentru stdout se > va goli odata al 4k bytes iar ala al filesystemului se va umple odata > al 128, ala al pipe-ului se va goli si el cumva, etc, e ca si cum > ai turna apa cu o sticla de 2l intr-o alta sticla de 2l sau intr-o > caldare - dupa caz). Te rog nu ameste iar pipe-ul aici. Nu are nici o legatura. > > Nu am sustinut niciodata asta. Am dat un exemplu in sensul asta > > Atunci ce tot o arzi sus si tare ca linux-4096 si > numaistiucareBSD-16384?!?! Sau vrei sa spui ca "ana are mere" insa > formulezi cumva ca "capra aia de pe cimpul lui 'nea Gica pe care a > boteza-o ionel 'ana' acum ceva timp a facut rost de o strachina in > care erau vreo citeva mere". Keep it simple si accentuiaza ideile pe > care vrei sa insisti - ca eu nu am distins vroe una. Exista trei tipuri de buffer-e: (1) ale pipe-urilor; fara legatura cu problema. (2) ale stdio(3), controlate de Bash; primul guess, dar incorect. (3) st_blksize, la nivel mai jos decat stdio(3), cu dimensiune dependenta de filesystem-ul pe care sta fisierul. Afirmatia mea e ca fisierele se scriu pe disc in chunk-uri avand dimensiunea de la (3), fara legatura cu (1) sau (2). Sper ca acum e ceva mai clar. Salutari, Liviu Daia -- Dr. Liviu Daia http://www.imar.ro/~daia _______________________________________________ RLUG mailing list RLUG@lists.lug.ro http://lists.lug.ro/mailman/listinfo/rlug