linux top 명령에서 PR 과 NI값 설명

서론

리눅스에서 top 명령을 치면 항목중에 PR(priority) 항목과 NI(nice) 항목이 존재한다.
이 글에서는 PR(priority) 과 NI(nice) 값에 대해서 정리한다. 언제나 그렇듯 틀린 내용일 수 있음.

  • PR은 프로세스 속성값중 priority값을 보여주는 항목이다.
  • NI는 프로세서 속성값중 nice값을 보여주는 항목이다.

그런데 top명령이 priority와 nice값을 있는 그대로 보여주는게 아니라 약간 계산을 해서 보여주기 때문에 혼란이 발생한다.

무슨 이야기냐 하면, 원래 PR(priority)값은 범위가 0 ~ 139까지이고, NI(nice) 값은 범위가 -20~19 까지이다.그런데 top명령에서 PR값은 RT ~ 0 범위로 표현하고, NI 값은 -20~19 까지로 표현한다. nice값은 제대로 보여주는데 priority값은 좀 변형해서 보여주고 있다. 이 부분을 설명한다.

NI(nice)에 대하여

nice 값은 프로세스가 얼마나 친절하냐(?)를 지정한다

nice 값은 -20 에서 19 사이에 값을 지정할 수 있으며, -20이 가장 불친절하기 때문에 더 많은 cpu자원을 쓰게 스케줄링 한다. 19는 가장 친절해서 cpu를 가장 덜 쓰게 스케줄링 한다. 기본적으로 손대지 않으면 0값을 가진다.

쉘에서 특정 프로세스의 nice 값을 바꾸는 명령은 아래와 같다
2997번 프로세스의 nice 값을 -20으로 변경한다

# renice -n -20 -p 2997

코드에서 nice 값을 바꾸는 예제는 아래와 같다

int which = PRIO_PROCESS;
id_t pid;
int priority = -20;
int ret;

pid = getpid();
ret = setpriority(which, pid, priority);

nice 값이 효과를 발휘하는 범위는 동일한 일반 유저 프로세서들 사이에서만 그렇다. nice 값은 일반적인 프로세스(유저 프로세스)에서 우위를 지정하게 해준다. 리눅스 시스템 전반(커널 스레드, 리얼 타임 프로세스, 일반 프로세스)에서 우선순위를 지정하는 값은 priority 이다.

nice 값은 priority값의 일부에 해당하는 영역에 불과하다. 그래서 nice 값와 priority 값은 상관관계가 있으며 변환식에 의해서 값 변화가 가능하다(변환식 아래 있음). 이런 nice 값을 가지고 우선권이 조정되는 프로세스들은 SCHED_OTHER, SCHED_BATCH, SCHED_IDLE 타입으로 지정되어 있다.

스케줄러의 종류와 우선순위 min/max를 보고 싶다면 아래 명령을 입력한다.

# chrt -m

4021번 프로세스가 어떤 스케줄러에 속해 있는지 알고 있다면 아래 명령을 입력한다.

# chrt -p 4021

PR(priority)에 대하여

nice 값을 이용하지 않고, priority 값만을 따지는 프로세스들이 있다. 리얼 타임 프로세스들이다. 모든 프로세스는 priority값을 가지고 있으며 그 범위는 1 ~ 139 까지 지정할 수 있다. 1이 가장 우선순위가 높고, 139가 가장 우선순위가 낮다. 리얼타임 프로세스들이 지정할 수 있는 priority 범위는 (1~99)까지이다. 리얼 타임 프로세스들은 언제나 일반 프로세스들보다 우선순위가 높아야 한다. 그런 이유로 nice 값만으로 변경할 수 있는 priority 범위는 100 ~ 139 까지이다.

  • nice 값 -20 이 priority 값 100 이다 (nice 중에서는 최고 높은 우선순위)
  • nice 값 19 가 priority 값 139 이다 (nice 중에서는 최고 낮은 우선순위)

