_IOWR when errno != 0

Xin LI delphij at delphij.net
Tue Apr 13 19:01:28 UTC 2010


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2010/04/13 05:53, John Baldwin wrote:
> On Monday 12 April 2010 8:26:48 pm Xin LI wrote:
>> On 2010/04/12 16:33, Alfred Perlstein wrote:
>>> * Xin LI <delphij at delphij.net> [100412 15:28] wrote:
>>>> -----BEGIN PGP SIGNED MESSAGE-----
>>>> Hash: SHA1
>>>>
>>>> Hi,
>>>>
>>>> Is there a sane way to copyout ioctl request when the returning errno !=
>>>> 0?  Looking at the code, currently, in sys/kern/sys_generic.c, we have:
>>>>
>>>> ===========
>>>>         error = kern_ioctl(td, uap->fd, com, data);
>>>>
>>>>         if (error == 0 && (com & IOC_OUT))
>>>>                 error = copyout(data, uap->data, (u_int)size);
>>>> ===========
>>>>
>>>> Is there any objection if I change it to something like:
>>>>
>>>> ===========
>>>>         saved_error = kern_ioctl(td, uap->fd, com, data);
>>>>
>>>>         if (com & IOC_OUT)
>>>>                 error = copyout(data, uap->data, (u_int)size);
>>>>         if (saved_error)
>>>>                 error = saved_error;
>>>> ===========
>>>
>>> Is this for linux compat?
>>
>> Do they do this way?  I'm not quite sure :-/
>>
>> I got a bug report and am thinking about how to fix it, it seems that we
>> do not have a generic way of returning an error number while giving some
>> "hints" about the error at the same time, for the ioctl() call.  Adding
>> an extra pointer to the request structure seems to be a last-resort way
>> and sounds to be ugly.
> 
> Actually, this pattern of embedding an error is quite common.  The mfi(4) and 
> mpt(4) pass-thru ioctls to send firmware commands embed the return status of 
> any firmware command in the structure that is passed in and out for example.
> 
>>> I'm not sure this would work, it might seriously break userland
>>> compat.  Have you looked around/queiried what the expected outcome
>>> is from a bad ioctl?  By default the buffer will be zero'd this
>>> might be unexpected by apps.  (all or nothing)
>>
>> Yes that's exactly why I'm asking, my understanding is that for normal
>> usages would be something like:
>>
>> 	if (ioctl(fd, SIOCSOMETHING, &req) < 0) {
>> 		// do something to handle the error
>> 	} else {
>> 		// use data fed back from req
>> 	}
>>
>> In this case, I think the result would not be affected.  Is there many
>> (if any) programs that don't bother to check return value of ioctl()?
>>
>> Speaking for the userland buffer, for _IOR ioctls, the side effect would
>> be that userland would see a zeroed out 'req' structure (kernel buffer
>> gets zeroed out before calling kern_ioctl), or "half-baked" one (the
>> kernel code may have only written partial data).  For _IOWR ioctls, the
>> side effect would be that the userland may get half-baked data.
> 
> You miss one important variation where the error handling involves adjusting 
> the request and retrying (or submitting the same request to a different ioctl 
> to handle renumbering conflicts, etc.).  Other APIs such as sysctl(2) and 
> setsockopt(2) can leave partial data, but the callers of those APIs expect 
> that (and in fact, those APIs return the actual length of data that is copied 
> out).  ioctl(2) has not had that behavior, however, and I would find it 
> surprising.

I see, that's what I am concerned about, thanks for the explanation.

In order to maintain ABI compatibility I now have a patch which changs
the current behavior of SIOCGIFDESCR to set the buffer field to NULL and
return no errno.  The existing code in -HEAD doesn't seem to work when
the field is big :(

I will post the patch to -net@ for review once I get it tested.

Cheers,
- -- 
Xin LI <delphij at delphij.net>	http://www.delphij.net/
FreeBSD - The Power to Serve!	       Live free or die
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (FreeBSD)

iQEcBAEBAgAGBQJLxL96AAoJEATO+BI/yjfBkkMIAIVjUmwrfHLl5F+mIlRD+Zpv
hYZVBZaeu3/ymv0Zepo5vhbvJCOWxgdtRnJgoVlkpglZLwVrKkAdfxWp/di5n8xm
O4BMc+BIra6tYnqaxmbCYoigKGoLVhim1n6j2Xld/h0n91ErBDpdrWBdHVbs8uV+
mRFLCPbGzGnEXw68rdbWjXFIDRIe7btTdmyYotaHd5AFaqQw6EM+OAXRG3UqGtm3
92o+9TW2LcTTP9gyresbQGoXvITHXVfSdihhDVfDMCtbaClQ+IFlny0oGqg0DttR
OhnEWDvBgUQD+aADYx2k8YLXziUsQzvTc7WTZuoxdz3LzZVecyQSewiydEhor/U=
=IHjf
-----END PGP SIGNATURE-----


More information about the freebsd-arch mailing list