로그 레벨 지정

커널 메시지는 그 중요도에 따라 레벨을 정하고 이를 커널 메시지 선두에 표현하는 방법을 사용하는데, 이를 로그 레벨이라 한다.

상수 선언문

의미

#define KERN_EMERG

“<0>”  /* 시스템이 동작하지 않는다. */

#define KERN_ALERT

“<1>”  /* 항상 출력된다. */

#define KERN_CRIT

“<2>”  /* 치명적인 정보 */

#define KERN_ERR

“<3>”  /* 오류 정보 */

#define KERN_WARNING

“<4>”  /* 경고 정보 */

#define KERN_NOTICE

“<5>”  /* 정상적인 정보 */

#define KERN_INFO

“<6>”  /* 시스템 정보 */

#define KERN_DEBUG

“<7>”  /* 디버깅 정보 */

레벨에 대한 표시를 하지 않는다면 KERN_WARNING와 같은 레벨로 처리 된다.


ex) printk(KERN_INFO "system ok\n");

      printk("<6>" "system ok\n");

      printk("<6>system ok\n");

다음 세 문장의 의미는 같다. 


원형 큐 구조 관리

커널 메시지는 콘솔 디바이스로 바로 출력되지 않고, 커널 내부에 있는 원형 큐 형식의 로그 버퍼라는 저장 공간에 저장된다. 이 로그 버퍼의 크기는 CONFIG_LOG_BUF_SHIFT 값으로 지정되는데, 2의 승수로 크기를 표현한다. 이 값은 include/config/log/buf/shift.h에 정의되어 있는데, 디폴트 값이 14이므로 로그 버퍼의 크기는 16 Kbyte 다.

커널 메시지를 저장하는 로그 버퍼는 출력하는 콘솔 디바이스와 데이터를 기록하는 로그 프로그램에 연결되어 있다. 그래서 printk() 함수에 의해 로그 버퍼에 저장되는 속도보다 데이터를 가져가는 속도가 느려서 로그 버퍼의 크기를 초과하면 가장 오래된 데이터가 손실된다.









커널 2.6 이상에서 사용하는 매크로


module_param(변수명, 변수 타입, 접근 속성)


[변수 타입]

- short  : short

- ushort  : unsigned short

- int  : int

- uint  : unsigned int

- long  : unsigned long

- charp  : char *

- bool  : int

- invbool  : int

- intarray  : int *


[접근 속성]

아주 특별한 경우가 아니면 보통 접근 속성은 0으로 지정하여 사용한다. 이는 사용자 권한에 따라 처리 허가 여부를 검사하는데, 일반 사용자가 모듈을 커널에 적재할 수 있는 경우는 매우 드물기 때문이다. 만약 굳이 접근 설정을 하고 싶다면 파일 퍼미션과 같은 개념으로 0644와 같은 8진수 값을 주면 된다.


라이선스

풀어쓰기

GPL

GNU Public License v2 or later

GPL v2

GNU Public License v2

GPL and additional rights

GNU Public License v2 rights and more

Dual BSD/GPL

GNU Public License v2 or BSD license choice

Dual MPL/GPL

GNU Public License v2 or Mozilla license choice

Proprietary

Non free products



/dev에 디바이스 파일이 있다고 해서 디바이스 파일에 해당하는 하드웨어를 모두 제어할 수 있는 것은 아니다. 디바이스 파일에 해당하는 하드웨어가 없을 수도 있다. 또한 하드웨어가 있더라도 커널에 디바이스 드라이버가 포함 되어 있지 않으면 제어할 수 없다. /dev/ 디렉토리 밑에는 수많은 디바이스 파일이 있다. 디바이스 파일은 크가가 작은 정보 파일이라서 미리 만들어 놓는데, 그래서 디바이스 파일의 수가 너무 많아 실질적인 제어가 가능한 디바이스 파일을 커널에서 자동으로 제공해 주는데, 이 기능을 바로 devfs라는 파일시스템이다. 이 파일 시스템은 시스템에 존재하는 하드웨어와 관련된 디바이스 드라이버가 있으면 자동으로 생성된다. 커널에서 자동으로 지원하지는 않으며, 디바이스 드라이버에 devfs 파일 시스템을 지원하도록 제작되어야 하고, 다음과 같이 마운트하여 사용할 수 있다.


