DAOS 源码解析之 daos_pool

网友投稿 806 2022-05-29

DAOS (Distributed Asynchronous Object Storage) 是一个开源的对象存储系统,专为大规模分布式非易失性内存设计,利用了 SCM 和 NVMe 等的下一代 NVM 技术。 DAOS 同时在硬件之上提供了键值存储接口,提供了诸如事务性非阻塞 I/O、具有自我修复的高级数据保护、端到端数据完整性、细粒度数据控制和弹性存储的高级数据保护,从而优化性能并降低成本。

本文以 Release 1.1.4 版本为标准,解析 include/daos_pool.h 中的具体实现。include/daos_pool.h 包含了 DAOS Stoarge Pool 相关的类型和函数。有关 Pool 的具体信息可参考 DAOS 分布式异步对象存储|存储模型 DAOS Pool 一节和 DAOS 分布式异步对象存储|Pool。

Storage Target

Target 的类型有 4 种:

typedef enum { // 未知 DAOS_TP_UNKNOWN, // 机械硬盘 DAOS_TP_HDD, // 闪存 DAOS_TP_SSD, // 持久内存 DAOS_TP_PM, // 易失性内存 DAOS_TP_VM, } daos_target_type_t;

Target 当前的状态有 6 种:

typedef enum { // 未知 DAOS_TS_UNKNOWN, // 不可用 DAOS_TS_DOWN_OUT, // 不可用,可能需要重建 DAOS_TS_DOWN, // 启动 DAOS_TS_UP, // 启动并运行 DAOS_TS_UP_IN, // Pool 映射改变导致的中间状态 DAOS_TS_NEW, // 正在被清空 DAOS_TS_DRAIN, } daos_target_state_t;

结构体daos_target_perf_t 用于描述 Target 的性能:

typedef struct { // TODO: 存储/网络带宽、延迟等 int foo; } daos_target_perf_t;

结构体 daos_space 表示 Pool Target 的空间使用情况:

struct daos_space { // 全部空间(字节) uint64_t s_total[DAOS_MEDIA_MAX]; // 空闲空间(字节) uint64_t s_free[DAOS_MEDIA_MAX]; };

其中,DAOS_MEDIA_MAX 表示存储空间介质的数量,一共有两种:

enum { DAOS_MEDIA_SCM = 0, DAOS_MEDIA_NVME, DAOS_MEDIA_MAX };

即 s_total[DAOS_MEDIA_SCM] 和 s_free[DAOS_MEDIA_SCM] 表示 SCM (Storage-Class Memory) 的使用信息,s_total[DAOS_MEDIA_NVME] 和 s_free[DAOS_MEDIA_NVME] 表示 NVMe (Non-Volatile Memory express) 的使用信息。

结构体 daos_target_info_t 表示 Target 的信息:

typedef struct { // 类型 daos_target_type_t ta_type; // 状态 daos_target_state_t ta_state; // 性能 daos_target_perf_t ta_perf; // 空间使用情况 struct daos_space ta_space; } daos_target_info_t;

Storage Pool

结构体 daos_pool_space 表示 Pool 的空间使用情况:

struct daos_pool_space { // 所有活动的 Target 的聚合空间 struct daos_space ps_space; // 所有 Target 中的最大可用空间(字节) uint64_t ps_free_min[DAOS_MEDIA_MAX]; // 所有 Target 中的最小可用空间(字节) uint64_t ps_free_max[DAOS_MEDIA_MAX]; // Target 平均可用空间(字节) uint64_t ps_free_mean[DAOS_MEDIA_MAX]; // Target(VOS, Versioning Object Store) 数量 uint32_t ps_ntargets; uint32_t ps_padding; };

结构体 daos_rebuild_status 表示重建状态:

struct daos_rebuild_status { // Pool 映射在重建过程中的版本或上一个完成重建的版本 uint32_t rs_version; // 重建的时间(秒) uint32_t rs_seconds; // 重建错误的错误码 int32_t rs_errno; // 重建是否完成 // 该字段只有在 rs_version 非 0 时有效 int32_t rs_done; // 重建状态的填充 int32_t rs_padding32; // 失败的 rank int32_t rs_fail_rank; // 要重建的对象总数,它不为 0 并且在重建过程中增加 // 当 rs_done = 1 时,它将不再更改,并且应等于 rs_obj_nr // 使用 rs_toberb_obj_nr 和 rs_obj_nr,用户可以知道重建的进度 uint64_t rs_toberb_obj_nr; // 重建的对象数量,该字段非 0 当且仅当 rs_done = 1 uint64_t rs_obj_nr; // 重建的记录数量,该字段非 0 当且仅当 rs_done = 1 uint64_t rs_rec_nr; // 重建的空间开销 uint64_t rs_size; };

daos_pool_info_bit 表示 Pool 信息查询位:

enum daos_pool_info_bit { // 如果为真,查询 Pool 的空间使用情况 DPI_SPACE = 1ULL << 0, // 如果为真,查询重建状态 DPI_REBUILD_STATUS = 1ULL << 1, // 查询所有的可选信息 DPI_ALL = -1, };

结构体 daos_pool_info_t 表示 Pool 的信息:

typedef struct { // UUID uuid_t pi_uuid; // Target 数量 uint32_t pi_ntargets; // Node 数量 uint32_t pi_nnodes; // 不活跃的 Target 数量 uint32_t pi_ndisabled; // 最新的 Pool 映射版本 uint32_t pi_map_ver; // 当前的 Raft Leader uint32_t pi_leader; // Pool 信息查询位,其值为枚举类型 daos_pool_info_bit uint64_t pi_bits; // 空间使用情况 struct daos_pool_space pi_space; // 重建状态 struct daos_rebuild_status pi_rebuild_st; } daos_pool_info_t;

对于每个 daos_pool_query() 调用,将始终查询基本 Pool 信息,如从 pi_uuid 到 pi_leader 的字段。但是 pi_space 和 pi_rebuild_st 是基于 pi_bits 的可选查询字段。

结构体 daos_pool_cont_info 表示 Pool Container 的信息:

struct daos_pool_cont_info { // UUID uuid_t pci_uuid; };

daos_pool_connect

daos_pool_connect 函数连接到由 UUID uuid 标识的 DAOS Pool。

成功执行后,poh 返回 Pool 句柄,info 返回最新的 Pool 信息。

参数:

uuid [in]:标识 Pool 的 UUID。

grp [in]:管理 Pool 的 DAOS 服务器的进程集合名称。

flags [in]:由 DAOS_PC_ 位表示的连接模式。

poh [out]:返回的打开句柄。

info [in, out]:可选参数,返回的 Pool 信息,参考枚举类型 daos_pool_info_bit。

ev [in]:结束事件,该参数是可选的,可以为 NULL。当该参数为 NULL 时,该函数在阻塞模式下运行。

返回值,在非阻塞模式下会被写入 ev::ev_error:

如果成功,返回 0。

如果失败,返回

-DER_INVAL:无效的参数。

-DER_UNREACH:无法访问网络。

-DER_NO_PERM:没有访问权限。

-DER_NONEXIST:Pool 不存在。

int daos_pool_connect(const uuid_t uuid, const char *grp, unsigned int flags, daos_handle_t *poh, daos_pool_info_t *info, daos_event_t *ev) { daos_pool_connect_t *args; tse_task_t * task; int rc; // 判断 *args 大小是否与 daos_pool_connect_t 的预期大小相等 DAOS_API_ARG_ASSERT(*args, POOL_CONNECT); if (!daos_uuid_valid(uuid)) // UUID 无效 return -DER_INVAL; // 创建新任务 dc_pool_connect,并将其与输入事件 ev 关联 // 如果事件 ev 为 NULL,则将获取私有事件 rc = dc_task_create(dc_pool_connect, NULL, ev, &task); if (rc) // dc_task_create 成功返回 0,失败返回负数 return rc; // 从 task 中获取参数 args = dc_task_get_args(task); args->grp = grp; args->flags = flags; args->poh = poh; args->info = info; uuid_copy((unsigned char *)args->uuid, uuid); // 调度创建的任务 task // 如果该任务的关联事件是私有事件,则此函数将等待任务完成 // 否则它将立即返回,并通过测试事件或在 EQ 上轮询找到其完成情况 // // 第二个参数 instant 为 true,表示任务将立即执行 return dc_task_schedule(task, true); }

Pool 的连接模式有三种,由 DAOS_PC_ 位表示:

// 以只读模式连接 Pool #define DAOS_PC_RO (1U << 0) // 以读写模式连接 Pool #define DAOS_PC_RW (1U << 1) // 以独占读写模式连接到 Pool // 如果当前存在独占 Pool 句柄,则不允许与 DSM_PC_RW 模式的连接。 #define DAOS_PC_EX (1U << 2) // 表示连接模式的位个数 #define DAOS_PC_NBITS 3 // 连接模式位掩码 #define DAOS_PC_MASK ((1U << DAOS_PC_NBITS) - 1)

结构体 daos_pool_connect_t 表示 Pool 连接参数:

typedef struct { // Pool 的 UUID uuid_t uuid; // 管理 Pool 的 DAOS 服务器的进程集合名称。 const char *grp; // 由 DAOS_PC_ 位表示的连接模式 unsigned int flags; // 返回的打开句柄 daos_handle_t *poh; // 可选,返回的 Pool 信息 daos_pool_info_t *info; } daos_pool_connect_t;

daos_pool_disconnect

daos_pool_disconnect 函数断开 DAOS Pool 的连接。它应该撤销该 Pool 的所有打开的 Container 句柄。

参数:

poh [in]:连接到 Pool 的句柄。

ev [in]:结束事件,该参数是可选的,可以为 NULL。当该参数为 NULL 时,该函数在阻塞模式下运行。

返回值,在非阻塞模式下会被写入 ev::ev_error:

如果成功,返回 0。

如果失败,返回

-DER_UNREACH:无法访问网络。

-DER_NO_HDL:Pool 句柄无效。

int daos_pool_disconnect(daos_handle_t poh, daos_event_t *ev) { daos_pool_disconnect_t *args; tse_task_t * task; int rc; // 判断 *args 大小是否与 daos_pool_disconnect_t 的预期大小相等 DAOS_API_ARG_ASSERT(*args, POOL_DISCONNECT); // 创建新任务 dc_pool_disconnect,并将其与输入事件 ev 关联 // 如果事件 ev 为 NULL,则将获取私有事件 rc = dc_task_create(dc_pool_disconnect, NULL, ev, &task); if (rc) // dc_task_create 成功返回 0,失败返回负数 return rc; // 从 task 中获取参数 args = dc_task_get_args(task); args->poh = poh; // 调度创建的任务 task // 如果该任务的关联事件是私有事件,则此函数将等待任务完成 // 否则它将立即返回,并通过测试事件或在 EQ 上轮询找到其完成情况 // // 第二个参数 instant 为 true,表示任务将立即执行 return dc_task_schedule(task, true); }

结构体 daos_pool_disconnect_t 表示断开 Pool 连接到参数:

typedef struct { // 打开的 Pool 句柄 daos_handle_t poh; } daos_pool_disconnect_t;

daos_pool_local2global

daos_pool_local2global 函数将本地 Pool 连接转换为可与对等进程共享的全局表示数据。

如果 glob->iov_buf 设置为 NULL,则通过 glob->iov_buf_len 返回全局句柄的实际大小。

此功能不涉及任何通信,也不阻塞。

参数:

poh [in]:要共享的打开的 Pool 连接句柄。

glob [out]:指向 IO vector 缓冲区的指针,用于存储句柄信息。

返回值,在非阻塞模式下:

如果成功,返回 0。

如果失败:

-DER_INVAL:无效的参数。

-DER_NO_HDL:Pool 句柄无效。

-DER_TRUNC:glob 中的缓冲区过小,要求更大的缓冲区。在这种情况下,要求的缓冲区大学会被写入 glob->iov_buf_len。

int daos_pool_local2global(daos_handle_t poh, d_iov_t *glob) { return dc_pool_local2global(poh, glob); }

daos_pool_global2local

daos_pool_global2local 函数为全局表示数据创建本地 Pool 连接。

参数:

glob [in]:要提取的集合句柄的全局(共享)表示。

poh [out]:返回的本地 Pool 连接句柄。

返回值,在非阻塞模式下:

如果成功,返回 0。

如果失败,返回

-DER_INVAL:无效的参数。

int daos_pool_global2local(d_iov_t glob, daos_handle_t *poh) { return dc_pool_global2local(glob, poh); }

daos_pool_query

daos_pool_query 函数查询 Pool 信息。用户应至少提供 info 和 tgts 中的一个作为输出缓冲区。

参数:

poh [in]:Pool 连接句柄。

tgts [out]:可选,返回的 Pool 中的 Target。

info [in, out]:可选,返回的 Pool 信息,参考枚举类型 daos_pool_info_bit。

pool_prop [out]:可选,返回的 Pool 属性。

如果为空,则不需要查询属性。

如果 pool_prop 非空,但其 dpp_entries 为空,则将查询所有 Pool 属性,DAOS 在内部分配所需的缓冲区,并将指针分配给 dpp_entries。

如果 pool_prop 的 dpp_nr > 0 且 dpp_entries 非空,则会查询特定的 dpe_type 属性,DAOS 会在内部为 dpe_str 或 dpe_val_ptr 分配所需的缓冲区,如果具有立即数的 dpe_type 则会直接将其分配给 dpe_val。

用户可以通过调用 daos_prop_free() 释放关联的缓冲区。

ev [in]:结束事件,该参数是可选的,可以为 NULL。当该参数为 NULL 时,该函数在阻塞模式下运行。

返回值,在非阻塞模式下:

如果成功,返回 0。

如果失败:

-DER_INVAL:无效的参数。

-DER_UNREACH:无法访问网络。

-DER_NO_HDL:Pool 句柄无效。

int daos_pool_query(daos_handle_t poh, d_rank_list_t *tgts, daos_pool_info_t *info, daos_prop_t *pool_prop, daos_event_t *ev) { daos_pool_query_t *args; tse_task_t * task; int rc; // 判断 *args 大小是否与 daos_pool_query_t 的预期大小相等 DAOS_API_ARG_ASSERT(*args, POOL_QUERY); if (pool_prop != NULL && !daos_prop_valid(pool_prop, true, false)) { // 无效输入 D_ERROR("invalid pool_prop parameter.\n"); return -DER_INVAL; } // 创建新任务 dc_pool_query,并将其与输入事件 ev 关联 // 如果事件 ev 为 NULL,则将获取私有事件 rc = dc_task_create(dc_pool_query, NULL, ev, &task); if (rc) // dc_task_create 成功返回 0,失败返回负数 return rc; // 从 task 中获取参数 args = dc_task_get_args(task); args->poh = poh; args->tgts = tgts; args->info = info; args->prop = pool_prop; // 调度创建的任务 task // 如果该任务的关联事件是私有事件,则此函数将等待任务完成 // 否则它将立即返回,并通过测试事件或在 EQ 上轮询找到其完成情况 // // 第二个参数 instant 为 true,表示任务将立即执行 return dc_task_schedule(task, true); }

结构体 daos_prop_t 表示 DAOS

Pool 或 Container 的属性:

typedef struct { // 项的数量 uint32_t dpp_nr; // 保留供将来使用,现在用于 64 位对齐 uint32_t dpp_reserv; // 属性项数组 struct daos_prop_entry *dpp_entries; } daos_prop_t;

DAOS Pool 的属性类型包括:

enum daos_pool_props { // 在 (DAOS_PROP_PO_MIN, DAOS_PROP_PO_MAX) 范围内有效 DAOS_PROP_PO_MIN = 0, // 标签:用户与 Pool 关联的字符串 // default = "" DAOS_PROP_PO_LABEL, // ACL:Pool 的访问控制列表 // 详细说明用户和组访问权限的访问控制项的有序列表。 // 期望的主体类型:Owner, User(s), Group(s), Everyone DAOS_PROP_PO_ACL, // 保留空间比例:每个 Target 上为重建目的保留的空间量。 // default = 0%. DAOS_PROP_PO_SPACE_RB, // 自动/手动 自我修复 // default = auto // 自动/手动 排除 // 自动/手动 重建 DAOS_PROP_PO_SELF_HEAL, // 空间回收策略 = time|batched|snapshot // default = snapshot // time:时间间隔 // batched:commits // snapshot:快照创建 DAOS_PROP_PO_RECLAIM, // 充当 Pool 所有者的用户 // 格式:user@[domain] DAOS_PROP_PO_OWNER, // 充当 Pool 所有者的组 // 格式:group@[domain] DAOS_PROP_PO_OWNER_GROUP, // Pool 的 svc rank list DAOS_PROP_PO_SVC_LIST, DAOS_PROP_PO_MAX, }; // Pool 属性类型数量 #define DAOS_PROP_PO_NUM (DAOS_PROP_PO_MAX - DAOS_PROP_PO_MIN - 1)

结构体 daos_pool_query_t 表示 Pool 查询的参数:

typedef struct { // 打开的 Pool 句柄 daos_handle_t poh; // 可选,返回的 Pool 中的 Target d_rank_list_t *tgts; // 可选,返回的 Pool 信息 daos_pool_info_t *info; // 可选,返回的 Pool 属性 daos_prop_t *prop; } daos_pool_query_t;

daos_pool_query_target

daos_pool_query_target 函数在 DAOS Pool 中查询 Target 信息。

参数:

poh [in]:Pool 连接句柄。

tgt [in]:要查询的单个 Target 的索引。

rank [in]:要查询的 Target 索引的排名。

info [out]:返回的有关 tgt 的信息。

ev [in]:结束事件,该参数是可选的,可以为 NULL。当该参数为 NULL 时,该函数在阻塞模式下运行。

返回值,在非阻塞模式下:

如果成功,返回 0。

如果失败:

-DER_INVAL:无效的参数。

-DER_UNREACH:无法访问网络。

-DER_NO_HDL:Pool 句柄无效。

-DER_NONEXIST:指定 Target 上没有 Pool。

int daos_pool_query_target(daos_handle_t poh, uint32_t tgt, d_rank_t rank, daos_target_info_t *info, daos_event_t *ev) { daos_pool_query_target_t *args; tse_task_t * task; int rc; // 判断 *args 大小是否与 daos_pool_query_target_t 的预期大小相等 DAOS_API_ARG_ASSERT(*args, POOL_QUERY_INFO); // 创建新任务 dc_pool_query_target,并将其与输入事件 ev 关联 // 如果事件 ev 为 NULL,则将获取私有事件 rc = dc_task_create(dc_pool_query_target, NULL, ev, &task); if (rc) // dc_task_create 成功返回 0,失败返回负数 return rc; // 从 task 中获取参数 args = dc_task_get_args(task); args->poh = poh; args->tgt_idx = tgt_idx; args->rank = rank; args->info = info; // 调度创建的任务 task // 如果该任务的关联事件是私有事件,则此函数将等待任务完成 // 否则它将立即返回,并通过测试事件或在 EQ 上轮询找到其完成情况 // // 第二个参数 instant 为 true,表示任务将立即执行 return dc_task_schedule(task, true); }

结构体 daos_pool_query_target_t 表示 Pool 的 Target 查询参数:

typedef struct { // 打开的 Pool 句柄 daos_handle_t poh; // 要查询的单个 Target uint32_t tgt_idx; // 要查询的 Target 的等级 d_rank_t rank; // 返回的 Target 信息 daos_target_info_t *info; } daos_pool_query_target_t;

daos_pool_list_attr

daos_pool_list_attr 函数列出所有用户定义的 Pool 属性的名称。

参数:

poh [in]:Pool 句柄。

buffer [out]:包含所有属性名的串联的缓冲区,每个属性名以空字符结尾。不执行截断,只返回全名。允许为 NULL,在这种情况下,只检索聚合大小。

size [in, out]:

[in]:缓冲区大小。

[out]:所有属性名(不包括终止的空字符)的聚合大小,忽略实际缓冲区大小。

ev [in]:结束事件,该参数是可选的,可以为 NULL。当该参数为 NULL 时,该函数在阻塞模式下运行。

int daos_pool_list_attr(daos_handle_t poh, char *buffer, size_t *size, daos_event_t *ev) { daos_pool_list_attr_t *args; tse_task_t * task; int rc; // 判断 *args 大小是否与 daos_pool_list_attr_t 的预期大小相等 DAOS_API_ARG_ASSERT(*args, POOL_LIST_ATTR); // 创建新任务 dc_pool_list_attr,并将其与输入事件 ev 关联 // 如果事件 ev 为 NULL,则将获取私有事件 rc = dc_task_create(dc_pool_list_attr, NULL, ev, &task); if (rc) // dc_task_create 成功返回 0,失败返回负数 return rc; // 从 task 中获取参数 args = dc_task_get_args(task); args->poh = poh; args->buf = buf; args->size = size; // 调度创建的任务 task // 如果该任务的关联事件是私有事件,则此函数将等待任务完成 // 否则它将立即返回,并通过测试事件或在 EQ 上轮询找到其完成情况 // // 第二个参数 instant 为 true,表示任务将立即执行 return dc_task_schedule(task, true); }

结构体 daos_pool_list_attr_t 表示 Pool 列出属性参数:

typedef struct { // 打开的 Pool 句柄 daos_handle_t poh; // 包含所有属性名的串联的缓冲区 char *buf; // [in]:缓冲区大小 // [out]:所有属性名(不包括终止的空字符)的聚合大小 size_t *size; } daos_pool_list_attr_t;

daos_pool_get_attr

daos_pool_get_attr 函数获取用户定义的 Pool 属性值列表。

参数:

poh [in]:Pool 句柄。

n [in]:属性的数量。

names [in]:存储以空字符结尾的属性名的 n 个数组。

buffer [out]:存储属性值的 n 个缓冲区的数组。大于相应缓冲区大小的属性值将被截断。允许为 NULL,将被视为与零长度缓冲区相同,在这种情况下,只检索属性值的大小。

sizes [in, out]:

[in]:存储缓冲区大小的 n 个数组。

[out]:存储属性值实际大小的 n 个数组,忽略实际缓冲区大小。

ev [in]:结束事件,该参数是可选的,可以为 NULL。当该参数为 NULL 时,该函数在阻塞模式下运行。

int daos_pool_get_attr(daos_handle_t poh, int n, char const *const names[], void *const buffers[], size_t sizes[], daos_event_t *ev) { daos_pool_get_attr_t *args; tse_task_t * task; int rc; // 判断 *args 大小是否与 daos_pool_get_attr_t 的预期大小相等 DAOS_API_ARG_ASSERT(*args, POOL_GET_ATTR); // 创建新任务 dc_pool_get_attr,并将其与输入事件 ev 关联 // 如果事件 ev 为 NULL,则将获取私有事件 rc = dc_task_create(dc_pool_get_attr, NULL, ev, &task); if (rc) // dc_task_create 成功返回 0,失败返回负数 return rc; // 从 task 中获取参数 args = dc_task_get_args(task); args->poh = poh; args->n = n; args->names = names; args->values = values; args->sizes = sizes; // 调度创建的任务 task // 如果该任务的关联事件是私有事件,则此函数将等待任务完成 // 否则它将立即返回,并通过测试事件或在 EQ 上轮询找到其完成情况 // // 第二个参数 instant 为 true,表示任务将立即执行 return dc_task_schedule(task, true); }

结构体 daos_pool_get_attr_t 表示 Pool 获取属性的参数:

typedef struct { // 打开的 Pool 句柄 daos_handle_t poh; // 属性数量 int n; // 存储 n 个以空字符结尾的属性名的 char const *const *names; // 存储 n 个属性值的缓冲区 void *const *values; // [in]:存储 n 个缓冲区大小 // [out]:存储 n 个属性值实际大小 size_t *sizes; } daos_pool_get_attr_t;

daos_pool_set_attr

daos_pool_set_attr 函数创建或更新用户定义的 Pool 属性值列表。

参数:

poh [in]:Pool 句柄。

n [in]:属性的数量。

names [in]:存储以空字符结尾的属性名的 n 个数组。

values [in]:存储属性值的 n 个数组。

sizes [in]:存储相应属性值大小的 n 个元素的数组。

DAOS 源码解析之 daos_pool

ev [in]:结束事件,该参数是可选的,可以为 NULL。当该参数为 NULL 时,该函数在阻塞模式下运行。

int daos_pool_set_attr(daos_handle_t poh, int n, char const *const names[], void const *const values[], size_t const sizes[], daos_event_t *ev) { daos_pool_set_attr_t *args; tse_task_t * task; int rc; // 判断 *args 大小是否与 daos_pool_set_attr_t 的预期大小相等 DAOS_API_ARG_ASSERT(*args, POOL_SET_ATTR); // 创建新任务 dc_pool_set_attr,并将其与输入事件 ev 关联 // 如果事件 ev 为 NULL,则将获取私有事件 rc = dc_task_create(dc_pool_set_attr, NULL, ev, &task); if (rc) // dc_task_create 成功返回 0,失败返回负数 return rc; // 从 task 中获取参数 args = dc_task_get_args(task); args->poh = poh; args->n = n; args->names = names; args->values = values; args->sizes = sizes; // 调度创建的任务 task // 如果该任务的关联事件是私有事件,则此函数将等待任务完成 // 否则它将立即返回,并通过测试事件或在 EQ 上轮询找到其完成情况 // // 第二个参数 instant 为 true,表示任务将立即执行 return dc_task_schedule(task, true); }

结构体 daos_pool_set_attr_t 表示 Pool 设置属性的参数:

typedef struct { // 打开的 Pool 句柄 daos_handle_t poh; // 属性的数量 int n; // 存储 n 个以空字符结尾的属性名 char const *const *names; // 存储 n 个属性值 void const *const *values; // 存储 n 个相应属性值的大小。 size_t const *sizes; } daos_pool_set_attr_t;

daos_pool_del_attr

daos_pool_del_attr 函数删除用户定义的 Pool 属性值列表。

参数:

poh [in]:Pool 句柄。

n [in]:属性的数量。

names [in]:存储以空字符结尾的属性名的 n 个数组。

ev [in]:结束事件,该参数是可选的,可以为 NULL。当该参数为 NULL 时,该函数在阻塞模式下运行。

返回值,在非阻塞模式下会被写入 ev::ev_error:

如果成功,返回 0。

如果失败,返回

-DER_INVAL:无效的参数。

-DER_UNREACH:无法访问网络。

-DER_NO_PERM:没有访问权限。

-DER_NO_HDL:无效的 Container 句柄。

-DER_NOMEM:内存不足。

int daos_pool_del_attr(daos_handle_t poh, int n, char const *const names[], daos_event_t *ev) { daos_pool_del_attr_t *args; tse_task_t * task; int rc; // 判断 *args 大小是否与 daos_pool_del_attr_t 的预期大小相等 DAOS_API_ARG_ASSERT(*args, POOL_DEL_ATTR); // 创建新任务 dc_pool_del_attr,并将其与输入事件 ev 关联 // 如果事件 ev 为 NULL,则将获取私有事件 rc = dc_task_create(dc_pool_del_attr, NULL, ev, &task); if (rc) // dc_task_create 成功返回 0,失败返回负数 return rc; // 从 task 中获取参数 args = dc_task_get_args(task); args->poh = poh; args->n = n; args->names = names; // 调度创建的任务 task // 如果该任务的关联事件是私有事件,则此函数将等待任务完成 // 否则它将立即返回,并通过测试事件或在 EQ 上轮询找到其完成情况 // // 第二个参数 instant 为 true,表示任务将立即执行 return dc_task_schedule(task, true); }

结构体 daos_pool_del_attr_t 表示 Pool 删除属性的参数:

typedef struct { // 打开的 Pool 句柄 daos_handle_t poh; // 属性的数量 int n; // 存储 n 个以空字符结尾的属性名 char const *const *names; } daos_pool_del_attr_t;

daos_pool_list_cont

daos_pool_list_cont 函数列出 Pool 的 Container。

参数:

poh [in]:Pool 连接句柄。

ncont [in, out]:

[in]:以元素为单位的 cbuf 长度。

[out]:Pool 中的 Container 数量。

cbuf [out]:存储 Container 结构的数组。允许为 NULL,在这种情况下只会讲 Container 的数量写入 ncont 返回。

ev [in]:结束事件,该参数是可选的,可以为 NULL。当该参数为 NULL 时,该函数在阻塞模式下运行。

返回值:

如果成功,返回 0。

如果失败,返回

-DER_INVAL:无效的参数。

-DER_TRUNC:cbuf 没有足够的空间存储 ncont 个元素。

int daos_pool_list_cont(daos_handle_t poh, daos_size_t *ncont, struct daos_pool_cont_info *cbuf, daos_event_t *ev) { daos_pool_list_cont_t *args; tse_task_t * task; int rc; // 判断 *args 大小是否与 daos_pool_list_cont_t 的预期大小相等 DAOS_API_ARG_ASSERT(*args, POOL_LIST_CONT); if (ncont == NULL) { // 无效输入 D_ERROR("ncont must be non-NULL\n"); return -DER_INVAL; } // 创建新任务 dc_pool_list_cont,并将其与输入事件 ev 关联 // 如果事件 ev 为 NULL,则将获取私有事件 rc = dc_task_create(dc_pool_list_cont, NULL, ev, &task); if (rc) // dc_task_create 成功返回 0,失败返回负数 return rc; // 从 task 中获取参数 args = dc_task_get_args(task); args->poh = poh; args->ncont = ncont; args->cont_buf = cbuf; // 调度创建的任务 task // 如果该任务的关联事件是私有事件,则此函数将等待任务完成 // 否则它将立即返回,并通过测试事件或在 EQ 上轮询找到其完成情况 // // 第二个参数 instant 为 true,表示任务将立即执行 return dc_task_schedule(task, true); }

相关信息

Emai: debugzhang@163.com

DAOS: https://github.com/daos-stack/daos

分布式 存储 对象存储服务 OBS

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:关于 Linux中Git等知识的一些笔记
下一篇:一个初学者的云开发心得
相关文章