open_by_handle_at(2) - wariua/manpages-ko GitHub Wiki
name_to_handle_at, open_by_handle_at - ๊ฒฝ๋ก๋ช ์ ๋ํ ํธ๋ค์ ์ป๊ณ ํธ๋ค์ ํตํด ํ์ผ ์ด๊ธฐ
#define _GNU_SOURCE /* feature_test_macros(7) ์ฐธ๊ณ */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int name_to_handle_at(int dirfd, const char *pathname,
struct file_handle *handle,
int *mount_id, int flags);
int open_by_handle_at(int mount_fd, struct file_handle *handle,
int flags);
name_to_handle_at()
๋ฐ open_by_handle_at()
์์คํ
ํธ์ถ์ openat(2)์ ๊ธฐ๋ฅ์ ๋ ๋ถ๋ถ์ผ๋ก ์ชผ๊ฐ ๊ฒ์ด๋ค. name_to_handle_at()
์ ์ง์ ํ ํ์ผ์ ๋์ํ๋ ๋ถํฌ๋ช
ํธ๋ค์ ๋ฐํํ๋ฉฐ open_by_handle_at()
์ ์์ name_to_handle_at()
ํธ์ถ์ด ๋ฐํํ ํธ๋ค์ ๋์ํ๋ ํ์ผ์ ์ด์ด์ ์ด๋ฆฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ฐํํ๋ค.
name_to_handle_at()
์์คํ
ํธ์ถ์ dirfd
๋ฐ pathname
์ธ์๋ก ์ง์ ํ ํ์ผ์ ๋์ํ๋ ํ์ผ ํธ๋ค๊ณผ ๋ง์ดํธ ID๋ฅผ ๋ฐํํ๋ค. ์ธ์ handle
์ ํตํด ํ์ผ ํธ๋ค์ ๋ฐํํ๋๋ฐ, ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ์ฒด์ ๋ํ ํฌ์ธํฐ์ด๋ค.
struct file_handle {
unsigned int handle_bytes; /* f_handle์ ํฌ๊ธฐ [in, out] */
int handle_type; /* ํธ๋ค ํ์
[out] */
unsigned char f_handle[0]; /* ํ์ผ ์๋ณ์ (ํธ์ถ์๊ฐ ํฌ๊ธฐ ์ง์ )
[out] */
};
f_handle
๋ก ๋ฐํ๋๋ ํธ๋ค์ ๋ด๊ธฐ์ ์ถฉ๋ถํ ํฐ ๊ตฌ์กฐ์ฒด๋ฅผ ํ ๋นํ๋ ๊ฑด ํธ์ถ์์ ์ฑ
์์ด๋ค. ํธ์ถ ์ ์ f_handle
์ ํ ๋น๋ ํฌ๊ธฐ๋ฅผ ๋ด๋๋ก handle_bytes
ํ๋๋ฅผ ์ด๊ธฐํํด์ผ ํ๋ค. (<fcntl.h>
์ ์ ์๋ ์์ MAX_HANDLE_SZ
๊ฐ ํ์ผ ํธ๋ค ํฌ๊ธฐ์ ์์ ์ต๋๊ฐ์ ๋ํ๋ธ๋ค. ํฅํ์ ํ์ผ ์์คํ
์์ ๋ ํฐ ๊ณต๊ฐ์ ํ์๋ก ํ ์ ์์ผ๋ฏ๋ก ๋ณด์ฅ๋ ์ํ์ ์๋๋ค.) ์ฑ๊ณต ๋ฐํ ์ ์ค์ f_handle
์ ๊ธฐ๋ก๋ ๋ฐ์ดํธ ์๋ฅผ ๋ด๋๋ก handle_bytes
ํ๋๊ฐ ๊ฐฑ์ ๋๋ค.
ํธ์ถ์๊ฐ handle->handle_bytes
๋ฅผ 0์ผ๋ก ํธ์ถ์ ํด์ file_handle
๊ตฌ์กฐ์ฒด์ ํ์ํ ํฌ๊ธฐ๋ฅผ ์์๋ผ ์ ์๋ค. ์ด ๊ฒฝ์ฐ ํธ์ถ์ด EOVERFLOW
์ค๋ฅ๋ก ์คํจํ๋ฉฐ handle->handle_bytes
๊ฐ ํ์ ํฌ๊ธฐ๋ก ์ค์ ๋๋ค. ๊ทธ๋ฌ๋ฉด ํธ์ถ์๊ฐ ๊ทธ ์ ๋ณด๋ฅผ ์ด์ฉํด ์ฌ๋ฐ๋ฅธ ํฌ๊ธฐ์ ๊ตฌ์กฐ์ฒด๋ฅผ ํ ๋นํ ์ ์๋ค. (์๋ EXAMPLE ์ฐธ๊ณ .) EOVERFLOW
์ค๋ฅ๊ฐ ํ์ผ ํธ๋ค ๊ฒ์์ ์ ์์ ์ผ๋ก ์ง์ํ๋ ํ์ผ ์์คํ
์์ ์ด ํน์ ์ด๋ฆ์ ๋ํด ์ฌ์ฉ ๊ฐ๋ฅํ ํ์ผ ํธ๋ค์ด ์๋ค๋ ๋ป์ผ ์๋ ์๊ธฐ ๋๋ฌธ์ ์ฝ๊ฐ์ ์ฃผ์๊ฐ ํ์ํ๋ค. handle_bytes
๊ฐ ์ฆ๊ฐํ์ง ์๊ณ EOVERFLOW
์ค๋ฅ๊ฐ ๋ฐํ๋๋ ๊ฒ์ผ๋ก ์ด ๊ฒฝ์ฐ๋ฅผ ์์๋ผ ์ ์๋ค.
handle_bytes
ํ๋๋ฅผ ์ด์ฉํ๋ ๊ฒ ์ธ์๋ ํธ์ถ์๊ฐ file_handle
๊ตฌ์กฐ์ฒด๋ฅผ ๋ถํฌ๋ช
ํ ๋ฐ์ดํฐ ํ์
์ผ๋ก ๋ค๋ค์ผ ํ๋ค. handle_type
๋ฐ f_handle
ํ๋๊ฐ ํ์ํ ๊ณณ์ ์ด์ด์ง๋ open_by_handle_at()
ํธ์ถ๋ฟ์ด๋ค.
flags
์ธ์๋ AT_EMPTY_PATH
์ AT_SYMLINK_FOLLOW
๋ฅผ 0๊ฐ ์ด์ OR ํด์ ๊ตฌ์ฑํ ๋นํธ ๋ง์คํฌ์ด๋ค. ๋์ ๋ํด์ ์๋์์ ์ค๋ช
ํ๋ค.
pathname
๋ฐ dirfd
์ธ์๋ ๋์ด ํจ๊ป ํธ๋ค์ ์ป์ ํ์ผ์ ์๋ณํ๋ค. ๋ค ๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ์๋ค.
-
pathname
์ด ๋น์ด ์์ง ์์ ๋ฌธ์์ด์ด๊ณ ์ ๋ ๊ฒฝ๋ก๋ช ์ ๋ด๊ณ ์์ผ๋ฉด ๊ทธ ๊ฒฝ๋ก๋ช ์ด ๊ฐ๋ฆฌํค๋ ํ์ผ์ ๋ํ ํธ๋ค์ ๋ฐํํ๋ค. ์ด ๊ฒฝ์ฐdirfd
๋ ๋ฌด์ํ๋ค. -
pathname
์ด ๋น์ด ์์ง ์์ ๋ฌธ์์ด์ด๊ณ ์๋ ๊ฒฝ๋ก๋ช ์ ๋ด๊ณ ์์ผ๋ฉฐdirfd
๊ฐ ํน์ ๊ฐAT_FDCWD
์ด๋ฉด ํธ์ถ์์ ํ์ฌ ์์ ๋๋ ํฐ๋ฆฌ๋ฅผ ๊ธฐ์ค์ผ๋กpathname
์ ํด์ํด์ ๊ทธ ๊ฒฝ๋ก๋ช ์ด ๊ฐ๋ฆฌํค๋ ํ์ผ์ ๋ํ ํธ๋ค์ ๋ฐํํ๋ค. -
pathname
์ด ๋น์ด ์์ง ์์ ๋ฌธ์์ด์ด๊ณ ์๋ ๊ฒฝ๋ก๋ช ์ ๋ด๊ณ ์์ผ๋ฉฐdirfd
๊ฐ ๋๋ ํฐ๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํค๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ด๋ฉดdirfd
๊ฐ ๊ฐ๋ฆฌํค๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ๊ธฐ์ค์ผ๋กpathname
์ ํด์ํด์ ๊ทธ ๊ฒฝ๋ก๋ช ์ด ๊ฐ๋ฆฌํค๋ ํ์ผ์ ๋ํ ํธ๋ค์ ๋ฐํํ๋ค. ("๋๋ ํฐ๋ฆฌ ํ์ผ ๋์คํฌ๋ฆฝํฐ"๊ฐ ์ ์ฉํ ์ด์ ์ ๋ํด์ openat(2) ์ฐธ๊ณ .) -
pathname
์ด ๋น ๋ฌธ์์ด์ด๊ณflags
์AT_EMPTY_PATH
๊ฐ์ด ์ง์ ๋ผ ์์ผ๋ฉดdirfd
๊ฐ ์์ ์ข ๋ฅ์ ํ์ผ์ ๊ฐ๋ฆฌํค๋ ์ด๋ฆฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ด๊ฑฐ๋ ํ์ฌ ์์ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ปํ๋AT_FDCWD
์ผ ์ ์์ผ๋ฉฐ, ๊ทธ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ํ์ผ์ ๋ํ ํธ๋ค์ ๋ฐํํ๋ค.
mount_id
์ธ์๋ pathname
์ ๋ถํฉํ๋ ํ์ผ ์์คํ
๋ง์ดํธ์ ๋ํ ์๋ณ์๋ฅผ ๋ฐํํ๋ค. ์ด๋ /proc/self/mountinfo
์ ์๋ ํ ๋ ์ฝ๋์ ์ฒซ ๋ฒ์งธ ํ๋์ ๋์ํ๋ค. ๊ทธ ๋ ์ฝ๋์ ๋ค์ฏ ๋ฒ์งธ ํ๋์ ์๋ ๊ฒฝ๋ก๋ช
์ ์ด๋ฉด ๊ทธ ๋ง์ดํธ ์ง์ ์ ๋ํ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ๋์ค๊ณ , ๊ทธ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ์ด์ด์ง๋ open_by_handle_at()
ํธ์ถ์ ์ฌ์ฉํ ์ ์๋ค. ์ฑ๊ณต ํธ์ถ๊ณผ EOVERFLOW
์ค๋ฅ๊ฐ ๋ ํธ์ถ ๋ชจ๋์์ mount_id
๊ฐ ๋ฐํ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก name_to_handle_at()
์์๋ pathname
์ด ์ฌ๋ณผ๋ฆญ ๋งํฌ์ธ ๊ฒฝ์ฐ ์ญ์ฐธ์กฐ๋ฅผ ํ์ง ์๊ณ ๊ทธ ๋งํฌ ์์ฒด์ ๋ํ ํธ๋ค์ ๋ฐํํ๋ค. flags
์ AT_SYMLINK_FOLLOW
๋ฅผ ์ง์ ํ๋ฉด pathname
์ด ์ฌ๋ณผ๋ฆญ ๋งํฌ์ธ ๊ฒฝ์ฐ ์ญ์ฐธ์กฐ๋ฅผ ํ๋ค. (๊ทธ๋์ ๊ทธ ๋งํฌ๊ฐ ๊ฐ๋ฆฌํค๋ ํ์ผ์ ๋ํ ํธ๋ค์ ๋ฐํํ๋ค.)
๊ฒฝ๋ก๋ช
์ ๋ง์ง๋ง ๊ตฌ์ฑ ์์๊ฐ automount ์ง์ ์ผ ๋๋ name_to_handle_at()
์ด ๋ง์ดํธ๋ฅผ ์ ๋ฐํ์ง ์๋๋ค. ํ์ผ ์์คํ
์์ ํ์ผ ํธ๋ค๊ณผ automount ์ง์ ๋ชจ๋๋ฅผ ์ง์ํ ๋ automount ์ง์ ์ ๋ํ name_to_handle_at()
ํธ์ถ์ handle_bytes
๋ฅผ ์ฌ๋ฆฌ์ง ์์ ์ฑ EOVERFLOW
์ค๋ฅ๋ฅผ ๋ฐํํ๊ฒ ๋๋ค. ๋ฆฌ๋
์ค 4.13 ์ด์์์ NFS๋ฅผ ์ธ ๋ ์๋ฒ ์์ ๋ณ๋ ํ์ผ ์์คํ
์ ์๋ ๋๋ ํฐ๋ฆฌ์ ์ ๊ทผ ์ ์ด๋ฐ ์ํฉ์ด ์๊ธธ ์ ์๋ค. ์ด ๊ฒฝ์ฐ์ ๊ฒฝ๋ก๋ช
๋์ "/"๋ฅผ ๋ง๋ถ์ด๋ฉด automount๋ฅผ ์ผ์ผํฌ ์ ์๋ค.
open_by_handle_at()
์์คํ
ํธ์ถ์ ์์ name_to_handle_at()
ํธ์ถ์ด ๋ฐํํ ํ์ผ ํธ๋ค์ธ handle
์ด ๊ฐ๋ฆฌํค๋ ํ์ผ์ ์ฐ๋ค.
mount_fd
์ธ์๋ handle
์ ํด์ํ ๊ธฐ์ค์ด ๋ผ์ผ ํ๋ ๋ง์ดํธ ๋ ํ์ผ ์์คํ
๋ด์ ์์ ๊ฐ์ฒด(ํ์ผ, ๋๋ ํฐ๋ฆฌ ๋ฑ)์ ๋ํ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ด๋ค. ํธ์ถ์์ ํ์ฌ ์์
๋๋ ํฐ๋ฆฌ๋ฅผ ๋ปํ๋ ํน์ ๊ฐ AT_FDCWD
๋ฅผ ์ง์ ํ ์ ์๋ค.
flags
์ธ์๋ open(2)์์์ ๊ฐ๋ค. handle
์ด ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๊ฐ๋ฆฌํค๋ ๊ฒฝ์ฐ ํธ์ถ์๊ฐ O_PATH
ํ๋๊ทธ๋ฅผ ์ง์ ํด์ผ ํ๋ฉฐ, ๊ทธ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ์ญ์ฐธ์กฐํ์ง ์๋๋ค. O_NOFOLLOW
ํ๋๊ทธ๋ ์ง์ ์ ๋ฌด์ํ๋ค.
open_by_handle_at()
์ ์ฐ๋ ค๋ฉด ํธ์ถ์์๊ฒ CAP_DAC_READ_SEARCH
์ญ๋ฅ์ด ์์ด์ผ ํ๋ค.
์ฑ๊ณต ์ name_to_handle_at()
์ 0์ ๋ฐํํ๋ฉฐ open_by_handle_at()
์ ์์ ์๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ฐํํ๋ค.
์ค๋ฅ ๋ฐ์ ์ ๋ ์์คํ
ํธ์ถ์ -1์ ๋ฐํํ๋ฉฐ ์ค๋ฅ ์์ธ์ ๋ํ๋ด๋๋ก errno
๋ฅผ ์ค์ ํ๋ค.
name_to_handle_at()
๊ณผ open_by_handle_at()
์ด openat(2)๊ณผ ๊ฐ์ ์ค๋ฅ๋ก ์คํจํ ์ ์๋ค. ๋๋ถ์ด ์๋์ ์ ์ ์ค๋ฅ๋ค๋ก ์คํจํ ์ ์๋ค.
name_to_handle_at()
์ด ๋ค์ ์ค๋ฅ๋ก ์คํจํ ์ ์๋ค.
EFAULT
-
pathname
์ด๋mount_id
,handle
์ด ์ ๊ทผ ๊ฐ๋ฅํ ์ฃผ์ ๊ณต๊ฐ ๋ฐ์ ๊ฐ๋ฆฌํจ๋ค. EINVAL
-
flags
์ ์ ํจํ์ง ์์ ๋นํธ ๊ฐ์ด ํฌํจ๋ผ ์๋ค. EINVAL
-
handle->handle_bytes
๊ฐMAX_HANDLE_SZ
๋ณด๋ค ํฌ๋ค. ENOENT
-
pathname
์ด ๋น ๋ฌธ์์ด์ธ๋ฐflags
์AT_EMPTY_PATH
๋ฅผ ์ง์ ํ์ง ์์๋ค. ENOTDIR
-
dirfd
๋ก ์ค ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ๋๋ ํฐ๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์์ง ์์ผ๋ฉฐ,flags
์AT_EMPTY_PATH
๊ฐ ์์ผ๋ฉด์pathname
์ด ๋น ๋ฌธ์์ด์ธ ๊ฒฝ์ฐ๊ฐ ์๋๋ค. EOPNOTSUPP
- ํ์ผ ์์คํ ์์ ๊ฒฝ๋ก๋ช ์ ํ์ผ ํธ๋ค๋ก ๋์ฝ๋ฉ ํ๋ ๊ฑธ ์ง์ํ์ง ์๋๋ค.
EOVERFLOW
- ํธ์ถ๋ก ์ ๋ฌํ
handle->handle_bytes
๊ฐ์ด ๋๋ฌด ์๋ค. ์ด ์ค๋ฅ ๋ฐ์ ์ ํธ๋ค์ ํ์ํ ํฌ๊ธฐ๋ฅผ ๋ํ๋ด๋๋กhandle->handle_bytes
๊ฐ ๊ฐฑ์ ๋๋ค.
open_by_handle_at()
์ด ๋ค์ ์ค๋ฅ๋ก ์คํจํ ์ ์๋ค.
EBADF
-
mount_fd
๊ฐ ์ด๋ฆฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์๋๋ค. EFAULT
-
handle
์ด ์ ๊ทผ ๊ฐ๋ฅํ ์ฃผ์ ๊ณต๊ฐ ๋ฐ์ ๊ฐ๋ฆฌํจ๋ค. EINVAL
-
handle->handle_bytes
๊ฐMAX_HANDLE_SZ
๋ณด๋ค ํฌ๊ฑฐ๋ 0๊ณผ ๊ฐ๋ค. ELOOP
-
handle
์ด ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๊ฐ๋ฆฌํค๋๋ฐflags
์O_PATH
๊ฐ ์ง์ ๋ผ ์์ง ์๋ค. EPERM
- ํธ์ถ์์๊ฒ
CAP_DAC_READ_SEARCH
์ญ๋ฅ์ด ์๋ค. ESTALE
- ์ง์ ํ
handle
์ด ์ ํจํ์ง ์๋ค. ์๋ฅผ ๋ค์ด ํ์ผ์ด ์ญ์ ๋์ ๋ ์ด ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค.
๋ฆฌ๋ ์ค 2.6.39์์ ์ด ์์คํ ํธ์ถ๋ค์ด ์ฒ์ ๋ฑ์ฅํ๋ค. glibc ๋ฒ์ 2.14๋ถํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ง์์ ์ ๊ณตํ๋ค.
์ด ์์คํ ํธ์ถ๋ค์ ๋นํ์ค ๋ฆฌ๋ ์ค ํ์ฅ์ด๋ค.
FreeBSD์ ๋๋ต ๋น์ทํ ํํ์ ์์คํ
ํธ์ถ ์ getfh()
์ openfh()
๊ฐ ์๋ค.
ํ ํ๋ก์ธ์ค์์ name_to_handle_at()
์ผ๋ก ํ์ผ ํธ๋ค์ ๋ง๋ค๊ณ ๋์ค์ ๋ค๋ฅธ ํ๋ก์ธ์ค์์ open_by_handle_at()
ํธ์ถ์ ์ธ ์ ์๋ค.
์ผ๋ถ ํ์ผ ์์คํ
์ ๊ฒฝ๋ก๋ช
์์ ํ์ผ ํธ๋ค๋ก์ ๋ณํ์ ์ง์ํ์ง ์๋๋ค. ์๋ก /proc
, /sys
, ์ฌ๋ฌ ๋คํธ์ํฌ ํ์ผ ์์คํ
๋ค์ด ์๋ค.
ํ์ผ์ด ์ญ์ ๋๊ฑฐ๋ ๊ธฐํ ํ์ผ ์์คํ
์์ฒด์ ์ธ ์ด๋ค ์ด์ ๋ก ํ์ผ ํธ๋ค์ด ์ ํจํ์ง ์๊ฒ ๋ ("์ํ ") ์ ์๋ค. ์ ํจํ์ง ์์ ํธ๋ค์ open_by_handle_at()
์์ ESTALE
์ค๋ฅ๋ก ์๋ ค ์ค๋ค.
์ด ์์คํ ํธ์ถ๋ค์ ์ฌ์ฉ์ ๊ณต๊ฐ ํ์ผ ์๋ฒ์์ ์ฐ๋๋ก ๋ง๋ค์ด์ง ๊ฒ์ด๋ค. ์๋ฅผ ๋ค์ด ์ฌ์ฉ์ ๊ณต๊ฐ NFS ์๋ฒ์์ ํ์ผ ํธ๋ค์ ์์ฑํด์ NFS ํด๋ผ์ด์ธํธ๋ก ์ ๋ฌํ ์ ์์ ๊ฒ์ด๋ค. ์ดํ ํด๋ผ์ด์ธํธ๊ฐ ๊ทธ ํ์ผ์ ์ด๊ณ ์ถ์ผ๋ฉด ๊ทธ ํธ๋ค์ ์๋ฒ์๊ฒ ๋ค์ ์ ๋ฌํ ์ ์๋ค. ์ด๋ฐ ๋ฅ์ ๊ธฐ๋ฅ์ ์ด์ฉํ๋ฉด ์ฌ์ฉ์ ๊ณต๊ฐ ํ์ผ ์๋ฒ๊ฐ ์ด์ฉ ํ์ผ๋ค์ ๋ํด ๋ฌด์ํ ๋ฐฉ์์ผ๋ก ๋์ํ ์ ์๋ค.
pathname
์ด ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๊ฐ๋ฆฌํค๊ณ flags
์ AT_SYMLINK_FOLLOW
๊ฐ ์ง์ ๋ผ ์์ง ์์ ๊ฒฝ์ฐ์ name_to_handle_at()
์ (๋งํฌ๊ฐ ๊ฐ๋ฆฌํค๋ ํ์ผ์ด ์๋๋ผ) ๋งํฌ์ ๋ํ ํธ๋ค์ ๋ฐํํ๋ค. ์ดํ ๊ทธ ํธ๋ค์ ๋ฐ์ ํ๋ก์ธ์ค๊ฐ O_PATH
ํ๋๊ทธ๋ฅผ ์ด open_by_handle_at()
์ผ๋ก ํธ๋ค์์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ก์ ๋ณํ์ ํ๊ณ ์ ๊ทธ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ readlinkat(2)๊ณผ fchownat(2) ๊ฐ์ ์์คํ
ํธ์ถ์ dirfd
์ธ์๋ก ์ ๋ฌํด์ ๊ทธ ์ฌ๋ณผ๋ฆญ ๋งํฌ์ ๋ํ ๋์์ ์ํํ ์ ์๋ค.
ํ์ผ ์์คํ
์ด ๋ง์ดํธ ๋๊ณ ํด์ ๋๋ฉด์ /proc/self/mountinfo
์ ๋ง์ดํธ ID๊ฐ ์ฌ์ฌ์ฉ๋ ์ ์๋ค. ๋ฐ๋ผ์ name_to_handle_at()
์ด (*mount_id
์) ๋ฐํํ ๋ง์ดํธ ID๋ฅผ ํด๋นํ๋ ๋ง์ดํธ ๋ ํ์ผ ์์คํ
์ ๋ํ ์์์ ์๋ณ์๋ก ๋ค๋ฃจ์ง ๋ง์์ผ ํ๋ค. ํ์ง๋ง ์์ฉ์์ ๊ทธ ๋ง์ดํธ ID์ ๋์ํ๋ mountinfo
๋ ์ฝ๋์ ์ ๋ณด๋ฅผ ์ด์ฉํด ์์์ ์ธ ์๋ณ์๋ฅผ ์ป์ด๋ผ ์ ์๋ค.
์๋ฅผ ๋ค์ด mountinfo
๋ ์ฝ๋์ ๋ค์ฏ ๋ฒ์งธ ํ๋์ ์๋ ์ฅ์น ์ด๋ฆ์ ๊ฐ์ง๊ณ /dev/disks/by-uuid
๋ด์ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ํตํด์ ํด๋น ์ฅ์น์ UUID๋ฅผ ์ฐพ์ ์ ์๋ค. (UUID๋ฅผ ์ป๋ ๋ ํธํ ๋ฐฉ๋ฒ์ libblkid(3)
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ๋ ๊ฒ์ด๋ค.) ๊ทธ๋ฌ๋ฉด ๊ทธ ๊ณผ์ ์ ๋ค์ง์ด์ UUID๋ฅผ ๊ฐ์ง๊ณ ์ฅ์น ์ด๋ฆ์ ์ฐพ์์ ํด๋น ๋ง์ดํธ ์ง์ ์ ์ป๊ณ , ๊ทธ๋์ open_by_handle_at()
์ ์ธ mount_fd
์ธ์๋ฅผ ๋ง๋ค์ด ๋ผ ์ ์๋ค.
์๋ ๋ ํ๋ก๊ทธ๋จ์ด name_to_handle_at()
๊ณผ open_by_handle_at()
์ฌ์ฉ ๋ฐฉ์์ ๋ณด์ฌ ์ค๋ค. ์ฒซ ๋ฒ์งธ ํ๋ก๊ทธ๋จ(t_name_to_handle_at.c
)์์๋ name_to_handle_at()
์ ์ฌ์ฉํด ๋ช
๋ นํ ์ธ์๋ก ์ง์ ํ ํ์ผ์ ๋ํ ํ์ผ ํธ๋ค๊ณผ ๋ง์ดํธ ID๋ฅผ ์ป๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ํธ๋ค๊ณผ ๋ง์ดํธ ID๋ฅผ ํ์ค ์ถ๋ ฅ์ผ๋ก ์ฐ๋๋ค.
๋ ๋ฒ์งธ ํ๋ก๊ทธ๋จ(t_open_by_handle_at.c
)์์๋ ํ์ค ์
๋ ฅ์ผ๋ก๋ถํฐ ๋ง์ดํธ ID์ ํ์ผ ํธ๋ค์ ์ฝ์ด ๋ค์ธ๋ค. ๊ทธ๋ฌ๊ณ ๋์ open_by_handle_at()
์ ์ฌ์ฉํด ๊ทธ ํธ๋ค๋ก ํ์ผ์ ์ฐ๋ค. ์ ํ์ ์ธ ๋ช
๋ นํ ์ธ์๋ฅผ ์ค ๊ฒฝ์ฐ์๋ ์ง๋ช
๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ด์ด์ open_by_handle_at()
์ ์ธ mount_fd
์ธ์๋ฅผ ์ป๋๋ค. ์๋ ๊ฒฝ์ฐ์๋ /proc/self/mountinfo
๋ฅผ ํ์ํด์ ํ์ค ์
๋ ฅ์ผ๋ก ์ฝ์ ๋ง์ดํธ ID์ ์ผ์นํ๋ ๋ ์ฝ๋๋ฅผ ์ฐพ์ ๋ค์ ๊ทธ ๋ ์ฝ๋์ ๋์จ ๋ง์ดํธ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ด์ด์ mount_fd
๋ฅผ ์ป๋๋ค. (์ด ํ๋ก๊ทธ๋จ๋ค์์๋ ๋ง์ดํธ ID๊ฐ ์์์ ์ด์ง ์๋ค๋ ์ ๊น์ง๋ ๋ค๋ฃจ์ง ์๋๋ค.)
๋ค์ ์ ธ ์ธ์ ์ด ๋ ํ๋ก๊ทธ๋จ์ ์ฌ์ฉ ๋ฐฉ์์ ๋ณด์ฌ ์ค๋ค.
$ echo 'Can you please think about it?' > cecilia.txt
$ ./t_name_to_handle_at cecilia.txt > fh
$ ./t_open_by_handle_at < fh
open_by_handle_at: Operation not permitted
$ sudo ./t_open_by_handle_at < fh # CAP_SYS_ADMIN ํ์ํจ
Read 31 bytes
$ rm cecilia.txt
์ด์ ํ์ผ์ ์ญ์ ํ๊ณ (์ฌ๋นจ๋ฆฌ) ๋ค์ ๋ง๋ค์ด์ ๋ด์ฉ์ด ๊ฐ๊ณ (์ฐ์ฐํ) ์์ด๋
ธ๋๋ ๊ฐ๋๋ก ํ๋ค. ๊ทธ๋ ๊ฒ ํด๋ open_by_handle_at()
์์ ํ์ผ ํธ๋ค์ด ๊ฐ๋ฆฌํค๋ ์๋ ํ์ผ์ด ๋ ์ด์ ์กด์ฌํ์ง ์๋๋ค๋ ๊ฑธ ์๋ค.
$ stat --printf="%i\n" cecilia.txt # ์์ด๋
ธ๋ ๋ฒํธ ํ์
4072121
$ rm cecilia.txt
$ echo 'Can you please think about it?' > cecilia.txt
$ stat --printf="%i\n" cecilia.txt # ์์ด๋
ธ๋ ๋ฒํธ ํ์ธ
4072121
$ sudo ./t_open_by_handle_at < fh
open_by_handle_at: Stale NFS file handle
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
int
main(int argc, char *argv[])
{
struct file_handle *fhp;
int mount_id, fhsize, flags, dirfd, j;
char *pathname;
if (argc != 2) {
fprintf(stderr, "Usage: %s pathname\n", argv[0]);
exit(EXIT_FAILURE);
}
pathname = argv[1];
/* file_handle ๊ตฌ์กฐ์ฒด ํ ๋น */
fhsize = sizeof(*fhp);
fhp = malloc(fhsize);
if (fhp == NULL)
errExit("malloc");
/* ์ฒซ ๋ฒ์งธ name_to_handle_at() ํธ์ถ๋ก ํ์ผ ํธ๋ค์ ํ์ํ
ํฌ๊ธฐ ์์๋ด๊ธฐ */
dirfd = AT_FDCWD; /* name_to_handle_at() ํธ์ถ์ ์ฌ์ฉ */
flags = 0; /* name_to_handle_at() ํธ์ถ์ ์ฌ์ฉ */
fhp->handle_bytes = 0;
if (name_to_handle_at(dirfd, pathname, fhp,
&mount_id, flags) != -1 || errno != EOVERFLOW) {
fprintf(stderr, "Unexpected result from name_to_handle_at()\n");
exit(EXIT_FAILURE);
}
/* ์ฌ๋ฐ๋ฅธ ํฌ๊ธฐ๋ก file_handle ๊ตฌ์กฐ์ฒด ์ฌํ ๋น */
fhsize = sizeof(struct file_handle) + fhp->handle_bytes;
fhp = realloc(fhp, fhsize); /* fhp->handle_bytes ๋ณต์ฌ๋จ */
if (fhp == NULL)
errExit("realloc");
/* ๋ช
๋ นํ์์ ๋ฐ์ pathname์ ๊ฐ์ง๊ณ ํ์ผ ํธ๋ค ์ป๊ธฐ */
if (name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags) == -1)
errExit("name_to_handle_at");
/* ๋ง์ดํธ ID, ํ์ผ ํธ๋ค ํฌ๊ธฐ, ํ์ผ ํธ๋ค์ stdout์ผ๋ก ์ถ๋ ฅ.
์ดํ t_open_by_handle_at.c์์ ์ฌ์ฉํจ */
printf("%d\n", mount_id);
printf("%d %d ", fhp->handle_bytes, fhp->handle_type);
for (j = 0; j < fhp->handle_bytes; j++)
printf(" %02x", fhp->f_handle[j]);
printf("\n");
exit(EXIT_SUCCESS);
}
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
/* /proc/self/mountinfo๋ฅผ ํ์ํด์ ๋ง์ดํธ ID๊ฐ 'mount_id'์ ์ผ์นํ๋
ํ์ ์ฐพ์๋ธ๋ค. (๋ ์ฌ์ด ๋ฐฉ๋ฒ์ 'util-linux' ํ๋ก์ ํธ์์ ์ ๊ณตํ๋
'libmount'๋ฅผ ์ค์นํด์ ์ฐ๋ ๊ฒ์ด๋ค.)
ํด๋น ๋ง์ดํธ ๊ฒฝ๋ก๋ฅผ ์ด์ด์ ๋์ค๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ฐํํ๋ค. */
static int
open_mount_path_by_id(int mount_id)
{
char *linep;
size_t lsize;
char mount_path[PATH_MAX];
int mi_mount_id, found;
ssize_t nread;
FILE *fp;
fp = fopen("/proc/self/mountinfo", "r");
if (fp == NULL)
errExit("fopen");
found = 0;
linep = NULL;
while (!found) {
nread = getline(&linep, &lsize, fp);
if (nread == -1)
break;
nread = sscanf(linep, "%d %*d %*s %*s %s",
&mi_mount_id, mount_path);
if (nread != 2) {
fprintf(stderr, "Bad sscanf()\n");
exit(EXIT_FAILURE);
}
if (mi_mount_id == mount_id)
found = 1;
}
free(linep);
fclose(fp);
if (!found) {
fprintf(stderr, "Could not find mount point\n");
exit(EXIT_FAILURE);
}
return open(mount_path, O_RDONLY);
}
int
main(int argc, char *argv[])
{
struct file_handle *fhp;
int mount_id, fd, mount_fd, handle_bytes, j;
ssize_t nread;
char buf[1000];
#define LINE_SIZE 100
char line1[LINE_SIZE], line2[LINE_SIZE];
char *nextp;
if ((argc > 1 && strcmp(argv[1], "--help") == 0) || argc > 2) {
fprintf(stderr, "Usage: %s [mount-path]\n", argv[0]);
exit(EXIT_FAILURE);
}
/* ํ์ค ์
๋ ฅ์๋ ๋ง์ดํธ ID์ ํ์ผ ํธ๋ค ์ ๋ณด๊ฐ ์๋ค:
1ํ: <mount_id>
2ํ: <handle_bytes> <handle_type> <16์ง์๋ก ๋ํ๋ธ ํธ๋ค>
*/
if ((fgets(line1, sizeof(line1), stdin) == NULL) ||
(fgets(line2, sizeof(line2), stdin) == NULL)) {
fprintf(stderr, "Missing mount_id / file handle\n");
exit(EXIT_FAILURE);
}
mount_id = atoi(line1);
handle_bytes = strtoul(line2, &nextp, 0);
/* handle_bytes๊ฐ ์ฃผ์ด์ ธ์ ์ด์ file_handle ๊ตฌ์กฐ์ฒด๋ฅผ ํ ๋นํ ์ ์์ */
fhp = malloc(sizeof(struct file_handle) + handle_bytes);
if (fhp == NULL)
errExit("malloc");
fhp->handle_bytes = handle_bytes;
fhp->handle_type = strtoul(nextp, &nextp, 0);
for (j = 0; j < fhp->handle_bytes; j++)
fhp->f_handle[j] = strtoul(nextp, &nextp, 16);
/* ๋ง์ดํธ ์ง์ ์ ๋ํ ํ์ผ ๋์คํฌ๋ฆฝํฐ ์ป๊ธฐ.
๋ช
๋ นํ์ ์ง์ ๋ ๊ฒฝ๋ก๋ช
์ ์ด๊ฑฐ๋, /proc/self/mounts๋ฅผ
ํ์ํด์ stdin์ผ๋ก ๋ฐ์ 'mount_id'์ ์ผ์นํ๋ ๋ง์ดํธ ํญ๋ชฉ
์ฐพ์๋ด๊ธฐ. */
if (argc > 1)
mount_fd = open(argv[1], O_RDONLY);
else
mount_fd = open_mount_path_by_id(mount_id);
if (mount_fd == -1)
errExit("opening mount fd");
/* ํธ๋ค๊ณผ ๋ง์ดํธ ์ง์ ์ผ๋ก ํ์ผ ์ด๊ธฐ */
fd = open_by_handle_at(mount_fd, fhp, O_RDONLY);
if (fd == -1)
errExit("open_by_handle_at");
/* ํ์ผ์์ ๋ช ๋ฐ์ดํธ ์ฝ์ด ๋ณด๊ธฐ */
nread = read(fd, buf, sizeof(buf));
if (nread == -1)
errExit("read");
printf("Read %zd bytes\n", nread);
exit(EXIT_SUCCESS);
}
open(2), libblkid(3)
, blkid(8)
, findfs(8)
, mount(8)
util-linux
์ต์ ๋ฆด๋ฆฌ์ค์ libblkid
๋ฐ libmount
๋ฌธ์ (https://www.kernel.org/pub/linux/utils/util-linux/)
2019-03-06