그런데 top 명령에서 priority값을 보여주는 PR 값은 위 공식대로 보여주지 않는다. 약간 변경해서 보여준다. 아래는 PR값의 계산 공식이다.

  • 일반적인 프로세스 PR = 20 + NI (NI의 범위는 -20 에서 19 까지)
    • NI값 -20 는 PR값 0 이다 (priority 값은 100, nice 중에는 최고 우선 순위)
    • NI값 0 는 PR값 20 이다 (priority 값은 120, nice 미 지정시 일반적 우선 순위)
    • NI값 19 는 PR값 39 이다 (priority 값은 139, nice 중에는 최하 우선 순위)
  • 리얼타임 프로세스 PR = -1 – rt_priority (rt_priority의 범위는 1 에서 99 까지)
    • rt_priority값 99 은 PR값 -100(rt) 이다 (priority 값은 1, real time 중 최고 우선 순위)
    • rt_priority값 1 은 PR값 -2 이다 (priority 값은 99, real time 중 최저 우선 순위)

위 공식에 따라서 PR이 양수라면 일반 프로세스를 뜻하며, PR값이 음수라면 리얼 타임 프로세스를 뜻한다.

  • PR값이 -100에 가까울 수록 더 높은 우선순위를 가진다
  • rt_priority값이 99에 가까울 수록 더 높은 우선순위를 가진다
  • priority값이 1에 가까울수록 더 높은 우선순위를 가진다

이제 nice값 수정으로는 올릴수 없는 rt_priority 1~99 값을 지정하는 방법을 알아보자.

6097번 프로세스를 fifo 스케줄러에 rt_priority 99로 설정하려면 아래와 같이 입력한다.

# chrt -f -p 99 6097

위 명령을 치고 top 명령을 치면 해당 프로세스의 PR값이 rt 라고 보여지게 된다. 가장 높은 우선순위를 지정받게 된 것이다. rt_priority 값 99는 priority 값 1에 해당한다.

6097번 프로세스를 fifo 스케줄러에 real_time_priority 1로 설정하려면 아래와 같이 입력한다.

# chrt -f -p 1 6097

참고 1
루트 유저가 아닌 프로세스에 대해서 /etc/security/limits.conf 파일을 통해서 nice 값 변경 범위를 제한할 수 있다.

참고 2
커널은 CPU사용량에 따라서 특정 프로세스의 priority값을 동적으로 변경할 수 있다. 이 경우 nice값을 손대는게 아니기 때문에, PR = 20 + NI 공식이 안맞게 된다. 하지만 일반적인 경우에는 이 공식이 맞다. real time priority는 커널이 priority를 임의로 손대지 않는다.

참고 3

chrt: failed to set pid 0's policy: Operation not permitted

chrt 명령으로 rt_priority를 변경하려고 했는데 위 에러가 발생한다면, 아래 명령을 입력한다

# sysctl -w kernel.sched_rt_runtime_us=-1

참고자료
* https://blog.naver.com/PostView.nhn?blogId=alice_k106&logNo=221149061940&parentCategoryNo=&categoryNo=23&viewDate=&isShowPopularPosts=false&from=postList
* https://code.i-harness.com/ko-kr/q/879ceb
* https://www.ibm.com/developerworks/library/l-lpic1-103-6/index.html
* https://askubuntu.com/questions/656771/process-niceness-vs-priority
* https://superuser.com/questions/203657/difference-between-nice-value-and-priority-in-the-top-output
* https://m.blog.naver.com/PostView.nhn?blogId=alice_k106&logNo=221170316769&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F

ARM Ubuntu 14.04에 최신 docker 설치기

회사 타켓보드에 개발 용이성을 위해서 ARM Ubuntu14.04에 docker를 올리는 시도를 했다

그냥 간단하게는 아래 명령으로 되는데,

$ sudo apt-get install docker.io

Ubuntu 14.04는 너무 오래되서, docker 버전이 너무 낮아서 시도를 하지 않았다. (실제로 저 명령으로 docker 설치가 잘 되는지 모른다는 이야기다)

처음부터 바로 docker ppa에서 바로 최신 버전을 받아서 설치를 진행했다.

https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#upgrade-docker-after-using-the-convenience-script

그리고 실행하니까 커널에 필요한 기능이 추가되어 있지 않아서 데몬이 동작하지 않는다.

첫번째 이슈는 cgroup이었다. 커널에 cgroup 자체는 활성화되어 있었지만, blkio같은 서브모듈이 비활성이어서 전부 활성화 처리 해주었다.

두번째는 network nat기능이었다. 이 부분은 너무 옵션이 많이 필요해서 관련 자료를 참고했다.

스크린샷 2017-11-03 오전 10.49.09.png스크린샷 2017-11-03 오전 10.49.17.png스크린샷 2017-11-03 오전 10.49.23.png

