Назад | Перейти на главную страницу

«Cat / proc / net / dev» и «ip -s link» показывают разную статистику. Кто врет?

Я замечаю это /proc/net/dev говорит, что у eth3 1753 dropс. ip -s link показывает 0 dropped. Почему есть разница? Откуда берутся разные данные? Который правильный?

Я удалил лишние данные.

# uname -a
Linux example09 2.6.32-5-amd64 #1 SMP Thu Mar 22 17:26:33 UTC 2012 x86_64 GNU/Linux

# lsb_release -a
Distributor ID: Debian
Description:    Debian GNU/Linux 6.0.4 (squeeze)
Release:        6.0.4
Codename:       squeeze

# cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
  eth3:1258629839430 12545003042    0 1753    0     0          0  10594858 6666255952912 10026428444    0    0    0     0       0          0

# ip -s link
5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:15:17:96:0b:61 brd ff:ff:ff:ff:ff:ff
    RX: bytes  packets  errors  dropped overrun mcast
    244248462  3955476484 0       0       0       10595400
    TX: bytes  packets  errors  dropped carrier collsns
    683632524  1436809416 0       0       0       0

На машине Squeeze доверяйте /proc/net/dev. Это более простой и надежный способ просмотра одних и тех же данных.

В конкретном случае выпавшего счетчика я не могу объяснить точную проблему, но я могу наблюдать это на других коробках Squeeze. Если бы мне было все равно, я бы сообщил об этом как об ошибке в Debian (и предложил бы, чтобы кто-то сделал это и сообщил сюда).

Оба берут число из tx_dropped поле net_device_stats. В /proc/net/dev, линия создается dev_seq_printf_stats из net/core/dev.c.

ip идет, как обычно, через netlink, а точнее для статистики сетевых устройств, rtnetlink. Структура перешла в пользовательское пространство, rtnl_link_stats.

Собственная структура использует unsigned longс, rtnetlink использует __u32, более или менее неявное преобразование выполняется в copy_rtnl_link_stats.

Довольно легко заметить, что 32-битная версия используется с самого начала структуры, rx_packets: в то время как /proc/net/dev показывает 1258629839430, ip показывает 244248462, что примерно соответствует последним 32 битам (плюс еще несколько байтов между командами); То же самое и с подсчетом пакетов.

Вот количество этих двух первых полей:

% echo '1258629839430 % (2^32)'|bc; echo 244248462
204421702
244248462
% echo '12545003042 % (2^32)'|bc; echo 3955476484 
3955068450
3955476484

С введением IFLA_STATS64:

  • в ядре (из коммита 10708f37ae729baba9b67bd134c3720709d4ae62, доступно в апстриме v2.6.35 и новее)
  • в iproute2 (из коммита 8864ac9dc5bd5ce049280337deb21191673a02d0, доступно в восходящем направлении в v2.6.33-36 и новее).

На большинстве устройств / proc / net / dev считывается с аппаратных счетчиков. Остальная статистика обновляется из сетевого стека в структурах устройств.

Отбрасывания с большей вероятностью не будут совпадать, поскольку они могут быть сделаны оборудованием: пункт назначения Mac пакета не является ни устройством, ни многоадресной рассылкой, и устройство не является беспорядочным: оборудование напрямую отбрасывает пакет, стек никогда не узнает о его существовании.

Наконец, вам может быть интересно, почему бы не синхронизировать их или всегда использовать статистику оборудования? Когда стек по какой-либо причине отбрасывает пакет, он не может обновить аппаратный счетчик, и для отладки полезно знать, что вы можете найти каждый, чтобы отследить, где был отброшен пакет.

Надеюсь это поможет