Skip to content

Commit

Permalink
Remove continous service feature
Browse files Browse the repository at this point in the history
  • Loading branch information
slowfranklin committed Feb 6, 2013
1 parent ab6471d commit fb751e8
Show file tree
Hide file tree
Showing 14 changed files with 152 additions and 402 deletions.
19 changes: 1 addition & 18 deletions etc/afpd/afp_dsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,23 +140,6 @@ static void afp_dsi_die(int sig)
}
}

/* SIGQUIT handler */
static void ipc_reconnect_handler(int sig _U_)
{
if (reconnect_ipc(AFPobj) != 0) {
LOG(log_error, logtype_afpd, "ipc_reconnect_handler: failed IPC reconnect");
afp_dsi_close(AFPobj);
exit(EXITERR_SYS);
}

if (ipc_child_write(AFPobj->ipc_fd, IPC_GETSESSION, AFPobj->sinfo.clientid_len, AFPobj->sinfo.clientid) != 0) {
LOG(log_error, logtype_afpd, "ipc_reconnect_handler: failed IPC ID resend");
afp_dsi_close(AFPobj);
exit(EXITERR_SYS);
}
LOG(log_note, logtype_afpd, "ipc_reconnect_handler: IPC reconnect done");
}

/* SIGURG handler (primary reconnect) */
static void afp_dsi_transfer_session(int sig _U_)
{
Expand Down Expand Up @@ -407,7 +390,7 @@ void afp_over_dsi_sighandlers(AFPObj *obj)
}

/* install SIGQUIT */
action.sa_handler = ipc_reconnect_handler;
action.sa_handler = afp_dsi_die;
if ( sigaction(SIGQUIT, &action, NULL ) < 0 ) {
LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
afp_dsi_die(EXITERR_SYS);
Expand Down
100 changes: 16 additions & 84 deletions etc/afpd/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
unsigned char nologin = 0;

static AFPObj obj;
static server_child *server_children;
static server_child_t *server_children;
static sig_atomic_t reloadconfig = 0;
static sig_atomic_t gotsigchld = 0;

Expand All @@ -54,9 +54,8 @@ static struct pollfd *fdset;
static struct polldata *polldata;
static int fdset_size; /* current allocated size */
static int fdset_used; /* number of used elements */
static int disasociated_ipc_fd; /* disasociated sessions uses this fd for IPC */

static afp_child_t *dsi_start(AFPObj *obj, DSI *dsi, server_child *server_children);
static afp_child_t *dsi_start(AFPObj *obj, DSI *dsi, server_child_t *server_children);

static void afp_exit(int ret)
{
Expand All @@ -81,16 +80,6 @@ static void fd_set_listening_sockets(const AFPObj *config)
LISTEN_FD,
dsi);
}

if (config->options.flags & OPTION_KEEPSESSIONS)
fdset_add_fd(config->options.connections + AFP_LISTENERS + FDSET_SAFETY,
&fdset,
&polldata,
&fdset_used,
&fdset_size,
disasociated_ipc_fd,
DISASOCIATED_IPC_FD,
NULL);
}

static void fd_reset_listening_sockets(const AFPObj *config)
Expand All @@ -100,9 +89,6 @@ static void fd_reset_listening_sockets(const AFPObj *config)
for (dsi = config->dsi; dsi; dsi = dsi->next) {
fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, dsi->serversock);
}

if (config->options.flags & OPTION_KEEPSESSIONS)
fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, disasociated_ipc_fd);
}

/* ------------------ */
Expand All @@ -112,22 +98,9 @@ static void afp_goaway(int sig)

case SIGTERM:
case SIGQUIT:
switch (sig) {
case SIGTERM:
LOG(log_note, logtype_afpd, "AFP Server shutting down on SIGTERM");
break;
case SIGQUIT:
if (obj.options.flags & OPTION_KEEPSESSIONS) {
LOG(log_note, logtype_afpd, "AFP Server shutting down on SIGQUIT, NOT disconnecting clients");
} else {
LOG(log_note, logtype_afpd, "AFP Server shutting down on SIGQUIT");
sig = SIGTERM;
}
break;
}
LOG(log_note, logtype_afpd, "AFP Server shutting down");
if (server_children)
server_child_kill(server_children, CHILD_DSIFORK, sig);

