// dump dbus
int dump_dbus_socket(int fd, SkOptsEntry *skopts)
{
int ret = 0;
ret |= dump_opt(fd, SOL_SOCKET, SO_REUSEADDR, &skopts->reuseaddr);
ret |= dump_opt(fd, SOL_SOCKET, SO_REUSEPORT, &skopts->reuseport);
ret |= dump_opt(fd, SOL_SOCKET, SO_KEEPALIVE, &skopts->keepalive);
return ret;
}
int restore_dbus_socket(int sk, SkOptsEntry *skopts)
{
int ret = 0;
if (skopts->has_reuseaddr)
ret |= restore_opt(sk, SOL_SOCKET, SO_REUSEADDR, &skopts->reuseaddr);
if (skopts->has_reuseport)
ret |= restore_opt(sk, SOL_SOCKET, SO_REUSEPORT, &skopts->reuseport);
if (skopts->has_keepalive)
ret |= restore_opt(sk, SOL_SOCKET, SO_KEEPALIVE, &skopts->keepalive);
return ret;
}
基于CRIU技术实现dbus服务的冻结与恢复
提交的文件位于
提交
目录下,以下内容为项目功能说明书的拷贝项目功能说明书
kubectl get pods
to see pods are in a ready state团队信息
学校:湖南大学
参赛队伍:风在山路吹过往的画面全都是我不队
队伍成员:刘昊鹏、林星彤、李平凡
指导教师:谢鲲
完成日期:2024年8月
项目结构
技术理论
比赛过程中遇到的问题都尽量团队自己解决,因此每一步都走的十分艰难,期间搞坏了多次服务器。经过不断的摸索,探索出一套可能可行的方案,但目前未能完整实现。
在添加dump和restore dbus连接的socket选项后:
restore后的dbus服务仍然不具备有效的连接:
此时dbus维护的connection已遭到破坏,为了完成dump dubs服务,仅仅dump socket连接远不能达到目标,所以也需要将dbus连接的一些必要信息进行存储。
DBus支持
DBusConnection
每个dbus服务一定要有一个DBusConnection连接,这个结构体中储存了该连接几乎所有的信息。经过对dbus源码和文档的阅读,未能发现 dbus 中心服务中储存了DBusConnection的信息。所以,应该是要从被dump的dbus进程本身获取DBusConnection。 dbus当前没有获取DBusConnection的接口,所以我们自己实现,方便起见采用了保存DBusConnection指针的地址的方式储存和获取DBusConnection。
criu支持
criu支持向被dump的进程本身注入代码,用于收集进程的一些信息。因此我们首先考虑在注入的代码里收集DBusConnection的信息。
criu/criu/pie/parasite.c
经过实验,注入的代码里仅能调用一些指定的系统调用,无法加载一些自定义的动态库。
代码原创说明
programs中的代码为用于测试的dbus的程序,参考的是网络上的代码片段
src中为criu和dbus的源码,我们的软件在此基础上开发。
scripts中原创的脚本代码.
软件介绍
在 openkylin中编译dbus,需要将Kysec设置为Softmode,否则会编译失败
编译dbus时指定前缀
使用自编译的dbus服务
软件测试
虽然没能完成题目的要求,但是基于这套框架进行了一个伪实现。
正常的method服务
dump
dump脚本输出一个inode,用于restore,dump后method失效:
restore
restore之后,右边重新可以调用dbus的method
方法是在criu的restore代码中插入一段重新建立相同连接的代码:
总结
从一开始信心满满选择这个具有挑战性的题目,到不断受挫,我们遇到了很多困难,最终才对这个题目和dbus、criu具有全面些的了解,但很遗憾最终无法完成全部的开发。为了弥补遗憾,最终针对一个特定的dbus程序的restore做了伪实现。
我们最终摸索出一套可能可行的方案,在注入的代码里收集dbus connection结构体的信息,但是注入的代码对可以调用的函数库有非常严格的限制,最终止步于此。
另外,可以从dbus的角度在daemon里保存没一个连接,则可以在connection的进程外获取其他进程的连接信息,这种方案会为每一个连接分配一块内存,造成资源浪费。
总之,在比赛的过程中,有很多的思考,学习了很多知识,比赛结束后希望能从别的队伍那里学习到更好的解决方案。
参考
Link
Interface DBus
https://dbus.freedesktop.org/doc/api/html/dbus-connection_8h_source.html
https://dbus.freedesktop.org/doc/api/html/modules.html
Introduction to CRIU and Live Migration
DBus API的使用
https://man.archlinux.org/man/criu.8.en
https://criu.org/Main_Page
https://blog.csdn.net/f110300641/article/details/106823611
Criu入门
https://blog.csdn.net/weixin_38669561/article/details/98183545
https://blog.csdn.net/chao2016/article/details/82587503
https://blog.csdn.net/o0xgw0o/article/details/124497819
https://cloud.tencent.com/developer/article/1159496
https://qytz-notes.readthedocs.io/tech/dbus/dbus.html
https://blog.csdn.net/ZengYinning/article/details/128188252
Paper
Love R. Get on the D-BUS[J]. Linux Journal, 2005, 2005(130): 3.
Tošić A. Run-time application migration using checkpoint/restore in userspace[J]. arXiv preprint arXiv:2307.12113, 2023.
原readme
作品完成和提交方式:选择本赛题的参赛队伍需要首先复刻(Fork)本项目,然后在复刻的项目中添加参赛队员、合作完成作品开发即可,无需提交PR到赛题项目。如果作品为文档形式,也请将作品文档提交到项目代码库中。在作品完成过程中,围绕作品的相关讨论等可以以疑修(Issue)形式发布和讨论,也可使用里程碑对整个任务进行规划管理。
1. 赛题说明
基于CRIU技术(Checkpoint/Restore In Userspace),实现dbus服务的冻结、恢复功能。在冻结时,保存该dbus服务上下文位置关系,进程以CRIU固有形式或其他状态冻结于系统磁盘上;在恢复后,dbus服务可基于原流程继续执行。
2. 赛题要求
1)dbus服务类型为SYSTEM BUS,可自己新建或利用系统原有的dbus服务组件,dbus服务需具备method及signal。 2)在dbus服务被冻结、恢复后,其他dbus服务可接收到dbus-daemon发出的对应操作信号,表明该服务进入冻结状态,退出冻结状态。 3)在dbus服务被冻结时,对该服务的访问需有报错提示,当恢复后,访问可正常进行。 4)dbus服务在恢复后与冻结前的程序上下文位置保持一致。 5)支持在系统重启后的进程正常恢复功能。 6)额外功能:支持同架构下跨设备的冻结与恢复。 7)支持基于wayland图形化应用的冻结与恢复。 8)进程恢复耗时需远优于直接启动该进程耗时。
3. 赛题导师
zhangtingting@kylinos.cn
4. 参考资料
1)https://man.archlinux.org/man/criu.8.en 2)https://criu.org/Main_Page