DAOS引擎启动流程-源码分析

2023-10-11 19:20

本文主要是介绍DAOS引擎启动流程-源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

执行:daos_server start, server通过golang调用engine的c

daos_enginedaos_server start
opts.name = "daos_engine"
engine/init.c
main(int argc, char **argv)
engine启动
parse 解析命令行参数: /usr/bin/ubip_engine -t 24 -x 2 -g ubip_server -d /var/run/ubip_server -T 2 -n /mnt/ubip0/ubip_nveme.conf -p 0 -I 0 -r 24567 -H 2 -s /mnt/ubip0
-p 绑定到哪个numa节点(pinned_numa_node)
-t 24 targets数量
-x xshelpernr 2个辅助线程docker
"/opt/daos/bin/daos_engine",  "-t",  "1",  "-x",  "0",  "-g",  "daos_server",  "-d",  "/var/run/daos_server",  "-T",  "2",  "-n",  "/mnt/daos/daos_nvme.conf",  "-I",  "0",  "-r",  "8192",  "-H",  "2",  "-s",  "/mnt/daos"禁用透明大页
daos_register_sighand(SIGILL, print_backtrace); 注册自己的信号和打印堆栈
server_inithlc_recovery_begingethostnamedaos_debug_set_id_cb(server_id_cb)daos_debug_init 日志级别 d_debug_data dlog_fac d_log_open D_LOG_STDERR_IN_LOG 合并错误消息 如何接管fabric日志? if (merge)客户端动态开日志freopen setlinebuf filenod_tm_init 遥测指标初始化dss_engine_metrics_initd_tm_record_timestampdrpc_init 初始化drpc客户端register_dbtree_classes 注册数据库树, b树dbtree_class_registerdss_topo_init 初始服务器拓扑, numa, cpu core, bitmap位图等abt_init argobots初始化, 机器人,atoi(env) 环境变量转整型set_abt_max_num_xstreams(max(nrequested, nrequired)) 两者中的较大值, 设置环境变量 ABT_MAX_NUM_XSTREAMS, 输入整型, 转为字符串char*D_ASPRINTF(value, "%d", n);ABT_init(argc, argv)dss_module_init 服务端模块初始化drpc_hdlr_init 注册表 static drpc_handler_t *registry_table 静态 drpc_handler_t *注册表, 函数指针dss_ctx_nr_get 获取cart上下文总数crt_init_opt 初始化网络层if (dss_mod_facs & DSS_FAC_LOAD_CLI) 如果需要加载客户端软件栈,默认不执行daos_init daos_hhash_init 初始化hash表daos_hhash_init_feats(D_HASH_FT_GLOCK | D_HASH_FT_LRU)d_hhash_create(feats | D_HASH_FT_NO_KEYINIT_LOCK, D_HHASH_BITS, &daos_ht.dht_hhash) 创建全局hash表 daos_htpl_init 初始化放置模块, 创建放置映射hash表d_hhash_set_ptrtype 服务端使用指针类型的控制器ds_iv_initD_INIT_LIST_HEAD(&ds_iv_ns_list) 初始化iv,ns链表头D_INIT_LIST_HEAD(&ds_iv_class_list)ds_iv_ns_tree_topo = crt_tree_topo(CRT_TREE_KNOMIAL, 4) 初始化树拓扑,位运算,移位,或modules_load 加载模块信息: vos, rdb, rsvc, security, mgmt, dtx, pool, cont, obj, rebuilddss_module_loadlmod->lm_dss_mod = smod 设置加载模块为动态打开的模块d_list_add_tail(&lmod->lm_lk, &loaded_mod_list) 动态打开 dlopen,并加入链表mem_leak_check_start();hlc_recovery_end 结束 HLC 恢复dss_set_start_epochdss_module_init_alldss_register_keyd_list_for_each_entry_safe(lmod, tmp, &loaded_mod_list 遍历之前加载的模块链表dss_module_init_one(lmod, &fac)rc = smod->sm_init() // vos_mod_init, dss_srv_init 初始化服务(服务初始化)dss_tls_init(DAOS_SERVER_TAG, 0, -1)vos_db_init(dss_storage_path)  sys_db.c dss_storage_path=/mnt/daosbio_nvme_init 全局nvme初始化d_getenv_boolopen(nvme_conf, O_RDONLY, 0600) 打开nvme配置文件smd_init(db) 服务元数据管理(每个服务) Per-Server Metadata Management (SMD),smd使用sysdb作为kv存储元数据spdk_bs_opts_init 将 spdk_bs_opts 结构初始化为默认的 blobstore 选项值。bio_spdk_env_init 环境初始化spdk_env_opts_init(&opts) 初始化选项 lib/env_dpdk/init.cbio_add_allowed_allocread_configspdk_json_parsespdk_json_find_arraycheck_vmd_statusadd_bdevs_to_optsspdk_env_init 初始化或重新初始化环境库。 对于初始化,必须在使用此库中的任何其他函数之前调用它。 对于重新初始化,参数 `opts` 必须设置为 NULL,并且必须在同一进程中通过 spdk_env_fini() 完成环境库后调用pci_env_reinitbuild_eal_cmdlinepush_argrte_eal_init(g_eal_cmdline_argcount, dpdk_args)  初始化环境抽象层 (EAL)。 此函数将仅在 MAIN lcore 上执行,并尽快在应用程序的 main() 函数中执行。 它将 WORKER lcores 置于 WAIT 状态。spdk_env_dpdk_post_initspdk_unaffinitize_thread 移除当前线程cpu亲和性spdk_thread_lib_init 初始化线程库。 必须在分配任何线程之前调用一次。bio_register_bulk_ops(crt_bulk_create, crt_bulk_free)dss_xstreams_initbio_nvme_ctl  操纵全局 NVMe 配置/状态drpc_listener_init 启动drpc监听generate_socket_path 生成socket路径 drpc_listener_socket_path=/var/run/daos_server/daos_engine_pid_sockdrpc_listener_start_ultserver_init_state_initdrpc_notify_readyserver_init_state_waitdss_module_setup_all 初始化服务端所有模块crt_register_event_cb(dss_crt_event_cb, NULL)crt_register_hlc_error_cb(dss_crt_hlc_error_cb, NULL)dss_xstreams_open_barrierd_tm_record_timestampd_tm_set_counter(metrics->rank_id, dss_self_rank())vos_db_initvos_db.db_pub.sd_fetch	  = db_fetch...db_open_createmkdir(vdb->db_path, 0777)vos_pool_createvos_pool_openvos_cont_createdb_upsertdss_xstreams_initdss_start_xs_id 0,1..., 计算偏移, 如: xs_id = dss_sys_xs_nr + dss_tgt_nr + i;hwloc_bitmap_first 计算位图中的第一个索引(最低有效位)dss_start_one_xstream(obj->cpuset, xs_id) 用计算的cpu集启动, 内部绑核dss_xstream_alloc(cpus)dx->dx_cpuset = hwloc_bitmap_dup(cpus)dss_sched_initABT_sched_def		sched_def.init	= sched_init,.run	= sched_run,sched_info_init(dx)info->si_cur_ts = daos_getmtime_coarse() 毫秒d_hash_table_create si_pool_hash 创建hash表 大小为2的4次方=16prealloc_requests(info, SCHED_PREALLOC_INIT_CNT) 预分配请求 8192D_ALLOC_PTR(req)D_INIT_LIST_HEAD(&req->sr_link)d_list_add_tail(&req->sr_link, &info->si_idle_list) 插入链表 sched_create_pools(dx); 创建3个池 从预定义类型创建新池。 ABT_pool_create_basic() 创建一个新池,由池类型 kind、访问类型 access 和自动标志 automatic 给出,并通过 newpool 返回其句柄。 kind 指定 newpool 的实现。 有关预定义池的详细信息,请参阅#ABT_pool_kind。 access 提示创建的池的使用。 Argobots 可以为具有更受限制的访问类型的池选择优化的实现(#ABT_POOL_ACCESS_PRIV 是最严格的访问类型)。 有关详细信息,请参阅#ABT_pool_access。 如果 automatic 为 ABT_FALSE,则 newpool 不会自动释放,因此 newpool 在使用后必须由 ABT_pool_free() 释放,除非 newpool 与主执行流的主调度程序相关联。ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPSC 创建的池可能只被一个执行流弹出ABT_sched_config_createABT_sched_create 使用调度程序定义创建新的调度程序。ABT_sched_create() 创建一个新的调度器,由定义 def 和调度器配置 config 定义,并通过 newsched 返回它的句柄。def 必须定义所有非可选函数。 有关详细信息,请参阅 ABT_sched_def。newsched 与 pools 数组关联,它有 num_pools 个 ABT_pool 句柄。 如果池的第 i 个元素是 ABT_POOL_NULL,则新创建具有默认池配置的默认 FIFO 池并用作第 i 个池。ABT_xstream_create_with_rank 创建具有特定等级的新执行流。 ABT_xstream_create_with_rank() 使用调度程序 sched 创建一个新的执行流,并通过 newxstream 返回其句柄。 如果 sched 为 ABT_SCHED_NULL,则使用具有基本 FIFO 队列和默认调度程序配置的默认调度程序。ABT_thread_attr_createABT_thread_attr_set_stacksize 在 ULT 属性中设置堆栈大小。 ABT_thread_attr_set_stacksize() 设置 ULT 属性 attr 中的堆栈大小 stacksize(以字节为单位)。 如果堆栈内存已由 ABT_thread_attr_set_stack() 设置,此例程将更新堆栈大小,同时将堆栈内存保留在 attr 中。ABT_thread_create dss_srv_handlerdss_srv_handler 服务控制器,设置cpu亲和性,初始化TLS,crt, nvme,gc, nvme, 启动网络polldss_xstream_set_affinity 设置亲和性hwloc_set_cpubind 绑核hwloc_set_membind 将当前进程或线程的默认内存绑定策略设置为更喜欢由 set 指定的 NUMA 节点。 这是最便携的形式,因为它允许 hwloc 使用基于进程的操作系统功能或基于线程的操作系统功能,具体取决于可用的功能。 如果指定了 ::HWLOC_MEMBIND_BYNODESET,则集合被视为节点集。 否则它是一个cpuset。dss_tls_init 初始化本地存储, 为特定线程分配 dss_thread_local_storage 并将指针存储在特定于线程的值中,该值可以随时使用 dss_tls_get() 获取。dss_thread_local_storage_init obj_tls_initdtls->dtls_values[i] = dmk->dmk_init(xs_id, tgt_id) dmk->dmk_init(xs_id, tgt_id) -> dss_srv_tls_init | vos_tls_init pthread_setspecific(dss_tls_key, dtls)dss_get_module_infodss_module_key_getcrt_context_createcrt_context_register_rpc_task dss_rpc_hdlr dss_iv_resp_hdlr 注册两个公共回调crt_context_idxtse_sched_init 使用可选的完成回调和指向用户数据的指针初始化调度程序。 调用者负责完成或取消调度程序。bio_xsctxt_alloc 初始化spdk环境和nvme上下文 dss_nvme_poll_ultfor (;;)crt_progressvos_tls_init 初始化vos本地线程存储D_INIT_LIST_HEAD(&tls->vtl_gc_pools)vos_obj_cache_create(LRU_CACHE_BITS 创建lrud_uhash_create vtl_pool_hhash vtl_cont_hhashumem_init_txd(&tls->vtl_txd) 为避免为每个事务分配阶段数据,umem 用户应准备每个 xstream 阶段数据并通过 umem_init_txd() 对其进行初始化,此每个 xstream 阶段数据将用于同一 xstream 中的所有事务txd->txd_magic = UMEM_TX_DATA_MAGICvos_ts_table_allocvos_ts_copy VOS_TS_TYPE_CONT 不执行此逻辑daos_dti_copy*des = *src 赋值memset(des, 0, sizeof(*des)) 置0lrua_array_allocd_tm_add_metricdss_nvme_poll_ultdss_get_module_infodss_current_xstreambio_nvme_poll poll nvme完成事件spdk_thread_pollis_bbs_ownerbio_bs_monitoris_init_xstreamscan_bio_bdevsbio_led_event_monitorABT_thread_yieldvos线程模型
bio_nvme_pollnvme配置文件
/mnt/ubip1/ubip_nvme.confsubsystem: bdev
trtype: PCIe
method: bdev_nvme_attach_controller核心数
主线程XS
首选线程数dss_topo_init 初始化拓扑numa_obj = hwloc_get_obj_by_depthdss_tgt_nr = dss_tgt_nr_get numa,核, 分配算法  超额认购 oversubscribe 计算每个引擎多少个targetcore 核。 一个计算单元(可以由多个 PU Processing Unit,也就是逻辑处理器共享)
处理器单元的缩写(不是进程!)。 hwloc 识别的最小物理执行单元。 例如,一个核心上可能有多个 PU(例如,硬件线程)。
当多台机器形成整体单一系统映像 (SSI) 时,可以使用附加系统类型,例如 Kerrighed。
最后,请注意,一个对象可以由其在拓扑图中的数字“深度”表示。
水平类型的宽度: 深度
查看硬件信息 hwloc-info 
depth 0:	1 Machine (type #1)
depth 1:	2 NUMANode (type #2)
depth 2:	2 Package (type #3) 
depth 3:	2 L3Cache (type #4)
depth 4:	56 L2Cache (type #4)
depth 5:	56 L1dCache (type #4)
depth 6:	56 L1iCache (type #4)
depth 7:	56 Core (type #5)
depth 8:	56 PU (type #6)
Special depth -3:	9 Bridge (type #9)
Special depth -4:	7 PCI Device (type #10)
Special depth -5:	10 OS Device (type #11)学习路线:初始化  *格式化创建池创建容器挂载IO路径故障后的重建,rebuildregister_dbtree_classesdbtree_class_register(DBTREE_CLASS_KV dbtree_kv_opsif (!(tree_feats & (BTR_FEAT_UINT_KEY | BTR_FEAT_DIRECT_KEY))) 利用位运算判断, 如果没有设置唯一键或直接键btr_class_registered[tree_class].tc_ops = ops 注册操作(利用数组index索引树的类型)btr_class_registered[tree_class].tc_feats = tree_feats 注册树类型特征位dss_module_init_onerc = smod->sm_init() 初始化单个模块 -> vos_mod_initdss_register_key(smod->sm_key)daos_rpc_register(smod->sm_proto_fmt[i], smod->sm_cli_count[i]... 注册RPC CRT_PROTO_OPCdrpc_hdlr_register_all(smod->sm_drpc_handlers) 注册所有控制器drpc_hdlr_registerregistry_table[module_id] = handler 注册drpc控制器, 模块id也就是对应的drpc枚举中的索引号模块列表, 模块初始化, vos,rdb,rsvc,security,mgmt,dtx,pool,cont,obj,rebuild
关键字: .sm_name 模块名
enum daos_module_id 模块ID
vos_srv -> vos_srv_module
vos_mod_init vos初始化vos_pool_settings_init vos池初始化设置pmemobj_ctl_set(NULL, "heap.arenas_assignment_type", &atype) 线程使用1个全局的arena POBJ_ARENAS_ASSIGNMENT_GLOBAL 全局模式vos_cont_tab_register 注册容器 VOS_BTR_CONT_TABLE class: 14vos_dtx_table_registerdbtree_class_register(VOS_BTR_DTX_ACT_TABLE 注册DTX活动表dbtree_class_register(VOS_BTR_DTX_CMT_TABLE 注册提交表vos_obj_tab_registerdbtree_class_register(VOS_BTR_OBJ_TABLE 注册对象索引表(OI) obj_tree_registerdbtree_class_register(ta->ta_class, ta->ta_feats 注册db树 vos_btr_attrs: VOS_BTR_DKEY, VOS_BTR_AKEY, VOS_BTR_SINGV, vos_dkey, vos_akey, singvvos_ilog_init 初始化全局化身日志ilog_initd_getenv_int DAOS_VOS_AGG_THRESH 触发vos聚合的块数=256块, 总大小256*4K=1MBrdb初始化
rdb_module_initrdb_hash_initd_hash_table_create_inplace rdb_hash 加锁创建rdb_hash表rsvc初始化
rsvc_module_initd_hash_table_create_inplace rsvc_hash安全模块security默认加载
initds_sec_server_socket_path = /var/run/daos_server/daos_server.sockmgmt 管理模块初始化
ds_mgmt_initds_mgmt_system_module_initcrt_group_lookupd_iov_setds_rsvc_class_register(DS_RSVC_CLASS_MGMT, &mgmt_svc_rsvc_class)rsvc_classes[id] = class 将类添加到rsvc类的数组中dtx 初始化
dtx_init设置阈值dbtree_class_register(DBTREE_CLASS_DTX_CFdbtree_class_register(DBTREE_CLASS_DTX_COS池初始化
pool
init(void) .sm_init	= initds_pool_cache_init 缓存初始化daos_lru_cache_create 创建lru缓存,内存中d_hash_table_create_inplace D_HASH_FT_LRU dlc_htable 创建lru_hash表D_INIT_LIST_HEAD 初始化链表头 驱逐LRU缓存条目时避免全扫描ds_pool_hdl_hash_initd_hash_table_create pool_hdl_hash 创建池控制器哈希表ds_pool_iv_init 添加服务器 iv 树以在服务器之间共享值。 通过iv tree共享pool map,只先做同步更新ds_iv_class_register IV_POOL_MAP 通过iv传播属性ds_pool_prop_default_init DAOS-7254 聚合:将 EC 聚合与 VOS 聚合分开 (#5667), 将 EC agg 和 VOS aggregate 分离成两个 ULT,避免 iv fetch,dsc_pool/container open 每次回调,同时保证 EC aggregation 可以在删除快照时触发。添加 DAOS_EC_AGG 环境以禁用 EC 聚合以进行测试entry = daos_prop_entry_get(&pool_prop_default, DAOS_PROP_PO_ACL)&prop->dpp_entries[i]entry->dpe_val_ptr = ds_sec_alloc_default_daos_pool_acl()alloc_default_daos_acl_with_permsalloc_ace_with_accessdaos_ace_createdaos_acl_createflatten_aces 扁平化ds_pool_rsvc_class_register DS_RSVC_CLASS_POOL 注册副本服务bio_register_ract_ops 设置nvme操作表, 故障回调, 重新加入的回调, io错误的回调cont 初始化容器服务
init(void)ds_oid_iv_initds_iv_class_register 注册iv类ds_cont_iv_initds_iv_class_register 注册各种类ds_cont_prop_default_initobj 对象初始化
obj_mod_init(void)obj_utils_initobj_class_initD_ALLOC_ARRAY(oc_ident_array, OC_NR)obj_ec_codec_initrebuild 重建初始化
init(void)D_INIT_LIST_HEAD rg_tgt_tracker_list 所有tagertrg_global_tracker_list 主ABT_mutex_create(&rebuild_gst.rg_lock) 重建全局锁rebuild_iv_initds_iv_class_register启动drpc监听用户级线程
drpc_listener_start_ultsetup_listener_ctx(&ctx)unlink(sockpath)listener = drpc_listen(sockpath, drpc_hdlr_process_msg)  unix domain socket 域套接字, 创建了一个新系统 XS (1),绑定到与 XS 0 相同的 CPU 核心。dRPC 侦听器循环专门在这个 XS 上运行。 当 dRPC 消息到达时,drpc_progress 在 XS 0 上启动一个新的 ULT 来处理消息。 它必须在 XS 0 上才能与只能在 XS 0 上运行的服务进行交互。为 dRPC 上下文结构添加了引用计数。 drpc_close 现在要么减少引用计数,要么如果这是最后一个引用,则关闭/释放套接字。 删除了现在不再使用的 drpc_recvdrpc_hdlr_process_msg drpc处理消息的控制器unixcomm_listen(sockaddr, O_NONBLOCK, &comm)new_unixcomm_socket(flags, &comm)comm->fd = socket(AF_UNIX, SOCK_SEQPACKET, 0) 创建socket , SOCK_SEQPACKET为固定最大长度的数据报提供有序的、可靠的、基于双向连接的数据传输路径; 消费者需要在每次输入系统调用时读取整个数据包, 协议参数, 该协议指定要与套接字一起使用的特定协议。 通常只存在一个协议来支持给定协议族中的特定套接字类型,在这种情况下 protocol 可以指定为 0。但是,可能存在许多协议,在这种情况下必须在此指定一个特定的协议 方式。要使用的协议号特定于要进行通信的“通信域”; 请参阅协议 (5)。 有关如何将协议名称字符串映射到协议编号的信息,请参阅 getprotoent(3)fcntl(comm->fd, F_SETFL, flags)fill_socket_address(sockaddr, &address)bind(comm->fd 在 SOCK_STREAM 套接字可以接收连接之前,通常需要使用 bind() 分配本地地址(请参阅 accept(2))listen(comm->fd, SOMAXCONN) listen() 将 sockfd 引用的套接字标记为被动套接字,即,作为将用于使用 accept(2) 接受传入连接请求的套接字。
sockfd 参数是一个文件描述符,它引用 SOCK_STREAM 或 SOCK_SEQPACKET 类型的套接字。
backlog 参数定义了 sockfd 的挂起连接队列可能增长到的最大长度。 如果连接请求在队列已满时到达,则客户端可能会收到带有 ECONNREFUSED 指示的错误,或者,如果底层协议支持重传,则可能会忽略该请求,以便稍后重新尝试连接成功init_drpc_ctx(ctx, comm, handler)ctx->handler = handler 赋值 = drpc_hdlr_process_msg*new_ctx = drpc_progress_context_create(listener)dss_ult_create(drpc_listener_runult_create_internal(funcstream_id = sched_ult2xs(xs_type, tgt_idx) 获取执行流id, 根据映射关系dx = dss_get_xstream(stream_id) 通过数组角标ABT_thread_attr_set_stacksize(attr, stack_size)sched_create_thread(dx, func, arg, attr, ult, flags)sched_xstream_stopping?daos_abt_thread_create(cur_dx->dx_sp, dss_free_stack_cb, abt_pool, func, arg, t_attr, thread)  max_map_count文件包含限制一个进程可以拥有的VMA(虚拟内存区域)的数量: sysctl vm.max_map_count 默认 64KABT_thread_create -> drpc_listener_runset_listener_running(true)while (is_listener_running()) rc = drpc_progress(ctx, 1000)drpc_progress_context_to_unixcomms(ctx, &comms)num_comms = get_open_drpc_session_count(ctx)unixcomm_poll(comms, num_comms, timeout_ms)fds[i].events = POLLIN | POLLPRIpoll_rc = poll(fds, num_comms, timeout_ms) 轮训comms[i].activity = poll_events_to_unixcomm_activity 获取激活原因process_activity(ctx, comms, num_comms) 处理激活的事件process_all_session_activities(ctx, comms, num_comms)process_session_activityhandle_incoming_calldrpc_recv_callget_incoming_callunixcomm_recvdrpc__call__unpackdrpc_response_createcreate_call_ctxdss_ult_create(drpc_handler_ultprocess_listener_activity(ctx, comms, num_comms)drpc_acceptd_list_add(&session_node->linkABT_thread_yield()drpc_progress_context_close(ctx)drpc_handler_ult 执行控制器ctx->session->handler(ctx->call, ctx->resp) -> drpc_hdlr_process_msgdrpc_hdlr_process_msghandler = drpc_hdlr_get_handler(request->module) 根据请求中的模块id, 获取请求对应的模块handler = registry_table[module_id] 从注册表中获取控制器handler(request, resp) 处理请求rc = drpc_send_response(ctx->session, ctx->resp)
free_call_ctx(ctx)static struct vos_sys_db	vos_db
vos_db_init vos初始化 元数据初始化vos_db_init_ex(db_path, NULL, false, false)memset(&vos_db, 0, sizeof(vos_db)) 系统db置零 /mnt/daos/daos_sys/sys_db 系统数据库sys_dbvos_db.db_poh = DAOS_HDL_INVALvos_db.db_pub.sd_fetch	  = db_fetch ...uuid_parse(SYS_DB_POOL, vos_db.db_pool) 保留系统池,容器的uuiddb_open_create(&vos_db.db_pub, !!create) 创建或打开 vos_pool_openaccess 先检查文件是否存在 第二轮创建vos_pool_create 创建vosp 系统scm池(128MB) jumpvos_cont_create(vdb->db_poh, vdb->db_cont) 在vos池中(vpool)创建一个容器cont_df_lookup(vpool, &ukey, &args)dbtree_lookup(vpool->vp_cont_th, &key, &value) b树搜索dbtree_fetch(toh, BTR_PROBE_EQ, DAOS_INTENT_DEFAULT, key, NULL 探测键等于提供键的记录btr_probe_key(tcx, opc, intent, key)btr_hkey_gen(tcx, key, hkey)btr_probe(tcx, probe_opc, intent, key, hkey) 查找b树btr_context_set_depthbtr_cmp 二分查找btr_node_is_leafbtr_trace_setbtr_node_child_at... b树umem_tx_begin(vos_pool2umm(vpool), NULL)dbtree_update(vpool->vp_cont_th, &key, &value)btr_upsert(tcx, BTR_PROBE_EQ, DAOS_INTENT_UPDATE, key, val) 更新或插入umem_tx_end(vos_pool2umm(vpool), rc)vos_cont_open(vdb->db_poh, vdb->db_cont, &vdb->db_coh)cont_lookup(&ukey, &pkey, &cont)d_uhash_link_lookup(vos_cont_hhash_get(), key, pkey)cont_df_lookup(pool, &ukey, &args)uuid_copy(cont->vc_id, co_uuid)cont->vc_pool	 = pool 设置容器属性D_INIT_LIST_HEAD(&cont->vc_dtx_act_list)gc_check_cont(cont) 检查是否需要加入gc列表D_INIT_LIST_HEAD(&cont->vc_gc_link)d_list_add_tail(&cont->vc_gc_link, &cont->vc_pool->vp_gc_cont)dbtree_open_inplace_ex(&cont->vc_cont_df->cd_obj_rootlrua_array_alloc(&cont->vc_dtx_array 分配LRU数组, 活动的dtx记录dbtree_create_inplace_ex(VOS_BTR_DTX_ACT_TABLEdbtree_create_inplace_ex(VOS_BTR_DTX_CMT_TABLEvea_hint_load(&cont->vc_cont_df->cd_hint_df[i]vos_dtx_act_reindex(cont)lrua_allocx_inplace(cont->vc_dtx_arraydbtree_upsert(cont->vc_dtx_active_hdldae->dae_start_time = crt_hlc_get()d_list_add_tail(&dae->dae_link, &cont->vc_dtx_act_list) dtx可能在其他线程中遍历此链表cont_insert(cont, &ukey, &pkey, coh)d_uhash_ulink_init(&cont->vc_uhlink, &co_hdl_uh_ops)d_uhash_link_insert(vos_cont_hhash_get(), key 插入uuid hash表rc = db_upsert(db, SYS_DB_MD, &key, &val) metadata元数据,做容器dkeydb_io_init(&io, table, key, val)io->io_iod.iod_type = DAOS_IOD_SINGLE 一个不可分割的值以原子方式更新vos_obj_update(vdb->db_coh 更新指定对象的记录。 如果sql中没有提供输入缓冲区,则该函数返回新分配的地址来存放记录,上层可以直接向这些地址写入数据(rdma模式)vos_obj_update_exvos_update_beginvos_check_akeys(iod_nr, iods)vos_ioc_createvos_ilog_fetch_init(&ioc->ic_dkey_info)ilog_fetch_init(&info->ii_entries)vos_ilog_fetch_init(&ioc->ic_akey_info)vos_ioc_reserve_init(ioc, dth)vos_ts_set_allocatevos_kh_clear()vos_ts_set_append_cflags(*ts_set, cflags)bio_iod_allocbsgl = bio_iod_sgl(ioc->ic_biod, i)rc = bio_sgl_init(bsgl, iov_nr)vos_space_hold(vos_cont2poolvos_space_query(pool, &vps, false)pmemobj_ctl_get(pool->vp_umm.umm_pool stats.heap.curr_allocatedvea_query(pool->vp_vea_info, attr, stat) 查询nvmedbtree_iterate(vsi->vsi_md_free_btr count_free_persistentverify_free_entrydbtree_iterate count_free_transientd_binheap_sized_binheap_rootd_binheap_findd_binheap_find_lockedd_binheap_pointerestimate_space 估计更新请求将消耗多少空间。 这个保守的估计总是假设新对象、dkey、akey 将被创建用于更新umem_slab_usizescm += estimate_space_key(umm, dkey)vos_media_selectdkey_update_begin(ioc)iod_set_cursorakey_update_beginvos_media_select(vos_cont2pool(ioc->ic_cont)vos_reserve_single(ioc, media, size)reserve_space(ioc, DAOS_MEDIA_SCM, scm_size, &off)vos_reserve_scmumem_reservevos_reserve_blocksvea_reservevos_irec_init_csum(irec, value_csum)bio_addr_set_holevos_reserve_recx(ioc, media, size, recx_csumbio_addr_set_holevos_dedup_lookup 去重d_hash_rec_find(pool->vp_dedup_hashiod_reservebio_iod_sgl 获取 io 描述符的指定 SG 列表的辅助函数vos_obj_copybio_iod_prepiterate_biov(biod, arg ? bulk_map_one : dma_map_one, arg)dma_rw(biod)bio_iod_copyiterate_biov(biod, copy_one, &arg)bio_iod_postdma_rw(biod)bdb = iod_dma_buf(biod)dma_drop_iod(bdb)ABT_cond_broadcast(bdb->bdb_wait_iods)vos_update_endvos_dedup_verify_finivos_ts_set_addvos_tx_beginvos_dtx_commit_internalvos_obj_hold(vos_obj_cache_current()dkey_updatevos_ts_set_check_conflictvos_space_unhold
dss_srv_tls_initdsm_tls_initds_cont_child_cache_createdaos_lru_cache_create cont_child_cache_opsds_cont_hdl_hash_createobj_tls_init每个IO指标

在这里插入图片描述

DAOS IO全路径详解(视频)
DAOS 项目简介(视频)
欢迎对DAOS, SPDK, RDMA等高性能技术感兴趣的朋友加入[DAOS技术交流(群)]

Author 晓兵

博客: https://logread.cn | https://blog.csdn.net/ssbandjl

weixin: ssbandjl

公众号: 云原生云

这篇关于DAOS引擎启动流程-源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/190280

相关文章

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

springboot3打包成war包,用tomcat8启动

1、在pom中,将打包类型改为war <packaging>war</packaging> 2、pom中排除SpringBoot内置的Tomcat容器并添加Tomcat依赖,用于编译和测试,         *依赖时一定设置 scope 为 provided (相当于 tomcat 依赖只在本地运行和测试的时候有效,         打包的时候会排除这个依赖)<scope>provided

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

用命令行的方式启动.netcore webapi

用命令行的方式启动.netcore web项目 进入指定的项目文件夹,比如我发布后的代码放在下面文件夹中 在此地址栏中输入“cmd”,打开命令提示符,进入到发布代码目录 命令行启动.netcore项目的命令为:  dotnet 项目启动文件.dll --urls="http://*:对外端口" --ip="本机ip" --port=项目内部端口 例: dotnet Imagine.M