当前位置: 首页 > news >正文

多看看spdk代码学习

多看看spdk代码学习

  • 还是干货直接上代码
  • 简易讲解
  • 详细讲解一下这份代码

还是干货直接上代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdbool.h>
#include <pthread.h>
#include <spdk/nvme.h>
#define MAX_CONTROLLERS 16
static struct spdk_nvme_ctrlr *g_controllers[MAX_CONTROLLERS];
static int g_num_controllers = 0;
static void
ctrlr_init_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,struct spdk_nvme_ctrlr_opts *opts)
{printf("Initializing controller %!s(MISSING)\n", trid->traddr);
}
static void
ctrlr_attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
{printf("Attached to controller %!s(MISSING)\n", trid->traddr);g_controllers[g_num_controllers++] = ctrlr;
}
static void
ctrlr_detach_cb(void *cb_ctx, struct spdk_nvme_ctrlr *ctrlr)
{printf("Detached from controller %!s(MISSING)\n", spdk_nvme_ctrlr_get_trid(ctrlr)->traddr);
}
static void
sigint_handler(int signal)
{int i;printf("Caught signal %!d(MISSING)\n", signal);for (i = 0; i < g_num_controllers; i++) {spdk_nvme_detach(g_controllers[i]);}spdk_nvme_cleanup();exit(0);
}
int main(int argc, char **argv)
{struct spdk_env_opts opts;struct spdk_env_opts_init(&opts);opts.name = "helloworld";opts.core_mask = "0x1";opts.shm_id = 0;spdk_env_init(&opts);struct spdk_nvme_transport_id trid = { 0 };const char *address = "0000:04:00.0";trid.trtype = SPDK_NVME_TRANSPORT_PCIE;trid.adrfam = SPDK_NVMF_ADRFAM_IPV4;strncpy(trid.traddr, address, sizeof(trid.traddr));struct spdk_nvme_ctrlr_opts ctrlr_opts;struct spdk_nvme_ctrlr_opts_set_defaults(&ctrlr_opts);ctrlr_opts.num_io_queues = 4;ctrlr_opts.use_cmb_sqs = true;struct spdk_nvme_probe_ctx *probe_ctx;probe_ctx = spdk_nvme_connect_async(&trid, &ctrlr_opts, sizeof(ctrlr_opts),ctrlr_init_cb, ctrlr_attach_cb, ctrlr_detach_cb);if (probe_ctx == NULL) {printf("Failed to connect to NVMe controller\n");exit(1);}signal(SIGINT, sigint_handler);while (true) {spdk_nvme_probe_poll_async(probe_ctx);usleep(1000);}return 0;
}

简易讲解

这个代码的作用是连接到一个NVMe SSD,并且打印出一些连接的信息。它的执行流程如下:

  1. 初始化SPDK环境。
  2. 定义NVMe控制器的传输ID和选项。
  3. 定义NVMe控制器连接的回调函数。
  4. 连接到NVMe控制器。
  5. 注册SIGINT信号处理函数。
  6. 循环调用spdk_nvme_probe_poll_async函数,等待NVMe控制器连接。
  7. 注销SPDK环境。
    在这个代码中,我们使用了以下的NVMe相关函数:
  • spdk_nvme_connect_async:异步连接到NVMe控制器。
  • spdk_nvme_ctrlr_opts_set_defaults:设置NVMe控制器选项的默认值。
  • spdk_nvme_probe_poll_async:异步探测NVMe控制器。
  • spdk_nvme_detach:断开与NVMe SSD的连接。
  • signal:注册信号处理函数。
    这个代码演示了如何使用SPDK的NVMe模块连接到NVMe SSD,并且可以扩展它来执行更复杂的操作。在实际的应用程序中,我们可以根据需要修改这个代码,比如读取数据、使用多个队列、使用多个命名空间等。

详细讲解一下这份代码

首先,我们需要了解一下NVMe(Non-Volatile Memory Express)是什么。NVMe是一个通用的高速输入/输出接口,用于连接Flash和其他非易失性存储器设备。它被设计为一种高效、低延迟的接口,可以满足需要高速数据传输的应用程序的需求。NVMe是一种标准化接口,它提供了一个统一的命令集和控制器接口,可以让软件开发人员更容易地访问和管理存储设备。