위에는 falinux에서 진행한 docker세미나 자료이다.

https://wiki.gentoo.org/wiki/Docker

위는 gentoo에서 제공하는 docker 커널 옵션이다. 나는 잘 안되서 2개를 다 시도 했다. 따라서 위 2개중에 어떤게 맞는지는 알수없다. 나는 그냥 2가지를 다 활성화시켰다.

그래도 네트워크쪽에서 아래와 같은 오류가 발생했다.

failed to create endpoint vigilant_varahamihira on network bridge: failed to add the host (vethadd7f95)  sandbox (veth63708ff) pair interfaces: operation not supported"

해결책은 아래 커널 옵션을 활성화 해준다

device driver -> network device support -> network core driver support -> virtual ethernet pair device

그래도 아래와 같은 오류가 발생했다.

starting container process caused "process_linux.go:368: container init caused \"rootfs_linux.go:57: mounting \\\"mqueue\\\" to rootfs \\\"/var/lib/docker/devicemapper/mnt/e8d53dff710da9a18279cec3db4fb324ecc1874b5f3fa2e4496b94c31938d715/rootfs\\\" at \\\"/dev/mqueue\\\" caused \\\"no such device\\\"\"".

해결책으로 CONFIG_POSIX_MQUEUE 커널 옵션을 활성화 했다

그래도 아래와 같은 오류가 발생했다.

oci runtime error: container_linux.go:265: starting container process caused \"process_linux.go:368: container init caused \\"open /dev/ptmx: no such file or directory\\"\"

해결책으로 아래와 같이 -v 옵션을 추가해서 실행했다.

$ sudo docker run --rm -it -v "/dev:/dev" arm32v7/ros:kinetic-ros-base /bin/bash

pulse audio 고생기

5422보드에서 오디오 작업을 하고 있는데 어느 순간 부터 재생음이 끊기고 겹치는 현상이 발생했다.
처음엔 안 괜찮다가, 어느 순간 부터 그랬다.
뭔가 apt-get으로 시스템 업데이트를 하면서 꼬였거나, 설정을 잘못 건들인 것으로 생각되서 문제점을 뒤졌다.
증상을 자세히 살펴보니,

$ aplay -D hw:0,0 test.wav

이렇게 명시적으로 장치를 지정하면 문제가 없는데,

$ aplay test.wav

이렇게 default 장치를 쓰면 문제가 발생했다.

차이점을 살펴보니 default 장치를 사용하게 되면, aplay가 PulseAudio PCM I/O Plugin을 이용해서 소리르 재생한다는 것을 알았다.

aplay는 alsa를 이용하는 저수준 프로그램인데 그 상위 계층인 PulseAudio에게 음악 재생을 시키다니..? 이해가 안됬지만, 뭐 편리함을 위해서 그럴수 있지…라고 결론짓고 이 부분은 그냥 패스..

문제의 핵심은 audio device -> ALSA -> PulseAudio로 넘어갔다.

PulseAudio는 디버깅 해본적이 한번도 없어서 자료를 찾아서 문제점을 파악하는 방법을 공부했다.
우선 PulseAudio는 환경설정 파일이 /etc/pulse 디렉토리에 몰려있었다.
여기서 특히 default.pa 파일은 어떤 모듈을 로딩할지에 대한 설정을 담고 있었다.
그 외에는 ~/.config/pulse 디렉토리에 안에 캐시 파일이나 개인 환경 설정이 저장된다.

여튼 PulseAudio가 밷어내는 출력 메세지를 보는 방법을 찾았는데 아래 문서에 자세하게 설명되어 있다.
https://wiki.ubuntu.com/PulseAudio/Log

$ echo autospawn = no >> ~/.config/pulse/client.conf

위 명령은 PulseAudio 서버가 자동으로 실행되는 것을 막아준다.

$ killall pulseaudio

이미 실행되고 있는 PulseAuido 서버를 다 죽인다.

LANG=C pulseaudio -vvvv –log-time=1 > ~/pulseverbose.log 2>&1

로그 기능을 활성화 해서 새롭게 PulseAudio 데몬 하나를 띄운다.

이렇게 해서 음악을 재생하면 긴 로그가 쌓이게 된다. 너무 내용도 길고 어려워서 뭔말인지 모르겠다…

