OVS代码笔记

OVS代码笔记

>> 原创文章,转载请保留地址,欢迎交流学习

  • ovsdb-client:

 

从main开始分析:

1、for (command = get_all_commands(); ; command++) {

        if (!command->name) {

            VLOG_FATAL("unknown command '%s'; use --help for help",

                       argv[optind]);

        } else if (!strcmp(command->name, argv[optind])) {

            break;

        }

}

获取ovsdb-client的相关的cmd操作的指针command,为后面的命令参数操作和命令实际操作函数handler做准备;这里的get_all_commands比较简单就不展开分析了;

 

2、if (command->need != NEED_NONE) {

        if (argc - optind > command->min_args

            && (isalpha((unsigned char) argv[optind][0])

                && strchr(argv[optind], ':'))) {

            rpc = open_jsonrpc(argv[optind++]);

        } else {

            char *sock = xasprintf("unix:%s/db.sock", ovs_rundir());

            rpc = open_jsonrpc(sock);

            free(sock);

        }

    } else {

        rpc = NULL;

}

这段代码的主要作用就是根据SERVER参数返回rpc(一般默认的SERVER的参数为unix:/usr/local/var/run/openvswitch/db.sock);该数据结构如下:

struct jsonrpc {

    struct stream *stream;

    char *name;

    int status;

 

    /* Input. */

    struct byteq input;

    uint8_t input_buffer[512];

    struct json_parser *parser;

 

    /* Output. */

    struct ovs_list output;     /* Contains "struct ofpbuf"s. */

    size_t output_count;        /* Number of elements in "output". */

    size_t backlog;

};

其中比较重要的几个部分是:

  1. stream,该指针通过函数jsonrpc_stream_open来实现其返回值;具体的做法是通过SERVER的名字查找到之前就定义好的stream class(这里默认的是unix_stream_class),然后用定义好的该stream class的open函数去填充stream中的内容,包括它自己的stream class(注意这里的stream class被修改为了stream_fd_class,后续会利用该stream class中的内容去处理stream信息),填充name为SERVER,至此,stream的相关的处理就完成了(这里仍然有部分细节还需要再分析);
  2. 得到了stream之后,再使用jsonrpc_open函数去根据stream得到这里比较重要的jsonrpc信息;具体的做法是新分配一个jsonrpc结构体,然后使用a中的stream来初始化jsonrpc中的stream和name信息,然后再初始化input和output相关的信息;

 

  1. if (command->need == NEED_DATABASE) {

        struct svec dbs;

 

        svec_init(&dbs);

        fetch_dbs(rpc, &dbs);

        if (argc - optind > command->min_args

            && svec_contains(&dbs, argv[optind])) {

            database = argv[optind++];

        } else if (dbs.n == 1) {

            database = xstrdup(dbs.names[0]);

        } else if (svec_contains(&dbs, "Open_vSwitch")) {

            database = "Open_vSwitch";

        } else {

            ovs_fatal(0, "no default database for `%s' command, please "

                      "specify a database name", command->name);

        }

        svec_destroy(&dbs);

    } else {

        database = NULL;

    }

 

    if (argc - optind < command->min_args ||

        argc - optind > command->max_args) {

        VLOG_FATAL("invalid syntax for '%s' (use --help for help)",

                    command->name);

    }

 

    command->handler(rpc, database, argc - optind, argv + optind);

 

    jsonrpc_close(rpc);

该段流程主要是完成了database的命名,并且根据相关的参数信息去完成handler的操作,该操作的主要调用流程可以查看all_commands命令的的处理(这里涉及到的细节较多,可以等待分析各个操作的时候再来分析);

 

  • Ovsdb_server:

shash_find_data(const struct shash *sh, const char *name):根据DATABASE-NAME查找出来ovsdb;

关注shash_node和shash之间的关系以及它们如何关联起来?

 

server_config结构:

struct server_config {

    struct sset *remotes;

    struct shash *all_dbs;

    FILE *config_tmpfile;

    struct ovsdb_jsonrpc_server *jsonrpc;

};

下面以server的main函数为例说明:

Remotes:存放DB相关的参数,其实主要存储了DB的name,以hash方式存储;

All_dbs:将结构体db(该结构体在ovsdb_file_open函数中做好了实例化操作)作为hash参数放入到其中,以hash方式存储;

Config_tmpfile:存放DB相关的参数的临时文件,包括了remotes和dbfilename;

Jsonrpc:存放被server服务的DB,最后将上面的db结构中的ovsdb结构体放入到jsonrpc->up.dbs中,以hash方式存储;另外其中的remotes存放的是ovsdb_jsonrpc_remote结构,以hash方式存储在node下的data中;

 

除此之外,还有一个比较重要的函数处理:reconfigure_remotes,它的第一个作用是将之前处理好的all_dbs中的数据库相关的数据获取出来并放入另外一个类似的临时结构中(该数据库的内容以hash方式存放在其中,这里比较不理解的是,在查找hash的过程中,返回来的void值都是以ovsdb_jsonrpc_options指针的形式返回的?其他的疑问为此处以数据库的内容为hash方式向hash中存放的是ovsdb_jsonrpc_options结构?该结构中并没有什么数据,最终以shash_node方式呈现,name存放的就是string类型的数据的内容,data存放的就是之前的ovsdb_jsonrpc_options结构。);另外一个作用是配置ovsdb_jsonrpc_server中的remotes项,该remotes以hash方式存放在node下的data中,数据内容为ovsdb_jsonrpc_remote结构;

 