[root@] # mount -n -t devfs none /dev 

출처 : 리눅스 디바이스 드라이버 "한빛미디어"




각 프로세서별로 별도의 캐시 메모리를 가지고 있는 공유 메모리 멀티프로세서에서, 한 명령어 피연산자의 복제본이 주기억장치에 하나, 그리고 각 캐시 메모리에 하나씩, 여러 개 존재할 수 있다. 이러한 상황에서 피연산자가 변경되면, 나머지 복제본 역시 변경되어야만 한다. 캐시 일관성은 공유된 피연산자의 값이 변경되면, 그 사실이 전체 시스템에 즉시 전파되는 것을 보장하는 하나의 질서이다.

캐시 일관성에는 다음 세 가지의 명확한 단계가 있다.

  1. 모든 쓰기 연산은 즉시 발생하는 것처럼 보인다.
  2. 모든 프로세스들은 독립되어 있는 각 피연산자들의 값이 정확히 같은 순서대로 변경되는 것을 본다.
  3. 다른 프로세스들은, 값들의 순서가 다른 것을 사실이라고 생각하는 피연산자를 볼 수 있을지도 모른다 (이것은 일관성이 없는 행동으로 간주된다).

2 단계의 행동과 3 단계의 행동 둘 모두에서, 프로그램은 틀린 데이터를 볼 수 있다. 컴퓨터 설계자들은 최근, 2 단계 행동을 다루는데 필요한 프로그래밍 규율이, 3 단계 행동을 다루는데 충분하다는 것을 깨닫게 되었다. 그러므로, 어떤 경우에는 같은 컴퓨터에서는 오직 1 단계와 3 단계 행동만이 보일 것이다.

출 처 : http://www.terms.co.kr/cachecoherence.htm

This post will show how to upgrade from Debian 5.0.x “Lenny” to the latest stable Debian release 6.0 “Squeeze”. One of the reasons I’ve liked Debian in the first place was the advantage of being able to do a live, in place updates from one major release to another, usually in a safe way. As always, if you do this, please take some time to backup your system if you care of your data, as this is a major upgrade and things can go wrong. Squeeze brings in a few big changes and I will outline some of them, but I would recommend to read the release notes and look for any incompatibilities (hardware or software) or changed things that could affect your particular setup.

1. Update apt sources.list

The first thing we will do (after the backup of course) is to edit the /etc/apt/sources.list file and replace “lenny” with “squeeze“. Originally, this might look like this (for a system using the main US mirrors; your file might use a different local one):

deb http://ftp.us.debian.org/debian/ lenny main contrib non-free
deb-src http://ftp.us.debian.org/debian/ lenny main contrib non-free

deb http://security.debian.org/ etch/updates lenny contrib non-free

after replacing lenny with squeeze the file will look like this:

deb http://ftp.us.debian.org/debian/ squeeze main contrib non-free
deb-src http://ftp.us.debian.org/debian/ squeeze main contrib non-free

deb http://security.debian.org/ squeeze/updates main contrib non-free

2. Perform the system upgrade

After updating the sources file, you will have to refresh the indexes with:
aptitude update

Next let’s manually upgrade the core apt packages (this will pull in some extra dependencies, and this is perfectly fine):
aptitude install apt dpkg aptitude

And finally we will perform the bulk of package upgrades with:
aptitude safe-upgrade
this will take a while depending on what packages you have installed (that will need to be upgraded) and on your internet connection speed.

Here are some changes that you might want to pay special attention during the upgrade:
- dash: squeeze uses dash instead of /bin/sh as the default system shell. This is the recommended way and it is supposed to be faster and improve the system overall performance. I recommend to use it and accept this change.
- grub2: is the default in squeeze and the upgrade will recommend to upgrade from your existing grub. This is a major change and for this reason initially the boot loader will be chainloaded in the existing menu.lst to verify it works fine. If you want to upgrade I would recommend to do the chainload and test it with at least one reboot before removing grub legacy.
- sysv-rc: to improve the boot process the upgrade will offer to move to dependency-based sequencing. This is irreversible but highly recommended. I had no problem with it and don’t see why anyone would not want this.
- UUIDs: the installer will recommend to switch from regular disk devices (aka /dev/sda*) to disk IDs (aka UUID=c6ecae74-6754-4ad0-986d-98dd9cbfd293) in various configuration places like /etc/fstab, /boot/grub/menu.lst. I personally don’t like that, but didn’t want to take the risk for the device to change its name with the new kernel and went with the change. If you do the same pls. doublecheck the changed files before rebooting.

