Commit 41ac51ee authored by Patrick Schaaf's avatar Patrick Schaaf Committed by Simon Horman

ipvs: make "no destination available" message more informative

When IP_VS schedulers do not find a destination, they output a terse
"WLC: no destination available" message through kernel syslog, which I
can not only make sense of because syslog puts them in a logfile
together with keepalived checker results.

This patch makes the output a bit more informative, by telling you which
virtual service failed to find a destination.

Example output:

kernel: [1539214.552233] IPVS: wlc: TCP 192.168.8.30:22 - no destination available
kernel: [1539299.674418] IPVS: wlc: FWM 22 0x00000016 - no destination available

I have tested the code for IPv4 and FWM services, as you can see from
the example; I do not have an IPv6 setup to test the third code path
with.

To avoid code duplication, I put a new function ip_vs_scheduler_err()
into ip_vs_sched.c, and use that from the schedulers instead of calling
IP_VS_ERR_RL directly.
Signed-off-by: default avatarPatrick Schaaf <netdev@bof.de>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent 6cb90db5
...@@ -1019,6 +1019,8 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, ...@@ -1019,6 +1019,8 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
struct ip_vs_proto_data *pd); struct ip_vs_proto_data *pd);
extern void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg);
/* /*
* IPVS control data and functions (from ip_vs_ctl.c) * IPVS control data and functions (from ip_vs_ctl.c)
......
...@@ -510,7 +510,7 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -510,7 +510,7 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
/* No cache entry or it is invalid, time to schedule */ /* No cache entry or it is invalid, time to schedule */
dest = __ip_vs_lblc_schedule(svc); dest = __ip_vs_lblc_schedule(svc);
if (!dest) { if (!dest) {
IP_VS_ERR_RL("LBLC: no destination available\n"); ip_vs_scheduler_err(svc, "no destination available");
return NULL; return NULL;
} }
......
...@@ -692,7 +692,7 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -692,7 +692,7 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
/* The cache entry is invalid, time to schedule */ /* The cache entry is invalid, time to schedule */
dest = __ip_vs_lblcr_schedule(svc); dest = __ip_vs_lblcr_schedule(svc);
if (!dest) { if (!dest) {
IP_VS_ERR_RL("LBLCR: no destination available\n"); ip_vs_scheduler_err(svc, "no destination available");
read_unlock(&svc->sched_lock); read_unlock(&svc->sched_lock);
return NULL; return NULL;
} }
......
...@@ -70,7 +70,7 @@ ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -70,7 +70,7 @@ ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
} }
if (!least) if (!least)
IP_VS_ERR_RL("LC: no destination available\n"); ip_vs_scheduler_err(svc, "no destination available");
else else
IP_VS_DBG_BUF(6, "LC: server %s:%u activeconns %d " IP_VS_DBG_BUF(6, "LC: server %s:%u activeconns %d "
"inactconns %d\n", "inactconns %d\n",
......
...@@ -99,7 +99,7 @@ ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -99,7 +99,7 @@ ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
} }
if (!least) { if (!least) {
IP_VS_ERR_RL("NQ: no destination available\n"); ip_vs_scheduler_err(svc, "no destination available");
return NULL; return NULL;
} }
......
...@@ -72,7 +72,7 @@ ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -72,7 +72,7 @@ ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
q = q->next; q = q->next;
} while (q != p); } while (q != p);
write_unlock(&svc->sched_lock); write_unlock(&svc->sched_lock);
IP_VS_ERR_RL("RR: no destination available\n"); ip_vs_scheduler_err(svc, "no destination available");
return NULL; return NULL;
out: out:
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <net/ip_vs.h> #include <net/ip_vs.h>
EXPORT_SYMBOL(ip_vs_scheduler_err);
/* /*
* IPVS scheduler list * IPVS scheduler list
*/ */
...@@ -146,6 +147,30 @@ void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler) ...@@ -146,6 +147,30 @@ void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler)
module_put(scheduler->module); module_put(scheduler->module);
} }
/*
* Common error output helper for schedulers
*/
void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg)
{
if (svc->fwmark) {
IP_VS_ERR_RL("%s: FWM %u 0x%08X - %s\n",
svc->scheduler->name, svc->fwmark,
svc->fwmark, msg);
#ifdef CONFIG_IP_VS_IPV6
} else if (svc->af == AF_INET6) {
IP_VS_ERR_RL("%s: %s [%pI6]:%d - %s\n",
svc->scheduler->name,
ip_vs_proto_name(svc->protocol),
&svc->addr.in6, ntohs(svc->port), msg);
#endif
} else {
IP_VS_ERR_RL("%s: %s %pI4:%d - %s\n",
svc->scheduler->name,
ip_vs_proto_name(svc->protocol),
&svc->addr.ip, ntohs(svc->port), msg);
}
}
/* /*
* Register a scheduler in the scheduler list * Register a scheduler in the scheduler list
......
...@@ -87,7 +87,7 @@ ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -87,7 +87,7 @@ ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
goto nextstage; goto nextstage;
} }
} }
IP_VS_ERR_RL("SED: no destination available\n"); ip_vs_scheduler_err(svc, "no destination available");
return NULL; return NULL;
/* /*
......
...@@ -223,7 +223,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -223,7 +223,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
|| !(dest->flags & IP_VS_DEST_F_AVAILABLE) || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
|| atomic_read(&dest->weight) <= 0 || atomic_read(&dest->weight) <= 0
|| is_overloaded(dest)) { || is_overloaded(dest)) {
IP_VS_ERR_RL("SH: no destination available\n"); ip_vs_scheduler_err(svc, "no destination available");
return NULL; return NULL;
} }
......
...@@ -75,7 +75,7 @@ ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -75,7 +75,7 @@ ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
goto nextstage; goto nextstage;
} }
} }
IP_VS_ERR_RL("WLC: no destination available\n"); ip_vs_scheduler_err(svc, "no destination available");
return NULL; return NULL;
/* /*
......
...@@ -147,8 +147,9 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -147,8 +147,9 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
if (mark->cl == mark->cl->next) { if (mark->cl == mark->cl->next) {
/* no dest entry */ /* no dest entry */
IP_VS_ERR_RL("WRR: no destination available: " ip_vs_scheduler_err(svc,
"no destinations present\n"); "no destination available: "
"no destinations present");
dest = NULL; dest = NULL;
goto out; goto out;
} }
...@@ -162,8 +163,8 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -162,8 +163,8 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
*/ */
if (mark->cw == 0) { if (mark->cw == 0) {
mark->cl = &svc->destinations; mark->cl = &svc->destinations;
IP_VS_ERR_RL("WRR: no destination " ip_vs_scheduler_err(svc,
"available\n"); "no destination available");
dest = NULL; dest = NULL;
goto out; goto out;
} }
...@@ -185,8 +186,9 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) ...@@ -185,8 +186,9 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
/* back to the start, and no dest is found. /* back to the start, and no dest is found.
It is only possible when all dests are OVERLOADED */ It is only possible when all dests are OVERLOADED */
dest = NULL; dest = NULL;
IP_VS_ERR_RL("WRR: no destination available: " ip_vs_scheduler_err(svc,
"all destinations are overloaded\n"); "no destination available: "
"all destinations are overloaded");
goto out; goto out;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment