网卡statistics数据内核过程分析
2018-03-16 00:31
423 查看
简介
本文只讲述网卡的statistics数据注册和获取流程,典型的如:/sys/class/net/eth0/statistics/rx_packets
/sys/class/net/eth0/statistics/tx_packets
/sys/class/net/eth0/statistics/rx_bytes
/sys/class/net/eth0/statistics/tx_bytes
/sys/class/net/eth0/statistics/rx_dropped
/sys/class/net/eth0/statistics/tx_dropped
或者通过# ifconfig eth0查看到的数据
设备节点的创建
注册
在网卡加入到kernel的时候都必须通过register_netdevice()进行注册,该函数通过调用netdev_register_kobject()函数来设置相关信息并注册对应的设备节点。点击(此处)折叠或打开/* Create sysfs entries for network device. */
int netdev_register_kobject(struct net_device *ndev){
struct device *dev = &(ndev->dev);
const struct attribute_group **groups = ndev->sysfs_groups;
...
dev->groups = groups;
...
*groups++ = &netstat_group;
...
device_add(dev);
}
device_add()->device_add_attrs()->device_add_groups(dev->groups)->sysfs_create_groups()
netstat_group定义
点击(此处)折叠或打开#define NETSTAT_ENTRY(name) \static ssize_t name##_show(struct device *d, \
struct device_attribute *attr, char *buf) \
{ \
return netstat_show(d, attr, buf, \
offsetof(struct rtnl_link_stats64, name)); \
} \
static DEVICE_ATTR_RO(name)
NETSTAT_ENTRY(rx_packets);
NETSTAT_ENTRY(tx_packets);
NETSTAT_ENTRY(rx_bytes);
NETSTAT_ENTRY(tx_bytes);
NETSTAT_ENTRY(rx_errors);
NETSTAT_ENTRY(tx_errors);
NETSTAT_ENTRY(rx_dropped);
NETSTAT_ENTRY(tx_dropped);
NETSTAT_ENTRY(multicast);
NETSTAT_ENTRY(collisions);
NETSTAT_ENTRY(rx_length_errors);
NETSTAT_ENTRY(rx_over_errors);
NETSTAT_ENTRY(rx_crc_errors);
NETSTAT_ENTRY(rx_frame_errors);
NETSTAT_ENTRY(rx_fifo_errors);
NETSTAT_ENTRY(rx_missed_errors);
NETSTAT_ENTRY(tx_aborted_errors);
NETSTAT_ENTRY(tx_carrier_errors);
NETSTAT_ENTRY(tx_fifo_errors);
NETSTAT_ENTRY(tx_heartbeat_errors);
NETSTAT_ENTRY(tx_window_errors);
NETSTAT_ENTRY(rx_compressed);
NETSTAT_ENTRY(tx_compressed);
NETSTAT_ENTRY(rx_nohandler);
static struct attribute *netstat_attrs[] = {
&dev_attr_rx_packets.attr,
&dev_attr_tx_packets.attr,
&dev_attr_rx_bytes.attr,
&dev_attr_tx_bytes.attr,
&dev_attr_rx_errors.attr,
&dev_attr_tx_errors.attr,
&dev_attr_rx_dropped.attr,
&dev_attr_tx_dropped.attr,
&dev_attr_multicast.attr,
&dev_attr_collisions.attr,
&dev_attr_rx_length_errors.attr,
&dev_attr_rx_over_errors.attr,
&dev_attr_rx_crc_errors.attr,
&dev_attr_rx_frame_errors.attr,
&dev_attr_rx_fifo_errors.attr,
&dev_attr_rx_missed_errors.attr,
&dev_attr_tx_aborted_errors.attr,
&dev_attr_tx_carrier_errors.attr,
&dev_attr_tx_fifo_errors.attr,
&dev_attr_tx_heartbeat_errors.attr,
&dev_attr_tx_window_errors.attr,
&dev_attr_rx_compressed.attr,
&dev_attr_tx_compressed.attr,
&dev_attr_rx_nohandler.attr,
NULL
};
static struct attribute_group netstat_group = {
.name = "statistics",
.attrs = netstat_attrs,
};
netstat_show函数
点击(此处)折叠或打开#define __stringify_1(x...) #x#define __stringify(x...) __stringify_1(x)
#define __ATTR_RO(_name) { \
.attr = { .name = __stringify(_name), .mode = S_IRUGO }, \
.show = _name##_show, \
}
#define DEVICE_ATTR_RO(_name) \
struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
struct rtnl_link_stats64 *storage)
{
const struct net_device_ops *ops = dev->netdev_ops;
if (ops->ndo_get_stats64) {
memset(storage, 0, sizeof(*storage));
ops->ndo_get_stats64(dev, storage);
} else if (ops->ndo_get_stats) {
netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev));
} else {
netdev_stats_to_stats64(storage, &dev->stats);
}
storage->rx_dropped += atomic_long_read(&dev->rx_dropped);
storage->tx_dropped += atomic_long_read(&dev->tx_dropped);
storage->rx_nohandler += atomic_long_read(&dev->rx_nohandler);
return storage;
}
static ssize_t netstat_show(const struct device *d,
struct device_attribute *attr, char *buf,
unsigned long offset)
{
struct net_device *dev = to_net_dev(d);
ssize_t ret = -EINVAL;
WARN_ON(offset > sizeof(struct rtnl_link_stats64) ||
offset % sizeof(u64) != 0);
read_lock(&dev_base_lock);
if (dev_isalive(dev)) {
struct rtnl_link_stats64 temp;
const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
ret = sprintf(buf, fmt_u64, *(u64 *)(((u8 *) stats) + offset));
}
read_unlock(&dev_base_lock);
return ret;
}
dev_get_stats
通过dev_get_stats()函数可以知道,如果网卡有注册ndo_get_stats64()函数或者ndo_get_stats()函数,则通过网卡驱动获取stats数据,否则直接通过dev->stats获取。其他
net/core/dev.cregister_netdevice
net/core/net-sysfs.c
netdev_register_kobject()->
dev->groups = groups;
*groups++ = &netstat_group;
device_add()->device_add_attrs()->device_add_groups(dev->groups)->sysfs_create_groups() http://www.guc5469.cn/ http://www.dcj3647.cn/ http://www.utm9669.cn/ http://www.ahg7671.cn/ http://www.nxn1651.cn/ http://www.rrq5757.cn/ http://www.pbr1256.cn/ http://www.oai3459.cn/ http://www.vaj6107.cn/ http://www.xfc0942.cn/ http://www.evc2128.cn/ http://www.bwu7749.cn/ http://www.rmf4655.cn/ http://www.pyq8206.cn/ http://www.sdk5229.cn/ http://www.sez8143.cn/ http://www.tfn8353.cn/ http://www.uem3051.cn/ http://www.tza5452.cn/ http://www.epp9269.cn/ http://www.tsr7510.cn/ http://www.xhv3734.cn/ http://www.vrc9998.cn/ http://www.dsf5404.cn/ http://www.xjm6385.cn/ http://www.iaz1229.cn/ http://www.kcv6320.cn/ http://www.usl0022.cn/ http://www.abo8793.cn/ http://www.qeb9677.cn/ http://www.atx6995.cn/ http://www.buv6436.cn/ http://www.lll4952.cn/ http://www.cjx5965.cn/ http://www.otg2660.cn/ http://www.bmn9515.cn/ http://www.ewf1466.cn/ http://www.cbc3788.cn/ http://www.iqp5694.cn/ http://www.drr8954.cn/ http://www.blk2293.cn/ http://www.tjx3222.cn/ http://www.ksy2010.cn/ http://www.uva7574.cn/ http://www.epq3151.cn/ http://www.ofi3691.cn/ http://www.hwh7329.cn/ http://www.qta0411.cn/ http://www.oni7878.cn/ http://www.xlp3436.cn/ http://www.trm9066.cn/ http://www.wrq6652.cn/ http://www.oph4016.cn/ http://www.eis6490.cn/ http://www.xfq2422.cn/ http://www.tlj5370.cn/
相关文章推荐
- Android IPC数据在内核空间中的发送过程分析
- Android IPC数据在内核空间中的发送过程分析
- Android IPC数据在内核空间中的发送过程分析
- Linux 2.6内核启动传递命令行的过程分析
- 网络中数据传输过程的分析
- linux内核分析第六周-分析Linux内核创建一个新进程的过程
- 内核启动过程分析
- SPSS统计分析过程包括描述性统计、均值比较、一般线性模型、相关分析、回归分析、对数线性模型、聚类分析、数据简化、生存分析、时间序列分析、多重响应等几大类
- 跟踪分析Linux内核的启动过程
- 读取数据过程分析
- “Linux内核分析”实验报告(六)分析Linux内核创建一个新进程的过程
- 网络中数据传输过程的分析
- linux内核分析作业6:分析Linux内核创建一个新进程的过程
- C编程获取指定网卡网络数据包并分析(附C语言源码)
- Linux内核分析-分析Linux内核创建一个新进程的过程
- 6.分析Linux内核创建一个新进程的过程
- Eclipse+Pydev+用于数据分析package安装过程中的问题解决
- Linux内核设计第三周学习总结 跟踪分析Linux内核的启动过程
- Parcel数据传输过程,简要分析Binder流程
- web中国的数据分析过程