网络设备的注册与初始化

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

NIC可用之前,其相关联的net_device数据结构必须先初始化,添加到内核网络设备数据库、配置并开启。不要把注册/除名以及开启/关闭混淆是十分重要的,这是两种不同的概念:

  • 如果把加载设备驱动程序模块的动作排除的话,注册和除名是独立于用户之外的,是由内核驱动的。仅仅注册了的设备还不能运转。
  • 开启和关闭设备都需要用户参与。一旦设备已由内核注册,用户就可通过用户命令看到该设备,配置并予以开启。

设备注册之时

加载NIC设备驱动程序

如果NIC设备驱动程序内建至内核中,则在引导期间初始化;否则,如果以模块加载,就会在运行期间初始化;否则,如果以模块加载,就会在运行期间初始化。每当发生初始化时,该驱动程序所控制的所有NIC都会被注册。

插入可热插拔网络设备

当用户把可热插拔NIC设备插入进来时,内核会通知其驱动程序,而驱动程序在注册该设备。

设备除名之时

卸载NIC设备驱动程序

这仅是针对那些以模块加载的驱动程序,不适合那些内建至内核的驱动程序。当管理员卸载NIC设备驱动程序时,所有相关联的NIC都必须除名。

删除可热插拔网络设备

当用户从系统(其运行的内核支持可热插拔设备)删除可热插拔NIC时,则网络设备就会被除名。

设备注册状态通知

内核组件和用户空间应用程序可能都想知道何时发生网络设备注册、除名、关闭或者开启之事。这类事件的通知是通过两种通道传送的:

netdev_chain,内核组件可以注册此通知链。设备的注册和除名在各个阶段的进展都是通过netdev_chain通知链报告的。此链定义在net/core/dev.c中,而对此类事件感兴趣的内核组件可以通过register_netdevice_notifier和unregister_netdevice_notifier分别对该链注册或除名。

netdev_chain报告的事件:

NETDEV_UP,NETDEV_GOING_DOWN,NETDEV_DOWN,送出NETDEV_UP以报告设备已开启,而且此事件是由dev_open产生。当设备要关闭时,就会送出NETDEV_GOING_DOWN.当设备已关闭时,就会送出NETDEV_DOWN.这些事件都是由dev_close()产生的。

NETDEV_REGISTER设备已注册,此事件是有register_netdevice产生的。

NETDEV_UNREGISTER,设备已经除名,此事件是由unregister_netdevice产生的。

NETDEV_CHANGEADDR设备的硬件地址已改变。

NETDEV_CHANGENAME设备已改变其名称

NETDEV_CHANGE设备的状态或配置已经改变,此事件会用在上述情况未包括的其他情况下。

注意,向链注册时,register_netdevice_notifier也会(仅对新注册者)重放当前系统已注册设备的所有过去的NETDEV_REGISTER和NETDEV_UP通知信息。这样就能给新注册者有关已注册设备的清晰图像。内核注册该链的子系统:路由,使用此通知信息新增或删除与此设备相关联的所有路由项目;协议代码,当改变一个本地设备的MAC地址时,ARP表也必须据此更新。RTnetlink。

Netlink的RTMGRP_LINK多播群组,用户空间程序可以注册netlink的RTMGRP_LINK多播群组,当设备的状态或配置中有变更时,就会用rtmsg_ifinfo把通知信息传送给Link多播群组RTMGRP_LINK,其中一些通知信息如下:

  • 当netdev_chain通知链收到一个通知信息时,RTnetlink会注册前一节所提及的netdev_chain,然后重放其接受到的通知信息。
  • 当一个已关闭的设备开启时或者处于相反的过程。
  • 当net_device->flags中的一个标识有变动时。

netplugd是守护进程,会监听这些通知信息,然后根据用户配置文件而反应。

函数netdev_wait_allrefs

netdev_wait_allrefs由一个循环组成,只有当dev->refcnt建至零时才会结束。此函数每秒都会发送出一个NETDEV_UNREGISTER通知信息,而没10秒都会在控制台上打印出一条警告信息。剩余时间都在休眠。此函数直到对输入net_device结构的所有引用都已释放为止。有两种常见情况需要传送一个以上的通知信息:

bug,例如有段代码持有对net_device结构的引用,但是因为没有在netdev_chain通知链注册,或因为没有正确处理通知信息,使其无法释放。

未决的定时器,例如,假设当定时器到期时要执行的那个函数必须访问的数据中,包含了对net_device结构的引用。在这种情况下,你必须等待直到该定时器到期,而且其处理函数有望会释放其引用。

   1:  /*
   2:   * netdev_wait_allrefs - wait until all references are gone.
   3:   *
   4:   * This is called when unregistering network devices.
   5:   *
   6:   * Any protocol or device that holds a reference should register
   7:   * for netdevice notification, and cleanup and put back the
   8:   * reference if they receive an UNREGISTER event.
   9:   * We can get stuck here if buggy protocols don't correctly
  10:   * call dev_put.
  11:   */
  12:  static void netdev_wait_allrefs(struct net_device *dev)
  13:  {
  14:      unsigned long rebroadcast_time, warning_time;
  15:      int refcnt;
  16:   
  17:      linkwatch_forget_dev(dev);
  18:   
  19:      rebroadcast_time = warning_time = jiffies;
  20:      refcnt = netdev_refcnt_read(dev);
  21:   
  22:      while (refcnt != 0) {
  23:          if (time_after(jiffies, rebroadcast_time + 1 * HZ)) {
  24:              rtnl_lock();
  25:   
  26:              /* Rebroadcast unregister notification */
  27:              call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
  28:              /* don't resend NETDEV_UNREGISTER_BATCH, _BATCH users
  29:               * should have already handle it the first time */
  30:   
  31:              if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
  32:                       &dev->state)) {
  33:                  /* We must not have linkwatch events
  34:                   * pending on unregister. If this
  35:                   * happens, we simply run the queue
  36:                   * unscheduled, resulting in a noop
  37:                   * for this device.
  38:                   */
  39:                  linkwatch_run_queue();
  40:              }
  41:   
  42:              __rtnl_unlock();
  43:   
  44:              rebroadcast_time = jiffies;
  45:          }
  46:   
  47:          msleep(250);
  48:   
  49:          refcnt = netdev_refcnt_read(dev);
  50:   
  51:          if (time_after(jiffies, warning_time + 10 * HZ)) {
  52:              printk(KERN_EMERG "unregister_netdevice: "
  53:                     "waiting for %s to become free. Usage "
  54:                     "count = %d\n",
  55:                     dev->name, refcnt);
  56:              warning_time = jiffies;
  57:          }
  58:      }
  59:  }

开启和关闭网络设备

设备一旦注册就可用,但是,除非用户明确的开启,否则还是无法传输和接收数据流。开始设备函数为dev_open

  • 如果有定义的话,调用dev->open。并非所有设备驱动程序都初始化此函数
  • 设置dev->state中的__LINK_STATE_START标识,把设备标识为开启和运行中。
  • 设置dev->flags中的IFF_UP标识,把设备标识为开启。
  • 调用dev_activate以初始化由流量控制使用的出口队列规则,然后启动看门狗定时器。如果流量控制没有用户配置,就指定默认的FIFO
  • 传送NETDEV_UP通知信息给netdev_chain通知链,以通知感兴趣的内核组件,该设备现已开启。

设备关闭

  • 传送NETDEV_GOING_DOWN通知信息给netdev_chain通知链,以通知感兴趣的内核组件该设备即将被关闭
  • 调用dev_deactivate以关闭出口队列规则,使得该设备再也无法用于传输,然后因为不在需要,停止看门狗定时器
  • 清除dev->state中的__LINK_STATE_START标识,把设备标识为关闭
  • 如果一个轮询动作被调度,以读取设备上的入口封包,就要等待该动作完成。因为__LINK_STATE_START标识已被清除,该设备上已不能再为其他接收的轮询动作进行调度了,但是在该标志清除前可能有一个轮询动作未决。
  • 如果有定义,调用dev->stop。
  • 清除dev->flags中的IFF_UP标识,把设备标识为关闭
  • 传送NETDEV_DOWN通知链

