Подтвердить что ты не робот

Каков максимальный размер сообщения дейтаграммы AF_UNIX, которое может быть отправлено в Linux?

В настоящее время я нажимаю жесткий лимит в 130688 байт. Если я попытаюсь отправить что-то большее в одном сообщении, я получаю ошибку ENOBUFS.

Я проверил параметры net.core.rmem_default, net.core.wmem_default, net.core.rmem_max, net.core.wmem_max и net.unix.max_dgram_qlen sysctl и увеличил их все, но они не влияют, потому что эти обрабатывать общий размер буфера, а не размер сообщения.

Я также установил опции сокета SO_SNDBUF и SO_RCVBUF, но это имеет ту же проблему, что и выше. Размер буфера сокета по умолчанию устанавливается в зависимости от параметров сокета _default.

Я посмотрел на источник ядра, где ENOBUFS возвращается в стек сокета, но мне было непонятно, откуда он. Единственные места, которые, похоже, возвращают эту ошибку, связаны с невозможностью выделения памяти.

Действительно ли максимальный размер 130688? Если это не может быть изменено без перекомпиляции ядра?

Спасибо!

4b9b3361

Ответ 1

AF_UNIX SOCK_DATAGRAM/SOCK_SEQPACKET датаграммы нуждаются в непрерывной памяти. Непрерывная физическая память трудно найти, а выделение не удастся, записав что-то похожее на это в журнале ядра:

udgc: page allocation failure. order:7, mode:0x44d0
[...snip...]
DMA: 185*4kB 69*8kB 34*16kB 27*32kB 11*64kB 1*128kB 1*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3788kB
Normal: 13*4kB 6*8kB 100*16kB 62*32kB 24*64kB 10*128kB 0*256kB 1*512kB 0*1024kB 0*2048kB 0*4096kB = 7012kB
[...snip...]

unix_dgram_sendmsg() вызывает sock_alloc_send_skb() lxr1, который вызывает sock_alloc_send_pskb() с data_len= 0 и header_len= размер дейтаграммы lxr2. sock_alloc_send_pskb() выделяет header_len из "нормального" буферного пространства skbuff, а data_len - сбрасывает/собирает страницы lxr3. Таким образом, похоже, что сокеты AF_UNIX не поддерживают разброс/сборку в текущем Linux.