fuse整理

【linux内核】 libfuse 源码分析 Fuse是filesystem in user space,一个用户空间的文件系统框架,fuse包含包含一个内核模块和一个用户空间守护进程 FUSE分为三大模块: FUSE内核模块(内核态) LibFUSE模块(用户态) 用户程序模块(用户态) LibFUSE 实现文件系统主要框架、对实现的文件系统操作进行封装、mount管理、通过设备/dev/fuse与内核模... 阅读详情
 FUSE 的工作原理如图所示。假设基于 FUSE 的用户态文件系统 hello 挂载在 /tmp/fuse 目录下。当应用层程序要访问 /tmp/fuse 下的文件时,通过 glibc 中的函数进行系统调用,处理这些系统调用的 VFS 中的函数会调用 FUSE 在内核中的文件系统;内核中的 FUSE 文件系统将用户的请求,发送给用户态文件系统 hello ;用户态文件系统收到请求后,进行处理,将结果返回给内核中的 FUSE 文件系统;最后,内核中的 FUSE 文件系统将数据返回给用户态程序。

FUSE整理 - bpingchang - bpingchang的博客

其中,用户态文件系统通过fuse提供的函数库libfuse,向内核中的fuse文件系统注册自己的文件处理函数。

我们以一个简单的基于FUSE的用户态文件系统hello为例,来分析FUSE的内部实现。 用 户态文件系统hello的源码hello.c的部分如下所示:

static struct fuse_operations hello_oper = {

.getattr = hello_getattr,

.readdir = hello_readdir,

.open      = hello_open,

.read       = hello_read,

}

int main(int argc, char *argv[])

{

     return  fuse_main(argc, argv, &hello_oper, NULL);

}

fuse_operations是libfuse提供给用户层文件系统的机 构,供用户定义自己的文件操作函数;fuse_main()是libfuse提供给用户文件系统最重要的接口,通过这个函数,用户层文件系统可以将自己定义的fuse_operation注册为文件系 统的处理函数,并挂载该文件系统。

1、内核FUSE文件系统和用户态文件系统的通信

在加载fuse模块的过程中,要在内核中注册fuse文件系统,并生成fuse设备/dev/fuse。

/dev/fuse是内核里的fuse文件系统和用户态文件系统的通信媒 介。用户态文件系统通过读取/dev/fuse的内容,获取内核中fuse文件系统发来的请求;而内核中的fuse文件系统,则把请求写入/dev/fuse,等待用户态文件系统处理。

在用户态文件系统和内核中的fuse模块通过/dev/fuse进行通信时,不可避免的会有内存拷贝。fuse中没有使用传统的copy_from_user/copy_to_user,而是用get_user_pages和memcpy来代替。

2、FUSE用户态文件系统的挂载过程

挂载用户态文件系统,只需运行其生成的程序。在hello中,运行编译hello.c生成的hello即可。fuse_main将完成一切的注册和挂载过程,其中主要分为两个步骤:

2.1          在内核中挂载新的用户态文件系统

1.         打开设备文件"/dev/fuse", 获得文件描述符fd

2.         挂载FUSE文件系统(内核里的 fuse文件系统),将fd作为参数传给内核里的挂载函数

3.         内核中的fuse文件系统在初始化 super_block的过程中,将创建一个新的fuse_conn,它就是内核fuse和用户态文件系统通信的工具

4.         将该fuse_conn设置为在用户 态打开的/dev/fuse的私有数据(file->private);同时,该文件系统的super_block的s_fs_info也指向该 fuse_conn

2.2 注册用户态文件系统的处理函数,并创建进程处理该文件系统的请求

1.         创建一个新的fuse_chan,用 来与内核中的fuse通信。它的处理函数是 fuse_chan_ops:

 

.receive = fuse_kern_chan_receive, 等待并从4.2.1-1步骤中打开的文件中读取请求

.send = fuse_kern_chan_send,            将用户态文件系统处理的结果发送给内 核fuse

.destroy = fuse_kern_chan_destroy, 释放fuse_chan

 

2.         创建一个fuse_session,并 注册用户态文件系统的处理函数,用来等待并处理该文件系统的请求

3.         等待用户态文件系统的请求,并处理它 们

 

