Re: Open master pty (/dev/ptmx) non blocking

2022-09-24 Thread Anthony Mallet
On Friday 23 Sep 2022, at 17:34, David H. Gutteridge wrote:
> On Fri, 23 Sep 2022 at 20:14:23 +, David Holland wrote:
> > On Fri, Sep 23, 2022 at 01:39:16PM +0200, Martin Husemann wrote:
> > >  Note that unlike implementations on some other operating
> > >  systems, posix_openpt() does not return EINVAL if the value
> > >  of oflag would be deemed invalid
> >
> > That is, however, kind of a feeble excuse :-)
>
> Agreed. But I inferred this was perhaps done this way on purpose, and
> could be controversial to change.

I noticed that this might also affect Linux emulation as
pty_alloc_master() is used for both native and emualted software.

Linux emulated applications may not be prepared deal with EINVAL if
they pass e.g. O_NONBLOCK.


Re: Open master pty (/dev/ptmx) non blocking

2022-09-24 Thread Anthony Mallet
On Fri, 23 Sep 2022, David Holland wrote:
> While my inclination would be to make it work, until someone wants to
> figure out how to do that it seems straightforward to make O_NONBLOCK
> fail:

Mostly out of curiosity and for the records, I tested the attached
patch. It enables the EINVAL error for unsupported flags and sets
O_NONBLOCK if present. This seems to work after a quick test.

Regarding the O_CLOEXEC, it may require a bit more work. I feel like
the fd_set_exclose() function in kern_descrip.c could be used.


Index: sys/kern/tty_ptm.c
===
RCS file: /cvsroot/src/sys/kern/tty_ptm.c,v
retrieving revision 1.43
diff -u -r1.43 tty_ptm.c
--- sys/kern/tty_ptm.c  29 Jun 2021 22:40:53 -  1.43
+++ sys/kern/tty_ptm.c  24 Sep 2022 15:41:44 -
@@ -87,7 +87,7 @@
 int pts_major, ptc_major;
 
 static dev_t pty_getfree(void);
-static int pty_alloc_master(struct lwp *, int *, dev_t *, struct mount *);
+static int pty_alloc_master(struct lwp *, int, int *, dev_t *, struct mount *);
 static int pty_alloc_slave(struct lwp *, int *, dev_t, struct mount *);
 static int pty_vn_open(struct vnode *, struct lwp *);
 
@@ -155,13 +155,16 @@
 }
 
 static int