那么,这份代码的作用是什么呢?它的主要功能是连接到一个NVMe SSD,并且打印出一些连接的信息。具体的执行流程如下:

  1. 初始化SPDK环境。
    这一步非常简单,只需要调用spdk_env_init函数即可。当然,我们也可以通过spdk_env_opts_init函数来设置环境选项。
  2. 定义NVMe控制器的传输ID和选项。
    在这个代码中,我们定义了一个struct spdk_nvme_transport_id类型的变量trid,用于指定NVMe SSD的传输ID。同时,我们也定义了一个struct spdk_nvme_ctrlr_opts类型的变量ctrlr_opts,用于设置NVMe控制器的选项,比如队列数量、命名空间等。
  3. 定义NVMe控制器连接的回调函数。
    在这个代码中,我们定义了三个回调函数,分别是ctrlr_init_cb、ctrlr_attach_cb和ctrlr_detach_cb。这些回调函数会在NVMe控制器连接的不同阶段被调用,我们可以在这些回调函数中实现一些自定义的逻辑。
  4. 连接到NVMe控制器。
    通过调用spdk_nvme_connect_async函数,我们可以异步地连接到NVMe控制器。这个函数会返回一个指向spdk_nvme_probe_ctx类型的结构体的指针,我们可以在之后的异步操作中使用这个结构体。
  5. 注册SIGINT信号处理函数。
    我们可以通过调用signal函数来注册信号处理函数,这里我们注册了SIGINT信号的处理函数。
  6. 循环调用spdk_nvme_probe_poll_async函数,等待NVMe控制器连接。
    在这个代码中,我们使用了一个循环来等待NVMe控制器的连接,这个循环中调用了spdk_nvme_probe_poll_async函数。这个函数会异步地探测NVMe控制器,如果探测到了NVMe控制器,就会调用之前定义的回调函数。我们可以在这些回调函数中实现一些自定义的逻辑,比如读取数据、使用多个队列、使用多个命名空间等。
  7. 注销SPDK环境。
    当程序退出时,我们需要调用spdk_nvme_cleanup函数来注销SPDK环境。
    这份代码涉及到了一些SPDK NVMe模块的API,比如spdk_nvme_connect_async、spdk_nvme_probe_poll_async、spdk_nvme_detach等。如果你想深入了解这些API的使用方法,可以参考SPDK官方文档。

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

相关文章:

多看看spdk代码学习

多看看spdk代码学习还是干货直接上代码简易讲解详细讲解一下这份代码还是干货直接上代码 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <signal.h> #include <stdbo…...

宾语从句it做形式主语的句子

It代替从句作形式主语的常见句型 一、it 代替连词 that 引导的从句作形式主语。 1、it be 过去分词 that 从句: It’s said that Tom has come back from abroad . It was reported that dozens of children died in the accident . 可用于该句型的过去分词还有&#xf…...

【C#基础】C# 文件与IO

序号系列文章9【C# 基础】C# 异常处理操作10【C#基础】C# 正则表达式11【C#基础】C# 预处理器指令文章目录前言1&#xff0c;文件和IO的概念2&#xff0c;文本文件操作2.1 File 类2.2 FileInfo 类2.3 FileStream 类2.4 StreamReader 类2.5 StreamWriter 类FileStream 和 Stream…...

死锁相关介绍【内含哲学家就餐问题】

死锁 死锁是这样一种情形&#xff1a;多个线程同时被阻塞&#xff0c;它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞&#xff0c;因此程序不可能正常终止。 场景1&#xff1a;一个线程&#xff0c;一把锁 一个线程&#xff0c;一把锁&#xff0c;线程…...

Java的Groovy执行器内存泄露(MetaSpace)问题分析与解决办法

环境与背景 在java程序中通过GroovyScriptEvaluator执行器创建脚本Script对象调用Groovy脚本语言来完成某些功能, ,会通过AppClassLoader或者GroovyClassLoader去生产一个随机的名称的Groovy的Script类对象,导致元数据,产生的class类会被AppClassLoader或者GroovyClassLoader内…...

【linux】进程信号——信号的产生

进程信号一、信号概念1.1 信号理解二、产生信号2.1 通过键盘产生信号2.2 捕捉信号自定义signal2.3 系统调用接口产生信号2.3.1 向任意进程发送任意信号kill2.3.2 给自己发送任意信号raise2.3.3 给自己发送指定信号abort2.3.4 理解2.4 硬件异常产生信号2.4.1 除0异常2.4.2 野指针…...

部署OpenStack

部署 1. 环境配置 配置主机名 使用CRT软件连接controller节点和compute节点&#xff0c;用户名默认为root&#xff0c;密码默认为000000。连接上之后&#xff0c;使用linux命令修改节点主机名。 [rootcontroller ~]# hostnamectl set-hostname controller [rootcontroller …...

Java 运算符与类型转化

Java 运算符与类型转化 1 算术运算符 Java中的算术运算符主要有&#xff08;加&#xff09;、-&#xff08;减&#xff09;、*&#xff08;乘&#xff09;、/&#xff08;除&#xff09;、%&#xff08;求余&#xff09;&#xff0c;它们都是二元运算符。 2 自增和自减运算…...

