GNU/Linux >> Linux Esercitazione >  >> Linux

Nessuno spazio buffer disponibile su connect

Beh, non so quale sia esattamente il problema, ma cercherò di trovare la direzione giusta per risolverlo.

Lo ENOBUFS code viene restituito quando sk_alloc() o dst_alloc() è fallito. Non riesco a trovare altre occorrenze di ENOBUFS nel codice sorgente relativo ai socket.

Inoltre non riesco a trovare alcun percorso dal SYSCALL_DEFINE3(connect) a sk_alloc() , e penso che il socket non dovrebbe essere allocato durante connect() call dove ricevi l'errore, quindi penso che non sia probabile che il sk_alloc() ha causato il problema.

L'dst_alloc() è probabilmente usato per controllare i percorsi durante il connect() , non riesco a trovare il percorso esatto, deve essere da qualche parte all'interno:SYSCALL_DEFINE3(connect) -> .connect() -> ip4_datagram_connect() -> ip_route_connect()

Il dst_alloc() alloca una voce in una cache SLAB corrispondente e potrebbe effettivamente fallire se la cache è piena. In realtà le vecchie voci dovrebbero essere eliminate se ciò accade, ma forse ci sono casi in cui restituisce ancora un errore.

Quindi penso che tu possa muoverti in questa direzione. La dimensione della cache dst potrebbe essere cambiata attraverso /proc/sys/net/ipv4/route/max_size . Innanzitutto, controlla se l'impostazione (o qualsiasi altra impostazione in sys.net.ipv4.route ) viene modificato da "modifiche TCP casuali mostrate su Google".


Nei kernel precedenti alla 3.6, potevi essere colpito da ENOBUFS per il normale traffico IPv4/v6, quando il limite net.ipv4.route.max_size o net.ipv6.route.max_size veniva esaurito, di conseguenza.

A partire dal kernel 3.6, la cache di routing è stata rimossa e net.ipv4.route.max_size ha perso la sua influenza sulla quantità di voci dst. Quindi, generalmente, ciò non sarebbe più possibile.

Tuttavia, puoi ancora incorrere in questo errore come me, quando usi IPSec. Dopo un certo numero di tunnel IPSec creati, non sono riuscito a eseguire il ping dell'host remoto:

# ping 10.100.0.1
connect: No buffer space available

ping da iputils crea un descrittore di file di test e utilizza connect() su di esso per associare l'ip dst. Quando accade, la voce della cache dst per il dato AF viene creata dal kernel e il limite delle voci della cache xfrm4 dst era già esaurito nel mio caso. Questo limite è controllato dall'impostazione sysctl:

xfrm4_gc_thresh - INTEGER
    The threshold at which we will start garbage collecting for IPv4
    destination cache entries.  At twice this value the system will
    refuse new allocations.

Mi sono imbattuto in questo usando il kernel 3.10.59, dove il limite predefinito è molto basso - 1024. A partire dal kernel 3.10.83, questo limite è stato aumentato a 32768, e sarebbe molto più difficile da raggiungere.

Quindi, ho emesso:

# sysctl net.ipv4.xfrm4_gc_thresh=32768

e ha fatto la cosa per me.

Percorso approssimativo nel kernel per il mio caso con IPSec:

ip4_datagram_connect() -> ip_route_connect() -> ip_route_output_flow() ->
xfrm_lookup() -> xfrm_resolve_and_create_bundle() ->
... -> xfrm_alloc_dst() -> dst_alloc() with xfrm4_dst_ops, where gc is set.

Linux
  1. VPN Kill Switch per OpenVPN Connect ora disponibile

  2. Connettiti a un server cloud

  3. Quanto è portatile mmap?

  4. Spazio esaurito sul dispositivo

  5. git gc:nessuno spazio rimasto sul dispositivo, anche se 3 GB disponibili e tmp_pack solo 16 MB

Come cancellare la cache di memoria RAM e il buffer e lo spazio di scambio su Linux

Come controllare lo spazio di scambio in Linux

Ubuntu 18.04 Bionic Beaver disponibile per il download

Fedora 30 sfondi disponibili per il download

Ubuntu 21.10 "Impish Indri" disponibile per il download

Le 10 migliori distribuzioni Linux