/* Bit values for receiver->flags */
#define RX_F_BOUND 0x00000001 /* receiver already bound */
-#define RX_F_INHERITED 0x00000002 /* inherited FD from the parent process (fd@) or duped from another local receiver */
+#define RX_F_INHERITED_FD 0x00000002 /* inherited FD from the parent process (fd@) */
#define RX_F_MWORKER 0x00000004 /* keep the FD open in the master but close it in the children */
#define RX_F_MUST_DUP 0x00000008 /* this receiver's fd must be dup() from a reference; ignore socket-level ops here */
#define RX_F_NON_SUSPENDABLE 0x00000010 /* this socket cannot be suspended hence must always be unbound */
#define RX_F_PASS_PKTINFO 0x00000020 /* pass pktinfo in received messages */
+#define RX_F_INHERITED_SOCK 0x00000040 /* inherited sock that could be duped from another local receiver */
/* Bit values for rx_settings->options */
#define RX_O_FOREIGN 0x00000001 /* receives on foreign addresses */
list_for_each_entry(l, &bind_conf->listeners, by_bind) {
HA_ATOMIC_INC(&unstoppable_jobs);
/* it's a sockpair but we don't want to keep the fd in the master */
- l->rx.flags &= ~RX_F_INHERITED;
+ l->rx.flags &= ~RX_F_INHERITED_FD;
global.maxsock++; /* for the listening socket */
}
proto->add(proto, l);
if (fd != -1)
- l->rx.flags |= RX_F_INHERITED;
+ l->rx.flags |= RX_F_INHERITED_FD|RX_F_INHERITED_SOCK;
guid_init(&l->guid);
/* it has been allocated already in the previous round */
shard_info_attach(&new_li->rx, ref->rx.shard_info);
new_li->rx.flags |= RX_F_MUST_DUP;
+ /* taking the other one's FD will result in it being marked
+ * extern and being dup()ed. Let's mark the receiver as
+ * inherited so that it properly bypasses all second-stage
+ * setup/unbind and avoids being passed to new processes.
+ */
+ new_li->rx.flags |= ref->rx.flags & RX_F_INHERITED_SOCK;
}
gmask &= gmask - 1; // drop lowest bit
err |= ERR_RETRYABLE;
goto bind_ret_err;
}
- /* taking the other one's FD will result in it being marked
- * extern and being dup()ed. Let's mark the receiver as
- * inherited so that it properly bypasses all second-stage
- * setup and avoids being passed to new processes.
- */
- rx->flags |= RX_F_INHERITED;
rx->fd = rx->shard_info->ref->fd;
}
* parent process and any possible subsequent worker inheriting it.
* Thus we just stop receiving from it.
*/
- if (rx->flags & RX_F_INHERITED)
+ if (rx->flags & RX_F_INHERITED_SOCK)
goto done;
if (connect(rx->fd, &sa, sizeof(sa)) < 0)
if (rx->fd < 0)
return 0;
- if ((rx->flags & RX_F_INHERITED) || listen(rx->fd, listener_backlog(l)) == 0) {
+ if ((rx->flags & RX_F_INHERITED_SOCK) || listen(rx->fd, listener_backlog(l)) == 0) {
fd_want_recv(l->rx.fd);
return 1;
}
/* we never do that with a shared FD otherwise we'd break it in the
* parent process and any possible subsequent worker inheriting it.
*/
- if (rx->flags & RX_F_INHERITED)
+ if (rx->flags & RX_F_INHERITED_SOCK)
goto done;
if (getsockname(rx->fd, (struct sockaddr *)&ss, &len) < 0)
if (rx->fd < 0)
return 0;
- if (!(rx->flags & RX_F_INHERITED) && connect(rx->fd, &sa, sizeof(sa)) < 0)
+ if (!(rx->flags & RX_F_INHERITED_SOCK) && connect(rx->fd, &sa, sizeof(sa)) < 0)
return -1;
fd_want_recv(rx->fd);
return;
if (!stopping && master &&
- rx->flags & RX_F_INHERITED)
+ rx->flags & RX_F_INHERITED_FD)
return;
rx->flags &= ~RX_F_BOUND;
err |= ERR_RETRYABLE;
goto bind_ret_err;
}
- /* taking the other one's FD will result in it being marked
- * extern and being dup()ed. Let's mark the receiver as
- * inherited so that it properly bypasses all second-stage
- * setup and avoids being passed to new processes.
- */
- rx->flags |= RX_F_INHERITED;
rx->fd = rx->shard_info->ref->fd;
}
fd_insert(fd, rx->owner, rx->iocb, rx->bind_tgroup, rx->bind_thread);
/* for now, all regularly bound TCP listeners are exportable */
- if (!(rx->flags & RX_F_INHERITED))
+ if (!(rx->flags & (RX_F_INHERITED_FD|RX_F_INHERITED_SOCK)))
HA_ATOMIC_OR(&fdtab[fd].state, FD_EXPORTED);
bind_return:
err |= ERR_RETRYABLE;
goto bind_ret_err;
}
- /* taking the other one's FD will result in it being marked
- * extern and being dup()ed. Let's mark the receiver as
- * inherited so that it properly bypasses all second-stage
- * setup and avoids being passed to new processes.
- */
- rx->flags |= RX_F_INHERITED;
rx->fd = rx->shard_info->ref->fd;
}
fd_insert(fd, rx->owner, rx->iocb, rx->bind_tgroup, rx->bind_thread);
/* for now, all regularly bound TCP listeners are exportable */
- if (!(rx->flags & RX_F_INHERITED))
+ if (!(rx->flags & (RX_F_INHERITED_FD|RX_F_INHERITED_SOCK)))
HA_ATOMIC_OR(&fdtab[fd].state, FD_EXPORTED);
return err;