>  기사  >  백엔드 개발  >  Go에서 마운트 네임스페이스를 입력할 때 발생하는 \"EINVAL\" 오류를 어떻게 해결하나요?

Go에서 마운트 네임스페이스를 입력할 때 발생하는 \"EINVAL\" 오류를 어떻게 해결하나요?

Susan Sarandon
Susan Sarandon원래의
2024-11-02 08:54:02587검색

How to resolve the

Go에서 마운트 네임스페이스 입력

문제:

Go에서 setns 호출은 EINVAL(잘못된 인수)을 반환합니다. 컨테이너에 대한 마운트 네임스페이스를 입력하려고 할 때.

설명:

setns를 사용하여 네임스페이스를 입력하려면 먼저 단일 스레드 컨텍스트에서 호출을 수행해야 합니다. Go 런타임 스레드가 시작됩니다.

해결책:

이 문제에 대한 두 가지 접근 방식이 있습니다.

1. 생성자 트릭 사용:

  • Go가 시작되기 전에 setns를 호출하는 C 함수에 __attribute__((constructor)) 매크로를 추가하세요.
  • 수정된 Go 코드:
<code class="go">/*
#include <sched.h>
#include <stdio.h>
#include <fcntl.h>

__attribute__((constructor)) void enter_namespace(void) {
   setns(open("/proc/<PID>/ns/mnt", O_RDONLY, 0644), 0);
}
*/
import "C"</code>

2. syscall.RawSyscall 사용:

  • Go 런타임 스레드를 시작하기 전에 기본 스레드에서 setns 호출이 이루어졌는지 확인하세요.
  • runtime.LockOSThread를 사용하여 기본 스레드를 잠그세요. 필요한 경우.
<code class="go">package main

import (
    "fmt"
    "os"
    "path/filepath"
    "syscall"
    "runtime"
)

func main() {
    if syscall.Geteuid() != 0 {
        fmt.Println("abort: you want to run this as root")
        os.Exit(1)
    }

    if len(os.Args) != 2 {
        fmt.Println("abort: you must provide a PID as the sole argument")
        os.Exit(2)
    }

    // Lock the main thread to the OS thread
    runtime.LockOSThread()

    namespaces := []string{"ipc", "uts", "net", "pid", "mnt"}

    for i := range namespaces {
        fd, _ := syscall.Open(filepath.Join("/proc", os.Args[1], "ns", namespaces[i]), syscall.O_RDONLY, 0644)
        err, _, msg := syscall.RawSyscall(308, uintptr(fd), 0, 0) // 308 == setns

        if err != 0 {
            fmt.Println("setns on", namespaces[i], "namespace failed:", msg)
        } else {
            fmt.Println("setns on", namespaces[i], "namespace succeeded")
        }

    }
}</code>

참고:

  • /proc/sys/kernel/namespaces_allowed를 확인하여 커널이 여러 네임스페이스를 지원하는지 확인하세요.
  • 문서에 인용된 커널 패치는 프로세스의 대상 마운트 네임스페이스에 CAP_SYS_ADMIN이 있어야 함을 지정합니다. setns를 호출하기 전에 이러한 조건이 충족되는지 확인하세요.

위 내용은 Go에서 마운트 네임스페이스를 입력할 때 발생하는 \"EINVAL\" 오류를 어떻게 해결하나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.