
拿到FAST‘25录用通知的那个下午邮件列表里紧接着就躺着一封来自Artifact EvaluationAE委员会的信标题大意是“您的论文已被邀请参与Artifact Evaluation”。当时我们团队在Linux内核存储路径上做了一个涉及透明加密与file_operations动态拦截的项目代码量不算小内核适配、依赖项、复现步骤都很棘手。说实话第一反应是抗拒——论文都中了为什么还要把代码和环境打包给别人跑但转头一想FAST这种存储系统顶会这几年的风向很明确AE不是选修课是证明研究可信度的重要一环。尤其我们做的是内核层的东西复现难度本来就高如果连AE都不参加等于主动向同行传递“我可能不想让你复现”的信号。所以这篇文章就是FAST‘25 AE全流程的记录从规则拆解、内核工件的特殊难点到README设计、脚本自研、评审往返最后到拿badge的复盘。适合两类人看一是打算投系统类会议FAST、OSDI、SOSP、ATC这类并准备参与AE的研究生和工程师二是手头有内核模块、文件系统、驱动这类底层工件、不确定怎么打包给评审跑的朋友。我会把踩过的坑、返工过的地方、以及那些“文档里绝对不会写”的细节都摊开讲。1. FAST‘25 Artifact Evaluation到底在评什么先把规则掰开1.1 从“论文可复现”到badge体系FAST‘25 AE在延续什么趋势很多人第一次接触AE会误以为它是“论文二审”或者“评审委员会再帮你检查一遍代码质量”。实际上完全不是这样。AE评的是你论文里描述的那个系统、那个实验、那组数据是否可以在脱离作者的环境下被别人重新构建和复现。换句话说它回答的问题是你说你做了一个能在Linux内核里动态替换file_operations并透明加密文件内容的系统那好请给我一套能跑起来的东西让我信。FAST‘25的AE规则延续了USENIX系列会议的成熟体系评估结束后会给工件打不同类型的badge通常会挂在论文页面上。常见的有三大类Artifact Available工件可获得你的代码、数据、README托管在公开平台比如Zenodo、GitHub、figshare有稳定标识如DOI评审人能直接下载。Artifact Functional工件功能可运行评审人在你的说明指导下成功把系统跑起来并且功能行为与论文描述一致。Results Reproduced结果可复现评审人不光跑了功能还复现了你论文里的关键性能数字或图表趋势也就是“结果层面”过关。这三级是递进的。对很多纯算法或纯用户态工具来说拿到前两级不算太难。但一旦涉及内核事情就复杂了。我会在第二节专门展开。1.2 AE评审人在实际操作中查什么和我们原来的理解不一样我最初以为AE评审人会非常仔细地读我们论文里的每个实验细节然后对照代码逐行检查。实际接触下来发现评审人更像是“照着README走流程的执行者”——他们手里有一台干净的机器或虚拟机会严格按你写的步骤一条命令一条命令地敲比对预期输出。评审过程中常看的要素包括构建是否顺利编译内核、编译模块、安装依赖的过程中有没有哪一步让评审人卡住超过十分钟功能是否自洽加载模块后文件系统行为是否与论文描述一致比如透明加密场景下普通read/write接口是否真的被拦截并加解密性能是否可解释论文里的性能图是如何生成的fio、io_uring、splice这类路径的测试脚本是否齐全关键参数有没有写清楚环境依赖是否明确需要什么架构的CPU是x86_64还是ARM物理机还是虚拟机内核版本范围是什么有一件事特别值得说评审人不是来找茬的但他们极度依赖文档。如果你的README写得不清晰或者脚本里藏着只有你本人才知道的“隐藏状态”那结果大概率是“Functional失败”。所以AE准备本质上是一次“把你的实验环境完整地交给一个陌生人”的训练。1.3 时间线与节点什么时候该干什么FAST‘25的AE时间线和大多数USENIX会议一致。按我们这次的经验大致是这样论文录用通知发出后一周内AE chair开始发邀请邮件。递交AE的deadline通常在camera-ready最终稿前约2到3周。评估窗口期评审人实际动手评估的时间大概是提交后的两周到三周。结果通知在camera-ready之前返回这样作者有机会把badge放到最终论文页面上。这里有一个很容易被低估的点不要把AE材料拖到deadline前才开始准备。我们当时预留了完整的两周专门做这件事依然很紧张尤其是为了跑通“从源码编译一个定制内核”这个流程反复试错就花掉好几天。后面第三节会讲我怎么设计打包方案说白了就是对时间不够的恐惧逼出来的。2. 内核类工件是AE里的“困难模式”环境锁定、硬件依赖与性能波动2.1 环境锁定问题内核版本、编译链与模块签名任何一个失配都直接挂我们的论文工作是在Linux内核层做透明加密具体实现里通过动态加载方式拦截了文件系统的file_operations结构体中的read和write指针把数据加解密逻辑植入到常规I/O路径中。这个方案的优势是无需修改业务层代码、对应用透明劣势是它极度依赖内核版本和编译配置。准备AE时第一个“困难模式”就砸过来了评审人不可能为了你的模块轻易重编自己的内核。他们更可能拿一台现成的Ubuntu或Debian虚拟机默认内核可能是6.2、5.15、4.18什么的。而我们的模块是为6.1 LTS编译的且依赖几个自定义config项比如需要启用CONFIG_MODULE_SIG验证、需要CONFIG_KALLSYMS全量符号。如果评审人直接默认内核insmod几乎必然失败。环境项我们开发机AE交付环境要求内核版本6.1.119定制LTS与开发机一致编译工具链gcc 12.2binutils 2.40版本浮动不能太大依赖启动项CONFIG_MODULE_SIG、CONFIG_KALLSYMSREADME中标明提供完整config内核模块头文件路径/lib/modules/$(uname -r)/build必须随内核一起交付我把这些信息整理成一张表放在README最前面目的就一个让评审人在敲第一条命令前就知道“这套东西是为哪个内核做的”。避免跑到第五步才发现环境不对情绪爆炸。2.2 透明加密与file_operations拦截的评估难点不是功能是“观察方式”老实说透明加密系统在功能验证上并不复杂创建文件、写入内容、关闭、重新打开、读取内容——只要能读到一致的明文功能就是对的。但AE评审要确认的不只是“能不能加解密”还包括“你到底拦没拦住那个read/write”。我们用的技术是动态替换目标文件系统file_operations里的read和write函数指针。要证明这件事单纯靠外部读文件是不够的因为ext4内部自己的加密逻辑也能做到类似效果。所以我在README里专门写了一个“内部观测”小节告诉评审人加载模块后用/proc/modules确认模块已加载用我们自己暴露的debugfs节点/sys/kernel/debug/xfs_enc/fops_check读取当前文件系统file_operations函数指针的哈希快照对比加载前后指针地址是否发生了变化再用dmesg查看拦截日志中打印的实际调用栈。这一步说明了一个很关键的经验给内核类工件写README不能只写“外部行为”一定要提供“内部机制可观测性”。因为评审人不是你的同事他们没看过你的代码结构你需要在文档里给他们一个把手让他们确认“这个系统确实在用论文说的机制工作”。2.3 性能结果复现fio数字天生会漂评审人到底想看到什么系统类论文通常都有性能实验我们的论文也不例外。透明加密在read/write路径上必然有开销我们用fio跑了几组典型负载附上了带宽和延迟数据。问题在于AE评审人的机器和我们的开发机不一样CPU频率、内存带宽、NVMe型号都会影响最终数据。第一次准备复现脚本时我天真的以为把fio命令写在README里就够了。后来才意识到这里有个“复现策略”需要想清楚。我们的策略是给评审人提供了两类实验功能正确性实验必须严格通过在指定目录创建加密区写入特定大小的文件用sha256sum对比加解密前后的内容哈希一致性能对比实验可接受趋势复现让评审人跑perf_test_compare.sh该脚本会依次执行“无加密基线”和“加密开启”两组fio输出两组数字并用analysis.py绘制趋势对比图。我们不要求评审人的绝对数字和论文完全一致只要“加密后性能损耗比例与论文趋势相近”即可。实际评估下来这个策略是对的。评审人反馈里写的是“性能数字与论文在同一量级损耗趋势一致”这就达到了Reproduced要求。如果你把宝押在“绝对数字一致”上那基本等于拖自己下海因为哪怕是最稳定的fio在不同机器上随机波动都可能超过10%。3. 提交材料的准备README、脚本、环境镜像一寸长一寸强3.1 README分级给不同角色的人提供不同深度的入口AE材料里没有哪个部分比README更重要。它决定了评审人对你工件的第一印象也决定了他们的耐心会被消耗到什么程度。我们给的README没有走“写了一万字的论文说明”那条路而是分成了四层第一层是“快速启动”五分钟内跑通功能验证的最小步骤包括下载预编译内核/模块、加载、挂载、写文件、读文件验证。第二层是“系统构建”从源码编译定制内核和模块适合评审人想验证“在没有预编译包的情况下能否从0复现”。第三层是“实验复现”包含fio性能测试、校准流程、解析脚本对应论文中图表。第四层是“FAQ与故障排除”把之前组里试跑时遇到的所有坑都列进去比如“insmod报Invalid parameters”“debugfs节点不出现”“模块加载后系统挂起”等。这个分级设计特别管用。评审人在有限时间里有优先策略——先读快速启动跑通早见成果再决定愿不愿意深入。哪怕他最后只跑了第一层他也能在评估表里写上“功能验证通过”。3.2 环境交付的两手方案预编译内核模块 vs 源码编译对于内核工件最怕的事情是评审人机器上没有你需要的编译环境或者编译依赖跟你的不一致。最保险的交付方式就是“一手交编译好的二进制环境一手交完整源码构建路径”。我们最终交付物包含一个定制的Linux 6.1.119内核源码包附带了完整的配置文件config file预编译好的内核镜像和模块包用于Ubuntu 22.04 x86_64环境可以直接加载QEMU/KVM虚拟机镜像约12GB压缩后里面已经预装了内核、模块、测试脚本和fio评审人如果能跑虚拟机可以直接在镜像里把功能和性能实验全跑完无需编译自动部署脚本用于在裸机或新VM上从源码构建脚本会先检查系统发行版、安装依赖、解压源码、make olddefconfig、编译内核和模块、安装。为什么要做双方案因为评审人手里机器的状态不可控。有的评审人只有一台不允许重启的云主机换内核根本不现实这时VM镜像就是救命稻草。有的评审人偏爱在原生态环境里编译验证那源码构建方案就派上用场了。两手方案能覆盖大多数情形。3.3 validate.sh让“能否通过”这件事变得毫无疑问AE评审人在有限时间内最想要的反馈是明确的“通过/不通过”。所以我把功能验证收敛到一个脚本里叫validate.sh它做下面几件事检查内核版本是否匹配不匹配时立刻提示正确版本检查debugfs是否挂载没挂载就自动挂载加载模块并用dmesg提取加载日志创建临时加密目录挂载一个基于loop设备的加密测试文件系统用dd写入2GB测试文件输出写入时的明文哈希关闭文件重新打开读取对比读取后的哈希是否一致校验完成打印PASS/FAIL。为了保证阅读方便脚本每一步都带上了详细的echo输出并且每一步之间用sleep隔开避免dmesg日志堆积。还有一个细节值得提我在脚本末尾加了exit 1/exit 0显式退出码这样评审人可以直接用./validate.sh echo OK这种常见方式判断结果不需要人肉读输出。3.4 性能数据的可追溯性原始日志、job文件与分析脚本一把梭性能实验最容易翻车的点不是脚本没跑通而是评审人不知道你论文里的图是用哪些参数跑出来的。我们论文里有三张性能图顺序读写带宽、4KB随机读写IOPS、io_uring/splice路径对比。所以对应地我在perf/目录下放了三套完整的fio job文件.fio格式每个job文件头部注释都写了对应论文图编号。跑完后fio会输出JSON格式的原始结果再加上analysis.py脚本直接读取JSON、计算平均值和方差、绘制趋势图。另外我还放了“机器信息采集”脚本自动收集CPU型号、核心数、内存大小、内核uname、磁盘型号、挂载参数。为什么要这些因为评审人复现的结果如果和论文差很多有了这些信息我们可以去判断是硬件差异导致的还是实现问题导致的。表格里附上这些信息也给评审人的最终报告提供了上下文。4. 提交、等待、沟通评审人比想象中更较真也比想象中更友好4.1 托管策略GitHub仓库、Zenodo DOI、release订单一气呵成提交AE材料的第一步是有一个稳定的下载地址。我们用GitHub公开仓库放置全部代码和数据再用Zenodo给该仓库生成了DOI把DOI写进README和提交表的“工件下载”栏。这里有两个容易忽略的坑不要只用GitHub仓库不加DOI。GitHub分支、tag可以被修改而AE要求的是“评审人拿到的就是作者声称的那一版”Zenodo的DOI能锁定归档版本。不要把大文件传GitHub。12GB的虚拟机镜像传上去非常痛苦。我们把镜像放在Zenodo支持大文件上传GitHub仓库里放的是脚本和源码README里写镜像的Zenodo下载链接。4.2 提交表与评审协同表“自验记录”是我们最聪明的决定FAST‘25 AE在提交系统里除了要填工件链接还要求填写一份协同文档或者是空的评审表评审人会在这个表里记录逐步评估的情况。我们做了一件后来被证明作用极大的事在提交前自己在协同表里填了一整份“作者自验记录”逐步骤列出了“我们预期评审人会看到什么”并在后面附上我们试跑时的输出截图和日志。这么做的好处非常明显评审人拿到一个已经“剧透”了预期结果的文档心理安全感和信任感会大大提升。如果他们跑出来的结果与自验记录不一致他们会更倾向认为是环境差异导致的而不是作者造假。自验记录本身也是“Functional”评级的有力佐证——作者主动把“什么样的内部状态才是系统正常工作的证据”摆在了桌面上。4.3 评审往返实例那些让人汗毛竖起的问题评估窗口期内我们收到了两个比较典型的问题问题一“当前实现是否支持ARM64如果不行请在README中注明。”这个问题很合理因为我们README只写了x86_64。但底细是我们的汇编层加密实现确实没在ARM64上验证过。于是我们及时更新了README明确列出了当前支持架构列表同时附上了代码中与架构相关的文件路径方便评审人判断影响范围。问题二“在KASLR开启的情况下函数指针拦截是否仍能正常工作”这个问题其实问到点子上了。我们的系统在正确性上不依赖指针的具体数值而是依赖对函数指针表中固定偏移位置的替换所以KASLR不会影响功能。我在FAQ里补了一段解释同时附上了一个“关闭KASLR/开启KASLR的对比测试日志”。这既是对评审人问题的直接回应也等于把潜在的风险窗口堵死了。整个往返过程中我最大的感受是AE评审人不是来挖坑的他们问的问题往往是真在帮你看漏洞。你回复得越详细、越坦诚最后评估结果越可能靠前。4.4 澄清电话Clarification Call把模糊地带扼杀在最后一公里在正式出结果之前评审组织方安排了一次可选的澄清电话时长大约30分钟评审人可以在会上直接问作者问题。我们当时觉得书面沟通已经够充分本来不想参加但后来发现这个电话的价值远超预期。会上评审人直接展示了他在复现性能实验时的一条报错perf_stat_parse.py在读取某个fio JSON文件时崩了原因是fio版本差异导致JSON字段名变了。这个细节在纯书面沟通中很难描述清楚但在视频会议里评审人直接屏幕共享日志我们花了五分钟定位问题给出两条解决方案一是固定fio版本二是修复脚本的字段匹配逻辑。挂电话后当晚我们就把脚本更新好并重新上传Zenodo归档。所以我的建议是如果AE chair提供澄清机会一定要参加。这是一次“人道主义救援窗口”能挽回在书面流程里可能直接导致Reproduced失分的小问题。5. 复盘与建议这些细节让我们的AE过程顺利很多5.1 组内试跑把AE材料交给“没有上下文的人”去跑越早越好在我们正式提交AE之前我做了一件后来被证明最值回票价的事情抓了组里一位低年级同学把README、脚本、压缩包一股脑塞给他告诉他“你现在就是FAST‘25评审人你只有两个小时从头到尾把这个artifact跑一遍中间不许问我任何问题”。结果他用了一个小时十分钟才跑完中间卡壳了四次包括不知道为什么要先用root用户make menuconfig那个步骤在我机器上开了图形界面在他的SSH环境里直接报错预编译模块在它加载时因为version magic不匹配失败因为我用了uname -r里的自定义后缀而他没装对应的内核头文件他试图在某个步骤用sudo -E结果丢了环境变量导致make失败。这些bug如果直接提交给AE可能被记录为“构建失败”或“功能不通过”。但通过组内试跑我们有足够时间在提交前修复掉。其中第二个问题我们后来把内核源码构建步骤中的make menuconfig改成了make olddefconfig从交互式菜单改成了完全自动化的非交互方式彻底消掉了SSH环境下的挂起点。5.2 版本锁定与依赖快照不要相信任何“最新版”AE材料最忌讳“运行时安装最新版”。我们要求所有脚本里安装依赖时都用固定版本号。比如apt install fio3.35、python3.10-venv、libelf-dev0.188-1等。虽然apt源里可能没有历史版本但至少要用apt-cache policy在README里给出推荐的精确版本。Python依赖方面我在requirements.txt里锁死了所有库的版本号连numpy和matplotlib都没放过。理由很简单如果评审人在python 3.12上装到新版的pandas很可能会因为API变化跑挂分析脚本那我们的“Reproduced”小目标就危险了。与其指望评审人有容错心不如把所有坑提前填平。5.3 安全与兼容性边界明确告知什么不做比承诺你能做所有事更重要这件事也是踩坑踩出来的。我们在README里一开始只写了“支持Linux内核6.1及以上”显得能力边界很广。但评审人说他在6.5内核上尝试编译失败了。原因很简单我们依赖的file_operations结构体布局在某个小版本上有了变更导致offsetof访问的字段位置发生了变化。后来我们更改了表述明确写出“当前已验证内核范围是6.1.119的LTS分支不承诺其他版本可用”。同时在代码里加了一个编译期检查如果内核版本不在兼容列表直接抛出错误日志。这个做法的好处是把“编译失败”这种不可控问题变成了“作者已声明不支持”的合规提示。评审人看到这个提示通常不会判定为工件问题而会标记为“环境受限”。5.4 省时间的关键细节磁盘空间、下载节点与并行编译小细节有时候能决定评审人能走多远。比如我们简易说“需要20GB磁盘空间编译内核”但实际需要接近40GB源码中间文件模块包。这时一定要在README里把需求写大一点不能低估。还有一个实用经验在编译步骤里给评审人提供了make -j$(nproc)的推荐做法并注明编译大约需要15-40分钟。同时在README里贴出用示例机器编译时的总耗时报文让评审人对时长有预期。人在有预期的时候更有耐心反而不会中途杀掉进程。网络也是个坑。Zenodo在国内某些网络环境下下载很慢我们在FAQ里提供了两个镜像地址一个Zenodo一个是直连的S3 bucket。AE本身不要求你的材料有跨国网络加速但你多提供一个节点评审人的成功率就会高一次。最后的几句实在话整个FAST‘25 AE流程走下来我最大的感触是AE准备不是一个可以临时抱佛脚的事情它考察的核心其实是“你对自己系统理解得够不够”。很多问题比如环境依赖、版本兼容、性能漂移、观测手段如果你在开发过程中就认真对待最后只是把这些记录包装成文档而已。反过来如果开发时稀里糊涂指望评审前补天那基本补不回来。还有一个非常实际的经验AE材料和论文camera-ready是同一时间线一定不要把AE材料放到论文定稿后。最好的安排是——论文录用后先别急着庆祝趁代码和实验环境都还热乎立刻花一到两周把AE材料整理出来。拖得越久你越容易忘掉当时为什么这样配置内核、为什么要加某个debugfs节点、那条被注释掉的workaround到底解决过什么。坦白讲即使做了这么多准备我们拿到badge的时候依然有几处后怕。比如虚拟机镜像文件上传到Zenodo后才发现忘记打上.config文件当时差点要重新上传12GB比如validate.sh里有一处硬编码的用户名幸好在组内试跑时被抓了出来。这些细节都很琐碎但正是它们决定了AE能不能绿灯通过。希望这篇记录能帮后来的朋友少交点学费。