设计自我升级策略

时间:2013-06-28 05:08:43

标签: windows unix coding-style

这是一般设计/编程问题。

我有责任为我们的产品设计升级策略。该产品在远程设备上运行,无需用户交互。所以我们必须远程实现一切。

该产品基本上有两个运行S1和S2的守护进程/服务。 S2完成所有工作,S1监督S2。 S1会定期检查S2,如果没有运行等,则重新启动它。

现在我需要在S1中编写自我升级功能。 S1必须检查服务器,如果有可用的升级,则必须下载它(让我们称之为upgradeFile)并执行它。

在执行upgradeFile之前,S1将停止S2。

upgradeFile,当它执行时,将尝试用它携带的新版本替换S1-disk-executable-file和S2-disk-executable-file。

执行upgradeFile完成后,S1将重启S2。

现在我非常担心在S1运行时我正在替换S1磁盘可执行文件。由于加载器和VM的所有复杂性,我不确定这是否是一个好策略。

我查过互联网论坛,书籍,但我还没有找到任何文章谈论这个。我甚至不知道我是否将这个问题放在正确的论坛中。

我目前正在Linux Mint 14和Qt 4.8上编程。我们还在为Android开发新版本。

编辑:   该产品在运行Linux Mint的远程专用硬件上运行。我们没有Windows版本。我们目前正在开发Android版本,但我可以稍后处理。

1 个答案:

答案 0 :(得分:0)

在Unix系统中,如果替换可执行文件而不是覆盖它,则没有问题。一个好的策略是:

  • 在与原始文件系统相同的文件系统中的临时文件中准备新的S1可执行文件,例如/usr/bin/S1.upgrade
  • /usr/bin/S1.upgrade重命名为/usr/bin/S1。此时,当前S1进程仍然指向旧的S1 i节点。因此,如果发生页面错误,仍然没有释放磁盘空间,并且仍然可以从旧的可执行文件加载需求。
  • 重新执行S1(例如,execvp(argv[0], argv)),使得正在运行的进程升级到新的可执行文件。现在,旧的索引节点未被引用,旧文件实际上已删除。

最有可能的是,无论分发是什么,软件包管理器默认会对此进行一些变更(减去重新启动S1),因此您可能需要考虑创建一个软件包并使用默认的升级机制。