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;

Reply via email to