链接状态变更侦测

可能导致链接状态变更的一些情况:

1,电缆线插入NIC,或者从NIC中拔出。

2. 电缆线另一端的设备电源关掉或关闭了。这类设备有HUB,桥接器,路由器以及PC NIC等

转载于:https://my.oschina.net/longscu/blog/57354

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/267075.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java jdbc reparecall_Java Connection.prepareCall方法代碼示例

本文整理匯總了Java中java.sql.Connection.prepareCall方法的典型用法代碼示例。如果您正苦於以下問題:Java Connection.prepareCall方法的具體用法?Java Connection.prepareCall怎麽用?Java Connection.prepareCall使用的例子?那…

Vue提供操作DOM的方法

<div ref"wrapper"> Vue.js 提供了我们一个获取 DOM 对象的接口—— vm.$refs。在这里&#xff0c;我们通过了 this.$refs.wrapper访问到了这个 DOM 对象&#xff0c;并且我们在 mounted 这个钩子函数里&#xff0c;this.$nextTick 的回调函数中初始化 因为 V…

[转]敏捷开发中编写高质量Java代码

本文转自&#xff1a;http://dev.yesky.com/103/11164603.shtml 敏捷开发的理念已经流行了很长的时间&#xff0c;在敏捷开发中的开发迭代阶段中&#xff0c;我们可以通过五个步骤&#xff0c;来有效的提高整个项目的代码质量。 Java项目开发过程中&#xff0c;由于开发人员的…

java静态成员方法_java的静态成员、静态方法的注意事项!

在JAVA中&#xff0c;存在内部类和外部类&#xff0c;如果出现有static时&#xff0c;大家应注意&#xff1a;1、 静态内部类不能直接访问外部类的非静态成员&#xff0c;但可以通过new 外部类().成员 的方式访问2、 如果外部类的静态成员与内部类的成员名称相同&#xff0c;可…

php实现姓名按首字母排序的类与方法

