Rumah > Artikel > pembangunan bahagian belakang > Mengapa Memanggil `setns` daripada Go Mengembalikan `EINVAL` untuk Ruang Nama Mnt?
Panggilan setns dari Go Returns EINVAL untuk mnt Namespace
Perihalan Masalah
Kod Dalam Go , cuba memasukkan ruang nama mnt menggunakan fungsi syscall.RawSyscall untuk memanggil panggilan sistem setns mengembalikan ralat EINVAL. Isu ini berterusan walaupun terdapat persediaan yang betul dan pelaksanaan C yang berfungsi yang berjaya memasuki ruang nama.
Punca dan Penyelesaian
Punca isu terletak pada pelbagai- sifat berulir Go. Panggilan sistem setns mesti dilaksanakan dari konteks satu thread untuk berjaya. Memandangkan aplikasi Go adalah berbilang benang secara lalai, panggilan setns mesti dibuat sebelum urutan masa jalan Go bermula.
Untuk menangani perkara ini, "helah pembina cgo" boleh digunakan. Teknik ini membolehkan kod C dilaksanakan sebelum masa jalan Go bermula. Dengan menggunakan makro __attribute__((pembina)) dalam kod C, fungsi boleh dihias untuk dijalankan dalam konteks C berbenang tunggal sebelum permulaan Go.
Kod Go Diubahsuai
Kod Go yang diubah suai berikut menggunakan helah pembina untuk menyelesaikan isu:
<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" ... rest of file is unchanged ...</code>
Dengan memanfaatkan helah pembina cgo, aplikasi Go kini boleh berjaya memasuki ruang nama mnt menggunakan panggilan sistem setns.
Atas ialah kandungan terperinci Mengapa Memanggil `setns` daripada Go Mengembalikan `EINVAL` untuk Ruang Nama Mnt?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!