With ntpd(8) on a uniprocessor kernel (i386/amd64) I've found that poll(2)
often reacts to the SIGCHLD from a constraint child process before the
response message is received. Then constraint_check_child() closes the fd
and the response is lost.

# /usr/sbin/ntpd -dvs
ntp engine ready
constraint request to 150.101.170.174
constraint request to 150.101.170.153
constraint request to 150.101.170.146
constraint request to 150.101.170.166
constraint request to 150.101.170.159
constraint request to 150.101.170.152
constraint request to 150.101.170.160
constraint request to 150.101.170.187
no reply received in time, skipping initial time setting
^Cntp engine exiting
Terminating

The diff below improves the situation for me.

Nathanael

Index: constraint.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/constraint.c,v
retrieving revision 1.12
diff -u -p -r1.12 constraint.c
--- constraint.c        28 May 2015 21:34:36 -0000      1.12
+++ constraint.c        25 Jun 2015 02:11:46 -0000
@@ -277,7 +277,8 @@ constraint_check_child(void)
                                    " received in time, next query %ds",
                                    log_sockaddr((struct sockaddr *)
                                    &cstr->addr->ss), CONSTRAINT_SCAN_INTERVAL);
-                       }
+                       } else if (cstr->state < STATE_REPLY_RECEIVED)
+                               constraint_dispatch_msg(cstr->fd);
 
                        if (fail || cstr->state < STATE_REPLY_RECEIVED) {
                                cstr->senderrors++;
@@ -372,7 +373,7 @@ constraint_remove(struct constraint *cst
 }
 
 int
-constraint_dispatch_msg(struct pollfd *pfd)
+constraint_dispatch_msg(int fd)
 {
        struct imsg              imsg;
        struct constraint       *cstr;
@@ -380,20 +381,17 @@ constraint_dispatch_msg(struct pollfd *p
        struct timeval           tv[2];
        double                   offset;
 
-       if ((cstr = constraint_byfd(pfd->fd)) == NULL)
-               return (0);
-
-       if (!(pfd->revents & POLLIN))
+       if ((cstr = constraint_byfd(fd)) == NULL)
                return (0);
 
        if ((n = imsg_read(&cstr->ibuf)) == -1 || n == 0) {
-               constraint_close(pfd->fd);
+               constraint_close(fd);
                return (1);
        }
 
        for (;;) {
                if ((n = imsg_get(&cstr->ibuf, &imsg)) == -1) {
-                       constraint_close(pfd->fd);
+                       constraint_close(fd);
                        return (1);
                }
                if (n == 0)
Index: ntp.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntp.c,v
retrieving revision 1.132
diff -u -p -r1.132 ntp.c
--- ntp.c       25 May 2015 14:58:34 -0000      1.132
+++ ntp.c       25 Jun 2015 02:11:46 -0000
@@ -425,7 +421,11 @@ ntp_main(int pipe_prnt[2], int fd_ctl, s
                }
 
                for (; nfds > 0 && j < i; j++) {
-                       nfds -= constraint_dispatch_msg(&pfd[j]);
+                       if (pfd[j].revents) {
+                               nfds--;
+                               if (pfd[j].revents & POLLIN)
+                                       constraint_dispatch_msg(pfd[j].fd);
+                       }
                }
 
                for (s = TAILQ_FIRST(&conf->ntp_sensors); s != NULL;
Index: ntpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntpd.h,v
retrieving revision 1.121
diff -u -p -r1.121 ntpd.h
--- ntpd.h      20 May 2015 13:32:39 -0000      1.121
+++ ntpd.h      25 Jun 2015 02:11:46 -0000
@@ -345,7 +345,7 @@ void         constraint_add(struct constraint *
 void    constraint_remove(struct constraint *);
 int     constraint_init(struct constraint *);
 int     constraint_query(struct constraint *);
-int     constraint_dispatch_msg(struct pollfd *);
+int     constraint_dispatch_msg(int fd);
 void    constraint_check_child(void);
 int     constraint_check(double);
 void    constraint_dns(u_int32_t, u_int8_t *, size_t);

Reply via email to