3、多个基于FUSE的用户态文件系统的共存

在挂载的过程中,每个用户态文件系统 都会创建一个自己的fuse_conn,并将该fuse_conn设为自己打开的/dev/fuse的私有数据(file_private);同时,该文 件系统在内核里的super_block,也将该fuse_conn设置为s_fs_info。在以后的过程中,用户态的文件系统处理线程都是从自己的 fuse_conn上读取请求;内核中的fuse文件系统,也只把请求发给s_fs_info指向的fuse_conn。通过这种机制,FUSE就能支持 多个用户态文件系统同时运行,且互不干扰。

FUSE是一个用户空间中的文件系统框架。它包含2个部分,FUSE内核模块和用户空间接口模块。在用户空间的执行文件系统能够大幅提高生长率,简化了为操作系统提供新的文件系统的工作量,适合于各种虚拟文件系 统和网络文件系统。

FUSE 作为用户态文件系统与内核交互的桥梁,拥有着2个模块。其一是与用户态文件系统直接交互模块,如上图中的libfuse接口。其二是内核中挂载到VFS上的FUSE内核模块。

FUSE信息处理流程:

当用户发起一个请求ls –l /tmp/fuse 时,操作系统调用内核函数接口glibc将该请求发送到内核态VFS;VFS根据请求判断出需要调用的文件系统(FUSE已经挂到VFS的文件系统列表上)并将此请求发送到FUSE内核模块;由内核模块再将此请求发 送到特殊文件/dev/fuse的请求队列中;而用户态的libfuse则不停的循环请求/dev/fuse文件中的请求队列,如获得请求则解析该请求,并发送给挂在其上的用户态文件系统,由它来执行请求。

在用户态文件系统执行完该请求后,按照逆方向返回执行结果给用户。

4、用户态文件系统的挂载过程

1)用户态文件系统启动的第一部就是将自身注册到VFS上去。首先调用./lib/helper.c文件中函数fuse_mount(const char *mountpoint, struct fuse_args *args), 参数包括挂载点mountpoint等,在挂载过程中只需要输入挂载点路径即可。

2)通过调用./lib/helper.c文件中函数fuse_mount_compat25(const char *mountpoint, struct fuse_args *args) 再调用./lib/mount.c文件中的fuse_kern_mount(const char *mountpoint, struct fuse_args *args),接着调用static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, const char *mnt_opts)函数,其中通过语句 fd = open(devname, O_RDWR);来检测文件/dev/fuse是否能够正常打开。如果正常,则直接调用系统函数res = mount(source, mnt, type, mo->flags, mo->kernel_opts);将其挂载到VFS上。

    3)创建并初始化一个跟/dev/fuse交互的通道结构体

struct fuse_chan {

struct fuse_chan_ops op; //其中操作包括receive, send, distroy三中方法。

struct fuse_session *se;  //通道的会话

int fd;      //文件/dev/fuse 的fd号

size_t bufsize;     //pagesize() + 0x1000

void *data;

int compat;

};

//通道操作的动作绑定结构体

struct fuse_chan_ops op = {

           .receive = fuse_kern_chan_receive,

           .send = fuse_kern_chan_send,

           .destroy = fuse_kern_chan_destroy,

    };

最后将建立的通道fuse_chan返回给用户文件系统的main()函数。

5 、 FUSE 用户态模块的业务逻辑结构

1)        在用户态文件系统的main()函数中调用文件fuse_loop.c中的函数void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch),将通道地址赋值给该会话结构体struct fuse_session se, 然后通过调用同一文件中的函数int fuse_session_loop(struct fuse_session *se)来做信息的接收与发送工作。

struct fuse_session {

       struct fuse_session_ops op;  //会话的操作

       void *data;

       volatile int exited;

       struct fuse_chan *ch;

};

2)  在函数int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size)中调用结构体struct fuse_chan 中绑定的操作函数static int fuse_kern_chan_receive(struct fuse_chan **chp, char *buf, size_t size)直接调用read()系统函数res = read(fuse_chan_fd(ch), buf, size); 来从/dev/fuse中读取消息。

//通道操作 的动作绑定结构体

struct fuse_chan_ops op = {