Ovsdb_jsonrpc_remote结构:

struct ovsdb_jsonrpc_remote {

    struct ovsdb_jsonrpc_server *server;

    struct pstream *listener;   /* Listener, if passive. */

    struct ovs_list sessions;   /* List of "struct ovsdb_jsonrpc_session"s. */

    uint8_t dscp;

};

Server:该结构和ovsdb_jsonrpc_remote相互关联,首先该结构和ovsdb_jsonrpc_remote中的server是同一块区域,其次ovsdb_jsonrpc_remote结构会以void *data的形式添加到ovsdb_jsonrpc_server的remotes哈希map结构的节点中;

Listener:跟我们的连接的方式(ptcp、punix、pssl等)有关系的一个pstream变量,该变量和client获取的方式类似;

Sessions:ovsdb_jsonrpc_sessions结构的链表,将ovsdb_jsonrpc_session中的node节点插入到该链表中;

 

 

 

Ovsdb_jsonrpc_server结构:

struct ovsdb_jsonrpc_server {

    struct ovsdb_server up;

    unsigned int n_sessions, max_sessions;

    struct shash remotes;      /* Contains "struct ovsdb_jsonrpc_remote *"s. */

};

up:目前没有发现该结构体的用途,因为只有初始化了,但是实际并没有做赋值操作,在注释中显示的是跟ovsdb关联的数据结构体(该结构的实际用途就是将ovsdb结构以hash方式存储在该ovsdb_server中,参见上面的server_config结构的说明);

n_sessions, max_sessions:表示了连接的数量和最多连接的数量;

remotes:该结构用来以哈希方式存储ovsdb_jsonrpc_remote的结构,可以参见上面的ovsdb_jsonrpc_remote结构的描述;

 

 

 

Ovsdb_server结构:

struct ovsdb_server {

    struct shash dbs;      /* Maps from a db name to a "struct ovsdb *". */

    struct hmap locks;     /* Contains "struct ovsdb_lock"s indexed by name. */

};

dbs:暂时没有发现什么用途;

locks:暂时没有发现什么用途;

 

 

Ovsdb_jsonrpc_session结构:

struct ovsdb_jsonrpc_session {

    struct ovs_list node;       /* Element in remote's sessions list. */

    struct ovsdb_session up;

    struct ovsdb_jsonrpc_remote *remote;

 

    /* Triggers. */

    struct hmap triggers;       /* Hmap of "struct ovsdb_jsonrpc_trigger"s. */

 

    /* Monitors. */

    struct hmap monitors;       /* Hmap of "struct ovsdb_jsonrpc_monitor"s. */

 

    /* Network connectivity. */

    struct jsonrpc_session *js;  /* JSON-RPC session. */

    unsigned int js_seqno;       /* Last jsonrpc_session_get_seqno() value. */

};

node:该节点为remote session的元素,最终该节点会被挂接到ovsdb_jsonrpc_remote结构中的sessions中去;

up:该结构和ovsdb_server类似,只是该节点表示client;

remote:该结构和ovsdb_jsonrpc_remote关联起来;

triggers:ovsdb_jsonrpc_trigger结构体的hash map;

monitors:ovsdb_jsonrpc_monitor结构体的hash map;

js:jsonrpc的session,该结构会和初始化好的jsonrpc_session关联起来;

js_seqno:用于存储上次的jsonrpc_session_get_seqno值,初始化时为0;

 

 

 

Jsonrpc_session结构:

struct jsonrpc_session {

    struct reconnect *reconnect;

    struct jsonrpc *rpc;

    struct stream *stream;

    struct pstream *pstream;

    int last_error;

    unsigned int seqno;

    uint8_t dscp;

};

reconnect:暂时不知道用途;

rpc:jsonrpc相关的结构,该结构会在client中进行描述说明;

stream:active stream connection相关的结构;

pstream:passive listener相关的结构;

last_error:应该是用于错误信息,暂时不知道其用途;

seqno:用于存储上次的jsonrpc_session_get_seqno值,初始化时为0;

sdcp:暂时不知道其用途;

 

 

 

Ovsdb_session结构:

struct ovsdb_session {

    struct ovsdb_server *server;

    struct ovs_list completions;/* Completed triggers. */

    struct hmap waiters;        /* "ovsdb_lock_waiter *"s by lock name. */

};

server:该结构会和ovsdb_jsonrpc_server中的ovsdb_server关联起来;

completions:从注释来看用于trigger的链表,暂时没有发现用途;

waiters:从注释来看用于ovsdb_lock_waiter的链表,暂时没有发现用途;

 

ovsdb结构:

struct ovsdb {

    struct ovsdb_schema *schema;

    struct ovs_list replicas;   /* Contains "struct ovsdb_replica"s. */

    struct shash tables;        /* Contains "struct ovsdb_table *"s. */

 

    /* Triggers. */

    struct ovs_list triggers;   /* Contains "struct ovsdb_trigger"s. */

    bool run_triggers;

};

Schema:database schema结构;

Replicas:用于处理ovsdb_replica的链表;

Tables:用于处理ovsdb_table的hash;

Triggers:用于处理ovsdb_trigger的链表;

Run_trigger:运行trigger标志位;

 

 

Ovsdb_schema结构:

/* Database schema. */

struct ovsdb_schema {

    char *name;

    char *version;

    char *cksum;

    struct shash tables;        /* Contains "struct ovsdb_table_schema *"s. */

};

 

 

 

 

  •  

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值