《C++ Primer Plus》第18章:探讨 C++ 新标准(2)

移动语义和右值引用 现在介绍本书前面未讨论的主题。C11 支持移动语义&#xff0c;这就提出了一些问题&#xff1a;为何需要移动语义&#xff1f;什么是移动语义&#xff1f;C11 如何支持它&#xff1f;下面首先讨论第一个问题。 为何需要移动语义 先来看 C11 之前的复制过程…...

QML定时器

QML使用Timer使用定时器 Timer 计时器可用于触发操作一次&#xff0c;或以给定的间隔重复触发。 常用属性&#xff1a; interval 设置触发器之间的间隔&#xff08;以毫秒为单位&#xff09;。 默认间隔为 1000 毫秒。 repeat 设置重复&#xff0c;为真&#xff0c;则以指定的…...

第三章 opengl之纹理

OpenGL纹理纹理环绕方式纹理过滤多级渐远纹理加载和创建纹理stb_image.h生成纹理纹理的应用纹理单元纹理 用stb_image.h库&#xff0c;原先用SOIL库也可以实现。 可以为每个顶点添加颜色来增加图形的细节。但是想得到一个真实的图形&#xff0c;需要足够多的顶点&#xff0c;…...

【Flink】FlinkSQL中执行计划以及如何用代码看执行计划

FilnkSQL怎么查询优化 Apache Flink 使用并扩展了 Apache Calcite 来执行复杂的查询优化。 这包括一系列基于规则和成本的优化,例如: • 基于 Apache Calcite 的子查询解相关 • 投影剪裁 • 分区剪裁 • 过滤器下推 • 子计划消除重复数据以避免重复计算 • 特殊子查询重写,…...

从业者必读,一篇文章轻松掌握DevOps核心概念和最佳技能实践!

文章目录前言一. DevOps的定义及由来二. DevOps的价值三. devops工具有哪些3.1 devops工程师的硬实力3.2 devops工程师的软实力总结前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓月&#xff0c;本文是对DevOps的总结&#xff0c;一篇文章告诉你什么是DevOps. 对很多…...

2023爱分析·一体化HR SaaS市场厂商评估报告:北森

目录 1.研究范围定义 2. 一体化HR SaaS市场分析 3.厂商评估&#xff1a;北森 4.入选证书 1.研究范围定义 研究范围 伴随数字化转型走向深入&#xff0c;企业人力资源数字化也进入快速发展阶段&#xff0c;人力资源的价值也得到了重新审视和定义。政策层面&#xff0c;《…...

JAVA练习67-二叉树的中序遍历

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、题目-二叉树的中序遍历 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 3月3日练习…...

【JeecgBoot-Vue3】第1节 源码下载和环境安装与启动

目录 一. 资料 1. 源码下载 2. 官网启动文档 二、 前端开发环境安装 2.1 开发工具 2.2 前后端代码下载 2.3 前端启动 Step 1&#xff1a;安装nodejs npm Step 2&#xff1a;配置国内镜像&#xff08;这里选阿里&#xff09; Step 3&#xff1a;安装yarn Step 4&…...

WebAPI

WebAPI知识详解day11.Web API 基本认知作用和分类什么是DOM&#xff1f;DOM树的概念DOM对象2.获取DOM对象通过css选择器获取dom对象通过其他方法获取dom3.设置/修改DOM元素内容方法1. document.write() 方法方法2. 对象.innerText 属性方法3. 对象.innerHTML4.设置/修改DOM元素…...

Shell命令——date的用法

date命令可以用来显示或设定系统的日期与时间。 一、显示系统的日期与时间 &#xff08;1&#xff09;如果date命令后面不加任何参数&#xff0c;则会按照固定的格式显示时间信息&#xff1a; 星期几 月份 日 时:分:秒 时区 年xjhubuntu:~/iot/tmp$ date Fri Mar 3 16:56:4…...

XSS跨站脚本

XSS跨站脚本XSS简介XSS验证XSS危害XSS简介 XSS被称为跨站脚本攻击(Cross-site scripting)&#xff0c;由于和CSS(Cascading Style Sheets)重名&#xff0c;所以改为XSS。XSS主要基于javascript语言完成恶意的攻击行为&#xff0c;因为javascript可以非常灵活的操作html、css和…...

【强烈建议收藏:MySQL面试必问系列之慢SQL优化专题】

一.知识回顾 学习本篇文章之前呢&#xff0c;我们可以先看一下【强烈建议收藏:MySQL面试必问系列之SQL语句执行专题】&#xff0c;看完这篇文章再来学习本篇文章可谓是如虎添翼。好的&#xff0c;那我们也不讲太多的废话&#xff0c;直接开始。 二.如何做慢SQL查询优化呢&…...

