Hello,
It sounds to me that it is some sort of sparc specific problem in the
LVS/ipvsadm code itself. I am more than happy to work on a kernel-side
or ipvsadm fix for it. The former I can put into debian myself, the
The problem is easily identified (in this example by invoking ipvsadm
without arguments):
From ip_vs.h:
struct ip_vs_get_services {
/* number of virtual services */
unsigned int num_services;
/* service table */
struct ip_vs_service_user entrytable[0];
};
In user space we use the following ioctl structures to pass a command:
struct ip_vs_get_services *ipvs_get_services(void)
{
struct ip_vs_get_services *get;
socklen_t len;
len = sizeof(*get) +
sizeof(struct ip_vs_service_user) * ipvs_info.num_services;
if (!(get = malloc(len)))
return NULL;
ipvs_cmd = GET_CMD(IP_VS_SO_GET_SERVICES);
get->num_services = ipvs_info.num_services;
printf("get [%d], len [%d] services [%d]\n", sizeof(*get), len,
ipvs_info.num_services);
if (getsockopt(sockfd, IPPROTO_IP,
IP_VS_SO_GET_SERVICES, get, &len) < 0) {
free(get);
return NULL;
}
return get;
}
struct ip_vs_get_services *get is 4 bytes, independant on the
architecture, at least this is what I see on sparc64 and IA32.
The output is:
ipvs_init successfull, returning socket fd=3 len=12
IP Virtual Server version 1.0.11 (size=16384)
get [4], len [4] services [0]
Module is wrong version [ipvsadm.c:list_all:1579]
In the kernel (ip_vs_ctl.c) we use the following structures:
case IP_VS_SO_GET_SERVICES:
{
struct ip_vs_get_services get;
if (*len < sizeof(get)) {
printk("sparc64 [%d]\n", sizeof(get));
IP_VS_ERR("length: %u < %Zu\n", *len, sizeof(get));
ret = -EINVAL;
goto out;
}
if (copy_from_user(&get, user, sizeof(get))) {
ret = -EFAULT;
goto out;
}
if (*len != (sizeof(get)+sizeof(struct
ip_vs_service_user)*get.n
um_services)) {
IP_VS_ERR("length: %u != %Zu\n", *len,
sizeof(get)+sizeof(struct
ip_vs_service_user)*
get.num_services);
ret = -EINVAL;
goto out;
}
ret = __ip_vs_get_service_entries(&get, user);
}
break;
struct ip_vs_get_services is 8 bytes. I'm a bit unsure as to why it
works under IA32 at all. I probably need some more sleep ;).
That's why I correctly get following entry in the kernlog:
sparc64 [8]
IPVS: length: 4 < 8
HTH and best regards,
Roberto Nibali, ratz
--
echo
'[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq' | dc
|