본문 바로가기
일상,취미

[TIL 34일차] linux -> window 포팅에 대한 나의 생각 , 지난 한 주를 돌아보며

by 진득한진드기 2024. 8. 10.

오늘 한일

linux 파일시스템을 추출하는 기능을 window로 포팅하는 기능이 왜 안되는지 되게 하는 방법은 없는지 지난 2주동안 엄청 나게 서치해봤다.

 

기본적으로 파일시스템을 구성하는 구조가 엄연히 다르다는 것이다.

 

linux는 슈퍼블록이나 inode 기반으로 이루어져 있는 구조 라고 한다면 MFT을 사용하거나, NTFS시스템으로 되어있기 때문에 이 동작자체가 원활하게 돌아간다는 보장도 없고, 중간에 코어모듈에서 사용된 모듈 함수 일부분은 shell을 이용하거나, yield 시스템 콜 호출 등 , linux posix 규격 호출을 사용하기 때문에 중간에 안되는 부분이 있을 것으로 보인다. 아직 내레벨에서 만들수 있는 기능은 아닌것 같아서 네이티브로 돌리는것보다는 wsl을 이용하거나 cygwin을 이용하는 방법을 이용하려고 했다.

 

근데 wsl을 사용할거면 그냥 docker을 사용하는게 좀더 실용성이 있어 보이고, cygwin은 사용해봤는데 파일 포팅하는 과정에서 squash파일이나 bff같은거에서는 완벽한 호환이 어려워 보인다.

 

결국 docker를 사용하여 필요한 의존성 패키지만 설치하고 돌리는방식으로 가야할 것 같다.

 

2주 넘게 삽질한 것 같지만 그래도 linux 파일 구조와 유효성 검사 및 파일에 따른 checksum 함수(CRC)의 동작을 코드레벨에서 분석할 수 있었던 경험 같다.

 

docker를 많이 까먹었지만 또 다음주 부터 사용해봐야겠다.

 

 

퇴근 후  공부



서버 모델의 경우 epoll 모델의 서버가 있다고 하면 그거를 가져다 놓고 서버의 기능을 간략화해서 사용한다.

만약 모델이 같다고 하면 보통 대부분의 기능을 제외하고는 비슷하다.

실제 서비스에서는 기능 코드가 대부분이기 때문에 사실상 개발을 할 때는 기능부분을 하게 될 것이고, 기능부분의 코드를 어떻게 간략하게 짜야되나 싶은 고민을 많이 하게 될 것이다.

우리가 배워본 epoll은 자체 2가지의 서버 모델을 가지고 있다. 바로 레벨 트리거와 엣지트리거 인데 이 둘은 상황에 따라 나눠서 사용해야한다.

근데 보통 세밀한 컨트롤이 필요할 때는 엣지 트리거를 쓰기한다.

레벨 트리거와 엣지 트리거의 차이점을 간단히 보면

 

레벨 트리거는 특정값이 바뀌어 있는 상태면 트리거를 보내고 값이 바뀌지 않으면 지속적으로 보낸다. 엣지 트리거는 값이 바뀌는 순간에만 트리거를 보낸다.

epoll은 기본값이 레벨 트리거이다.

epoll_wait은 지속적으로 트리거를 올린다.

 

레벨 트리거의 이벤트 특성 파악하기

 
버퍼 사이즈로 인해서 트리거를 올리는 횟수랑 보내는 횟수가 달라지기에 버퍼 사이즈를 잘 조절 해주는게 좋다.

레벨 트리거는 한번에 요청을 하고 한번의 응답을 하는식으로 구현하는게 좋다.

엣지 트리거로도 구현할 수 있지만 번거롭기에 그냥 저런상황에서는 레벨 트리거를 쓰는게 낫다.


엣지 트리거 기반의 서버 구현을 위해 필요한 것


int flag = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flag | O_NONBLOCK);

fcntl 함수호출을 통해서 소켓의 기본 설정정보를 얻은 다음, 거기에 O_NONBLCOK 속성을 더해서 소켓의 특성을 재설정 한다.

엣지 트리거는 데이터 수신 시 딱 한번만 이벤트가 발생하기 때문에 이벤트가 발생했을 때 충분한 양의 버퍼를 마련한 다음에 모든 데이터를 다 읽어 들여야 한다.
즉, 데이터의 분량에 따라서 IO로 인한 Delay가 생길 수 있다. 그래서 엣지 트리거에서는  논 블로킹 IO를 이용한다. 입력 함수의 호출과 다른 작업을 병행할 수 있기 때문이다.

int errno; 

논 블로킹 IO기반으로 데이터 입력 시 데이터 수신이 완료되었는지 별도로 확인 해야한다. 헤더 파일<error.h>를 포함하고 있는 변수 errno을 참조한다.
errno에 EAGAIN이 저장되면 버퍼가 빈 상태이다.


엣지 트리거와 레벨 트리거의 비교


- 서버는 클라이언트 A,B,C 로부터 각각 데이터를 수신한다.
- 서버는 수신한 데이터를 A,B,C의 순으로 조합한다.
- 조합한 데이터는 임이의 호스트에게 전달한다.

위와 같은 시나리오 상에서 클라이언트가 서버에 접속 및 데이터를 전송하는 순서는 서버의 기대와 상관이 없다. 이처럼 서버측에서의 컨트롤 요소가 많은 경우에는 엣지 트리거가 유리하다. 반면, 서버의 역할이 상대적으로 단순하고 또 데이터 송수신의 상황이 다양하지 않다면, 레벨 트리거 방식을 선택할 만하다.

이유는 레벨 트리거를 막 사용하게 되면 이벤트가 너무 많이 발생할 수 있음.

 

결과에 따라서 어떤 의미가 송신되었는지도 확인이 가능한데 

 

read == 0은 EOF

read < -1은 오류를 의미한다.