鸿蒙PC的samba 4.21.0:从waf到selftest合入实录
欢迎加入开源鸿蒙PC社区: https://harmonypc.csdn.net/
欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
鸿蒙PC的samba 4.21.0:从waf到selftest合入实录
| 项 | 内容 |
|---|---|
| 对象 | samba 4.21.0(SMB 文件/打印服务套件,waf 私有构建系统 + PIDL IDL 编译器) |
| 环境 | HAD-W24(鸿蒙 PC)/ HarmonyOS 6.1.0.117(SP68C00E100R13P3) / aarch64 / HongMeng Kernel 1.12.0 / conan 2.29.1 / clang 15(cppstd 17,libc++,musl) |
| 仓库 | https://atomgit.com/OpenHarmonyPCDeveloper/build_in_harmonyos |
| PR | #11515 |
| 关联 Issue | #3179 |
摘要:记录 samba 4.21.0——Windows 互操作标准套件——在鸿蒙 PC(aarch64)上的完整适配。难点:samba 使用私有 waf 构建系统与 PIDL IDL 编译器,上游 selftest 管线还依赖一组运行时 wrapper。最终以 11 个配置式/符号级补丁(0 处平台宏)让构建全绿:默认变体 3571/3571 waf 任务全过,本地证据用的 selftest 变体 4192/4192 全过(含 86 个 python 扩展模块);消费者用例 2/2 通过(libwbclient 公开 API + smbd --version)。对上游 selftest 本文给出诚实申报:全量 testlist 实测 2685 条(selftest.pl 计划口径 1084 是其子集),四层实跑(非 root 手工/非 root 配方/root 预检/root 直跑)0 通过——失败全部卡在测试环境 provisioning 阶段(设备策略层封锁 socket 创建、能力集受限、上游 selftest.pl L896 perl 崩溃),0 项属于构建适配层失败。PR 于 2026-09-28 合入。
真正的难点有三层:私有 waf 构建系统(全部配置逻辑在 python 里,没有 CMake/autotools 那样的跨平台抽象层可依赖)、PIDL IDL 编译器(selftest 需要 Perl 工具链)、设备 HAP 沙箱策略层(root 的 socket() 创建都被封锁)——前两层决定"能不能编",最后一层决定"能不能测"。
声明:上游全量 selftest 在本适配中 0 通过(四层实跑全部停在环境 provisioning),原因是鸿蒙 PC 设备的策略层/能力集限制,不是构建适配问题。本文的"测试通过"主张限定于:构建任务 100%(3571/3571、4192/4192)与消费者用例 2/2。本文不宣称 Samba 文件共享功能可用,不宣称上游 selftest 通过。
目录:
- 一、背景:为什么值得做
- 二、环境与差异前置
- 三、适配过程:11 个补丁逐个拆
- 四、验证:构建 / 消费者 / 上游 selftest 诚实申报
- 五、知识沉淀
- 六、FAQ
- 七、总结
- 参考链接
一、背景:为什么值得做
生态价值:samba 是 SMB/CIFS 协议的标准实现,提供文件共享、打印服务与(裁剪后的)域集成。鸿蒙 PC 作为桌面操作系统,与 Windows 文件共享互通是刚需场景,smbd/smbclient 是这一场景的基础组件。本适配裁剪了 ad-dc/ldap/json/acl/pam/quotas/cups 等可选组件,保留核心服务面。
先例与难度定位:build_in_harmonyos 仓库已适配一批 C 库;samba 的体量(3571 个构建任务)与构建系统复杂度(waf + PIDL + Perl 工具链 + 5 个运行时 wrapper)远高于普通库。它的上游基础库 tdb/ldb 已在同生态适配并 published——samba 是这条依赖链的自然终点,也是"复杂 C 工程"适配能力上限的一次检验。
选库理由:waf 私有构建系统、PIDL IDL 编译器、Perl 工具链、cwrap LD_PRELOAD 运行时 wrapper 机制——samba 几乎覆盖了 C 生态构建系统的全部挑战类型。适配过程中沉淀的方法(探测式补丁、符号级版本门控、.pc shim 旁路、四层实测归因)对同生态其他 waf/PIDL 项目可直接复用。
二、环境与差异前置
环境表(工程机实测值,非文档声明值):
| 项 | 实测值 | 测量方式 |
|---|---|---|
| 设备型号 | HAD-W24(鸿蒙 PC) | param get const.product.software.version |
| 系统版本 | 6.1.0.117(SP68C00E100R13P3) | 同上(输出 “HAD-W24 6.1.0.117(SP68C00E100R13P3)”) |
| OHOS 版本 | OpenHarmony-6.1.0.115 | param get const.ohos.fullname |
| 架构 | aarch64 | uname -m |
| 内核 | HongMeng Kernel 1.12.0 | uname -r |
| Conan | 2.29.1(OHOS 适配版,os=OHOS 为有效枚举值) | conan --version |
| 编译器 | clang / clang++ 15(/data/service/hnp/bin) | conan profile show + create 日志 profile 段 |
| C++ 标准 / STL | cppstd 17 / libc++ | conan profile show |
| libc | musl(OHOS 原生工具链) | 工具链实测(无 libtirpc/libintl/libacl 等 glibc 系符号) |
| 上游源(conandata 实源) | GitHub tag tarball,实测可达(302→codeload) | curl -sI(2026-10-06) |
| 官方发布源 | download.samba.org,实测 200 OK(国内可达) | curl -sI(2026-10-06) |
| 源码 sha256 | 79ad4e1820f9eb405640bea57076b514082ef01ade0d435b2f03005b9e4c9072 | conandata.yml(tag 源 tarball 实测值) |
差异前置:先列全所有问题,再逐个展开。 下表 15 项为上游假设与鸿蒙 PC 实际情况的全部差异点;其中 10 项由 11 个补丁处理(0002/0003 共用一项差异),2 项由非补丁方案处理(.pc shim、python 交叉编译旁路),3 项属环境受限(无补丁可解,见 4.1 归因):
| # | 上游假设 | 鸿蒙 PC 实际情况 | 处理位置 |
|---|---|---|---|
| 1 | /tmp 可写(mkstemp 探针直接写 /tmp) | /tmp 是只读 erofs | 补丁 0001(探针改 TMPDIR) |
| 2 | glibc 提供 ethtool_cmd_speed() | musl 不提供 | 补丁 0002+0003(符号级探测 + 0 兜底) |
| 3 | yapp 二进制可用(PIDL 源码生成) | yapp 二进制缺失 | 补丁 0004(vendored Driver + pre-generated 降级) |
| 4 | libc 未预定义 uintptr_t | C23 风格 libc 经 UINTPTR_TYPE 内建宏已定义 | 补丁 0005(跳过重复 typedef) |
| 5 | uid-wrapper ≥ 1.3.1 | 制品仓仅 1.2.5 | 补丁 0006(门限放宽,nm 实证) |
| 6 | rpcgen 二进制可用 | 缺失(rpc/xdr.h 亦缺失) | 补丁 0007(模块按可用性门控) |
| 7 | acl 头存在(sys/acl.h / acl/libacl.h) | sysroot 无 libacl(–without-acl-support) | 补丁 0008(测试二进制门控) |
| 8 | PAM 头存在 | 缺失(–without-pam,configure 整段跳过) | 补丁 0009(None 防御) |
| 9 | python cryptography/pyasn1 可安装 | 无对应系统包(import 实测 MISSING) | 补丁 0010(required=False 降级) |
| 10 | platform.system() == ‘Linux’ | ‘HarmonyOS’(linux_kernel_version=None) | 补丁 0011(None 守卫) |
| 11 | 系统 libtirpc / rpc.h 可用(bundled wrapper 可编) | musl 无 libtirpc、rpc/rpc.h 缺失 | .pc shim(配方写本地 shim,命中系统 wrapper、跳过 bundled 编译) |
| 12 | python3-config --ldflags --embed 不输出 -lintl | OHOS/musl 无 libintl,输出 -lintl -ldl → 链接失败 | python_cross_compile 环境变量旁路(配方构建期注入) |
| 13 | umask 022(上游 CI 环境) | 设备 umask/fs 语义产生 0771(与上游 0755 期望不符) | 环境受限(4.1) |
| 14 | 测试执行上下文具备完整 root | HAP 沙箱:agent 上下文 CapBnd=0;root 上下文亦被策略层封锁 socket() 创建 | 环境受限(4.1) |
| 15 | stat 支持 --file-system | 设备 stat 无该选项 | 环境受限(4.1,非致命) |
三、适配过程:11 个补丁逐个拆
3.0 侦察
lang-preflight 误判:预检工具初判 mixed → env_unsupported,差点终止任务。复核证据:顶层仅 setup.cfg(pycodestyle 样式配置,不是打包 manifest)、无 setup.py/pyproject.toml、构建系统为 waf、主体是 C(3969 个 .c 文件,占 78% 以上);同源的 ldb/2.9.2 已作为 C 库 published 可作参照。判定为工具误判,继续 C 适配。
依赖发布状态核验(逐项 conan download):gnutls/3.8.10、zlib/1.3.1、perl/5.42.2 均在制品仓;selftest 变体所需的 5 个 cwrap wrapper(resolv-wrapper/1.1.8、nss-wrapper/1.1.16、socket-wrapper/1.5.2、uid-wrapper/1.2.5、pam-wrapper/1.1.8)与 libarchive/3.8.7 亦已发布。无阻塞性缺失依赖。
构建系统与测试策略:waf(顶层 wscript,configure 是 buildtools/bin/waf 的 wrapper);上游测试入口是 selftest/selftest.pl(Perl runner)+ 三层 tests.py 测试列表规划(selftest / source3/selftest / source4/selftest),运行期靠 5 个 wrapper 走 cwrap LD_PRELOAD 做网络/uid/nss 拦截。CI 只承载消费者验证,全量 selftest 走本地证据变体(见 4.5 双变体设计)。
依赖树(默认变体 = CI/制品;selftest 变体为本地证据,非发布制品):
samba/4.21.0(本配方)
├── gnutls/3.8.10 # waf configure 强制依赖
│ ├── gmp / libgcrypt / libgpg-error / libtasn1 / libunistring / nettle # 传递依赖(版本随制品仓)
├── zlib/1.3.1 # force=True 统一整图(化解 libarchive 钉死 1.3.1.1 的冲突)
├── perl/5.42.2 # tool_requires(PIDL Parse::Yapp)
└── [仅 selftest 变体 with_selftest=True,本地证据]
├── socket-wrapper/1.5.2 ├── nss-wrapper/1.1.16
├── resolv-wrapper/1.1.8 ├── uid-wrapper/1.2.5
├── pam-wrapper/1.1.8 └── libarchive/3.8.7
以下坑位时序按补丁顺序还原(0001→0011);实际排查与构建迭代(c1-c29 共 29 轮 conan create 尝试)是交错的。每个坑按"现象→定位→方案→经验"四段记录。
3.1 坑一(补丁 0001):mkstemp 探针在只读 /tmp 上失败
- 现象:waf configure 的 HAVE_SECURE_MKSTEMP 探针失败,构建落入不安全的 rep_mkstemp(mktemp) 替换路径。
- 定位:单独复现探针逻辑——探针把测试文件硬编码写到 /tmp,设备 /tmp 是只读 erofs,写不进去。顺带发现原判定"mode 恰好等于 0600"过于苛刻:restrictive umask 下真实安全的 mkstemp(如 mode 0660)也会被误判。
- 方案:探针改用 TMPDIR(不再硬编码 /tmp);安全判定放宽为"属主可读写(07000600)且组/其他无写权限(00020)";探针改为非强制。
- 经验:探针代码硬编码系统路径是跨平台通病;放宽安全判定必须保留"组/其他无写权限"约束,不能只改 mode 比较。
3.2 坑二(补丁 0002+0003):ethtool_cmd_speed 符号缺失
- 现象:lib/socket/interfaces.c 查询链路速率调用 ethtool_cmd_speed(),musl 无此符号,链接失败。
- 定位:nm 确认该符号由 glibc(及部分 libc)提供,OHOS 工具链缺失。
- 方案:新增 HAVE_ETHTOOL_CMD_SPEED 符号级链接探测(define 由工具链真实链接结果决定,不依赖平台宏);interfaces.c 按该宏分支——符号可用走 ethtool_cmd_speed(),否则 *speed=0 兜底(与上游"无链接检测"降级路径对齐)。
- 经验:链路速率查不到填 0 是上游已有的降级语义,不是功能削减;"真实链接结果决定 define"比"平台宏判断"更便携。
3.3 坑三(补丁 0004):yapp 二进制缺失导致 PIDL 硬失败
- 现象:PIDL 构建硬失败——yapp 二进制缺失、Parse::Yapp::Driver 不可用。
- 定位:release tarball 本身携带 pre-generated 解析器,真正的问题是 yapp 缺失时探针没有降级路径。
- 方案:配方 vendored 注入 Parse::Yapp::Driver(PERL5LIB 指向构建树 parse-yapp/);yapp 二进制缺失时降级使用 pre-generated 解析器并告警,不再硬失败。
- 经验:IDL 编译"优先 pre-generated 产物、源码生成兜底"是更稳的跨平台策略;Perl 模块注入走 PERL5LIB 而非改源码。
3.4 坑四(补丁 0005):cmocka.h 的 uintptr_t typedef 冲突
- 现象:third_party/cmocka/cmocka.h 重定义 uintptr_t,报 typedef redefinition。
- 定位:C23 风格 libc 已通过编译器内建宏 UINTPTR_TYPE 提供 uintptr_t,cmocka 的 typedef 与之冲突。
- 方案:UINTPTR_TYPE 可用时跳过重复 typedef。
- 经验:守卫条件用编译器内建宏(UINTPTR_TYPE),不是平台宏——本适配 11 个补丁 0 处 OHOS,全凭此类探测。
3.5 坑五(补丁 0006):uid-wrapper 版本门限 1.3.1 卡死
- 现象:selftest 变体 configure 的 uid_wrapper 版本检查失败——上游要求 ≥1.3.1,制品仓只有 1.2.5。
- 定位:nm 实证 1.2.5 的导出符号覆盖了 1.3.1 源码中全部 selftest 相关截获函数(setuid/setgid/setre*/setres*/getres*/setgroups/getgroups/pthread_create/pthread_exit/uid_wrapper_enabled/uwrap_*);唯一差异 __getgroups_chk 是 glibc fortify 符号,musl 上本就不存在;且 selftest 经 LD_PRELOAD + UID_WRAPPER=1 环境变量协议工作,不直接调用 wrapper 符号 API。
- 方案:minversion 1.3.1→1.2.5。
- 经验:版本门限放宽必须有符号级证据(nm 比对),不能凭"差个小版本没事";同时要确认消费协议(这里是环境变量)不依赖高版本符号。
3.6 坑六(补丁 0007):rpcgen 缺失卡住 nfs4acl 模块生成
- 现象:selftest 变体构建要求生成 nfs41acl.x→nfs41acl.h,设备无 rpcgen 二进制(rpc/xdr.h 亦缺失)。
- 定位:默认构建本就不启用 vfs_nfs4acl_xattr 模块;也没有 selftest 套件依赖该模块。
- 方案:按 rpcgen 可用性门控——缺失时跳过生成任务且不声明该模块,使 selftest 构建对齐默认构建的模块集;有 rpcgen 的上游构建不受影响。
- 经验:门控条件要对齐"默认构建的模块集",不是随手删模块——这保证 selftest 构建的模块面与发布变体一致。
3.7 坑七(补丁 0008):test_vfs_posixacl 测试二进制缺 acl 类型
- 现象:该测试直接 include vfs_posixacl.c 源文件,需要 acl_t 等类型;OHOS sysroot 无 libacl(sys/acl.h 与 acl/libacl.h 均不存在,配方本就是 --without-acl-support)。
- 定位:没有 selftest 套件运行这个测试二进制;vfs_posixacl 模块在 acl 缺失时本就不构建。
- 方案:无 acl 头时不构建该测试二进制;有 acl 平台行为不变。
- 经验:与坑六同理——测试集与功能门控对齐;"该测试没有消费者"是敢不构建它的依据。
3.8 坑八(补丁 0009):–without-pam 后 wrapper 路径变量 None 崩溃
- 现象:selftest 变体 SELFTEST_EXIT=2,selftest.pl 根本没启动——cmd_testonly 里 str + NoneType 直接崩溃。
- 定位:–without-pam(OHOS 无 PAM 头)时 configure 整体跳过 pam_wrapper/pam_matrix 配置段,变量未定义,原代码无条件把它们拼进 selftest.pl 选项。
- 方案:逐变量判空,仅已设置项拼入选项(nss/resolv/uid/socket 四值实测已在 config.h 设置为裸 .so 名,经 LD_LIBRARY_PATH 解析);pam 相关套件按环境受限如实归类。
- 经验:"可选功能整体跳过"会让下游所有变量可能为 None——拼选项前必须逐变量判空。这类坑只在启用可选变体后才出现,默认变体永远踩不到。
3.9 坑九(补丁 0010):python 可选模块 cryptography/pyasn1 缺失被当致命
- 现象:selftest 变体 python/wscript 对 cryptography/pyasn1 缺失报 Errors.WafError(fatal)。
- 定位:两模块仅被 AD-DC GPO/GPDI/krb5 加密相关套件运行时 import(gkdi、gp_cert_auto_enroll_ext、krb5 kcrypto/lockout/pkinit);设备 python 无对应系统包(python3-cryptography/python3-pyasn1 不可安装,import 实测 MISSING);dateutil.parser 实测可用(与 iso8601 的二选一检查天然满足)。
- 方案:缺失模块降级为非必需(COMPOUND_END(False) 跳过),受影响套件运行时 ImportError 按环境受限如实归类;模块在场时行为不变。
- 经验:区分"构建期硬依赖"和"运行时 import"——后者缺失的正确处理是构建期跳过 + 运行期归类,不是阻断整个构建。
3.10 坑十(补丁 0011):非 Linux 平台 kernel oplocks 判定 None 崩溃
- 现象:source3/selftest/tests.py 生成测试列表时崩溃(selftest.pl 0 tests)——compare_versions(None, [5,3,1]) 抛 TypeError。
- 定位:非 Linux 平台实测 platform.system()=‘HarmonyOS’,linux_kernel_version 保持 None;config.h 有 HAVE_KERNEL_OPLOCKS_LINUX 时,原代码无条件比较。
- 方案:None 时视同无 kernel oplocks(have_linux_kernel_oplocks=False),依赖该特性的套件按环境受限如实归类;Linux 平台(linux_kernel_version 非 None)行为不变。
- 经验:假设 platform.system()==‘Linux’ 的 python 脚本要做 None 守卫;测试列表生成的崩溃比构建失败更隐蔽——“0 tests"看起来像"全部跳过”,实际是规划器死了。
3.11 十一补丁小结
11 个补丁按生成方式分两批:批次一(0001-0005,per-file-difflib 全树对比生成)、批次二(0006-0011,逐文件 diff -u 生成,dry-run + apply + py_compile 三重验证);按性质分类:6 个探测/守卫型(auto,guard 全部是真实探测驱动)+ 5 个门控/防御型(manual)。共同特征:0 处平台宏(OHOS),全部走配置式/符号级/编译器内建宏探测,上游平台行为逐条不变——这是补丁可随 CI 迁移的前提。
四、验证:构建 / 消费者 / 上游 selftest 诚实申报
口径声明:本节统计分层、分别陈述——构建任务数、消费者用例数、上游 testlist 规划数、上游实跑数是 4 个独立口径,层与层之间不做相加、不改名、不拼接。"混在一起说就是造假"是本文的申报红线。
4.1 上游测试实跑(R51 台账)
规划口径(先清点):对终配构建树的三层测试列表规划入口全量执行,块级计数:
| 规划入口 | TEST 块 | TEST-LOADLIST 块 | 小计 |
|---|---|---|---|
| selftest/tests.py | 77 | 64 | 141 |
| source3/selftest/tests.py | 782 | 445 | 1227 |
| source4/selftest/tests.py | 505 | 812 | 1317 |
| 合计(声明的 N) | 1364 | 1321 | 2685 |
selftest.pl 计划口径 1084(skip/slow 排除后)——1084 是 2685 经 selftest.pl 过滤后的执行计划,2685 ⊇ 1084,两个口径的关系如上,不做并列相加。2685 的复现命令与日志哈希见 4.7②。

