1998-03-10 17:54  Ulrich Drepper  <drepper@cygnus.com>

	* libc.map: Add _dl_debug_message.
	* elf/dl-misc.c: Make _dl_debug_message a function.  Print the PID
	before every line.
	* elf/fini.c: Correctly use new _dl_debug_message function.
	* elf/init.c: Likewise.
	* elf/dl-lookup.c: Likewise.
	* sysdeps/unix/sysv/linux/libc-start.c: Likewise.
	* elf/dl-load.c: Likewise.  Add more debugging prints.
	* elf/dl-reloc.c: Likewise.
	* elf/dl-version.c: Likewise.
	* elf/dl-support.c: Add variables for debugging.
	* elf/rtld.c: Likewise.  Recognize new debug options.
	* elf/link.h: Declare new variables.

	* elf/dl-deps.c (_dl_map_object_deps): Little optimizations.

	* sysdeps/unix/sysv/linux/sys/quota.h: Extract information from
	kernel headers.  Patch by a sun <asun@saul7.u.washington.edu>.

1998-03-11 00:16  Tim Waugh  <tim@cyberelk.demon.co.uk>

	* posix/wordexp-test.c (command_line_test): New function to allow
	testing of specific cases from the command-line.

1998-03-10  Ulrich Drepper  <drepper@cygnus.com>

	* elf/dl-init.c (_dl_init_next): Print nicer messages.
	* elf/dl-fini.c (_dl_fini): Likewise.
	* sysdeps/unix/sysv/linux/libc-start.c (__libc_start_main): Likewise.
This commit is contained in:
Ulrich Drepper 1998-03-10 18:04:16 +00:00
parent 62c349c632
commit 8193034b1d
16 changed files with 395 additions and 47 deletions

View File

@ -1,5 +1,37 @@
1998-03-10 17:54 Ulrich Drepper <drepper@cygnus.com>
* libc.map: Add _dl_debug_message.
* elf/dl-misc.c: Make _dl_debug_message a function. Print the PID
before every line.
* elf/fini.c: Correctly use new _dl_debug_message function.
* elf/init.c: Likewise.
* elf/dl-lookup.c: Likewise.
* sysdeps/unix/sysv/linux/libc-start.c: Likewise.
* elf/dl-load.c: Likewise. Add more debugging prints.
* elf/dl-reloc.c: Likewise.
* elf/dl-version.c: Likewise.
* elf/dl-support.c: Add variables for debugging.
* elf/rtld.c: Likewise. Recognize new debug options.
* elf/link.h: Declare new variables.
* elf/dl-deps.c (_dl_map_object_deps): Little optimizations.
1998-03-10 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/sys/quota.h: Extract information from
kernel headers. Patch by a sun <asun@saul7.u.washington.edu>.
1998-03-11 00:16 Tim Waugh <tim@cyberelk.demon.co.uk>
* posix/wordexp-test.c (command_line_test): New function to allow
testing of specific cases from the command-line.
1998-03-10 Ulrich Drepper <drepper@cygnus.com>
* elf/dl-init.c (_dl_init_next): Print nicer messages.
* elf/dl-fini.c (_dl_fini): Likewise.
* sysdeps/unix/sysv/linux/libc-start.c (__libc_start_main): Likewise.
* elf/dl-lookup.c (_dl_lookup_versioned_symbol): Print version
symbol in debug message.
(_dl_lookup_versioned_symbol_skip): Likewise.

View File

