]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-program-client: Use event logging.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 26 Feb 2018 21:27:40 +0000 (22:27 +0100)
committerAki Tuomi <aki.tuomi@dovecot.fi>
Sun, 18 Mar 2018 10:53:18 +0000 (12:53 +0200)
This also makes the overall log messages better match similar messages produced
by other parts of Dovecot.

src/lib-program-client/program-client-local.c
src/lib-program-client/program-client-private.h
src/lib-program-client/program-client-remote.c
src/lib-program-client/program-client.c
src/lib-program-client/program-client.h

index bb6c067cb06c77498dbb161a82ebe9cc46b7531c..46b87dc58bef469b742e231b7acc6a390d783a08 100644 (file)
@@ -29,6 +29,8 @@ struct program_client_local {
        struct child_wait *child_wait;
        struct timeout *to_kill;
 
+       char *bin_path;
+
        pid_t pid;
        int status;
        bool exited:1;
@@ -59,20 +61,22 @@ exec_child(const char *bin_path, const char *const *args,
                out_fd = dev_null_fd;
 
        if (in_fd != STDIN_FILENO && dup2(in_fd, STDIN_FILENO) < 0)
-               i_fatal("dup2(stdin) failed: %m");
+               i_fatal("program %s: dup2(stdin) failed: %m", bin_path);
        if (out_fd != STDOUT_FILENO && dup2(out_fd, STDOUT_FILENO) < 0)
-               i_fatal("dup2(stdout) failed: %m");
+               i_fatal("program %s: dup2(stdout) failed: %m", bin_path);
 
        if (in_fd != STDIN_FILENO && in_fd != dev_null_fd && close(in_fd) < 0)
-               i_error("close(in_fd) failed: %m");
+               i_error("program %s: close(in_fd) failed: %m", bin_path);
        if (out_fd != STDOUT_FILENO && out_fd != dev_null_fd &&
            (out_fd != in_fd) && close(out_fd) < 0)
-               i_error("close(out_fd) failed: %m");
+               i_error("program %s: close(out_fd) failed: %m", bin_path);
 
        /* Drop stderr if requested */
        if (drop_stderr) {
-               if (dup2(dev_null_fd, STDERR_FILENO) < 0)
-                       i_fatal("dup2(stderr) failed: %m");
+               if (dup2(dev_null_fd, STDERR_FILENO) < 0) {
+                       i_fatal("program %s: "
+                               "dup2(stderr) failed: %m", bin_path);
+               }
        }
 
        /* Setup extra fds */
@@ -83,18 +87,22 @@ exec_child(const char *bin_path, const char *const *args,
                        i_assert(efd[1] != STDOUT_FILENO);
                        i_assert(efd[1] != STDERR_FILENO);
                        if (efd[0] != efd[1]) {
-                               if (dup2(efd[0], efd[1]) < 0)
-                                       i_fatal("dup2(extra_fd=%d) failed: %m",
-                                               efd[1]);
+                               if (dup2(efd[0], efd[1]) < 0) {
+                                       i_fatal("program %s"
+                                               "dup2(extra_fd=%d) failed: %m",
+                                               bin_path, efd[1]);
+                               }
                        }
                }
                for(efd = extra_fds; *efd != -1; efd += 2) {
                        if (efd[0] != efd[1] && efd[0] != STDIN_FILENO &&
                            efd[0] != STDOUT_FILENO &&
                            efd[0] != STDERR_FILENO) {
-                               if (close(efd[0]) < 0)
-                                       i_error("close(extra_fd=%d) failed: %m",
-                                               efd[1]);
+                               if (close(efd[0]) < 0) {
+                                       i_error("program %s"
+                                               "close(extra_fd=%d) failed: %m",
+                                               bin_path, efd[1]);
+                               }
                        }
                }
        }
@@ -156,13 +164,13 @@ program_client_local_connect(struct program_client *pclient)
        /* create normal I/O fds */
        if (pclient->input != NULL) {
                if (pipe(fd_in) < 0) {
-                       i_error("pipe(in) failed: %m");
+                       e_error(pclient->event, "pipe(in) failed: %m");
                        return -1;
                }
        }
        if (pclient->output != NULL) {
                if (pipe(fd_out) < 0) {
-                       i_error("pipe(out) failed: %m");
+                       e_error(pclient->event, "pipe(out) failed: %m");
                        return -1;
                }
        }
@@ -178,7 +186,8 @@ program_client_local_connect(struct program_client *pclient)
                        child_extra_fds = t_new(int, xfd_count * 2 + 1);
                        for(i = 0; i < xfd_count; i++) {
                                if (pipe(extra_fd) < 0) {
-                                       i_error("pipe(extra=%d) failed: %m",
+                                       e_error(pclient->event,
+                                               "pipe(extra=%d) failed: %m",
                                                extra_fd[1]);
                                        return -1;
                                }
@@ -192,28 +201,34 @@ program_client_local_connect(struct program_client *pclient)
 
        /* fork child */
        if ((plclient->pid = fork()) == (pid_t)-1) {
-               i_error("fork() failed: %m");
+               e_error(pclient->event, "fork() failed: %m");
 
                /* clean up */
                if (fd_in[0] >= 0 && close(fd_in[0]) < 0) {
-                       i_error("close(pipe:in:rd) failed: %m");
+                       e_error(pclient->event,
+                               "close(pipe:in:rd) failed: %m");
                }
                if (fd_in[1] >= 0 && close(fd_in[1]) < 0) {
-                       i_error("close(pipe:in:wr) failed: %m");
+                       e_error(pclient->event,
+                               "close(pipe:in:wr) failed: %m");
                }
                if (fd_out[0] >= 0 && close(fd_out[0]) < 0) {
-                       i_error("close(pipe:out:rd) failed: %m");
+                       e_error(pclient->event,
+                               "close(pipe:out:rd) failed: %m");
                }
                if (fd_out[1] >= 0 && close(fd_out[1]) < 0) {
-                       i_error("close(pipe:out:wr) failed: %m");
+                       e_error(pclient->event,
+                               "close(pipe:out:wr) failed: %m");
                }
                for(i = 0; i < xfd_count; i++) {
                        if (close(child_extra_fds[i * 2]) < 0) {
-                               i_error("close(pipe:extra=%d:wr) failed: %m",
+                               e_error(pclient->event,
+                                       "close(pipe:extra=%d:wr) failed: %m",
                                        child_extra_fds[i * 2 + 1]);
                        }
                        if (close(parent_extra_fds[i]) < 0) {
-                               i_error("close(pipe:extra=%d:rd) failed: %m",
+                               e_error(pclient->event,
+                                       "close(pipe:extra=%d:rd) failed: %m",
                                        child_extra_fds[i * 2 + 1]);
                        }
                }
@@ -222,13 +237,18 @@ program_client_local_connect(struct program_client *pclient)
 
        if (plclient->pid == 0) {
                /* child */
-               if (fd_in[1] >= 0 && close(fd_in[1]) < 0)
-                       i_error("close(pipe:in:wr) failed: %m");
-               if (fd_out[0] >= 0 && close(fd_out[0]) < 0)
-                       i_error("close(pipe:out:rd) failed: %m");
+               if (fd_in[1] >= 0 && close(fd_in[1]) < 0) {
+                       e_error(pclient->event,
+                               "close(pipe:in:wr) failed: %m");
+               }
+               if (fd_out[0] >= 0 && close(fd_out[0]) < 0) {
+                       e_error(pclient->event,
+                               "close(pipe:out:rd) failed: %m");
+               }
                for(i = 0; i < xfd_count; i++) {
                        if (close(parent_extra_fds[i]) < 0) {
-                               i_error("close(pipe:extra=%d:rd) failed: %m",
+                               e_error(pclient->event,
+                                       "close(pipe:extra=%d:rd) failed: %m",
                                        child_extra_fds[i * 2 + 1]);
                        }
                }
@@ -240,17 +260,23 @@ program_client_local_connect(struct program_client *pclient)
                                        RESTRICT_ACCESS_FLAG_ALLOW_ROOT : 0),
                                pclient->set.home);
 
-               exec_child(pclient->path, pclient->args, &pclient->envs,
+               exec_child(plclient->bin_path, pclient->args, &pclient->envs,
                           fd_in[0], fd_out[1], child_extra_fds,
                           pclient->set.drop_stderr);
                i_unreached();
        }
 
        /* parent */
-       if (fd_in[0] >= 0 && close(fd_in[0]) < 0)
-               i_error("close(pipe:in:rd) failed: %m");
-       if (fd_out[1] >= 0 && close(fd_out[1]) < 0)
-               i_error("close(pipe:out:wr) failed: %m");
+       program_client_set_label(pclient,
+               t_strdup_printf("exec:%s (%d)", plclient->bin_path,
+                               plclient->pid));
+
+       if (fd_in[0] >= 0 && close(fd_in[0]) < 0) {
+               e_error(pclient->event, "close(pipe:in:rd) failed: %m");
+       }
+       if (fd_out[1] >= 0 && close(fd_out[1]) < 0) {
+               e_error(pclient->event, "close(pipe:out:wr) failed: %m");
+       }
        if (fd_in[1] >= 0) {
                net_set_nonblock(fd_in[1], TRUE);
                pclient->fd_out = fd_in[1];
@@ -261,7 +287,8 @@ program_client_local_connect(struct program_client *pclient)
        }
        for(i = 0; i < xfd_count; i++) {
                if (close(child_extra_fds[i * 2]) < 0) {
-                       i_error("close(pipe:extra=%d:wr) failed: %m",
+                       e_error(pclient->event,
+                               "close(pipe:extra=%d:wr) failed: %m",
                                child_extra_fds[i * 2 + 1]);
                }
                net_set_nonblock(parent_extra_fds[i], TRUE);
@@ -287,7 +314,8 @@ program_client_local_close_output(struct program_client *pclient)
 
        /* Shutdown output; program stdin will get EOF */
        if (fd_out >= 0 && close(fd_out) < 0) {
-               i_error("close(%s) failed: %m", pclient->path);
+               e_error(pclient->event,
+                       "close(fd_out) failed: %m");
                return -1;
        }
        return 1;
@@ -312,8 +340,9 @@ program_client_local_exited(struct program_client_local *plclient)
                int exit_code = WEXITSTATUS(plclient->status);
 
                if (exit_code != 0) {
-                       i_info("program `%s' terminated with non-zero exit code %d",
-                              pclient->path, exit_code);
+                       e_info(pclient->event,
+                              "Terminated with non-zero exit code %d",
+                              exit_code);
                        pclient->exit_code = PROGRAM_CLIENT_EXIT_FAILURE;
                } else {
                        pclient->exit_code = PROGRAM_CLIENT_EXIT_SUCCESS;
@@ -321,20 +350,24 @@ program_client_local_exited(struct program_client_local *plclient)
        } else if (WIFSIGNALED(plclient->status)) {
                /* Killed with a signal */
                if (plclient->sent_term) {
-                       i_error("program `%s' was forcibly terminated with signal %d",
-                               pclient->path, WTERMSIG(plclient->status));
+                       e_error(pclient->event,
+                               "Forcibly terminated with signal %d",
+                               WTERMSIG(plclient->status));
                } else {
-                       i_error("program `%s' terminated abnormally, signal %d",
-                               pclient->path, WTERMSIG(plclient->status));
+                       e_error(pclient->event,
+                               "Terminated abnormally with signal %d",
+                               WTERMSIG(plclient->status));
                }
        } else if (WIFSTOPPED(plclient->status)) {
                /* Stopped */
-               i_error("program `%s' stopped, signal %d",
-                       pclient->path, WSTOPSIG(plclient->status));
+               e_error(pclient->event,
+                       "Stopped with signal %d",
+                       WSTOPSIG(plclient->status));
        } else {
                /* Something else */
-               i_error("program `%s' terminated abnormally, return status %d",
-                       pclient->path, plclient->status);
+               e_error(pclient->event,
+                       "Terminated abnormally with status %d",
+                       plclient->status);
        }
 
        program_client_disconnected(pclient);
@@ -343,6 +376,8 @@ program_client_local_exited(struct program_client_local *plclient)
 static void
 program_client_local_kill_now(struct program_client_local *plclient)
 {
+       struct program_client *pclient = &plclient->client;
+
        if (plclient->child_wait != NULL) {
                /* no need for this anymore */
                child_wait_free(&plclient->child_wait);
@@ -353,17 +388,19 @@ program_client_local_kill_now(struct program_client_local *plclient)
 
        /* kill it brutally now: it should die right away */
        if (kill(plclient->pid, SIGKILL) < 0) {
-               i_error("failed to send SIGKILL signal to program `%s'",
-                       plclient->client.path);
+               e_error(pclient->event,
+                       "Failed to send SIGKILL signal to program");
        } else if (waitpid(plclient->pid, &plclient->status, 0) < 0) {
-               i_error("waitpid(%s) failed: %m",
-                       plclient->client.path);
+               e_error(pclient->event, "waitpid(%d) failed: %m",
+                       plclient->pid);
        }
 }
 
 static void
 program_client_local_kill(struct program_client_local *plclient)
 {
+       struct program_client *pclient = &plclient->client;
+
        /* time to die */
        timeout_remove(&plclient->to_kill);
 
@@ -374,29 +411,27 @@ program_client_local_kill(struct program_client_local *plclient)
 
        if (plclient->sent_term) {
                /* Timed out again */
-               if (plclient->client.debug) {
-                       i_debug("program `%s' (%d) did not die after %d milliseconds: "
-                               "sending KILL signal",
-                               plclient->client.path, plclient->pid, KILL_TIMEOUT);
-               }
+               e_debug(pclient->event,
+                       "Program did not die after %d milliseconds",
+                       KILL_TIMEOUT);
 
                program_client_local_kill_now(plclient);
                program_client_local_exited(plclient);
                return;
        }
 
-       if (plclient->client.debug)
-               i_debug("program `%s'(%d) execution timed out after %u milliseconds: "
-                       "sending TERM signal", plclient->client.path, plclient->pid,
-                       plclient->client.set.input_idle_timeout_msecs);
+       e_debug(pclient->event,
+               "Execution timed out after %u milliseconds: "
+               "Sending TERM signal",
+               pclient->set.input_idle_timeout_msecs);
 
        /* send sigterm, keep on waiting */
        plclient->sent_term = TRUE;
 
        /* Kill child gently first */
        if (kill(plclient->pid, SIGTERM) < 0) {
-               i_error("failed to send SIGTERM signal to program `%s'",
-                       plclient->client.path);
+               e_error(pclient->event,
+                       "Failed to send SIGTERM signal to program");
                (void)kill(plclient->pid, SIGKILL);
                program_client_local_exited(plclient);
                return;
@@ -443,10 +478,8 @@ program_client_local_disconnect(struct program_client *pclient, bool force)
            runtime < pclient->set.input_idle_timeout_msecs)
                timeout = pclient->set.input_idle_timeout_msecs - runtime;
 
-       if (pclient->debug) {
-               i_debug("waiting for program `%s' to finish after %lu msecs",
-                       pclient->path, runtime);
-       }
+       e_debug(pclient->event,
+               "Waiting for program to finish after %lu msecs", runtime);
 
        force = force ||
                (timeout == 0 && pclient->set.input_idle_timeout_msecs > 0);
@@ -492,16 +525,20 @@ program_client_local_create(const char *bin_path,
                            const struct program_client_settings *set)
 {
        struct program_client_local *plclient;
+       const char *label;
        pool_t pool;
 
+       label = t_strconcat("exec:", bin_path, NULL);
+
        pool = pool_alloconly_create("program client local", 1024);
        plclient = p_new(pool, struct program_client_local, 1);
-       program_client_init(&plclient->client, pool, bin_path, args, set);
+       program_client_init(&plclient->client, pool, label, args, set);
        plclient->client.connect = program_client_local_connect;
        plclient->client.close_output = program_client_local_close_output;
        plclient->client.switch_ioloop = program_client_local_switch_ioloop;
        plclient->client.disconnect = program_client_local_disconnect;
        plclient->client.destroy = program_client_local_destroy;
+       plclient->bin_path = p_strdup(pool, bin_path);
        plclient->pid = -1;
 
        child_wait_init();
index ff5750744aea3aebdf342f8cd7f1c7ff27d09c12..381042234503e47e4701e84a8d393def684f179a 100644 (file)
@@ -32,10 +32,11 @@ struct program_client {
        pool_t pool;
        struct program_client_settings set;
 
-       char *path;
        const char **args;
        ARRAY_TYPE(const_string) envs;
 
+       struct event *event;
+
        int fd_in, fd_out;
        struct io *io;
        struct timeout *to;
@@ -67,8 +68,11 @@ struct program_client {
        bool destroying:1;
 };
 
+void program_client_set_label(struct program_client *pclient,
+                             const char *label);
+
 void program_client_init(struct program_client *pclient, pool_t pool,
-                        const char *path,
+                        const char *initial_label,
                         const char *const *args,
                         const struct program_client_settings *set);
 
index e579c051212474e5994a6784b19409317e317d73..d2c3df01c530bb64fc2ae53d45e9e3a4e1a8715f 100644 (file)
@@ -206,7 +206,7 @@ program_client_istream_create(struct program_client *program_client,
 struct program_client_remote {
        struct program_client client;
 
-       const char *hostname;
+       const char *address;
        struct dns_lookup_settings dns_set;
        struct dns_lookup *lookup;
        unsigned int ips_count;
@@ -218,6 +218,7 @@ struct program_client_remote {
 
        bool noreply:1;
        bool resolved:1;
+       bool have_hostname:1;
 };
 
 static void
@@ -265,7 +266,8 @@ program_client_remote_connected(struct program_client_remote *prclient)
 
        if (o_stream_send(pclient->raw_program_output,
                          str_data(str), str_len(str)) < 0) {
-               i_error("write(%s) failed: %s",
+               e_error(pclient->event,
+                       "write(%s) failed: %s",
                        o_stream_get_name(pclient->raw_program_output),
                        o_stream_get_error(pclient->raw_program_output));
                program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
@@ -291,25 +293,25 @@ program_client_unix_connect(struct program_client *pclient)
                (struct program_client_remote *)pclient;
        int fd;
 
-       if (pclient->set.debug)
-               i_debug("Trying to connect %s", pclient->path);
+       e_debug(pclient->event, "Trying to connect");
 
        timeout_remove(&prclient->to_retry);
 
-       if ((fd = net_connect_unix(pclient->path)) < 0) {
+       if ((fd = net_connect_unix(prclient->address)) < 0) {
                switch (errno) {
                case EACCES:
-                       i_error("%s",
+                       e_error(pclient->event, "%s",
                                eacces_error_get("net_connect_unix",
-                                                pclient->path));
+                                                prclient->address));
                        return -1;
                case EAGAIN:
                        prclient->to_retry = timeout_add_short(100,
                                program_client_unix_reconnect, prclient);
                        return 0;
                default:
-                       i_error("net_connect_unix(%s) failed: %m",
-                               pclient->path);
+                       e_error(pclient->event,
+                               "net_connect_unix(%s) failed: %m",
+                               prclient->address);
                        return -1;
                }
        }
@@ -330,8 +332,8 @@ program_client_net_connect_timeout(struct program_client_remote *prclient)
        io_remove(&pclient->io);
        timeout_remove(&pclient->to);
 
-       i_error("connect(%s) failed: timeout in %u milliseconds", 
-               pclient->path,
+       e_error(pclient->event, "connect(%s) failed: "
+               "Timeout in %u milliseconds", prclient->address,
                pclient->set.client_connect_timeout_msecs);
 
        /* set error to timeout here */
@@ -351,8 +353,8 @@ program_client_net_connected(struct program_client_remote *prclient)
        io_remove(&pclient->io);
 
        if ((errno = net_geterror(pclient->fd_out)) != 0) {
-               i_error("connect(%s) failed: %m",
-                       pclient->path);
+               e_error(pclient->event, "connect(%s) failed: %m",
+                       prclient->address);
 
                /* disconnect and try again */
                i_close_fd(&pclient->fd_out);
@@ -368,7 +370,7 @@ static void
 program_client_net_connect_real(struct program_client_remote *prclient)
 {
        struct program_client *pclient = &prclient->client;
-       const char *str;
+       const char *address, *label;
 
        timeout_remove(&pclient->to);
 
@@ -376,22 +378,20 @@ program_client_net_connect_real(struct program_client_remote *prclient)
 
        i_assert(prclient->ips_count > 0);
 
-       if (net_ipport2str(prclient->ips, prclient->port, &str) < 0)
+       if (net_ipport2str(prclient->ips, prclient->port, &address) < 0)
                i_unreached();
-       pclient->path = p_strdup(pclient->pool, str);
+       label = t_strconcat("tcp:", address, NULL);
+       program_client_set_label(pclient, label);
 
-       if (pclient->debug) {
-               i_debug("Trying to connect %s (timeout %u msecs)",
-                       pclient->path,
-                       pclient->set.client_connect_timeout_msecs);
-       }
+       e_debug(pclient->event, "Trying to connect (timeout %u msecs)",
+               pclient->set.client_connect_timeout_msecs);
 
        /* try to connect */
        int fd;
        if ((fd = net_connect_ip(prclient->ips, prclient->port,
                                 (prclient->ips->family == AF_INET ?
                                  &net_ip4_any : &net_ip6_any))) < 0) {
-               i_error("connect(%s) failed: %m", pclient->path);
+               e_error(pclient->event, "connect(%s) failed: %m", address);
                prclient->to_retry = timeout_add_short(0,
                        program_client_net_connect_again, prclient);
                return;
@@ -419,10 +419,10 @@ program_client_net_connect_again(struct program_client_remote *prclient)
        pclient->error = PROGRAM_CLIENT_ERROR_NONE;
 
        if (--prclient->ips_left == 0) {
-               if (prclient->ips_count > 1)
-                       i_error("program-client-net: "
-                               "%s: No addresses left to try",
-                               prclient->hostname);
+               if (prclient->ips_count > 1) {
+                       e_error(pclient->event,
+                               "No IP addresses left to try");
+               }
                program_client_fail(pclient,
                                    error != PROGRAM_CLIENT_ERROR_NONE ?
                                                error :
@@ -441,9 +441,8 @@ program_client_net_connect_resolved(const struct dns_lookup_result *result,
        struct program_client *pclient = &prclient->client;
 
        if (result->ret != 0) {
-               i_error("program-client-net: Cannot resolve '%s': %s",
-                       pclient->path,
-                       result->error);
+               e_error(pclient->event, "Cannot resolve `%s': %s",
+                       prclient->address, result->error);
                program_client_fail(pclient, PROGRAM_CLIENT_ERROR_OTHER);
                return;
        }
@@ -475,24 +474,20 @@ program_client_net_connect_init(struct program_client *pclient)
        struct ip_addr ip;
 
        if (prclient->ips != NULL) {
-               prclient->hostname = p_strdup(pclient->pool,
-                                             net_ip2addr(prclient->ips));
-       } else if (net_addr2ip(pclient->path, &ip) == 0) {
-               prclient->hostname = p_strdup(pclient->pool,
-                                             net_ip2addr(&ip));
+               /* nothing to do */
+       } else if (net_addr2ip(prclient->address, &ip) == 0) {
                prclient->resolved = TRUE;
                prclient->ips = p_new(pclient->pool, struct ip_addr, 1);
                *prclient->ips = ip;
                prclient->ips_count = 1;
        } else {
                prclient->resolved = FALSE;
-               prclient->hostname = p_strdup(pclient->pool, pclient->path);
                if (pclient->set.dns_client_socket_path != NULL) {
                        prclient->dns_set.dns_client_socket_path =
                                pclient->set.dns_client_socket_path;
                        prclient->dns_set.timeout_msecs =
                                pclient->set.client_connect_timeout_msecs;
-                       dns_lookup(pclient->path, &prclient->dns_set,
+                       dns_lookup(prclient->address, &prclient->dns_set,
                                   program_client_net_connect_resolved,
                                   prclient, &prclient->lookup);
                        return 0;
@@ -501,13 +496,13 @@ program_client_net_connect_init(struct program_client *pclient)
                        unsigned int ips_count;
                        int err;
                        /* guess we do it here then.. */
-                       if ((err = net_gethostbyname(pclient->path,
+                       if ((err = net_gethostbyname(prclient->address,
                                              &ips, &ips_count)) != 0) {
-                               i_error("program-client-remote: "
-                                       "Cannot resolve '%s': %s",
-                                       pclient->path,
+                               e_error(pclient->event,
+                                       "Cannot resolve `%s': %s",
+                                       prclient->address,
                                        net_gethosterror(err));
-                                       return -1;
+                               return -1;
                        }
                        prclient->ips_count = ips_count;
                        prclient->ips = p_memdup(pclient->pool,
@@ -533,8 +528,8 @@ program_client_remote_close_output(struct program_client *pclient)
                if (fd_in >= 0) {
                        if (shutdown(fd_out, SHUT_WR) < 0 &&
                            errno != ENOTCONN) {
-                               i_error("shutdown(%s, SHUT_WR) failed: %m",
-                                       pclient->path);
+                               e_error(pclient->event,
+                                       "shutdown(fd_out, SHUT_WR) failed: %m");
                                return -1;
                        }
                } else {
@@ -575,15 +570,19 @@ program_client_unix_create(const char *socket_path, const char *const *args,
                           bool noreply)
 {
        struct program_client_remote *prclient;
+       const char *label;
        pool_t pool;
 
+       label = t_strconcat("unix:", socket_path, NULL);
+
        pool = pool_alloconly_create("program client unix", 1024);
        prclient = p_new(pool, struct program_client_remote, 1);
-       program_client_init(&prclient->client, pool, socket_path, args, set);
+       program_client_init(&prclient->client, pool, label, args, set);
        prclient->client.connect = program_client_unix_connect;
        prclient->client.close_output = program_client_remote_close_output;
        prclient->client.disconnect = program_client_remote_disconnect;
        prclient->client.switch_ioloop = program_client_remote_switch_ioloop;
+       prclient->address = p_strdup(pool, socket_path);
        prclient->noreply = noreply;
 
        return &prclient->client;
@@ -596,16 +595,21 @@ program_client_net_create(const char *host, in_port_t port,
                          bool noreply)
 {
        struct program_client_remote *prclient;
+       const char *label;
        pool_t pool;
 
+       label = t_strdup_printf("tcp:%s:%u", host, port);
+
        pool = pool_alloconly_create("program client net", 1024);
        prclient = p_new(pool, struct program_client_remote, 1);
-       program_client_init(&prclient->client, pool, host, args, set);
+       program_client_init(&prclient->client, pool, label, args, set);
        prclient->client.connect = program_client_net_connect_init;
        prclient->client.close_output = program_client_remote_close_output;
        prclient->client.disconnect = program_client_remote_disconnect;
        prclient->client.set.use_dotstream = TRUE;
+       prclient->address = p_strdup(pool, host);
        prclient->port = port;
+       prclient->have_hostname = TRUE;
        prclient->noreply = noreply;
        return &prclient->client;
 }
@@ -618,19 +622,24 @@ program_client_net_create_ips(const struct ip_addr *ips, size_t ips_count,
                              bool noreply)
 {
        struct program_client_remote *prclient;
+       const char *label;
        pool_t pool;
 
        i_assert(ips != NULL && ips_count > 0);
 
+       if (net_ipport2str(ips, port, &label) < 0)
+               i_unreached();
+       label = t_strconcat("tcp:", label, NULL);
+
        pool = pool_alloconly_create("program client net", 1024);
        prclient = p_new(pool, struct program_client_remote, 1);
-       program_client_init(&prclient->client, pool, net_ip2addr(ips),
-                           args, set);
+       program_client_init(&prclient->client, pool, label, args, set);
        prclient->client.connect = program_client_net_connect_init;
        prclient->client.close_output = program_client_remote_close_output;
        prclient->client.disconnect = program_client_remote_disconnect;
        prclient->client.switch_ioloop = program_client_remote_switch_ioloop;
        prclient->client.set.use_dotstream = TRUE;
+       prclient->address = p_strdup(pool, net_ip2addr(ips));
        prclient->ips = p_memdup(pool, ips,
                                 sizeof(struct ip_addr)*ips_count);
        prclient->ips_count = ips_count;
index eecba8d99c83c0ec6b7ad7bcb34730866d455c61..0dc0b540c5106a5775d4f7884cc9c4151977f16d 100644 (file)
 #define MAX_OUTPUT_BUFFER_SIZE 16384
 #define MAX_OUTPUT_MEMORY_BUFFER (1024*128)
 
+void program_client_set_label(struct program_client *pclient,
+                             const char *label)
+{
+       event_set_append_log_prefix(pclient->event,
+               t_strconcat("program ", label, ": ", NULL));
+}
+
 static void
 program_client_callback(struct program_client *pclient, int result,
                        void *context)
@@ -35,16 +42,18 @@ program_client_callback(struct program_client *pclient, int result,
 static void
 program_client_timeout(struct program_client *pclient)
 {
-       i_error("program `%s' execution timed out (> %u msecs)",
-               pclient->path, pclient->set.input_idle_timeout_msecs);
+       e_error(pclient->event,
+               "Execution timed out (> %u msecs)",
+               pclient->set.input_idle_timeout_msecs);
        program_client_fail(pclient, PROGRAM_CLIENT_ERROR_RUN_TIMEOUT);
 }
 
 static void
 program_client_connect_timeout(struct program_client *pclient)
 {
-       i_error("program `%s' socket connection timed out (> %u msecs)",
-               pclient->path, pclient->set.client_connect_timeout_msecs);
+       e_error(pclient->event,
+               "Connection timed out (> %u msecs)",
+               pclient->set.client_connect_timeout_msecs);
        program_client_fail(pclient, PROGRAM_CLIENT_ERROR_CONNECT_TIMEOUT);
 }
 
@@ -207,7 +216,8 @@ program_client_output_finish(struct program_client *pclient)
 
        /* flush the output */
        if ((ret=o_stream_finish(output)) < 0) {
-               i_error("write(%s) failed: %s",
+               e_error(pclient->event,
+                       "write(%s) failed: %s",
                        o_stream_get_name(output),
                        o_stream_get_error(output));
                program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
@@ -232,13 +242,15 @@ program_client_output_pump_finished(enum iostream_pump_status status,
        case IOSTREAM_PUMP_STATUS_INPUT_EOF:
                break;
        case IOSTREAM_PUMP_STATUS_INPUT_ERROR:
-               i_error("read(%s) failed: %s",
+               e_error(pclient->event,
+                       "read(%s) failed: %s",
                        i_stream_get_name(input),
                        i_stream_get_error(input));
                program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
                return;
        case IOSTREAM_PUMP_STATUS_OUTPUT_ERROR:
-               i_error("write(%s) failed: %s",
+               e_error(pclient->event,
+                       "write(%s) failed: %s",
                        o_stream_get_name(output),
                        o_stream_get_error(output));
                program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
@@ -278,7 +290,8 @@ program_client_input_finish(struct program_client *pclient)
                return;
        if (ret < 0) {
                if (input->stream_errno != 0) {
-                       i_error("read(%s) failed: %s",
+                       e_error(pclient->event,
+                               "read(%s) failed: %s",
                                i_stream_get_name(input),
                                i_stream_get_error(input));
                        program_client_fail(pclient,
@@ -317,13 +330,15 @@ program_client_input_pump_finished(enum iostream_pump_status status,
        case IOSTREAM_PUMP_STATUS_INPUT_EOF:
                break;
        case IOSTREAM_PUMP_STATUS_INPUT_ERROR:
-               i_error("read(%s) failed: %s",
+               e_error(pclient->event,
+                       "read(%s) failed: %s",
                        i_stream_get_name(input),
                        i_stream_get_error(input));
                program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
                return;
        case IOSTREAM_PUMP_STATUS_OUTPUT_ERROR:
-               i_error("write(%s) failed: %s",
+               e_error(pclient->event,
+                       "write(%s) failed: %s",
                        o_stream_get_name(output),
                        o_stream_get_error(output));
                program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
@@ -428,18 +443,21 @@ void program_client_connected(struct program_client *pclient)
 }
 
 void program_client_init(struct program_client *pclient, pool_t pool,
-                        const char *path,
-                        const char *const *args,
+                        const char *initial_label, const char *const *args,
                         const struct program_client_settings *set)
 {
        pclient->pool = pool;
-       pclient->path = p_strdup(pool, path);
        if (args != NULL)
                pclient->args = p_strarray_dup(pool, args);
        pclient->set = *set;
        pclient->debug = set->debug;
        pclient->fd_in = -1;
        pclient->fd_out = -1;
+
+       pclient->event = event_create(set->event);
+       if ((set != NULL && set->debug))
+               event_set_forced_debug(pclient->event, TRUE);
+       program_client_set_label(pclient, initial_label);
 }
 
 void program_client_set_input(struct program_client *pclient,
@@ -585,6 +603,8 @@ void program_client_destroy(struct program_client **_pclient)
        if (pclient->destroy != NULL)
                pclient->destroy(pclient);
 
+       event_unref(&pclient->event);
+
        pool_unref(&pclient->pool);
 }
 
index 53b28c1ce6c27df06f4bae2a6fdf1ab6c5203d12..2020d13ae797c538602b4fe3c76a87a7f83af2dd 100644 (file)
@@ -16,6 +16,9 @@ struct program_client_settings {
        const char *dns_client_socket_path;
        const char *home;
 
+       /* Event to use for the program client. */
+       struct event *event;
+
        bool allow_root:1;
        bool debug:1;
        bool drop_stderr:1;