              .receive = fuse_kern_chan_receive,

              .send = fuse_kern_chan_send,

              .destroy = fuse_kern_chan_destroy,

};

3)   在函数void fuse_session_process(struct fuse_session *se, const char *buf, size_t len, struct fuse_chan *ch)中调用已绑定的se->op.process()函 数转向文件./lib/fuse_lowlevel.c中被绑定函数static void fuse_ll_process(void *data, const char *buf, size_t len, struct fuse_chan *ch)。

struct fuse_session_ops sop = {

              .process = fuse_ll_process,

              .destroy = fuse_ll_destroy,

};

在这个函数处理过程中,首先要申明一个请求结构体指针struct fuse_req *req, 然 后通过在read(fuse_chan_fd(ch), buf, size); 函数执行中读取的数据buf,且将其强制转化为fuse_in_header类型(struct fuse_in_header *in = (struct fuse_in_header *) buf;),并初始化请求结构体req。\

struct fuse_req {

}

通过解析出in->opcode的数据和用户态文 件系统定义的已绑定的接口函数相比较,得到相应的处理函数,最后执行这个函数完成请求。示例如下:如in->opcode =FUSE_MKDIR, 则通过结构体

6 、FUSE 内核模块的业务逻辑结构

FUSE 作为用户态文件系统与内核交互的桥梁,拥有着2个模块。其一是与用户态文件系统直接交互模块,如上图中的libfuse接口。其二是内核中挂载到VFS上的FUSE内核模块。

FUSE信息处理流程:

当用户发起一个请求ls –l /tmp/fuse 时,操作系统调用内核函数接口glibc将该请求发送到内核态VFS;VFS根据请求判断出需要调用的文件系统(FUSE已经挂到VFS的文件系统列表上)并将此请求发送到FUSE内核模块;由内核模块再将此请求发 送到特殊文件/dev/fuse的请求队列中;而用户态的libfuse则不停的循环请求/dev/fuse文件中的请求队列,如获得请求则解析该请求,并发送给挂在其上的用户态文件系统,由它来执行请求。

在用户态文件系统执行完该请求后,按照逆方向返回执行结果给用户。

6.1        用户态文件系统的挂载过程

1)        用户态文件系统启动的第一部就是将自身注册 到VFS上去。首 先调用./lib/helper.c文件中函数fuse_mount(const char *mountpoint, struct fuse_args *args), 参数包括挂载点mountpoint等,在挂载过程中只需 要输入挂载点路径即可。

2)        通过调用./lib/helper.c文件中函数fuse_mount_compat25(const char *mountpoint, struct fuse_args *args)再调用./lib/mount.c文件中的fuse_kern_mount(const char *mountpoint, struct fuse_args *args),接着调用static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, const char *mnt_opts)函数,其中通过语句 fd = open(devname, O_RDWR);来检测文件/dev/fuse是否能够正常打开。如果正常,则直接调用系统函数res = mount(source, mnt, type, mo->flags, mo->kernel_opts);将其挂载到VFS上。

3)        创建并初始化一个跟/dev/fuse交互的通道结构体

struct fuse_chan {

struct fuse_chan_ops op; //其中操作包括receive, send, distroy三中方法。

struct fuse_session *se;  //通道的会话

int fd;                //文件/dev/fuse 的fd号

size_t bufsize;         //pagesize() + 0x1000

void *data;

int compat;

};

//通道操作的动作绑定结构体

struct fuse_chan_ops op = {

           .receive = fuse_kern_chan_receive,

           .send = fuse_kern_chan_send,

           .destroy = fuse_kern_chan_destroy,

    };

最后将建立的通道fuse_chan返回给用户文件系统的main()函数。

6.2        FUSE用户态模块的业务逻辑结构

1)        在用户态文件系统的main()函数中调用文件fuse_loop.c中的函数void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch),将通道地址赋值给该会话结构体struct fuse_session se, 然后通过调用同一文件中的函数int fuse_session_loop(struct fuse_session *se)来做信息的接收与发送工作。

struct fuse_session {

       struct fuse_session_ops op;  //会话的操作

       void *data;

       volatile int exited;

       struct fuse_chan *ch;

};

