mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-04-19 02:00:45 +02:00
platform: merge branch 'th/platform-recvmsg-enobufs'
This commit is contained in:
commit
583c759dd7
10 changed files with 64 additions and 42 deletions
|
|
@ -457,7 +457,7 @@ create_and_realize (NMDevice *device,
|
|||
g_assert (iface);
|
||||
|
||||
plerr = nm_platform_link_bond_add (NM_PLATFORM_GET, iface, out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create bond interface '%s' for '%s': %s",
|
||||
iface,
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ create_and_realize (NMDevice *device,
|
|||
hwaddr ? mac_address : NULL,
|
||||
hwaddr ? ETH_ALEN : 0,
|
||||
out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create bridge interface '%s' for '%s': %s",
|
||||
iface,
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ create_and_realize (NMDevice *device,
|
|||
}
|
||||
|
||||
plerr = nm_platform_link_infiniband_add (NM_PLATFORM_GET, parent_ifindex, p_key, out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create InfiniBand P_Key interface '%s' for '%s': %s",
|
||||
nm_device_get_iface (device),
|
||||
|
|
|
|||
|
|
@ -661,7 +661,7 @@ create_and_realize (NMDevice *device,
|
|||
}
|
||||
|
||||
plerr = nm_platform_link_gre_add (NM_PLATFORM_GET, iface, &lnk_gre, out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create GRE interface '%s' for '%s': %s",
|
||||
iface,
|
||||
|
|
@ -687,7 +687,7 @@ create_and_realize (NMDevice *device,
|
|||
lnk_sit.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel);
|
||||
|
||||
plerr = nm_platform_link_sit_add (NM_PLATFORM_GET, iface, &lnk_sit, out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create SIT interface '%s' for '%s': %s",
|
||||
iface,
|
||||
|
|
@ -713,7 +713,7 @@ create_and_realize (NMDevice *device,
|
|||
lnk_ipip.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel);
|
||||
|
||||
plerr = nm_platform_link_ipip_add (NM_PLATFORM_GET, iface, &lnk_ipip, out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create IPIP interface '%s' for '%s': %s",
|
||||
iface,
|
||||
|
|
@ -742,7 +742,7 @@ create_and_realize (NMDevice *device,
|
|||
lnk_ip6tnl.proto = nm_setting_ip_tunnel_get_mode (s_ip_tunnel) == NM_IP_TUNNEL_MODE_IPIP6 ? IPPROTO_IPIP : IPPROTO_IPV6;
|
||||
|
||||
plerr = nm_platform_link_ip6tnl_add (NM_PLATFORM_GET, iface, &lnk_ip6tnl, out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create IPIP interface '%s' for '%s': %s",
|
||||
iface,
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ create_and_realize (NMDevice *device,
|
|||
lnk.tap = nm_setting_macvlan_get_tap (s_macvlan);
|
||||
|
||||
plerr = nm_platform_link_macvlan_add (NM_PLATFORM_GET, iface, parent_ifindex, &lnk, out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create %s interface '%s' for '%s': %s",
|
||||
lnk.tap ? "macvtap" : "macvlan",
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ create_and_realize (NMDevice *device,
|
|||
nm_setting_tun_get_vnet_hdr (s_tun),
|
||||
nm_setting_tun_get_multi_queue (s_tun),
|
||||
out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create TUN/TAP interface '%s' for '%s': %s",
|
||||
iface,
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ create_and_realize (NMDevice *device,
|
|||
vlan_id,
|
||||
nm_setting_vlan_get_flags (s_vlan),
|
||||
out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create VLAN interface '%s' for '%s': %s",
|
||||
iface,
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ create_and_realize (NMDevice *device,
|
|||
props.l3miss = nm_setting_vxlan_get_l3_miss (s_vxlan);
|
||||
|
||||
plerr = nm_platform_link_vxlan_add (NM_PLATFORM_GET, iface, &props, out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create VXLAN interface '%s' for '%s': %s",
|
||||
iface,
|
||||
|
|
|
|||
|
|
@ -673,7 +673,7 @@ create_and_realize (NMDevice *device,
|
|||
NMPlatformError plerr;
|
||||
|
||||
plerr = nm_platform_link_team_add (NM_PLATFORM_GET, iface, out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create team master interface '%s' for '%s': %s",
|
||||
iface,
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@
|
|||
|
||||
#define VLAN_FLAG_MVRP 0x8
|
||||
|
||||
/* nm-internal error codes for libnl. Make sure they don't overlap. */
|
||||
#define _NLE_NM_NOBUFS 500
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
#define IFQDISCSIZ 32
|
||||
|
|
@ -2804,13 +2807,23 @@ delayed_action_wait_for_nl_response_complete (NMPlatform *platform,
|
|||
|
||||
static void
|
||||
delayed_action_wait_for_nl_response_complete_all (NMPlatform *platform,
|
||||
WaitForNlResponseResult result)
|
||||
WaitForNlResponseResult fallback_result)
|
||||
{
|
||||
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
|
||||
|
||||
if (NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) {
|
||||
while (priv->delayed_action.list_wait_for_nl_response->len > 0)
|
||||
delayed_action_wait_for_nl_response_complete (platform, priv->delayed_action.list_wait_for_nl_response->len - 1, result);
|
||||
while (priv->delayed_action.list_wait_for_nl_response->len > 0) {
|
||||
const DelayedActionWaitForNlResponseData *data;
|
||||
guint idx = priv->delayed_action.list_wait_for_nl_response->len - 1;
|
||||
WaitForNlResponseResult r;
|
||||
|
||||
data = &g_array_index (priv->delayed_action.list_wait_for_nl_response, DelayedActionWaitForNlResponseData, idx);
|
||||
|
||||
/* prefer the result that we already have. */
|
||||
r = data->seq_result ? : fallback_result;
|
||||
|
||||
delayed_action_wait_for_nl_response_complete (platform, idx, r);
|
||||
}
|
||||
}
|
||||
nm_assert (!NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE));
|
||||
nm_assert (priv->delayed_action.list_wait_for_nl_response->len == 0);
|
||||
|
|
@ -3461,7 +3474,7 @@ event_seq_check (NMPlatform *platform, struct nl_msg *msg, WaitForNlResponseResu
|
|||
}
|
||||
|
||||
static void
|
||||
event_valid_msg (NMPlatform *platform, struct nl_msg *msg)
|
||||
event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_events)
|
||||
{
|
||||
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
|
||||
nm_auto_nmpobj NMPObject *obj = NULL;
|
||||
|
|
@ -3477,6 +3490,9 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg)
|
|||
if (_support_kernel_extended_ifa_flags_still_undecided () && msghdr->nlmsg_type == RTM_NEWADDR)
|
||||
_support_kernel_extended_ifa_flags_detect (msg);
|
||||
|
||||
if (!handle_events)
|
||||
return;
|
||||
|
||||
if (NM_IN_SET (msghdr->nlmsg_type, RTM_DELLINK, RTM_DELADDR, RTM_DELROUTE)) {
|
||||
/* The event notifies about a deleted object. We don't need to initialize all
|
||||
* fields of the object. */
|
||||
|
|
@ -5517,24 +5533,30 @@ continue_reading:
|
|||
errno = 0;
|
||||
n = nl_recv (sk, &nla, &buf, &creds);
|
||||
|
||||
/* Work around a libnl bug fixed in 3.2.22 (375a6294) */
|
||||
if (n == 0 && errno == EAGAIN) {
|
||||
/* EAGAIN is equal to EWOULDBLOCK. If it would not be, we'd have to
|
||||
* workaround libnl3 mapping EWOULDBLOCK to -NLE_FAILURE. */
|
||||
G_STATIC_ASSERT (EAGAIN == EWOULDBLOCK);
|
||||
n = -NLE_AGAIN;
|
||||
switch (n) {
|
||||
case 0:
|
||||
/* Work around a libnl bug fixed in 3.2.22 (375a6294) */
|
||||
if (errno == EAGAIN) {
|
||||
/* EAGAIN is equal to EWOULDBLOCK. If it would not be, we'd have to
|
||||
* workaround libnl3 mapping EWOULDBLOCK to -NLE_FAILURE. */
|
||||
G_STATIC_ASSERT (EAGAIN == EWOULDBLOCK);
|
||||
n = -NLE_AGAIN;
|
||||
}
|
||||
break;
|
||||
case -NLE_NOMEM:
|
||||
if (errno == ENOBUFS) {
|
||||
/* we are very much interested in a overrun of the receive buffer.
|
||||
* nl_recv() maps all kinds of errors to NLE_NOMEM, so check also
|
||||
* for errno explicitly. And if so, hack our own return code to signal
|
||||
* the overrun. */
|
||||
n = -_NLE_NM_NOBUFS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (n <= 0)
|
||||
return n;
|
||||
|
||||
if (!handle_events) {
|
||||
/* we read until failure or there is nothing to read (EAGAIN). */
|
||||
g_clear_pointer (&buf, free);
|
||||
g_clear_pointer (&creds, free);
|
||||
goto continue_reading;
|
||||
}
|
||||
|
||||
hdr = (struct nlmsghdr *) buf;
|
||||
while (nlmsg_ok (hdr, n)) {
|
||||
gboolean abort_parsing = FALSE;
|
||||
|
|
@ -5627,7 +5649,9 @@ continue_reading:
|
|||
/* Valid message (not checking for MULTIPART bit to
|
||||
* get along with broken kernels. NL_SKIP has no
|
||||
* effect on this. */
|
||||
event_valid_msg (platform, msg);
|
||||
|
||||
event_valid_msg (platform, msg, handle_events);
|
||||
|
||||
seq_result = WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK;
|
||||
}
|
||||
|
||||
|
|
@ -5651,6 +5675,12 @@ continue_reading:
|
|||
goto continue_reading;
|
||||
}
|
||||
stop:
|
||||
if (!handle_events) {
|
||||
/* when we don't handle events, we want to drain all messages from the socket
|
||||
* without handling the messages (but still check for sequence numbers).
|
||||
* Repeat reading. */
|
||||
goto continue_reading;
|
||||
}
|
||||
err = 0;
|
||||
out:
|
||||
nlmsg_free (msg);
|
||||
|
|
@ -5696,12 +5726,10 @@ event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks)
|
|||
case -NLE_DUMP_INTR:
|
||||
_LOGD ("netlink: read: uncritical failure to retrieve incoming events: %s (%d)", nl_geterror (nle), nle);
|
||||
break;
|
||||
case -NLE_NOMEM:
|
||||
case -_NLE_NM_NOBUFS:
|
||||
_LOGI ("netlink: read: too many netlink events. Need to resynchronize platform cache");
|
||||
/* Drain the event queue, we've lost events and are out of sync anyway and we'd
|
||||
* like to free up some space. We'll read in the status synchronously. */
|
||||
delayed_action_wait_for_nl_response_complete_all (platform, WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC);
|
||||
event_handler_recvmsgs (platform, FALSE);
|
||||
delayed_action_wait_for_nl_response_complete_all (platform, WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC);
|
||||
delayed_action_schedule (platform,
|
||||
DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS |
|
||||
DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES |
|
||||
|
|
@ -5926,14 +5954,8 @@ constructed (GObject *_object)
|
|||
nle = nl_socket_set_nonblocking (priv->nlh);
|
||||
g_assert (!nle);
|
||||
|
||||
/* The default buffer size wasn't enough for the testsuites. It might just
|
||||
* as well happen with NetworkManager itself. For now let's hope 128KB is
|
||||
* good enough.
|
||||
*
|
||||
* FIXME: it's unclear that this is still actually needed. The testsuite
|
||||
* certainly doesn't fail for me. Maybe it can be removed.
|
||||
*/
|
||||
nle = nl_socket_set_buffer_size (priv->nlh, 131072, 0);
|
||||
/* use 8 MB for receive socket kernel queue. */
|
||||
nle = nl_socket_set_buffer_size (priv->nlh, 8*1024*1024, 0);
|
||||
g_assert (!nle);
|
||||
|
||||
nle = nl_socket_add_memberships (priv->nlh,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue