
存储分布式文件系统对象存储云原生【免费下载链接】cubefscloud-native distributed storage项目地址https://gitcode.com/gh_mirrors/cu/cubefs点击查看免费下载本指南基于 CubeFS 官方开发文档系统讲解 libsdk用户态客户端库的定位、构建方式、生命周期管理以及全部 C 语言接口的用法并结合仓库源码client/libsdk说明其底层实现原理。读完本文你将能够自行编译 libcfs.so并在自己的 C/C 或支持 C ABI 的应用程序中完成客户端创建、配置、启动以及文件/目录的增删改查、读写与加锁等全套操作。libsdk 是什么libsdk 是 CubeFS 文件存储的用户态客户端库用于应用程序与 CubeFS 分布式文件系统进行交互。它对外提供了一整套文件系统操作接口包括文件和目录的创建、读取、写入和删除等。与传统的 FUSE 内核态挂载方式不同应用程序通过 libsdk 可以直接连接到 CubeFS 存储集群不经过内核态挂载与转发。从源码结构看libsdk 的 Go 实现位于 client/libsdk/libsdk.go通过 cgo 的//export指令把 Go 函数导出为 C 可调用的符号C 头文件为 client/libsdk/libcfs.h由 cgo 生成的导出声明被 cgo 注释中的结构体定义所支撑。应用程序使用 libsdk 时需要引用两个产物libcfs.hC 接口声明头文件位于 client/libsdk/libcfs.hlibcfs.so动态链接库通过执行make libsdk编译得到。在 Makefile 中可以看到libsdk目标依赖libsdkpre二者均通过 build/build.sh 执行构建build_libsdkpre与build_libsdk实际执行CGO_ENABLED1 go build -buildmode c-shared命令将 client/libsdk/libsdk.go 编译为共享库输出路径默认为${BuildBinPath}/libcfs.so。libsdk 访问流程libsdk 的使用遵循一个固定而简单的生命周期共五步应用程序创建 client对应cfs_new_client应用程序设置 client 配置参数对应cfs_set_client应用程序启动 client对应cfs_start_client应用程序调用对应的文件处理接口对文件执行 open、read、write、close 等操作应用程序关闭 client对应cfs_close_client。该流程与 client/libsdk/libsdk.go 中的客户端管理逻辑一一对应cfs_new_client内部通过newClient()创建client结构并注册到全局clientManager的clientsmap 中cfs_start_client调用client.start()完成元数据封装meta.MetaWrapper与数据流客户端stream.ExtentClient的初始化cfs_close_client依次关闭数据流客户端、元数据封装并移除客户端。libsdk 的优点libsdk 相比内核态挂载方式具有以下特点灵活性可以使用各种编程语言和框架来开发从而提供更大的灵活性和自由度独立性在用户空间中运行相对独立于操作系统内核可以更容易地升级和调试客户端程序而无需关注操作系统的限制和依赖易扩展用户态客户端可以实现更高级的功能和协议以满足特定的应用需求高性能相比 FUSE 挂载libsdk 减少了内核态的转发有助于性能提高。从源码看这种“用户态直连”体现在 client/libsdk/libsdk.go 的start()方法中libsdk 直接通过 Master SDK 拉取卷信息loadConfFromMaster、构造元数据与数据流客户端所有 I/O 均在用户态完成不经过 VFS/FUSE 内核路径。libsdk 接口使用说明以下接口按功能分组逐一说明。所有函数签名均可在 client/libsdk/libcfs.h 中查到返回值中的statusOK为 0其余错误状态均为负数对应各 errno 取反见 client/libsdk/libsdk.go。客户端生命周期接口cfs_new_clientextern int64_t cfs_new_client();创建一个新的客户端。返回值是一个int64_t类型的值即新创建客户端的 ID。从实现看cfs_new_client内部会预先把 fd 0、1、2 置位避免与标准输入/输出/错误混淆新客户端的 ID 由atomic.AddInt64自增分配见 client/libsdk/libsdk.go。cfs_set_clientextern int cfs_set_client(int64_t id, char* key, char* val);设置客户端的配置项参数说明如下id客户端的 IDkey配置项的键val配置项的值。返回statusOK成功或statusEINVAL非法参数。配置示例cfs_set_client(client_id, volName, test); cfs_set_client(client_id, accessKey, WgkHUb03XViuRkHX); cfs_set_client(client_id, secretKey, oMQsYfGNcEdaUbbrw5D2GEp092RgNvQb); cfs_set_client(client_id, masterAddr, 172.16.1.101:17010); cfs_set_client(client_id, logDir, /home/test_sdk/log); cfs_set_client(client_id, logLevel, debug); cfs_set_client(client_id, enableSummary, true);通过 client/libsdk/libsdk.go 的cfs_set_client实现可以确认当前支持的配置键及其行为配置键取值示例说明volNametest卷Volume名称必填masterAddr172.16.1.101:17010Master 节点地址多个地址用逗号分隔followerReadtrue/false是否允许从 follower 副本读logDir/home/test_sdk/log日志输出目录空则不初始化日志logLeveldebug/info/warn/error日志级别未设置时默认WARNenableBcachetrue/false是否启用本地块缓存BlockCachereadBlockThread整数读并发线程数为 0 时默认 10writeBlockThread整数写并发线程数为 0 时默认 10accessKey字符串访问密钥用于权限校验secretKey字符串秘密密钥用于权限校验pushAddr字符串监控指标上报地址enableAudittrue/false是否开启客户端审计日志enableInnerReqtrue/false是否使用内部请求通道说明文档中出现的enableSummary对应 proto/mount_options.go 中的EnableSummary字段其配置入口属于挂载级选项libsdk 的cfs_set_client仅识别上表中的键传入未知键将返回statusEINVAL。accessKey与secretKey在cfs_start_client阶段会通过checkPermission()与 Master 返回的用户信息做一致性校验见 client/libsdk/libsdk.go两者缺失或错误会导致启动失败。cfs_start_clientextern int cfs_start_client(int64_t id);启动客户端。参数id为客户端的 ID。返回statusOK成功、statusEINVAL非法参数或statusEIOI/O 错误。启动过程client/libsdk/libsdk.go主要完成初始化日志与统计模块、初始化 buffer 池、从 Master 拉取卷与集群配置、校验权限、按需初始化审计与 BlockCache并构造MetaWrapper与ExtentClient。cfs_close_clientextern void cfs_close_client(int64_t id);关闭客户端。参数id为客户端的 ID无返回值。实现会关闭数据流客户端与元数据封装、移除客户端记录并刷新日志见 client/libsdk/libsdk.go。文件打开与关闭接口cfs_openextern int cfs_open(int64_t id, char* path, int flags, mode_t mode);打开/创建文件。参数说明idclient 的 IDpath文件的路径flags打开文件的标志如O_RDONLY、O_WRONLY、O_RDWR、O_CREAT、O_TRUNC、O_APPEND、O_DIRECT、O_SYNC等mode文件的权限模式。返回值大于 0 时表示成功返回文件描述符失败返回小于 0 的值可能的错误包括statusEINVAL非法参数、statusEACCES权限错误、statusEMFILE文件描述符已达上限、statusEIOI/O 错误。需要注意两点实现细节其一libsdk 打开文件时忽略 rwx 模式位源码注释明确说明rwx mode is ignored其二以O_CREAT打开时必须同时指定写权限O_WRONLY或O_RDWR否则返回statusEACCES见 client/libsdk/libsdk.go。cfs_closeextern void cfs_close(int64_t id, int fd);关闭文件。参数id为 client 的 IDfd为文件描述符无返回值。对于普通文件cfs_close在释放 fd 的同时会执行 flush 并关闭数据流见 client/libsdk/libsdk.go。读写接口cfs_readextern ssize_t cfs_read(int64_t id, int fd, void* buf, size_t size, off_t off);从指定的文件描述符中读取数据。参数说明idclient 的 IDfd文件描述符buf指向内存区域的指针用于存储读取的数据size要读取的数据大小off文件偏移量。返回值大于 0 表示实际读取的数据大小失败返回小于 0 的值可能的错误包括statusEINVAL、statusEACCES以只写方式打开的文件不可读、statusEBADFD错误文件描述符、statusEIO。从实现看cfs_read通过反射构造 Go slice 直接引用调用方传入的缓冲区零拷贝传递给内部读取逻辑对于热卷走ExtentClient.Read对于冷卷/BlobStore 卷走blobstore.Reader.Read见 client/libsdk/libsdk.go 与 client/libsdk/libsdk.go。cfs_writeextern ssize_t cfs_write(int64_t id, int fd, void* buf, size_t size, off_t off);向指定的文件描述符中写数据。参数说明idclient 的 IDfd文件描述符buf指向要写的数据缓冲区size缓冲区大小off偏移量。返回值大于 0 表示写入的字节数失败返回小于 0 的值可能的错误包括statusEINVAL、statusEACCES、statusEBADFD、statusENOSPC空间不足、statusEIO。实现要点client/libsdk/libsdk.go以O_DIRECT、O_SYNC、O_DSYNC打开的热卷文件写入后会自动 flush 以保证落盘以O_APPEND打开的文件以及冷卷文件会自动追加FlagsAppend | FlagsSyncWrite标志热卷写入会经过配额检查UidIsLimited/IsQuotaLimitedById配额受限时返回ENOSPC。cfs_flushextern int cfs_flush(int64_t id, int fd);flush 文件将缓冲数据刷盘。参数id为 client 的 IDfd为文件描述符。成功返回 0失败返回小于 0 的值statusOK、statusEINVAL、statusEBADFD、statusEIO。热卷通过ExtentClient.Flush完成刷盘见 client/libsdk/libsdk.go。cfs_truncateextern int cfs_truncate(int64_t id, int fd, size_t size);truncate 文件。参数id为 client 的 IDfd为文件描述符size为 truncate 后文件的大小。成功返回 0失败返回小于 0 的值statusOK、statusEINVAL、statusEBADFD、statusEIO。文件与目录操作接口cfs_mkdirsextern int cfs_mkdirs(int64_t id, char* path, mode_t mode);创建多级目录。参数id为 client 的 IDpath为要创建的目录路径mode为权限模式。成功返回 0失败返回小于 0 的值statusOK、statusEINVAL、statusEEXIST目录已存在。实现会按/逐级拆分路径逐级Lookup/Create路径为根目录/时直接返回statusEEXIST见 client/libsdk/libsdk.go。cfs_rmdirextern int cfs_rmdir(int64_t id, char* path);删除指定路径的目录。参数id为 client 的 IDpath为目录路径。成功返回 0失败返回小于 0 的值。底层调用MetaWrapper.Delete_ll并清除 inode/dentry 缓存见 client/libsdk/libsdk.go。cfs_unlinkextern int cfs_unlink(int64_t id, char* path);删除文件。参数id为 client 的 IDpath为文件路径。成功返回 0失败返回小于 0 的值statusOK、statusEINVAL、statusEISDIR目标为目录。实现中会先校验目标不是目录删除后还会调用Evict驱逐对应 inode见 client/libsdk/libsdk.go。cfs_renameextern int cfs_rename(int64_t id, char* from, char* to, GoUint8 overwritten);重命名一个文件或目录。参数说明idclient 的 IDfrom原始文件或目录的路径to新的文件或目录的路径overwritten是否允许覆盖已存在的目标。成功返回 0失败返回小于 0 的值。该操作在客户端内部加锁串行执行并同步清理源/目标两侧的 dentry 缓存见 client/libsdk/libsdk.go。cfs_readdirextern int cfs_readdir(int64_t id, int fd, GoSlice dirents, int count);读取目录的文件和子目录列表。参数说明idclient 的 IDfd文件描述符dirents存储文件和子目录信息的数组元素为cfs_dirent结构包含ino、name[256]、d_type、nameLencount要读取的目录项数量。返回值大于 0 表示读取的目录项数失败返回小于 0 的值statusEINVAL、statusEBADFD。实现使用dirStream维护游标支持分多次读取见 client/libsdk/libsdk.go。cfs_lsdirextern int cfs_lsdir(int64_t id, int fd, GoSlice direntsInfo, int count);列出指定目录下的文件和子目录信息包括元数据信息。参数说明idclient 的 IDfd文件描述符direntsInfo存储文件和子目录信息的数组元素为cfs_dirent_info内含cfs_hdfs_stat_info元数据count要读取的目录项数量。返回值大于 0 表示读取的目录项数失败返回小于 0 的值statusEINVAL、statusEBADFD。与cfs_readdir不同cfs_lsdir会对每个目录项批量获取 inode 元数据size、mode、atime、mtime 等一并返回见 client/libsdk/libsdk.go。属性接口cfs_getattrextern int cfs_getattr(int64_t id, char* path, struct cfs_stat_info* stat);获取文件的属性。参数说明idclient 的 IDpath文件的路径statcfs_stat_info结构体指针用于存储文件属性定义在 client/libsdk/libcfs.h 中。成功返回 0失败返回小于 0 的值。cfs_stat_info包含ino、size、blocks、atime/mtime/ctime及纳秒部分、mode、nlink、blk_size、uid、gid等字段。实现中mode会根据文件类型普通文件/目录/软链/其他自动补上S_IFREG、S_IFDIR、S_IFLNK等类型位见 client/libsdk/libsdk.go。cfs_setattrextern int cfs_setattr(int64_t id, char* path, struct cfs_stat_info* stat, int valid);设置文件的属性。参数说明idclient 的 IDpath文件的路径statcfs_stat_info结构体指针包含待设置的属性valid位掩码标识哪些属性是有效的如模式、uid、gid、atime、mtime。成功返回 0失败返回小于 0 的值。实现中仅允许设置 rwx 权限位mode 0o777且会保留原有的文件类型位见 client/libsdk/libsdk.go 与 client/libsdk/libsdk.go。cfs_IsDir 与 cfs_IsRegularextern int cfs_IsDir(mode_t mode); extern int cfs_IsRegular(mode_t mode);根据mode判断类型cfs_IsDir返回 1 表示是目录、0 表示不是cfs_IsRegular返回 1 表示是普通文件、0 表示不是。实现分别对mode S_IFMT与S_IFDIR/S_IFREG做比较见 client/libsdk/libsdk.go。链接接口cfs_symlinkextern int cfs_symlink(int64_t id, char *src_path, char *dst_path);创建软链接。参数id为 client 的 IDsrc_path为源路径dst_path为目的路径。成功返回 0失败返回小于 0 的值。实现通过MetaWrapper.Create_ll以ModeSymlink | ModePerm模式创建见 client/libsdk/libsdk.go。cfs_linkextern int cfs_link(int64_t id, char *src_path, char *dst_path);创建硬链接。参数id为 client 的 IDsrc_path为源路径dst_path为目的路径。成功返回 0失败返回小于 0 的值。注意源文件必须是普通文件否则返回statusEPERM见 client/libsdk/libsdk.go。目录锁接口目录锁适用于对目录有互斥需求的应用基于元数据 XAttrkey 为dir_lock实现。目录加锁后如果在有效期内再次加锁会返回失败加锁成功会返回唯一的lockId。cfs_lock_dirextern int64_t cfs_lock_dir(int64_t id, char *path, int64_t lease, int64_t lock_id);对目录加锁。参数说明idclient 的 IDpath目录路径lease加锁期限lock_id若指定了lock_id则表示对该lock_id的加锁期限lease进行续期修改。成功时返回唯一的lock_id失败时返回小于 0 的值见 client/libsdk/libsdk.go。cfs_unlock_dirextern int cfs_unlock_dir(int64_t id, char *path);对目录解锁。参数id为 client 的 IDpath为目录路径。成功返回 0失败返回小于 0 的值见 client/libsdk/libsdk.go。cfs_get_dir_lockextern int cfs_get_dir_lock(int64_t id, char *path, int64_t *lock_id, char **valid_time);获取目录锁的有效时间。参数说明idclient 的 IDpath目录路径lock_id输出参数返回对应的锁 IDvalid_time输出参数返回对应lock_id的有效期。成功返回 0失败返回小于 0 的值目录未加锁时返回ENOENT。实现从 XAttr 中解析出lockId|lease两部分见 client/libsdk/libsdk.go。其他扩展接口client/libsdk/libcfs.h 中还导出了文档未逐条展开但同样可用的接口包括cfs_chdir/cfs_getcwd修改/获取客户端当前工作目录相对路径基于该目录解析cfs_fchmod按 fd 修改文件权限cfs_batch_get_inodes批量获取 inode 属性cfs_getsummary/cfs_refreshsummary获取/刷新目录摘要文件数与字节数按 HDD/SSD/BlobStore 分类支持缓存与并发数控制cfs_get_xattr/cfs_list_vols/cfs_get_accessFiles扩展属性、卷列表与访问文件清单查询。错误码速查所有接口的返回约定统一为0 表示成功负数表示错误。常见错误码及含义汇总如下对应 client/libsdk/libsdk.go 中定义的 status 常量返回值名称含义0statusOK成功-EINVALstatusEINVAL非法参数如 client 不存在-EIOstatusEIOI/O 错误-EACCESstatusEACCES权限错误如只写 fd 上执行读-EBADFDstatusEBADFD错误文件描述符-EMFILEstatusEMFILE文件描述符已达上限-ENOSPCstatusENOSPC空间不足-EEXISTstatusEEXIST目标已存在-EISDIRstatusEISDIR目标是目录如对目录执行 unlink-ENOTDIRstatusENOTDIR目标不是目录-EPERMstatusEPERM操作不允许如对非普通文件建立硬链接结语快速上手指南构建在仓库根目录执行make libsdk依赖libsdkpre产物为libcfs.so与libcfs.h见 Makefile 与 build/build.sh接入将 client/libsdk/libcfs.h 加入头文件路径链接libcfs.so编码按“new → set → start → 文件操作 → close”五步生命周期编写业务逻辑部署确保应用可访问 Master 地址与目标卷并配置正确的accessKey/secretKey否则cfs_start_client会因权限校验失败而无法启动。libsdk 让开发者在不引入内核模块与 FUSE 的前提下以纯用户态方式获得 CubeFS 文件系统的全部能力适合对灵活性、可移植性与低延迟有较高要求的应用场景。赞分享存储分布式文件系统对象存储云原生【免费下载链接】cubefscloud-native distributed storage项目地址https://gitcode.com/gh_mirrors/cu/cubefs点击查看免费下载相关推荐CANN竞赛Add算子测试报告 元信息请如实填写此区块将由组委会脚本自动解析请保持字段名不变 team_name: WISE小队 team_members:CANN文档高性能计算docker-gitlab API使用指南从项目管理到用户操作全接口docker gitlab API使用指南从项目管理到用户操作全接口 你是否在寻找一种高效管理GitLab项目的方式是否希望通过代码自动化处理用户权限、项目运维云原生上一篇18课搭出一个AI智能体新手入门AI智能体开发的实战课程下一篇Beamer主题完全解析从默认到高级自定义创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考