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

Linux nbd 网络块设备(2)-内核实现

Linux nbd网络块设备(2)-内核实现

关注我,一起学习吧,后续持续更新内核相关

1. 概述:

  • 内核linux/drivers/block/nbd.c 是nbd 网络设备的底层驱动实现逻辑。
  • 本文主要介绍nbd 设备注册及I/O请求的处理逻辑。

2. nbd 设备的初始化:

在这里插入图片描述

  • disk 注册到内核后会产生/dev/nbdx 节点,后续nbd_client 可以通过该节点开始nbd 块设备传输;

  • 设置tag_set.ops操作函数:

    nbd->tag_set.ops = &nbd_mq_ops;
    static const struct blk_mq_ops nbd_mq_ops = {.queue_rq	= nbd_queue_rq,.complete	= nbd_complete_rq,.init_request	= nbd_init_request,.timeout	= nbd_xmit_timeout,
    };
    
  • 设置disk 的操作函数:

    • 该函数集主要用于nbd_client 打开nbd 设备,执行ioctl 指令,开始块传输等操作;
    disk->fops = &nbd_fops;
    static const struct block_device_operations nbd_fops =
    {.owner =	THIS_MODULE,.open =		nbd_open,.release =	nbd_release,.ioctl =	nbd_ioctl,.compat_ioctl =	nbd_ioctl,.free_disk =	nbd_free_disk,
    };
    
  • nbd 与tag_set 的关联:

    • tag_set 是nbd的成员

    • tag_set的driver_data 指向该nbd

      nbd->tag_set
      nbd->tag_set.driver_data=nbd
      
  • nbd 与disk的关联:

    • disk 基于tag_set 分配并初始化
    • disk 是nbd 的成员
    • disk的private_data 指向该nbd
    disk = blk_mq_alloc_disk(&nbd->tag_set, NULL);
    nbd->disk = disk;
    disk->private_data = nbd;
    

3. nbd 设备实例创建流程:

在这里插入图片描述

  • nbd_fops 是操作disk 时的相关处理函数,执行nbd_open时会实例化config
  • 所有的ioctl cmd 均通过nbd_ioctl 进行处理,主要设置config 相关属性
  • 执行完NBD_DO_IT 后,nbd 会更新硬件队列并将recv_work 提交工作队列
  • sock 存储关系:
    • 可以通config→socks[connection_number]→sock 访问到链接nbd_client 建立的sock,基于该sock 读取nbd_client 的数据或发送相关cmd

      //nbd.c nbd_add_socket()
      sock = nbd_get_socket(nbd, arg, &err);
      nsock->sock = sock;
      socks[config->num_connections++] = nsock;
      config->socks = socks;
      

3. nbd I/O 传输流程:

  • 通过sock 将块层请求发送给服务端
    • 以virtual-media 为例,将读取镜像的请求通过sock 发送给远程服务端
  • 通过sock 读取来着服务端的响应及响应数据,然后存储到bio_vec 指定内存。供更底层设备获取。

3.1 nbd 块层请求及数据发送:

  • 以virtual-meida 举例,USB层会将USB的请求转换为块请求,并通过nbd_queue_rq 将请求数据通过sock 发给服务端。
    在这里插入图片描述

3.2 nbd 接收处理:

  • recv_work 触发:
    • nbd 模组初始化执行nbd_dev_add 的时候,会创建recv_workq接收工作队列;
    • nbd 响应NBD_DO_IT ioctl cmd 执行nbd_start_device(nbd);时,将recv_work 提交到recv_workq,内核调度会执行recv_workq的工作线程,并执行recv_work.
    • 在recv_work 中主要通过socket读取服务端replay 并读取对应数据到bio_vec
      在这里插入图片描述

相关文章:

  • Universal Media Server (UMS)部署指南
  • 如何做好一份技术文档?
  • docker面试题(3)
  • 学习路之uniapp--unipush2.0推送功能--使用
  • Python包管理工具uv 国内源配置
  • XCOSnTh-fatfsShell
  • 使用Gemini, LangChain, Gradio打造一个书籍推荐系统 (第一部分)
  • 友思特方案 | 光示原形:高精度晶圆缺陷检测的高功率UVLED方案
  • SOC-ESP32S3部分:4-参数配置可视化menuconfig
  • 如何通过外链建设提升Shopify独立站的权重和排名
  • 第9.1讲、Tiny Encoder Transformer:极简文本分类与注意力可视化实战
  • 23种经典设计模式(GoF设计模式)
  • 【spring】spring学习系列之十一:spring的事件监听
  • 《会计研究》顶刊数据复刻!上市公司环境规制压力数据及研究价值
  • Android多线程下载文件拆解:原理、实现与优化
  • 2570. 合并两个二维数组 - 求和法
  • 每日leetcode
  • 手搓四人麻将程序
  • 如何应对kaggle离线安装环境?
  • 5月21日星期三今日早报简报微语报早读
  • 网站建设注意那/网页开发培训网
  • 做h5小游戏的网站有哪些/5g网络优化工程师
  • 泰安人才网首页/常州seo
  • 不会写程序如何做网站/seo短视频网页入口引流下载
  • 顶尖的锦州网站建设/广州seo排名外包
  • 报纸门户网站建设方案/bt种子bt天堂