接下来在while()循环中函数int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size)用于消息的接收函数,如果接收到消息,则调用fuse_session.c文件中void fuse_session_process(struct fuse_session *se, const char *buf, size_t len,处理函数进行处理,其中调用会话控制结构体中的process函数指针所指向的函数来做实 际的处理(这个函数是由用户态文件系统提供的文件操作函数接口)。

struct fuse_session_ops {

void (*process) (void *data, const char *buf, size_t len,  struct fuse_chan *ch);

void (*exit) (void *data, int val);

int (*exited) (void *data);

void (*destroy) (void *data);

};

1)        在函数int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size)中调用结构体struct fuse_chan中绑定的 操作函数static int fuse_kern_chan_receive(struct fuse_chan **chp, char *buf, size_t size)直接调用read()系统函数res = read(fuse_chan_fd(ch), buf, size); 来从/dev/fuse中读取消息。

//通道操作的动作绑定结构体

struct fuse_chan_ops op = {

              .receive = fuse_kern_chan_receive,

              .send = fuse_kern_chan_send,

              .destroy = fuse_kern_chan_destroy,

};

1)        在函数void fuse_session_process(struct fuse_session *se, const char *buf, size_t len, struct fuse_chan *ch)中 调用已绑定的se->op.process()函数转向文件./lib/fuse_lowlevel.c中被绑定函数static void fuse_ll_process(void *data, const char *buf, size_t len, struct fuse_chan *ch)。

struct fuse_session_ops sop = {

              .process = fuse_ll_process,

              .destroy = fuse_ll_destroy,

};

在这个函数处理过程中,首先要申明一个请求结构体指针struct fuse_req *req, 然后通过在read(fuse_chan_fd(ch), buf, size); 函数执行中读取的数据buf,且将其强制转化为fuse_in_header类型(struct fuse_in_header *in = (struct fuse_in_header *) buf;),并初 始化请求结构体req。\

struct fuse_req {}

通过解析出in->opcode的数据和用户态文件系统定义的已绑定的接口函数相比较,得到相应的处理函数,最后执行这个函数完成 请求。示例如下:如in->opcode = FUSE_MKDIR, 则通过结构体

static struct {

       void (*func)(fuse_req_t, fuse_ino_t, const void *);

       const char *name;

}中已经初始化绑定的[FUSE_MKDIR] = { do_mkdir, "MKDIR" },一行数据找到函数static void do_mkdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)最后来实现请求。

1)        当需要返回数据时,需要调用文件./lib/fuse_lowlevel.c中 的函数static int send_reply(fuse_req_t req, int error, const void *arg, size_t argsize),之后经过一系列的解析和变换,最后调用 文件./fuse_kern_chan.c中的static int fuse_kern_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count)函数,它再调用系 统函数writev()(ssize_t res = writev(fuse_chan_fd(ch), iov, count);)来将返回数据写入到/dev/fuse中去。

 

7、FUSE内核模块的业务逻辑结构

1)        说明:(因VFS与FUSE内核模块的交互部分是由Linux内核编译生成的,暂时无法打印调试,因此对这部分代码的分析还不够确切,在接下来的工作中将会编译FUSE内核部分代码,并再次详细分析其运行过程)。

2)        当用户发出请求,若请求为:”rm /mnt/fuse/file” 时, 操作系统直接调用VFS函数sys_unlink()。

1)        通过VFS的转向,调用已注册的“FUSE文件系统”(FUSE内核模块)的函数fuse_unlink()。

2)        FUSE内核模块将接收到的请求保存到结构体struct fuse_conn fc的fc->unused_list中,通 过函数request_send()函数将其写入fc->pending,同时使用函数fuse_dev_writev()将此请求写到特殊文件/dev/fuse中。

8、内核中/dev/fuse读写详细流程

1)        前提介绍

当VFS要下发命令到FUSE或者从FUSE获取恢复时,首先找到与FUSE绑定的接口函数结构体(在dev.c中)。

struct file_operations fuse_dev_operations = {}

1)        读取/dev/fuse中的请求

