You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu 20.04 LTS下POSIX共享内存重启后留存且归root所有问题

重要通知

问题完全未解决,也并非由拼写错误导致。仅因部分用户无法复现(基于其本地测试环境),并不代表该问题在我的环境中不存在。我可稳定复现问题,仍在寻求解决方案或解释。

如需更多信息,请告知具体需要哪些内容。

演示视频

有演示该问题的短视频可供查看。


原问题

我使用POSIX共享内存在应用的多个实例间共享状态,通过shm_open()创建共享内存,ftruncate()扩展至所需大小,再通过mmap()映射到内存。同时使用sem_open()创建信号量,用于同步共享内存访问并确保首个实例完成初始化。

目前该流程运行正常,共享内存对象显示在/dev/shm/目录下,所有者和权限均符合预期。但在Linux(Ubuntu 20.04 LTS)中出现异常:重启后共享内存对象(及信号量)仍存在!据我所知,共享内存是易失性的,/dev/shm/是基于RAM的tmpfs文件系统,本不应在重启后留存。更糟的是,重启后共享内存的所有者从原用户变为root,导致重启后启动应用时shm_open()因权限拒绝失败!这说明系统关机时存在某种机制将共享内存持久化到磁盘,重启时恢复,但为何所有者会变更导致共享内存无法访问?

注:我在MacOS X和FreeBSD上测试未发现此问题。

我多次测试确认:重启前ls -al /dev/shm显示共享内存(及信号量)的原所有者,重启后则显示root为所有者,期间未运行应用。目前唯一解决办法是重启后执行sudo rm -f /dev/shm/*,但这绝非标准解决方案,Linux下该如何规范处理此问题?


我的代码如下:

static unsigned char *initialize(const int create_shmem)
{
    void *buffer = NULL;

    int fd = shm_open(OBJECT_NAME, create_shmem ? O_CREAT | O_EXCL | O_RDWR : O_RDONLY, 0644);
    if (fd < 0) {
        if ((!create_shmem) && (errno == ENOENT)) {
            return initialize(1);
        } else {
            return NULL;
        }
    }

    if (create_shmem) {
        if (ftruncate(fd, BUFFER_SIZE) != 0) {
            goto failure;
        }
    }

    buffer = mmap(NULL, BUFFER_SIZE, create_shmem ? PROT_READ | PROT_WRITE : PROT_READ, MAP_SHARED, fd, 0U);
    if (buffer == MAP_FAILED) {
        goto failure;
    }

    /* ... */
}

我知道可通过shm_unlink()在重启前显式删除共享内存,这或许能避免问题,但该方式不可靠!若应用因崩溃等原因未正常清理,重启后将留下无法访问的共享内存对象。


我发现systemd登录管理器有RemoveIPC配置项,可控制用户完全注销时删除其System V和POSIX IPC对象,但该设置对root用户的共享内存无效,且无法解释为何重启时所有者会从原用户变为root而非直接删除共享内存(删除的话普通用户可重新创建),目前也无删除root所有IPC对象的类似选项。


Linux是否提供每次开机或重启时递增的“启动计数器”?若有,我可将计数器附加到对象名称,规避root用户占用旧对象名称的问题。


我已创建systemd服务单元,在系统关机时执行脚本删除/dev/shm目录下所有内容。日志显示脚本已执行且确实删除了共享内存,但重启后/dev/shm中共享内存仍存在且归root所有!

我推测原因是:系统重启时将/dev/shm内容持久化到磁盘的操作,早于我的删除脚本执行。


内容的提问来源于stack exchange,提问作者Schraubstock1990

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:05:33