Programmation.perl : Perl, AIX et les limits

Posté par Dabowl_92 () le 01 avril 2008
0

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

> Lire le message (5 commentaires, moyenne: 1).  

Vous avez demandé le commentaire #918556.

Une histoire de famille

Posté par peck (page perso, ) le 01/04/2008 à 17:30. (lien). É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).

[ Répondre ]

  • [^]Re: Une histoire de famille

    Posté par Dabowl_92 () le 01/04/2008 à 18:17. (lien). É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épondre ]