Now it is time to reboot your system for the first time into squeeze. Fingers crossed and in a few minutes you will be running squeeze (as always an out of band impi console is handy when doing such upgrades)

3. Complete the upgrade

If you upgraded to grub2 and want to remove the chainloaded grub-legacy you can remove it completely from the system with:
upgrade-from-grub-legacy
and the output will look like this:
0
Installation finished. No error reported.
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-2.6.32-5-amd64
Found initrd image: /boot/initrd.img-2.6.32-5-amd64
Found linux image: /boot/vmlinuz-2.6.26-2-amd64
Found initrd image: /boot/initrd.img-2.6.26-2-amd64
done

You can now run:
aptitude full-upgrade
and this will complete some extra packages that were not straitforward and not seen as safe by the normal upgrade process (there might be none, depending on the state of your existing system). Evaluate them before moving forward. And finally once you are done reboot once more (to see that grub2 is working fine by itself) and you will be running the latest uptodate squeeze system.

4. (Optional) Convert your ext3 filesystems to ext4

This step is optional and if you are happy with the ext3 filesystem then you can safely skip it. Myself, I’ve done this most of the time so I thought it might be useful to add it here for anyone else interested to do the same.

First doublecheck if you are running the 2.6.32 squeeze kernel:
uname -a
Linux srv01 2.6.32-5-amd64 #1 SMP Wed Jan 12 03:40:32 UTC 2011 x86_64 GNU/Linux

Older than 2.6.28 kernels (like lenny 2.6.26 for example) don’t have native support for ext4, so this will fail for an older kernel. Because ext4 is backwards compatible with ext3, all we have to do is to change the mount definitions to ext4 in fstab:
vim /etc/fstab
and change the filesystem from ext3 to ext4 for any devices you might have. Make a note on the devices you change, and reboot the machine. After the reboot the machine will use the ext4 driver for the old filesystem even though it doesn’t take full advantage of the ext4 capabilities. To complete this and enable the extra ext4 features we will need to run for each filesystem:
tune2fs -O extents,uninit_bg,dir_index <device>
like, for example for /dev/sda1:
tune2fs -O extents,uninit_bg,dir_index /dev/sda1
this will only be activated when the filesystem is unmounted and we can achieve this with yet another reboot (especially for the root filesystem), and the system will auto fsck them (as the last command marked the filesystem as dirty) and perform the upgrade. I would highly recommend for this to have a remote console on the system as in most of the cases the auto fsck will fail and you will have to run it manually from the console.

Hopefully this howto will help you upgrade your debian system to squeeze with ext4. If you have encountered anything special during the upgrade feel free to share it with others using the comment box bellow.

 

출처 : http://www.ducea.com/2011/02/05/howto-upgrade-from-debian-lenny-to-squeeze/

zimage와 bzImage는 무슨 차이가 있는걸까? 필자는 처음에 z와 b의 의미 때문에 gzip으로 압축하거나 아니면 bzip2로 압축한 것의 차이인줄 알았지만 압축은 gzip으로 같고 단지 z는 압축했단 의미고 b는 'big kernel'이란 뜻인걸 알았다. 왜 이렇게 나눠졌는가?

이미 1.7절에서 언급했던 것 처럼 커널의 크기가 너무 커서 압축 후에도 일정 크기를 넘어가면 zImage 대신 bzImage를 사용해야한다고 했는데 이유는 다음과 같다.

pc가 처음 만들어질 땐 OS로 도스가 사용됐고 이 때 M$의 유명한 분이 640KB면 충분하다고 했단 소릴 들은적이 있을 것이다. 처음 PC가 만들어질 때의 CPU는 8086으로 16bit CPU 였다. 이 프로세서가 지원하는 최대의 메모리는 1MB였기 때문에 모든 어드레스 스페이스가 1MB 내로 제한됐다. 그러므로 램을 640kb 사용하고 나머지 영역엔 MGA, VGA와 같은 다른 디바이스를 할당해 줬다.

