7 장 파일시스템 파일시스템의개요 ext2 파일시스템 파일시스템관련자료구조 NFS 파일시스템 proc 파일시스템 한빛미디어 ( 주 )
Section 01 파일시스템의개요 파일 디스크와같은물리적인저장매체에저장되는프로그램 데이터정보에대한논리적인저장단위 파일시스템 파일을어떻게관리할것인가에대한정책 파일을저장하고또한찾기가용이하도록유지및관리하는방법 파일 + 디렉토리구조 ext2, ext3, ex4, msdos, ntfs, iso9660, minix, vfat, proc, smb, ncp, sysv, hpfs, affs, ufs 다양한파일시스템을지원하기위해가상파일시스템 (VFS:Virtual File System) 을도입 2
Section 01 파일시스템의개요 가상파일시스템 (abstraction layer) 다양한파일시스템을일관된형태로인식할수있도록하는기법 [ 그림 7-1] 가상파일시스템의역할 3
Section 01 파일시스템의개요 파일저장공간의할당방법 파일시스템은파일을디스크블록이라는논리적인단위의집합으로관리 사용자가파일을디스크에저장하기를요청하면파일은이블록단위로분할되어파일시스템의정책에따라일정한장소에내용을기록 블록의크기 1KB, 4KB, 16KB, 64KB 등 디스크블록과대응되는섹터 (512 byte) 들을매핑하는역할은디스크디바이스드라이버 ( 디스크컨트롤러 ) 가수행 (p271 예 ) 파일크기 100KB, 블록크기 4KB: 25 개디스크블록 (200 개섹터 ) 할당 연속할당 vs 불연속할당 4
Section 01 파일시스템의개요 연속할당 디스크내의연속된블록을하나의파일에순차적으로할당하는방법 가용공간을선택하는방법 최초적합 (first-fit), 최적적합 (best-fit), 최악적합 (worst-fit) 방법 외부단편화발생 파일의크기가가변적으로변화되는경우연속적인할당이불가능 해결방법은? [ 그림 7-2] 디스크블록할당예 5
Section 01 파일시스템의개요 불연속할당 불연속적인공간에흩어진디스크블록에나누어저장하는방법 구현방법 연결할당 (Linked Allocation), 인덱스할당 (Indexed Allocation) 기법 연결할당 흩어진블록들을연결리스트로관리하는기법 순차접근인경우에는효과적인지만직접접근방식에서는매우비효율적» DOS와같은운영체제 : FAT 기법사용 인덱스할당 디스크블록에대한위치정보를가지고있는인덱스블록을사용» 블록이할당될때마다해당엔트리에정보를기록» 직접접근문제는해결, 인덱스블록을유지하는비용문제가발생 파일이커지면하나의인덱스블록만으로관리불가능» 여러개의인덱스블록이필요하면이를연결리스트로관리 리눅스는 inode를이용한 inode 기법을사용 6
Section 02 ext2 파일시스템 ext2 파일시스템의이해 EXT(Extended File System) EXT2 EXT3 EXT4 EXT3 파일시스템 EXT2 파일시스템에저널링기능을추가 데이터의신뢰성을강화하고, 속도를향상시킨파일시스템 mke2fs 파일시스템을만드는명령어 블록의크기 -b 옵션을사용하여 1024, 2048, 4096를지정가능» 생략시 4096 7
Section 02 ext2 파일시스템 ext4: Extended File System 4 또는 ext4 는차세대저널링파일시스템이며이전파일시스템인 ext3 과의호환성도제공 http://www.ibm.com/developerworks/kr/library/l-anatomy-ext4/index.html Linux 를지원하는최초의파일시스템은 Minix 파일시스템이었지만이파일시스템에는몇가지심각한성능문제가있었기때문에 Extended File System 이라는파일시스템이 Linux 를위해특별히개발되었다. Remy Card 가설계한첫번째 Extended File System(ext) 은 1992 년 4 월에 Linux 에채택되었다. ext 파일시스템은 0.96c 커널에구현된 VFS(Virtual File System) 스위치를최초로사용했으며최대 2GB 크기의파일시스템을지원했다. 두번째 Extended File System(ext2) 또한 Remy Card 가구현했으며 1993 년 1 월에발표되었다. 이파일시스템은 Berkeley FFS(Fast File System) 와같은당시의다른파일시스템의발전된아이디어를채택했다. Ext2 에서는지원되는파일시스템의크기가 2TB 로확장되었으며 2.6 커널에서는 ext2 파일시스템의최대크기가 32TB 로확장되었다. 세번째 Extended File System(ext3) 은일부경쟁파일시스템에비해성능이떨어지기는했지만 Linux 파일시스템의맥락에서는크게발전한모습을보여준파일시스템이다. ext3 파일시스템에서는예기치않게시스템이중단되었을때파일시스템의신뢰성을높여주는저널링개념이도입되었다. Silicon Graphics 의 XFS 및 IBM JFS(Journaled File System) 와같은경쟁파일시스템의성능이더좋기는했지만 ext3 은이미 ext2 를사용하고있는시스템에서직접업그레이드할수있는기능을지원했다. Ext3 은 2001 년 11 월에발표되었으며 Stephen Tweedie 가구현했다. 현재, 네번째 Extended File System(ext4) 이발표되었다. Ext4 에는성능, 확장성및신뢰성을향상시킨수많은새기능이도입되었다. 가장눈에띄는특징은 ext4 가 1EB(exabyte) 의파일시스템을지원한다는것이다. Ext4 는 ext3 를유지관리해온 Theodore Tso 가이끄는개발자팀에의해구현되어 2.6.19 커널에채택되었다. 그리고지금은 2.6.28 커널에이르러안정적인상태로유지되고있다 (2008 년 12 월현재 ). Ext4 에는다양한경쟁파일시스템의유용한개념이적용되었다. 예를들어, 익스텐트를사용하여블록을관리하는방법은 JFS 에서구현했으며또다른블록관련기능인지연된할당은 XFS 와 Sun Microsystems 의 ZFS 에서구현했다. 새로운 ext4 파일시스템에서는혁신적으로개선된다양한기능을볼수있다. 새롭게추가된기능, 현재파일시스템의한계를뛰어넘은우수한확장성, 오류에효과적으로대응할수있는신뢰성및뛰어난성능에이르기까지파일시스템의모든부분에서개선된사항을발견할수있다. 8
Section 02 ext2 파일시스템 ext2 파일시스템의블록구성 GRUB [ 그림 7-3] ext2 파일시스템의블록구성 첫번째블록 ( 블록 0) 파티션부트섹터 (partition boot sector) 를위해예약 부트로더인 LILO 또는 GRUB이들어감 두번째블록 ( 블록 1) 부터 block group 0 이시작 파일시스템전체는여러개의 block group 으로구성 9
Section 02 ext2 파일시스템 block group 구성 super block, group descriptor, block bitmap, inode bitmap, inode tab le, data block 로구성됨 data block 들사이에는 directory block 도함께위치 block bitmap 1 개의블록을차지하며각 bit 가한블록의사용상태 (yes/no) 를나타냄 block bitmap 이관리할수있는블록의갯수» 블록크기 4Kbyte 로가정» 4K(=4096) x 8(bit)= 32768 개» 블록 32769 부터 2 번째블록그룹이시작 블록그룹 1 개의크기 블록크기에의해결정 크기가 4KB 이면 4K x 8(bit)x 4K byte=128mbyte 10
Section 02 ext2 파일시스템 수퍼블록 (Super block) 수퍼블록의이해 블록크기나 free 블록개수등파일시스템에전체에관한내용이포함 이부분은각그룹마다내용이동일 파일시스템이깨지는경우를대비하기위해수퍼블록의복사본을둠 1 번째그룹 ( 그룹 0) 의수퍼블록과 2 번째그룹 ( 그룹 1) 의수퍼블록의내용이동일 수퍼블록의자료구조 include/linux/ex2_fs.h 파일내에 373 행 : ext2_super_block 구조체로정의 dumpe2fs 명령 파일시스템전체정보를볼수있는명령어 ext2_super_block 구조체의멤버변수들을참조하여해당정보를보여줌 $ mount ( 또는 $ df ) 로파일시스템구조확인 $ dumpe2fs /dev/sda1 more 11
Section 02 ext2 파일시스템 dumpe2fs 수행화면 [ 그림 7-4] dumpe2fs /dev/hda2 수행화면 12
Section 02 ext2 파일시스템 수퍼블록에포함되는정보들 Magic Number(s_magic) 마운트하는커널로하여금이것이진짜 EXT2 파일시스템의수퍼블록임을확인할수있게한다. 0xEF53 을가짐 Revision Level(s_rev_level) major revision 번호와 minor revision 번호로구성 어떤특정한버전에서만지원되는기능여부를체크할때사용 Mount Count(s_mnt_count, s_max_mnt_count) 파일시스템이마운트될때마다 1 씩증가한다. Maximum Mount Count 와 Mount Count 값이같아지면최대마운트값에도달» 파일시스템체크프로그램 (e2fsck) 를실행 " 메시지표시 Block Count(s_blocks_count) 디스크블록수 13
Section 02 ext2 파일시스템 Block Size(s_log_block_size) 이파일시스템의블록크기를바이트단위로표시 Blocks per Group(s_blocks_per_group) 하나의그룹에속하는블록의개수 블록크기와마찬가지로파일시스템을만들때정해짐 Free Blocks(s_free_blocks_count) 파일시스템내의 free block 수 Free Inode(s_free_inodes_count) 파일시스템내의 free inode 수 Inodes per group(s_inodes_per_group) 각그룹당 inode 개수 14
Section 02 ext2 파일시스템 그룹디스크립터 (Group Descriptor) 각블록그룹을관리하는정보 전체적으로는하나의그룹디스크립터테이블형성 실제로사용되는것은블록그룹 0에있는첫번째복사본 나머지는원본이손상될경우를대비 ext2_group_desc 구조체에정의 Blocks Bitmap(bg_block_bitmap) 그룹내의블록의할당상태를나타내는 block bitmap 블록의위치를가리킴 Inode Bitmap(bg_inode_bitmap) 그룹내의 inode 의할당상태를나타내는 inode bitmap 블록의위치를가리킴 Inode Table(bg_inode_table) 그룹내의 inode 테이블의시작블록의위치를가리킴 15
Section 02 ext2 파일시스템 Free Blocks Count(bg_free_blocks_count) 그룹내의 free block 개수 Free Inode Count(bg_free_inodes_count) free 그룹내의 free inode 개수 Used Directory Count(bg_used_dirs_count) 그룹내에서사용된디렉토리개수 블록비트맵 (Block Bitmap) 각 bit는그룹내각블록의사용상태 (yes/no) 를나타냄커널은비어있는블록을찾을때이 block bitmap을참조파일시스템정보를담은블록 처음부터사용중으로표시 super block, group descriptor block, inode table block 등해당 16
Section 02 ext2 파일시스템 Inode bitmap 그룹내각 inode 의사용상태 (yes/no) 를나타냄 Inode table 각각의 inode 에대한정보를나타내는 inode descriptor 들로구성 하나의파일은 1 개의 inode 를가짐 ext2 파일시스템의 inode 자료구조는 ext2_inode 구조체 (include/linux/ex2_fs.h 242 행 ) 로정의 inode descriptor 의항목 Mode 파일 mode, 즉 read/write/execute 권한등을나타내는퍼미션 Owner Info(User ID 와 Group ID) 이파일 ( 또는디렉토리 ) 에대한사용자와그룹식별자 이정보를이용하여파일시스템은접근권한 (access permission) 을관리 Size: 파일의크기를바이트단위로가짐 Timestamps inode 가만들어진시간과최종적으로수정된시간을기록 17
Section 02 ext2 파일시스템 Blocks pointers array 파일의실제데이터가저장된위치 (= 블록번호 ) 를가리키는 15 개의포인터배열 blocks pointers 는동작방식에의해아래의 4 가지로나누어짐 Direct blocks pointer» 파일데이터가저장된블록에대한직접포인터 Indirect blocks pointer» 파일데이터가저장된블록에대한간접포인터 Double indirect pointer» 파일데이터가저장된블록에대한이중간접포인터 Triple indirect pointer» 파일데이터가저장된블록에대한삼중간접포인터 18
Section 02 ext2 파일시스템 Blocks pointers 동작 [ 그림 7-5] blocks pointers 동작 19
Section 02 ext2 파일시스템 지원가능한최대파일크기 가정 : a logical block=4kb Max. file size 1. Direct 12 entries : 48KB ( 4KB * 12 ) 2. Single indirect 1 entry : 4MB» 인덱스블록에는 1024 개의포인터가존재» 디스크블록에존재하며크기는 4KB» 디스크블록을가리키는포인터로구성, 각포인터를위해 4byte 가필요» 각포인터는 4KB 크기의블록을하나씩가리킴» 1024 * 4KB = 4MB 3. Double indirect 1 entry : 4GB» 1024 * 1024 * 4KB = 4GB 4. Triple indirect 1 entry : 4TB ( 아직까지는사용하지않음 )» 1024 * 1024 * 1024 * 4KB = 4TB ( 문제 ) 블록크기가 1KB 인경우의 Max.file size 는? 최대크기 : 48KB + 4MB + 4GB + 4TB 개념상 4TB 정도의파일지원가능 실제로 4GB(2GB) 까지지원» 리눅스의경우, 파일시스템의내부함수들이 32 비트로구현된인자나변수를사용되어있기때문에 4GB( 또는 2GB) 까지지원 20
Section 02 ext2 파일시스템 data block 파일의실제데이터가들어가는부분 파일시스템공간의대부분을차지 inode descriptor 의블록포인터는파일이저장되는블록번호를가리킴 directory block 필요에따라데이터블록사이사이에위치 해당디렉토리의엔트리 ( 즉파일, 디렉토리 ) 에대한정보를가짐 Inode Number inode table 내에서의 inode descriptor 위치를가리키는 inode 번호 File Name 파일 ( 디렉토리 ) 이름을가짐 256 byte 이며이름이들어가고남는 byte 는 0 으로채워짐 21
Section 03 파일시스템관련자료구조 task_struct 내의 files 와 fs 멤버변수 struct fs_struct *fs; (include/linux/sched.h 1266 행 ) struct files_struct *files; (include/linux/sched.h 1268 행 ) fs_struct (include/linux/fs_struct.h 6 행 ) 이구조체를사용하고있는프로세스의수에대한정보 루트디렉토리와현재작업디렉토리정보를갖는멤버변수로구성 files_struct (include/linux/fdtable.h 41 행 ) 파일을관리하기위한정보들 fd_array 변수 struct file * fd_array[nr_open_default]; NR_OPEN_DEFAULT : 32 로정의, 한번에열수있는파일의수 첫번째항 (fd_array[0]) 은표준입력, 두번째항은표준출력, 세번째항은표준에러로설정, 그다음부터는새로운파일을열때마다태스크가할당되어사용 struct fs_struct { int users; rwlock_t lock; int umask; int in_exec; struct path root, pwd; }; 22
Section 03 파일시스템관련자료구조 file 구조체의멤버변수 (include/linux/fs.h 838 행 ) f_dentry dentry 구조체를가리킴 f_pos 이구조체내의 d_inode 변수가 inode 를가리킴» 태스크의파일에대한 inode 는이와같은연결고리로 task_struct 와연결 현재파일에서읽거나쓸위치를나타냄 파일이처음열리면 0 으로설정 읽기또는쓰기연산이수행됨에따라위치가이동 f_op file_operations 자료구조를가리키는포인터 include/linux/fs.h 23 struct files_struct { /* * read mostly part */ atomic_t count; struct fdtable *fdt; struct fdtable fdtab; /* * written part on a separate cache line in SMP */ spinlock_t file_lock cacheline_aligned_in_smp; int next_fd; struct embedded_fd_set close_on_exec_init; struct embedded_fd_set open_fds_init; struct file * fd_array[nr_open_default]; }; struct file { union { struct list_head fu_list; struct rcu_head fu_rcuhead; } f_u; struct path f_path; #define f_dentry f_path.dentry #define f_vfsmnt f_path.mnt const struct file_operations *f_op; atomic_long_t f_count; unsigned int f_flags; fmode_t f_mode; loff_t f_pos; struct fown_struct f_owner; const struct cred *f_cred; struct file_ra_state f_ra; u64 f_version; void *private_data; struct address_space *f_mapping; };
Section 03 파일시스템관련자료구조 file_operations lseek, read, write, open 등과같은파일관련연산변수들로구성 각변수에는실제연산을수행하는함수의시작주소가등록 리눅스는정규파일, 디렉토리, 블록디바이스파일, 문자디바이스파일외에파이프, 링크, 소켓등다양한유형의파일을지원 커널은요청된파일이어떤유형인가에따라각파일에적합한함수를서비스함» file_operations 자료구조가이용됨 ext2 파일시스템에서파일을읽는방법과 NFS 의파일을읽는방법이다름 파일연산은각파일의유형에따라서로다른함수로구현됨 ext2 파일 : fs/ext2/file.c NFS 파일 : fs/nfs/file.c 사용자는일반함수사용으로파일사용가능 open() 또는 read() 함수로파일을열거나읽을수있음 파일이 ext2 파일시스템에속한경우에는 generic_file_open() 또는 generic_file_read() 함수를호출하여처리 24
Section 03 파일시스템관련자료구조 ext2 파일시스템의 file_operations 구조체 (fs/ext2/file.c 45 행 ) struct file_operations ext2_file_operations = { llseek: generic_file_llseek, read: generic_file_read, write: generic_file_write, ioctl: ext2_ioctl, mmap: generic_file_mmap, open: generic_file_open, release: ext2_release_file, fsync: ext2_sync_file, }; 25
Section 03 파일시스템관련자료구조 NFS 에서의 file_operations 구조체 (fs/nfs/file.c 61 행 ) struct file_operations nfs_file_operations = { llseek: generic_file_llseek, read: nfs_file_read, write: nfs_file_write, mmap: nfs_file_mmap, open: nfs_open, flush: nfs_file_flush, release: nfs_release, fsync: nfs_fsync, lock: nfs_lock, }; 26
Section 04 NFS 파일시스템 NFS 파일시스템의이해 TCP/IP 네트워크를통해다른컴퓨터의파일시스템을마치자신의로컬파일시스템처럼사용할수있게해줌 다른컴퓨터의하드디스크일부를내컴퓨터에부착된하드디스크처럼사용할수있음을의미 [ 그림 7-8] NFS 동작 27
Section 04 NFS 파일시스템 NFS 서버쪽 /etc/exports 파일설정 형식 : share-directory client1(options,,,) client2(options,,,) share-directory : 공유할디렉토리명 client1 options : 공유디렉토리에접근할수있도록허용된호스트들 : 접근권한설정 options ro : 클라이언트는공유디렉토리에대해읽기만가능하다. rw : 클라이언트는공유디렉토리에대해읽기 / 쓰기가가능하다. no_root_squash : 클라이언트의 root 는서버의 root 와같은권한을가진다. No_subtree_check : 공유된디렉토리내에있는서브디렉토리들을공유에서제외시키는경우설정 /etc/exports 파일설정예 # vi /etc/exports /home/user01 *.incheon.ac.kr(ro) /export/ftp/pub 192.168.1.1/255.255.255.0(ro) / banana(rw),kiwi(rw,no_root_squash) 8. Networking 28 28
Section 04 NFS 파일시스템 서버쪽방화벽이가동되고있다면공유가되지않는다. 따라서방화벽을꺼준다. # /sbin/service iptables stop 또는 # /etc/init.d/iptables stop 서버쪽 portmap 과 nfs 서비스를가동한다. * nfs 서비스는 portmap 서비스에의존하여가동되기때문에 portmap 서비스를먼저가동해야한다. # /sbin/service portmap start 또는 # /etc/init.d/portmap start Starting portmapper: [ OK ] # /sbin/service nfs start 또는 # /etc/init.d/nfs start Starting NFS services: [ OK ] Starting NFS quotas: [ OK ] Starting NFS daemon: [ OK ] Starting NFS mountd: [ OK ] 8. Networking 29 29
Section 04 NFS 파일시스템 NFS 클라이언트설정 # /etc/init.d/nfslock start or # /sbin/service nfslock start # mount.nfs Server IP Address:Server directory pass mount directory pass -v o proto=udp mount 예 # mount.nfs 117.16.244.156:/export/myshare /mnt -v o proto=udp 마운트실행시사용할수있는옵션들 -o timeo=10 : NFS 서버와연결이끊어진경우 timeo 에서지정한시간 (1/10 초단위 ) 기다렸다가경고메시지를발생 -o rsize=1024 wsize=1024 : 읽고 / 쓰기버퍼의크기를설정한다.(1024KB=1M) -o soft : remote mount 를실행할때성공하지못하면 timeo 까지만 retry 후에러메시지를발생하고종료 -o hard : remote mount 가성공할때까지무한시재시도한다. ( 디폴트값이다 ) -o bg : 첫번째마운트시도가실패인경우백그라운드로계속마운트를재시도한다. 시스템부팅시자동으로서버의파일시스템을마운트하도록설정한다. # vi /etc/fstab Server IP Address:Server directory pass mount directory pass nfs defaults NFS- 서버 :/export/myshare /mnt nfs defaults 8. Networking 30 30
Section 05 proc 파일시스템 proc 파일시스템의이해 디스크상에위치하는대신메모리상에위치하는파일시스템 /proc 시스템의정보나커널및현재실행중인태스크의각종정보포함 /proc/meminfo: 메모리사용의세부사항 /proc/version : 커널버전 /proc/devices : 설정되어있는장치의목록 /proc/dma : DMA 채널과관련된정보 /proc/filesystems : 설정된파일시스템의목록 /proc/interrupts : 현재사용중인인터럽트, 사용빈도에대한통계 /proc/ioports : 현재사용중인 I/O 포트들 /proc/kcore : 수행되고있는커널의실행이미지 /proc/kmsg : 커널이출력하는메시지 /proc/ksyms : 커널이사용하는심볼들의목록 /proc/loadavg : 시스템의평균부하량 /proc/modules : 현재사용중인커널모듈목록 lsmod 명령으로확인가능 /proc/net : 네트워크프로토콜들의상태정보 /proc/stat : 시스템의상태에관련된정보들 31
Section 05 proc 파일시스템 /proc 디렉토리내에숫자로표시되는디렉토리 태스크의 PID 로, 하위디렉토리에해당태스크의관련정보를담고있음 /proc/pid 에서제공하는태스크정보들 cmdline : 명령행옵션 cwd : 작업디렉토리링크 exe : 태스크를실행시킨명령어링크 fd : 파일디스크립터목록을가지는디렉토리 maps : 태스크의메모리맵 mem : 태스크가사용중인메모리 root : 태스크의루트디렉토리 stat : 태스크상태 statm : 태스크의메모리상태 status : 태스크의각종정보및메모리정보 32
Section 05 proc 파일시스템 디렉토리생성함수 proc_mkdir() proc 파일시스템의최상위디렉토리 (/proc) 를기준으로디렉토리생성 내부적으로 proc_mkdir_mode() 함수를호출하여수행하고 proc_dir_entry 구조체의주소를반환 인자» name : 생성할디렉토리이름» parent : name 으로만들어진디렉토리가위치할디렉토리. NULL 값을가지면 /proc 디렉토리를의미 proc_dir_entry 구조체 생성된디렉토리에관련된정보 ( 또는파일에관련된정보 ) 를담는멤버변수로구성 include/linux/proc_fs.h 디렉토리생성과정 proc_dir_entry 구조체의변수선언후 proc_mkdir() 함수로디렉토리생성 예 ) /proc 하위에 dt 디렉토리생성 struct proc_dir_entry *proc_dir = NULL; proc_dir = proc_mkdir("dt", 0 ); 33
Section 05 proc 파일시스템 파일생성함수 create_proc_entry( ) 함수 struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent) name : proc 파일이름 mode : 생성할파일의접근권한, 일반파일에서사용되는권한부여와동일 parent : name 으로만들어질파일이위치할디렉토리 예 ) dt 디렉토리내에 file 이라는파일을생성 struct proc_dir_entry *proc_fp = NULL; proc_fp = create_proc_entry("file", 755, "proc_dir" ); 파일또는디렉토리제거함수 remove_proc_entry() 함수 void remove_proc_entry(const char *name, struct proc_dir_entry *parent) 예 ) 생성한디렉토리 dt와파일 file을제거 struct proc_dir_entry *proc_fp = NULL; proc_fp = create_proc_entry("file", 755, "proc_dir" ); 34
Section 05 proc 파일시스템 읽기 / 쓰기함수 해당함수구현후 proc_dir_entry 구조체에있는 read_proc, write_proc 변수에대입 예 ) 생성한 dt 디렉토리내의 file 에데이터읽고쓰기 proc_fp->data = str; proc_fp->read_proc = read_file; proc_fp->write_proc = write_file; 해당함수의구현형식 typedef int (read_proc_t)(char *page, char **start, off_t off, int count, int *eof, void *data); typedef int (write_proc_t)(struct file *file, const char *buffer, unsigned long count, void *data); 35
Section 05 proc 파일시스템 읽기함수 사용자영역의태스크로부터요청들어오면 커널메모리영역에서데이터를읽어와적정포맷으로변경한후태스크로되돌려줌 통상적으로 copy_to_user() 함수를이용 쓰기함수 사용자영역의태스크로부터데이터를받아커널에게넘겨줌 통상적으로 copy_from_user() 함수를이용 proc 파일시스템에서의데이터는커널메모리상에저장 36
[ 실습 7-1] proc 파일시스템에디렉토리와파일생성하기 문제 모듈을이용하여 proc 파일시스템에자신의학번디렉토리 ( 예 :20050001) 를생성하고, B, C 의두개의파일을생성해보자. "B" 파일은소유자, 그룹, 일반유저모두가읽기 / 쓰기가가능 "C" 파일은모두읽기만가능한접근권한을부여 사용자가 B 파일에데이터를쓰면모듈내에서내부적으로복사본을 C 파일에저장 [ 실행화면예 ] 37
[ 실습 7-1] proc 파일시스템에디렉토리와파일생성하기 (1) 모듈프로그램작성 01 #include <linux/module.h> 02 #include <linux/kernel.h> 03 #include <asm/uaccess.h> 04 #include <linux/proc_fs.h> 05 #include <linux/init.h> 06 #define EOF (0) 07 08 struct proc_dir_entry *dir_fp = NULL; 09 struct proc_dir_entry *B_fp = NULL; 10 struct proc_dir_entry *C_fp = NULL; 11 12 char strb[255]; 13 char strc[255]; 14 15 int read_file(char *page, char **start, off_t off, int count, int *eof, void *data) 16 { 17 int len; 18 len = sprintf( page, "%s", (char*)data ); 19 return len; 20 } 38 [ 소스 7-1]
[ 실습 7-1] proc 파일시스템에디렉토리와파일생성하기 (1) 모듈프로그램작성 ( 계속 ) 21 int copy_read_file(char *page, char **start, off_t off, int count, int *eof, void *data) 22 { 23 int len; 24 data = strb; 25 len = sprintf( page, "This is copy file \n %s", (char*)data ); 26 return len; 27 } 28 29 int write_file( struct file *file, const char *buffer, unsigned long count, void *data) 30 { 31 int i; 32 char *kdata; 33 34 kdata = (char *) data; 35 i = copy_from_user(kdata, buffer, count); 36 kdata[count] = EOF; 37 return count; 38 } 39 39
[ 실습 7-1] proc 파일시스템에디렉토리와파일생성하기 (1) 모듈프로그램작성 ( 계속 ) 40 int init_module(void) 41 { 42 dir_fp = proc_mkdir("20050001", 0 ); 43 B_fp = create_proc_entry("b", 0644, dir_fp); 44 if( B_fp ) 45 { 46 B_fp->data = strb; 47 B_fp->read_proc = read_file; 48 B_fp->write_proc = write_file; 49 } 50 51 C_fp = create_proc_entry("c", 0444, dir_fp); 52 53 if( C_fp ) 54 { 55 C_fp->data = strc; 56 C_fp->read_proc = copy_read_file; 57 } 40
[ 실습 7-1] proc 파일시스템에디렉토리와파일생성하기 (1) 모듈프로그램작성 ( 계속 ) 58 return 0; 59 } 60 61 void cleanup_module(void) 62 { 63 remove_proc_entry("c", dir_fp ); 64 remove_proc_entry("b", dir_fp ); 65 remove_proc_entry("20050001",0 ); 66 } 67 68 MODULE_LICENSE("GPL"); 1 14 행 ~19 행 파일 B의읽기함수 파일 B의내용 (data) 을읽어서출력하고내용의크기를반환 data는 init_module에서정의한 strb와연결된데이터 41
[ 실습 7-1] proc 파일시스템에디렉토리와파일생성하기 2 21 행 ~27 행 파일 C 의읽기함수 사용자가파일을읽으면파일 B 의내용을복사하여출력해주며파일의첫부분에 "This is copy file" 문자열을포함시킴 3 29 행 ~37 행 파일 B 의쓰기함수 vi 에디터나 echo 명령을사용하여파일에쓰기를하면 copy_from_user 함수를사용하여사용자공간의데이터를커널공간으로복사 kdata[count] = EOF; 부분은쓰여진데이터의마지막을가리키기위해 null 문자를삽입하는부분 EOF 는 5 행의 define 문에서 0 으로정의된상수값 4 40 행 ~59 행 모듈이적재될때학번디렉토리와파일 B, C 를생성 이때접근권한과데이터및읽기 / 쓰기함수를지정하는부분을포함 5 61 행 ~66 행 모듈이제거되면생성된디렉토리와파일을제거 42
[ 실습 7-1] proc 파일시스템에디렉토리와파일생성하기 (2) 컴파일및모듈적재 #make #insmod proc_file.ko (3) 실행과정 1 #cd /proc -> #ls 명령으로학번디렉토리가생성되었는지확인 2 3 #cd 20050001 명령으로디렉토리이동후 #ls -l 명령으로파일 B,C 의생성확인 접근권한도확인한다. #vi B 명령을실행후몇줄을에디팅한후저장 이때쓰기함수에해당하는 write_file() 함수실행 4 #vi B 또는 #cat B 명령으로파일의내용을읽기. 5 6 7 이때읽기함수에해당하는 read_file() 함수실행 #vi C 또는 #cat C 명령으로파일의내용읽기 이때읽기함수에해당하는 copy_read_file() 함수실행 #echo "test" > B 명령으로파일의내용변경 다시 4 를실행하면한줄의문자열로내용이변경되었음을확인 35 행의 kdata[count] = EOF; 문이빠져있으면이전에편집한다른내용도함께출력됨 echo 명령으로사용한문자열의마지막에 null 문자가포함되지않기때문 43
[ 실습 7-2] 현재시스템시간을저장하는 proc 파일구현하기 문제 현재시스템시간을확인하여 /proc 디렉토리하위에 systemtime 파일에저장하는프로그램을구현해보자. 여기서는실습 [7-1] 과마찬가지로모듈로구현 (proc_clock.c) 현재시간을 xtime 변수를통해알아낸다. proc 파일의이름은 clock 으로하며읽기전용의권한을부여한다. 파일생성과초기화를한번에처리할수있는 create_proc_read_entry() 함수사용법을익힌다. [ 실행화면예 ] 44
[ 실습 7-2] 현재시스템시간을저장하는 proc 파일구현하기 (1) 모듈프로그램작성 01 #include <linux/kernel.h> [ 소스 7-2] 02 #include <linux/module.h> 03 #include <linux/types.h> 04 #include <linux/proc_fs.h> 05 #include <linux/time.h> 06 07 static int read_clock( char *page, char **start, off_t off, int count, int *eof, void *data ) 08 { 09 int len; 10 struct timeval ktv; 11 12 cli(); 13 ktv = xtime; 14 sti(); 15 16 len = sprintf(page, "%ld %ld\n", ktv.tv_sec, ktv.tv_usec); 17 return len; 18 } 19 45
[ 실습 7-2] 현재시스템시간을저장하는 proc 파일구현하기 (1) 모듈프로그램작성 ( 계속 ) 20 int init_module() 21 { 22 create_proc_read_entry("clock",0444, 0,read_clock, NULL); 23 return 0; 24 } 25 void cleanup_module() 26 { 27 remove_proc_entry("clock",0); 28 } 29 MODULE_LICENSE("GPL"); [ 소스 7-2] 46
[ 실습 7-2] 현재시스템시간을저장하는 proc 파일구현하기 1 7 행 ~19 행 읽기함수 xtime 변수를통해초와마이크로초값을가져옴 이때이값을읽기전에인터럽트를금지하고읽은후에는다시인터럽트를허용한다. sprintf() 함수를사용하여파일에시간을쓴다. 2 21 행 ~25 행 create_proc_read_entry 함수를사용하여파일의생성과초기화를함께수행 이함수의인자는순서대로파일이름, 접근모드, 파일이생성될디렉토리, 읽기연산을수행할함수의포인터및데이터값이다. 생성되는파일의이름은 "clock", 접근모드는읽기전용. 이파일은 /proc 하위에바로생성 읽기연산을수행할함수는 read_clock 이고초기데이터값은 NULL 임 3 26 행 ~29 행 모듈이제거되면 clock 파일을제거하는부분 47
[ 실습 7-2] 현재시스템시간을저장하는 proc 파일구현하기 (2) 컴파일및모듈적재 #make #insmod proc_clock.o (3) 실행과정 1 #cd /proc -> #ls 명령으로 clock 파일이생성되었는지확인 2 #cat clock 명령으로초와마이크로초단위의시간이출력되는것을확인 48