server_child_kill(server_children, SIGTERM);
_exit(0);
break;

Expand All @@ -137,7 +110,7 @@ static void afp_goaway(int sig)
LOG(log_info, logtype_afpd, "disallowing logins");

if (server_children)
server_child_kill(server_children, CHILD_DSIFORK, sig);
server_child_kill(server_children, sig);
break;

case SIGHUP :
Expand Down Expand Up @@ -167,11 +140,9 @@ static void child_handler(void)
#endif /* ! WAIT_ANY */

while ((pid = waitpid(WAIT_ANY, &status, WNOHANG)) > 0) {
for (i = 0; i < server_children->nforks; i++) {
if ((fd = server_child_remove(server_children, i, pid)) != -1) {
fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, fd);
break;
}
if ((fd = server_child_remove(server_children, pid)) != -1) {
fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, fd);
break;
}

if (WIFEXITED(status)) {
Expand Down Expand Up @@ -232,7 +203,7 @@ int main(int ac, char **av)
/* install child handler for asp and dsi. we do this before afp_goaway
* as afp_goaway references stuff from here.
* XXX: this should really be setup after the initial connections. */
if (!(server_children = server_child_alloc(obj.options.connections, CHILD_NFORKS))) {
if (!(server_children = server_child_alloc(obj.options.connections))) {
LOG(log_error, logtype_afpd, "main: server_child alloc: %s", strerror(errno) );
afp_exit(EXITERR_SYS);
}
Expand Down Expand Up @@ -350,12 +321,6 @@ int main(int ac, char **av)
cnid_init();

/* watch atp, dsi sockets and ipc parent/child file descriptor. */

if (obj.options.flags & OPTION_KEEPSESSIONS) {
LOG(log_note, logtype_afpd, "Activating continous service");
disasociated_ipc_fd = ipc_server_uds(_PATH_AFP_IPC);
}

fd_set_listening_sockets(&obj);

/* set limits */
Expand Down Expand Up @@ -433,54 +398,21 @@ int main(int ac, char **av)
&polldata,
&fdset_used,
&fdset_size,
child->ipc_fd,
child->afpch_ipc_fd,
IPC_FD,
child);
}
break;

case IPC_FD:
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_fd) != 0) {
fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fd);
close(child->ipc_fd);
child->ipc_fd = -1;
if ((obj.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);
}
}
break;

case DISASOCIATED_IPC_FD:
LOG(log_debug, logtype_afpd, "main: IPC reconnect request");
if ((recon_ipc_fd = accept(disasociated_ipc_fd, NULL, NULL)) == -1) {
LOG(log_error, logtype_afpd, "main: accept: %s", strerror(errno));
break;
}
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(recon_ipc_fd);
break;
}
LOG(log_note, logtype_afpd, "main: IPC reconnect from pid [%u]", pid);
LOG(log_debug, logtype_afpd, "main: IPC request from child[%u]", child->afpch_pid);

if ((child = server_child_add(server_children, CHILD_DSIFORK, pid, recon_ipc_fd)) == NULL) {
LOG(log_error, logtype_afpd, "main: server_child_add");
close(recon_ipc_fd);
break;
if (ipc_server_read(server_children, child->afpch_ipc_fd) != 0) {
fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->afpch_ipc_fd);
close(child->afpch_ipc_fd);
child->afpch_ipc_fd = -1;
}
child->disasociated = 1;
fdset_add_fd(obj.options.connections + AFP_LISTENERS + FDSET_SAFETY,
&fdset,
&polldata,
&fdset_used,
&fdset_size,
recon_ipc_fd,
IPC_FD,
child);
break;

default:
Expand All @@ -494,7 +426,7 @@ int main(int ac, char **av)
return 0;
}

