Skip to content

Commit

Permalink
fix some bugs found in 1.0pre1 testing
Browse files Browse the repository at this point in the history
  • Loading branch information
garlick committed Mar 17, 2010
1 parent a2217f4 commit 930b6d3
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 136 deletions.
9 changes: 8 additions & 1 deletion ChangeLog
@@ -1,11 +1,18 @@
2010-03-16 Jim Garlick <garlick@llnl.gov>
2010-03-17 Jim Garlick <garlick@llnl.gov>

* diod/diod.c, diodctl/diodctl.c : Daemonize before listening or
daemon () closes our ports for us. Remove log complaints about chdir
to rundir.

* diodctl/ops.c : Include a log message for all attach failures.

* test/Makefile.am : Remove test directories only if they exist.

* common/diod_sock.[ch], diodctl/serv.c : Fix a bug in the testing
of the connection to private diod server. Also restructure the code
to test all of the listen addresses until successful. Improve
logging on failure.

2010-03-16 Jim Garlick <garlick@llnl.gov>

* : tag 1.0-pre1
213 changes: 113 additions & 100 deletions common/diod_sock.c
Expand Up @@ -44,6 +44,7 @@
#include <tcpd.h>
#endif
#include <poll.h>
#include <assert.h>

#include "npfs.h"
#include "list.h"
Expand All @@ -57,12 +58,14 @@ int allow_severity = LOG_INFO;
int deny_severity = LOG_WARNING;
#define DAEMON_NAME "diod"

#define BASE_PORT 1942 /* arbitrary non-privileged port */
#define MAX_PORT (BASE_PORT + 1024)