@ -139,7 +139,7 @@ _dl_map_object_deps (struct link_map *map,
{
struct link_map *l = runp->map;
if (l->l_info[AUXTAG] || l->l_info[FILTERTAG] || l->l_info[DT_NEEDED])
if (l->l_info[DT_NEEDED] || l->l_info[AUXTAG] || l->l_info[FILTERTAG])
{
const char *strtab = ((void *) l->l_addr
+ l->l_info[DT_STRTAB]->d_un.d_ptr);
@ -228,12 +228,11 @@ _dl_map_object_deps (struct link_map *map,
newp = alloca (sizeof (struct list));
/* Copy the content of the current entry over. */
memcpy (newp, orig, sizeof (*newp));
orig->dup = memcpy (newp, orig, sizeof (*newp));
/* Initialize new entry. */
orig->done = 0;
orig->map = args.aux;
orig->dup = newp;
/* We must handle two situations here: the map is new,
so we must add it in all three lists. If the map
@ -347,7 +346,7 @@ _dl_map_object_deps (struct link_map *map,
if (runp->done)
do
runp = runp->unique;
while (runp && runp->done);
while (runp != NULL && runp->done);
}
/* Store the search list we built in the object. It will be used for

View File

@ -32,9 +32,9 @@ _dl_fini (void)
{
/* When debugging print a message first. */
if (_dl_debug_impcalls)
_dl_debug_message ("\n\tcalling fini: ",
_dl_debug_message (1, "\ncalling fini: ",
l->l_name[0] ? l->l_name : _dl_argv[0],
"\n", NULL);
"\n\n", NULL);
(*(void (*) (void)) (l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
}

View File

@ -60,7 +60,7 @@ _dl_init_next (struct link_map *map)
/* Print a debug message if wanted. */
if (_dl_debug_impcalls)
_dl_debug_message ("\tcalling init: ",
_dl_debug_message (1, "\ncalling init: ",
l->l_name[0] ? l->l_name : _dl_argv[0],
"\n\n", NULL);

View File

@ -28,6 +28,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "dynamic-link.h"
#include <stdio-common/_itoa.h>
/* On some systems, no flag bits are given to specify file mapping. */
@ -527,6 +528,7 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
const ElfW(Ehdr) *header;
const ElfW(Phdr) *phdr;
const ElfW(Phdr) *ph;
size_t maplength;
int type;
/* Look again to see if the real name matched another already loaded. */
@ -545,6 +547,10 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
return l;
}
/* Print debugging message. */
if (_dl_debug_files)
_dl_debug_message (1, "file=", name, "; generating link map\n", NULL);
/* Map in the first page to read the header. */
header = map (0, sizeof *header);
@ -663,6 +669,9 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
/* Now process the load commands and map segments into memory. */
c = loadcmds;
/* Length of the sections to be loaded. */
maplength = loadcmds[nloadcmds - 1].allocend - c->mapstart;
if (type == ET_DYN || type == ET_REL)
{
/* This is a position-independent shared object. We can let the
@ -678,7 +687,6 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
the OS can do whatever it likes. */
caddr_t mapat;
ElfW(Addr) mappref;
size_t maplength = loadcmds[nloadcmds - 1].allocend - c->mapstart;
mappref = (ELF_PREFERRED_ADDRESS (loader, maplength, c->mapstart)
- MAP_BASE_ADDR (l));
mapat = map_segment (mappref, maplength, c->prot, 0, c->mapoff);
@ -786,6 +794,36 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
l->l_entry += l->l_addr;
if (_dl_debug_files)
{
const size_t nibbles = sizeof (void *) * 2;
char buf1[nibbles + 1];
char buf2[nibbles + 1];
char buf3[nibbles + 1];
buf1[nibbles] = '\0';
buf2[nibbles] = '\0';
buf3[nibbles] = '\0';
memset (buf1, '0', nibbles);
memset (buf2, '0', nibbles);
memset (buf3, '0', nibbles);
_itoa_word ((unsigned long int) l->l_ld, &buf1[nibbles], 16, 0);
_itoa_word ((unsigned long int) l->l_addr, &buf2[nibbles], 16, 0);
_itoa_word (maplength, &buf3[nibbles], 16, 0);
_dl_debug_message (1, " dynamic: 0x", buf1, " base: 0x", buf2,
" size: 0x", buf3, "\n", NULL);
memset (buf1, '0', nibbles);
memset (buf2, '0', nibbles);
memset (buf3, ' ', nibbles);
_itoa_word ((unsigned long int) l->l_entry, &buf1[nibbles], 16, 0);
_itoa_word ((unsigned long int) l->l_phdr, &buf2[nibbles], 16, 0);
_itoa_word (l->l_phnum, &buf3[nibbles], 10, 0);
_dl_debug_message (1, " entry: 0x", buf1, " phdr: 0x", buf2,
" phnum: ", buf3, "\n\n", NULL);
}
elf_get_dynamic_info (l->l_ld, l->l_info);
if (l->l_info[DT_HASH])
_dl_setup_hash (l);
@ -800,7 +838,7 @@ print_search_path (struct r_search_path_elem **list,
{
int first = 1;
_dl_debug_message ("\t search path=", NULL);
_dl_debug_message (1, " search path=", NULL);
while (*list != NULL && (*list)->what == what) /* Yes, ==. */
{
@ -809,23 +847,23 @@ print_search_path (struct r_search_path_elem **list,
if ((*list)->machdirstatus != nonexisting)
{
buf[(*list)->machdirnamelen - 1] = '\0';
_dl_debug_message (first ? "" : ":", buf, NULL);
_dl_debug_message (0, first ? "" : ":", buf, NULL);
first = 0;
}
if ((*list)->dirstatus != nonexisting)
{
buf[(*list)->dirnamelen - 1] = '\0';
_dl_debug_message (first ? "" : ":", buf, NULL);
_dl_debug_message (0, first ? "" : ":", buf, NULL);
first = 0;
}
++list;
}
if (name != NULL)
_dl_debug_message ("\t\t(", what, " from file ",
_dl_debug_message (0, "\t\t(", what, " from file ",
name[0] ? name : _dl_argv[0], ")\n", NULL);
else
_dl_debug_message ("\t\t(", what, ")\n", NULL);
_dl_debug_message (0, "\t\t(", what, ")\n", NULL);
}
/* Try to open NAME in one of the directories in DIRS.
@ -871,7 +909,7 @@ open_path (const char *name, size_t namelen, int preloaded,
/* Print name we try if this is wanted. */
if (_dl_debug_libs)
_dl_debug_message ("\t trying file=", buf, "\n", NULL);
_dl_debug_message (1, " trying file=", buf, "\n", NULL);
fd = __open (buf, O_RDONLY);
if (this_dir->machdirstatus == unknown)
@ -926,7 +964,7 @@ open_path (const char *name, size_t namelen, int preloaded,
/* Print name we try if this is wanted. */
if (_dl_debug_libs)
_dl_debug_message ("\t trying file=", buf, "\n", NULL);
_dl_debug_message (1, " trying file=", buf, "\n", NULL);
fd = __open (buf, O_RDONLY);
if (this_dir->dirstatus == unknown)
@ -1038,6 +1076,12 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
return l;
}
/* Display information if we are debugging. */
if (_dl_debug_files && loader != NULL)
_dl_debug_message (1, "\nfile=", name, "; needed by ",
loader->l_name[0] ? loader->l_name : _dl_argv[0],
"\n", NULL);
if (strchr (name, '/') == NULL)
{
/* Search for NAME in several places. */
@ -1045,7 +1089,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
size_t namelen = strlen (name) + 1;
if (_dl_debug_libs)
_dl_debug_message ("\tfind library=", name, "; searching\n", NULL);
_dl_debug_message (1, "find library=", name, "; searching\n", NULL);
fd = -1;
@ -1109,7 +1153,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
/* Add another newline when we a tracing the library loading. */
if (_dl_debug_libs)
_dl_debug_message ("\n", NULL);
_dl_debug_message (1, "\n", NULL);
}
else
{

View File

@ -100,7 +100,7 @@ do_lookup (const char *undef_name, unsigned long int hash,
/* Print some debugging info if wanted. */
if (_dl_debug_symbols)
_dl_debug_message ("\tsymbol=", undef_name, "; lookup in file=",
_dl_debug_message (1, "symbol=", undef_name, "; lookup in file=",
map->l_name[0] ? map->l_name : _dl_argv[0],
"\n", NULL);
@ -236,7 +236,7 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
}
if (_dl_debug_bindings)
_dl_debug_message ("\tbinding file ", reference_name, " to ",
_dl_debug_message (1, "binding file ", reference_name, " to ",
current_value.m->l_name[0]
? current_value.m->l_name : _dl_argv[0],
": symbol `", undef_name, "'\n", NULL);
@ -281,7 +281,7 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
}
if (_dl_debug_bindings)
_dl_debug_message ("\tbinding file ", reference_name, " to ",
_dl_debug_message (1, "binding file ", reference_name, " to ",
current_value.m->l_name[0]
? current_value.m->l_name : _dl_argv[0],
": symbol `", undef_name, "'\n", NULL);
@ -342,7 +342,7 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
}
if (_dl_debug_bindings)
_dl_debug_message ("\tbinding file ", reference_name, " to ",
_dl_debug_message (1, "binding file ", reference_name, " to ",
current_value.m->l_name[0]
? current_value.m->l_name : _dl_argv[0],
": symbol `", undef_name, "' [", version->name,
@ -396,7 +396,7 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
}
if (_dl_debug_bindings)
_dl_debug_message ("\tbinding file ", reference_name, " to ",
_dl_debug_message (1, "binding file ", reference_name, " to ",
current_value.m->l_name[0]
? current_value.m->l_name : _dl_argv[0],
": symbol `", undef_name, "' [", version->name,

View File

@ -22,8 +22,10 @@
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <stdio-common/_itoa.h>
#ifndef MAP_ANON
/* This is the only dl-sysdep.c function that is actually needed at run-time
@ -89,6 +91,54 @@ _dl_sysdep_output (int fd, const char *msg, ...)
size_t len = strlen (msg);
__write (fd, msg, len);
msg = va_arg (ap, const char *);
} while (msg);
}
while (msg != NULL);
va_end (ap);
}
void
_dl_debug_message (int new_line, const char *msg, ...)
{
/* We print the strings we get passed one after the other but start all
lines using the current PID. */
static int pid;
va_list ap;
if (pid == 0)
pid = getpid ();
va_start (ap, msg);
do
if (msg[0] == '\0')
/* Get the next argument. */
msg = va_arg (ap, const char *);
else
{
const char *endp;
/* We actually will print something in this line. So print the
PID now if needed. */
if (new_line)
{
char buf[7] = "00000:\t";
__write (_dl_debug_fd, _itoa_word (pid, &buf[5], 10, 0), 7);
new_line = 0;
}
endp = strchr (msg, '\n');
if (endp == NULL)
{
__write (_dl_debug_fd, msg, strlen (msg));
msg = va_arg (ap, const char *);
}
else
{
__write (_dl_debug_fd, msg, endp - msg + 1);
msg = endp + 1;
new_line = 1;
}
}
while (msg != NULL);
va_end (ap);
}

View File

@ -32,6 +32,10 @@ _dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy)
if (l->l_relocated)
return;
if (_dl_debug_reloc)
_dl_debug_message (1, "\nrelocation processing: ",
l->l_name[0] ? l->l_name : _dl_argv[0], "\n", NULL);
if (l->l_info[DT_TEXTREL])
{
/* Bletch. We must make read-only segments writable

View File

@ -39,6 +39,9 @@ int _dl_debug_libs;
int _dl_debug_impcalls;
int _dl_debug_bindings;
int _dl_debug_symbols;
int _dl_debug_versions;
int _dl_debug_reloc;
int _dl_debug_files;
/* If nonzero print warnings about problematic situations. */
int _dl_verbose;

View File

@ -79,6 +79,12 @@ match_symbol (const char *name, ElfW(Word) hash, const char *string,
ElfW(Addr) def_offset;
ElfW(Verdef) *def;
/* Display information about what we are doing while debugging. */
if (_dl_debug_versions)
_dl_debug_message (1, "checking for version `", string, "' in file ",
map->l_name[0] ? map->l_name : _dl_argv[0],
" required by file ", name, "\n", NULL);
if (map->l_info[VERSTAG (DT_VERDEF)] == NULL)
{
/* The file has no symbol versioning. I.e., the dependent

View File

@ -253,6 +253,9 @@ extern int _dl_debug_libs;
extern int _dl_debug_impcalls;
extern int _dl_debug_bindings;
extern int _dl_debug_symbols;
extern int _dl_debug_versions;
extern int _dl_debug_reloc;
extern int _dl_debug_files;
/* File deccriptor to write debug messages to. */
extern int _dl_debug_fd;
@ -267,9 +270,10 @@ extern void _dl_sysdep_output (int fd, const char *string, ...);
/* OS-dependent function to write a debug message on the specified
descriptor for this. All arguments are `const char *'; args until
a null pointer are concatenated to form the message to print. */
#define _dl_debug_message(string, args...) \
_dl_sysdep_output (_dl_debug_fd, string, ##args)
a null pointer are concatenated to form the message to print. If
NEW_LINE is nonzero it is assumed that the message starts on a new
line.*/
extern void _dl_debug_message (int new_line, const char *string, ...);
/* OS-dependent function to write a message on the standard output.
All arguments are `const char *'; args until a null pointer

View File

@ -78,6 +78,9 @@ int _dl_debug_libs;
int _dl_debug_impcalls;
int _dl_debug_bindings;
int _dl_debug_symbols;
int _dl_debug_versions;
int _dl_debug_reloc;
int _dl_debug_files;
/* Set nonzero during loading and initialization of executable and
libraries, cleared before the executable's entry point runs. This
@ -927,7 +930,15 @@ process_dl_debug (char *dl_debug)
++dl_debug;
if (*dl_debug != '\0')
{
if (strncmp (dl_debug, "bindings", 8) == 0
if (strncmp (dl_debug, "files", 5) == 0
&& (issep (dl_debug[5]) || dl_debug[5] == '\0'))
{
_dl_debug_files = 1;
_dl_debug_impcalls = 1;
any_debug = 1;
dl_debug += 5;
}
else if (strncmp (dl_debug, "bindings", 8) == 0
&& (issep (dl_debug[8]) || dl_debug[8] == '\0'))
{
_dl_debug_bindings = 1;
@ -935,6 +946,25 @@ process_dl_debug (char *dl_debug)
any_debug = 1;
dl_debug += 8;
}
else if (strncmp (dl_debug, "help", 4) == 0
&& (issep (dl_debug[4]) || dl_debug[4] == '\0'))
{
_dl_sysdep_message ("\
Valid options for the LD_DEBUG environment variable are:\n\
\n\
bindings display information about symbol binding\n\
files display processing of files and libraries\n\
help display this help message and exit\n\
libs display library search paths\n\
reloc display relocation processing\n\
symbols display symbol table processing\n\
versions display version dependencies\n\
\n\
To direct the debugging output into a file instead of standard output\n\
a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n",
NULL);
_exit (0);
}
else if (strncmp (dl_debug, "libs", 4) == 0
&& (issep (dl_debug[4]) || dl_debug[4] == '\0'))
{
@ -943,21 +973,13 @@ process_dl_debug (char *dl_debug)
any_debug = 1;
dl_debug += 4;
}
else if (strncmp (dl_debug, "help", 4) == 0
&& (issep (dl_debug[4]) || dl_debug[4] == '\0'))
else if (strncmp (dl_debug, "reloc", 4) == 0
&& (issep (dl_debug[5]) || dl_debug[5] == '\0'))
{
_dl_sysdep_message ("\
Valid options for the LD_DEBUG environment variable are:\n\
\n\
bindings display information about symbol binding\n\
help display this help message and exit\n\
libs display library search paths\n\
symbols display symbol table processing\n\
\n\
To direct the debugging output into a file instead of standard output\n\
a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n",
NULL);
_exit (0);
_dl_debug_reloc = 1;
_dl_debug_impcalls = 1;
any_debug = 1;
dl_debug += 5;
}
else if (strncmp (dl_debug, "symbols", 7) == 0
&& (issep (dl_debug[7]) || dl_debug[7] == '\0'))
@ -967,6 +989,14 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n",
any_debug = 1;
dl_debug += 7;
}
else if (strncmp (dl_debug, "versions", 8) == 0
&& (issep (dl_debug[8]) || dl_debug[8] == '\0'))
{
_dl_debug_versions = 1;
_dl_debug_impcalls = 1;
any_debug = 1;
dl_debug += 8;
}
else
{
/* Display a warning and skip everything until next

View File

@ -99,6 +99,7 @@ GLIBC_2.0 {
_rpc_dtablesize; _null_auth; _seterr_reply;
__res_randomid; __getpid;
__strcasecmp; __write; _strerror_internal; _dl_sysdep_output;
_dl_debug_message;
__ffs;
# Exception handling support functions from libgcc

View File

@ -89,8 +89,19 @@ struct test_case_struct
static int testit (struct test_case_struct *tc);
void
command_line_test (const char *words)
{
wordexp_t we;
int i;
int retval = wordexp (words, &we, 0);
printf ("wordexp returned %d\n", retval);
for (i = 0; i < we.we_wordc; i++)
printf ("we_wordv[%d] = \"%s\"\n", i, we.we_wordv[i]);
}
int
main (int argc, char * argv[])
main (int argc, char *argv[])
{
struct passwd *pw;
int test;
@ -101,6 +112,12 @@ main (int argc, char * argv[])
if (testit (&test_case[test]))
++fail;
if (argc > 1)
{
command_line_test (argv[1]);
return 0;
}
pw = getpwnam ("root");
if (pw != NULL)
{

View File

@ -50,14 +50,14 @@ __libc_start_main (int (*main) (int, char **, char **), int argc,
/* Call the initializer of the libc. */
#ifdef PIC
if (_dl_debug_impcalls)
_dl_debug_message ("\tinitialize libc\n\n", NULL);
_dl_debug_message (1, "\ninitialize libc\n\n", NULL);
#endif
__libc_init_first (argc, argv, __environ);
/* Call the initializer of the program. */
#ifdef PIC
if (_dl_debug_impcalls)
_dl_debug_message ("\tinitialize program: ", argv[0], "\n\n", NULL);
_dl_debug_message (1, "\ninitialize program: ", argv[0], "\n\n", NULL);
#endif
(*init) ();
@ -66,7 +66,7 @@ __libc_start_main (int (*main) (int, char **, char **), int argc,
#ifdef PIC
if (_dl_debug_impcalls)
_dl_debug_message ("\ttransferring control: ", argv[0], "\n\n", NULL);
_dl_debug_message (1, "\ntransferring control: ", argv[0], "\n\n", NULL);
#endif
exit ((*main) (argc, argv, __environ));

View File

@ -1,3 +1,161 @@
/* The kernel header file contains all declarations and definitions. */
/* This just represents the non-kernel parts of <linux/quota.h>.
*
* here's the corresponding copyright:
* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Robert Elz at The University of Melbourne.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Version: $Id$
*/
#ifndef _SYS_QUOTA_H
#define _SYS_QUOTA_H 1
#include <features.h>
#include <sys/types.h>
#include <linux/quota.h>
/*
* Convert diskblocks to blocks and the other way around.
* currently only to fool the BSD source. :-)
*/
#define dbtob(num) ((num) << 10)
#define btodb(num) ((num) >> 10)
/*
* Convert count of filesystem blocks to diskquota blocks, meant
* for filesystems where i_blksize != BLOCK_SIZE
*/
#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / BLOCK_SIZE)
/*
* Definitions for disk quotas imposed on the average user
* (big brother finally hits Linux).
*
* The following constants define the amount of time given a user
* before the soft limits are treated as hard limits (usually resulting
* in an allocation failure). The timer is started when the user crosses
* their soft limit, it is reset when they go below their soft limit.
*/
#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */
#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */
#define MAXQUOTAS 2
#define USRQUOTA 0 /* element used for user quotas */
#define GRPQUOTA 1 /* element used for group quotas */
/*
* Definitions for the default names of the quotas files.
*/
#define INITQFNAMES { \
"user", /* USRQUOTA */ \
"group", /* GRPQUOTA */ \
"undefined", \
};
#define QUOTAFILENAME "quota"
#define QUOTAGROUP "staff"
#define NR_DQHASH 43 /* Just an arbitrary number any suggestions ? */
#define NR_DQUOTS 256 /* Number of quotas active at one time */
/*
* Command definitions for the 'quotactl' system call.
* The commands are broken into a main command defined below
* and a subcommand that is used to convey the type of
* quota that is being manipulated (see above).
*/
#define SUBCMDMASK 0x00ff
#define SUBCMDSHIFT 8
#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
#define Q_QUOTAON 0x0100 /* enable quotas */
#define Q_QUOTAOFF 0x0200 /* disable quotas */
#define Q_GETQUOTA 0x0300 /* get limits and usage */
#define Q_SETQUOTA 0x0400 /* set limits and usage */
#define Q_SETUSE 0x0500 /* set usage */
#define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */
#define Q_SETQLIM 0x0700 /* set limits */
#define Q_GETSTATS 0x0800 /* get collected stats */
/*
* The following structure defines the format of the disk quota file
* (as it appears on disk) - the file is an array of these structures
* indexed by user or group number.
*/
struct dqblk
{
u_int32_t dqb_bhardlimit; /* absolute limit on disk blks alloc */
u_int32_t dqb_bsoftlimit; /* preferred limit on disk blks */
u_int32_t dqb_curblocks; /* current block count */
u_int32_t dqb_ihardlimit; /* maximum # allocated inodes */
u_int32_t dqb_isoftlimit; /* preferred inode limit */
u_int32_t dqb_curinodes; /* current # allocated inodes */
time_t dqb_btime; /* time limit for excessive disk use */
time_t dqb_itime; /* time limit for excessive files */
};
/*
* Shorthand notation.
*/
#define dq_bhardlimit dq_dqb.dqb_bhardlimit
#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit
#define dq_curblocks dq_dqb.dqb_curblocks
#define dq_ihardlimit dq_dqb.dqb_ihardlimit
#define dq_isoftlimit dq_dqb.dqb_isoftlimit
#define dq_curinodes dq_dqb.dqb_curinodes
#define dq_btime dq_dqb.dqb_btime
#define dq_itime dq_dqb.dqb_itime
#define dqoff(UID) ((loff_t)((UID) * sizeof (struct dqblk)))
struct dqstats
{
u_int32_t lookups;
u_int32_t drops;
u_int32_t reads;
u_int32_t writes;
u_int32_t cache_hits;
u_int32_t pages_allocated;
u_int32_t allocated_dquots;
u_int32_t free_dquots;
u_int32_t syncs;
};
__BEGIN_DECLS
extern int quotactl __P ((int __cmd, const char *__special, int __id,
caddr_t __addr));
__END_DECLS
#endif /* sys/quota.h */