-pty_alloc_master(struct lwp *l, int *fd, dev_t *dev, struct mount *mp)
+pty_alloc_master(struct lwp *l, int flag, int *fd, dev_t *dev, struct mount 
*mp)
 {
int error;
struct file *fp;
struct vnode *vp;
int md;
 
+   if (flag & ~(O_ACCMODE | O_NOCTTY | O_NONBLOCK))
+   return EINVAL;
+
if ((error = fd_allocfile(, fd)) != 0) {
DPRINTF(("fd_allocfile %d\n", error));
return error;
@@ -199,7 +202,7 @@
else
goto bad;
}
-   fp->f_flag = FREAD|FWRITE;
+   fp->f_flag = FREAD|FWRITE | (flag & O_NONBLOCK);
fp->f_type = DTYPE_VNODE;
fp->f_ops = 
fp->f_vnode = vp;
@@ -343,7 +346,7 @@
case 2: /* /emul/linux/dev/ptmx */
if ((error = pty_getmp(l, )) != 0)
return error;
-   if ((error = pty_alloc_master(l, , , mp)) != 0)
+   if ((error = pty_alloc_master(l, flag, , , mp)) != 0)
return error;
if (minor(dev) == 2) {
/*
@@ -392,7 +395,7 @@
if ((error = pty_getmp(l, )) != 0)
return error;
 
-   if ((error = pty_alloc_master(l, , , mp)) != 0)
+   if ((error = pty_alloc_master(l, 0, , , mp)) != 0)
return error;
 
if ((error = pty_grant_slave(l, newdev, mp)) != 0)


Re: Open master pty (/dev/ptmx) non blocking

2022-09-23 Thread Anthony Mallet
> The man page says:
> 
>  Note that unlike implementations on some other operating systems,
>  posix_openpt() does not return EINVAL if the value of oflag would
>  be deemed invalid

Oh, right. I missed that...

I see that this was added 2 weeks ago and my base is from last March
only. While I did check that the code did not change, I did not look
for recent commits in the manual.

Allrighty, sorry for the noise!

Cheers,
Anthony


Re: Open master pty (/dev/ptmx) non blocking

2022-09-23 Thread Anthony Mallet
On Friday 23 Sep 2022, at 10:29, RVP wrote:
> So, O_NONBLOCK is, at least, _definitely_ non-portable. Best to use
> fcntl() here and not depend on a Linux-specific behaviour.

Fair enough :)

Then, shouldn't the open(2) (and posix_openpt(3)) at least fail with
EINVAL or something if other flags are specified?


Open master pty (/dev/ptmx) non blocking

2022-09-23 Thread Anthony Mallet
Hi,

I have a piece of software that opens a master pty non-blocking:
fd = open("/dev/ptmx", O_RDWR | O_NOCTTY | O_NONBLOCK);

The intent is to make further read(2) on the master non blocking. But
the O_NONBLOCK flag seems to be ignored. Attached is a minimal sample
C program showing the issue.

Several remarks:
* open(2) manual does not mention a master pty as special regarding the
  O_NONBLOCK flag, and even says "this flag also has the effect of making
  all subsequent I/O on the open file non-blocking",
* explicitly setting the file descriptor as non-blocking with fcntl(2)
  works fine,
* a slave pty has no such issue (O_NONBLOCK in open(2) is honoured),
* FWIW, linux has no surprise here, the flag behaves as one would expect,
* POSIX does not mention the flag as supported in posix_openpt(3) (it
  does not says it's not supported either :).

So, I'm not sure if something should be changed here, and if someone
is willing to check that? I tried to track down where in the kernel
this happens, maybe in pty_alloc_master in kern/tty_ptm.c? I really
don't master those kernel aspects so I'm not confident in providing a
patch.

I guess the principle of least surprise would say that the flag should
be supported (e.g. for maximum portability). OTOH, if the current
behaviour is deemed correct or sufficient, maybe at least some manual
(posix_openpt, open, ...) should mention this is not supported?

Best,
Anthony

#include 

#include 
#include 
#include 

int
main()
{
  char buf[8];
  ssize_t s;
  int fd;

  /* open non-blocking: ignored */
  fd = open("/dev/ptmx", O_RDWR | O_NOCTTY | O_NONBLOCK);
  if (fd < 0) err(2, "/dev/ptmx");

#if 0
  /* set non-blocking: OK */
  int flag;
  flag = fcntl(fd, F_GETFL);
  if (flag == -1) err(2, "F_GETFL");

  fcntl(fd, F_SETFL, flag | O_NONBLOCK);
#endif

  /* read */
  s = read(fd, buf, sizeof(buf));
  warn("read %zd", s);

  return 0;
}


Re: "Boot this kernel once" functionality? (amd64)

2020-09-16 Thread Anthony Mallet
[I noticed that for some reason I was not subscribed anymore to
tech-kern, so I'm manually pasting some replies read from the
mail-index web :/]

Mouse wrote:
> kexec stuff?  I've occasionally wondered why more ports don't implement
> it.

Valery Ushakov wrote:
> As der Mouse mentioned upthread, kloader(4) would seem like a
> promising candidate to implement this.
> Of course that doesn't suit your immediate needs...

I was not aware of kloader(4), thanks!

I don't need an urgent solution, so this looks actually very
promising. I will try to read more about this and get familiar with
the code.

In the meantime, if you (Mouse) come up with something to test or just
draft ideas, I'd be happy to help.


Re: "Boot this kernel once" functionality? (amd64)

2020-09-16 Thread Anthony Mallet
On Wednesday 16 Sep 2020, at 12:09, Martin Husemann wrote:
> This works fine on e.g. sparc*; I can do: shutdown -b netbsd.t -r
> now
>
> No state is modified on any disks, very convenient.

Right, not changing any state seems safer!

> I don't know if there is enough of a persistent environment for UEFI
> boots (I would guess there is), and probably no easy way for BIOS
> boot.

The machine in question is not UEFI, so I would be more interested in
a pure BIOS solution.


"Boot this kernel once" functionality? (amd64)

2020-09-16 Thread Anthony Mallet
Hi,

I own a remote amd64 machine, with no physical access at all (no
serial console either). It can be remotely power cycled,
though. Upgrading a kernel there is always a bit frightening. In case
of a boot failure, the recovery process to revert to the old kernel is
painful and a bit involved (netboot on a debian system is doable, but
then accessing the netbsd UFS partition is tricky).

I was wondering how easy that would be to add a "boot once" feature to
our secondary boot loader. I know that OpenBSD has a trick that
searches for a "bsd.upgrade" kernel with the +x bit, then `chmod -x`
it and boots that. So, in case of failure, a power cycle will
reboot into the regular kernel. Grub also has some tricks to achieve
this, although a bit more obfuscated.

I checked a bit the secondary boot loader code. It seems that the bios
disk I/O routines are read-only (I was checking amd64 BIOS and UEFI
boot loaders). So this prevents implementing the OpenBSD trick. Is
this by design, or just because it was never required to add a writing
capability in the biosdisk_strategy() function? Is it just a matter of
implementing it?

I was also wondering if it would be possible to pass arguments to the
primary or secondary bootloader via reboot(2) and the boothowto
flags. But this doesn't seem doable. Right?

So I was about to give up with this idea, but I'm checking here for
more comments, feedback ... especially on adding write support to
biosdisk_strategy(), since I have no clue about BIOS in general :)

Cheers,
Anthony


Re: in which we present an ugly hack to make sys/queue.h CIRCLEQ work

2013-11-24 Thread Anthony Mallet
On Saturday, at 19:08, Dennis Ferguson wrote:
| gcc can't correctly eliminate the comparison just because you are asking
| it to compare pointers to different structure types.  No aliasing issues
| arise in any case unless you actually use the pointers to access something,
| and there are many ways that two pointers of different structure types can
| validly refer to the same object.

(I think that) strict aliasing rules implies that if two types type{1,2} do
not match any of the aliasing rules (e.g. type1 is of the same type as
the first member of type2, or type1 is a char, or ...), then any two pointers
ptr{1,2} on type{1,2} respectively _ARE_ different, because *ptr1 != *ptr2 per
the aliasing rules and this implies ptr1 != ptr2.