본문 바로가기

OS/Linux

Daemon & 패키징 & 로그

윈도우 서비스 프로그램은 만들어본 적이 있지만 유닉스용 데몬은 처음이라 살펴보았다.


처음에는 윈도우 서비스 뼈대처럼 생각을 했는데, 의외로 프로그램 코드는 간단했다.

Service Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/ms685942(v=vs.85).aspx

윈도우의 서비스 애플리케이션은 ServiceMain 이라는 프로토타입이 정해져 있다.

따라서 아래와 같은 뼈대가 만들어진다. (출처: Writing a Service Program's main Function)

void __cdecl _tmain(int argc, TCHAR *argv[]) { SERVICE_TABLE_ENTRY DispatchTable[] = { { SVCNAME, (LPSERVICE_MAIN_FUNCTION) SvcMain }, { NULL, NULL } }; if (!StartServiceCtrlDispatcher( DispatchTable )) { SvcReportEvent(TEXT("StartServiceCtrlDispatcher")); } }


VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv ) { gSvcStatusHandle = RegisterServiceCtrlHandler( SVCNAME, SvcCtrlHandler); if( !gSvcStatusHandle ) { SvcReportEvent(TEXT("RegisterServiceCtrlHandler")); return; } gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; gSvcStatus.dwServiceSpecificExitCode = 0; ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR, 3000 ); SvcInit( dwArgc, lpszArgv ); // 무한 루프를 돌며 무엇인가를 서비스를 한다. }


추가적으로 시스템이 SCM에게 어떤 제어 요청을 하면 처리를 어떻게 수행할 지 프로그램 코드에서 구현을 해주어야 한다.

아래 코드에 보면 콜백 함수의 인자로 DWORD 타입의 코드가 오는데 SCM에 의해 어떤 타입의 이벤트인지 구분하게 해준다. (Ref)

  • SERVICE_CONTINUE_PENDING (5)
  • SERVICE_PAUSE_PENDING (6)
  • SERVICE_PAUSED (7)
  • SERVICE_RUNNING (4)
  • SERVICE_START_PENDING (2)
  • SERVICE_STOP_PENDING (3)
  • SERVICE_STOPPED (1)

VOID WINAPI SvcCtrlHandler( DWORD dwCtrl ) { switch(dwCtrl) { case SERVICE_CONTROL_STOP: ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); SetEvent(ghSvcStopEvent); ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0); return; case SERVICE_CONTROL_INTERROGATE: break; default: break; } }


대충 전체 구조는 아래와 같다.

_tmain (main, wmain) -> StartServiceCtrlDispatcher(<-서비스 메인 함수 포인터 등록)

 -> RegisterServiceCtrlHandler(<-핸들러 콜백 함수 포인터 등록)


그런데 리눅스에서는 그런 제어에 대한 것이 소스가 아닌 init.d라는 스크립트에 들어가 있었다.

mongodb를 샘플로 해서 보았다.

running_pid() {

}


running() {

}


start_server() {

}


stop_server() {

}


force_stop() {

}


패키징 및 시작

우분투(Ubuntu) 패키지 만들기 - http://kukuta.tistory.com/171

Linux init.d 에서 등록하기. 부팅 시 자동실행 설정 관리자 - http://www.digipine.com/software/23108


로깅

로그 파일 크기 관리하는 logrotate 설치하고 설정하기 - http://www.cmsfactory.net/node/10416


위키백과

https://ko.wikipedia.org/wiki/윈도_서비스

https://ko.wikipedia.org/wiki/데몬_(컴퓨팅)

'OS > Linux' 카테고리의 다른 글

[zsh] PATH 에 경로 추가  (0) 2019.03.20
[SSH] Permission denied (publickey) 가 발생할 때...  (0) 2019.03.20