제목에 ‘꽃삽질’을 붙이긴 오랜만이다. 그만큼, 이번 꽃삽질은 짜증 속에 이뤄졌다.
왜 이런 걸 찾게 됐었는지, 그 이유부터 써놔야겠다.
서버를 종료할 때, 그냥 poweroff
명령을 내린다. 가끔 ‘한시간 뒤’ 등으로 시간 조건을 붙일 때는 있지만, 아무튼 현재 서버 상황은 고려하지 않고 무작정 꺼버리는 경우가 대부분이다.
하지만, 특정 시간에 내가 걸어놓은 작업들이 있어서, 그게 진행되고 있음에도 그냥 꺼버릴 때가 종종 있었다. 그래봐야 다음에 다시 하면 되는 일이니 대단치는 않지만..
아무튼, 이런 위험을 조금이나마 방지하고자 스크립트를 만들어보기로 했다.
특정 디렉토리에 변경이 감지되면, poweroff 를 하지 못하도록.
헌데, 이 ‘감지’에서 한방 먹고 말았다.
이 분야(?)의 대표 주자는 lsof
로 보인다. lsof <dir>
형식으로, 그 디렉토리에서 열린 파일이 있는지를 알아낼 수 있다.
그런데, lsof 가 감지하지 못하는 경우도 있다.
nfs 서버에, nfs 클라이언트가 연결(mount)하여 파일 작업을 하면, 이 상황을 lsof 는 알아내질 못한다. lsof 는 ‘LiSt Open Files’ 의 약자인데, 왜 못잡아낼까??
아마도, 저런 작업에는 Process 가 할당되지 않기 때문인가보다.
NFS Client 쪽에선 lsof -N <dir>
형식으로, NFS 로 작업하고 있는 파일들을 찾을 수 있다. 하지만, 서버 쪽에선 불가능하다.
여기까지 알아내는데만 해도 반나절 이상 걸렸던 듯. 덩달아 짜증은 치솟았고, 정신 건강(!!)에 조금씩 무리가 오기 시작했다.
………………….
그리하여, 아예 다른 방법을 생각해보기로 했다.
예를 들어 다음과 같다.
- NFS Client 에서는 NFS Server 로 파일 복사를 시작할 때, 시작을 알리는 파일을 특정 디렉토리에 만든다.
- 서버에서는 종료 명령 스크립트에서 저 파일이 있는지 여부를 확인한다. 만약 파일이 있다면 Shutdown 을 실행하지 않는다.
- NFS Client 에서는 NFS Server 로 파일 복사가 끝날 때, 아까 만든 파일을 지운다.
이렇게만 하면 큰 무리는 없으리라 생각하고 진행하려 했다.
그러다가!!
문득, 디렉토리에 변경이 생겼음은 감지할 방법이 있지 않을까? 하는 생각이 들었고, 다음과 같이 검색어를 넣어 보았다.
linux how to check directory change
그렇게 해서 찾아낸 명령이 바로 fswatch
이다. 이 프로그램은 inode 를 감시하다가 변경이 생기면 알려주는 기능을 하는데, 내 상황에 딱 맞는다 할 수 있겠다.
여러가지 복잡한 선택사항이 많은데, 몇가지를 골라서 만든 명령어는 이렇다.
fswatch -rtx1 --event 'Created' <dir>
- -r : Recursive
- -t : 시간 표시. (Timestamp)
- -x : event 표시
- -1 : 최초 변경 사항만 출력하고 끝냄. (원래는 계속 감시하며 출력)
- –event ‘Created’ : x 로 표시된 이벤트 중, Created 만 화면에 출력
이 명령을 내리면, 해당 디렉토리에 변경이 있는지 감시하다가, 변경이 있으면 해당 사항을 출력해준다.
그/런/데! 여기서 또 한가지 문제.
fswatch 는, 그야말로 Watch 에 충실하여, 변경을 감지하려 계속 실행된다. 즉, 사용자가 강제로 중단시키지 않으면 무한 루프에 빠져 있는 상태다.
물론, ‘-1’ 로 인해 1회만 출력을 하고 말게끔 설정은 했다지만, 그건 파일 복사가 실행되고 있을 때 얘기고, 복사가 되고 있지 않다면, 즉 디렉토리에 아무런 변화가 없다면 그야말로 계속 상주하고 있는 상황이 돼 버린다. 그럼 도대체 Shutdown 은 언제 할 수 있는거냐고..
하여, 여기에 한가지 명령을 덧붙였다.
timeout 10 fswatch -rtx1 --event 'Created'
timeout
은 바로 뒤에 초단위로 숫자를 넣어주면, 그 동안만 뒤에 나오는 명령을 실행하고 강제 종료 시킨다.
즉, 10초 동안만 fswatch 를 실행하다가 끊어버리라는 의미가 된다.
만약 10초 이내에 fswatch 가 종료되면 당연히 거기서 끝이다. (10초가 될 때까지 기다리진 않는다는 뜻.)
이렇게 해서, 이 결과를 바탕으로 스크립트를 만들었다. 복사가 되고 있지 않으면 shutdown 명령을 내려주고, 복사가 되고 있다면 shutdown 을 실행시키지 않게끔.
스크립트는 사실 별게 없는데, fswatch 를 알아내는데까지 시간이 좀 걸렸다.
큰 꽃삽질, 또 한번 푸~욱 떴군.