From 72a0ebf986c1cb57d160d35a678be4df2d566e33 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Fri, 4 May 2012 10:25:32 +0200 Subject: [PATCH] Fix regression introduced by previous IPC fds fix --- etc/afpd/afp_config.c | 12 +++--------- etc/afpd/afp_dsi.c | 1 - etc/afpd/main.c | 25 +++++++++++++------------ include/atalk/server_child.h | 4 ++-- libatalk/dsi/dsi_getsess.c | 16 +++++++--------- libatalk/util/server_child.c | 26 ++++++++------------------ 6 files changed, 33 insertions(+), 51 deletions(-) diff --git a/etc/afpd/afp_config.c b/etc/afpd/afp_config.c index c15e0b7d..29b552d3 100644 --- a/etc/afpd/afp_config.c +++ b/etc/afpd/afp_config.c @@ -223,15 +223,8 @@ static afp_child_t *dsi_start(AFPConfig *config, AFPConfig *configs, if (!(child = dsi_getsession(dsi, server_children, config->obj.options.tickleval))) { - LOG(log_error, logtype_afpd, "dsi_start: session error: %s", strerror(errno)); - return NULL; - } - - /* we've forked. */ - if (parent_or_child == 1) { + /* we've forked. */ configfree(configs, config); - config->obj.ipc_fd = child->ipc_fds[1]; - free(child); afp_over_dsi(&config->obj); /* start a session */ exit (0); } @@ -449,6 +442,7 @@ srvloc_reg_err: config->fd = dsi->serversock; config->obj.handle = dsi; + dsi->AFPobj = &config->obj; config->obj.config = config; config->obj.proto = AFPPROTO_DSI; @@ -590,7 +584,7 @@ AFPConfig *configinit(struct afp_options *cmdline) first = AFPConfigInit(cmdline, cmdline); /* Now register with zeroconf, we also need the volumes for that */ - if (! (first->obj.options.flags & OPTION_NOZEROCONF)) { + if (first && !(first->obj.options.flags & OPTION_NOZEROCONF)) { load_volumes(&first->obj); zeroconf_register(first); } diff --git a/etc/afpd/afp_dsi.c b/etc/afpd/afp_dsi.c index 8379f5bc..bf454e15 100644 --- a/etc/afpd/afp_dsi.c +++ b/etc/afpd/afp_dsi.c @@ -389,7 +389,6 @@ void afp_over_dsi(AFPObj *obj) struct sigaction action; AFPobj = obj; - dsi->AFPobj = obj; obj->exit = afp_dsi_die; obj->reply = (int (*)()) dsi_cmdreply; obj->attention = (int (*)(void *, AFPUserBytes)) dsi_attention; diff --git a/etc/afpd/main.c b/etc/afpd/main.c index edcfe6a7..e23d5570 100644 --- a/etc/afpd/main.c +++ b/etc/afpd/main.c @@ -409,7 +409,7 @@ int main(int ac, char **av) (void)setlimits(); afp_child_t *child; - int fd[2]; /* we only use one, but server_child_add expects [2] */ + int recon_ipc_fd; pid_t pid; int saveerrno; @@ -482,7 +482,7 @@ int main(int ac, char **av) &polldata, &fdset_used, &fdset_size, - child->ipc_fds[0], + child->ipc_fd, IPC_FD, child); } @@ -492,10 +492,10 @@ int main(int ac, char **av) child = (afp_child_t *)polldata[i].data; LOG(log_debug, logtype_afpd, "main: IPC request from child[%u]", child->pid); - if (ipc_server_read(server_children, child->ipc_fds[0]) != 0) { - fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fds[0]); - close(child->ipc_fds[0]); - child->ipc_fds[0] = -1; + if (ipc_server_read(server_children, child->ipc_fd) != 0) { + fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fd); + close(child->ipc_fd); + child->ipc_fd = -1; if ((default_options.flags & OPTION_KEEPSESSIONS) && child->disasociated) { LOG(log_note, logtype_afpd, "main: removing reattached child[%u]", child->pid); server_child_remove(server_children, CHILD_DSIFORK, child->pid); @@ -505,19 +505,20 @@ int main(int ac, char **av) case DISASOCIATED_IPC_FD: LOG(log_debug, logtype_afpd, "main: IPC reconnect request"); - if ((fd[0] = accept(disasociated_ipc_fd, NULL, NULL)) == -1) { + if ((recon_ipc_fd = accept(disasociated_ipc_fd, NULL, NULL)) == -1) { LOG(log_error, logtype_afpd, "main: accept: %s", strerror(errno)); break; } - if (readt(fd[0], &pid, sizeof(pid_t), 0, 1) != sizeof(pid_t)) { + if (readt(recon_ipc_fd, &pid, sizeof(pid_t), 0, 1) != sizeof(pid_t)) { LOG(log_error, logtype_afpd, "main: readt: %s", strerror(errno)); - close(fd[0]); + close(recon_ipc_fd); break; } LOG(log_note, logtype_afpd, "main: IPC reconnect from pid [%u]", pid); - if ((child = server_child_add(server_children, CHILD_DSIFORK, pid, fd)) == NULL) { + + if ((child = server_child_add(server_children, CHILD_DSIFORK, pid, recon_ipc_fd)) == NULL) { LOG(log_error, logtype_afpd, "main: server_child_add"); - close(fd[0]); + close(recon_ipc_fd); break; } child->disasociated = 1; @@ -526,7 +527,7 @@ int main(int ac, char **av) &polldata, &fdset_used, &fdset_size, - fd[0], + recon_ipc_fd, IPC_FD, child); break; diff --git a/include/atalk/server_child.h b/include/atalk/server_child.h index f548ce4d..5ee8314f 100644 --- a/include/atalk/server_child.h +++ b/include/atalk/server_child.h @@ -32,7 +32,7 @@ typedef struct server_child_data { uint32_t time; /* client boot time (from the mac client) */ uint32_t idlen; /* clientid len (from the Mac client) */ char *clientid; /* clientid (from the Mac client) */ - int ipc_fds[2]; /* socketpair for IPC bw */ + int ipc_fd; /* socket for IPC bw afpd parent and childs */ struct server_child_data **prevp, *next; } afp_child_t; @@ -40,7 +40,7 @@ extern int parent_or_child; /* server_child.c */ extern server_child *server_child_alloc (const int, const int); -extern afp_child_t *server_child_add (server_child *, int, pid_t, uint ipc_fds[2]); +extern afp_child_t *server_child_add (server_child *, int, pid_t, int ipc_fd); extern int server_child_remove (server_child *, const int, const pid_t); extern void server_child_free (server_child *); diff --git a/libatalk/dsi/dsi_getsess.c b/libatalk/dsi/dsi_getsess.c index 7a6109d1..bcc32da2 100644 --- a/libatalk/dsi/dsi_getsess.c +++ b/libatalk/dsi/dsi_getsess.c @@ -64,17 +64,18 @@ afp_child_t *dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval break; default: /* parent */ - /* using SIGQUIT is hokey, but the child might not have + /* using SIGKILL is hokey, but the child might not have * re-established its signal handler for SIGTERM yet. */ - if ((child = server_child_add(serv_children, CHILD_DSIFORK, pid, ipc_fds)) == NULL) { + close(ipc_fds[1]); + if ((child = server_child_add(serv_children, CHILD_DSIFORK, pid, ipc_fds[0])) == NULL) { LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno)); + close(ipc_fds[0]); dsi->header.dsi_flags = DSIFL_REPLY; dsi->header.dsi_code = DSIERR_SERVBUSY; dsi_send(dsi); dsi->header.dsi_code = DSIERR_OK; - kill(pid, SIGQUIT); + kill(pid, SIGKILL); } - close(ipc_fds[1]); dsi->proto_close(dsi); return child; } @@ -91,6 +92,7 @@ afp_child_t *dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval } /* get rid of some stuff */ + dsi->AFPobj->ipc_fd = ipc_fds[1]; close(ipc_fds[0]); close(dsi->serversock); server_child_free(serv_children); @@ -124,11 +126,7 @@ afp_child_t *dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval dsi->timer.it_interval.tv_usec = dsi->timer.it_value.tv_usec = 0; signal(SIGPIPE, SIG_IGN); /* we catch these ourselves */ dsi_opensession(dsi); - if ((child = calloc(1, sizeof(afp_child_t))) == NULL) - exit(EXITERR_SYS); - child->ipc_fds[1] = ipc_fds[1]; - return child; - break; + return NULL; default: /* just close */ LOG(log_info, logtype_dsi, "DSIUnknown %d", dsi->header.dsi_command); diff --git a/libatalk/util/server_child.c b/libatalk/util/server_child.c index 7fea57c8..86f05a09 100644 --- a/libatalk/util/server_child.c +++ b/libatalk/util/server_child.c @@ -121,7 +121,7 @@ server_child *server_child_alloc(const int connections, const int nforks) * add a child * @return pointer to struct server_child_data on success, NULL on error */ -afp_child_t *server_child_add(server_child *children, int forkid, pid_t pid, uint ipc_fds[2]) +afp_child_t *server_child_add(server_child *children, int forkid, pid_t pid, int ipc_fd) { server_child_fork *fork; afp_child_t *child = NULL; @@ -152,8 +152,7 @@ afp_child_t *server_child_add(server_child *children, int forkid, pid_t pid, uin child->pid = pid; child->valid = 0; child->killed = 0; - child->ipc_fds[0] = ipc_fds[0]; - child->ipc_fds[1] = ipc_fds[1]; + child->ipc_fd = ipc_fd; hash_child(fork->table, child); children->count++; @@ -181,15 +180,9 @@ int server_child_remove(server_child *children, const int forkid, pid_t pid) } /* In main:child_handler() we need the fd in order to remove it from the pollfd set */ - fd = child->ipc_fds[0]; - if (child->ipc_fds[0] != -1) { - close(child->ipc_fds[0]); - child->ipc_fds[0] = -1; - } - if (child->ipc_fds[1] != -1) { - close(child->ipc_fds[1]); - child->ipc_fds[1] = -1; - } + fd = child->ipc_fd; + if (fd != -1) + close(fd); free(child); children->count--; @@ -207,7 +200,6 @@ void server_child_free(server_child *children) server_child_fork *fork; struct server_child_data *child, *tmp; int i, j; - pid_t pid = getpid(); for (i = 0; i < children->nforks; i++) { fork = (server_child_fork *) children->fork + i; @@ -215,9 +207,7 @@ void server_child_free(server_child *children) child = fork->table[j]; /* start at the beginning */ while (child) { tmp = child->next; - - if (child->ipc_fds[0] != -1) - close(child->ipc_fds[0]); + close(child->ipc_fd); if (child->clientid) { free(child->clientid); } @@ -309,12 +299,12 @@ int server_child_transfer_session(server_child *children, LOG(log_note, logtype_default, "Reconnect: transfering session to child[%u]", pid); - if (writet(child->ipc_fds[0], &DSI_requestID, 2, 0, 2) != 2) { + if (writet(child->ipc_fd, &DSI_requestID, 2, 0, 2) != 2) { LOG(log_error, logtype_default, "Reconnect: error sending DSI id to child[%u]", pid); EC_STATUS(-1); goto EC_CLEANUP; } - EC_ZERO_LOG(send_fd(child->ipc_fds[0], afp_socket)); + EC_ZERO_LOG(send_fd(child->ipc_fd, afp_socket)); EC_ZERO_LOG(kill(pid, SIGURG)); EC_STATUS(1); -- 2.39.2