Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Patrick Schaaf <netdev@bof.de>
Signed-off-by: Simon Horman <horms@verge.net.au>

authored by

Patrick Schaaf and committed by
Simon Horman
41ac51ee 6cb90db5

+43 -14
+2
include/net/ip_vs.h
··· 1019 1019 extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, 1020 1020 struct ip_vs_proto_data *pd); 1021 1021 1022 + extern void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg); 1023 + 1022 1024 1023 1025 /* 1024 1026 * IPVS control data and functions (from ip_vs_ctl.c)
+1 -1
net/netfilter/ipvs/ip_vs_lblc.c
··· 510 510 /* No cache entry or it is invalid, time to schedule */ 511 511 dest = __ip_vs_lblc_schedule(svc); 512 512 if (!dest) { 513 - IP_VS_ERR_RL("LBLC: no destination available\n"); 513 + ip_vs_scheduler_err(svc, "no destination available"); 514 514 return NULL; 515 515 } 516 516
+1 -1
net/netfilter/ipvs/ip_vs_lblcr.c
··· 692 692 /* The cache entry is invalid, time to schedule */ 693 693 dest = __ip_vs_lblcr_schedule(svc); 694 694 if (!dest) { 695 - IP_VS_ERR_RL("LBLCR: no destination available\n"); 695 + ip_vs_scheduler_err(svc, "no destination available"); 696 696 read_unlock(&svc->sched_lock); 697 697 return NULL; 698 698 }
+1 -1
net/netfilter/ipvs/ip_vs_lc.c
··· 70 70 } 71 71 72 72 if (!least) 73 - IP_VS_ERR_RL("LC: no destination available\n"); 73 + ip_vs_scheduler_err(svc, "no destination available"); 74 74 else 75 75 IP_VS_DBG_BUF(6, "LC: server %s:%u activeconns %d " 76 76 "inactconns %d\n",
+1 -1
net/netfilter/ipvs/ip_vs_nq.c
··· 99 99 } 100 100 101 101 if (!least) { 102 - IP_VS_ERR_RL("NQ: no destination available\n"); 102 + ip_vs_scheduler_err(svc, "no destination available"); 103 103 return NULL; 104 104 } 105 105
+1 -1
net/netfilter/ipvs/ip_vs_rr.c
··· 72 72 q = q->next; 73 73 } while (q != p); 74 74 write_unlock(&svc->sched_lock); 75 - IP_VS_ERR_RL("RR: no destination available\n"); 75 + ip_vs_scheduler_err(svc, "no destination available"); 76 76 return NULL; 77 77 78 78 out:
+25
net/netfilter/ipvs/ip_vs_sched.c
··· 29 29 30 30 #include <net/ip_vs.h> 31 31 32 + EXPORT_SYMBOL(ip_vs_scheduler_err); 32 33 /* 33 34 * IPVS scheduler list 34 35 */ ··· 147 146 module_put(scheduler->module); 148 147 } 149 148 149 + /* 150 + * Common error output helper for schedulers 151 + */ 152 + 153 + void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg) 154 + { 155 + if (svc->fwmark) { 156 + IP_VS_ERR_RL("%s: FWM %u 0x%08X - %s\n", 157 + svc->scheduler->name, svc->fwmark, 158 + svc->fwmark, msg); 159 + #ifdef CONFIG_IP_VS_IPV6 160 + } else if (svc->af == AF_INET6) { 161 + IP_VS_ERR_RL("%s: %s [%pI6]:%d - %s\n", 162 + svc->scheduler->name, 163 + ip_vs_proto_name(svc->protocol), 164 + &svc->addr.in6, ntohs(svc->port), msg); 165 + #endif 166 + } else { 167 + IP_VS_ERR_RL("%s: %s %pI4:%d - %s\n", 168 + svc->scheduler->name, 169 + ip_vs_proto_name(svc->protocol), 170 + &svc->addr.ip, ntohs(svc->port), msg); 171 + } 172 + } 150 173 151 174 /* 152 175 * Register a scheduler in the scheduler list
+1 -1
net/netfilter/ipvs/ip_vs_sed.c
··· 87 87 goto nextstage; 88 88 } 89 89 } 90 - IP_VS_ERR_RL("SED: no destination available\n"); 90 + ip_vs_scheduler_err(svc, "no destination available"); 91 91 return NULL; 92 92 93 93 /*
+1 -1
net/netfilter/ipvs/ip_vs_sh.c
··· 223 223 || !(dest->flags & IP_VS_DEST_F_AVAILABLE) 224 224 || atomic_read(&dest->weight) <= 0 225 225 || is_overloaded(dest)) { 226 - IP_VS_ERR_RL("SH: no destination available\n"); 226 + ip_vs_scheduler_err(svc, "no destination available"); 227 227 return NULL; 228 228 } 229 229
+1 -1
net/netfilter/ipvs/ip_vs_wlc.c
··· 75 75 goto nextstage; 76 76 } 77 77 } 78 - IP_VS_ERR_RL("WLC: no destination available\n"); 78 + ip_vs_scheduler_err(svc, "no destination available"); 79 79 return NULL; 80 80 81 81 /*
+8 -6
net/netfilter/ipvs/ip_vs_wrr.c
··· 147 147 148 148 if (mark->cl == mark->cl->next) { 149 149 /* no dest entry */ 150 - IP_VS_ERR_RL("WRR: no destination available: " 151 - "no destinations present\n"); 150 + ip_vs_scheduler_err(svc, 151 + "no destination available: " 152 + "no destinations present"); 152 153 dest = NULL; 153 154 goto out; 154 155 } ··· 163 162 */ 164 163 if (mark->cw == 0) { 165 164 mark->cl = &svc->destinations; 166 - IP_VS_ERR_RL("WRR: no destination " 167 - "available\n"); 165 + ip_vs_scheduler_err(svc, 166 + "no destination available"); 168 167 dest = NULL; 169 168 goto out; 170 169 } ··· 186 185 /* back to the start, and no dest is found. 187 186 It is only possible when all dests are OVERLOADED */ 188 187 dest = NULL; 189 - IP_VS_ERR_RL("WRR: no destination available: " 190 - "all destinations are overloaded\n"); 188 + ip_vs_scheduler_err(svc, 189 + "no destination available: " 190 + "all destinations are overloaded"); 191 191 goto out; 192 192 } 193 193 }