在内核中要读取/dev/fuse中的请求数据时,最终要调用文件dev.c中的函数static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, unsigned long nr_segs, loff_t *off), 此函数首先通过传入的参数file来初始化一个struct fuse_conn *fc结构体。然后调用请求等待函数static void request_wait(struct fuse_conn *fc), 先申明并初始化一个进程等待列表DECLARE_WAITQUEUE(wait, current); 

将wait加入到fc->waitq等待队列中,当有请求发到fuse文件系统时(通过request_send),这个等待队列上的进程会被唤醒,某一个进程会被赋予CPU使用权:add_wait_queue_exclusive(&fc->waitq, &wait),接着不断的检查fc的pending队列及interrupts队列,看是否有请求,没有请求会一直while循环。

while (fc->connected && !request_pending(fc)) {}

如果有请求,则break出来将当前进程状态设置为TASK_RUNNING状态,set_current_state(TASK_RUNNING);并将其从等待队列中移出,remove_wait_queue(&fc->waitq, &wait) 。 

在fc->pending列表为非空时,证明已经有数据到达,那么作一些相应的状态修改,初始化等工作后,判断这个请求是否 合法,如果是合法请求,这从fc->pending列表中移除并拷贝其请求数据到用户空间的缓冲区。如果该请求是不需要回复的、意外终止、出现错误或者 正常结束的情况下调用函数static void request_end(struct fuse_conn *fc, struct fuse_req *req)来作一些处理后结束本次请求读取过程。

1)        将请求发送到/dev/fuse中

首先申明一个结构体fc, struct fuse_conn *fc = fuse_get_conn(file); 然后检查当前的设备状态,如 果没问题则初始化一个拷贝状态。

static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc,

然后在当前的处理列表中查找写缓冲区的请求。如果找到,然后从列表中删除它并复制缓冲区的其余部 分。完成该请求通过调用函数static void request_end(struct fuse_conn *fc, struct fuse_req *req)。

9、总结

FUSE内核模块主要工作就是进行队列的管 理,对fuse设 备的读(写)其实就是从相应的队列移除(添加)请求(或响应),request_send将请求加入pending队列,唤醒fuse守护程序,并在req的waitq上等待请求结果,守护程序通过fuse_dev_readv从pending队列中移除请求并处理,处理完成后,守护程序唤醒req的waitq上的进程,该进程读取结果,并返回 给用户。

总的来说,一个请求从发起到完成会经过4步:

1)        fuse守护程序在fc的waitq上等待请求;

2)        用户的请求唤醒fc的waitq,从该waitq上移除一个请求进行处理,并在req的waitq上等待请求结果;

3)        fuse守护程序被唤醒,读取请求,处理请求,返回结果,唤醒对应req上的waitq队列。

4)        请求被唤醒,读取fuse守护程序返回的结果,返回给用户。

【Linux】分析Fuse中libfuse源码 剖析libfuse库基本工作原理 阅读详情

相关推荐

深入解析libfuse:从用户态到内核态的FUSE通信机制

本文深入解析了libfuse框架如何实现用户态文件系统与Linux内核的通信机制。通过剖析/dev/fuse设备文件、fuse_chan通信通道及fuse_session会话管理等核心数据结构,详细阐述了FUSE请求从内核打包、用户态解析回调到响应返回的完整生命周期,并结合源码分析揭示了其同步与异步处理模型,是掌握FUSE技术原理与开发实践的关键指南。

m3n5b7v8c9x的博客 533

探索未来文件系统:libfuse 深入解析与应用

探索未来文件系统:libfuse 深入解析与应用 libfuseThe reference implementation of the Linux FUSE (Filesystem in Userspace) interface项目地址:https://gitcode.com/gh_mirrors/li/libfuse 项目介绍 libfuse 是一个强大的开源库,它允许在用户空间实现自定义的文...

gitblog_00053的博客 826

libfuse:Linux FUSE(用户空间中的文件系统)接口的参考实现

