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

Raspunde prin e-mail lui