轻量级虚拟化技术草稿
Support Tech
ST.1 virtiofs
ST.1.1 fuse framework
引用wiki中关于fuse的定义:
Filesystem in Userspace (FUSE) is a software interface for Unix and Unix-like computer operating systems that lets non-privileged users create their own file systems without editing kernel code. This is achieved by running file system code in user space while the FUSE module provides only a bridge to the actual kernel interfaces.
其代码框架如下:

主要分为三部分:
- 内核Fuse Filsystem Client,对接Linux Kernel的VFS
- Fuse协议,其中包括了op code及其参数格式,参考GitHub - libfuse/libfuse: The reference implementation of the Linux FUSE (Filesystem in Userspace) interfaceThe reference implementation of the Linux FUSE (Filesystem in Userspace) interface - GitHub - libfuse/libfuse: The reference implementation of the Linux FUSE (Filesystem in Userspace) interface
https://github.com/libfuse/libfuse - Fuse传输层,目前包括两种,本地char设备和virtio
参考代码:
fuse_do_readpage()
---...loff_t pos = page_offset(page);struct fuse_page_desc desc = { .length = PAGE_SIZE };struct fuse_io_args ia = {.ap.args.page_zeroing = true,.ap.args.out_pages = true,.ap.num_pages = 1,.ap.pages = &page,.ap.descs = &desc,};...fuse_wait_on_page_writeback(inode, page->index);...fuse_read_args_fill(&ia, file, pos, desc.length, FUSE_READ);res = fuse_simple_request(fm, &ia.ap.args);...SetPageUptodate(page);
---fuse_lookup_name()
---fuse_lookup_init(fm->fc, &args, nodeid, name, outarg);---args->opcode = FUSE_LOOKUP;args->nodeid = nodeid;args->in_numargs = 1;args->in_args[0].size = name->len + 1;args->in_args[0].value = name->name;args->out_numargs = 1;args->out_args[0].size = sizeof(struct fuse_entry_out);args->out_args[0].value = outarg;// fuse_entry_out.attr includes all of inode attributes, such as ino/size/blocks/atime/mtime/ctime/nlink/mode/uid/gid ...---err = fuse_simple_request(fm, &args);...*inode = fuse_iget(sb, outarg->nodeid, outarg->generation,&outarg->attr, entry_attr_timeout(outarg),attr_version);
---fuse_simple_request()
---if (args->force) {atomic_inc(&fc->num_waiting);req = fuse_request_alloc(fm, GFP_KERNEL | __GFP_NOFAIL);...__set_bit(FR_WAITING, &req->flags);__set_bit(FR_FORCE, &req->flags);} else {req = fuse_get_req(fm, false);...}...__fuse_request_send(req);...fuse_put_request(req);
---__fuse_request_send()-> spin_lock(&fiq->lock);-> queue_request_and_unlock()---list_add_tail(&req->list, &fiq->pending);fiq->ops->wake_pending_and_unlock(fiq);----> request_wait_answer()---if (!fc->no_interrupt) {/* Any signal may interrupt this */err = wait_event_interruptible(req->waitq,test_bit(FR_FINISHED, &req->flags));...}if (!test_bit(FR_FORCE, &req->flags)) {/* Only fatal signals may interrupt this */err = wait_event_killable(req->waitq,test_bit(FR_FINISHED, &req->flags));...}/** Either request is already in userspace, or it was forced.* Wait it out.*/wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));---
以上代码中列举了两个常见的文件系统操作,readpage和lookup,它们都是同步的,所以,需要request_wait_answer()。
write page的处理代码如下:
fuse_writepage_locked()
---tmp_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);...fuse_write_args_fill(&wpa->ia, wpa->ia.ff, page_offset(page), 0);copy_highpage(tmp_page, page);wpa->ia.write.in.write_flags |= FUSE_WRITE_CACHE;wpa->next = NULL;ap->args.in_pages = true;ap->num_pages = 1;ap->pages[0] = tmp_page;ap->descs[0].offset = 0;ap->descs[0].length = PAGE_SIZE;ap->args.end = fuse_writepage_end;wpa->inode = inode;inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);inc_node_page_state(tmp_page, NR_WRITEBACK_TEMP);spin_lock(&fi->lock);tree_insert(&fi->writepages, wpa);list_add_tail(&wpa->queue_entry, &fi->queued_writes);fuse_flush_writepages(inode);spin_unlock(&fi->lock);end_page_writeback(page);
---fuse_writepages()
---err = write_cache_pages(mapping, wbc, fuse_writepages_fill, &data);if (data.wpa) {WARN_ON(!data.wpa->ia.ap.num_pages);fuse_writepages_send(&data);}
---fuse_writepages_send()
---spin_lock(&fi->lock);list_add_tail(&wpa->queue_entry, &fi->queued_writes);fuse_flush_writepages(inode);spin_unlock(&fi->lock);for (i = 0; i < num_pages; i++)end_page_writeback(data->orig_pages[i]);
---fuse_flush_writepages()-> fuse_send_writepage()-> fuse_simple_background()-> fuse_request_queue_background()---if (likely(fc->connected)) {fc->num_background++;if (fc->num_background == fc->max_background)fc->blocked = 1;if (fc->num_background == fc->congestion_threshold && fm->sb) {set_bdi_congested(fm->sb->s_bdi, BLK_RW_SYNC);set_bdi_congested(fm->sb->s_bdi, BLK_RW_ASYNC);}list_add_tail(&req->list, &fc->bg_queue);flush_bg_queue(fc);queued = true;}---fuse_send_writepage()
---fi->writectr++;
---fuse_writepage_end()
---fi->writectr--;fuse_writepage_finish(fm, wpa);---for (i = 0; i < ap->num_pages; i++) {dec_wb_stat(&bdi->wb, WB_WRITEBACK);dec_node_page_state(ap->pages[i], NR_WRITEBACK_TEMP);wb_writeout_inc(&bdi->wb);}wake_up(&fi->page_waitq);---
---fuse_fsync()-> file_write_and_wait_range()-> fuse_sync_writes(inode)-> fuse_set_nowrite()---spin_lock(&fi->lock);BUG_ON(fi->writectr < 0);fi->writectr += FUSE_NOWRITE;spin_unlock(&fi->lock);wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);---
---
write page中最大的不同在于:fuse申请了一个tmp_page,然后使用这个tmp_page去承载数据,并发给对端;发出去之后,立刻就调用了end_page_writeback(),此时page cache中的数据还没有真正落盘;数据落盘的语义最终是通过fsync保证的。这样就避免了用户态fuse daemon故障导致系统dirty pages无人处理。
对与这个设计,fuse的commit的comment中做了解释:
Fuse page writeback design--------------------------fuse_writepage() allocates a new temporary page with GFP_NOFS|__GFP_HIGHMEM.It copies the contents of the original page, and queues a WRITE request to theuserspace filesystem using this temp page.The writeback is finished instantly from the MM's point of view: the page isremoved from the radix trees, and the PageDirty and PageWriteback flags arecleared.For the duration of the actual write, the NR_WRITEBACK_TEMP counter isincremented. The per-bdi writeback count is not decremented until the actualwrite completes.On dirtying the page, fuse waits for a previous write to finish beforeproceeding. This makes sure, there can only be one temporary page used at atime for one cached page.This approach is wasteful in both memory and CPU bandwidth, so why is this^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^complication needed?The basic problem is that there can be no guarantee about the time in which^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^the userspace filesystem will complete a write. It may be buggy or even^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^malicious, and fail to complete WRITE requests. We don't want unrelated partsof the system to grind to a halt in such cases.Also a filesystem may need additional resources (particularly memory) tocomplete a WRITE request. There's a great danger of a deadlock if thatallocation may wait for the writepage to finish.
相关文章:
轻量级虚拟化技术草稿
Support Tech ST.1 virtiofs ST.1.1 fuse framework 引用wiki中关于fuse的定义: Filesystem in Userspace (FUSE) is a software interface for Unix and Unix-like computer operating systems that lets non-privileged users create their own file systems w…...
bootz启动 Linux内核过程中涉及的 do_bootm_states 函数
一. bootz启动Linux uboot 启动Linux内核使用bootz命令。当然还有其它的启动命令,例如,bootm命令等等。 本文只分析 bootz命令启动 Linux内核的过程中涉及的几个重要函数。具体分析 do_bootm_states 函数执行过程。 本文继上一篇文章,地址…...
springcloud学习笔记(3)-服务管理组件Nacos
Nacos简介 在2中学习了服务治理中心eureka,而本节的nacos来自springcloud alibaba。 Nacos也是一个服务注册和管理的组件。 Nacos 支持几乎所有主流类型的“服务”的发现、配置和管理 官方文档 快速开始 | Spring Cloud Alibaba (aliyun.com) 概述 | Spring C…...
Insight h2database 更新、读写锁以及事务原理
文章基于 RegularTable 来分析和拆解更新操作。 锁模型比较简单,方便了解更新的整个流程。并发读写的实现在 MVStore 存储引擎中分析。 主要关注数据更新的实现、事务的提交和回滚。 相关概念 讨论更新操作,就需要涉及到事务隔离级别以及事务的概念。 也…...
skywalking动态配置[集成nacos/apollo/consul]
说明:以下配置仅关于的阈值规则的动态配置,其他参数也可以进行配置。 1,skywalking动态配置集成nacos 编辑application.yml nacos配置参数如下: nacos:# Nacos Server HostserverAddr: 10.10.5.145# Nacos Server Portport: 8848# Nacos Configuration Groupgroup: skywal…...
UniApp创建项目HelloWorld
浏览器预览效果镇楼 普通项目创建 点击创建完成后,就如下所示 确实和微信小程序开发差不多。只是稍微换了一个名字的概念了,这个就是开发嘛,不要过于纠结概念性东西。开发开发,开了就知道怎么发了? 或许是 反正write就…...
Qt/C++原创推流工具/支持多种流媒体服务/ZLMediaKit/srs/mediamtx等
一、前言 1.1 功能特点 支持各种本地视频文件和网络视频文件。支持各种网络视频流,网络摄像头,协议包括rtsp、rtmp、http。支持将本地摄像头设备推流,可指定分辨率和帧率等。支持将本地桌面推流,可指定屏幕区域和帧率等。自动启…...
学习黑马程序员JavaScript总结
今天注意学习了数据类型、运算符、常量、数组,这些内容接受的还是比较快的,因为前面学过C语言还有Python,比较不同的地方就是未定义类型undefined,这个类型是在只声明了变量但未赋值,而unll空类型它是赋了值但该值是空…...
浅谈高速公路服务区分布式光伏并网发电
前言 今年的国家经济工作会议提出:将“做好碳达峰、碳中和工作”作为 2021年的主要任务之一,而我国高速公路里程 15.5万公里,对能源的需求与日俱增,碳排放量增速明显。 为了实现采用减少碳排放量,采用清洁能源替代的…...
MATLAB算法实战应用案例精讲-【图像处理】机器视觉(番外篇)
目录 前言 算法原理 机器视觉检测系统工作原理 机器视觉光源分类...
塑胶材料检测对激光焊机的作用
塑胶材料的激光焊接已经普遍用于各种零配件,而塑料的透光率是焊接工艺质量的一个重要指标。针对这类塑胶材料推出这款专门检测塑胶材料近红外透光率特性的透光率检测仪,对注塑件的透光率进行全画面扫描。 全球工业致力于贯彻绿色环保、节能减排发展理念&…...
将Eureka服务注册到Eureka中心
1、在微服务的pom.xml引入依赖文件中 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>2、在微服务的application.yml配置文件中加上…...
将网站域名访问从http升级到https(腾讯云/阿里云)
文章目录 1.前提说明2.服务器安装 docker 与 nginx2.1 安装 docker🍀 基于 centos 的安装🍀 基于ubuntu 2.2 配置阿里云国内加速器🍀 找到相应页面🍀 创建 docker 目录🍀 创建 daemon.json 文件🍀 重新加载…...
QT通过TCP协议发送结构体数据
QT通过TCP协议发送结构体数据 Chapter1 QT通过TCP协议发送结构体数据前言1. memcpy方式1.1 发送整个结构体1.2 发送部分数据 2. QDataStream2.1 符号<<2.2 wrieteRawData 总结 Chapter2 qt中操作json,读取json,写入json,转换json一、说…...
C++标准库之numeric
文章目录 一. numeric库介绍二.详解accumulate1. 计算数组中所有元素的和2. 计算数组中所有元素的乘积3. 计算数组中每个元素乘以3之后的和4.计算数组中每个元素减去3之后的和5.计算班级内学生的平均分6.拼接字符串 adjacent_differenceinner_productpartial_sumiota 三. 参考 …...
第六章:最新版零基础学习 PYTHON 教程—Python 正则表达式(第二节 - Python 中的正则表达式与示例套装)
正则表达式 (RegEx)是一种特殊的字符序列,它使用搜索模式来查找字符串或字符串集。它可以通过将文本与特定模式进行匹配来检测文本是否存在,并且还可以将模式拆分为一个或多个子模式。Python 提供了一个re模块,支持在 Python 中使用正则表达式。它的主要功能是提供搜索,其中…...
【Python】WebUI自动化—Selenium的下载和安装、基本用法、项目实战(16)
文章目录 一.介绍二.下载安装selenium三.安装浏览器驱动四.QuickStart—自动访问百度五.Selenium基本用法1.定位节点1.1.单个元素定位1.2.多个元素定位 2.控制浏览器2.1.设置浏览器窗口大小、位置2.2.浏览器前进、刷新、后退、关闭3.3.等待3.4.Frame3.5.多窗口3.6.元素定位不到…...
c++视觉处理---图像重映射
图像重映射:cv::remap cv::remap 是OpenCV中的一个函数,用于执行图像重映射,允许您通过重新映射像素的位置来变换图像。这个函数非常有用,可以用于各种图像处理任务,如校正畸变、透视变换、几何变换等。 下面是 cv::…...
基于YOLO算法的单目相机2D测量(工件尺寸和物体尺寸)
1.简介 1.1 2D测量技术 基于单目相机的2D测量技术在许多领域中具有重要的背景和意义。 工业制造:在工业制造过程中,精确测量是确保产品质量和一致性的关键。基于单目相机的2D测量技术可以用于检测和测量零件尺寸、位置、形状等参数,进而实…...
Insight h2database 执行计划评估以及 Selectivity
生成执行计划是任何一个数据库不可缺少的过程。通过本文看执行计划生成原理。 最优的执行计划就是寻找最小计算成本的过程。 本文侧重 BTree 索引的成本计算的实现 以及 基础概念选择度的分析。 寻找最优执行计划 找到最佳的索引,实现最少的遍历,得到想要…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
