Forum Programmation.perl Perl, AIX et les limits

Posté par  .
Étiquettes : aucune
0
1
avr.
2008
Bonjour,

Voilà je rencontre un soucis avec Perl sous AIX, je cherche à comprendre pourquoi un paramètre sytème n'est pas pris en compte dans l'environnement de Perl.

J'ai configuré sous AIX les limit avec les valeurs suivantes :


time(seconds) unlimited
file(blocks) unlimited
data(kbytes) unlimited
stack(kbytes) unlimited
memory(kbytes) unlimited
coredump(blocks) 2097151
nofiles(descriptors) 2000


Ces paramètres sont bien pris en compte par n'importe quelle session shell SAUF dans l'environnement Perl :


# perl
system("ulimit -a");
time(seconds) unlimited
file(blocks) unlimited
data(kbytes) 2097152
stack(kbytes) unlimited
memory(kbytes) unlimited
coredump(blocks) 2097151
nofiles(descriptors) 2000


On remarque que le paramètre "data" ne correspond pas à ce qui est paramétré dans le système.

D'après cette documentation http://perl.enstimac.fr/DocFr/perlfunc.html#item_system

Il apparait que la fonction system() fait appel à un shell de cette façon :

sh -c "argument"

Or, si je reproduis ce que fait perl, j'obtiens bien les bonnes valeurs :


# sh -c "ulimit -a"
time(seconds) unlimited
file(blocks) unlimited
data(kbytes) unlimited
stack(kbytes) unlimited
memory(kbytes) unlimited
coredump(blocks) 2097151
nofiles(descriptors) 2000


Mais finalement, je ne suis pas sûr de bien reproduire l'environnement de perl car le shell que je lance est fils du mien (l'interactif), et donc les paramètres sont à priori bien hérités.

D'après mes recherches sur la toile, je trouve bien des gens qui ont le même problème que moi :

http://www.perlmonks.org/?node_id=651397

Les solutions proposées ne sont pas envisageables car les scripts perl que j'exécute sont livrés par notre éditeur et il est hors de question de les modifier, même si c'est tentant :-)

De même que l'installation d'un module supplémentaire est à exclure.

http://www.tek-tips.com/viewthread.cfm?qid=1454391&page=2

L'astuce proposée ici m'a paru après coup la plus évidente, il suffirait de basculer sur les binaires 64 bits, ce que j'ai fait avec le script qui va bien, mais le problème reste toujours là, le paramètre "data" est bloqué à 2048Mo.

Je précise que aix tourne bien en 64 bits (le noyau) et que le CPU est aussi 64 bits.

Est-ce que quelqu'un pourrait éclairer ma lanterne ?

Merci par avance.

PS: Voici le résultat d'un perl -V


