On Thu, Sep 01, 2022 at 06:06:10PM +0200, Moritz Buhl wrote: > I addressed your concerns as well as these of jca, just the kernel > part (and the new ktrace stuff) below. > > One minor thing: I didn't see any kdump output where one struct was > contained in another one but I am printing it like ddb would so I > guess it should be fine.
OK bluhm@ > Index: kern/syscalls.master > =================================================================== > RCS file: /mount/openbsd/cvs/src/sys/kern/syscalls.master,v > retrieving revision 1.229 > diff -u -p -r1.229 syscalls.master > --- kern/syscalls.master 1 Aug 2022 14:56:59 -0000 1.229 > +++ kern/syscalls.master 1 Sep 2022 14:52:47 -0000 > @@ -244,8 +244,10 @@ > const char *permissions); } > 115 STD { int sys___realpath(const char *pathname, \ > char *resolved); } > -116 OBSOL t32_gettimeofday > -117 OBSOL t32_getrusage > +116 STD NOLOCK { int sys_recvmmsg(int s, struct mmsghdr *mmsg, \ > + unsigned int vlen, unsigned int flags, \ > + struct timespec *timeout); } > +117 UNIMPL sendmmsg > 118 STD { int sys_getsockopt(int s, int level, int name, \ > void *val, socklen_t *avalsize); } > 119 STD { int sys_thrkill(pid_t tid, int signum, void *tcb); } > Index: kern/uipc_syscalls.c > =================================================================== > RCS file: /mount/openbsd/cvs/src/sys/kern/uipc_syscalls.c,v > retrieving revision 1.201 > diff -u -p -r1.201 uipc_syscalls.c > --- kern/uipc_syscalls.c 14 Aug 2022 01:58:28 -0000 1.201 > +++ kern/uipc_syscalls.c 1 Sep 2022 14:37:26 -0000 > @@ -805,6 +805,140 @@ done: > } > > int > +sys_recvmmsg(struct proc *p, void *v, register_t *retval) > +{ > + struct sys_recvmmsg_args /* { > + syscallarg(int) s; > + syscallarg(struct mmsghdr *) mmsg; > + syscallarg(unsigned int) vlen; > + syscallarg(unsigned int) flags; > + syscallarg(struct timespec *) timeout; > + } */ *uap = v; > + struct mmsghdr mmsg, *mmsgp; > + struct timespec ts, now; > + struct iovec aiov[UIO_SMALLIOV], *uiov, *iov = aiov; > + struct file *fp; > + struct socket *so; > + struct timespec *timeout; > + size_t iovlen = UIO_SMALLIOV; > + register_t retrec; > + unsigned int vlen, dgrams; > + int error = 0, flags, s; > + > + s = SCARG(uap, s); > + if ((error = getsock(p, s, &fp))) > + return (error); > + so = (struct socket *)fp->f_data; > + > + timeout = SCARG(uap, timeout); > + if (timeout != NULL) { > + error = copyin(timeout, &ts, sizeof(ts)); > + if (error) > + return error; > +#ifdef KTRACE > + if (KTRPOINT(p, KTR_STRUCT)) > + ktrreltimespec(p, &ts); > +#endif > + getnanotime(&now); > + timespecadd(&now, &ts, &ts); > + } > + > + flags = SCARG(uap, flags); > + > + /* Arbitrarily capped at 1024 datagrams. */ > + vlen = SCARG(uap, vlen); > + if (vlen > 1024) > + vlen = 1024; > + > + mmsgp = SCARG(uap, mmsg); > + for (dgrams = 0; dgrams < vlen;) { > + error = copyin(&mmsgp[dgrams], &mmsg, sizeof(mmsg)); > + if (error) > + break; > + > + if (mmsg.msg_hdr.msg_iovlen > IOV_MAX) { > + error = EMSGSIZE; > + break; > + } > + > + if (mmsg.msg_hdr.msg_iovlen > iovlen) { > + if (iov != aiov) > + free(iov, M_IOV, iovlen * > + sizeof(struct iovec)); > + > + iovlen = mmsg.msg_hdr.msg_iovlen; > + iov = mallocarray(iovlen, sizeof(struct iovec), > + M_IOV, M_WAITOK); > + } > + > + if (mmsg.msg_hdr.msg_iovlen > 0) { > + error = copyin(mmsg.msg_hdr.msg_iov, iov, > + mmsg.msg_hdr.msg_iovlen * sizeof(struct iovec)); > + if (error) > + break; > + } > + > + uiov = mmsg.msg_hdr.msg_iov; > + mmsg.msg_hdr.msg_iov = iov; > + mmsg.msg_hdr.msg_flags = flags; > + > + error = recvit(p, s, &mmsg.msg_hdr, NULL, &retrec); > + if (error) { > + if (error == EAGAIN && dgrams > 0) > + error = 0; > + break; > + } > + > + if (dgrams == 0 && flags & MSG_WAITFORONE) { > + flags &= ~MSG_WAITFORONE; > + flags |= MSG_DONTWAIT; > + } > + > + mmsg.msg_hdr.msg_iov = uiov; > + mmsg.msg_len = retrec; > +#ifdef KTRACE > + if (KTRPOINT(p, KTR_STRUCT)) { > + ktrmmsghdr(p, &mmsg); > + if (mmsg.msg_hdr.msg_iovlen) > + ktriovec(p, iov, mmsg.msg_hdr.msg_iovlen); > + } > +#endif > + > + error = copyout(&mmsg, &mmsgp[dgrams], sizeof(mmsg)); > + if (error) > + break; > + > + dgrams++; > + if (mmsg.msg_hdr.msg_flags & MSG_OOB) > + break; > + > + if (timeout != NULL) { > + getnanotime(&now); > + timespecsub(&now, &ts, &now); > + if (now.tv_sec > 0) > + break; > + } > + } > + > + if (iov != aiov) > + free(iov, M_IOV, iovlen * sizeof(struct iovec)); > + > + *retval = dgrams; > + > + /* > + * If we succeeded at least once, return 0, hopefully so->so_error > + * will catch it next time. > + */ > + if (error && dgrams > 0) { > + so->so_error = error; > + error = 0; > + } > + > + FRELE(fp, p); > + return (error); > +} > + > +int > recvit(struct proc *p, int s, struct msghdr *mp, caddr_t namelenp, > register_t *retsize) > { > Index: sys/ktrace.h > =================================================================== > RCS file: /mount/openbsd/cvs/src/sys/sys/ktrace.h,v > retrieving revision 1.41 > diff -u -p -r1.41 ktrace.h > --- sys/ktrace.h 22 Feb 2022 17:14:14 -0000 1.41 > +++ sys/ktrace.h 1 Sep 2022 14:35:13 -0000 > @@ -239,6 +239,8 @@ void ktrstruct(struct proc *, const c > ktrstruct((p), "quota", (s), sizeof(struct dqblk)) > #define ktrmsghdr(p, s) \ > ktrstruct(p, "msghdr", s, sizeof(struct msghdr)) > +#define ktrmmsghdr(p, s) \ > + ktrstruct(p, "mmsghdr", s, sizeof(struct mmsghdr)) > #define ktriovec(p, s, count) \ > ktrstruct(p, "iovec", s, (count) * sizeof(struct iovec)) > #define ktrcmsghdr(p, c, len) \ > Index: sys/socket.h > =================================================================== > RCS file: /mount/openbsd/cvs/src/sys/sys/socket.h,v > retrieving revision 1.102 > diff -u -p -r1.102 socket.h > --- sys/socket.h 22 Feb 2022 01:01:02 -0000 1.102 > +++ sys/socket.h 1 Sep 2022 08:49:48 -0000 > @@ -490,6 +490,13 @@ struct msghdr { > int msg_flags; /* flags on received message */ > }; > > +struct mmsghdr { > + struct msghdr msg_hdr; > + unsigned int msg_len; > +}; > + > +struct timespec; > + > #define MSG_OOB 0x1 /* process out-of-band data */ > #define MSG_PEEK 0x2 /* peek at incoming message */ > #define MSG_DONTROUTE 0x4 /* send without using routing > tables */ > @@ -502,6 +509,7 @@ struct msghdr { > #define MSG_MCAST 0x200 /* this message rec'd as > multicast */ > #define MSG_NOSIGNAL 0x400 /* do not send SIGPIPE */ > #define MSG_CMSG_CLOEXEC 0x800 /* set FD_CLOEXEC on received > fds */ > +#define MSG_WAITFORONE 0x1000 /* nonblocking but wait for one > msg */ > > /* > * Header for ancillary data objects in msg_control buffer. > @@ -565,6 +573,8 @@ int listen(int, int); > ssize_t recv(int, void *, size_t, int); > ssize_t recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t > *); > ssize_t recvmsg(int, struct msghdr *, int); > +int recvmmsg(int, struct mmsghdr *, unsigned int, unsigned int, > + struct timespec *); > ssize_t send(int, const void *, size_t, int); > ssize_t sendto(int, const void *, > size_t, int, const struct sockaddr *, socklen_t); > Index: usr.bin/kdump/kdump.c > =================================================================== > RCS file: /mount/openbsd/cvs/src/usr.bin/kdump/kdump.c,v > retrieving revision 1.149 > diff -u -p -r1.149 kdump.c > --- usr.bin/kdump/kdump.c 20 Jul 2022 05:56:36 -0000 1.149 > +++ usr.bin/kdump/kdump.c 1 Sep 2022 15:03:03 -0000 > @@ -795,6 +795,7 @@ static const formatter scargs[][8] = { > [SYS_ppoll] = { Pptr, Pucount, Pptr, Pptr }, > [SYS_pselect] = { Pcount, Pptr, Pptr, Pptr, Pptr, Pptr }, > [SYS_sigsuspend] = { Sigset }, > + [SYS_recvmmsg] = { Pfd, Pptr, Pcount, Sendrecvflagsname, Pptr }, > [SYS_getsockopt] = { Pfd, PASS_TWO, Sockoptlevelname, Pptr, Pptr }, > [SYS_thrkill] = { Ppid_t, Signame, Pptr }, > [SYS_readv] = { Pfd, Pptr, Pcount }, > Index: usr.bin/kdump/ktrstruct.c > =================================================================== > RCS file: /mount/openbsd/cvs/src/usr.bin/kdump/ktrstruct.c,v > retrieving revision 1.29 > diff -u -p -r1.29 ktrstruct.c > --- usr.bin/kdump/ktrstruct.c 21 Dec 2020 07:47:37 -0000 1.29 > +++ usr.bin/kdump/ktrstruct.c 1 Sep 2022 15:24:42 -0000 > @@ -398,6 +398,18 @@ ktrquota(const struct dqblk *quota) > } > > static void > +ktrmmsghdr(const struct mmsghdr *mmsg) > +{ > + printf("struct mmsghdr { msg_hdr = { name=%p, namelen=%u, iov=%p, > iovlen=%u," > + " control=%p, controllen=%u, flags=", > + mmsg->msg_hdr.msg_name, mmsg->msg_hdr.msg_namelen, > + mmsg->msg_hdr.msg_iov, mmsg->msg_hdr.msg_iovlen, > + mmsg->msg_hdr.msg_control, mmsg->msg_hdr.msg_controllen); > + sendrecvflagsname(mmsg->msg_hdr.msg_flags); > + printf(" }, msg_len = %u }\n", mmsg->msg_len); > +} > + > +static void > ktrmsghdr(const struct msghdr *msg) > { > printf("struct msghdr { name=%p, namelen=%u, iov=%p, iovlen=%u," > @@ -649,6 +661,13 @@ ktrstruct(char *buf, size_t buflen) > goto invalid; > memcpy(&msg, data, datalen); > ktrmsghdr(&msg); > + } else if (strcmp(name, "mmsghdr") == 0) { > + struct mmsghdr mmsg; > + > + if (datalen != sizeof(mmsg)) > + goto invalid; > + memcpy(&mmsg, data, datalen); > + ktrmmsghdr(&mmsg); > } else if (strcmp(name, "iovec") == 0) { > if (datalen % sizeof(struct iovec)) > goto invalid;