proc 가상 파일 시스템의 Linux 마운트 지점?

proc 가상 파일 시스템의 Linux 마운트 지점?

이 질문을 stackoverflow에서 여기로 옮기라는 요청을 받았습니다.

나는 guitmz의 memrun repo를 포크했습니다(asm 및 go용).
내 포크에는 C에 대한 memrun 및 memfd_create가 있습니다.
https://github.com/Hermann-SW/memrun?organization=Hermann-SW&organization=Hermann-SW#fork-mission-statement

memfd_create.c메모리 파일(/memfd:...)을 생성하고 프로세스 pid와 메모리 파일 설명자를 반환합니다.

pi@raspberrypi400:~/memrun/C $ gcc memfd_create.c -o memfd_create
pi@raspberrypi400:~/memrun/C $ ./memfd_create
1880 3
pi@raspberrypi400:~/memrun/C $ ls -l /proc/1880/fd
total 0
lrwx------ 1 pi pi 64 Oct  6 20:54 0 -> /dev/pts/0
lrwx------ 1 pi pi 64 Oct  6 20:54 1 -> /dev/pts/0
lrwx------ 1 pi pi 64 Oct  6 20:54 2 -> /dev/pts/0
lrwx------ 1 pi pi 64 Oct  6 20:54 3 -> '/memfd:rab.oof (deleted)'
pi@raspberrypi400:~/memrun/C $ 

인메모리 파일에 10MB 파일 시스템을 생성하는 방법은 다음과 같습니다.

pi@raspberrypi400:~/memrun/C $ dd if=/dev/zero of=/proc/1880/fd/3 bs=1024 count=10240 2> /dev/null
pi@raspberrypi400:~/memrun/C $ mkfs.ext2 /proc/1880/fd/3 > /dev/null
mke2fs 1.44.5 (15-Dec-2018)
pi@raspberrypi400:~/memrun/C $

32비트 Raspberry Pi OS(debian) 및 64비트 Intel Ubuntu에서는 /proc(!) 아래에 파일 시스템을 마운트할 수 있습니다.

pi@raspberrypi400:~/memrun/C $ ls -l /proc/1880/fd
total 12
drwx------ 2 root root 12288 Oct  6 20:56 lost+found
pi@raspberrypi400:~/memrun/C $ 

/proc 아래의 동일한 마운트는 Red Hat Enterprise Linux에서 작동하지 않습니다:

$ ./memfd_create
26611 3
$ ls -l /proc/26611/fd
total 0
lrwx------. 1 stammw stammw 64 Oct  6 21:00 0 -> /dev/pts/0
lrwx------. 1 stammw stammw 64 Oct  6 21:00 1 -> /dev/pts/0
lrwx------. 1 stammw stammw 64 Oct  6 21:00 2 -> /dev/pts/0
lrwx------. 1 stammw stammw 64 Oct  6 21:00 3 -> '/memfd:rab.oof (deleted)'
$ 
$ dd if=/dev/zero of=/proc/26611/fd/3 bs=1024 count=10240 2> /dev/null
$ mkfs.ext2 /proc/26611/fd/3 > /dev/null
mke2fs 1.45.6 (20-Mar-2020)
$ 
$ sudo mount /proc/26611/fd/3 /proc/26611/fd
[sudo] password for stammw: 
mount: /proc/26611/fd: cannot mount /dev/loop0 read-only.
$

/proc 아래 설치가 전혀 작동하지 않아야 합니까?
그렇다면 RHEL의 /proc에 성공적으로 마운트하려면 무엇이 필요합니까?

아마도 내가 이렇게 한 이유는 tcc "-run" 옵션이 g++/gcc, 모든 gcc/g++ 임시 파일 및 RAM의 실행 파일을 향상시키고 RAM에서 실행하기 때문일 것입니다.

pi@raspberrypi400:~/memrun/C $ fortune -s | bin/g++ -run demo.cpp foo 123
bar foo
Sorry.  I forget what I was going to say.
pi@raspberrypi400:~/memrun/C $ 
pi@raspberrypi400:~/memrun/C $ cat demo.cpp 
/**
*/
#include <iostream>

int main(int argc, char *argv[])
{
  printf("bar %s\n", argc>1 ? argv[1] : "(undef)");

  for(char c; std::cin.read(&c, 1); )  { std::cout << c; }

  return 0;
}
pi@raspberrypi400:~/memrun/C $

다른 스레드의 첫 번째 답변:

RHEL 출력에는 권한 뒤에 .가 표시됩니다. 이는 다른 SELinux 권한이 적용되고 있음을 의미합니다. 그들이 무엇인지 볼 수 있나요? - 다른 사람

RHEL에서:

