VPP启动

VPP启动在上文说到 在 VPP 启动之前 会提前通过宏定义的方式注册各种需要初始化的业务逻辑函数 本文主要介绍 VPP 的启动流程 nbsp VPP 的入口函数在 src vpp vnet main c1 nbsp nbsp nbsp 加载 startup conf 获取配置信息 VPP 启动 可以通过命令 如 vpp c etc vpp startup conf 启动 startup conf 包含了 VPP 默认的配置信息 涉及多种配置参数

在上文说到,在VPP启动之前,会提前通过宏定义的方式注册各种需要初始化的业务逻辑函数,本文主要介绍VPP的启动流程

 

VPP的入口函数在src/vpp/vnet/main.c

1.   加载startup.conf,获取配置信息

VPP启动,可以通过命令:如vpp –c /etc/vpp/startup.conf启动

startup.conf包含了VPP默认的配置信息,涉及多种配置参数,每个参数用大括号进行区分:

可以包含的默认配置有:具体可见:https://wiki.fd.io/view/VPP/Command-line_Arguments

VPP启动时主要关心:pluginpath和heapsize,获取plugin路径和堆大小

2.   clib_mem_init:

根据默认配置,分配主堆内存

3.   vpe_main_init:

设置VPP提示,

 

注册srp_ips_process_node, srp_input_node, srp_control_input_node3个node节点

 

此处没细研究,主要理解应该是实现旁路操作系统,实现网络数据直接在网卡和VPP之间传递做准备

4.   vlib_unix_main

核心的启动业务逻辑就在该函数中:

int vlib_unix_main (int argc, char *argv[])

{

 vlib_main_t *vm = &vlib_global_main;        /*one and only time for this! */

 vlib_thread_main_t *tm = &vlib_thread_main;

 unformat_input_t input;

  u8*thread_stacks;

 clib_error_t *e;

  inti;

 

 vm->argv = (u8 ) argv;

 vm->name = argv[0];

 vm->heap_base = clib_mem_get_heap ();

 ASSERT (vm->heap_base);

 

 unformat_init_command_line (&input, (char ) vm->argv);

  //获取plugin信息并填充结构体

if ((e = vlib_plugin_config (vm, &input)))

    {

     clib_error_report (e);

     return 1;

    }

 unformat_free (&input);

 

  //加载启动插件功能

  i =vlib_plugin_early_init (vm);

  if(i)

   return i;

 

 unformat_init_command_line (&input, (char ) vm->argv);

  if(vm->init_functions_called == 0)

   vm->init_functions_called = hash_create (0, /* value bytes */ 0);

  //启动所有宏定义VLIB_EARLY_CONFIG_FUNCTION和VLIB_CONFIG_FUNCTION注册的链表函数

e = vlib_call_all_config_functions (vm, &input, 1 /* early */ );

  if(e != 0)

    {

     clib_error_report (e);

     return 1;

    }

 unformat_free (&input);

 

  /*

   *allocate n x VLIB_THREAD_STACK_SIZE stacks, aligned to a

   *VLIB_THREAD_STACK_SIZE boundary

   *See also: os_get_cpu_number() in vlib/vlib/threads.c

   */

 thread_stacks = clib_mem_alloc_aligned

   ((uword) tm->n_thread_stacks * VLIB_THREAD_STACK_SIZE,

    VLIB_THREAD_STACK_SIZE);

 

 vec_validate (vlib_thread_stacks, tm->n_thread_stacks – 1);

  for(i = 0; i < vec_len (vlib_thread_stacks); i++)

    {

     vlib_thread_stacks[i] = thread_stacks;

 

     /*

      * Disallow writes to the bottom page of the stack, to

      * catch stack overflows.

      */

     if (mprotect (thread_stacks, clib_mem_get_page_size (), PROT_READ) <0)

         clib_unix_warning(“thread stack”);

 

     thread_stacks += VLIB_THREAD_STACK_SIZE;

    }

 

 //这里启动thread0

  i =clib_calljmp (thread0, (uword) vm,

                       (void *) (vlib_thread_stacks[0] +

                                  VLIB_THREAD_STACK_SIZE));

 return i;

}

5.   vlib/unix/main.c的thread0()函数

调用vlib/中的vlib_main函数

vlib_main (vlib_main_t * volatile vm,unformat_input_t * input)

