OVS vswitchd 模块分析(2)


3.bridge,ofproto模块是vswitchd的核心,启动的时候初始化网桥(OVSDB配置相关),接着依次运行RPC服务,网桥,网络设备相关的调用。
----------vswitchd/ovs-vswitchd.c
     bridge_init(remote);
    free(remote);

    exiting = false;
    while (!exiting) {
        worker_run();
        bridge_run_fast();
        bridge_run();
        bridge_run_fast();
        unixctl_server_run(unixctl);
        netdev_run();
............
---------lib/worker.c
3.1 如果该进程启动了一个worker(client_sock >= 0)并且没有发生故障,调用reply_cb来回复。其实就相当于多线程,时刻待命响应主进程的各种请求。
void worker_run(void){
    if (worker_is_running()) {
        int error;

        error = rxbuf_run(&client_rx, client_sock, sizeof(struct worker_reply));
        if (!error) {
            struct worker_reply *reply = client_rx.header.data;
            reply->reply_cb(&client_rx.payload, client_rx.fds, client_rx.n_fds, reply->reply_aux);
            rxbuf_clear(&client_rx);
        } else if (error != EAGAIN) {
            worker_broke();
            VLOG_ABORT("receive from worker failed (%s)",
                       ovs_retval_to_string(error));
        }
    }
}

3.2  函数 bridge_run_fast执行间歇性的活动:遍历所有的网桥,然后完成of switch的功能(通过bridge->ofproto)。在每次轮询循环中多次呼叫这个函数很有意义,因为ofprotos使用ofproto-dpif 实现,可以有性能提升。
     函数 bridge_run 通过和ovsdb的沟通维护一些系统状态,核心逻辑仍然是通过ofproto完成相应的任务。

void   bridge_run_fast(void) {
    struct bridge *br;

    HMAP_FOR_EACH (br, node, &all_bridges) {
        ofproto_run_fast(br->ofproto);
    }
}

void bridge_run(void) {
    static const struct ovsrec_open_vswitch null_cfg;
    const struct ovsrec_open_vswitch *cfg;
    struct ovsdb_idl_txn *reconf_txn = NULL;

    bool vlan_splinters_changed;
    struct bridge *br;

    ovsrec_open_vswitch_init((struct ovsrec_open_vswitch *) &null_cfg);

    /* (Re)configure if necessary. */
    if (!reconfiguring) {
        ovsdb_idl_run(idl);

        if (ovsdb_idl_is_lock_contended(idl)) {
            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
            struct bridge *br, *next_br;

            VLOG_ERR_RL(&rl, "another ovs-vswitchd process is running, disabling this process until it goes away");

            HMAP_FOR_EACH_SAFE (br, next_br, node, &all_bridges) {
                bridge_destroy(br);
            }
            return;
        } else if (!ovsdb_idl_has_lock(idl)) {
            return;
        }
    }
    cfg = ovsrec_open_vswitch_first(idl);

    /* Let each bridge do the work that it needs to do. */
    HMAP_FOR_EACH (br, node, &all_bridges) {
        ofproto_run(br->ofproto);
    }

    /* 重新配置SSL,选择在主循环中而不是在数据库改变的时候配置ssl,是因为在没有数据库改变的情况下key和certificate文件内容也会改变;选择在 bridge_reconfigure()之前是因为这个函数可能需要初始化SSL连接(需要配置SSL)。 */
    if (cfg && cfg->ssl) {
        const struct ovsrec_ssl *ssl = cfg->ssl;

        stream_ssl_set_key_and_cert(ssl->private_key, ssl->certificate);
        stream_ssl_set_ca_cert_file(ssl->ca_cert, ssl->bootstrap_ca_cert);
    }

    if (!reconfiguring) {
        /* If VLAN splinters are in use, then we need to reconfigure if VLAN usage has changed. */
        vlan_splinters_changed = false;
        if (vlan_splinters_enabled_anywhere) {
            HMAP_FOR_EACH (br, node, &all_bridges) {
                if (ofproto_has_vlan_usage_changed(br->ofproto)) {
                    vlan_splinters_changed = true;
                    break;
                }
            }
        }

        if (ovsdb_idl_get_seqno(idl) != idl_seqno || vlan_splinters_changed) {
            idl_seqno = ovsdb_idl_get_seqno(idl);
            if (cfg) {
                reconf_txn = ovsdb_idl_txn_create(idl);
                bridge_reconfigure(cfg);
            } else {
                /* We still need to reconfigure to avoid dangling pointers to
                 * now-destroyed ovsrec structures inside bridge data. */
                bridge_reconfigure(&null_cfg);
            }
        }
    }

    if (reconfiguring) {
        if (cfg) {
            if (!reconf_txn) {
                reconf_txn = ovsdb_idl_txn_create(idl);
            }
            if (bridge_reconfigure_continue(cfg)) {
                ovsrec_open_vswitch_set_cur_cfg(cfg, cfg->next_cfg);
            }
        } else {
            bridge_reconfigure_continue(&null_cfg);
        }
    }

    if (reconf_txn) {
        ovsdb_idl_txn_commit(reconf_txn);
        ovsdb_idl_txn_destroy(reconf_txn);
        reconf_txn = NULL;
    }

    /* Refresh interface and mirror stats if necessary. */
    if (time_msec() >= iface_stats_timer) {
        if (cfg) {
            struct ovsdb_idl_txn *txn;

            txn = ovsdb_idl_txn_create(idl);
            HMAP_FOR_EACH (br, node, &all_bridges) {
                struct port *port;
                struct mirror *m;

                HMAP_FOR_EACH (port, hmap_n
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值