Re: Open master pty (/dev/ptmx) non blocking
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
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
> 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
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
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)
[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)
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)
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
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.