{

 clib_error_t *volatile error;

 

 vm->queue_signal_callback = dummy_queue_signal_callback;

 

 clib_time_init (&vm->clib_time);

 

  /*Turn on event log. */

  if(!vm->elog_main.event_ring_size)

   vm->elog_main.event_ring_size = 128 << 10;

 elog_init (&vm->elog_main, vm->elog_main.event_ring_size);

 elog_enable_disable (&vm->elog_main, 1);

 

  /*Default name. */

  if(!vm->name)

   vm->name = “VLIB”;

 

 vec_validate (vm->buffer_main, 0);

 vlib_buffer_cb_init (vm);

 

  if((error = vlib_thread_init (vm)))

    {

     clib_error_report (error);

     goto done;

    }

 

 //启动宏定义VLIB_REGISTER_NODE注册的所有node节点功能函数,功能比较简单,就是将各个节点加到一个vlib_node_main_t-> nodes

  /*Register static nodes so that init functions may use them. */

 vlib_register_all_static_nodes (vm);

 

  /*Set seed for random number generator.

    Allow user to specify seed to make random sequence deterministic. */

  if(!unformat (input, “seed %wd”, &vm->random_seed))

   vm->random_seed = clib_cpu_time_now ();

 clib_random_buffer_init (&vm->random_buffer, vm->random_seed);

 

  /*Initialize node graph. */

//初始化node graph,看代码基本就是填充节点关系字段

  if((error = vlib_node_main_init (vm)))

    {

     /* Arrange for graph hook up error to not be fatal when debugging. */

     if (CLIB_DEBUG > 0)

         clib_error_report(error);

     else

         gotodone;

    }

 

  /*See unix/main.c; most likely already set up */

  if(vm->init_functions_called == 0)

   vm->init_functions_called = hash_create (0, /* value bytes */ 0);

//启动所有宏定义VLIB_INIT_FUNCTION:注册的链表函数

if ((error = vlib_call_all_init_functions(vm)))

   goto done;

 

  /*Create default buffer free list. */

 vlib_buffer_get_or_create_free_list (vm,

                                            VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES,

                                            “default”);

 

 switch (clib_setjmp (&vm->main_loop_exit,VLIB_MAIN_LOOP_EXIT_NONE))

    {

   case VLIB_MAIN_LOOP_EXIT_NONE:

     vm->main_loop_exit_set = 1;

     break;

 

   case VLIB_MAIN_LOOP_EXIT_CLI:

     goto done;

 

   default:

     error = vm->main_loop_error;

     goto done;

    }

 

  if((error = vlib_call_all_config_functions (vm, input, 0 /* is_early */ )))

   goto done;

 

 

  /*Call all main loop enter functions. */

  {

   clib_error_t *sub_error;

   //启动宏定义VLIB_MAIN_LOOP_ENTER_FUNCTION指定的函数,这里主要启动thread.c中的start_workers

 sub_error =vlib_call_all_main_loop_enter_functions (vm);

   if (sub_error)

     clib_error_report (sub_error);

  }

  //处理节点的核心功能函数

 vlib_main_loop (vm);

 

done:

  /*Call all exit functions. */

  {

   clib_error_t *sub_error;

   sub_error = vlib_call_all_main_loop_exit_functions (vm);

   if (sub_error)

     clib_error_report (sub_error);

  }

 

  if(error)

   clib_error_report (error);

 

 return 0;

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232238.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Excel连接字符串「建议收藏」

    Excel连接字符串「建议收藏」通过OleDb方式读取Excel文件时常常出现读取某些字段为null值,其实是有值,原因是读取文件时,Excel通常会以前10行的数据类型为参考,如果后边的与其不一致,则会出现些问题。可以通过修改E

    2022年8月3日
    6
  • noip2014普及组复赛题解_noip2019普及组复赛试题

    noip2014普及组复赛题解_noip2019普及组复赛试题NOIP2012普及组解题报告            byRtPYH——————————————————————————————————————前言:作者是一个蒟蒻,如果对本文有建议,欢迎提出!鄙人将虚心接受。

    2022年8月22日
    7
  • J2ME开发站点资源「建议收藏」

    J2ME开发站点资源「建议收藏」英文站点,英文好的开发者应该收藏的站点。SUNJ2MEWebSite:http://java.sun.com/j2me/诺基亚开发论坛:http://discussion.forum.nokia.com/forum/IBMalphaworks:http://alphaworks.ibm.com/wirelessIBM新兴技术资源网站,这里有各种最新的技术,当然也有非常丰富的J2ME开发资

    2022年7月27日
    3
  • 全新安装Mac OSX 开发者环境 同时使用homebrew搭建 (LNMP开发环境)

    全新安装Mac OSX 开发者环境 同时使用homebrew搭建 (LNMP开发环境)

    2021年5月11日
    219
  • RAID10磁盘阵列损坏修复操作

    RAID10磁盘阵列损坏修复操作-f模拟硬盘损坏mdadm/dev/md0-f/dev/sdb1、查看损坏磁盘阵列的情况2、将损坏的硬盘设备移除3、插上新的硬盘(在真机上操作,虚拟机之间将损坏的硬盘删除,然后在添加新的硬盘即可)4、卸载挂载操作5、将新的硬盘添加到RAID10磁盘阵列中6、查看修复成功后的磁盘阵列信息(因为新添加的需要等待一段时间等待系统重新创建)7、重新挂载1、查看损坏后的磁盘阵列信息2、将损坏的硬盘从磁盘阵列中移除mdadm/dev/md0-r损坏的硬盘设备名mdadm-D/

    2022年6月3日
    41
  • socket使用方法_socket调试工具怎么用

    socket使用方法_socket调试工具怎么用socketpair函数概要如下:#include#includeintsocketpair(intdomain,inttype,intprotocol,intsv[2]);sys/types.h文件需要用来定义一些C宏常量。sys/socket.h文件必须包含进来定义socketpair函数原型。socketpair函数需要四个参数。他们是:套接口的域

    2022年10月14日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号