#include <haproxy/counters-t.h>
#include <haproxy/guid-t.h>
-int counters_fe_shared_prepare(struct fe_counters_shared *counters, const struct guid_node *guid);
-int counters_be_shared_prepare(struct be_counters_shared *counters, const struct guid_node *guid);
+int counters_fe_shared_prepare(struct fe_counters_shared *counters, const struct guid_node *guid, char **errmsg);
+int counters_be_shared_prepare(struct be_counters_shared *counters, const struct guid_node *guid, char **errmsg);
void counters_fe_shared_drop(struct fe_counters_shared *counters);
void counters_be_shared_drop(struct be_counters_shared *counters);
#include <haproxy/counters.h>
#include <haproxy/global.h>
#include <haproxy/time.h>
+#include <haproxy/tools.h>
static void _counters_shared_drop(void *counters)
{
/* prepare shared counters pointer for a given <guid> object
* <size> hint is expected to reflect the actual tg member size (fe/be)
* if <guid> is not set, then sharing is disabled
- * Returns the pointer on success or NULL on failure
+ * Returns the pointer on success or NULL on failure, in which case
+ * <errmsg> will contain additional hints about the error and must be freed accordingly
*/
-static int _counters_shared_prepare(struct counters_shared *shared, const struct guid_node *guid, size_t size)
+static int _counters_shared_prepare(struct counters_shared *shared,
+ const struct guid_node *guid, size_t size, char **errmsg)
{
int it = 0;
while (it < global.nbtgroups) {
shared->tg[it] = calloc(1, size);
if (!shared->tg[it]) {
+ memprintf(errmsg, "memory error, calloc failed");
_counters_shared_drop(shared);
return 0;
}
}
/* prepare shared fe counters pointer for a given <guid> object */
-int counters_fe_shared_prepare(struct fe_counters_shared *shared, const struct guid_node *guid)
+int counters_fe_shared_prepare(struct fe_counters_shared *shared, const struct guid_node *guid, char **errmsg)
{
- return _counters_shared_prepare((struct counters_shared *)shared, guid, sizeof(struct fe_counters_shared_tg));
+ return _counters_shared_prepare((struct counters_shared *)shared, guid, sizeof(struct fe_counters_shared_tg), errmsg);
}
/* prepare shared be counters pointer for a given <guid> object */
-int counters_be_shared_prepare(struct be_counters_shared *shared, const struct guid_node *guid)
+int counters_be_shared_prepare(struct be_counters_shared *shared, const struct guid_node *guid, char **errmsg)
{
- return _counters_shared_prepare((struct counters_shared *)shared, guid, sizeof(struct be_counters_shared_tg));
+ return _counters_shared_prepare((struct counters_shared *)shared, guid, sizeof(struct be_counters_shared_tg), errmsg);
}
static int proxy_postcheck(struct proxy *px)
{
struct listener *listener;
+ char *errmsg = NULL;
int err_code = ERR_NONE;
/* allocate private memory for shared counters: used as a fallback
* proxy postparsing, see proxy_postparse()
*/
if (px->cap & PR_CAP_FE) {
- if (!counters_fe_shared_prepare(&px->fe_counters.shared, &px->guid)) {
- ha_alert("out of memory while setting up shared counters for %s %s\n",
- proxy_type_str(px), px->id);
+ if (!counters_fe_shared_prepare(&px->fe_counters.shared, &px->guid, &errmsg)) {
+ ha_alert("out of memory while setting up shared counters for %s %s : %s\n",
+ proxy_type_str(px), px->id, errmsg);
+ ha_free(&errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
* be_counters may be used even if the proxy lacks the backend
* capability
*/
- if (!counters_be_shared_prepare(&px->be_counters.shared, &px->guid)) {
- ha_alert("out of memory while setting up shared counters for %s %s\n",
- proxy_type_str(px), px->id);
+ if (!counters_be_shared_prepare(&px->be_counters.shared, &px->guid, &errmsg)) {
+ ha_alert("out of memory while setting up shared counters for %s %s : %s\n",
+ proxy_type_str(px), px->id, errmsg);
+ ha_free(&errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
list_for_each_entry(listener, &px->conf.listeners, by_fe) {
if (listener->counters) {
- if (!counters_fe_shared_prepare(&listener->counters->shared, &listener->guid)) {
+ if (!counters_fe_shared_prepare(&listener->counters->shared, &listener->guid, &errmsg)) {
ha_free(&listener->counters);
- ha_alert("out of memory while setting up shared listener counters for %s %s\n",
- proxy_type_str(px), px->id);
+ ha_alert("out of memory while setting up shared listener counters for %s %s : %s\n",
+ proxy_type_str(px), px->id, errmsg);
+ ha_free(&errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
int srv_postinit(struct server *srv)
{
int err_code = ERR_NONE;
+ char *errmsg = NULL;
err_code |= _srv_check_proxy_mode(srv, 1);
if (err_code & ERR_CODE)
goto out;
- if (!counters_be_shared_prepare(&srv->counters.shared, &srv->guid)) {
- ha_alert("memory error while setting up shared counters for %s/%s server\n", srv->proxy->id, srv->id);
+ if (!counters_be_shared_prepare(&srv->counters.shared, &srv->guid, &errmsg)) {
+ ha_alert("memory error while setting up shared counters for %s/%s server : %s\n", srv->proxy->id, srv->id, errmsg);
+ ha_free(&errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}