static afp_child_t *dsi_start(AFPObj *obj, DSI *dsi, server_child *server_children)
static afp_child_t *dsi_start(AFPObj *obj, DSI *dsi, server_child_t *server_children)
{
afp_child_t *child = NULL;

Expand Down
2 changes: 1 addition & 1 deletion include/atalk/dsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ extern int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address, con
extern void dsi_free(DSI *dsi);

/* in dsi_getsess.c */
extern int dsi_getsession (DSI *, server_child *, const int, afp_child_t **);
extern int dsi_getsession (DSI *, server_child_t *, const int, afp_child_t **);
extern void dsi_kill (int);


Expand Down
1 change: 0 additions & 1 deletion include/atalk/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
#define OPTION_UUID (1 << 7)
#define OPTION_ACL2MACCESS (1 << 8)
#define OPTION_NOZEROCONF (1 << 9)
#define OPTION_KEEPSESSIONS (1 << 10) /* preserve sessions across master afpd restart with SIGQUIT */
#define OPTION_SHARE_RESERV (1 << 11) /* whether to use Solaris fcntl F_SHARE locks */

#define PASSWD_NONE 0
Expand Down
1 change: 0 additions & 1 deletion include/atalk/paths.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
* netatalk paths
*/
#define _PATH_AFPTKT "/tmp/AFPtktXXXXXX"
#define _PATH_AFP_IPC ATALKPATHCAT(_PATH_LOCKDIR,"afpd_ipc")
#if defined (FHS_COMPATIBILITY) || defined (__NetBSD__) || defined (__OpenBSD__)
# define _PATH_NETATALK_LOCK ATALKPATHCAT(_PATH_LOCKDIR,"netatalk.pid")
#else
Expand Down
67 changes: 34 additions & 33 deletions include/atalk/server_child.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,42 @@
/* useful stuff for child processes. most of this is hidden in
* server_child.c to ease changes in implementation */

#define CHILD_NFORKS 2
#define CHILD_ASPFORK 0
#define CHILD_PAPFORK 0
#define CHILD_DSIFORK 1

typedef struct server_child {
void *fork;
int count, nsessions, nforks;
} server_child;

typedef struct server_child_data {
pid_t pid; /* afpd worker process pid (from the worker afpd process )*/
uid_t uid; /* user id of connected client (from the worker afpd process) */
int valid; /* 1 if we have a clientid */
int killed; /* 1 if we already tried to kill the client */
int disasociated; /* 1 if this is not a child, but a child from a previous afpd master */
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_fd; /* socket for IPC bw afpd parent and childs */
struct server_child_data **prevp, *next;
#define CHILD_HASHSIZE 32

/* One AFP session child process */
typedef struct afp_child {
pid_t afpch_pid; /* afpd worker process pid (from the worker afpd process )*/
uid_t afpch_uid; /* user id of connected client (from the worker afpd process) */
int afpch_valid; /* 1 if we have a clientid */
int afpch_killed; /* 1 if we already tried to kill the client */
uint32_t afpch_time; /* client boot time (from the mac client) */
uint32_t afpch_idlen; /* clientid len (from the Mac client) */
char *afpch_clientid; /* clientid (from the Mac client) */
int afpch_ipc_fd; /* socket for IPC bw afpd parent and childs */
struct afp_child **afpch_prevp;
struct afp_child *afpch_next;
} afp_child_t;

/* Info and table with all AFP session child processes */
typedef struct {
pthread_mutex_t servch_lock; /* Lock */
int servch_count; /* Current count of active AFP sessions */
int servch_nsessions; /* Number of allowed AFP sessions */
afp_child_t *servch_table[CHILD_HASHSIZE]; /* Hashtable with data of AFP sesssions */
void (*servch_cleanup)(const pid_t); /* Cleanup handler */
} server_child_t;

/* 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, int ipc_fd);
extern int server_child_remove (server_child *, const int, const pid_t);
extern void server_child_free (server_child *);

extern void server_child_kill (server_child *, const int, const int);
extern void server_child_kill_one_by_id (server_child *children, const int forkid, const pid_t pid, const uid_t,
const uint32_t len, char *id, uint32_t boottime);
extern int server_child_transfer_session(server_child *children, int forkid, pid_t, uid_t, int, uint16_t);
extern void server_child_setup (server_child *, const int, void (*)(const pid_t));
extern void server_child_handler (server_child *);
extern void server_reset_signal (void);
extern server_child_t *server_child_alloc(int);
extern afp_child_t *server_child_add(server_child_t *, pid_t, int ipc_fd);
extern int server_child_remove(server_child_t *, pid_t);
extern void server_child_free(server_child_t *);

extern void server_child_kill(server_child_t *, int);
extern void server_child_kill_one_by_id(server_child_t *children, pid_t pid, uid_t,
uint32_t len, char *id, uint32_t boottime);
extern int server_child_transfer_session(server_child_t *children, pid_t, uid_t, int, uint16_t);
extern void server_child_handler(server_child_t *);
extern void server_reset_signal(void);

#endif
5 changes: 1 addition & 4 deletions include/atalk/server_ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
#define IPC_DISCOLDSESSION 0
#define IPC_GETSESSION 1

extern int ipc_server_uds(const char *name);
extern int ipc_client_uds(const char *name);
extern int reconnect_ipc(AFPObj *);
extern int ipc_server_read(server_child *children, int fd);
extern int ipc_server_read(server_child_t *children, int fd);
extern int ipc_child_write(int fd, uint16_t command, int len, void *token);

#endif /* IPC_GETSESSION_LOGIN */
2 changes: 1 addition & 1 deletion include/atalk/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ extern void apply_ip_mask(struct sockaddr *ai, int maskbits);
extern int compare_ip(const struct sockaddr *sa1, const struct sockaddr *sa2);

/* Structures and functions dealing with dynamic pollfd arrays */
enum fdtype {IPC_FD, LISTEN_FD, DISASOCIATED_IPC_FD};
enum fdtype {IPC_FD, LISTEN_FD};
struct polldata {
enum fdtype fdtype; /* IPC fd or listening socket fd */
void *data; /* pointer to AFPconfig for listening socket and *
Expand Down
6 changes: 3 additions & 3 deletions libatalk/dsi/dsi_getsess.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* @param childp (w) after fork: parent return pointer to child, child returns NULL
* @returns 0 on sucess, any other value denotes failure
*/
int dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval, afp_child_t **childp)
int dsi_getsession(DSI *dsi, server_child_t *serv_children, int tickleval, afp_child_t **childp)
{
pid_t pid;
int ipc_fds[2];
Expand Down Expand Up @@ -61,7 +61,7 @@ int dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval, afp_chi
/* using SIGKILL is hokey, but the child might not have
* re-established its signal handler for SIGTERM yet. */
close(ipc_fds[1]);
if ((child = server_child_add(serv_children, CHILD_DSIFORK, pid, ipc_fds[0])) == NULL) {
if ((child = server_child_add(serv_children, 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;
Expand All @@ -77,7 +77,7 @@ int dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval, afp_chi

/* child: check number of open connections. this is one off the
* actual count. */
if ((serv_children->count >= serv_children->nsessions) &&
if ((serv_children->servch_count >= serv_children->servch_nsessions) &&
(dsi->header.dsi_command == DSIFUNC_OPEN)) {
LOG(log_info, logtype_dsi, "dsi_getsess: too many connections");
dsi->header.dsi_flags = DSIFL_REPLY;
Expand Down
2 changes: 0 additions & 2 deletions libatalk/util/netatalk_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1641,8 +1641,6 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
options->flags |= OPTION_ANNOUNCESSH;
if (iniparser_getboolean(config, INISEC_GLOBAL, "map acls", 1))
options->flags |= OPTION_ACL2MACCESS;
if (iniparser_getboolean(config, INISEC_GLOBAL, "keep sessions", 0))
options->flags |= OPTION_KEEPSESSIONS;
if (iniparser_getboolean(config, INISEC_GLOBAL, "close vol", 0))
options->flags |= OPTION_CLOSEVOL;
if (!iniparser_getboolean(config, INISEC_GLOBAL, "client polling", 0))
Expand Down
Loading

0 comments on commit fb751e8

Please sign in to comment.