libfuse 关于 FUSE(用户空间中的文件系统)是用户空间程序将文件系统导出到Linux内核的接口。 FUSE项目包含两个组件:保险丝内核模块(在常规内核存储库中维护)和libfuse用户空间库(在此存储库中维护)。 libfuse提供了与FUSE内核模块进行通信的参考实现。 FUSE文件系统通常实现为与libfuse链接的独立应用程序。 libfuse提供了以下功能:挂载文件系统,卸载文件系统,从内核读取请求以及将响应发送回。 libfuse提供了两个API:“高级”同步API和“低级”异步API。 在这两种情况下,来自内核的传入请求都使用回调传递给主程序。 使用高级API时,回调可以使用文件名和路径而不是inode来工作,并且在回调函数返回时,请求的处理完成。 使用低级API时,回调函数必须与inode一起使用,并且必须使用一组单独的API函数显式发送响应。 发展状况 libf

FUSE文件系统

Fuse(filesystem in userspace),是一个用户空间的文件系统。通过fuse内核模块的支持,开发者只需要根据fuse提供的接口实现具体的文件操作就可以实现一个文件系...

内核工匠 1万+

深入解析SSD报错“READ FPDMA QUEUED”:从诊断到修复全流程

本文深入解析了SSD报错“READ FPDMA QUEUED”的含义、成因与全流程解决方案。该错误通常指示硬盘硬件或健康状态问题。文章详细介绍了如何通过系统日志定位错误、解读关键的S.M.A.R.T.健康报告(重点关注重分配扇区计数等指标),并逐步进行硬件排查(如更换SATA数据线)、软件修复与数据抢救,最终指导用户根据诊断结果做出维修或更换SSD的决策。

weixin_29233333的博客 399

STM32 Modbus-RTU从零到实战:手把手教你用HAL库实现工业通信(附完整代码)

本文详细介绍了如何使用STM32 HAL库从零开始实现Modbus-RTU从机通信。内容涵盖RS485硬件设计、CubeMX串口与定时器配置、基于空闲中断的高效数据接收、协议栈状态机设计、CRC16校验实现以及常用功能码处理。文章提供了完整的代码框架和调试方法,帮助开发者快速构建稳定的工业通信节点。

weixin_28278377的博客 188

fuse调用流程有待整理

fuse处理请求的整个流程如下图所示,以unlink操作为例进行说明。其中“>”表示调用,”     fuse通过fuse_session_loop(或对应多线程的方法)来启动fuse守护程序,守护程序不断的从/dev/fuse上读取请求,并处理。   代码片段1 int fuse_session_loop(struct fuse_session *se)//在fuse_mai

zhuangshu_feng'‘每天进步一点点 1282

详解STM32F407双重ADC同步采集与DMA传输的配置技巧及实战应用

本文详细解析了STM32F407双重ADC同步采集与DMA传输的配置技巧及实战应用。通过CubeMX配置、代码实现和常见问题解决方案,帮助开发者高效实现多通道数据同步采集,提升工业自动化和嵌入式系统的数据采集效率与精度。

ii567的博客 364

支持STRM刮削/媒体整理/本地挂载,NAS部署网盘聚合神器LitePan

可能很多小伙伴会把它和同类网盘聚合工具(比如说AList/OpenList)想比较,但用过之后你就会发现,LitePan很明显更偏向于我们NAS的影音用户。对于LitePan来说,网盘聚合只是它的功能之一, 而它更大的优势在于专为影音场景打造的一些列优化与自动化处理,比如说对网盘内的影视资源进行目录整理、媒体识别、STRM 输出、WebDAV 挂载等,相当于直接把网盘资源当做我们NAS本地硬盘的标准媒体库来使用的。总的来说,这个项目绝对值得拥有网盘会员的NAS用户体验~

qq_63499861的博客 563

使用STC15F104W产生PWM脉冲

最近的小项目中使用到了STC15F104W产生PWM脉冲

yeats1989的专栏 1万+

【小白深度教程 1.3】使用 BP-Net 深度补全网络,进行 KITTI 稠密点云和图像融合(Depth Completion 实战)

在上一节中,我们展示了如何将从激光雷达获取的稀疏点云(深度)映射到图像。因此这篇论文我们尝试使用 Depth Completion(深度补全)技术,来将稀释的点云深度,补全为稠密深度。

2401_87064292的博客 1199

2024年最新【初学数据结构】顺序表_fuse,2024年最新吐血整理

大家好呀!👋这个是付青云同学的博客,是一名大一在校生哦!😁😁目前一直在学习C语言。🐸写博客是为了来记录我的学习过程,同时也希望通过博客能够帮助到需要帮助的人。如果我的博客可以帮助到你,不妨给我一个关注哦😁。