그래서 실시간으로 보기 위해서 그냥 콘솔에서 직업 로그가 나오게 했다.

$ pulseaudio -vvvv –log-level=debug

이렇게 하고 다른 창에서 aplay로 음악을 재생해보니, 음이 문제가 되는 시점마다 로그에 아래 메세지가 찍힌다.

( 4.176| 0.000) I: [alsa-sink-Playback wm8960-hifi-0] alsa-sink.c: Increasing wakeup watermark to 40.00 ms

구글링을 통해서 정확한 답은 찾지 못했지만 비슷한 이슈를 하나 찾았다.
http://mailman.alsa-project.org/pipermail/alsa-devel/2015-August/097068.html

그래서 나도 /etc/pulse/default.pa 파일의 아래 라인을 수정했더니 잘 되었다!

load-module module-alsa-sink rate=44100 tsched=0

이 글은 Ubuntu 14.04 에서 테스트 되었음

PulseAudio 관련 명령어들

$ pacmd

이 문제를 조사하면서 참고한 자료들이다.
* https://wiki.ubuntu.com/PulseAudio
* https://wiki.ubuntu.com/PulseAudio/Log
* https://wiki.archlinux.org/index.php/PulseAudio/Examples

우분투 14.04 부팅시 실행되는 서비스 관리하기

우분투는 버전에 따라서 system v init, upstart, systemd가 다 쓰인다 -_-;

자신이 쓰고 있는 우분투 버전이 뭔지에 따라서 어떤걸 쓰는지 다른것이다. 우분투 14.04 같은 경우는 upstart를 사용한다.

그런데 system v init 시스템이 그대로 존재하는 것처럼 보인다. 이 부분이 오해를 일으켰다..

rcconf 프로그램으로 아무리 rc 설정을 바꿔도 반영이 이루어지지 않았다.

이 내용을 잘 설명해준 글이 있어서 링크를 첨부~ 불펌은 안되니까 ㅋ

http://snoopybox.co.kr/1720

zsh 설치

zsh를 설치한다

sudo apt-get install zsh

zsh를 기본 쉘로 변경한다

chsh -s `which zsh`

oh-my-zsh를 설치한다

wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O – | zsh

alias-tips 플러그인을 설치한다

$ cd ${ZSH_CUSTOM1:-$ZSH/custom}/plugins
$ git clone https://github.com/djui/alias-tips.git

~/.zshrc 파일을 열어서 아래 설정으로 변경해서, 테마와 자동완성시 빨간점이 보이게 바꾼다

ZSH_THEME=”agnoster”
COMPLETION_WAITING_DOTS=”true”
plugins=(git alias-tips)

agnoster 테마는 powerline-patched-font가 필요하다. 여기로 가서 받아서 터미널 프로그램을 설정한다.

 

참고자료

마운트된 파티션 크기 늘리기

이미 사용중인 파일 시스템의 크기를 늘릴 수 있다
조건은 사용중인 파티션 뒤쪽으로 붙어있는 파티션만 가능하다는 점이다. (앞쪽에 비어있는 파티션은 불가)

$ cfdisk /dev/mmcblk0

위 명령으로 들어가서 현재 사용중인 파티션, 합쳐질 파티션 2개를 전부 DELETE 한다
그리고 새롭게 파티션을 만든다. 이때 크기는 2개 파티션을 합친 크기만큼의 파티션이 만들어 질 것이다
종료전에 WRITE 를 수행해야 변경 내용이 반영된다

리붓한다

이제 새롭게 늘어난 파티션의 파일 시스템 크기도 늘려준다

$ resize2fs /dev/mmcblk0p3

참고자료 : http://positon.org/resize-an-ext3-ext4-partition

리눅스 콘솔에서 WIFI 설정하기

iwconfig를 이용하는 방법이 있는데 이 방법은 AP에 암호가 걸려 있으면 좀 복잡하다

우분투에서는 아래 설정으로 되었다

root@torooc:~/work# cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto wlan0
iface wlan0 inet dhcp

wpa-ssid "xxxxxxx"
wpa-psk "xxxxxxx"

auto eth0
iface eth0 inet static
        address 192.168.0.93
        netmask 255.255.255.0
        gateway 192.168.0.1

다 됬으면 아래 명령으로 활성화를 해보자

$ sudo dhclient wlan0