抓紧时间学AI大模型,抓住金三银四机会抢占高薪offer(附转型大模型学习路线)!!!

2026年金三银四跳槽黄金期快来了&#xff01;给大家整理了转型需要跳槽路径、学习建议、学习内容&#xff0c;有转型想法的宝子建议收藏&#xff5e;今年AI大模型应用开发工程师、AI产品经理、AI智能硬件解决方案工程师等AI行业的岗位数量将会暴涨。 数据显示&#xff0c;AI相关…...

Pi0机器人控制中心惊艳案例:YOLOv8实时目标检测系统

Pi0机器人控制中心惊艳案例&#xff1a;YOLOv8实时目标检测系统 本文展示了Pi0机器人控制中心集成YOLOv8实现的实时目标检测系统&#xff0c;通过多场景测试数据和性能指标分析&#xff0c;全面呈现了这一技术方案的实际应用效果。 1. 系统概览与核心能力 Pi0机器人控制中心集…...

费曼说“造不出来就是不明白“,芯片工程师画不出时序图也一样

费曼在黑板上写过一句话&#xff1a;"What I cannot create, I do not understand."如果你真的懂&#xff0c;你应该能从头把它造出来。放到芯片设计里&#xff0c;这个逻辑一样成立。有一类工程师&#xff0c;RTL看得很流畅&#xff0c;但一旦问他"这个模块的微…...

头歌平台实战:如何通过预防性维护避免斐波那契数列计算的性能陷阱

头歌平台实战&#xff1a;斐波那契数列计算的性能优化与预防性维护 在编程学习与算法实践中&#xff0c;斐波那契数列计算是一个经典案例。它不仅帮助我们理解递归与迭代的区别&#xff0c;更是性能优化和代码维护的绝佳教材。本文将从头歌平台的实际任务出发&#xff0c;深入探…...

解密Doris副本同步机制:Raft协议在分布式查询中的特殊优化

Doris副本同步机制的深度优化&#xff1a;Raft协议在OLAP场景下的创新实践 在分布式数据库领域&#xff0c;副本同步机制是确保数据高可用和一致性的核心技术。Apache Doris作为一款高性能的MPP分析型数据库&#xff0c;其副本管理系统在标准Raft协议基础上进行了多项创新优化&…...

Origin计算XRD半峰宽(FWHM)

在材料表征中&#xff0c;XRD衍射峰的半峰宽&#xff08;FWHM&#xff09;是一个非常关键的参数&#xff0c;常用于晶粒尺寸计算&#xff08;如Scherrer公式&#xff09;、结晶度分析等。半峰宽&#xff0c;顾名思义&#xff0c;就是峰高一半位置的宽度。峰越宽表明该材料晶粒越…...

linux2.6.28 MTD 内存技术设备(块设备)platform driver源码分析

//////////////////////drivers/mtd/nand/s3c_nand.c module_init(s3c_nand_init);//模块初始化 static int __init s3c_nand_init(void) { printk(“S3C NAND Driver, © 2008 Samsung Electronics\n”); platform_driver_register(&s3c6400_nand_driver); platform_d…...

Kubernetes 1.28 集群架构深入解析:从基础到企业级部署

文章目录 🌐 Kubernetes 1.28 集群架构深度解析:从基础到企业级部署 ✅ 前言:云原生时代的操作系统 一、Kubernetes 1.28 集群架构全景图 1.1 核心设计哲学:声明式、期望状态、控制器模式 1.2 架构演进:从单节点到全球分布式集群 1.3–1.5 架构组件全景(统一图谱) 二、…...

手机拍照为啥总翻车?一文看懂ISP芯片如何拯救你的废片

手机拍照为啥总翻车&#xff1f;一文看懂ISP芯片如何拯救你的废片 每次拍完照片查看相册时&#xff0c;是否常遇到这些崩溃瞬间&#xff1f;夜景模式拍出的灯光全是模糊光斑&#xff0c;逆光下的人脸黑得像剪影&#xff0c;餐厅暖光让食物颜色失真发黄…这些翻车现场背后&#…...

从MYCIN到GPT-4:专家系统40年进化史中的5个关键转折点

从MYCIN到GPT-4&#xff1a;专家系统40年进化史中的5个关键转折点 1976年&#xff0c;斯坦福大学的传染病专家们面对一个棘手问题&#xff1a;如何快速准确诊断脑膜炎患者的病原体类型&#xff1f;传统实验室检测需要48小时&#xff0c;而患者往往等不起。这个临床需求催生了MY…...