DAOS 源码解析之 daos_pool

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

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_uuidpi_leader 的字段。但是 pi_spacepi_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_TRUNCglob 中的缓冲区过小,要求更大的缓冲区。在这种情况下,要求的缓冲区大学会被写入 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 信息。用户应至少提供 infotgts 中的一个作为输出缓冲区。

参数:

  • 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_propdpp_nr > 0 且 dpp_entries 非空,则会查询特定的 dpe_type 属性,DAOS 会在内部为 dpe_strdpe_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_TRUNCcbuf 没有足够的空间存储 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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。