Summary of my perl5 (revision 5.0 version 8 subversion 2) configuration:
Platform:
osname=aix, osvers=5.2.0.0, archname=aix-thread-multi-64all
uname='aix perlfly 2 5 000ad7df4c00 '
config_args=''
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=define use64bitall=define uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc_r', ccflags ='-D_ALL_SOURCE -D_ANSI_C_SOURCE -D_POSIX_SOURCE -qmaxmem=-1 -qnoansialias -DUSE_NATIVE_DLOPEN -DNEED_PTHREAD_INIT -q64 -DUSE_64_BIT_ALL -q64',
optimize='-O',
cppflags='-D_ALL_SOURCE -D_ANSI_C_SOURCE -D_POSIX_SOURCE -qmaxmem=-1 -qnoansialias -DUSE_NATIVE_DLOPEN -DNEED_PTHREAD_INIT'
ccversion='', gccversion='', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=87654321
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='ld', ldflags ='-brtl -bmaxdata:0x80000000 -q64 -b64'
libpth=/lib /usr/lib /usr/ccs/lib
libs=-lbind -lnsl -ldbm -ldl -lld -lm -lcrypt -lpthreads -lc_r -lbsd
perllibs=-lbind -lnsl -ldl -lld -lm -lcrypt -lpthreads -lc_r -lbsd
libc=/lib/libc.a, so=a, useshrplib=true, libperl=libperl.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_aix.xs, dlext=so, d_dlsymun=undef, ccdlflags=' -bE:/usr/opt/perl5/lib64/5.8.2/aix-thread-multi-64all/CORE/perl.exp'
cccdlflags=' ', lddlflags='-b64 -bhalt:4 -bM:SRE -bI:$(PERL_INC)/perl.exp -bE:$(BASEEXT).exp -bnoentry -lpthreads -lc_r'


Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY USE_ITHREADS USE_64_BIT_INT USE_64_BIT_ALL USE_LARGE_FILES PERL_IMPLICIT_CONTEXT
Built under aix
Compiled at Feb 7 2005 19:07:12
@INC:
/usr/opt/perl5/lib64/5.8.2/aix-thread-multi-64all
/usr/opt/perl5/lib64/5.8.2
/usr/opt/perl5/lib64/site_perl/5.8.2/aix-thread-multi-64all
/usr/opt/perl5/lib64/site_perl/5.8.2
/usr/opt/perl5/lib64/site_perl
  • # TLDR

    Posté par  . Évalué à -4.

    TLDR
  • # Une histoire de famille

    Posté par  (site web personnel) . Évalué à 2.

    ulimit est une commande shell qui ne s'applique qu'au shell en cours et à ses descendants.

    La fonction system en perl lance une commande shell. Et donc dans un sous shell puisque perl n'interprète pas le shell :)

    Par conséquent ta commande ulimit ne peut être prise en compte par perl qui et le père du shell ayant lancé la commande.

    Pour que la commande s'applique au processus en cours, il faut faire appel directement à l'appel système concerné. Je ne doute pas que tu puisse trouver ton bonheur dans le cpan.

    L'autre solution est de lancer ton script perl dans un script shell qui fera lui-même la commande ulimit avant de lancer perl (son fils cette fois).
    • [^] # Re: Une histoire de famille

      Posté par  . Évalué à 2.

      ulimit est une commande shell qui ne s'applique qu'au shell en cours et à ses descendants.

      Tout à fait, sauf que mes paramètres sont persistants c'est à dire qu'ils sont bien stockés dans le fichier /etc/security/limits d'AIX et donc ils doivent s'appliquer à tous les environnements shell.

      La fonction system en perl lance une commande shell. Et donc dans un sous shell puisque perl n'interprète pas le shell :)

      Ce n'est pas parce que la commande "ulimit" n'est pas gérée par Perl qu'il y a création d'un nouveau process, c'est juste que c'est la fonction première de system() que de faire un fork() et donc un process shell (sh -c en locurence), donc le shell exécuté est effectivement bien fils de perl..

      En effet, on pourrait pu tout aussi bien écrire exec("ulimit -a") où là le shell remplace le process perl le temps de l'exécution, enfin bref, le coeur du problème n'est pas là :-)

      Par conséquent ta commande ulimit ne peut être prise en compte par perl qui et le père du shell ayant lancé la commande.

      Mais je ne cherche pas à appliquer cette commande à perl, je cherche à comprendre pourquoi l'environnement du shell lancé par Perl est différent des autres !

      Pour que la commande s'applique au processus en cours, il faut faire appel directement à l'appel système concerné. Je ne doute pas que tu puisse trouver ton bonheur dans le cpan.

      merci mais ce n'est pas ce que je veux faire, je ne cherche pas à appliquer le paramètre au process en cours, et je connais quel est le module en question, il est même proposé dans la première URL de mes recherches.

      L'autre solution est de lancer ton script perl dans un script shell qui fera lui-même la commande ulimit avant de lancer perl (son fils cette fois).

      Comme précisé plus haut, mes paramètres ulimit sont persistants c'est à dire qu'il n'y a pas besoin de les spécifier au runtime, donc que je lance perl depuis un shell interactif ou non revient au même...

      La preuve par l'exemple :


      #!/usr/bin/ksh

      ulimit -d unlimited
      echo "Affichage des params effectifs sous shell"
      ulimit -a

      echo "Affichage des params effectifs sous le shell lancé par Perl"
      perl << EOF
      system("ulimit -a");
      EOF


      et le résultat :


      Affichage des params effectifs sous shell
      time(seconds) unlimited
      file(blocks) unlimited
      data(kbytes) unlimited
      stack(kbytes) unlimited
      memory(kbytes) unlimited
      coredump(blocks) 2097151
      nofiles(descriptors) 2000
      Affichage des params effectifs sous le shell lancé par Perl
      time(seconds) unlimited
      file(blocks) unlimited
      data(kbytes) 2097152
      stack(kbytes) unlimited
      memory(kbytes) unlimited
      coredump(blocks) 2097151
      nofiles(descriptors) 2000


      Tu constates comme moi que le paramètre data n'est pas le même, c'est que ce je ne comprends pas :-/
  • # Résolu

    Posté par  . Évalué à 3.

    Vu sur comp.unix.aix, en fait perl a été compilé avec un parmaètre maxdata limité à 2Go :


    perl -V | grep maxdata
    ld='ld', ldflags ='-brtl -bmaxdata:0x80000000 -q64 -b64'


    Même les binaires 64 bits sont compilés avec cette option.

    Il semblerait bien que ce paramètre influe sur les limit de l'environnement shell généré par Perl via les fonctions system, exec....

    Il ne reste plus qu'à recompiler Perl...
    • [^] # Re: Résolu

      Posté par  (site web personnel) . Évalué à 2.

      Il me semblait avoir vu dans la doc que l'utilisation du paramètre bmaxdata était à proscrire en cas d'utilisation 64bits.
      Quelqu'un sait s'il y a un intérêt à l'utiliser ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.