Accepting request 186287 from Virtualization

- cache FQDN in kvp_daemon to avoid timeouts (bnc#828714)
- use full nlmsghdr in netlink_send
- correct payload size in netlink_send
- use single send+recv buffer
- log errors to syslog in kvp_set_ip_info
- check return value of system in hv_kvp_daemon
- in kvp_set_ip_info free mac_addr right after usage
- check return value of daemon to fix compiler warning.

OBS-URL: https://build.opensuse.org/request/show/186287
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/hyper-v?expand=0&rev=13
This commit is contained in:
Stephan Kulow 2013-08-07 18:44:11 +00:00 committed by Git OBS Bridge
commit e226398705
3 changed files with 53 additions and 45 deletions

View File

@ -1,3 +1,15 @@
-------------------------------------------------------------------
Wed Aug 7 19:04:35 CEST 2013 - ohering@suse.de
- cache FQDN in kvp_daemon to avoid timeouts (bnc#828714)
- use full nlmsghdr in netlink_send
- correct payload size in netlink_send
- use single send+recv buffer
- log errors to syslog in kvp_set_ip_info
- check return value of system in hv_kvp_daemon
- in kvp_set_ip_info free mac_addr right after usage
- check return value of daemon to fix compiler warning.
------------------------------------------------------------------- -------------------------------------------------------------------
Thu Aug 1 14:21:57 CEST 2013 - ohering@suse.de Thu Aug 1 14:21:57 CEST 2013 - ohering@suse.de

View File

@ -89,6 +89,7 @@ static char *processor_arch;
static char *os_build; static char *os_build;
static char *os_version; static char *os_version;
static char *lic_version = "Unknown version"; static char *lic_version = "Unknown version";
static char full_domain_name[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
static struct utsname uts_buf; static struct utsname uts_buf;
/* /*
@ -1299,6 +1300,7 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
} }
error = kvp_write_file(file, "HWADDR", "", mac_addr); error = kvp_write_file(file, "HWADDR", "", mac_addr);
free(mac_addr);
if (error) if (error)
goto setval_error; goto setval_error;
@ -1344,7 +1346,6 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
goto setval_error; goto setval_error;
setval_done: setval_done:
free(mac_addr);
fclose(file); fclose(file);
/* /*
@ -1353,18 +1354,22 @@ setval_done:
*/ */
snprintf(cmd, sizeof(cmd), "%s %s", "hv_set_ifconfig", if_file); snprintf(cmd, sizeof(cmd), "%s %s", "hv_set_ifconfig", if_file);
system(cmd); if (system(cmd)) {
syslog(LOG_ERR, "Failed to execute cmd '%s'; error: %d %s",
cmd, errno, strerror(errno));
return HV_E_FAIL;
}
return 0; return 0;
setval_error: setval_error:
syslog(LOG_ERR, "Failed to write config file"); syslog(LOG_ERR, "Failed to write config file. error: %d %s",
free(mac_addr); errno, strerror(errno));
fclose(file); fclose(file);
return error; return error;
} }
static int static void
kvp_get_domain_name(char *buffer, int length) kvp_get_domain_name(char *buffer, int length)
{ {
struct addrinfo hints, *info ; struct addrinfo hints, *info ;
@ -1378,34 +1383,29 @@ kvp_get_domain_name(char *buffer, int length)
error = getaddrinfo(buffer, NULL, &hints, &info); error = getaddrinfo(buffer, NULL, &hints, &info);
if (error != 0) { if (error != 0) {
strcpy(buffer, "getaddrinfo failed\n"); snprintf(buffer, length, "getaddrinfo failed: 0x%x %s",
return error; error, gai_strerror(error));
return;
} }
strcpy(buffer, info->ai_canonname); snprintf(buffer, length, "%s", info->ai_canonname);
freeaddrinfo(info); freeaddrinfo(info);
return error;
} }
static int static int
netlink_send(int fd, struct cn_msg *msg) netlink_send(int fd, struct cn_msg *msg)
{ {
struct nlmsghdr *nlh; struct nlmsghdr nlh = { .nlmsg_type = NLMSG_DONE };
unsigned int size; unsigned int size;
struct msghdr message; struct msghdr message;
char buffer[64];
struct iovec iov[2]; struct iovec iov[2];
size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len); size = sizeof(struct cn_msg) + msg->len;
nlh = (struct nlmsghdr *)buffer; nlh.nlmsg_pid = getpid();
nlh->nlmsg_seq = 0; nlh.nlmsg_len = NLMSG_LENGTH(size);
nlh->nlmsg_pid = getpid();
nlh->nlmsg_type = NLMSG_DONE;
nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
nlh->nlmsg_flags = 0;
iov[0].iov_base = nlh; iov[0].iov_base = &nlh;
iov[0].iov_len = sizeof(*nlh); iov[0].iov_len = sizeof(nlh);
iov[1].iov_base = msg; iov[1].iov_base = msg;
iov[1].iov_len = size; iov[1].iov_len = size;
@ -1435,25 +1435,29 @@ int main(void)
int pool; int pool;
char *if_name; char *if_name;
struct hv_kvp_ipaddr_value *kvp_ip_val; struct hv_kvp_ipaddr_value *kvp_ip_val;
char *kvp_send_buffer;
char *kvp_recv_buffer; char *kvp_recv_buffer;
size_t kvp_recv_buffer_len; size_t kvp_recv_buffer_len;
daemon(1, 0); if (daemon(1, 0))
return 1;
openlog("KVP", 0, LOG_USER); openlog("KVP", 0, LOG_USER);
syslog(LOG_INFO, "KVP starting; pid is:%d", getpid()); syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
kvp_recv_buffer_len = NLMSG_HDRLEN + sizeof(struct cn_msg) + sizeof(struct hv_kvp_msg); kvp_recv_buffer_len = NLMSG_LENGTH(0) + sizeof(struct cn_msg) + sizeof(struct hv_kvp_msg);
kvp_send_buffer = calloc(1, kvp_recv_buffer_len);
kvp_recv_buffer = calloc(1, kvp_recv_buffer_len); kvp_recv_buffer = calloc(1, kvp_recv_buffer_len);
if (!(kvp_send_buffer && kvp_recv_buffer)) { if (!kvp_recv_buffer) {
syslog(LOG_ERR, "Failed to allocate netlink buffers"); syslog(LOG_ERR, "Failed to allocate netlink buffer");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/* /*
* Retrieve OS release information. * Retrieve OS release information.
*/ */
kvp_get_os_info(); kvp_get_os_info();
/*
* Cache Fully Qualified Domain Name because getaddrinfo takes an
* unpredicatable amount of time to finish.
*/
kvp_get_domain_name(full_domain_name, sizeof(full_domain_name));
if (kvp_file_init()) { if (kvp_file_init()) {
syslog(LOG_ERR, "Failed to initialize the pools"); syslog(LOG_ERR, "Failed to initialize the pools");
@ -1489,7 +1493,7 @@ int main(void)
/* /*
* Register ourselves with the kernel. * Register ourselves with the kernel.
*/ */
message = (struct cn_msg *)kvp_send_buffer; message = (struct cn_msg *)kvp_recv_buffer;
message->id.idx = CN_KVP_IDX; message->id.idx = CN_KVP_IDX;
message->id.val = CN_KVP_VAL; message->id.val = CN_KVP_VAL;
@ -1672,8 +1676,7 @@ int main(void)
switch (hv_msg->body.kvp_enum_data.index) { switch (hv_msg->body.kvp_enum_data.index) {
case FullyQualifiedDomainName: case FullyQualifiedDomainName:
kvp_get_domain_name(key_value, strcpy(key_value, full_domain_name);
HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
strcpy(key_name, "FullyQualifiedDomainName"); strcpy(key_name, "FullyQualifiedDomainName");
break; break;
case IntegrationServicesVersion: case IntegrationServicesVersion:

View File

@ -105,23 +105,18 @@ static int vss_operate(int operation)
static int netlink_send(int fd, struct cn_msg *msg) static int netlink_send(int fd, struct cn_msg *msg)
{ {
struct nlmsghdr *nlh; struct nlmsghdr nlh = { .nlmsg_type = NLMSG_DONE };
unsigned int size; unsigned int size;
struct msghdr message; struct msghdr message;
char buffer[64];
struct iovec iov[2]; struct iovec iov[2];
size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len); size = sizeof(struct cn_msg) + msg->len;
nlh = (struct nlmsghdr *)buffer; nlh.nlmsg_pid = getpid();
nlh->nlmsg_seq = 0; nlh.nlmsg_len = NLMSG_LENGTH(size);
nlh->nlmsg_pid = getpid();
nlh->nlmsg_type = NLMSG_DONE;
nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
nlh->nlmsg_flags = 0;
iov[0].iov_base = nlh; iov[0].iov_base = &nlh;
iov[0].iov_len = sizeof(*nlh); iov[0].iov_len = sizeof(nlh);
iov[1].iov_base = msg; iov[1].iov_base = msg;
iov[1].iov_len = size; iov[1].iov_len = size;
@ -145,7 +140,6 @@ int main(void)
struct cn_msg *incoming_cn_msg; struct cn_msg *incoming_cn_msg;
int op; int op;
struct hv_vss_msg *vss_msg; struct hv_vss_msg *vss_msg;
char *vss_send_buffer;
char *vss_recv_buffer; char *vss_recv_buffer;
size_t vss_recv_buffer_len; size_t vss_recv_buffer_len;
@ -155,10 +149,9 @@ int main(void)
openlog("Hyper-V VSS", 0, LOG_USER); openlog("Hyper-V VSS", 0, LOG_USER);
syslog(LOG_INFO, "VSS starting; pid is:%d", getpid()); syslog(LOG_INFO, "VSS starting; pid is:%d", getpid());
vss_recv_buffer_len = NLMSG_HDRLEN + sizeof(struct cn_msg) + sizeof(struct hv_vss_msg); vss_recv_buffer_len = NLMSG_LENGTH(0) + sizeof(struct cn_msg) + sizeof(struct hv_vss_msg);
vss_send_buffer = calloc(1, vss_recv_buffer_len);
vss_recv_buffer = calloc(1, vss_recv_buffer_len); vss_recv_buffer = calloc(1, vss_recv_buffer_len);
if (!(vss_send_buffer && vss_recv_buffer)) { if (!vss_recv_buffer) {
syslog(LOG_ERR, "Failed to allocate netlink buffers"); syslog(LOG_ERR, "Failed to allocate netlink buffers");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -185,7 +178,7 @@ int main(void)
/* /*
* Register ourselves with the kernel. * Register ourselves with the kernel.
*/ */
message = (struct cn_msg *)vss_send_buffer; message = (struct cn_msg *)vss_recv_buffer;
message->id.idx = CN_VSS_IDX; message->id.idx = CN_VSS_IDX;
message->id.val = CN_VSS_VAL; message->id.val = CN_VSS_VAL;
message->ack = 0; message->ack = 0;