[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MiNT] patch:MiNT:KM_FREE



On Sun, 2009-12-13 at 16:57 +0000, Helmut Karlowski wrote:
> Hello
> 
> I've added the possibility to free a kernel-module to MiNT. Drawback is
> that the caller only has path/name it passed to identify the module, and
> MiNT may use another spelling for it. It would be better to have a unique
> id to pass to the kernel for KM_FREE.

Helmut,

Would you be willing to add unique identification to module loading
rather than use a filename ?

Then I'd be happy to commit. I think using filenames may not be robust
enough.

Alan.

> A kernel-module may only be loaded once
> 
> 
> ---------------------------------------------------------
> add the possibility to free a kernel-module.
> ---------------------------------------------------------
> 
> 
> 
> --- orig/module.c	2009-04-26 12:59:27.406250000 +0200
> +++ module.c	2009-12-13 17:53:32.718750000 +0100
> @@ -725,6 +725,7 @@
>  //		sys_c_conin();
>  // 		run = (long _cdecl(*)(struct kentry *, const char *))km->b->p_tbase;
>  		run = (long _cdecl(*)(struct kentry *, const struct kernel_module *))km->b->p_tbase;
> +		km->caller = curproc;
>  		err = (*run)(&kentry, km); //km->path);
>  	}
>  	else
> @@ -808,20 +809,73 @@
>  module_ioctl(FILEPTR *f, int mode, void *buf)
>  {
>  	long r = ENOSYS;
> +	char *p1, *p2;
> +	struct kernel_module *km;
>  	
>  	DEBUG(("module_ioctl [%i]: (%x, (%c %i), %lx)",
>  		f->fc.aux, mode, (char)(mode >> 8), (mode & 0xff), buf));
> -	
> +
> +	if( !buf )
> +		return EINVAL;
> +
> +	/* only root may */
> +	if( !suser (curproc->p_cred->ucr) )
> +		return EPERM;
> +
> +	/* stored name may have path or not */
> +	p1 = strrchr( buf, '/');
> +	p2 = strrchr( buf, '\\');
> +	if( p2 > p1 )
> +		p1 = p2;
> +	if( !p1 )
> +		p1 = buf;
> +	else
> +		p1++;
> +
>  	switch (mode)
>  	{
>  		case KM_RUN:
>  		{
> -			r = run_km(buf);
> +			/* check if module already loaded */
> +			for( km = loaded_modules; km; km = km->next )
> +			{
> +				DEBUG(("module_ioctl: run_km: looking(%s,%s)", km->name, p1));
> +				if( km->class == MODCLASS_KM && !(strcmp( p1, km->name ) && strcmp( buf, km->name )) )
> +				{
> +					DEBUG(("module_ioctl: module_ioctl:KM_RUN:(%s) already loaded",p1));
> +					r = EACCES;	/* ELOCKED? */
> +					break;
> +				}
> +			}
> +			if( !km )	/* not found -> run */
> +				r = run_km(buf);
> +			break;
> +		}
> +
> +		case KM_FREE:
> +		{
> +			/* check if module loaded */
> +			for( km = loaded_modules; km; km = km->next )
> +			{
> +				DEBUG(("module_ioctl: free_km: looking(%s) cur:%lx caller:%lx", km->name, curproc, km->caller));
> +				if( km->class == MODCLASS_KM && km->caller == curproc && !strcmp( buf, km->name ) )
> +				{
> +					DEBUG(("module_ioctl: free_km(%s)",km->name));
> +					free_km( km );
> +					r = 0;
> +					break;
> +				}
> +				if( !km )
> +				{
> +					r = ENOENT;
> +					DEBUG(("module_ioctl: free_km(%s) not found",buf));
> +				}
> +			}
>  			break;
>  		}
>  	}
>  	
> -	DEBUG (("module_ioctl: return %li", r));
> +	DEBUG (("module_ioctl(%d): return %li", mode&0xff, r));
>  	return r;
>  }
>  
> --- orig/mint/module.h	2009-12-13 11:44:11.218750000 +0100
> +++ mint/module.h	2009-12-13 11:32:36.328125000 +0100
> @@ -57,6 +57,7 @@
>  	struct kernel_module *next;
>  	struct kernel_module *prev;
>  	struct basepage *b;
> +	struct proc *caller;
>  	short class;
>  	short subclass;
>  	unsigned long flags;
> --- orig/mint/ioctl.h	2006-11-14 13:54:20.000000000 +0100
> +++ mint/ioctl.h	2009-11-07 11:03:26.687500000 +0100
> @@ -104,6 +104,7 @@
>   */
>  
>  # define KM_RUN		(('K'<< 8) | 1)		/* 1.16 */
> +# define KM_FREE		(('K'<< 8) | 2)		/* 1.17.1 */
>  
> 
>  /*