如何在Linux中“hibernate”一个进程,将其内存储存到磁盘并在以后恢复?
是否有可能在Linuxhibernate一个进程? 就像笔记本上的“hibernate”一样,我会把进程使用的所有内存写入磁盘,释放内存。 然后,我可以“恢复过程”,即从内存中读取所有数据并将其放回内存,然后继续执行过程?
我曾经保持CryoPID ,这是一个程序,正是你所说的。 它将程序的地址空间,VDSO,文件描述符引用和状态的内容写入到稍后可以重build的文件中。 CryoPID在Linux本身没有可用的钩子的情况下启动,完全从用户空间运行(实际上,根据你的发行版/内核/安全设置,它仍然可以工作)。
问题是(确实)套接字,等待RT信号,许多X11问题,glibccachinggetpid()实现等等。 随机化(特别是VDSO)在Bernard离开之后对我们中的less数人来说是不可逾越的。 然而,这很有趣,成了几位硕士论文的主题。
如果您只是在考虑一个可以保存其运行状态并直接重新启动到该状态的程序,那么它远远…更容易从程序本身保存信息,或许在维修信号时。
我想在这里提供一个状态更新,截至2014年。
被接受的答案build议将CryoPID作为执行检查点/恢复的工具,但是我发现这个项目是无意识的,不可能用最近的内核来编译。 现在,我发现了两个积极的项目提供应用程序检查点function。
第一,我build议的原因是我运行得更好,是主要在用户空间执行检查点/恢复的CRIU ,并要求启用内核选项CONFIG_CHECKPOINT_RESTORE才能工作。
Checkpoint / Restore In Userspace或CRIU(发音为kree-oo,IPA:/krɪʊ/,俄语:криу)是Linux操作系统的一个软件工具。 使用此工具,可以冻结正在运行的应用程序(或其中的一部分),并将其作为文件集合检查到硬盘驱动器。 然后,您可以使用这些文件从冻结点恢复并运行应用程序。 CRIU项目的显着特点是主要在用户空间实施。
后者是DMTCP ; 从他们的主页引用:
DMTCP(分布式multithreading检查点)是一种透明地检查多个同时应用程序(包括multithreading和分布式应用程序)状态的工具。 它直接在用户二进制可执行文件上运行,没有任何Linux内核模块或其他内核修改。
在参数上还有一个很好的维基百科页面: Application_checkpointing
提到ctrl-z
的答案确实是在谈论用信号停止进程,在这种情况下是SIGTSTP
。 你可以用kill
来发出一个停止信号:
kill -STOP <pid>
这将暂停执行进程。 它不会立即释放它所使用的内存,但是由于其他进程需要内存,被停止进程所使用的内存将逐渐被换出。
当你想再次唤醒时,使用
kill -CONT <pid>
像CryoPID这样更复杂的解决scheme,只有当你希望被停止的进程能够在系统关机/重启时能够存活下来,这种解决scheme才是真正需要的 – 听起来你并不需要。
问题是恢复程序已打开的stream – 文件和套接字。
当你的整个操作系统hibernate,本地文件等显然可以恢复。 networking连接不是,但是访问互联网的代码通常是更多的错误检查,并且在错误条件下(或者应该)仍然存在。
如果您按程序hibernate(没有应用程序支持),您将如何处理打开的文件? 如果另一个进程在临时访问这些文件呢? 等等?
程序未加载时保持状态将变得困难。
简单地挂起线程并让它交换到磁盘会有很多相同的效果?
或者在虚拟机上运行程序,让虚拟机处于暂停状态。
简短的答案是“是的,但并不总是可靠的”。 检查CryoPID:
打开文件确实是最常见的问题。 CryoPID明确指出:
打开的文件和偏移被恢复。 临时文件已经被取消链接,并且在文件系统上不可访问的文件始终保存在图像中。 恢复中不存在的其他文件尚未还原。 计划支持为这种情况保存文件内容。
同样的问题也会影响TCP连接,尽pipeCryoPID支持TCP连接恢复。
现在Linux内核部分实现了检查点/重启期货: https : //ckpt.wiki.kernel.org/ ,状态就在这里 。
一些有用的信息是在Linux(Linux周刊): http ://lwn.net/Articles/375855/ http://lwn.net/Articles/412749/ ……
所以答案是“是”
简短的回答是“是的”。 你可以先看看这个想法: ELF可执行的核心映像重构 ( http://vx.netlux.org/lib/vsc03.html )
我扩展了Cryopid,从SourceForge中生成一个名为Cryopid2的包。 这可以迁移一个进程并将其hibernate(以及任何打开的文件和套接字 – 套接字/pipe道中的数据在进程hibernate时被吸入到进程中,并在进程重新启动时进入这些进程)。
我没有积极参与这个项目的原因是我不是一个内核开发者 – 这个(和/或原始的cryopid)需要得到一个能够让他们运行最新内核的人(例如Linux 3.x) 。
Cryopid方法确实有效,并且可能是我在Linux中遇到的一般用途进程hibernate/迁移的最佳解决scheme。
正如其他人所指出的那样,操作系统很难提供这种function,因为应用程序需要内置错误检查来处理破坏的stream。
但是,请注意,一些使用虚拟机的编程语言和工具明确支持这种function,例如Self编程语言 。
在linux中有ctrl+z
,但我不确定它提供了你指定的function。 我怀疑你问这个问题,因为它没有
Ctrl-Z增加了进程页面被交换的机会,但是并没有完全释放进程的资源。 完全释放进程资源的问题是,文件句柄,套接字是进程可以使用的内核资源,但不知道如何自行保留。 所以Ctrl-Z就像它得到的一样好。
Linux在2.2和2.4天内对检查点/恢复进行了一些研究,但它从来没有使它成为过去的原型。 这是可能的(与其他答案中描述的警告)可能的某些值 – 我可以编写一个内核模块来做到这一点,这是可能的。 但是对于可能的共同价值(我可以从商业Linux发行版的shell中完成),这是不可能的。
这是集群操作系统的最终目标。 Mathew Dillon在他的Dragonfly BSD项目中付出了很多努力来实现这样的function。