图1:testlist 三入口计数实测输出(141/1227/1317=2685)
实跑口径(四层独立实测,全部 0 通过):
| 层 | 上下文 | 结果 | 卡点(逐字来自日志) |
|---|---|---|---|
| 1 手工 run(tap4) | 非 root(agent 沙箱 CapBnd=0) | 0 套件启动 | smbpasswd -L can only be used by root → Unable to create user at Samba3.pm line 3862 |
| 2 配方端到端(verify3) | 非 root | 2 个 blackbox 用例运行、0 通过 | invalid permissions ... has 0771 should be 0755 + Unable to initialize messaging context! + net setlocalsid failed: 256 + http_server bind OSError Errno 99(socket wrapper 拦截)+ selftest.pl L896 崩溃 |
| 3 root 预检 | 真 root + 满能力集(000000ffffffffff) | socket() 创建即 EPERM | bind 445 与 8080 双双在 socket 构造阶段被拒(非 bind 拒绝)→ 能力层之下的设备策略层封锁 |
| 4 root 直跑(run#2) | 真 root + 满能力集 | 0 通过 | 权限层通过(root umask 无 0771 报错)→ 死于 Unable to initialize messaging context!(IPC socket 被策略层封锁)+ L896 崩溃 |
失败模式三分类(全部未通过项的归因:2685 规划条,其中 1084 在 selftest.pl 计划内):
- 环境受限:设备策略层 socket() 创建封锁(层 3 预检证据)→ 2 个测试环境 provisioning 失败 → 1084 计划中所有环境依赖套件不可运行。设备侧证据:agent 上下文 /proc/self/status 实测 Uid=20020090、CapBnd=0000000000000000、cgroup=com.huawei.hmos.hishell/app_8174(HAP 沙箱标准策略);root 上下文满能力集仍被策略层拦截——两层封锁互证。
- 运行环境项:root 直跑中 blackbox 用例死于运行脚本 PATH 缺 python 别名(
bash: python: command not found)——如实标注,非构建适配问题。 - 上游 bug:selftest.pl L896
Can't call method "getlog_env" on an undefined value(上游错误处理缺陷,仅环境未定义时触发,verify3 与 run#2 均现)。
0 项属于构建适配层失败:全部二进制正确产出(4192/4192)、消费者 2/2,失败全部卡在测试环境 provisioning 阶段。归属判定:设备 seccomp/HAP 策略层 + 能力集位于适配层之下,"跑不起来"与"编不对"是两回事,本文只申报前者。
4.2 断言 1:1 移植执行
不适用(如实说明):可移植断言子集 = 能在目标平台以公共 API 断言形式执行的用例。samba 的上游 selftest 是全环境依赖套件(需要守护进程启动与测试环境 provisioning),2685 规划条因 4.1 的环境限制整体不可运行,故不存在可移植断言子集。消费者用例(4.4)独立覆盖公开 API(libwbclient)与核心守护进程入口(smbd --version)。
口径边界:本文的"移植"指 11 个补丁在目标平台保持上游语义(每个补丁逐条注明"上游平台行为不变"),不是"移植上游测试断言"。
4.3 私有 API 分类留证
不适用:消费者用例只使用公开 API(wbclient.h 位于 include/,链接 libwbclient);本适配不存在"以非导出符号为断言对象"的场景,无需 nm -D 留证。同时说明为什么不链接内部静态库:消费者编译只链接公开库 libwbclient + 全图依赖 rpath,不引用 libsmbd 等内部符号——保持消费者与最终用户同视角。
4.4 消费者测试
L2(真实 API + 结果断言):conftest.c 调用 libwbclient 公开 API 做 SID 字符串↔二进制往返 + 字段断言(纯字符串解析,无需 winbindd 守护进程):
/* samba 4.21.0 消费者用例:调用 libwbclient 公开 API。
* 使用包内安装的公开头 wbclient.h:
* - wbcStringToSid / wbcSidToString:SID 字符串 <-> 二进制互转;
* - wbcFreeMemory:释放 wbcSidToString 分配的内存。
* 纯字符串解析,无需 winbindd 守护进程。编译、链接、运行三步验证。
*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "wbclient.h"
int main(void)
{
struct wbcDomainSid sid;
char *sid_string = NULL;
if (!WBC_ERROR_IS_OK(wbcStringToSid("S-1-5-21-1111111111-2222222222-3333333333-1001", &sid))) {
printf("FAIL wbcStringToSid\n");
return 1;
}
if (sid.sid_rev_num != 1 || sid.num_auths != 5) {
printf("FAIL SID fields\n");
return 2;
}
if (!WBC_ERROR_IS_OK(wbcSidToString(&sid, &sid_string))) {
printf("FAIL wbcSidToString\n");
return 3;
}
if (strcmp(sid_string, "S-1-5-21-1111111111-2222222222-3333333333-1001") != 0) {
printf("FAIL SID roundtrip mismatch: %s\n", sid_string);
return 4;
}
printf("wbclient_sid_roundtrip_ok v%s\n", sid_string);
wbcFreeMemory(sid_string);
return 0;
}
编译 + 链接(test_package 实测 RUN 行,路径缩写为 ):
clang conftest.c -o conftest -I<pkg>/include -L<pkg>/lib \
-Wl,-rpath,<pkg>/lib:<pkg>/lib/private:<gnutls>:<libtasn1>:<libgcrypt>:<libgpg-error> -lwbclient
实测运行输出:
wbclient_sid_roundtrip_ok vS-1-5-21-1111111111-2222222222-3333333333-1001
L1(版本断言):核心守护进程入口 smbd --version,实测输出 Version 4.21.0。声明:L1 版本断言只证明"制品可运行、版本正确",不能宣称文件共享功能完成。
消费者结果:2/2 通过(L2 断言 + L1 入口)。

图2:CI 制品包 smbd --version 真机实测输出(Version 4.21.0),证明制品可运行;L1 版本断言不宣称文件共享功能完成。
4.5 产物核验
| 变体 | 构建任务 | 关键产物 | 性质 |
|---|---|---|---|
| 默认(CI/制品) | 3571/3571 | Package ‘74581ffb898c8c9f493b2b8ed3c5313d3ae9f8d3’ created;产物树 bin/lib/include/etc/libexec/sbin/private/bind-dns(含 smbd/smbclient 可执行) | 发布制品 |
| selftest(本地证据) | 4192/4192 | 含 86 个 python 扩展 .so(bin/python/samba/ 构成完整 samba 包);R9 真门禁生效(SELFTEST_EXIT=255 → ConanException Error 255,create 按预期失败,不强制通过) | 本地证据,非发布 |
双变体设计:默认变体不含 wrapper/libarchive/python 绑定,对发布产物零影响(回归门禁验证:补强 commit 后回归实测 3571/3571 + 消费者 2/2);selftest 变体仅本地跑证据,CI 不承载。构建耗时未逐条记录,不写入本文。
制品仓状态(2026-09-28,CI 制品):samba/4.21.0 recipe 修订 4e28db950e4888397419c587a35abf52;package 4c8805498accdb9210dbaad20a4af452de3881f6(armv8/Release/clang15/cppstd17/libc++/OHOS 6.0,shared=True,with_selftest=False)。
4.6 CI 与评审(完整轮次)
CI 轮次表:
| 轮次 | 时间(+08) | 触发 | CI 构建号 | 结果 | 说明 |
|---|---|---|---|---|---|
| R0 | 09-20 22:55 | /rebuild(PR 创建后首次) | #53939 | ❌ 失败 | 基础设施故障:Worker 网络不可达 download.samba.org(源码下载超时;已知可达 zlib.net、不可达 ftp.gnu.org)→ 作废轮;conandata 源随后切 GitHub tag |
| R1 | 09-21 06:03 | 自动(源切换后) | #54072 | ✅ 通过 | test_package 通过,L0/L1 门禁通过 |
| R2 | 09-21 15:56 | /rebuild(评审 A1 后) | #54889(队列另有 #57538 记录)+ 09-23 两次 /rebuild | 无结论评论 | 评论流未见该轮通过/失败结论,被后续轮次覆盖 |
| R3 | 09-24 20:49 | /rebuild | #59992 | ✅ 通过 | Worker CI-006;test_package/L0/L1 全过 |
| R4 | 09-26 17:40 | /rebuild(补强 commit 418894d71a 后) | #61896 | ✅ 通过 | Worker CI-015 |
| R5 | 09-27 14:42 | /rebuild(正文 N=2685 修正后) | #62719 | ✅ 通过 | Worker CI-035;此后 09-28 合入 |
评审轮次表(pc-pr-review 自动化评审):
| 轮次 | 时间(+08) | 裁决 | FAIL 项与修复动作 |
|---|---|---|---|
| A1 | 09-21 13:03 | ❌ FAIL | rule4(实测 N=133 > 声明 N=5)+ rule6(AI 检视未覆盖 01:29 新提交)→ 补统计表合计行与声明 N、重触发 AI 检视 |
| A2 | 09-21 15:35 | ❌ FAIL | rule1(统计表缺合计行)+ rule6 + rule7(最新提交 15:31 晚于 CI 结论 06:03)→ /ai review force + /rebuild |
| A3 | 09-27 11:11 | ❌ FAIL | 仅 rule4(实测 N=154 > 声明 N=133),其余 12 条 PASS → 声明 N 改为可复现实测值 2685、正文 8 处更新、/rebuild #62719 |
| 合入 | 09-28 18:36 | ✅ merged | 维护者 ningyu405 合入;approval approvers=2、testers=2;ci_state_passed=true;head 418894d71a → main b95978a475 |
AI 检视:共 6 次触发(P0/P1=0)。
合并记录:PR #11515 于 2026-09-28由维护者合入 main;关联 Issue #3179(评审过程中的口径修正补记见该 Issue 评论)

图3:PR #11515 合入页(2026-09-28 merged)
4.7 复现速查
三条命令,全部 2026-10-06 现场实测通过(①③ 为远端制品链路,② 为本地证据链路):
① 全量构建 + 消费者测试(约需完整构建时间;CWD 为配方目录):
cd /storage/Users/currentUser/ohpc-contest/samba-4.21.0/build_in_harmonyos/archives/s/samba/4.21.0
conan create . -pr:h=ci/conan/profiles/ohos-aarch64 -pr:b=ci/conan/profiles/ohos-aarch64
期望输出(节选,与实测日志一致):[3571/3571] 全过 → Package '<id>' created → test_package wbclient_sid_roundtrip_ok vS-1-5-21-... 与 Version 4.21.0。
② 上游证据链复跑(testlist 块级计数,秒级):
B=/storage/Users/currentUser/.conan2/p/b/samba4c88c0cb57935/b
cd $B
export PYTHONPATH=$B/bin/python:$B/python:$B/source4/selftest:$B/selftest
export PERL=/storage/Users/currentUser/.conan2/p/perlbad96edf51f7f/p/bin/perl
/storage/Users/currentUser/usr/local/bin/python3 selftest/tests.py 2>/dev/null | grep -cE '^-- TEST(-LOADLIST)? --$'
/storage/Users/currentUser/usr/local/bin/python3 source3/selftest/tests.py 2>/dev/null | grep -cE '^-- TEST(-LOADLIST)? --$'
/storage/Users/currentUser/usr/local/bin/python3 source4/selftest/tests.py 2>/dev/null | grep -cE '^-- TEST(-LOADLIST)? --$'
期望输出:141 / 1227 / 1317(合计 2685;计数格式与上游 selftest.pl read_testlist 一致)。
③ 制品核验(CI 制品包真机运行,秒级):
conan download "samba/4.21.0:4c8805498accdb9210dbaad20a4af452de3881f6" -r=ohpcd
P=$(conan cache path "samba/4.21.0:4c8805498accdb9210dbaad20a4af452de3881f6")
LIBS=$(find /storage/Users/currentUser/.conan2/p -maxdepth 4 -type d -name lib | tr '\n' ':')
LD_LIBRARY_PATH="$P/lib:$P/lib/private:$LIBS" "$P/sbin/smbd" --version
期望输出:Version 4.21.0。
口径对应:命令 1 → 4.5(3571/3571、消费者 2/2);命令 2 → 4.1(141+1227+1317=2685 声明值);命令 3 → 4.4(smbd --version 实测)。三条命令分别复现 4.5 的构建/消费者结果、4.1 的声明 N、4.4 的制品可运行性,与正文数字一一对应——读者可以逐条照抄验证本文每一个关键数字。
五、知识沉淀
声明:本 PR 未提交独立知识草稿;本适配的知识沉淀在配方 manifest.yaml 的 knowledge_gained 6 条 + notes.md 全程记录中,随 PR 入仓:
| # | 知识 | 来源坑位 | 复用价值 |
|---|---|---|---|
| K1 | waf mkstemp 探针要求 mode 恰为 0600,restrictive umask 下真实安全文件被误判;放宽为"属主可读写且组/其他无写权限" | 坑一(0001) | 其他 waf 项目的探针类补丁 |
| K2 | waf 生成的可执行文件需 chmod +x,缺执行位导致 configure 失败 | 早期构建迭代 | waf 项目通用 |
| K3 | GnuTLS/zlib 是 waf configure 强制依赖,需 conan 注入 PKG_CONFIG_PATH | 侦察阶段 | waf + conan 组合通用 |
| K4 | OHOS HAP 沙箱下全量 selftest 判"环境受限"的四层实测方法(能力集/策略层逐层取证,/proc/self/status 实证) | 4.1 四层实测 | 任何"全量测试不可运行"场景的归因流程 |
| K5 | waf python 交叉编译环境变量旁路(PYTHON_VERSION/PYTAG/pyext_PATTERN/PYTHON_PY*FLAGS),避开 python3-config 输出 -lintl -ldl(musl 无 libintl) | selftest 设计 | musl/OHOS 上一切 python embedding 构建 |
| K6 | 构建树 python 全量复制到 bin/python/samba/ 并同置 86 个扩展 .so 构成完整包;PYTHONPATH 必须 bin/python 置前(源码 python/ 包胜出但无 .so → samba.param ModuleNotFoundError) | selftest 设计 | 构建树内 python 包路径优先级问题 |
边界说明:同生态 tdb/1.4.15 适配曾贡献两条 waf 相关草稿(testonly 执行口径、waf-samba standalone 构建策略),触发实例为 tdb 而非本 PR,本文不冒领为本 PR 产出。
六、FAQ
Q1:上游 selftest 0 通过,PR 为什么能合入?这算"通过"吗?
本文没有宣称上游 selftest 通过。四层实跑全部卡在测试环境 provisioning(设备策略层/能力集),0 项属于构建适配层失败;CI 的职责是默认变体构建 + 消费者 2/2(全部通过),全量 selftest 走本地证据变体(with_selftest),结论按 R51 两段式如实回填 PR。评审通过判的是"如实申报 + 不假通过 + 构建与消费者真实全绿",不是"全量 selftest 通过"——后者在这台设备的环境约束下物理不可达(root 的 socket() 创建都被策略层封锁)。
Q2:11 个补丁动核心逻辑吗?影响上游行为吗?
全部是构建系统层(wscript / wscript_build / 头文件守卫 / python 脚本)的探测、守卫、门控,0 处平台宏(OHOS);每个补丁的描述都逐条注明"有 X 的上游平台行为不变"。核心 C 逻辑(smbd/librpc/协议栈)一行未改。分类:6 个探测/守卫型 + 5 个门控/防御型。
Q3:2710 和 2685 什么关系?数字怎么越修越小?
最初 09-26 复测记录 source4 为 1342(合计 2710);09-27 在同构建树复测为 1317(合计 2685)。10-06 对两份原始日志做块级 diff:差值恰好是 25 个 pidl.* TEST 块(pidl.cutil、pidl.dump、pidl.header、pidl.ndr、…、pidl.wireshark-ndr,完整清单见 diff 日志),0 个新增——PIDL 编译器自测套件的规划输出在两次运行间有漂移。PR 声明值取可复现的下界 2685:评审方两轮静态清点(133/154)均 ≤ 2685,声明值覆盖全部已观测口径。证据三重:三份日志全量 sha256 + 4.7② 复现命令 + 25 套件 diff,PR 正文与 Issue 均已如实披露漂移。
Q4:3571 和 4192 能相加吗?
不能。3571 是默认变体(CI/制品,–disable-python --without-libarchive)的 waf 任务数,4192 是 selftest 变体(本地证据,启用 python 绑定 + 5 wrapper + libarchive)的任务数;两者是同一源码两次独立构建,差值 621 主要是 86 个 python 扩展模块与 selftest 相关任务,不是子集关系,本文分层陈述、不加和。
Q5:为什么 CI 不跑全量 selftest?
全量 selftest 需要的运行环境(root + 完整能力集 + 无策略层拦截)在这台设备不可达,CI Worker 同理。CI 承载默认变体(构建 + 消费者),全量 selftest 作本地证据、结论如实申报——"跑不起来的测试不申报为通过"是本文(也是 R51 红线)的底线。
Q6:消费者 2/2 能证明 Samba 可用吗?
不能。消费者只验证公开 API(libwbclient SID 往返)与守护进程入口(smbd --version),证明"制品构建、链接、加载正确,入口可运行";文件共享/打印功能需要真实 SMB 客户端-服务端环境,与 selftest 被同一策略层阻塞,未验证。本文的边界声明限定在"构建 + 入口"层面。
七、总结
7.1 量化盘点
| 维度 | 数字 |
|---|---|
| 补丁 | 11 个(0 处平台宏;6 探测/守卫型 + 5 门控/防御型) |
| 差异点(第二节表) | 15 项(10 项补丁处理、2 项非补丁方案、3 项环境受限) |
| 非补丁方案 | .pc shim(bundled wrapper 旁路)+ python_cross_compile 环境变量旁路 |
| 构建任务 | 默认变体 3571/3571;selftest 变体 4192/4192(含 86 个 python 扩展 .so) |
| 上游 testlist 规划 | 2685(141+1227+1317,块级计数);selftest.pl 计划 1084(2685 的子集) |
| 上游实跑 | 四层实测 0 通过(0 构建适配失败;三分类:环境受限/运行环境项/上游 bug L896) |
| 消费者用例 | 2/2(L2 libwbclient 断言 + L1 smbd --version) |
| CI 轮次 | 5 轮(4 通过 + 1 基础设施作废);AI 检视 6 次(5 次 P0/P1=0) |
| 评审 | 3 轮 FAIL(均 rule 口径问题)→ 维护者 2026-09-28 合入 |
| 知识沉淀 | manifest knowledge_gained 6 条 + notes.md 全程记录 |
7.2 可复用方法
- 探测式补丁范式:让工具链的真实链接/探针结果决定 define,不用平台宏(坑一~坑四)——可迁移到任何私有构建系统的跨平台适配。
- 符号级版本门控放宽:nm 实证目标版本符号覆盖 + 确认消费协议不依赖高版本符号,才敢降 minversion(坑五)。
- .pc shim 旁路:制品仓包 .pc 指向发布者机器路径时,配方在 generators_folder 写本地 shim 覆盖,让纯 pkg-config 探测命中系统包、跳过 bundled 编译——"bundled vs 系统"决策的通用解法。
- R9 真门禁:测试执行走真实退出码传播(exit $ec),不强制通过——跑不起来就是跑不起来,结论如实回填。
- 四层实测归因法:非 root 手工 / 非 root 配方 / root 预检 / root 直跑,每层记录精确卡点 + 能力集/策略层证据(/proc/self/status),把"跑不起来"归到环境层而非适配层。
- testlist 块级复数:声明的测试 N 用可复现命令计数(
^-- TEST(-LOADLIST)? --$)+ 日志哈希背书,让 N 可审计、可重跑。
7.3 流程 checklist(通用)
- 预检判定先复核是否误判(setup.cfg ≠ 打包 manifest;waf/C 项目可能被误判 env_unsupported)
- 依赖逐项 conan download --only-recipe 核验发布状态
- 探针类代码一律"真实结果决定",不写平台宏
- 版本门限放宽前做符号级实证(nm)
- 可选功能整体跳过时,下游变量逐个判空
- 区分构建期硬依赖与运行时 import
- 测试执行用真门禁(退出码传播),不强制通过
- 跑不起来时逐层实测归因(能力集/策略层/工具链语义/上游 bug)
- 声明测试数用可复现口径 + 日志哈希背书
- CI 制品与本地证据变体分离(option 隔离 + 回归门禁)
7.4 后续工作(诚实边界)
- selftest.pl L896 上游 perl 崩溃(getlog_env on undefined,仅环境未定义时触发)可向上游报 issue——上游 CI 正常路径不受影响。
- 设备策略层 socket() 创建封锁是设备级约束;全量 selftest 在特权容器/开发板上下文才有运行意义,不在本适配范围内。
- 批次二补丁(0006-0011)为 09-26 diff -u 生成,上游版本更新时需按 refresh-patch 流程重生成。
参考链接
- PR:https://atomgit.com/OpenHarmonyPCDeveloper/build_in_harmonyos/merge_requests/11515
- 关联 Issue:https://atomgit.com/OpenHarmonyPCDeveloper/build_in_harmonyos/issues/3179
- 配方仓库:https://atomgit.com/OpenHarmonyPCDeveloper/build_in_harmonyos(archives/s/samba/4.21.0/)
- 上游源码:https://github.com/samba-team/samba (tag samba-4.21.0)
- 官方发布源:https://download.samba.org/pub/samba/stable/samba-4.21.0.tar.gz (国内可达,截至发稿实测 200)
- 社区:https://harmonypc.csdn.net/ | https://atomgit.com/OpenHarmonyPCDeveloper
更多推荐



所有评论(0)