/* Open/bind sockets for all addresses that can be associated with host:port,
* and expand pollfd array (*fdsp) to contain the new file descriptors,
* updating its size (*nfdsp) also.
* Return the number of file descriptors added (can be 0).
* This is a helper for diod_sock_listen_hostport_list ().
*/
static int
_setup_one (char *host, char *port, struct pollfd **fdsp, int *nfdsp,
int quiet)
_setup_one (char *host, char *port, struct pollfd **fdsp, int *nfdsp, int flags)
{
struct addrinfo hints, *res = NULL, *r;
int opt, i, error, fd, nents = 0;
Expand Down Expand Up @@ -104,7 +107,8 @@ _setup_one (char *host, char *port, struct pollfd **fdsp, int *nfdsp,
continue;
}
if (bind (fd, r->ai_addr, r->ai_addrlen) < 0) {
err ("bind: %s:%s", host, port);
if (errno != EADDRINUSE || !(flags & DIOD_SOCK_QUIET_EADDRINUSE))
err ("bind: %s:%s", host, port);
close (fd);
continue;
}
Expand All @@ -120,58 +124,57 @@ _setup_one (char *host, char *port, struct pollfd **fdsp, int *nfdsp,
return ret;
}

/* Bind to sockets associated with host:port name.
* Fd's are placed in pollfd array (allocated/expanded).
* Returns 0 on failure, nonzero on success.
*/
int
diod_sock_setup_one (char *host, char *port, struct pollfd **fdsp, int *nfdsp)
static int
_listen_fds (struct pollfd *fds, int nfds)
{
return _setup_one (host, port, fdsp, nfdsp, 0);
int ret = 0;
int i;

for (i = 0; i < nfds; i++) {
if (listen (fds[i].fd, 5) == 0)
ret++;
}
return ret;
}

/* Bind to sockets associated with host:port name, where port is
* dynamically allocated between BASE_PORT and MAX_PORT.
* Fd's are placed in pollfd array (allocated/expanded).
* Returns 0 on failure, nonzero on success.
* A port string is placed in pp (caller must free).
/* Set up listen ports based on list of host:port strings.
* If nport is non-NULL, use it in place of host:port ports.
* Return the number of file descriptors opened (can return 0).
*/
int
diod_sock_setup_alloc (char *host, struct pollfd **fdsp, int *nfdsp, char **pp)
diod_sock_listen_hostport_list (List l, struct pollfd **fdsp, int *nfdsp,
char *nport, int flags)
{
int i = BASE_PORT;
char *port;
int ret = 0;
ListIterator itr;
char *hostport, *host, *port;
int n, ret = 0;

if (!(port = malloc (NI_MAXSERV))) {
if (!(itr = list_iterator_create(l))) {
msg ("out of memory");
goto done;
}
for (i = BASE_PORT; i < MAX_PORT; i++) {
snprintf (port, NI_MAXSERV, "%d", i);
if (_setup_one (host, port, fdsp, nfdsp, 1)) {
ret = 1;
break;
while ((hostport = list_next(itr))) {
if (!(host = strdup (hostport))) {
msg ("out of memory");
goto done;
}
port = strchr (host, ':');
assert (port != NULL);
*port++ = '\0';
if (nport)
port = nport;
if ((n = _setup_one (host, port, fdsp, nfdsp, flags)) == 0) {
free (host);
goto done;
}
ret += n;
free (host);
}
if (!(flags & DIOD_SOCK_SKIPLISTEN))
ret = _listen_fds (*fdsp, *nfdsp);
done:
if (ret == 1) {
*pp = port;
} else if (port)
free (port);
return ret;
}

int
diod_sock_listen (struct pollfd *fds, int nfds)
{
int ret = 0;
int i;

for (i = 0; i < nfds; i++) {
if (listen (fds[i].fd, 5) == 0)
ret++;
}
if (itr)
list_iterator_destroy(itr);
return ret;
}

Expand All @@ -180,7 +183,7 @@ diod_sock_listen (struct pollfd *fds, int nfds)
* Return 0 on failure, nonzero on success.
*/
int
diod_sock_listen_fds (struct pollfd **fdsp, int *nfdsp, int nfds)
diod_sock_listen_first_nfds (struct pollfd **fdsp, int *nfdsp, int nfds)
{
struct pollfd *fds;
int i;
Expand All @@ -195,43 +198,13 @@ diod_sock_listen_fds (struct pollfd **fdsp, int *nfdsp, int nfds)
*nfdsp = nfds;
*fdsp = fds;

ret = diod_sock_listen (fds, nfds);
done:
return ret;
}

/* Set up listen ports based on list of host:port strings.
* Return 0 on failure, nonzero on success.
*/
int
diod_sock_listen_list (struct pollfd **fdsp, int *nfdsp, List l)
{
ListIterator itr;
char *hostport, *host, *port;
int ret = 0;

if (!(itr = list_iterator_create(l))) {
msg ("out of memory");
goto done;
}
while ((hostport = list_next(itr))) {
if (!(host = strdup (hostport))) {
msg ("out of memory");
goto done;
}
port = strchr (host, ':');
*port++ = '\0';
if (diod_sock_setup_one (host, port, fdsp, nfdsp) == 0)
goto done;
}
list_iterator_destroy(itr);

ret = diod_sock_listen (*fdsp, *nfdsp);
ret = _listen_fds (fds, nfds);
done:
return ret;
}

/* Accept one connection on a ready fd and pass it on to the npfs 9P engine.
* This is a helper for diod_sock_accept_loop ().
*/
static void
_accept_one (Npsrv *srv, int fd, int wrap)
Expand Down Expand Up @@ -287,11 +260,10 @@ _accept_one (Npsrv *srv, int fd, int wrap)
diod_trans_destroy (trans);
return;
}

//msg ("accepted connection from %s on port %s", host, svc);
}

/* Loop accepting and handling new connections.
/* Loop accepting and handling new 9P connections.
* Both diod and diodctl use this.
*/
void
diod_sock_accept_loop (Npsrv *srv, struct pollfd *fds, int nfds, int wrap)
Expand All @@ -317,44 +289,85 @@ diod_sock_accept_loop (Npsrv *srv, struct pollfd *fds, int nfds, int wrap)
/*NOTREACHED*/
}

int
diod_sock_connect (char *host, char *port, int maxtries, int retry_wait_ms)
/* Try to connect to host:port. Return 1 on success, 0 on failure.
*/
static int
_connect_one (char *host, char *port)
{
int i, error, fd = -1;
int error, fd = -1;
struct addrinfo hints, *res = NULL, *r;

memset (&hints, 0, sizeof (hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

if ((error = getaddrinfo (host, port, &hints, &res)) != 0) {
msg ("getaddrinfo localhost:%s: %s", port, gai_strerror (error));
msg ("getaddrinfo %s:%s", host, port, gai_strerror (error));
goto done;
}
if (!res) {
msg ("could not look up %s:%s", host, port);
goto done;
}
for (i = 0; i < maxtries && fd == -1; i++) {
for (r = res; r != NULL && fd == -1; r = r->ai_next) {
if ((fd = socket (r->ai_family, r->ai_socktype, 0)) < 0)
continue;
if (connect (fd, r->ai_addr, r->ai_addrlen) < 0) {
close (fd);
fd = -1;
}
for (r = res; r != NULL && fd == -1; r = r->ai_next) {
if ((fd = socket (r->ai_family, r->ai_socktype, 0)) < 0)
continue;
if (connect (fd, r->ai_addr, r->ai_addrlen) < 0) {
close (fd);
fd = -1;
}
if (fd == -1)
usleep (1000 * retry_wait_ms);
}
if (fd == -1) {
msg ("%d connect attempts to %s:%s failed", i, host, port);
if (res)
freeaddrinfo (res);
done:
if (fd != -1) {
close (fd);
return 1;
}
return 0;
}

/* Try to connect to any members of host:port list.
* If nport is non-NULL, substitute that for :port.
* Return 1 on success, 0 on failure.
*/
int
diod_sock_tryconnect (List l, char *nport, int maxtries, int retry_wait_ms)
{
int i, res = 0;
char *hostport, *host, *port;
ListIterator itr;

if (!(itr = list_iterator_create(l))) {
msg ("out of memory");
goto done;
}
for (i = 0; i < maxtries; i++) {
if (i > 0) {
usleep (1000 * retry_wait_ms);
list_iterator_reset (itr);
}
while ((hostport = list_next(itr))) {
if (!(host = strdup (hostport))) {
msg ("out of memory");
goto done;
}
port = strchr (host, ':');
assert (port != NULL);
*port++ = '\0';
if (nport)
port = nport;
if ((res = _connect_one (host, port))) {
free (host);
goto done;
}
free (host);
}
}
done:
if (res)
freeaddrinfo (res);
return fd;
if (itr)
list_iterator_destroy(itr);
return res;
}

/*
Expand Down
21 changes: 12 additions & 9 deletions common/diod_sock.h
@@ -1,13 +1,16 @@
int diod_sock_listen (struct pollfd *fds, int nfds);
int diod_sock_listen_fds (struct pollfd **fdsp, int *nfdsp, int nfds);
int diod_sock_listen_list (struct pollfd **fdsp, int *nfdsp, List l);
enum {
DIOD_SOCK_SKIPLISTEN=1,
DIOD_SOCK_QUIET_EADDRINUSE=2,
};

int diod_sock_listen_first_nfds (struct pollfd **fdsp, int *nfdsp, int nfds);

int diod_sock_listen_hostport_list (List l, struct pollfd **fdsp, int *nfdsp,
char *nport, int flags);

void diod_sock_accept_loop (Npsrv *srv, struct pollfd *fds, int nfds, int wrap);
int diod_sock_setup_one (char *host, char *port, struct pollfd **fdsp,
int *nfdsp);
int diod_sock_setup_alloc (char *host, struct pollfd **fdsp, int *nfdsp,
char **pp);
int diod_sock_connect (char *host, char *port,
int maxtries, int retry_wait_ms);

int diod_sock_tryconnect (List l, char *port, int maxtries, int retry_wait_ms);

/*
* vi:tabstop=4 shiftwidth=4 expandtab
Expand Down
6 changes: 4 additions & 2 deletions diod/diod.c
Expand Up @@ -121,6 +121,7 @@ main(int argc, char **argv)
struct pollfd *fds = NULL;
int nfds = 0;
uid_t uid;
List hplist;

diod_log_init (argv[0]);
if (!isatty (STDERR_FILENO))
Expand Down Expand Up @@ -236,10 +237,11 @@ main(int argc, char **argv)
if (!srv)
msg_exit ("out of memory");
if (Fopt) {
if (!diod_sock_listen_fds (&fds, &nfds, Fopt))
if (!diod_sock_listen_first_nfds (&fds, &nfds, Fopt))
msg_exit ("failed to set up listen ports");
} else {
if (!diod_sock_listen_list (&fds, &nfds, diod_conf_get_diodlisten ()))
hplist = diod_conf_get_diodlisten ();
if (!diod_sock_listen_hostport_list (hplist, &fds, &nfds, NULL, 0))
msg_exit ("failed to set up listen ports");
}

Expand Down
5 changes: 4 additions & 1 deletion diodctl/diodctl.c
Expand Up @@ -126,6 +126,7 @@ main(int argc, char **argv)
char *Dopt = NULL;
struct pollfd *fds = NULL;
int nfds = 0;
List hplist;

diod_log_init (argv[0]);
if (!isatty (STDERR_FILENO))
Expand Down Expand Up @@ -218,7 +219,9 @@ main(int argc, char **argv)
srv = np_srv_create (diod_conf_get_nwthreads ());
if (!srv)
msg_exit ("out of memory");
if (!diod_sock_listen_list (&fds, &nfds, diod_conf_get_diodctllisten ()))

hplist = diod_conf_get_diodctllisten ();
if (!diod_sock_listen_hostport_list (hplist, &fds, &nfds, NULL, 0))
msg_exit ("failed to set up listen ports");

/* FIXME: temp file created by diod_conf_mkconfig () needs cleanup */
Expand Down

0 comments on commit 930b6d3

Please sign in to comment.