0

这是一个通用的设计/编程问题。

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

该产品基本上有两个运行 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 版本,但我可以稍后处理。

4

1 回答 1

0

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

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

最有可能的是,无论发行版是什么,默认情况下,包管理器都会做一些变化(减去重新启动 S1),因此您可能需要考虑创建一个包并简单地使用默认升级机制。

于 2013-06-28T09:57:27.010 回答