aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/diag.c1
-rw-r--r--src/meta1gram.y1
-rw-r--r--src/pies.c12
-rw-r--r--src/pies.h10
-rw-r--r--src/progman.c10
-rw-r--r--src/socket.c146
6 files changed, 113 insertions, 67 deletions
diff --git a/src/diag.c b/src/diag.c
index 8ae3911..c377b45 100644
--- a/src/diag.c
+++ b/src/diag.c
@@ -28,6 +28,7 @@ syslog_printer (int prio, const char *fmt, va_list ap)
#else
char buf[128];
vsnprintf (buf, sizeof buf, fmt, ap);
+ syslog (prio, "%s", buf);
#endif
}
diff --git a/src/meta1gram.y b/src/meta1gram.y
index db92d61..5fa143b 100644
--- a/src/meta1gram.y
+++ b/src/meta1gram.y
@@ -365,7 +365,6 @@ meta1_translate (struct meta1_stmt *stmt)
}
comp->privs.allgroups = 1;
comp->dir = META1_QUEUE_DIR ();
- comp->settle_timeout = 1;
comp->redir[RETR_ERR].type = redir_file;
comp->redir[RETR_ERR].v.file = xasprintf ("%s/%s.log",
META1_QUEUE_DIR (),
diff --git a/src/pies.c b/src/pies.c
index d4a8013..f2ed365 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -776,11 +776,11 @@ struct grecs_keyword component_keywords[] = {
grecs_type_bool, NULL, offsetof (struct component, disabled),
NULL,
},
- {"settle-timeout",
+ {"pass-fd-timeout",
NULL,
- N_("Time to wait before starting this component."),
+ N_("Time to wait for pass-fd socket to become available."),
grecs_type_uint, NULL,
- offsetof (struct component, settle_timeout),
+ offsetof (struct component, pass_fd_timeout),
NULL,
},
{"precious",
@@ -1856,6 +1856,9 @@ main (int argc, char **argv)
exit (EX_USAGE);
}
+ if (!foreground)
+ log_setup (log_to_stderr = 0);
+
logmsg (LOG_INFO, _("%s starting"), program_version);
if (!foreground)
@@ -1917,9 +1920,10 @@ main (int argc, char **argv)
if (action == ACTION_RESTART && argv[0][0] == '/')
{
+ int minfd = log_to_stderr ? 2 : 0;
int i;
- for (i = getmaxfd (); i > 0; i--)
+ for (i = getmaxfd (); i > minfd; i--)
close (i);
remove_pidfile (pidfile);
diff --git a/src/pies.h b/src/pies.h
index 751c2a2..9b8ee2d 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -61,6 +61,8 @@
#define SLEEPTIME 5*60
#define MAXSPAWN 10
+#define DEFAULT_PASS_FD_TIMEOUT 5
+
#define RETR_OUT 0
#define RETR_ERR 1
@@ -134,7 +136,7 @@ enum pies_comp_mode
struct component
{
- enum pies_comp_mode mode;
+ enum pies_comp_mode mode;
char *tag; /* Entry tag (for diagnostics purposes) */
char *program; /* Program name */
char **argv; /* Program command line */
@@ -142,8 +144,6 @@ struct component
char *dir; /* Working directory */
gl_list_t prereq; /* Prerequisites */
gl_list_t depend; /* Dependency targets */
- unsigned settle_timeout; /* Time needed for started prerequisites to
- settle */
/* FIXME: disabled and precious can be encoded as bits in mode */
int disabled; /* The componenet is disabled */
int precious; /* The component is precious (cannot be disabled) */
@@ -155,6 +155,8 @@ struct component
(if mode != pies_comp_exec) */
char *pass_fd_socket; /* Socket to pass fd on
(if mode == pies_comp_pass_fd) */
+ unsigned pass_fd_timeout; /* Maximum time to wait for pass_fd socket to
+ become available. */
pies_acl_t acl;
/* Redirectors: */
int facility; /* Syslog facility. */
@@ -239,7 +241,7 @@ const char * pies_url_get_arg (struct pies_url *url, const char *argname);
void pies_pause (void);
int register_listener (int fd);
-int pass_fd (const char *socket, int fd);
+int pass_fd (const char *socket, int fd, unsigned time_out);
int create_socket (struct pies_url *url, const char *user, mode_t umask);
diff --git a/src/progman.c b/src/progman.c
index 7438837..cc107f7 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -773,8 +773,9 @@ prog_start (struct prog *prog)
default:
if (prog->v.p.comp->mode == pies_comp_pass_fd)
{
- sleep(1);
- pass_fd (prog->v.p.comp->pass_fd_socket, prog->v.p.socket);
+ pass_fd (prog->v.p.comp->pass_fd_socket, prog->v.p.socket,
+ prog->v.p.comp->pass_fd_timeout ?
+ prog->v.p.comp->pass_fd_timeout : DEFAULT_PASS_FD_TIMEOUT);
/* FIXME: Error code */;
}
if (prog->v.p.comp->mode != pies_comp_exec)
@@ -1164,7 +1165,6 @@ prog_start_prerequisites (struct prog *prog)
{
int i;
int ret;
- unsigned settle_timeout = 0;
if (!prog->prereq)
return 0; /* Ok to startup */
@@ -1203,11 +1203,7 @@ prog_start_prerequisites (struct prog *prog)
prog_start (prog_lookup_by_tag (prog->prereq[i]));
if (!(dp->v.p.status == status_enabled && dp->pid))
ret = 1;
- else
- settle_timeout = prog->v.p.comp->settle_timeout;
}
- if (ret == 0 && settle_timeout)
- sleep (settle_timeout);
return ret;
}
diff --git a/src/socket.c b/src/socket.c
index 8f32ae7..1aa1256 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -249,37 +249,6 @@ create_socket (struct pies_url *url, const char *user, mode_t umaskval)
}
static int
-open_unix_socket (const char *socket_name)
-{
- int fd;
- struct sockaddr_un addr;
-
- if (strlen (socket_name) > sizeof addr.sun_path)
- {
- logmsg (LOG_ERR, _("%s: UNIX socket name too long"), socket_name);
- return -1;
- }
-
- fd = socket (PF_UNIX, SOCK_STREAM, 0);
- if (fd == -1)
- {
- logmsg (LOG_ERR, "socket: %s", strerror (errno));
- return -1;
- }
- addr.sun_family = AF_UNIX;
- strcpy (addr.sun_path, socket_name);
-
- if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)))
- {
- logmsg (LOG_ERR, _("%s: connect failed: %s"), socket_name, strerror (errno));
- close (fd);
- return -1;
- }
-
- return fd;
-}
-
-static int
pass_fd0 (int fd, int payload)
{
struct msghdr msg;
@@ -324,40 +293,115 @@ pass_fd0 (int fd, int payload)
}
int
-pass_fd (const char *socket, int fd)
+pass_fd (const char *socket_name, int fd, unsigned maxtime)
{
- int i;
- struct stat st;
+ enum { fds_init, fds_open, fds_connected, fds_ready } state = fds_init;
+ static char *fds_descr[] = { "init", "open", "connected", "ready" };
+ time_t start = time (NULL);
+ int sockfd = -1;
+ int res = -1;
+ struct sockaddr_un addr;
- for (i = 0; i < 10; i++)
+ if (strlen (socket_name) > sizeof addr.sun_path)
{
- if (stat (socket, &st) == 0)
+ logmsg (LOG_ERR, _("%s: UNIX socket name too long"), socket_name);
+ return -1;
+ }
+ addr.sun_family = AF_UNIX;
+ strcpy (addr.sun_path, socket_name);
+
+ for (;;)
+ {
+ time_t now = time (NULL);
+
+ if (now - start > maxtime)
{
- int rc;
- int sockfd;
-
- if (!S_ISSOCK (st.st_mode))
+ logmsg (LOG_ERR, _("pass-fd timed out in state %s"),
+ fds_descr[state]);
+ break;
+ }
+
+ if (state == fds_init)
+ {
+ struct stat st;
+
+ if (stat (socket_name, &st) == 0)
+ {
+ if (!S_ISSOCK (st.st_mode))
+ {
+ logmsg (LOG_ERR, _("%s: not a socket"), socket_name);
+ break;
+ }
+
+ sockfd = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (sockfd == -1)
+ {
+ if (errno == EINTR)
+ continue;
+ logmsg (LOG_ERR, "socket: %s", strerror (errno));
+ break;
+ }
+ state = fds_open;
+ }
+ else if (errno != ENOENT)
{
- logmsg (LOG_ERR, _("%s: not a socket"), socket);
+ logmsg (LOG_ERR, _("cannot stat %s: %s"),
+ socket_name, strerror (errno));
break;
}
- sockfd = open_unix_socket (socket);
- if (sockfd == -1)
- rc = 1;
- else
+ }
+
+ if (state == fds_open)
+ {
+ if (connect (sockfd, (struct sockaddr *) &addr, sizeof (addr)))
+ {
+ switch (errno)
+ {
+ case EINTR:
+ case ECONNREFUSED:
+ case EAGAIN:
+ continue;
+ }
+ logmsg (LOG_ERR, _("%s: connect failed: %s"),
+ socket_name, strerror (errno));
+ break;
+ }
+ state = fds_connected;
+ }
+
+ if (state == fds_connected)
+ {
+ int rc;
+ fd_set fds;
+ struct timeval tv;
+
+ FD_ZERO (&fds);
+ FD_SET (sockfd, &fds);
+ tv.tv_usec = 0;
+ tv.tv_sec = maxtime - (now - start);
+ rc = select (sockfd + 1, NULL, &fds, NULL, &tv);
+ if (rc == 0)
+ continue;
+ if (rc < 0)
{
- rc = pass_fd0 (sockfd, fd);
- close (sockfd);
+ if (errno == EINTR)
+ continue;
+ logmsg (LOG_ERR, _("select failed: %s"), strerror (errno));
+ break;
}
- return rc;
+ state = fds_ready;
}
- if (errno != ENOENT)
+
+ if (state == fds_ready)
{
- logmsg (LOG_ERR, _("cannot stat %s: %s"), socket, strerror (errno));
+ res = pass_fd0 (sockfd, fd);
break;
}
}
- return -1;
+
+ if (sockfd >= 0)
+ close (sockfd);
+ return res;
}

Return to:

Send suggestions and report system problems to the System administrator.