mmap(2) - wariua/manpages-ko GitHub Wiki
mmap, munmap - νμΌμ΄λ μ₯μΉλ₯Ό λ©λͺ¨λ¦¬λ‘ λ§΅ νκ±°λ ν΄μ νκΈ°
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);
κΈ°λ₯ νμΈ λ§€ν¬λ‘ μ건μ λν μ 보λ NOTESλ₯Ό 보λΌ.
mmap()
μ νΈμΆ νλ‘μΈμ€μ κ°μ μ£Όμ κ³΅κ° μμ μ λ§€νμ λ§λ λ€. addr
μλ μ λ§€νμ μμ μ£Όμλ₯Ό μ§μ νλ€. length
μΈμλ λ§€νμ κΈΈμ΄(0λ³΄λ€ μ»€μΌ ν¨)λ₯Ό λνλΈλ€.
addr
μ΄ NULLμ΄λ©΄ λ§€νμ μμ±ν (νμ΄μ§μ μ λ ¬λ) μ£Όμλ₯Ό 컀λμμ μ ννλ€. μ΄κ² μ λ§€νμ λ§λλ κ°μ₯ μ΄μμ± μ’μ λ°©μμ΄λ€. addr
μ΄ NULLμ΄ μλλ©΄ 컀λμμ μ΄λ₯Ό λ§€νμ λ μμΉμ λν ννΈλ‘ λ°μλ€μΈλ€. 리λ
μ€ μ»€λμμ κ°κΉμ΄ νμ΄μ§ κ²½κ³λ‘ (νμ§λ§ νμ /proc/sys/vm/mmap_min_addr
μ μ§μ ν κ° μ΄μμΌλ‘) μ νλ€. μ λ§€νμ μ£Όμλ₯Ό νΈμΆ κ²°κ³Όλ‘ λ°ννλ€.
νμΌ λ§€νμ λ΄μ©μ (μ΅λͺ
λ§€νκ³Ό λ¬λ¦¬, μλ MAP_ANONYMOUS
μ°Έκ³ ) νμΌ λμ€ν¬λ¦½ν° fd
κ° κ°λ¦¬ν€λ νμΌμ (λλ λ€λ₯Έ κ°μ²΄μ) μ€νμ
offset
μ length
κ° λ°μ΄νΈλ‘ μ±μμ§λ€. offset
μ sysconf(_SC_PAGE_SIZE)
κ° λ°ννλ νμ΄μ§ ν¬κΈ°μ λ°°μμ¬μΌ νλ€.
mmap()
νΈμΆ λ°ν νμ μ¦μ fd
λ₯Ό λ«μ μ μλ€. κ·Έλ κ² ν΄λ λ§€νμ΄ λ¬΄ν¨νλμ§ μλλ€.
prot
μΈμλ λ§€νμ μνλ λ©λͺ¨λ¦¬ λ³΄νΈ λ°©μμ κΈ°μ νλ€. (νμΌμ μ΄κΈ° λͺ¨λμ μΆ©λνμ§ μμμΌ νλ€.) PROT_NONE
μ΄κ±°λ λ€μ νλκ·Έλ€ μ€ νλ μ΄μμ λΉνΈ OR ν κ²μ΄λ€.
PROT_EXEC
- νμ΄μ§λ₯Ό μ€νν μ μλ€.
PROT_READ
- νμ΄μ§λ₯Ό μ½μ μ μλ€.
PROT_WRITE
- νμ΄μ§μ μΈ μ μλ€.
PROT_NONE
- νμ΄μ§μ μ κ·Όν μ μλ€.
flags
μΈμλ λ§€νμ λν κ°±μ λ΄μ©μ΄ κ°μ μμμ λ§΅ νκ³ μλ λ€λ₯Έ νλ‘μΈμ€μκ² λ³΄μ΄λμ§ μ¬λΆλ₯Ό, κ·Έλ¦¬κ³ κ·Έ κ°±μ λ΄μ©μ΄ κΈ°λ° νμΌκΉμ§ κ°κ² λλμ§ μ¬λΆλ₯Ό κ²°μ νλ€. λ€μ μ€ μ νν ν κ° κ°μ flags
μ μ§μ΄λ£μ΄μ λμ λ°©μμ μ νλ€.
MAP_SHARED
- λ§€νμ 곡μ νλ€. λ§€νμ λν κ°±μ λ΄μ©μ΄ κ°μ μμμ λ§΅ νκ³ μλ λ€λ₯Έ νλ‘μΈμ€μκ² λ³΄μ΄λ©° (νμΌ κΈ°λ° λ§€νμΈ κ²½μ°) κ·Έ κ°±μ λ΄μ©μ΄ κΈ°λ° νμΌκΉμ§ κ°λ€. (κ°±μ λ΄μ©μ΄ κΈ°λ° νμΌλ‘ κ°λ μμ μ μ νν μ μ΄νλ €λ©΄ msync(2)λ₯Ό μ¬μ©ν΄μΌ νλ€.)
-
MAP_SHARED_VALIDATE
(리λ μ€ 4.15λΆν°) - μ΄ νλκ·Έμ λμ λ°©μμ
MAP_SHARED
μ κ°λ,MAP_SHARED
λ§€νμμλflags
μ λͺ¨λ₯΄λ νλκ·Έκ° μμΌλ©΄ 무μνλ€λ μ μ΄ λ€λ₯΄λ€. λ°λ©΄MAP_SHARED_VALIDATE
λ‘ λ§€νμ λ§λ€ λλ μ λ¬λ νλκ·Έλ€μ΄ λͺ¨λ μλ €μ§ κ²μΈμ§ 컀λμμ κ²μ¬ν΄μ λͺ¨λ₯΄λ νλκ·Έκ° μμΌλ©΄EOPNOTSUPP
μ€λ₯λ‘ λ§€νμ΄ μ€ν¨νλ€. λ μΌλΆ λ§€ν νλκ·Έ(κ°λ ΉMAP_SYNC
)λ₯Ό μ¬μ©νλ €λ©΄ μ΄ λ§€ν μ νμ΄ νμνλ€. MAP_PRIVATE
- λΉκ³΅μ copy-on-write λ§€νμ λ§λ λ€. λ§€νμ λν κ°±μ λ΄μ©μ΄ κ°μ νμΌμ λ§΅ νκ³ μλ λ€λ₯Έ νλ‘μΈμ€μκ² λ³΄μ΄μ§ μμΌλ©° κΈ°λ° νμΌκΉμ§ κ°μ§ μλλ€.
mmap()
νΈμΆ νμ νμΌμμ μΌμ΄λ λ³κ²½ λ΄μ©μ΄ λ§΅ λ μμμ 보μ΄λμ§ μ¬λΆλ λͺ μΈλμ΄ μμ§ μλ€.
MAP_SHARED
μ MAP_PRIVATE
λͺ¨λ POSIX.1-2001 λ° POSIX.1-2008μ κΈ°μ λΌ μλ€. MAP_SHARED_VALIDATE
λ 리λ
μ€ νμ₯μ΄λ€.
λλΆμ΄ flags
μ λ€μ κ°λ€μ 0κ° μ΄μ OR ν μ μλ€.
-
MAP_32BIT
(리λ μ€ 2.4.20, 2.6λΆν°) - λ§€νμ νλ‘μΈμ€ μ£Όμ 곡κ°μ μ²μ 2κΈ°κ°λ°μ΄νΈ μμ λ£λλ€. x86-64 μμμ 64λΉνΈ νλ‘κ·Έλ¨μλ§ μ΄ νλκ·Έλ₯Ό μ§μνλ€. μ€λ λ μ€νμ λ©λͺ¨λ¦¬μ μ²μ 2GB λ΄μ μ΄λκ°μ ν λΉν΄μ μΌλΆ μ΄κΈ° 64λΉνΈ νλ‘μΈμλ€μμ λ¬Έλ§₯ μ ν μ±λ₯μ κ°μ ν μ μλλ‘ μΆκ°λ κ²μ΄λ€. μμ¦μ x86-64 νλ‘μΈμμλ μ΄λ° μ±λ₯ λ¬Έμ κ° μκΈ° λλ¬Έμ μ΄ νλκ·Έλ₯Ό μΈ νμκ° μλ€.
MAP_FIXED
κ° μ€μ λΌ μλ κ²½μ°MAP_32BIT
νλκ·Έλ₯Ό 무μνλ€. MAP_ANON
-
MAP_ANONYMOUS
μ λμμ΄. μ κ±° μμ . MAP_ANONYMOUS
- λ§€νμ΄ νμΌμ κΈ°λ°μΌλ‘ νμ§ μμΌλ©° λ΄μ©λ¬Όμ΄ 0μΌλ‘ μ±μμ§λ€.
fd
μΈμλ₯Ό 무μνλ€. νμ§λ§ μΌλΆ ꡬνμμλMAP_ANONYMOUS
(λλMAP_ANON
) μ§μ μfd
κ° -1μ΄κΈ°λ₯Ό μꡬνλ―λ‘ μ΄μ κ°λ₯ν μμ©μμλ κ·Έλ κ² νλ κ² μ’λ€.offset
μΈμλ 0μ΄μ΄μΌ ν κ²μ΄λ€.MAP_ANONYMOUS
λ₯ΌMAP_SHARED
μ κ²°ν©ν΄ μ°λ κ²μ 리λ μ€ μ»€λ 2.4λΆν° μ§μνλ€. MAP_DENYWRITE
- μ΄ νλκ·Έλ 무μνλ€. (μμ μλ (리λ
μ€ 2.0 λ° κ·Έ μ μμλ) κΈ°λ° νμΌμ λν μ°κΈ°κ°
ETXTBUSY
λ‘ μ€ν¨ν΄μΌ νλ€λ λ»μ΄μλ€. νμ§λ§ μλΉμ€ κ±°λΆ κ³΅κ²©μ μμΈμ΄ λλ€.) MAP_EXECUTABLE
- μ΄ νλκ·Έλ 무μνλ€.
MAP_FILE
- νΈνμ© νλκ·Έ. 무μνλ€.
MAP_FIXED
-
addr
μ ννΈλ‘ ν΄μνμ§ μλλ€. μ¦ μ νν κ·Έ μ£Όμμ λ§€νμ μμΉμν¨λ€.addr
μ΄ μ μ ν μ λ ¬λΌ μμ΄μΌ νλ€. λλΆλΆμ μν€ν μ²μμλ νμ΄μ§ ν¬κΈ°μ λ°°μμ΄λ©΄ μΆ©λΆνμ§λ§ μ΄λ€ μν€ν μ²μμλ μΆκ° μ μ½μ΄ μμ μ μλ€.addr
κ³Όlen
μΌλ‘ μ§μ ν λ©λͺ¨λ¦¬ μμμ΄ κΈ°μ‘΄ λ§€ν(λ€)μ νμ΄μ§μ κ²ΉμΉλ κ²½μ°μλ κΈ°μ‘΄ λ§€νμ κ²ΉμΉλ λΆλΆμ λ²λ¦¬κ² λλ€. μ§μ ν μ£Όμλ₯Ό μ¬μ©ν μ μμΌλ©΄mmap()
μ΄ μ€ν¨νκ² λλ€.μ΄μμ±μ΄ μκΈ°λ₯Ό λ°λΌλ μννΈμ¨μ΄μμλ
MAP_FIXED
νλκ·Έλ₯Ό μ‘°μ¬ν΄μ μ¬μ©ν΄μΌ νλ€. νλ‘μΈμ€ λ©λͺ¨λ¦¬ λ§€νλ€μ μ νν λ°°μΉκ° 컀λ λ²μ , C λΌμ΄λΈλ¬λ¦¬ λ²μ , μ΄μ 체μ 릴리μ€μ λ°λΌ ν¬κ² λ€λ₯Ό μ μλ€λ μ μ μ λ ν΄μΌ νλ€. NOTESμ μλ μ΄ νλκ·Έμ λν λ΄μ©μ μ£Όμν΄μ μ½μ΄ 보λΌ! -
MAP_FIXED_NOREPLACE
(리λ μ€ 4.17λΆν°) -
μ΄ νλκ·Έμ λμ λ°©μμ
addr
κ°μ λΌλ μ μμMAP_FIXED
μ λΉμ·νλ°,MAP_FIXED_NOREPLACE
λ μ λ κΈ°μ‘΄ λ§€ν λ²μλ₯Ό μμμν€μ§ μλλ€λ μ μ΄ λ€λ₯΄λ€. μμ² λ²μκ° κΈ°μ‘΄ λ§€νκ³Ό μΆ©λνλ €λ κ²½μ°μ μ΄ νΈμΆμEEXIST
μ€λ₯λ‘ μ€ν¨νλ€. λ°λΌμ μ΄ νλκ·Έλ₯Ό μ¬μ©νλ©΄ (λ€λ₯Έ μ€λ λλ€μ λν΄) μμμ μΌλ‘ μ£Όμ λ²μ λ§€νμ μλν μ μλ€. ν μ€λ λλ§ μ±κ³΅νκ³ λλ¨Έμ§λ μ€ν¨λ₯Ό λ³΄κ³ νκ² λλ€.μ°Έκ³ λ‘
MAP_FIXED_NOREPLACE
νλκ·Έλ₯Ό μΈμνμ§ λͺ»νλ ꡬμ 컀λλ€μ (κΈ°μ‘΄ λ§€νκ³Όμ μΆ©λμ νμ§νμ λ) λ³΄ν΅ "λΉ-MAP_FIXED
" λμ λ°©μμΌλ‘ νν΄νκ² λλ€. μ¦ μμ²ν μ£Όμμ λ€λ₯Έ μ£Όμλ₯Ό λ°ννκ² λλ€. λ°λΌμ νμ νΈνμ± μλ μννΈμ¨μ΄μμλ λ°ν μ£Όμκ° μμ² μ£Όμμ κ°μμ§ νμΈν νμκ° μλ€. MAP_GROWSDOWN
- μ€νμ μ°λ νλκ·Έλ€. λ§€νμ΄ λ©λͺ¨λ¦¬μμ μλ λ°©ν₯μΌλ‘ λμ΄λμΌ νλ€κ³ 컀λ κ°μ λ©λͺ¨λ¦¬ μμ€ν
μκ² μλ¦°λ€. λ°ν μ£Όμλ νλ‘μΈμ€ κ°μ μ£Όμ 곡κ°μ μ€μ μμ±ν λ©λͺ¨λ¦¬ μμλ³΄λ€ ν νμ΄μ§ μλμ μ£Όμμ΄λ€. λ§€ν μλμ κ·Έ "λ°©νΈ κ΅¬μ" νμ΄μ§ λ΄μ μ£Όμλ₯Ό 건λ리면 λ§€νμ΄ ν νμ΄μ§λ§νΌ μ±μ₯νκ² λλ€. κ·Έ μ±μ₯μ΄ λ°λ³΅λ μ μμΌλ©°, λ§€νμ΄ μλμͺ½ λ€μ λ§€νμ μ΅μλ¨ νμ΄μ§λ‘ μ±μ₯ν΄μΌ νλ μμ μ "λ°©νΈ κ΅¬μ" νμ΄μ§λ₯Ό 건λ리면
SIGSEGV
μκ·Έλμ΄ λ°μνκ² λλ€. -
MAP_HUGETLB
(리λ μ€ 2.6.32λΆν°) - "κ±°λ νμ΄μ§"λ‘ λ§€νμ ν λΉνλ€. μμΈν λ΄μ©μ 리λ
μ€ μ»€λ μμ€ νμΌ
Documentation/admin-guide/mm/hugetlbpage.rst
λ₯Ό 보λΌ. μλ NOTESλ μ°Έκ³ . -
MAP_HUGE_2MB
,MAP_HUGE_1GB
(리λ μ€ 4.8λΆν°) -
μ¬λ¬ κ°μ§ hugetlb νμ΄μ§ ν¬κΈ°λ₯Ό μ§μνλ μμ€ν μμ
MAP_HUGETLB
μ μ‘°ν©ν΄ μ¬μ©ν΄μ λ€λ₯Έ hugetlb νμ΄μ§ ν¬κΈ°(κ°κ° 2MBμ 1GB)λ₯Ό μ ννλ€.λ μΌλ°μ μΌλ‘λ μ€νμ
MAP_HUGE_SHIFT
μ μ¬μ― λΉνΈμ μνλ νμ΄μ§ ν¬κΈ°μ λ°μ 2 λ‘κ·Έλ₯Ό μΈμ½λ© ν΄μ μνλ κ±°λ νμ΄μ§ ν¬κΈ°λ₯Ό μ€μ ν μ μλ€. (μ΄ λΉνΈ νλμμ 0 κ°μ κΈ°λ³Έ κ±°λ νμ΄μ§ ν¬κΈ°μ΄λ€. κΈ°λ³Έ κ±°λ νμ΄μ§ ν¬κΈ°λ/proc/meminfo
μ λμ€λHugepagesize
νλλ₯Ό ν΅ν΄ μ μ μλ€.) λ°λΌμ μ λ μμλ λ€μκ³Ό κ°μ΄ μ μλΌ μλ€.#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) #define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
/sys/kernel/mm/hugepages
μ νμ λλ ν°λ¦¬λ₯Ό νμΈνλ©΄ μμ€ν μμ μ§μνλ κ±°λ νμ΄μ§ ν¬κΈ°λ€μ μ μ μλ€. -
MAP_LOCKED
(리λ μ€ 2.5.37λΆν°) - λ§΅ ν μμμ mlock(2)κ³Ό κ°μ λ°©μμΌλ‘ κ³ μ νκ² νμνλ€. μ¬κΈ°μ μ 체 λ²μλ₯Ό μ±μ°λ €κ³ (미리 ν΄νΈ) μλλ νμ§λ§ μ€ν¨ν κ²½μ°μ
mmap()
νΈμΆμ΄ μ€ν¨νμ§ μλλ€. λ°λΌμ μ΄νμ λ©μ΄μ ν΄νΈκ° λ°μν μλ μλ€. μ¦ mlock(2)λ§νΌ μλ―Έλ‘ μ΄ κ°λ ₯νμ§ μλ€. λ§€ν μ΄κΈ°ν νμ λ©μ΄μ ν΄νΈλ₯Ό νμ©ν μ μλ€λ©΄mmap()
μ mlock(2)μ λν΄μ μ°λ κ² μ’λ€. ꡬμ 컀λμμλMAP_LOCKED
νλκ·Έλ₯Ό 무μνλ€. -
MAP_NONBLOCK
(리λ μ€ 2.5.46λΆν°) - μ΄ νλκ·Έλ
MAP_POPULATE
μ ν¨κ» μΈ λλ§ μλ―Έκ° μλ€. 미리 μ½κΈ°λ₯Ό μννμ§ μλλ€. μ¦ μ΄λ―Έ λ¨ λ΄μ μλ νμ΄μ§μλ§ νμ΄μ§ ν μ΄λΈ νλͺ©μ λ§λ λ€. 리λ μ€ 2.6.23λΆν°λ μ΄ νλκ·Έλ₯Ό μ°λ©΄MAP_POPULATE
κ° μ무κ²λ νμ§ μκ² λλ€. μΈμ κ°MAP_POPULATE
μMAP_NONBLOCK
μ μ‘°ν©μ΄ μ¬κ΅¬νλ μλ μλ€. MAP_NORESERVE
- μ΄ λ§€νμ μν μ€μ 곡κ°μ μλΉν΄ λμ§ μλλ€. μ€μ 곡κ°μ΄ μλΉλΌ μμ λλ λ§€νμ λ³κ²½νλ κ² κ°λ₯νλ€κ³ 보μ₯λλ€. μ€μ 곡κ°μ΄ μλΉλΌ μμ§ μμ λλ μ¬μ© κ°λ₯ν 물리μ λ©λͺ¨λ¦¬κ° μμΌλ©΄ μ°κΈ° μ
SIGSEGV
λ₯Ό λ°μ μλ μλ€. proc(5)μ/proc/sys/vm/overcommit_memory
νμΌ λ Όμλ μ°Έκ³ νλΌ. 2.6 μ μ 컀λμμλ λΉκ³΅μ μ°κΈ° κ°λ₯ λ§€νμλ§ μ΄ νλκ·Έκ° ν¨κ³Όκ° μμλ€. -
MAP_POPULATE
(리λ μ€ 2.5.46λΆν°) - λ§€νμ λν νμ΄μ§ ν
μ΄λΈμ μ±μ΄λ€ (미리 ν΄νΈ). νμΌ λ§€νμΈ κ²½μ° νμΌμμ 미리 μ½κΈ°λ₯Ό νκ² νλ€. μ΄ν νμ΄μ§ ν΄νΈμμ λ§νλ κ±Έ μ€μ΄λ λ° λμμ΄ λ κ²μ΄λ€. λΉκ³΅μ λ§€νμλ 리λ
μ€ 2.6.23λΆν°
MAP_POPULATE
λ₯Ό μ§μνλ€. -
MAP_STACK
(리λ μ€ 2.6.27λΆν°) - νλ‘μΈμ€λ μ€λ λ μ€νμ μ ν©ν μ£Όμμ λ§€νμ ν λΉνλ€. μ΄ νλκ·Έλ νμ¬ no-opμ§λ§ glibc μ€λ λ© κ΅¬νμμ μ¬μ©νλλ°, μΌλΆ μν€ν μ²μμ μ€ν ν λΉμ νΉλ³ν μ²λ¦¬λ₯Ό μνλ κ²½μ° λμ€μ ν¬λͺ νκ² μ§μμ ꡬνν μ μκΈ° μν΄μλ€.
-
MAP_SYNC
(리λ μ€ 4.15λΆν°) -
μ΄ νλκ·Έλ
MAP_SHARED_VALIDATE
λ§€ν μ νμλ§ μ¬μ© κ°λ₯νλ€.MAP_SHARED
μ ν λ§€νμμλ μ΄ νλκ·Έλ₯Ό μ‘°μ©ν 무μνλ€. DAX(μμ λ©λͺ¨λ¦¬ μ§μ λ§€ν) μ§μ νμΌμμλ§ μ΄ νλκ·Έλ₯Ό μ§μνλ€. κ·Έλ μ§ μμ νμΌμμ μ΄ νλκ·Έλ‘ λ§€νμ λ§λ€λ €κ³ νλ©΄EOPNOTSUPP
μ€λ₯κ° λ°μνλ€.μ΄ νλκ·Έλ₯Ό μ΄ κ³΅μ νμΌ λ§€νμμλ νλ‘μΈμ€ μ£Όμ 곡κ°μ μ΄λ€ λ©λͺ¨λ¦¬κ° μ°κΈ° κ°λ₯νκ² λ§΅ λμ΄ μλ λμμ μμ€ν μ΄ μ£½κ±°λ μ¬λΆν λ νμλ λμΌ νμΌμ λμΌ μ€νμ μμ κ·Έ λ΄μ©μ λ³Ό μ μλ€κ³ 보μ₯λλ€. μ μ ν CPU μΈμ€νΈλμ κ³Ό ν¨κ» μ¬μ©νλ©΄ λ ν¨μ¨μ μΈ λ°©μμΌλ‘ λ°μ΄ν° λ³κ²½μ μμμν€λ λ§€νμ΄ κ°λ₯ν΄μ§λ€.
-
MAP_UNINITIALIZED
(리λ μ€ 2.6.33λΆν°) - μ΅λͺ
νμ΄μ§ λ΄μ©μ λΉμ°μ§ μλλ€. μ΄ νλκ·Έλ μλ² λλ μ₯μΉμμ μ±λ₯μ κ°μ νκΈ° μν κ²μ΄λ€. 컀λμ΄
CONFIG_MMAP_ALLOW_UNINITIALIZED
μ΅μ μΌλ‘ ꡬμ±λ κ²½μ°μλ§ μ΄ νλκ·Έλ₯Ό λ°λ₯Έλ€. 보μμ ν¨μ λλ¬Έμ λ³΄ν΅ μλ² λλ μ₯μΉμμλ§ (μ¦ μ¬μ©μ λ©λͺ¨λ¦¬ λ΄μ©λ¬Όμ μμ ν ν΅μ κ° μ΄λ€μ§λ μ₯μΉμμλ§) μ΄ μ΅μ μ μΌ λ€.
μ νλκ·Έλ€ μ€ MAP_FIXED
λ§ POSIX.1-2001 λ° POSIX.1-2008μ λͺ
μΈλμ΄ μλ€. νμ§λ§ λ§μ μμ€ν
μμ MAP_ANONYMOUS
λ (λλ λμμ΄μΈ MAP_ANON
μ) μ§μνλ€.
mmap()
μΌλ‘ λ§΅ ν λ©λͺ¨λ¦¬λ fork(2)λ₯Ό κ±°μΉλ©° κ°μ μμ±μΌλ‘ μ μ§λλ€.
νμΌμ νμ΄μ§ ν¬κΈ°μ λ°°μλ‘ λ§΅ λλ€. νμΌ ν¬κΈ°κ° νμ΄μ§ ν¬κΈ°μ λ°°μκ° μλ κ²½μ° λ§΅ ν λ λλ¨Έμ§ λ©λͺ¨λ¦¬λ₯Ό 0μΌλ‘ μ±μ°λ©° κ·Έ μμμ μ΄ κ²μ΄ νμΌμ κΈ°λ‘λμ§ μλλ€. λ§€ν κΈ°λ° νμΌμ ν¬κΈ°κ° λ°λ λ νμΌμ μΆκ°λκ±°λ μ κ±°λλ μμμ λμνλ νμ΄μ§λ€μ μ΄λ€ μν₯μ μ£Όλμ§λ λͺ μΈλμ΄ μμ§ μλ€.
munmap()
μμ€ν
νΈμΆμ μ§μ ν μ£Όμ λ²μμ λν λ§€νμ μμ νκ³ κ·Έ λ²μ λ΄ μ£Όμμ λν μ΄ν μ°Έμ‘°κ° λΉμ ν¨ λ©λͺ¨λ¦¬ μ°Έμ‘°λ₯Ό μΌμΌν€λλ‘ νλ€. νλ‘μΈμ€κ° μ’
λ£ν λλ μλμΌλ‘ ν΄μ νλ€. λ°λ©΄ νμΌ λμ€ν¬λ¦½ν°λ₯Ό λ«λ κ²μΌλ‘λ λ§΅μ ν΄μ νμ§ μλλ€.
μ£Όμ addr
μ νμ΄μ§ ν¬κΈ°μ λ°°μμ¬μΌ νλ€. (length
λ κ·Έλ΄ νμκ° μλ€.) μ§μ ν λ²μμ μΌλΆλΌλ λ΄μ λͺ¨λ νμ΄μ§λ€μ΄ ν΄μ λλ©° μ΄ν κ·Έ νμ΄μ§λ€μ λν μ°Έμ‘°κ° SIGSEGV
λ₯Ό μΌμΌν€κ² λλ€. μ§μ ν λ²μ μμ λ§΅ λ νμ΄μ§κ° μλλΌλ μ€λ₯κ° μλλ€.
μ±κ³΅ μ mmap()
μ λ§΅ ν μμμ λν ν¬μΈν°λ₯Ό λ°ννλ€. μ€λ₯ μ MAP_FAILED
κ°(μ¦ (void *) -1
)μ λ°ννλ©° μ€λ₯ μμΈμ λνλ΄λλ‘ errno
λ₯Ό μ€μ νλ€.
μ±κ³΅ μ munmap()
μ 0μ λ°ννλ€. μ€ν¨ μ -1μ λ°ννλ©° μ€λ₯ μμΈ(μλ§ EINVAL
)μ λνλ΄λλ‘ errno
λ₯Ό μ€μ νλ€.
EACCES
- νμΌ λμ€ν¬λ¦½ν°κ° λΉμ κ· νμΌμ κ°λ¦¬ν€κ³ μλ€. λλ νμΌ λ§€νμ μμ²νλλ°
fd
κ° μ½κΈ° κ°λ₯νκ² μ΄λ € μμ§ μλ€. λλMAP_SHARED
λ₯Ό μμ²νκ³PROT_WRITE
κ° μ€μ λΌ μλλ°fd
κ° μ½κΈ°/μ°κΈ° λͺ¨λ(O_RDWR
)λ‘ μ΄λ € μμ§ μλ€. λλPROT_WRITE
κ° μ€μ λΌ μλλ° νμΌμ΄ λ§λΆμ μ μ©μ΄λ€. EAGAIN
- νμΌμ΄ μ 겨 μκ±°λ λ무 λ§μ λ©λͺ¨λ¦¬κ° κ³ μ λΌ μλ€. (setrlimit(2) μ°Έκ³ .)
EBADF
-
fd
κ° μ ν¨ν νμΌ λμ€ν¬λ¦½ν°κ° μλλ€. (그리κ³MAP_ANONYMOUS
λ₯Ό μ€μ νμ§ μμλ€.) EEXIST
-
flags
μMAP_FIXED_NOREPLACE
λ₯Ό μ§μ νμΌλ©°addr
κ³Όlength
κ° λνλ΄λ λ²μκ° κΈ°μ‘΄ λ§€νκ³Ό μΆ©λνλ€. EINVAL
-
addr
,length
,offset
μ΄ λ§μμ λ€μ§ μλλ€. (κ°λ Ή λ무 ν¬κ±°λ νμ΄μ§ κ²½κ³μ μ λ ¬λΌ μμ§ μλ€.) EINVAL
- (리λ
μ€ 2.6.12λΆν°)
length
κ° 0μ΄λ€. EINVAL
-
flags
μMAP_PRIVATE
κ³ΌMAP_SHARED
μ΄λ μͺ½λ μκ±°λ λ λ€ ν¬ν¨λΌ μλ€. ENFILE
- μ΄λ¦° νμΌ μ΄κ°μμ λν μμ€ν μ μ μ νμ λλ¬νλ€.
ENODEV
- μ§μ ν νμΌμ κΈ°λ° νμΌ μμ€ν μ΄ λ©λͺ¨λ¦¬ λ§€νμ μ§μνμ§ μλλ€.
ENOMEM
- μ¬μ© κ°λ₯ν λ©λͺ¨λ¦¬κ° μλ€.
ENOMEM
- νλ‘μΈμ€μ λ§€ν μ΅λ κ°μλ₯Ό μ΄κ³Όνλ € νλ€.
munmap()
μμλ μ΄ μ€λ₯κ° λ°μν μ μλλ°, κΈ°μ‘΄ λ§€νμ μ€κ° λΆλΆμ λ§΅ ν΄μ νλ©΄ κ·Έ μμͺ½μΌλ‘ μμ λ§€ν λ κ°κ° μκΈ°κΈ° λλ¬Έμ΄λ€. ENOMEM
- (리λ
μ€ 4.7λΆν°) νλ‘μΈμ€μ
RLIMIT_DATA
μ ν(getrlimit(2)μμ μ€λͺ ν¨)μ μ΄κ³Όνλ € νλ€. EOVERFLOW
- 32λΉνΈ μν€ν
μ²μ ν° νμΌ νμ₯(μ¦ 64λΉνΈ
off_t
)μ μ°λ κ²½μ°:length
λ₯Ό μν νμ΄μ§ κ°μμoffset
μ μν νμ΄μ§ κ°μλ₯Ό λνλ©΄unsigned long
(32λΉνΈ)μ λκ² λλ€. EPERM
-
prot
μΈμμμPROT_EXEC
λ₯Ό μμ²νλλ° λ§΅ μμμ΄ μ€ν λΆκ°λ₯νκ² λ§μ΄νΈ λ νμΌ μμ€ν μμ νμΌμ μν΄ μλ€. EPERM
- νμΌ λ΄μΈ λλ¬Έμ λμμ΄ λ§νλ€. fcntl(2) μ°Έκ³ .
ETXTBSY
-
MAP_DENYWRITE
κ° μ€μ λΌ μμ§λ§fd
λ‘ μ§μ ν κ°μ²΄κ° μ°κΈ° κ°λ₯νκ² μ΄λ € μλ€.
λ§΅ ν μμμ μ¬μ©ν λ λ€μ μκ·Έλμ΄ λ°μν μ μλ€.
SIGSEGV
- μ½κΈ° μ μ©μΌλ‘ λ§΅ ν μμμ μ°κΈ°λ₯Ό μλνλ€.
SIGBUG
- νμΌμ λμνμ§ μλ λ²νΌ λΆλΆμ μ κ·Όμ μλνλ€. (μλ₯Ό λ€μ΄ νμΌ λ λλ¨Έμ μ κ·ΌνκΈ°. λ€λ₯Έ νλ‘μΈμ€κ° νμΌμ μλΌλ΄λ κ²½μ° ν¬ν¨.)
μ΄ μ μμ μ¬μ©νλ μ©μ΄λ€μ λν μ€λͺ μ attributes(7)λ₯Ό 보λΌ.
μΈν°νμ΄μ€ | μμ± | κ° |
---|---|---|
mmap() , munmap()
|
μ€λ λ μμ μ± | MT-Safe |
POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD.
mmap()
, msync(2), munmap()
μ΄ μ¬μ© κ°λ₯ν POSIX μμ€ν
μλ <unistd.h>
μ _POSIX_MAPPED_FILES
κ° 0λ³΄λ€ ν° κ°μΌλ‘ μ μλμ΄ μλ€. (sysconf(3)λ μ°Έκ³ .)
μΌλΆ νλμ¨μ΄ μν€ν
μ²(κ°λ Ή i386)μμλ PROT_WRITE
κ° PROT_READ
λ₯Ό ν¨μνλ€. μν€ν
μ²μ λ°λΌ PROT_READ
κ° PROT_EXEC
λ₯Ό ν¨μνλμ§ μ¬λΆκ° λ€λ₯΄λ€. μ΄μ κ°λ₯ν νλ‘κ·Έλ¨μμλ μ λ§€ν λ΄μ μ½λλ₯Ό μ€νν μμ μ΄λ©΄ νμ PROT_EXEC
λ₯Ό μ€μ νλ κ² μ’λ€.
λ§€νμ λ§λλ μ΄μμ± μλ λ°©λ²μ addr
μ 0(NULL)μΌλ‘ μ§μ νκ³ flags
μμ MAP_FIXED
λ₯Ό λΉΌλ κ²μ΄λ€. μ΄λ κ² νλ κ²½μ° λ§€νμ μΈ μ£Όμλ₯Ό μμ€ν
μ΄ μ ννλ€. κΈ°μ‘΄ λ§€νκ³Ό μΆ©λνμ§ μμΌλ©° 0μ΄ μλκ² μ£Όμλ₯Ό μ ννλ€. MAP_FIXED
νλκ·Έλ₯Ό μ§μ νλ κ²½μ° addr
μ΄ 0(NULL)μ΄λ©΄ λ§΅ ν μ£Όμκ° 0(NULL)μ΄ λλ€.
μ΄λ€ flags
μμλ€μ μ μ ν κΈ°λ₯ νμΈ λ§€ν¬λ‘κ° (λλ‘ κΈ°λ³ΈμΌλ‘) μ μλΌ μλ κ²½μ°μλ§ μ μλΌ μλ€. glibc 2.19 λ° μ΄νμμλ _DEFAULT_SOURCE
, glibc 2.19 λ° μ΄μ μμλ _BSD_SOURCE
λ _SVID_SOURCE
μ΄λ€. (_GNU_SOURCE
μ¬μ©μΌλ‘λ μΆ©λΆνλ©°, λͺ
νν μ΄ λ§€ν¬λ‘λ₯Ό μ건μΌλ‘ νλ κ² λ λ
Όλ¦¬μ μΌ μλ μλ κ²μ΄, κ·Έ νλκ·Έλ€ λͺ¨λ 리λ
μ€ μ μ©μ΄λ€.) ν΄λΉνλ νλκ·Έλ MAP_32BIT
, MAP_ANONYMOUS
(λ° λμμ΄μΈ MAP_ANON
), MAP_DENYWRITE
, MAP_EXECUTABLE
, MAP_FILE
, MAP_GROWSDOWN
, MAP_HUGETLB
, MAP_LOCKED
, MAP_NONBLOCK
, MAP_NORESERVE
, MAP_POPULATE
, MAP_STACK
μ΄λ€.
μμ©μμ mincore(2)λ₯Ό μ¬μ©νλ©΄ λ§€νμ μ΄λ€ νμ΄μ§κ° νμ¬ λ²νΌ/νμ΄μ§ μΊμμ μμ£Ό μ€μΈμ§ μμλΌ μ μλ€.
MAP_FIXED
λ₯Ό μμ νκ² μΈ μ μλ μ μΌν κ²½μ°λ addr
κ³Ό length
λ‘ μ§μ ν μ£Όμ λ²μκ° μ΄λ―Έ λ€λ₯Έ λ§€νμ ν΅ν΄ μ‘ν μμ λμ΄λ€. κ·Έ μΈ κ²½μ°μμλ MAP_FIXED
μ¬μ©μ΄ κ·Ήν μννλ°, κΈ°μ‘΄μ μλ λ§€νμ κ°μ λ‘ μμ λ―λ‘ λ€μ€ μ€λ λ νλ‘μΈμ€μμ μκΈ° μ£Όμ 곡κ°μ μ€μΌμν€κΈ° μ½κ² λκΈ° λλ¬Έμ΄λ€.
μλ₯Ό λ€μ΄ μ€λ λ Aκ° /proc/<pid>/maps
λ₯Ό μ΄ν΄λ΄μ MAP_FIXED
λ‘ λ§΅ ν μ μλ μ μ°λ μ£Όμ λ²μλ₯Ό μ°Ύλ λμ μ€λ λ Bκ° λμμ κ°μ μ£Όμ λ²μμ μΌλΆ λ΄μ§ μ 체λ₯Ό νλν μ μλ€. κ·Έλ¬κ³ μ μ€λ λ Aκ° mmap(MAP_FIXED)
λ₯Ό μ¬μ©νλ©΄ μ€λ λ Bκ° λ§λ λ§€νμ μ€μ§μ μΌλ‘ μμμν€κ² λλ€. μ΄ κ²½μ°μμ μ€λ λ Bκ° κΌ λ§€νμ μ§μ μμ±ν΄μΌ νλ 건 μλλ€. λ΄λΆμ μΌλ‘ dlopen(3)μ μ¨μ μ΄λ€ λ€λ₯Έ 곡μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ μ¬νλ λΌμ΄λΈλ¬λ¦¬ νΈμΆμ νλ κ²λ§μΌλ‘ μΆ©λΆνλ€. κ·Έ dlopen(3) νΈμΆμ΄ λΌμ΄λΈλ¬λ¦¬λ₯Ό νλ‘μΈμ€μ μ£Όμ 곡κ°μΌλ‘ λ§΅ νκ² λλ€. λΏλ§ μλλΌ κ±°μ λͺ¨λ λΌμ΄λΈλ¬λ¦¬ νΈμΆμ΄ μ΄ κΈ°λ²μ΄λ λ¨μ λ©λͺ¨λ¦¬ ν λΉμ ν΅ν΄ μ£Όμ 곡κ°μ λ©λͺ¨λ¦¬ λ§€νμ μΆκ°νλλ‘ κ΅¬νλμ΄ μμ μ μλ€. brk(2), malloc(3), pthread_create(3), PAM λΌμ΄λΈλ¬λ¦¬(http://www.linux-pam.org) λ±μ΄ κ·Έ μμ΄λ€.
리λ
μ€ 4.17λΆν°λ λ€μ€ μ€λ λ νλ‘κ·Έλ¨μμ MAP_FIXED_NOREPLACE
νλκ·Έλ₯Ό μ¬μ©ν΄μ κΈ°μ‘΄ λ§€νμΌλ‘ μμ½λΌ μμ§ μμ κ³ μ μ£Όμμ λ§€νμ λ§λ€λ € ν λ μμμ μ€λͺ
ν μνμ νΌν μ μλ€.
νμΌ κΈ°λ° λ§€νμμλ mmap()
κ³Ό λμνλ λ§΅ ν΄μ μ¬μ΄μ μ΄λ μμ μλ λ§΅ λ νμΌμ st_atime
νλκ° κ°±μ λ μ μλ€. λ§΅ λ νμ΄μ§μ μ²μ μ°Έμ‘°ν λ κ·Έ νλκ° μμ§ κ°±μ λμ§ μμμΌλ©΄ κ°±μ νκ² λλ€.
PROT_WRITE
λ° MAP_SHARED
λ‘ λ§΅ ν νμΌμ st_ctime
λ° st_mtime
νλλ λ§΅ μμμ λν μ°κΈ° νμ, κ·Έλ¦¬κ³ μ΄ν MS_SYNC
λ΄μ§ MS_ASYNC
νλκ·Έλ‘ msync(2) νλ κ²½μ° κ·Έ μ μ κ°±μ λλ€.
κ±°λ νμ΄μ§λ₯Ό μ΄μ©νλ λ§€νμμλ mmap()
κ³Ό munmap()
μΈμμ λν μκ±΄μ΄ μμ€ν
κΈ°λ³Έ νμ΄μ§ ν¬κΈ°λ₯Ό μ°λ λ§€νμ λν μ건과 μ’ λ€λ₯΄λ€.
mmap()
μμλ offset
μ΄ κΈ°λ° κ±°λ νμ΄μ§ ν¬κΈ°μ λ°°μμ¬μΌ νλ€. μμ€ν
μμ length
λ₯Ό κΈ°λ° κ±°λ νμ΄μ§ ν¬κΈ°μ λ°°μλ‘ μλμΌλ‘ λ§μΆλ€.
munmap()
μμλ addr
κ³Ό length
κ° λͺ¨λ κΈ°λ° κ±°λ νμ΄μ§ ν¬κΈ°μ λ°°μμ¬μΌ νλ€.
μ΄ νμ΄μ§μμλ glibcμ mmap()
λνΌ ν¨μκ° μ 곡νλ μΈν°νμ΄μ€λ₯Ό κΈ°μ νλ€. μλλ κ·Έ ν¨μμμ μ΄λ¦μ΄ κ°μ μμ€ν
νΈμΆμ λΆλ λ€. 컀λ 2.4λΆν° κ·Έ μμ€ν
νΈμΆμ΄ mmap2(2)λ‘ λ체λκ³ , κ·Έλμ μμ¦μλ glibcμ mmap()
λνΌ ν¨μμμ μ μ ν μ‘°μ ν offset
κ°μΌλ‘ mmap2(2)λ₯Ό λΆλ₯Έλ€.
리λ
μ€μμλ μμ MAP_NORESERVE
μμ μΈκΈνλ κ²λ€μ 보μ₯νμ§ μλλ€. κΈ°λ³Έμ μΌλ‘ μμ€ν
μ λ©λͺ¨λ¦¬κ° λΆμ‘±ν λλ μΈμ μ΄λ νλ‘μΈμ€λ μ£½μ μ μλ€.
컀λ 2.6.7 μ μμλ prot
λ₯Ό PROT_NONE
μΌλ‘ μ§μ ν κ²½μ°μλ§ MAP_POPULATE
νλκ·Έμ ν¨λ ₯μ΄ μλ€.
SUSv3μμλ length
κ° 0μ΄λ©΄ mmap()
μ΄ μ€ν¨νλ κ² μ’λ€κ³ λͺ
μΈνλ€. νμ§λ§ 컀λ 2.6.12 μ μμλ μ΄ κ²½μ°μ mmap()
μ΄ μ±κ³΅νλ€. μ무 λ§€νλ λ§λ€μ§ μκ³ νΈμΆμ΄ addr
μ λ°ννλ€. 컀λ 2.6.12λΆν°λ μ΄ κ²½μ°μ mmap()
μ΄ EINVAL
μ€λ₯λ‘ μ€ν¨νλ€.
POSIXμμλ κ°μ²΄ λμ λΆλΆ νμ΄μ§λ₯Ό νμ μμ€ν μμ 0μΌλ‘ μ±μμΌ νλ©° κ°μ²΄ λ λλ¨Έμμμ λ³κ²½ λ΄μ©μ μμ€ν μ΄ μ λ κΈ°λ‘νμ§ μλλ€κ³ λͺ μΈνλ€. 리λ μ€μμ κ·Έλ° κ°μ²΄ λ λ€μμ λΆλΆ νμ΄μ§μ λ°μ΄ν°λ₯Ό μ°λ κ²½μ° νμΌμ΄ λ«νκ³ λ§΅μ΄ ν΄μ λ νμ μ λ νμΌμλ κΈ°λ‘λμ§ μμ§λ§ λ°μ΄ν°κ° νμ΄μ§ μΊμ λ΄μ λ¨μμ μ΄ν λ§€νμμ κ·Έ λ³κ²½λ λ΄μ©μ λ³Ό μλ μλ€. μ΄λ€ κ²½μ°μλ λ§΅ ν΄μ μ μ msync(2)λ₯Ό νΈμΆν΄μ κ³ μΉ μλ μμ§λ§ tmpfs(5)μμλ (μλ₯Ό λ€μ΄ shm_overview(7)μ κΈ°λ‘λ POSIX 곡μ λ©λͺ¨λ¦¬ μΈν°νμ΄μ€λ₯Ό μΈ λλ) ν΅νμ§ μλλ€.
λ€μ νλ‘κ·Έλ¨μ 첫 λ²μ§Έ λͺ
λ Ήν μΈμμ μ§μ ν νμΌμ μΌλΆλ₯Ό νμ€ μΆλ ₯μΌλ‘ μ°λλ€. λ λ²μ§Έμ μΈ λ²μ§Έ λͺ
λ Ήν μΈμμ μ€νμ
λ° κΈΈμ΄ κ°μ ν΅ν΄ μ°μ λ²μλ₯Ό μ§μ νλ€. νλ‘κ·Έλ¨μμ νμΌμ νμν νμ΄μ§λ€λ‘ λ©λͺ¨λ¦¬ λ§€νμ λ§λ λ€μ write(2)
λ₯Ό μ¨μ μνλ λ°μ΄νΈλ€μ μΆλ ₯νλ€.
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(int argc, char *argv[])
{
char *addr;
int fd;
struct stat sb;
off_t offset, pa_offset;
size_t length;
ssize_t s;
if (argc < 3 || argc > 4) {
fprintf(stderr, "%s file offset [length]\n", argv[0]);
exit(EXIT_FAILURE);
}
fd = open(argv[1], O_RDONLY);
if (Fd == -1)
handle_error("open");
if (fstat(fd, &sb) == -1) /* νμΌ ν¬κΈ° μ»κΈ° */
handle_error("fstat");
offset = atoi(argv[2]);
pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
/* mmap() μ€νμ
μ΄ νμ΄μ§μ μ λ ¬λΌ μμ΄μΌ ν¨ */
if (offset >= sb.st_size) {
fprintf(stderr, "offset is past end of file\n");
exit(EXIT_FAILURE);
}
if (argc == 4) {
length = atoi(argv[3]);
if (offset + length > sb.st_size)
length = sb.st_size - offset;
/* νμΌ λ λλ¨Έμ λ°μ΄νΈλ νμν μ μμ */
} else { /* length μΈμ μμ ==> νμΌ λκΉμ§ νμ */
length = sb.st_size - offset;
}
addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
MAP_PRIVATE, fd, pa_offset);
if (addr == MAP_FAILED)
handle_error("mmap");
s = write(STDOUT_FILENO, addr + offset - pa_offset, length);
if (s != length) {
if (s == -1)
handle_error("write");
fprintf(stderr, "partial write");
exit(EXIT_FAILURE);
}
munmap(addr, length + offset - pa_offset);
close(fd);
exit(EXIT_SUCCESS);
}
ftruncate(2), getpagesize(2), memfd_create(2), mincore(2), mlock(2), mmap2(2), mprotect(2), mremap(2), msync(2), remap_file_pages(2), setrlimit(2), shmat(2), userfaultfd(2), shm_open(3), shm_overview(7)
proc(5) λ΄μ /proc/[pid]/maps
, /proc/[pid]/map_files
, /proc/[pid]/smaps
νμΌμ λν μ€λͺ
.
B.O. Gallmeister, POSIX.4, O'Reilly, 128-129μͺ½ λ° 389-391μͺ½.
2019-02-27