$ sudo ls -Z /proc/26611/fd
[sudo] password for stammw: 
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 0
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 1
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 3
$
$ ls -Z /proc/26611 | grep fd$
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 fd
$

답변1

/proc 아래의 동일한 마운트는 Red Hat Enterprise Linux에서 작동하지 않습니다:
mount: /proc/26611/fd: cannot mount /dev/loop0 read-only.

로그를 확인하고 그 안에 무엇이 있는지 시도해 보세요 ;-)

[root@rhel8 ~]# journalctl --no-pager -n1 | sed 's/^ *//'
-- Logs begin at Thu 2021-10-07 03:05:03 BST, end at Thu 2021-10-07 03:10:49 BST. --
Oct 07 03:06:54 rhel8.od platform-python[2154]: SELinux is preventing mount from mounton access on the directory /proc/<pid>/fd.

*****  Plugin catchall (100. confidence) suggests   **************************

If you believe that mount should be allowed mounton access on the fd directory by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'mount' --raw | audit2allow -M my-mount
# semodule -X 300 -i my-mount.pp

그러나 나는 이것이 좋은 생각이라고 생각하지 않습니다. NET에 설치하는 대신 그대로 두고 다른 것을 시도하는 것이 좋습니다 /proc/<pid>/fd.

tcc "-run" 옵션은 g++/gcc, RAM의 모든 gcc/g++ 임시 파일 및 실행 파일을 향상시키고 RAM에서 실행합니다.

임시 디렉토리나 tmpfs가 적합하므로 자신이 너무 복잡해집니다.

답변2

아래 설치가 /proc전혀 작동하지 않습니까?

아니요, 다음 디렉토리는 /proc다른 제한 사항이 없는 한 이 점에서 다른 디렉토리와 다르지 않습니다(다른 디렉토리 참조).답변) 거기에는 무엇이든 설치할 수 있습니다.

경로의 한 가지 특징 /proc/<pid>/*은 그러한 디렉토리에 마운트하면자동 지연 제거[1]종료 되면 <pid>.

이 함수를 사용하면 프로세스가 종료될 때(종료 방법에 관계없이) 임시 디렉터리를 만들 수 있습니다 /proc/self.

예시 스크립트:

#! /bin/sh
set -e
mount -t tmpfs tmpfs /proc/$$/attr
cd /proc/$$/attr
bash

이렇게 하면 현재 디렉터리가 있는 셸에 들어가게 되며 /proc/$$/attr, 여기에서 셸을 종료하면 사라지는 다른 파일과 디렉터리를 생성할 수 있습니다.

하지만더 나은 선택마운트할 위치에 대한 더 많은 옵션을 제공하는 프라이빗 마운트 네임스페이스를 만드는 것입니다.

$ export T=$(mktemp -d)
$ unshare -Urm 
root# mount -t tmpfs t $T
root# echo > $T/somefile
root# ls $T
somefile
root# exit
$ ls $T
<nothing left>

참고: 일부 Debian 계열 시스템에서는 sysctl kernel.unprivileged_userns_clone=1이를 일반 사용자로 실행하려면 루트로 활성화해야 합니다.cap_sys_admin+eip바이너리 래퍼는 다음을 수행할 수 있습니다.공유 취소네임스페이스를 마운트하고 해당 마운트 전파를 비공개로 설정한 다음 (추가 사용자 네임스페이스를 만들지 않고) tmpfs 마운트를 수행한 다음 다른 프로그램이나 스크립트를 실행합니다.


[1] 언로드가 연기된 디렉터리는 그 안에 있는 파일과 디렉터리에 대한 모든 참조가 닫힐 때까지 "부동" 상태로 유지됩니다. 이로 인해 파일 시스템에 없는 별도의(그러나 완전히 작동하는) 파일 시스템이 있고 시스템 호출이 다음으로 끝나는 파일을 반환하는 이상한 상황이 발생합니다 /proc/mounts. getcwd(2)이 파일은 POSIX 정의와 일치하도록 glibc 래퍼에 패치해야 하며 실패가 (unreachable)/필요합니다. getcwd()또는 절대 경로를 반환합니다):

# sleep 2 & mount -t tmpfs t /proc/$!/attr; cd /proc/$!/attr
[1] 6585
/proc/6585/attr# 
[1]+  Done                    sleep 2  (wd: ~)
/proc/6585/attr# /bin/pwd
/bin/pwd: couldn't find directory entry in '..' with matching i-node
/proc/6585/attr# strace /bin/pwd 2>&1 | grep cwd
getcwd("(unreachable)/", 4096)          = 15
/proc/6585/attr# mkdir sub        # you can still use the dir normally

당신도 할 수 있습니다.게으른umount(MNT_DETACH)/explicitly 파일 시스템 마운트 해제를 사용하십시오 umount -l.

관련 정보