2401_84976678的博客 292

SAP生产订单技术性完成(TECO)操作指南与实战应用

生产订单技术关闭操作指南主要包括单笔和批量关闭两种方式,通过CO02/COHV事务码完成。

m0_47402127的博客 1932

android存储学习大纲

3、mount、df、dd、du、ls、touch、chmod、chown、chgrp、lsof、vmstat、iozone、blktrace、fio、vdc、sqlite等工具使用。9、存储安全实现和调优:分区加密与dm-crypt、 文件级加密、镜像验证与dm-verity 、DAC与sandbox、MAC与selinux。1、文件系统(VFS、内存文件系统、FAT,EXT4、F2FS、OVERLAY,EROFS)移植与参数调优。5、FUSE与直通模式的配置、移植和功能扩展;

yangzex的专栏 722

RSL-RL:开源人形机器人强化学习控制研究库

摘要:RSL-RL是一款专为机器人领域设计的开源强化学习库,其核心特点是紧凑性、可修改性和高性能。该库聚焦PPO和BC两大主流算法,并整合了对称性增强、好奇心驱动等机器人专用技术。通过纯GPU训练优化,RSL-RL在大型仿真中展现出卓越的吞吐性能,已成功应用于腿足运动控制、全身协调等多个机器人研究场景。其轻量级架构包含运行器、算法和网络三个可独立修改的组件,支持TensorBoard等主流日志工具。该框架特别适合需要快速原型开发的机器人研究者,但不适用于通用机器学习基准测试。开源地址:https://git

2506_90492529的博客 1675

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

解决 linux在 VMware中的问题 汇总 (***)

在虚拟机机中安装完Ubuntu18.04之后界面显示的特别小,默认的好像是800*600分辨率,看着不舒服。解决Ubuntu在VMware中不能全屏的问题。解决Ubuntu在VMware中不能全屏的问题。不需要安装 VMware tools。解决虚拟机与宿主机的文件共享问题。解决虚拟机与宿主机的文件共享问题。解决虚拟机与宿主机的文件共享问题。终端:带有双向的复制、粘贴功能。

ken2232的博客 212

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

ROS使用过程中的常见问题与解决办法

ROS使用过程中的常见问题与解决办法 我们在使用ROS的过程中,或多或少的会碰到一些问题,这儿我会将我经常碰到的问题整理下来,并且会分析原因, 最终给出解决办法,后续会不断更新。 一、rosrun或者roslaunch用tab补全问题 1)问题描述:执行过source之后,在使用ROS的过程中,当我们用rosrun或roslaunch启动节点的过程中,利用Tab键补

BYR_Lu的博客 6674

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

python torch exp_Python torch.diag方法代码示例

本文整理汇总了Python中torch.diag方法的典型用法代码示例。如果您正苦于以下问题:Python torch.diag方法的具体用法?Python torch.diag怎么用?Python torch.diag使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在模块torch的用法示例。在下文中一共展示了torch.diag方法的29个代码示...

weixin_39831493的博客 1393

Linux指令收录

压缩(xz压缩率最高,但最慢)图形界面:Ctrl + H。3.共享文件夹无法共享。

Hat_man_的博客 124

C/C++第三方类库

1、libconfig   (官网:http://www.hyperrealm.com/libconfig/)

地中海蒲公英 1218

FUSE协议解析

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34372728的博客 4028

linux fuse安装脚本,Linux FUSE(用户态文件系统)的使用:用libfuse创建FUSE文件系统...

说明FUSE 是Linux Kernel的特性之一:一个用户态文件系统框架,a userspace filesystem framework。 形象的说就是可以在用户态运行一个程序,这个程序暴露出一个FUSE文件系统,对这个文件系统进行的读写操作都会被转给用户态的程序处理。FUSE由内核模块 fuse.ko 和用户空间的动态链接库 libfuse.* 组成,如果要开发使用fuse的用户态程序,需要...

weixin_36085931的博客 1791
上一篇: Linux 文件系统剖析
下一篇: rpm包如何制作-个人经验
乐动心情
博客等级 码龄16年 36粉丝 10原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值