On Thu, Mar 11, 2021 at 12:40:37AM +0300, Vitaliy Makkoveev wrote:
> Since UNIX domain sockets are unlocked it makes sense to unlock
> sys_sendsyslog too. Console output still requires kernel lock to be
> held but this path is only followed while `syslogf' socket is not set.
> 
> New `syslogf_rwlock' used to protect `syslogf' access.
> 
> ok?

regress passes, OK bluhm@

> Index: sys/kern/subr_log.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/subr_log.c,v
> retrieving revision 1.73
> diff -u -p -r1.73 subr_log.c
> --- sys/kern/subr_log.c       9 Mar 2021 15:08:23 -0000       1.73
> +++ sys/kern/subr_log.c       10 Mar 2021 21:25:24 -0000
> @@ -86,7 +86,9 @@ int log_open;                       /* also used in log() */
>  int  msgbufmapped;                   /* is the message buffer mapped */
>  struct       msgbuf *msgbufp;                /* the mapped buffer, itself. */
>  struct       msgbuf *consbufp;               /* console message buffer. */
> +
>  struct       file *syslogf;
> +struct       rwlock syslogf_rwlock = RWLOCK_INITIALIZER("syslogf");
>  
>  /*
>   * Lock that serializes access to log message buffers.
> @@ -215,8 +217,11 @@ logclose(dev_t dev, int flag, int mode, 
>  {
>       struct file *fp;
>  
> +     rw_enter_write(&syslogf_rwlock);
>       fp = syslogf;
>       syslogf = NULL;
> +     rw_exit(&syslogf_rwlock);
> +
>       if (fp)
>               FRELE(fp, p);
>       log_open = 0;
> @@ -407,7 +412,7 @@ out:
>  int
>  logioctl(dev_t dev, u_long com, caddr_t data, int flag, struct proc *p)
>  {
> -     struct file *fp;
> +     struct file *fp, *newfp;
>       int error;
>  
>       switch (com) {
> @@ -441,9 +446,14 @@ logioctl(dev_t dev, u_long com, caddr_t 
>       case LIOCSFD:
>               if ((error = suser(p)) != 0)
>                       return (error);
> -             fp = syslogf;
> -             if ((error = getsock(p, *(int *)data, &syslogf)) != 0)
> +             if ((error = getsock(p, *(int *)data, &newfp)) != 0)
>                       return (error);
> +
> +             rw_enter_write(&syslogf_rwlock);
> +             fp = syslogf;
> +             syslogf = newfp;
> +             rw_exit(&syslogf_rwlock);
> +
>               if (fp)
>                       FRELE(fp, p);
>               break;
> @@ -635,12 +645,15 @@ dosendsyslog(struct proc *p, const char 
>       int error;
>  
>       /* Global variable syslogf may change during sleep, use local copy. */
> +     rw_enter_read(&syslogf_rwlock);
>       fp = syslogf;
>       if (fp)
>               FREF(fp);
> -     else if (!ISSET(flags, LOG_CONS))
> -             return (ENOTCONN);
> -     else {
> +     rw_exit(&syslogf_rwlock);
> +
> +     if (fp == NULL) {
> +             if (!ISSET(flags, LOG_CONS))
> +                     return (ENOTCONN);
>               /*
>                * Strip off syslog priority when logging to console.
>                * LOG_PRIMASK | LOG_FACMASK is 0x03ff, so at most 4
> @@ -690,41 +703,45 @@ dosendsyslog(struct proc *p, const char 
>               error = sosend(fp->f_data, NULL, &auio, NULL, NULL, flags);
>               if (error == 0)
>                       len -= auio.uio_resid;
> -     } else if (constty || cn_devvp) {
> -             error = cnwrite(0, &auio, 0);
> -             if (error == 0)
> -                     len -= auio.uio_resid;
> -             aiov.iov_base = "\r\n";
> -             aiov.iov_len = 2;
> -             auio.uio_iov = &aiov;
> -             auio.uio_iovcnt = 1;
> -             auio.uio_segflg = UIO_SYSSPACE;
> -             auio.uio_rw = UIO_WRITE;
> -             auio.uio_procp = p;
> -             auio.uio_offset = 0;
> -             auio.uio_resid = aiov.iov_len;
> -             cnwrite(0, &auio, 0);
>       } else {
> -             /* XXX console redirection breaks down... */
> -             if (sflg == UIO_USERSPACE) {
> -                     kbuf = malloc(len, M_TEMP, M_WAITOK);
> -                     error = copyin(aiov.iov_base, kbuf, len);
> +             KERNEL_LOCK();
> +             if (constty || cn_devvp) {
> +                     error = cnwrite(0, &auio, 0);
> +                     if (error == 0)
> +                             len -= auio.uio_resid;
> +                     aiov.iov_base = "\r\n";
> +                     aiov.iov_len = 2;
> +                     auio.uio_iov = &aiov;
> +                     auio.uio_iovcnt = 1;
> +                     auio.uio_segflg = UIO_SYSSPACE;
> +                     auio.uio_rw = UIO_WRITE;
> +                     auio.uio_procp = p;
> +                     auio.uio_offset = 0;
> +                     auio.uio_resid = aiov.iov_len;
> +                     cnwrite(0, &auio, 0);
>               } else {
> -                     kbuf = aiov.iov_base;
> -                     error = 0;
> -             }
> -             if (error == 0)
> -                     for (i = 0; i < len; i++) {
> -                             if (kbuf[i] == '\0')
> -                                     break;
> -                             cnputc(kbuf[i]);
> -                             auio.uio_resid--;
> +                     /* XXX console redirection breaks down... */
> +                     if (sflg == UIO_USERSPACE) {
> +                             kbuf = malloc(len, M_TEMP, M_WAITOK);
> +                             error = copyin(aiov.iov_base, kbuf, len);
> +                     } else {
> +                             kbuf = aiov.iov_base;
> +                             error = 0;
>                       }
> -             if (sflg == UIO_USERSPACE)
> -                     free(kbuf, M_TEMP, len);
> -             if (error == 0)
> -                     len -= auio.uio_resid;
> -             cnputc('\n');
> +                     if (error == 0)
> +                             for (i = 0; i < len; i++) {
> +                                     if (kbuf[i] == '\0')
> +                                             break;
> +                                     cnputc(kbuf[i]);
> +                                     auio.uio_resid--;
> +                             }
> +                     if (sflg == UIO_USERSPACE)
> +                             free(kbuf, M_TEMP, len);
> +                     if (error == 0)
> +                             len -= auio.uio_resid;
> +                     cnputc('\n');
> +             }
> +             KERNEL_UNLOCK();
>       }
>  
>  #ifdef KTRACE
> Index: sys/kern/syscalls.master
> ===================================================================
> RCS file: /cvs/src/sys/kern/syscalls.master,v
> retrieving revision 1.208
> diff -u -p -r1.208 syscalls.master
> --- sys/kern/syscalls.master  18 Jan 2021 18:25:51 -0000      1.208
> +++ sys/kern/syscalls.master  10 Mar 2021 21:25:25 -0000
> @@ -235,7 +235,7 @@
>                           fd_set *ex, const struct timespec *ts, \
>                           const sigset_t *mask); }
>  111  STD             { int sys_sigsuspend(int mask); }
> -112  STD             { int sys_sendsyslog(const char *buf, size_t nbyte, \
> +112  STD NOLOCK      { int sys_sendsyslog(const char *buf, size_t nbyte, \
>                           int flags); }
>  113  UNIMPL          fktrace
>  114  STD             { int sys_unveil(const char *path, \

Reply via email to