Golang在CentOS中将文件挂载为只读模式的方法

Golang在CentOS中将文件挂载为只读模式的方法 你好,

我正在尝试在我的 CentOS 7 服务器上挂载一个文件。

这是我的代码:

syscall.Mount(src, dst, "auto", syscall.MS_BIND, "ro")

问题是文件被挂载了,但不是以只读方式,而是以读写方式挂载的。

cat /etc/mtab | grep "firewall"
/dev/vda1 /root/firewall.txt ext4 rw,relatime,data=ordered,jqfmt=vfsv1,usrjquota=quota.user 0 0

我希望以只读方式挂载该文件。


更多关于Golang在CentOS中将文件挂载为只读模式的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

有人知道吗?我们如何在 Linux 系统(CentOS)中将文件挂载为只读?

更多关于Golang在CentOS中将文件挂载为只读模式的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好,我想帮忙,但我对“挂载一个文件”有点困惑。我知道可以挂载一个文件系统,但挂载单个文件对我来说是新的。(虽然从你的 cat 输出中我能看到这是可行的。)

syscall.Mount() 是否返回了任何非 nil 的错误?

从 Go 的角度来看,你是否已经尝试过使用 golang.org/x/sys/unix 包而不是 syscall

syscall 包已被弃用并锁定,也许 syscall.Mount 中存在的某个错误在 unix.Mount 中已经修复了(这只是个猜测)。

另外,这个 Stack Overflow 帖子 表明“auto”与 syscall.Mount 配合得不好。也许可以尝试传递“ext4”代替。

在 CentOS 7 中使用 Go 挂载文件为只读模式时,需要正确组合挂载标志。syscall.MS_BIND 标志需要与 syscall.MS_RDONLY 标志一起使用才能实现只读绑定挂载。

以下是修正后的代码示例:

package main

import (
    "fmt"
    "syscall"
)

func main() {
    src := "/path/to/original/file.txt"
    dst := "/path/to/mount/point/file.txt"
    
    // 先进行普通挂载
    err := syscall.Mount(src, dst, "", syscall.MS_BIND, "")
    if err != nil {
        fmt.Printf("绑定挂载失败: %v\n", err)
        return
    }
    
    // 然后重新挂载为只读
    err = syscall.Mount("", dst, "", syscall.MS_REMOUNT|syscall.MS_BIND|syscall.MS_RDONLY, "")
    if err != nil {
        fmt.Printf("重新挂载为只读失败: %v\n", err)
        // 清理:卸载绑定挂载
        syscall.Unmount(dst, syscall.MNT_DETACH)
        return
    }
    
    fmt.Println("文件已成功挂载为只读模式")
}

或者使用单个系统调用,但需要正确的标志组合:

package main

import (
    "fmt"
    "syscall"
)

func main() {
    src := "/root/original/firewall.txt"
    dst := "/root/firewall.txt"
    
    // 直接使用 MS_BIND 和 MS_RDONLY 组合
    flags := syscall.MS_BIND | syscall.MS_RDONLY
    err := syscall.Mount(src, dst, "", uintptr(flags), "")
    
    if err != nil {
        fmt.Printf("挂载失败: %v\n", err)
        return
    }
    
    fmt.Println("文件已成功挂载为只读模式")
    
    // 验证挂载
    data, _ := syscall.Getfsstat(nil, syscall.MNT_NOWAIT)
    for _, stat := range data {
        if string(stat.Mntonname[:]) == dst {
            fmt.Printf("挂载点: %s, 标志: 0x%x\n", dst, stat.Flags)
        }
    }
}

对于需要更多控制的情况,可以使用 mount 系统调用直接操作:

package main

import (
    "fmt"
    "golang.org/x/sys/unix"
)

func main() {
    src := "/root/original/firewall.txt"
    dst := "/root/firewall.txt"
    
    // 使用 unix 包,它提供了更好的常量定义
    err := unix.Mount(src, dst, "", unix.MS_BIND|unix.MS_RDONLY, "")
    
    if err != nil {
        fmt.Printf("挂载失败: %v\n", err)
        return
    }
    
    fmt.Println("文件已成功挂载为只读模式")
    
    // 使用 mount 命令验证
    fmt.Println("运行命令验证: mount | grep firewall")
}

确保在运行代码前:

  1. 目标挂载点目录必须存在
  2. 源文件必须存在
  3. 程序需要以 root 权限运行

验证挂载是否成功:

# 检查挂载点
mount | grep firewall

# 或检查 /proc/mounts
cat /proc/mounts | grep firewall

# 尝试写入测试(应该失败)
echo "test" > /root/firewall.txt

如果仍然遇到问题,可能需要检查内核版本和文件系统类型,某些文件系统可能对绑定挂载的只读标志有特殊要求。

回到顶部