getrlimit, getrusage, setrlimit - devuelve/establece el
límite de recursos y su utilización
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
int getrlimit(int resource, struct rlimit
*rlim);
int getrusage(int who, struct rusage
*usage);
int setrlimit(int resource, const struct rlimit
*rlim);
getrlimit y setrlimit devuelve / establece el
límite de recursos, respectivamente. Cada recurso tiene asociado un
límite flexible y otro estricto, tal como se define en la estructura
rlimit (el argumento rlim de las rutinas getrlimit() y
setrlimit()):
struct rlimit {
rlim_t rlim_cur; /* Límite flexible (Soft limit) */
rlim_t rlim_max; /* Límite estricto (Hard limit)
(tope para rlim_cur) */
};
El límite flexible es el valor que impone el núcleo para el
recurso correspondiente. El límite estricto actúa como un tope
para el límite flexible: un proceso no privilegiado puede solamente
establecer su límite flexible a un valor comprendido entre 0 y el
límite estricto, y (irreversiblemente) menor que su límite
estricto. Un proceso privilegiado puede hacer cualquier cambio sobre ambos
valores límite.
El valor RLIM_INFINITY no impone ningún
límite sobre un recurso (tanto en la estructura devuelta por
getrlimit() como en la estructura pasada a setrlimit()).
resource debe ser uno de los siguientes valores:
- RLIMIT_CPU
- Tiempo de CPU en segundos. Cuando el proceso alcanza el límite
flexible, se le envía una señal SIGXCPU. La
acción por defecto para esta señal es terminar el proceso.
Sin embargo, la señal puede ser atrapada, y el manejador puede
devolver el control al programa principal. Si el proceso continúa
consumiendo tiempo de CPU, se le enviará SIGXCPU una vez por
segundo hasta que se alcance el límite estricto, momento en el cual
se le enviará la señal SIGKILL. (Este último
punto describe el comportamiento de Linux 2.2 y 2.4. Las implementaciones
varían en el tratamiento de los procesos que continúna
consumiendo tiempo de CPU después de alcanzar el límite
flexible. Las aplicaciones portables que necesiten atrapar esta
señal deberían realizar una terminación ordenada
después de recibir la primera señal SIGXCPU.)
- RLIMIT_DATA
- El tamaño máximo del segmento de datos del proceso (datos
inicializados, no inicializados y el montículo). Este límite
afecta a las llamadas a brk() and sbrk(), que fallan con el
error ENOMEM al llegarse al límite flexible de este
recurso.
- RLIMIT_FSIZE
- El tamaño máximo de los ficheros que puede crear el proceso.
Los intentos por sobrepasar este límite provocan la
comunicación de una señal SIGXFSZ. Por defecto, esta
señal termina el proceso, pero un proceso puede atrapar esta
señal en su lugar, en cuyo caso la llamada al sistema relevante
(p.e., write(), truncate()) falla con el error
EFBIG.
- RLIMIT_LOCKS
- Un límite sobre el número combinado de bloqueos
flock() y arrendamientos fcntl() que este proceso puede
establecer (Linux 2.4 y posteriores).
- RLIMIT_MEMLOCK
- El número máximo de bytes de memoria virtual que pueden ser
bloqueados en RAM usando mlock() y mlockall().
- RLIMIT_NOFILE
- Especifica un valor que es el número máximo de descriptor de
fichero que puede ser abierto por este proceso. Los intentos de
(open(), pipe(), dup(), etc.) por exceder este
límite provocarán el error EMFILE.
- RLIMIT_NPROC
- El número máximo de procesos que pueden ser creados por el
identificador de usuario real del proceso invocador. Al alcanzar este
límite, fork() falla con el error EAGAIN.
- Especifica el límite (en páginas) del conjunto residente del
proceso (el número de páginas virtuales residentes en RAM).
Este límite sólo tiene efecto en Linux 2.4 en adelante, y
sólo afecta a las llamadas a madvise() especificando
MADVISE_WILLNEED.
- RLIMIT_STACK
- El tamaño máximo de la pila del proceso, en bytes. Al
alcanzar este límite, se genera una señal SIGSEGV.
Para manejar esta señal, un proceso debe emplear una pila de
señales alternativa (sigaltstack(2)).
RLIMIT_OFILE es el nombre BSD para
RLIMIT_NOFILE.
getrusage devuelve la utilización actual de los
recursos, para un who de cualquiera de los siguientes, bien
RUSAGE_SELF oo RUSAGE_CHILDREN.
struct rusage {
struct timeval ru_utime; /* tiempo de usuario utilizado */
struct timeval ru_stime; /* tiempo de sistema utilizado */
long ru_maxrss; /* tamaño máximo de la parte
establecida como residente */
long ru_ixrss; /* tamaño total de la memoria
compartida */
long ru_idrss; /* tamaño total de la memoria
no compartida */
long ru_isrss; /* tamaño de pila no compartido */
long ru_minflt; /* peticiones de página */
long ru_majflt; /* fallos de página */
long ru_nswap; /* intercambios */
long ru_inblock; /* operaciones de entrada de
bloques */
long ru_oublock; /* operaciones de salida de
bloques */
long ru_msgsnd; /* mensajes enviados */
long ru_msgrcv; /* mensajes recibidos */
long ru_nsignals; /* señales recibidas */
long ru_nvcsw; /* cambios de contexto
voluntarios */
long ru_nivcsw; /* cambios de contexto
involuntarios */
};
Si tiene éxito, devuelve cero. Si hay error, devuelve -1, y
errno toma el correspondiente valor.
- EFAULT
- rlim o usage apuntan fuera del espacio de direcciones
accesible.
- EINVAL
- getrlimit o setrlimit es llamado con un resource
erróneo, o getrusage es llamado con un who
erróneo.
- EPERM
- Un no-superusuario intenta utilizar setrlimit() para incrementar el
límite `flexible' o `estricto' por encima del límite
estricto actual, o un superusuario intenta incrementar RLIMIT_NOFILE por
encima del máximo actual del núcleo.
Incluir <sys/time.h> no es necesario actualmente,
pero incrementa la transportabilidad. (De hecho, struct timeval
está definida en <sys/time.h>.)
En Linux, si la acción asociada a SIGCHLD es
SIG_IGN los usos del recurso por los procesos hijo son incluidos
automáticamente en el valor devuelto por RUSAGE_CHILDREN,
aunque POSIX 1003.1-2001 prohíbe ésto
explícitamente.
La estructura de arriba fue tomada de BSD 4.3 Reno. No todos los
campos son significativos bajo Linux. En la actualidad (Linux 2.4)
sólo los campos ru_utime, ru_stime, ru_minflt,
ru_majflt, y ru_nswap son mantenidos.
dup(2), fcntl(2), fork(2), mlock(2),
mlockall(2), mmap(2), open(2), quotactl(2),
sbrk(2), wait3(2), wait4(2), malloc(3),
ulimit(3), signal(7)