当前位置 : 主页 > 编程语言 > c语言 >

rdma-core之libibverbs案例分析

来源:互联网 收集:自由互联 发布时间:2023-08-28
这个是一些列分析,主要用于帮助自己的理解和记录思考时候的一些笔记。 device_list.c // 库文件的导入#include config.h#include stdio.h#include endian.h#include infiniband/verbs.hint main(int argc, char *arg

这个是一些列分析,主要用于帮助自己的理解和记录思考时候的一些笔记。

device_list.c

// 库文件的导入
#include <config.h>
#include <stdio.h>
#include <endian.h>
#include <infiniband/verbs.h>

int main(int argc, char *argv[])
{
	struct ibv_device **dev_list; // 等价于struct ibv_device dev_list[][],类似一个二维数组,数组里面每一个都是存储ibv_device信息的
	int num_devices, i;

	dev_list = ibv_get_device_list(&num_devices); // 这个就是获取这个机器上面能够获取到的所有的RDMA设备信息,然后把信息存储在dev_list里面。
	if (!dev_list) {
		perror("Failed to get IB devices list");
		return 1;
	}
	// 打印相关的设备的厂商信息GUID和设备信息
	printf("    %-16s\t   node GUID\n", "device");
	printf("    %-16s\t----------------\n", "------");

	// 具体的打印过程
	for (i = 0; i < num_devices; ++i) {
		printf("    %-16s\t%016llx\n",
		       ibv_get_device_name(dev_list[i]),
		       (unsigned long long) be64toh(ibv_get_device_guid(dev_list[i])));
	}

	ibv_free_device_list(dev_list); // 释放dev_list里面的所有设备信息,避免内存泄漏。

	return 0;
}

总结:获取设备信息,并且打印所有的设备信息和GUID,最后把获取的设备资源释放掉,避免内存泄漏。

asyncwatch.c

// 主函数,阅读入口
int main(int argc, char *argv[])
{
	struct ibv_device **dev_list; // 设备数组
	struct ibv_context *context; // ibv的上下文(个人理解就是具体操作的设备上下文信息)
	struct ibv_async_event event; // 异步事件
	char   *ib_devname = NULL; // 具体使用的设备名称
	int i = 0;

	/* Force line-buffering in case stdout is redirected */
	setvbuf(stdout, NULL, _IOLBF, 0); // stdout是标准的输出流指针,输出到屏幕。整个功能是,在屏幕上面只要遇到\n就覆情况,然后刷新屏幕信息。

	while (1) {
		int ret = 1;
		int c;
		static struct option long_options[] = {
			{ .name = "ib-dev",    .has_arg = 1, .val = 'd' },
			{ .name = "help",      .has_arg = 0, .val = 'h' },
			{}
		};

		c = getopt_long(argc, argv, "d:h", long_options, NULL); // 参数解析,只接受d和h的参数
		if (c == -1)
			break;
		switch (c) {
		case 'd':
			ib_devname = strdupa(optarg);
			break;
		case 'h':
			ret = 0;
			SWITCH_FALLTHROUGH;
		default:
			usage(argv[0]);
			return ret;
		}
	}
	dev_list = ibv_get_device_list(NULL); // 用于获取所有的dev信息存储在dev_list里面。
	if (!dev_list) {
		perror("Failed to get IB devices list");
		return 1;
	}
  // 指定了设备名称,查找这个设备信息
	if (ib_devname) {
		for (; dev_list[i]; ++i) {
			if (!strcmp(ibv_get_device_name(dev_list[i]), ib_devname))
				break;
		}
	}

	if (!dev_list[i]) {
		fprintf(stderr, "IB device %s not found\n",
			ib_devname ? ib_devname : "");
		return 1;
	}

	context = ibv_open_device(dev_list[i]); // 把设备打开,保存设备的上下文(查资料看到,这个地方会顺便初始化context)
	if (!context) {
		fprintf(stderr, "Couldn't get context for %s\n",
			ibv_get_device_name(dev_list[i]));
		return 1;
	}

  // 打印设备名字和异步文件描述符信息
	printf("%s: async event FD %d\n",
	       ibv_get_device_name(dev_list[i]), context->async_fd);

  // 获取事件,然后打印信息
	while (1) {
		if (ibv_get_async_event(context, &event))
			return 1;

		printf("  event_type %s (%d), port %d\n",
		       event_name_str(event.event_type),
		       event.event_type, event.element.port_num);

		ibv_ack_async_event(&event);
	}

	return 0;
}

上面最后几行代码里面有调用这个event_name_str函数,这个函数就是返回对应的事件信息。

static const char *event_name_str(enum ibv_event_type event_type)
{
	switch (event_type) {
	case IBV_EVENT_DEVICE_FATAL:
		return "IBV_EVENT_DEVICE_FATAL";
	case IBV_EVENT_PORT_ACTIVE:
		return "IBV_EVENT_PORT_ACTIVE";
	case IBV_EVENT_PORT_ERR:
		return "IBV_EVENT_PORT_ERR";
	case IBV_EVENT_LID_CHANGE:
		return "IBV_EVENT_LID_CHANGE";
	case IBV_EVENT_PKEY_CHANGE:
		return "IBV_EVENT_PKEY_CHANGE";
	case IBV_EVENT_SM_CHANGE:
		return "IBV_EVENT_SM_CHANGE";
	case IBV_EVENT_CLIENT_REREGISTER:
		return "IBV_EVENT_CLIENT_REREGISTER";
	case IBV_EVENT_GID_CHANGE:
		return "IBV_EVENT_GID_CHANGE";

	case IBV_EVENT_CQ_ERR:
	case IBV_EVENT_QP_FATAL:
	case IBV_EVENT_QP_REQ_ERR:
	case IBV_EVENT_QP_ACCESS_ERR:
	case IBV_EVENT_COMM_EST:
	case IBV_EVENT_SQ_DRAINED:
	case IBV_EVENT_PATH_MIG:
	case IBV_EVENT_PATH_MIG_ERR:
	case IBV_EVENT_SRQ_ERR:
	case IBV_EVENT_SRQ_LIMIT_REACHED:
	case IBV_EVENT_QP_LAST_WQE_REACHED:
	default:
		return "unexpected";
	}
}

总结:首先解析命令行信息,然后获取设备和上下文信息,最后获取事件信息,然后打印事件的详细信息。

【文章原创作者:高防cdn http://www.558idc.com/gfcdn.html提供,感恩】
上一篇:Qt 新手小白从0开始学习笔记-持续更新
下一篇:没有了
网友评论