diff --git a/include/haproxy/log.h b/include/haproxy/log.h index 497b486ee..d36e1840f 100644 --- a/include/haproxy/log.h +++ b/include/haproxy/log.h @@ -91,6 +91,7 @@ int postresolve_logger_list(struct list *loggers, const char *section, const cha struct logger *dup_logger(struct logger *def); void free_logger(struct logger *logger); +void deinit_log_target(struct log_target *target); /* Parse "log" keyword and update the linked list. */ int parse_logger(char **args, struct list *loggers, int do_del, const char *file, int linenum, char **err); diff --git a/src/log.c b/src/log.c index d77f462ee..96f53bc49 100644 --- a/src/log.c +++ b/src/log.c @@ -745,7 +745,7 @@ static inline void init_log_target(struct log_target *target) target->resolv_name = NULL; } -static void deinit_log_target(struct log_target *target) +void deinit_log_target(struct log_target *target) { ha_free(&target->addr); if (!(target->flags & LOG_TARGET_FL_RESOLVED)) @@ -1054,15 +1054,33 @@ static int postcheck_log_backend(struct proxy *be) err_code |= ERR_ALERT | ERR_FATAL; goto end; } - srv->log_target->addr = &srv->addr; - if (srv->addr_type.proto_type == PROTO_TYPE_DGRAM) + init_log_target(srv->log_target); + if (srv->addr_type.proto_type == PROTO_TYPE_DGRAM) { srv->log_target->type = LOG_TARGET_DGRAM; + /* Try to allocate log target addr (only used in DGRAM mode) */ + srv->log_target->addr = calloc(1, sizeof(*srv->log_target->addr)); + if (!srv->log_target->addr) { + memprintf(&msg, "memory error when allocating log server '%s'\n", srv->id); + err_code |= ERR_ALERT | ERR_FATAL; + goto end; + } + /* We must initialize it with known addr:svc_port, it will then + * be updated automatically by the server API for runtime changes + */ + ipcpy(&srv->addr, srv->log_target->addr); + set_host_port(srv->log_target->addr, srv->svc_port); + } else { /* for now BUFFER type only supports TCP server to it's almost - * explicit. This will require ring buffer creation during log - * postresolving step. + * explicit */ srv->log_target->type = LOG_TARGET_BUFFER; + srv->log_target->sink = sink_new_from_srv(srv, "log backend"); + if (!srv->log_target->sink) { + memprintf(&msg, "error when creating sink from '%s' log server", srv->id); + err_code |= ERR_ALERT | ERR_FATAL; + goto end; + } } if (target_type == -1) @@ -1073,14 +1091,7 @@ static int postcheck_log_backend(struct proxy *be) err_code |= ERR_ALERT | ERR_FATAL; goto end; } - if (target_type == LOG_TARGET_BUFFER) { - srv->log_target->sink = sink_new_from_srv(srv, "log backend"); - if (!srv->log_target->sink) { - memprintf(&msg, "error when creating sink from '%s' log server", srv->id); - err_code |= ERR_ALERT | ERR_FATAL; - goto end; - } - } + srv->log_target->flags |= LOG_TARGET_FL_RESOLVED; srv->cur_eweight = 1; /* ignore weights, all servers have the same weight */ _log_backend_srv_queue(srv); srv = srv->next; diff --git a/src/server.c b/src/server.c index 8ff084a9d..c854fc1b7 100644 --- a/src/server.c +++ b/src/server.c @@ -177,6 +177,11 @@ void _srv_set_inetaddr(struct server *srv, const struct sockaddr_storage *addr, { ipcpy(addr, &srv->addr); srv->svc_port = svc_port; + if (srv->log_target && srv->log_target->type == LOG_TARGET_DGRAM) { + /* server is used as a log target, manually update log target addr for DGRAM */ + ipcpy(addr, srv->log_target->addr); + set_host_port(srv->log_target->addr, svc_port); + } } /* @@ -2819,7 +2824,10 @@ void srv_free_params(struct server *srv) free(srv->resolvers_id); free(srv->addr_node.key); free(srv->lb_nodes); - free(srv->log_target); + if (srv->log_target) { + deinit_log_target(srv->log_target); + free(srv->log_target); + } if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->destroy_srv) xprt_get(XPRT_SSL)->destroy_srv(srv);