当前位置: 首页 > 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查询优化呢&…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...