团队中的小队
我们应该提到,我们最终在这个 sprint 中组成了三个小队
- Sockets & Services 小队,致力于正确支持 systemd sockets 以及其他与 systemd 相关的任务(当然,都在 YaST 的上下文中)。
- Qt and UI 小队,致力于用户界面相关的工作,例如向软件包选择界面添加一个新视图,以显示由服务管理的软件包,以及一些控制中心改进。
- Bug Fighting 小队,处理每天涌入以及我们待办事项列表中的 bug。
修复了大于 8EiB 的磁盘问题
你家里不太可能有一个大于 8EiB(八 exbibytes,263)的磁盘存储。但在企业或云环境中,这可能是可能的。
事实证明,YaST 包管理器无法很好地处理如此大的磁盘。在开始时,你可能会看到这个错误的错误消息
问题
有两个问题
- 磁盘上肯定有很多可用空间,错误提示用户空间不足,只是在说谎。
- 磁盘大小显示为错误的负值。
事实证明,问题是由使用有符号 64 位整数数据类型引起的,该类型对于大于 8EiB 的值会溢出,并且数字变为负数。
修复
我们不得不修复几个地方,每个地方都需要不同的解决方案。
- 尽可能使用无符号 64 位整数,这显然可以避免溢出。
- libzypp 中的数字使用 KiB 单位,在某些地方我们需要将该数字转换为 MiB。但首先,我们将转换为纯字节(通过乘以 1024),然后除以 1MiB。而这个第一步乘法运算可能会导致溢出。相反,我们直接通过除以 1024 将 KiB 转换为 MiB,而无需在中间出现溢出风险。
- 使用浮点
double数据类型将值转换为人类可读的文本或百分比。double具有更宽的范围,并且在这些情况下我们不需要精确的精度,因此浮点运算中的舍入无关紧要。 - 忽略空闲空间检查中的负数。在某个地方,该值通过 YaST 组件系统,该系统使用有符号整数,这很难更改。在这种情况下,我们将负的空闲空间视为足以安装任何软件包,超过 8EiB 的空闲空间应该足以安装任何软件包™。
大型数字仍然存在一些小问题。支持的最高单位是 TiB,因此即使是非常大的数字也以 TiB 单位显示,如上面的屏幕截图所示。该修复计划作为维护更新发布,并且此更改将破坏向后兼容性,因此我们将在以后改进它,但仅限于将来的版本。
测试
但是,如何测试这种行为是一个问题?你可以在代码中伪造一些数字,但为了进行全面测试或 QA 验证,最好在真实的磁盘上进行测试。但你通常没有这么大的存储用于测试…
幸运的是,在 Linux 中,可以使用 稀疏文件 和 loop 设备 相当容易地伪造如此大的文件系统。这是一个简短的教程
# create two big sparse files
truncate -s 6E /tmp/huge_file1
truncate -s 6E /tmp/huge_file2
# create block devices via loopback
losetup -f /tmp/huge_file1
losetup -f /tmp/huge_file2
# get the loop back device names, the names might be different
# if the system already uses some other loop back devices
losetup -a
/dev/loop1: [0056]:1171324 (/tmp/huge_file2)
/dev/loop0: [0056]:1171323 (/tmp/huge_file1)
# create a btrfs file system over both "disks"
mkfs.btrfs -K /dev/loop0 /dev/loop1
# mount it on /mnt2 (or whatever else, do not use /mnt, that is ignored by libzypp!)
mkdir /mnt2
mount /dev/loop0 /mnt2
# verify the size
df -h /mnt2
Filesystem Size Used Avail Use% Mounted on
/dev/loop0 12E 17M 12E 1% /mnt2
# voila! you have a 12EiB file system! enjoy
注意:显然,即使你有一个 12EiB 的文件系统,你也无法在下面的真实文件系统(在本例中为 /tmp)中保存更多数据。如果你尝试,你会得到写入错误,没有永动机…
加速 yast2-storage-ng 中的单元测试和 Travis 构建
新的 yast2-storage-ng 包具有相当大量的单元测试。这很好,它可以减少错误代码并确保功能按预期工作。
另一方面,缺点是运行测试需要太长时间。如果你必须在代码中的任何小更改后等待 3 或 4 分钟,那么你就会浪费太多时间,或者根本不运行测试。所以我们研究了如何加速测试。
并行运行测试
主要问题是所有测试都是按顺序一个接一个地执行的。即使你有一个多 CPU 系统,也只有一个处理器被使用。事实证明,使用 parallel_test Ruby gem 可以轻松地并行运行测试,从而利用所有可用的处理器。
唯一可能的问题是测试之间不能有任何依赖关系或冲突,否则并行运行测试将会失败。幸运的是,yast2-storage-ng 测试中只有一个小问题,我们可以毫不费力地启用并行测试。
并行运行 Travis 作业
Travis 作业也花费了相当多的时间。并行运行测试在 Travis 上有帮助,但仍然不够好。
幸运的是,Travis 允许并行运行多个作业。因此,我们将运行测试、构建包、运行语法检查等的单个 CI 作业拆分为三个独立的组,这些组可以并行启动。
文档
如果你对细节感兴趣,可以查看我们更新的 Travis 文档 和 并行测试文档。或者查看 公告 在 YaST 邮件列表中。
结果
这里有一些真实的数据来查看加速效果
- 本地运行测试套件 (
rake test:unit):从 2:44 到 0:38(在启用超线程的四核 CPU 上加速 4.3 倍) - 本地构建包 (
rake osc:build):从 137s 到 49s(使用缓存的 RPM 包,但包括 chroot 安装) - OBS 中的包构建:从 323s-505s 到 102s-235s(它高度依赖于所用工作者的速度)
- Travis 加速:从 8-10 分钟到 3-4 分钟(使用并行 Travis 作业和并行测试)
这使我们能够继续向包中添加更多的测试。 ![]()
产品扩展/模块提供的软件包是什么?
在软件管理模块中,我们有一个“存储库”视图,你可以在其中查看按提供它们的存储库分组的软件包。但这对于查看产品扩展或模块提供的软件包没有太大帮助,因为每个产品模块由多个存储库组成:最初发布的软件包、更新、源代码、调试信息。
幸运的是,每个产品模块的存储库都组合在一个存储库服务中,并且我们已向软件管理添加了一个服务过滤器。
Qt 服务过滤器
ncurses 服务过滤器
(参考:Feature #320573)