문제는 여기서 시작되는데 AT시절의 PC 기본 구조는 현재까지도 계속 유지되고 있기 때문에 PC가 처음 부팅되면 하위 1MB 만을 사용한다고 생각하면 된다. 보호모드라고 알고 있는 386 이상의 cpu가 가진 기능을 사용하지 않고 리얼모드란 8086 호환 모드를 사용하기 때문인데 이는 OS가 보호모드를 사용할 상태를 만들고 전환하기 전까지는 계속 리얼모드로 남아있기 때문이다.

리눅스 커널의 크기가 커서 커널을 읽어들이는 프로그램 크기나 시스템에서 사용되는 약간의 메모리를 제외한 나머지 램의 빈공간에 읽어 들이지 못하면 하위 1MB가 아니라 그 이상의 연속된 메모리에 커널을 읽어 들이고 압축을 푸는 등의 일을 해야할 것이다. 반대로 남은 용량에 커널이 들어갈 수 있다면 당연히 읽어 들이고 압축을 풀면 끝날 것이고...

이렇게 메모리에 처음 적재되고 압축 풀리고 하는 절차와 위치가 다르기 때문에 zImage와 bzImage오 나뉜 것이고 커널 이미지 파일의 앞부분 bootsect와 setup이 각각에 따라 맞는 것으로 합쳐지게된다. 그리고 bzimage의 경우 하위 1M는 사용하지 못하는데 리눅스에선 그렇다!

컴파일 단계에서 make zImage 했을 경우 System is too big. Try using bzImage or modules. 라고 에러가 난다면 더 많은 부분을 module로 만들거나 bzImage를 사용해야한다.


출 처 : http://blog.naver.com/hdalba?Redirect=Log&logNo=130002608246




kernel

태스크 관리자가 구현된 디렉토리. 문맥 교환(context switch)과 같은 하드웨어 종속적인 태스크 관리 부분은 arch/$(ARCH)$/kernel 디렉토리에 구현되어 있다.


arch

리눅스 커널 기능 중 하드웨어 종속적인 부분들이 구현된 디렉토리.


fs

리눅스에서 지원하는 다양한 파일시스템과 open(), read(), write() 등의 시스템 호출이 구현된 디렉토리. 현재 리눅스에는 약 50가지 정도의 파일시스템이 구현되어 있으며 계속 새로운 파일시스템이 개발중이다. 다양한 파일시스템을 일관된 인터페이스로 접근할 수 있도록 하기 위해 리눅스가 도입한 가상 파일시스템(virtual file system)도 이 디렉토리에 존재한다.


mm

메모리 관리자가 구현된 디렉토리.


driver

리눅스에서 지원하는 디바이스 드라이버가 구현된 디렉토리.


net

리눅스 커널 소스 중 상당히 많은 양을 차지하는 이 디렉토리는 리눅스가 지원하는 통신 프로토콜이 구현된 디렉토리다.


ipc

리눅스 커널이 지원하는 프로세스간 통신 기능이 구현된 디렉토리. 이 디렉토리에는 message passing, shared memory, semaphone가 구현되어 있다.
파이프는 fs 디렉토리에, 시그널은 kernel 디렉토리에, 소켓은 net 디렉토리에 구현되어 있다.


init

커널 초기화 부분, 즉 커널의 메인 시작 함수가 구현된 디렉토리. 하드웨어 종속적인 초기화가 arch/$(ARCH)$/kernel 디렉토리 하위에 있는 head.S와 mics.c에서 이뤄지고 나면, 이 디렉토리에 구현되어 있는 start_kernel() 이라는 C함수로 제어가 넘어 온다.


include

리눅스 커널이 사용하는 헤더 파일들이 구현된 디렉토리. 헤더 파일 중에서 하드웨어 독립적인 부분은 include/linux 하위 디렉토리에 정의되어 있으며, 하드웨어 종속적인 부분은 include/asm-$(ARCH) 디렉토리에 정의되어 있다.


