Re: Adding own fcntl
Re: Adding own fcntl
- Subject: Re: Adding own fcntl
- From: Jorgen Lundman <email@hidden>
- Date: Mon, 09 May 2016 14:33:13 +0900
Ah ok, so the code in
libsyscall/wrappers/cancelable/fcntl-base.c
has a switch() with a large list of fcntls that are to be handled as "void
*" and everything else is int *.
All the void * entries listed there, is handled in bsd/kern/kern_descrip.c,
and will not reach the default case. So I can't "borrow" an legacy fcntl
for my own purposes.
So it would seem it is not supported to add your own fcntl (non-int) calls.
Lund
Jorgen Lundman wrote:
>
> Dear list,
>
> So, IllumOS OpenZFS has fcntl(F_FREESP), and even though XNU does not have
> it, the testing environment uses it for some of its tests. So I do not need
> it, but thought it would be "amusing" to support it anyway.
>
> I define the standard:
>
> #define F_FREESP_IOC _IOW('Z', 11, struct flock)
> #define F_FREESP IOCBASECMD(F_FREESP)
>
> Where I made up 'Z' and 11 (although, 11 is the value in IllumOS). I use
> _IOW as it should copyin() a struct flock.
>
> The userland program simply calls:
>
> struct flock fl;
> if (fcntl(fd, F_FREESP_IOC, &fl) != 0) {
>
> and in kernel I have the handler for:
>
> case F_FREESP:
>
>
> The end of the giant switch in fcntl_nocancel() bsd/kern/kern_descrip.c
> appears to check for IOC_IN and calls copyin() before passing it to me with
> VNOP_IOCTL().
>
> Except that it doesn't.
>
> I simply get EFAULT from fcntl(), and clearly I am doing something wrong.
>
> dtrace tells me this:
>
>
> * userland:
>
> 24580/0x149320: write_nocancel(0x1, "Address 0x7fff506cfbf0\n\0", 0x17)
> = 23 0
> 24580/0x149320: fcntl(0x3, 0x80185A0B, 0x506CFBF0) = -1 Err#14
>
> (Already truncated here?)
>
> * kernel.
> fcntl_nocancel(proc_t p, struct fcntl_nocancel_args *uap, int32_t *retval)
>
> # dtrace -n 'fcntl_nocancel:entry { printf("%s %p %p %p", execname, arg0,
> arg1, arg2); tracemem(arg1, 100, 100);}'
>
>
>
> 0 191560 fcntl_nocancel:entry randfree_file ffffff8022fcca78
> ffffff801c3d6000 ffffff801c3d6040
> 0 1 2 3 4 5 6 7 8 9 a b c d e f
> 0: 03 00 00 00 00 00 00 00 61 00 00 00 00 00 00 00
> 10: 00 c3 6c 50 ff 7f 00 00 00 70 00 00 00 00 00 00
>
>
> 0 191560 fcntl_nocancel:entry randfree_file ffffff8022fcca78
> ffffff801c3d6000 ffffff801c3d6040
> 0 1 2 3 4 5 6 7 8 9 a b c d e f
> 0: 03 00 00 00 00 00 00 00 0b 5a 18 80 00 00 00 00
> 10: f0 fb 6c 50 00 00 00 00 01 00 00 00 00 00 00 00
>
> So the userland call ends up calling fcntl_nocancel() twice, the first time
> the uap->arg is 0x7fff506cc300 and the second time it has been truncated to
> 32bit, but the correct 32bits, 0x506cfbf0.
>
> The first call is off by 0x38f0 (14576).
>
>
> So maybe something goes wrong with the 32/64 syscall layer, but I am unsure
> how I can fix it. If I use _IO() definition (ie, IOC_VOID) it does call my
> ioctl handler, but the ptr is wrong, and if I call copyin() I get the same
> EFAULT error. It looks like maybe I could do 0x38f0 math on the ptr, but
> that can't be right.. surely..
>
>
> Any insight?
>
> Lund
>
--
Jorgen Lundman | <email@hidden>
Unix Administrator | +81 (0)90-5578-8500 (work)
Shibuya-ku, Tokyo | +81 (0)80-2090-5800 (cell)
Japan | +81 (0)3 -3375-1767 (home)
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Filesystem-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden