Neo wrote:
> I am writing a kernel module to redirect common system calls to my custom 
> syscalls using "sysent" array. It is working fine for 64bit syscalls.

There are some high-level problems with that approach.  The main one is
that the syscall interface is _intentionally_ undocumented.  It can
change arbitrarily at any time without warning, even in a patch.  The
only documented ABI is the one provided by libc and the other system
libraries.

The result of this is that the only way to make something like this
stable enough for common use would be to integrate the source code into
the Solaris kernel.  If you're doing this just for kicks or as an
experiment of sorts, then drive on, but expect possible trouble.  If
you're trying to write software that someone else will have to rely on,
you may want to think again.

(Yes, Sun has historically tried to preserve at least some of the common
syscalls so as to avoid being perversely cruel to third party
applications camping out in this area, but it's certainly the case that
new calls have sprung up and disappeared overnight without warning.
When I worked there, a fair number of folks felt that syscall changes
didn't necessarily even warrant architectural review.  Be careful here!)

> Now, I am going to write the same for 32bit syscalls.
> My problem is I can't redirect/trace 32bit sys calls in my module.

Tracing is probably better done with dtrace, though it may be tough
given where these pointers are installed.

>   old_call=(int (*)())sysent[SYS_mkdir].sy_call;
>   old_call_c=(int64_t (*)())sysent[SYS_mkdir].sy_callc;
> 
>   #ifdef _SYSCALL32_IMPL
>   old_call=(int (*)())sysent32[SYS_mkdir].sy_call;
>   old_call_c=(int64_t (*)())sysent32[SYS_mkdir].sy_callc;
>   #endif

That overwrites (and loses) the pointer assigned to "old_call_c" from
the sysent[] array.  Are you sure you don't want to define an
"old_call_32_c" variable?

You might also want to look more closely at the way 'struct sysent' is
constructed in usr/src/uts/common/os/sysent.c.  That sy_call pointer
likely is not what you think it is.  I'd expect you are (and should be)
getting NULL for "old_call".

>   /* Show in the new one: */
> 
>   sysent[SYS_mkdir].sy_call=(int (*)())new_mkdir;

You shouldn't be assigning anything to sy_call if the original sy_call
entry was NULL.  For the "mkdir" entry, sy_call should be NULL.  Look at
the SYSENT_* macrosm, and SYSENT_CI in particular.

Also, you might want to look at the 'mkdirat' entry as well.  It's
possible that the calls you're missing are coming in through a different
vector.

The dtrace 'syscall' provider might be your friend here.

-- 
James Carlson         42.703N 71.076W         <carls...@workingcode.com>
_______________________________________________
opensolaris-code mailing list
opensolaris-code@opensolaris.org
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to