DAOS 源码解析之 daos_pool
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
个元素的数组。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
- 点赞
- 收藏
- 关注作者
评论(0)