php将名字按首字母进行排序 <?php public function getFirstChar($s){$s0 mb_substr($s,0,3); //获取名字的姓$s iconv(UTF-8,gb2312, $s0); //将UTF-8转换成GB2312编码//dump($s0);if (ord($s0)>128) { //汉字开头&#xff0c;汉字没有以U、V开头的$ascord($s{0})*25…

ios3怎么取消长按弹出菜单_苹果:iOS13取消3D-Touch重压改为长按只是个BUG~

原标题&#xff1a;苹果&#xff1a;iOS13取消3D-Touch重压改为长按只是个BUG~目前iOS 13中3D-Touch功能在桌面级菜单采用的是类似iPhone XR的触觉感应(Haptic touch)&#xff0c;用户只需要长按App图标即可呼出菜单&#xff0c;继续长按则会出现删除应用的抖动界面。不同于以往…

设△ABC的内角A,B,C,所对的边分别为a,b,c,且acosB-bcosA=3/5c,则tan(A-B)的最大值为

设△ABC的内角A,B,C,所对的边分别为a,b,c,且acosB-bcosA3/5c,则tan(A-B)的最大值为 转载于:https://www.cnblogs.com/Mary-Sue/p/9048289.html

BGP笔记1

1、BGP属于EGP&#xff0c;是高级DV协议&#xff0c;也被称为路径矢量协议&#xff0c;基于TCP 179端口。 2、现在使用版本BGP-4。 3、第一次做完整更新&#xff0c;以后就只增量更新 4、Autonomous Systems&#xff1a;运行同一种选路策略&#xff0c;由统一管理者管理。 1&am…

java 打包下载文件_java下载打包下载文件

一&#xff1a;对于文件的一些操作1.创建文件夹private String CreateFile(String dir) {File file new File(dir);if (!file.exists()) {//创建文件夹boolean mkdir file.mkdir();} else {}return dir;}2.复制文件private void copyFile(File source, File dest) throws IOE…

也说读书

记得当年毕业前夕&#xff0c;一位教授说&#xff1a;“希望你们毕业后&#xff0c;能坚持每年读10本书。”当时不以为然&#xff0c;区区十本&#xff0c;岂非小菜&#xff01;毕业后&#xff0c;迫于生计&#xff0c;东奔西走&#xff0c;很难静心读书&#xff0c;偶尔拿起书…

C# 巧用anchor和dock设计复杂界面(控件随着窗体大小的变化而变化)【转】

这个在做winform程序的空间编程的时候遇到过太多次了&#xff0c;自己也想留下点经验&#xff0c;搜索了一下&#xff0c;这篇文章很好很强大了&#xff0c;感谢博主“驴子的菜园”。 程序界面如上 各部分简要说明&#xff1a; 整个窗体上覆盖一个splitcontainer。 splitcontai…

修改java启动参数_如何修改jvm启动参数

用java命令查看。用java -option进行修改参数。还有tomcat&#xff0c;eclipse启动时通过配置文件加载的。详细如下&#xff1a;安装Java开发软件时&#xff0c;默认安装包含两个文件夹&#xff0c;一个JDK(Java开发工具箱)&#xff0c;一个JRE(Java运行环境&#xff0c;内含JV…

非常完善的Log4net详细说明(转)

最可能来源&#xff1a;https://blog.csdn.net/ydm19891101/article/details/50561638 其它转载者&#xff1a;http://www.cnblogs.com/zhangchenliang/p/4546352.html 1、概述 log4net是.Net下一个非常优秀的开源日志记录组件。log4net记录日志的功能非常强大。它可以将日志分…

话说招聘面试

最近公司有一个新项目&#xff0c;是一个软件和硬件结合的项目&#xff0c;具体的就是一个cs软件通过485通信操作硬件的基站&#xff0c;基站上面挂着传感器和其他设备&#xff0c; 当然我只负责软件也就是上位机部分。通过1个月多的时间&#xff0c;每天开会开会调研调研&…

mysql内链接与交叉连接_SQLServer 2008中的交叉连接与内部连接

这里是交叉连接和内部连接的最佳示例。考虑下表表&#xff1a;Teacherx------------------------x| TchrId | TeacherName |x----------|-------------x| T1 | Mary || T2 | Jim |x------------------------x表&#xff1a;Studentx-------------…

获得数据库中表字段的名字.txt

获得数据库中所有数据库的名字&#xff1a;select name From sysdatabases 获得某个数据库中所有表的名字&#xff1a;select name from sysobjects where typeU获得某个表中字段的名字&#xff1a;select name from syscolumns where idobject_id(表名)use masterif exists(S…

java pause_java – 更有效的暂停循环方式

可用的工具是&#xff1a;等待/通知 – 我们都试图摆脱这个古老的系统.信号量 – 一旦你的线程抓住它,你持有它直到释放,所以再次抓住它不会阻止.这意味着您无法在自己的线程中暂停.CyclicBarrier – 每次使用时都必须重新创建.ReadWriteLock – 我的最爱.您可以让任意多个线程…

jmeter java接口_JMeter接口Java开发五步曲

想做jmeter接口二次开发但不知道如何入手&#xff0c;要解决这个问题&#xff0c;我们可以分为5个步骤第一步&#xff1a;了解jmeter处理java请求的流程第二步&#xff1a;通过实现jmeter中的接口JavaSamplerClient编写自定义JAVA接口第三步&#xff1a;打包第四步&#xff1a;…

循环

# l []# for x in range(3,10):# #pass# l.append(x)# print(x,:,l)# print(l)#break/continue(break:终止。continue:继续)#list [1,2,3,4] #遍历# for x in list:# if x 3:# print(x,#*20)# break #终止当前循环# else:# pr…

Redhat ssh服务登录慢

redhat在安装以后每次通过ssh服务登录&#xff0c;要等待几秒才能进入。 只要在sshd_config修改一下以下值就好 vim /etc/ssh/sshd_config UseDNS no service sshd restart 再次用ssh终端登录就快了转载于:https://www.cnblogs.com/passedbylove/p/9070405.html