others

Documentation - 리눅스 커널 및 명령어들에 대한 자세한 문서 파일들이 존재하는 디렉토리
lib - 커널 라이브러리 함수들이 구현된 디렉토리
scripts - 커널 구성 및 컴파일 시 이용되는 스크립트 들이 존재하는 디렉토리


APUE에 보니까 그 이유가 나와있네요.
pp. 411-413 까지에 mmap을 이용한 파일복사 예제가 나와있는데,
output 파일의 사이즈를 설정할 필요가 있다고 합니다.
파일의 사이즈를 설정한다고 하는 것이 제가 생각하기로는 그 파일을 위한 공간을 할당한다는 의미로 해석을 해야 하는 것 같습니다. (사용자가 파일연산을 통하지 않고 곧바로 stat 정보의 file size 를 변경할 수 없지 않나요?) 
포인터를 사용해서 strcpy() 를 할 때, 대상 포인터가 가리키는 영역이 미리 할당되어 있어야 하는 것과 비슷한 생각이 드는데요. 여기서 포인터가 mmap한 주소가 되겠고, 실제파일영역이 mmap을 통해서 가리키는 저장공간이 되겠죠.

테스트를 해 보기 위해서 a.out 을 a.out2 라는 파일로 복사해 보았습니다.
% cp a.out a.out2
% a.out a.out a.out2
=> Bus Error

코드 상에 O_TRUNC 가 있어서 cp를 통해 a.out 을 a.out2 로 복사해 놓아도 open이 되면 0 byte로 변하게 되어서 여전히 Bus Error가 발생했습니다.
open의 O_TRUNC를 빼고 다시 컴파일해서 수행했더니 정상수행됐습니다.

복사하려는 파일보다 더 큰 크기를 가지는 파일을 대상파일로 설정해 보았습니다. 이 경우도 O_TRUNC는 빼 놓았구요.

% cp biggerfile cli.d
% ls -al cli cli.d
...
-rwxr-xr-x 1 ... 9888 1월 5일 1853 cli
-rw------- 1 ... 23720 3월 29일 1619 cli.d
% a.out cli cli.d
...
-rwxr-xr-x 1 ... 9888 1월 5일 1853 cli
-rw------- 1 ... 23720 3월 29일 1619 cli.d

정상수행됐지만 대상파일의 크기가 이전파일크기를 그대로 유지하네요. 예상됐던 결과지요. 아마 cli.d 의 앞쪽 9888 바이트만큼은 cli와 동일하겠죠?

결론. 
정상 수행을 위해서는 O_TRUNC 옵션을 빼면 안 되겠고, 
대상 파일크기 설정을 위해서는 대상파일이 원본파일만큼 크기를 가지도록 보장해 주어야 하겠고, lseek() 후 맨 끝에 한바이트 써주는 식으로 해주면 된다.

해당 원문입니다. 참조하세요.

Program 12.14 copies a file (similar to the cp(1) command) using memory mapped I/O. We first open both files and then call fstat to obtain the size of the input file. We need this size fo the call to mmap for the input file, plus we need to set the size of the output file. We call lseek and then write one byte to set the size of the output file. If we don't set the output file's size, the call to mmap for the output file is OK, but the fist reference to the associated memory region generates SIGBUS. ...

출 처 : http://kldp.org/node/1575

umask

- 새로운 파일이나 디렉토리에 대한 허가권 지정 명령어

- chmod와 반대로 해당 그룹 및 다른 사용자들에게 쓰기 권한을 박탈하는 것

- 일반 파일의 경우 666, 디렉토리인 경우 777에서 umask 값을 뺀 값으로 허가권 지정

- .profile, .cshrc, .bashrc, .login과 같은 사용자 프로파일에서 설정

 

 umask

 디렉토리 허가권 

 파일 허가권

002 

 775

 664

 007

 770

 660

 020

 757

 646

 070

 705

 604

 022

 755

 644

 


모든 사용자에서 적용할 umask 값은  /etc/login.defs 에서 UMASK 값을 설정함으로써 정할 수 있다.


출 처 : http://gimbonggu.blog.me/90100567367 

+ Recent posts