Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Oct 2012 08:05:17 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Marcin Mazur <willyvmm@gmail.com>
Cc:        freebsd-emulation@freebsd.org
Subject:   Re: TCSBRK implementation for linux compat
Message-ID:  <20121026050517.GM35915@deviant.kiev.zoral.com.ua>
In-Reply-To: <CALK1EdxGdR92hqiVP3wFZJdmzL8iS06Gz2iZtoJcUJVNxNU5GA@mail.gmail.com>
References:  <CALK1EdxGdR92hqiVP3wFZJdmzL8iS06Gz2iZtoJcUJVNxNU5GA@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--0Oyvl1jN+EoPbLMC
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Thu, Oct 25, 2012 at 09:17:39PM +0200, Marcin Mazur wrote:
> Hi.
>=20
> I needed suport for this feature in FreeBSD linux emulation, because I
> have to use precompiled linux library/binary that uses it. There was a
> lot of errors in logs like:
>=20
>=20
> "... ioctl fd=3D52, cmd=3D0x5409 ('T',9) is not implemented"
>=20
> I could not find any help so I had to do that by myself
>=20
> I found implementation in NetBSD sources, and just 'translated' it to
> the FreeBSD
>=20
> There is my work:
>=20
> -------------------------
> --- linux_ioctl.orig    2012-08-06 01:54:33.000000000 +0200
> +++ linux_ioctl.c       2012-10-25 13:59:12.000000000 +0200
> @@ -778,8 +778,26 @@
>                     td));
>                 break;
>=20
> -       /* LINUX_TCSBRK */
> -
> +       case LINUX_TCSBRK:
> +               if (args->arg)
> +                   {
> +                       args->cmd =3D TIOCDRAIN;
> +                       error =3D (sys_ioctl(td, (struct ioctl_args *)arg=
s));
> +                       break;
> +                   }
> +               else
> +                   {
> +                       if ((error =3D fo_ioctl(fp, TIOCSBRK, NULL,
> td->td_ucred,td)) !=3D 0)
> +                           break;
> +                       error =3D tsleep(&args->arg, PZERO | PCATCH,
> "linux_tcsbrk", hz / 4);
> +                       if (error =3D=3D EINTR || error =3D=3D ERESTART) {
> +                           fo_ioctl(fp, TIOCCBRK, NULL, td->td_ucred, td=
);
> +                           error =3D EINTR;
> +                       } else
> +                           error =3D fo_ioctl (fp, TIOCCBRK, NULL,
> td->td_ucred, td);
> +                       break;
> +                   }
> +
>         case LINUX_TCXONC: {
>                 switch (args->arg) {
>                 case LINUX_TCOOFF:
> --------------------
> Could someone have a look at this if the code is correct?
> Sorry but I do not have kernel developing experience and this is my first=
 patch
> I'm testing this patch for over 20 hours now and it seems to work
> well. No errors, load average dropped from 2.5 to 0.5
> Please CC me, I'am not on the list.
> And sorry for my bad english...


This looks good, below is the commit candidate. I did small changes
according to style and my taste. The biggest is the removal of PZERO
=66rom tsleep flags, which is actually shall not be used, since it changes
the thread priority (instead of usual assumption that the value is to
preserve the current priority).

diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index 0a9cd27..5ebf7ed 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -699,7 +699,7 @@ linux_ioctl_termio(struct thread *td, struct linux_ioct=
l_args *args)
 	struct linux_termios lios;
 	struct linux_termio lio;
 	struct file *fp;
-	int error;
+	int error, error1;
=20
 	if ((error =3D fget(td, args->fd, CAP_IOCTL, &fp)) !=3D 0)
 		return (error);
@@ -778,7 +778,27 @@ linux_ioctl_termio(struct thread *td, struct linux_ioc=
tl_args *args)
 		    td));
 		break;
=20
-	/* LINUX_TCSBRK */
+	case LINUX_TCSBRK:
+		/*
+		 * Non-zero argument is interpreted as the request to
+		 * perform tcdrain().
+		 * Zero argument means tcsendbreak().
+		 */
+		if (args->arg !=3D 0)
+			error =3D fo_ioctl(fp, TIOCDRAIN, NULL, td->td_ucred, td);
+		else {
+			error =3D fo_ioctl(fp, TIOCSBRK, NULL, td->td_ucred, td);
+			if (error !=3D 0)
+				break;
+			error =3D tsleep(&args->arg, PCATCH, "linux_tcsbrk",
+			    hz / 4);
+			error1 =3D fo_ioctl(fp, TIOCCBRK, NULL, td->td_ucred, td);
+			if (error =3D=3D EINTR || error =3D=3D ERESTART)
+				error =3D EINTR;
+			else
+				error =3D error1;
+		}
+		break;
=20
 	case LINUX_TCXONC: {
 		switch (args->arg) {

--0Oyvl1jN+EoPbLMC
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (FreeBSD)

iEYEARECAAYFAlCKGgkACgkQC3+MBN1Mb4j6GACdEEvt9MHDvo746/pMnalJFPik
f+8AnRimt1agGAy1m/+VeVDjhe9IJZ7n
=izFK
-----END PGP SIGNATURE-----

--0Oyvl1jN+EoPbLMC--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20121026050517.GM35915>