mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-07 21:45:22 +00:00
util: fix libvirtd startup failure due to netlink error
This is part of the solution to the problem detailed in:
https://bugzilla.redhat.com/show_bug.cgi?id=816465
and further detailed in
https://www.redhat.com/archives/libvir-list/2012-May/msg00202.htm
A short explanation is included in the comments of the patch itself.
Note that this patch by itself breaks communication between lldpad and
libvirtd, so the other 3 patches in the series must be applied at the
same time as this patch.
(cherry picked from commit 642973135c
)
Conflicts:
daemon/libvirtd.c
This commit is contained in:
parent
d617c987b7
commit
3cc52164b1
@ -1483,6 +1483,12 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
use_polkit_dbus = config->auth_unix_rw == REMOTE_AUTH_POLKIT ||
|
use_polkit_dbus = config->auth_unix_rw == REMOTE_AUTH_POLKIT ||
|
||||||
config->auth_unix_ro == REMOTE_AUTH_POLKIT;
|
config->auth_unix_ro == REMOTE_AUTH_POLKIT;
|
||||||
|
|
||||||
|
if (virNetlinkStartup() < 0) {
|
||||||
|
ret = VIR_DAEMON_ERR_INIT;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(srv = virNetServerNew(config->min_workers,
|
if (!(srv = virNetServerNew(config->min_workers,
|
||||||
config->max_workers,
|
config->max_workers,
|
||||||
config->prio_workers,
|
config->prio_workers,
|
||||||
@ -1620,6 +1626,7 @@ cleanup:
|
|||||||
virNetServerProgramFree(qemuProgram);
|
virNetServerProgramFree(qemuProgram);
|
||||||
virNetServerClose(srv);
|
virNetServerClose(srv);
|
||||||
virNetServerFree(srv);
|
virNetServerFree(srv);
|
||||||
|
virNetlinkShutdown();
|
||||||
if (statuswrite != -1) {
|
if (statuswrite != -1) {
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
/* Tell parent of daemon what failed */
|
/* Tell parent of daemon what failed */
|
||||||
|
@ -1327,6 +1327,8 @@ virNetlinkEventRemoveClient;
|
|||||||
virNetlinkEventServiceIsRunning;
|
virNetlinkEventServiceIsRunning;
|
||||||
virNetlinkEventServiceStop;
|
virNetlinkEventServiceStop;
|
||||||
virNetlinkEventServiceStart;
|
virNetlinkEventServiceStart;
|
||||||
|
virNetlinkShutdown;
|
||||||
|
virNetlinkStartup;
|
||||||
|
|
||||||
|
|
||||||
# virnetmessage.h
|
# virnetmessage.h
|
||||||
|
@ -88,9 +88,62 @@ static int nextWatch = 1;
|
|||||||
# define NETLINK_EVENT_ALLOC_EXTENT 10
|
# define NETLINK_EVENT_ALLOC_EXTENT 10
|
||||||
|
|
||||||
static virNetlinkEventSrvPrivatePtr server = NULL;
|
static virNetlinkEventSrvPrivatePtr server = NULL;
|
||||||
|
static struct nl_handle *placeholder_nlhandle = NULL;
|
||||||
|
|
||||||
/* Function definitions */
|
/* Function definitions */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNetlinkStartup:
|
||||||
|
*
|
||||||
|
* Perform any initialization that needs to take place before the
|
||||||
|
* program starts up worker threads. This is currently used to assure
|
||||||
|
* that an nl_handle is allocated prior to any attempts to bind a
|
||||||
|
* netlink socket. For a discussion of why this is necessary, please
|
||||||
|
* see the following email message:
|
||||||
|
*
|
||||||
|
* https://www.redhat.com/archives/libvir-list/2012-May/msg00202.html
|
||||||
|
*
|
||||||
|
* The short version is that, without this placeholder allocation of
|
||||||
|
* an nl_handle that is never used, it is possible for nl_connect() in
|
||||||
|
* one thread to collide with a direct bind() of a netlink socket in
|
||||||
|
* another thread, leading to failure of the operation (which could
|
||||||
|
* lead to failure of libvirtd to start). Since getaddrinfo() (used by
|
||||||
|
* libvirtd in virSocketAddrParse, which is called quite frequently
|
||||||
|
* during startup) directly calls bind() on a netlink socket, this is
|
||||||
|
* actually a very common occurrence (15-20% failure rate on some
|
||||||
|
* hardware).
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 on failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNetlinkStartup(void)
|
||||||
|
{
|
||||||
|
if (placeholder_nlhandle)
|
||||||
|
return 0;
|
||||||
|
placeholder_nlhandle = nl_handle_alloc();
|
||||||
|
if (!placeholder_nlhandle) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("cannot allocate placeholder nlhandle for netlink"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNetlinkShutdown:
|
||||||
|
*
|
||||||
|
* Undo any initialization done by virNetlinkStartup. This currently
|
||||||
|
* destroys the placeholder nl_handle.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
virNetlinkShutdown(void)
|
||||||
|
{
|
||||||
|
if (placeholder_nlhandle) {
|
||||||
|
nl_handle_destroy(placeholder_nlhandle);
|
||||||
|
placeholder_nlhandle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virNetlinkCommand:
|
* virNetlinkCommand:
|
||||||
* @nlmsg: pointer to netlink message
|
* @nlmsg: pointer to netlink message
|
||||||
@ -536,6 +589,18 @@ static const char *unsupported = N_("libnl was not available at build time");
|
|||||||
static const char *unsupported = N_("not supported on non-linux platforms");
|
static const char *unsupported = N_("not supported on non-linux platforms");
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetlinkStartup(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
virNetlinkShutdown(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int virNetlinkCommand(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
|
int virNetlinkCommand(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
|
||||||
unsigned char **respbuf ATTRIBUTE_UNUSED,
|
unsigned char **respbuf ATTRIBUTE_UNUSED,
|
||||||
unsigned int *respbuflen ATTRIBUTE_UNUSED,
|
unsigned int *respbuflen ATTRIBUTE_UNUSED,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
* Copyright (C) 2010-2012 Red Hat, Inc.
|
||||||
* Copyright (C) 2010-2012 IBM Corporation
|
* Copyright (C) 2010-2012 IBM Corporation
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -35,6 +35,9 @@ struct nlattr;
|
|||||||
|
|
||||||
# endif /* __linux__ */
|
# endif /* __linux__ */
|
||||||
|
|
||||||
|
int virNetlinkStartup(void);
|
||||||
|
void virNetlinkShutdown(void);
|
||||||
|
|
||||||
int virNetlinkCommand(struct nl_msg *nl_msg,
|
int virNetlinkCommand(struct nl_msg *nl_msg,
|
||||||
unsigned char **respbuf, unsigned int *respbuflen,
|
unsigned char **respbuf, unsigned int *respbuflen,
|
||||||
int nl_pid);
|
int nl_pid);
|
||||||
|
Loading…
Reference in New Issue
Block a user