cvs commit: patches/sysklogd sysklogd-1.4.1-querymod.patch

tushar at linuxfromscratch.org tushar at linuxfromscratch.org
Sun Oct 5 13:11:48 PDT 2003


tushar      03/10/05 14:11:48

  Added:       sysklogd sysklogd-1.4.1-querymod.patch
  Log:
  Added sysklogd-1.4.1-querymod.patch
  
  Revision  Changes    Path
  1.1                  patches/sysklogd/sysklogd-1.4.1-querymod.patch
  
  Index: sysklogd-1.4.1-querymod.patch
  ===================================================================
  Submitted By: Kelledin <kelledin at users.sourceforge.net>
  Date: 2003-10-05
  Initial Package Version: 1.4.1
  Origin: Kelledin <kelledin at users.sourceforge.net>
  Description: klogd (from sysklogd-1.4.1) uses an antiquated method of tracing
               tracing module symbols by seeking through /dev/kmem.  Not only is
               this obsolete, it incurs a possible race condition and often does
               not work on 64-bit platforms.  This patch updates klogd to use
               the newer, safer query_module() function.
  
  
  diff -Naur sysklogd-1.4.1/ksym_mod.c sysklogd-1.4.1-querymodules/ksym_mod.c
  --- sysklogd-1.4.1/ksym_mod.c	2000-09-12 16:15:28.000000000 -0500
  +++ sysklogd-1.4.1-querymodules/ksym_mod.c	2003-10-03 23:18:05.000000000 -0500
  @@ -122,6 +122,8 @@
   #define getsyms get_kernel_syms
   #endif /* __GLIBC__ */
   
  +extern int query_module(const char *, int, void *, size_t, size_t *);
  +
   /* Variables static to this module. */
   struct sym_table
   {
  @@ -142,7 +144,7 @@
   };
   
   static int num_modules = 0;
  -struct Module *sym_array_modules = (struct Module *) 0;
  +struct Module *sym_array_modules = NULL;
   
   static int have_modules = 0;
   
  @@ -155,8 +157,8 @@
   
   /* Function prototypes. */
   static void FreeModules(void);
  -static int AddSymbol(struct Module *mp, unsigned long, char *);
  -static int AddModule(unsigned long, char *);
  +static int AddSymbol(struct Module *mp, unsigned long, const char *);
  +static int AddModule(char *);
   static int symsort(const void *, const void *);
   
   
  @@ -179,81 +181,107 @@
   extern int InitMsyms()
   
   {
  -	auto int	rtn,
  -			tmp;
  +	auto size_t	rtn;
  +	auto int	tmp;
  +
  +	auto char	**mod_table,
  +			**p;
  +
  +	char			*modbuf = NULL,
  +				*newbuf;
   
  -	auto struct kernel_sym	*ksym_table,
  -				*p;
  +	int			 modsize = 32,
  +				 result;
   
   
   	/* Initialize the kernel module symbol table. */
   	FreeModules();
   
  +	/*
  +	 * New style symbol table parser.  This uses the newer query_module
  +	 * function rather than the old obsolete hack of stepping thru
  +	 * /dev/kmem.
  +	 */
   
   	/*
  -	 * The system call which returns the kernel symbol table has
  -	 * essentialy two modes of operation.  Called with a null pointer
  -	 * the system call returns the number of symbols defined in the
  -	 * the table.
  -	 *
  -	 * The second mode of operation is to pass a valid pointer to
  -	 * the call which will then load the current symbol table into
  -	 * the memory provided.
  -	 *
  -	 * Returning the symbol table is essentially an all or nothing
  -	 * proposition so we need to pre-allocate enough memory for the
  -	 * complete table regardless of how many symbols we need.
  -	 *
  -	 * Bummer.
  +	 * First, we query for the list of loaded modules.  We may
  +	 * have to grow our buffer in size.
   	 */
  -	if ( (rtn = getsyms((struct kernel_sym *) 0)) < 0 )
  -	{
  -		if ( errno == ENOSYS )
  -			Syslog(LOG_INFO, "No module symbols loaded - "
  -			       "kernel modules not enabled.\n");
  -		else
  +	do {
  +		modsize+=modsize;
  +		newbuf=realloc(modbuf, modsize);
  +
  +		if (newbuf==NULL) {
  +			/* Well, that sucks. */
   			Syslog(LOG_ERR, "Error loading kernel symbols " \
   			       "- %s\n", strerror(errno));
  +			if (modbuf!=NULL) free(modbuf);
  +			return(0);
  +		}
  +
  +		modbuf=newbuf;
  +
  +		result=query_module(NULL, QM_MODULES, modbuf, modsize, &rtn);
  +
  +		if (result<0 && errno!=ENOSPC) {
  +			Syslog(LOG_ERR, "Error querying loaded modules " \
  +			       "- %s\n", strerror(errno));
  +			free(modbuf);
  +			return(0);
  +		}
  +	} while (result<0);
  +
  +	if ( rtn <= 0 ) {
  +		/* No modules??? */
  +		Syslog(LOG_INFO, "No module symbols loaded - "
  +		       "modules disabled?\n");
  +		free(modbuf);
   		return(0);
   	}
   	if ( debugging )
   		fprintf(stderr, "Loading kernel module symbols - "
   			"Size of table: %d\n", rtn);
   
  -	ksym_table = (struct kernel_sym *) malloc(rtn * \
  -						  sizeof(struct kernel_sym));
  -	if ( ksym_table == (struct kernel_sym *) 0 )
  +	mod_table = (char **) malloc(rtn * sizeof(char *));
  +	if ( mod_table == NULL )
   	{
   		Syslog(LOG_WARNING, " Failed memory allocation for kernel " \
   		       "symbol table.\n");
  +		free(modbuf);
   		return(0);
   	}
  -	if ( (rtn = getsyms(ksym_table)) < 0 )
  +
  +	sym_array_modules = (struct Module *) malloc(rtn * sizeof(struct Module));
  +	if ( sym_array_modules == NULL )
   	{
  -		Syslog(LOG_WARNING, "Error reading kernel symbols - %s\n", \
  -		       strerror(errno));
  +		Syslog(LOG_WARNING, " Failed memory allocation for kernel " \
  +		       "symbol table.\n");
  +		free(mod_table);
  +		free(modbuf);
   		return(0);
   	}
   
  -
   	/*
   	 * Build a symbol table compatible with the other one used by
   	 * klogd.
   	 */
  -	tmp = rtn;
  -	p = ksym_table;
  -	while ( tmp-- )
  +	newbuf=modbuf;
  +	for (tmp=rtn-1; tmp>=0; tmp--)
   	{
  - 		if ( !AddModule(p->value, p->name) )
  +		mod_table[tmp]=newbuf;
  +		newbuf+=(strlen(newbuf)+1);
  + 		if ( !AddModule(mod_table[tmp]) )
   		{
   			Syslog(LOG_WARNING, "Error adding kernel module table "
   				"entry.\n");
  -			free(ksym_table);
  +			free(mod_table);
  +			free(modbuf);
   			return(0);
   		}
  -		++p;
   	}
   
  +	have_modules = 1;
  +
   	/* Sort the symbol tables in each module. */
   	for (rtn = tmp= 0; tmp < num_modules; ++tmp)
   	{
  @@ -271,7 +299,8 @@
   		Syslog(LOG_INFO, "Loaded %d %s from %d module%s", rtn, \
   		       (rtn == 1) ? "symbol" : "symbols", \
   		       num_modules, (num_modules == 1) ? "." : "s.");
  -	free(ksym_table);
  +	free(mod_table);
  +	free(modbuf);
   	return(1);
   }
   
  @@ -316,23 +345,23 @@
   
   	/* Check to see if the module symbol tables need to be cleared. */
   	have_modules = 0;
  -	if ( num_modules == 0 )
  -		return;
  -
   
  -	for (nmods= 0; nmods < num_modules; ++nmods)
  -	{
  -		mp = &sym_array_modules[nmods];
  -		if ( mp->num_syms == 0 )
  -			continue;
  +	if (sym_array_modules != NULL) {
  +		for (nmods= 0; nmods < num_modules; ++nmods)
  +		{
  +			mp = &sym_array_modules[nmods];
  +			if ( mp->num_syms == 0 )
  +				continue;
   	       
  -		for (nsyms= 0; nsyms < mp->num_syms; ++nsyms)
  -			free(mp->sym_array[nsyms].name);
  -		free(mp->sym_array);
  +			for (nsyms= 0; nsyms < mp->num_syms; ++nsyms)
  +				free(mp->sym_array[nsyms].name);
  +			free(mp->sym_array);
  +		}
  +
  +		free(sym_array_modules);
  +		sym_array_modules = NULL;
   	}
   
  -	free(sym_array_modules);
  -	sym_array_modules = (struct Module *) 0;
   	num_modules = 0;
   	return;
   }
  @@ -344,23 +373,25 @@
    * Purpose:	This function is responsible for adding a module to
    *		the list of currently loaded modules.
    *
  - * Arguements:	(unsigned long) address, (char *) symbol
  - *
  - *		address:->	The address of the module.
  + * Arguements:	(char *) symbol
    *
    *		symbol:->	The name of the module.
    *
    * Return:	int
    **************************************************************************/
   
  -static int AddModule(address, symbol)
  -
  -     unsigned long address;
  +static int AddModule(symbol)
   
        char *symbol;
   
   {
  -	auto int memfd;
  +	size_t rtn;
  +	size_t i;
  +	const char *cbuf;
  +	int symsize=128;
  +	int result;
  +	struct module_symbol *symbuf=NULL,
  +			     *newbuf;
   
   	auto struct Module *mp;
   
  @@ -368,78 +399,75 @@
   	/* Return if we have loaded the modules. */
   	if ( have_modules )
   		return(1);
  +	
  +	/* We already have space for the module. */
  +	mp = &sym_array_modules[num_modules];
  +
  +	if (query_module(symbol, QM_INFO, &sym_array_modules[num_modules].module,
  +			 sizeof(struct module), &rtn)<0)
  +	{
  +		Syslog(LOG_WARNING, "Error reading module info for %s.\n",
  +		       symbol);
  +		return(0);
  +	}
  +
  +	/* Save the module name. */
  +	mp->name = strdup(symbol);
  +	if ( mp->name == NULL )
  +		return(0);
  +
  +	mp->num_syms = 0;
  +	mp->sym_array = NULL;
  +	++num_modules;
   
   	/*
  -	 * The following section of code is responsible for determining
  -	 * whether or not we are done reading the list of modules.
  +	 * First, we query for the list of exported symbols.  We may
  +	 * have to grow our buffer in size.
   	 */
  -	if ( symbol[0] == '#' )
  -	{
  +	do {
  +		symsize+=symsize;
  +		newbuf=realloc(symbuf, symsize);
   
  -		if ( symbol[1] == '\0' )
  -		{
  -			/*
  -			 * A symbol which consists of a # sign only
  -			 * signifies a a resident kernel segment.  When we
  -			 * hit one of these we are done reading the
  -			 * module list.
  -			 */
  -			have_modules = 1;
  -			return(1);
  -		}
  -		/* Allocate space for the module. */
  -		sym_array_modules = (struct Module *) \
  -			realloc(sym_array_modules, \
  -				(num_modules+1) * sizeof(struct Module));
  -		if ( sym_array_modules == (struct Module *) 0 )
  -		{
  -			Syslog(LOG_WARNING, "Cannot allocate Module array.\n");
  +		if (newbuf==NULL) {
  +			/* Well, that sucks. */
  +			Syslog(LOG_ERR, "Error loading kernel symbols " \
  +			       "- %s\n", strerror(errno));
  +			if (symbuf!=NULL) free(symbuf);
   			return(0);
   		}
  -		mp = &sym_array_modules[num_modules];
   
  -		if ( (memfd = open("/dev/kmem", O_RDONLY)) < 0 )
  -		{
  -			Syslog(LOG_WARNING, "Error opening /dev/kmem\n");
  -			return(0);
  -		}
  -		if ( lseek64(memfd, address, SEEK_SET) < 0 )
  -		{
  -			Syslog(LOG_WARNING, "Error seeking in /dev/kmem\n");
  -			Syslog(LOG_WARNING, "Symbol %s, value %08x\n", symbol, address);
  -			return(0);
  -		}
  -		if ( read(memfd, \
  -			  (char *)&sym_array_modules[num_modules].module,  \
  -			  sizeof(struct module)) < 0 )
  -		{
  -			Syslog(LOG_WARNING, "Error reading module "
  -			       "descriptor.\n");
  -			return(0);
  -		}
  -		close(memfd);
  +		symbuf=newbuf;
  +
  +		result=query_module(symbol, QM_SYMBOLS, symbuf, symsize, &rtn);
   
  -		/* Save the module name. */
  -		mp->name = (char *) malloc(strlen(&symbol[1]) + 1);
  -		if ( mp->name == (char *) 0 )
  +		if (result<0 && errno!=ENOSPC) {
  +			Syslog(LOG_ERR, "Error querying symbol list for %s " \
  +			       "- %s\n", symbol, strerror(errno));
  +			free(symbuf);
   			return(0);
  -		strcpy(mp->name, &symbol[1]);
  +		}
  +	} while (result<0);
   
  -		mp->num_syms = 0;
  -		mp->sym_array = (struct sym_table *) 0;
  -		++num_modules;
  -		return(1);
  -	}
  -	else
  -	{
  -	    if (num_modules > 0)
  -		mp = &sym_array_modules[num_modules - 1];
  -	    else
  -		mp = &sym_array_modules[0];
  -		AddSymbol(mp, address, symbol);
  +	if ( rtn < 0 ) {
  +		/* No symbols??? */
  +		Syslog(LOG_INFO, "No module symbols loaded - unknown error.\n");
  +		free(symbuf);
  +		return(0);
   	}
   
  +	cbuf=(char *)symbuf;
  +
  +	for (i=0; i<rtn; i++) {
  +		if (num_modules > 0)
  +			mp = &sym_array_modules[num_modules - 1];
  +		else
  +			mp = &sym_array_modules[0];
  +
  +		AddSymbol(mp, symbuf[i].value,
  +			  cbuf+(unsigned long)(symbuf[i].name));
  +	}
   
  +	free(symbuf);
   	return(1);
   }
   
  @@ -471,7 +499,7 @@
   
   	unsigned long address;
   	
  -	char *symbol;
  +	const char *symbol;
   	
   {
   	auto int tmp;
  
  
  



More information about the patches mailing list