2019. 8. 16. 16:29

"Debian Package 만들기"



 

    개요

Debian Package란 *.deb 확장자를 가지는 파일로 윈도우의 *.msi 와 같은 프로그램 설치를 위한 파일 이다.

 

데비안 패키지(.deb) dpkg 라는 패키지 관리 도구에 의해 관리 유지 되며,

dpkg 데비안, 우분투, 칼리, 민트 기타 많은 배포판에서 사용되는 패키지 관리 도구이다.

 

.deb 파일은 데비안 패키지이지만 실제로는 표준 유닉스 아카이브(.ar) 파일일 뿐이다.

나중에 다루겠지만 apt역시 dpkg 사용해서 만든 고급 관리도구 이다.

 

 

 

    인스톨된 패키지 확인

현재 자신의 리눅스 장비에 설치된 패키지를 확인해 보자.

dpkg -l       # List installed packages
dpkg -s mypkg # Get status of specific package

apt list --installed # List installed packages
apt list # List *all* packages in available repos

               

 

 

 

    패키지 만들기(Create a package)



1. BASE 디렉토리 만들기

먼저 패키지를 새롭게 만들려면 BASE 디렉토리를 만든다.

디렉토리는 안에는 메타데이터 패키지 내용이 저장 된다.

  • <패키지 이름>_<버전>-<리비전>

Example: devpack_1.0.0-1

$ mkdir devpack_1.0.0-1

 

 


2. DEBIAN/control 파일 만들기

여기서 (DEBIAN) 디렉토리는 하나의 특수 파일로 무조건 있어야 하는 디렉토리 이다.

디렉토리는 안에는 control script 파일이 존재하며, 여기서 만드는 control 파일은 제어파일로

패키지에 대한 중요 정보를 제공하는 파일이다. (Debian control file fields)

Package: devpack
Version: 1.0.0
Maintainer: Your Name <dev@example.com>
Description: My test package
Homepage: http://devanix.tistory.com
Architecture: all

Section:non-free

Priority:optiona
Depends: git, tomcat(>=10.0.1)

  • Package

패키지 이름을 적는다.

소문자로만 이루어 져야하며, (_) 대신 (-) 를 사용한다.

  • Version

패키지의 버전을 명시함.

apt 서버(repository) 및 설치 서버의 내부 DB에서 관리 됨으로 잘 관리 해야함

  • Architecture

amd64/i386 으로 구분됨, 그냥 amd64를 쓰면 됨

  • Maintainer

자식의 이름(닉네임), 연락처 혹은 메일 기입

  • Description

aptcache 나 aptitude 로 패키지 search 를 했을때 Package 이름과 함께 설명으로 출력 되는 부분

  • Depends 필드는 생성할 패키지가 가지는 의존성을 기록한다.

없어도 되는 옵션 필드이지만 자주 사용된다.
기입한 패키지 버전 조건이 맞지 않으면 설치되지 않거나 설치 업데이트를 시도한다.

ex) mysqld ( >= 10.0.0.1) : mysql 패키지가 10.0.0.1 이상이여야 함

ex) tomcat ( = 6.0.0) : tomcat 패키지가 반드시 6.0.0 이여야 함

 

 

DEBIAN/control 파일까지만 만들면 최소한의 패키지 구성이 된다.

# Minimum required structure for a package

devpack-1.0.0/     # Directory
└── DEBIAN/       
# Directory
    └── control   
# File                   

 


3. DEBIAN/conffiles

conffiles 명시된 파일들은(절대경로) 패키지를 제거 (dpkg -r, --remove) 혹은 업데이트 경우

명시된 파일들을 삭제 하거나 덮어쓰지 못하게 합니다.

conffiles 명시된 파일은 dpkg -P, --purge 의해서만 삭제 됩니다.

 

Example :

/etc/myconf.ini
/usr/local/mypack/conf/config.ini
             

 


4. DEBIAN/script 구성

패키지 설치 (preinst), 설치 (postinst), 삭제 (prerm), 삭제 (postrm) 구동 되는
스크립트로 (스크립트 작동 방식 설명) script 이용해 다양하게 구성이 가능하다.


 

 

DEBIAN/preinst

패키지내 포함된 파일을 서버에 설치하기 전에 실행 되는 스크립트

스크립트 아규먼트로 install/upgrade를 받을 수 있다.

 

Example :

#!/bin/bash

############################################################
# preinst script main
############################################################

case "$1" in
install)
  #
최초 설치시 파일 설치 전 수행 되어야 할 내용을 bash 스크립트로 기술
  # EX)
기존 설정 백업, 가동중인 프로세스 down
  ;;

upgrade)
  #
업그레이드시 파일 설치 전 수행 되어야 할 내용을 bash 스크립트로 기술
  ;;

*)
  echo "Unrecognized preinst argument '$1'"

esac

                   

 

 

DEBIAN/postinst

패키지내 포함된 파일을 서버에 설치한 후에 실행 되는 스크립트

스크립트 아규먼트로 configure/upgrade를 받을 수 있다.

 

 

DEBIAN/prerm

패키지 삭제 전 실행 되는 스크립트

스크립트 아규먼트로 upgrade/remove를 받을 수 있다.

 

Example :

#!/bin/bash

############################################################
# prerm script main
############################################################

case "$1" in
upgrade)
  #
업그레이드 전에 해야할 작업 기술
  # EX)
패키지가 업그레이드 될때, 다음 버전 패키지에 의하여 호출 됨.
  ;;

remove)
  #
파일 삭제 전에 해야할 작업 기술
  # EX)
프로세스 중단 등, postinst 에서 했던 작업의 원복으로 생각하면 이해가 편함.
  ;;

*)
  echo "Unrecognized preinst argument '$1'"

esac

                   

 

 

DEBIAN/postrm

패키지 삭제 후 실행 되는 스크립트

스크립트 아규먼트로 remove/purge를 받을 수 있다.

remove - 설정 파일을 제외한 바이너리 파일 삭제.

purge - 설정 파일까지 모두 삭제.

remove 후 재설치를 하면 기존 설정 대로 재사용이 가능 하지만, purge 후 재설치 하면 설정을 다시해야한다.

 

Example :

#!/bin/bash

############################################################
# postrm script main
############################################################

case "$1" in
remove)
  #
파일 삭제 후에 해야할 작업 기술
  # EX) preinst
에서 했던 작업의 원복으로 생각하면 이해가 편함.
  ;;

purge)
  #
파일 삭제 후에 해야할 작업 기술
  # EX) preinst
에서 했던 작업의 원복으로 생각하면 이해가 편함.
  ;;

*)
  echo "Unrecognized preinst argument '$1'"

esac

                   

 


5. 패키지 내용 구성

BASE 디렉토리 밑으로 원하는 패키지 내용을 구성 한다.

일반적으로 패키지 구성으로 라이브러리, 문서, 환경파일, 실행 프로그램, systemd service등으로 구성 있다.

Example:

  • /usr/local/bin
  • /usr/share/man
  • /etc/
  • /usr/local/lib
  • /usr/local/include

 

 

 

 

    패키지 빌드(Build)

패키지 구성을 완료 하였다면 다음과 같이 빌드를 진행해 보자.

자세한 내용은 (dpkg-deb manpage) 참조 한다.

 

dpkg-deb -b ${패키지구성요소디렉토리명} ${패키지명}_{패키지버전}.deb

Example:

# ls -l

total 4

drwxr-xr-x 4 root root 4096 Aug 15 02:51 devpack_1.0.1

 

# dpkg-deb --build devpack_1.0.1 

dpkg-deb: building package `devpack' in `devpack_1.0.1.deb'.


or
 

# dpkg-deb --build devpack_1.0.1 devpack_1.0.1.deb

dpkg-deb: building package `devpack' in `devpack_1.0.1.deb'.

 

 

     



Posted by devanix
2018. 11. 2. 23:52

"Swap Memory"

 



 

리눅스의 메모리 부족할 경우 OOM(Out Of Memory) or Cannot allocate memory 문제가 발생 있습니다.

리눅스는 이런 메모리 부족을 대비 하여 일종에 보조 역활을 수행 하기 위한 방법으로 스왑(Swap)메모리를 사용합니다.

스왑(Swap) 물리적인 메모리가 완전히 활용되었을 운영 체제에서 사용하기 위한 가상 메모리 입니다.

이것은 디스크 파티션이나 파일 있습니다. (리눅스는 파티션, 파일 모두 파일로 인지 합니다)

 

 

일반적으로  리눅스 서버를 운영하게 되면 스왑 파티션을 기본적으로 사용하게 되지만

AWS 프리티어를 사용하기 위해 EC2 t2.micro 이용해 리눅스로 서비스를 경우

"Cannot allocate memory" 나타날 있다.  이런 다양한 케이스를 대비 하여 Swap 생성하는 방법을 알아 봅시다.

 

 

 

    스왑(Swap) 확인

 

[방법 1] swapon -s : 스왑이 잡혀 있지 않으면 아무런 결과가 출력되지 않음

 

# swapon -s

 

 

[방법 2] free -m : Swap : 항목에 모든 결과가 "0"으로 출력

# free -m

             total       used       free     shared    buffers     cached

Mem:           999        883        115          8          3         62

-/+ buffers/cache:        817        181

Swap:          0           0          0

 

 

    스왑(Swap) 설정

 

  1. 스왑메모리로 사용할 파일을 생성 합니다.

단계에서는 아무런 기능도 하지 않는 단순 디스크 공간을 할당 하는 파일을 생성 한다.

 

[방법 1] dd 이용해 파일 생성 (블럭 1M * 2048 = 2GB )

 

# dd if=/dev/zero of=/swapfile bs=1M count=2048

 

 

[방법 2] fallocate 이용해 파일 생성

 

# fallocate --length 2G /swapfile

 

 

[ 참고 ]

실제로 file명령을 통해 파일의형을 확인해 보면 단순 data 파일임을 있다.

# file  /swapfile

/swapfile: data

 

 

  1. 파일 사용 권한 설정

퍼미션 설정은 파일 소유자(root)로 제한 한다.

 

# chmod  600  /swapfile

 

# ls -al swapfile 

-rw------- 1 root root 2147483648 Oct 31 06:25 swapfile

 

  1. 스왑 파일 설정

단계에서는 단순 data 파일을 swap 파일로 초기화 한다.

# mkswap /swapfile 

Setting up swapspace version 1, size = 2097148 KiB

no label, UUID=79411347-40af-4680-a31e-657700076ce8

 

File명령을 통해 파일 Type 확인해 보면 swap file문구를 출력 한다.

# file /swapfile 

/swapfile: Linux/i386 swap file (new style) …

 

  1. 스왑 파일 장착

[ swap 활성화 ] : 스왑(swap)파일을 시스템이 사용할 있도록 swap 영역 으로 활성화 한다.

 

# swapon  /swapfile

 

 

[ swap 비활성화 ] : 반대로 swap 영역 비활성화

swap 크기를 변경 하고자 경우 swapoff 명령을 통해 비활성화 1 과정을 되풀이 한다.

 

# swapoff  /swapfile

 

 

[ 참고 ]

미션이 0600 아니면 아래와 같이 0600 제안하는 메시지를 출력 하며, swap 영역으로 활성화는 된다.

 

# swapon /swapfile

swapon: /swapfile: insecure permissions 0644, 0600 suggested.

 

 

 

    /etc/fstab 등록

시스템이 재부팅 되면왑영역이 비활성화 되어 있어 수동으로 swapon명령을 통해 스왑 영으로 활성화 해줘야

하는 번거로움이 있다. 재부팅시에 자동으로 스왑 영역을 활성화 되도록 /etc/fstab 등록 한다.

 

  1. 스왑 파일 UUID 확인

 

# blkid /swapfile 

/swapfile: UUID="79411347-40af-4680-a31e-657700076ce8" TYPE="swap"

 

 

  1. /etc/fstab 등록

해당 파일 하단에 아래와 같이 swap 설정 추가 한다.

 

UUID=79411347-40af-4680-a31e-657700076ce8 swap swap defaults 0 0

 

 

  • UUD – device /file name, UUID
  • swap – defines device mount point
  • swap – specifies the file-system type
  • defaults – describes the mount options
  • 0 – specifies the option to be used by the dump program
  • 0 – specifies the fsck command option

 

 

[ 참고 ]

/etc/fstab 등록되어 있다면  "swapon -a"옵션을 통해 자동 활성화 한다.

아래와 같이 swapoff 통해 스왑영역 비활성화 swapon -a 통해 자동 등록 되는 것을 있다.

 

# swapoff /swapfile 

# swapon -s

# swapon -a

# swapon -s

Filename Type Size Used Priority

/swapfile                              file    2097148 0 -1

 


Posted by devanix
2017. 6. 27. 19:25

NTP 시간 동기화

 

NTP(Network Time Protocol) 인터넷상의 시간을 정확하게 유지시켜 주기 위한 통신망 시간 규약이다

라디오나 원자시계에 맞추어 시간을 조정하며 밀리초 1/1000 단위까지 시간을 맞출  있다.

기본적으로, NTP 방식은 straum이라는 계층구조를 가지는데 straum 0  GPS 세슘 원자 시계등 시간을 구하는 장비를 말하며

straum 1 GPS  세슘 원자 시계등에서 직접 시간을 동기화하는 서버를 의미한다. strum 2 부터는 트리 구조를 형성하게 된다

보통 straum 2에서 동기화를 하고 동기화를 받은 straum 3 서버에서 나머지 같이 운영하는 서버들을 peer 해서 동기화를 

시키므로써 straum 1 서버들의 부하를 줄인다.

 

 

NTP 설정


 1. peer 정을 위한 ntp.conf 수정

시간 동기화를 받기 위한 설정내용이다기본적으로 입력되어있는 server 0.gentoo.pool.ntp.org등을

주석처리하 국내 (혹은 해당 사이트) NTP서버로 대체한다.

vi /etc/ntp.conf

# Pools for Gentoo users

server kr.pool.ntp.org

server time.bora.net

server time.kornet.net

 

#server 0.gentoo.pool.ntp.org

#server 1.gentoo.pool.ntp.org

#server 2.gentoo.pool.ntp.org

#server 3.gentoo.pool.ntp.org

 

 2. NTPD 스크립트 수정

기본값의 경우 ntpd 는 오프셋이 패닉 임계 값 (기본값 : 1000 초)을 초과하면 시스템 로그에 메시지와 함께 종료함으로,

ntpd script에 다음과 같이 NPTD_OPTS='-g'를 추가하여 저장 한다.

vi /etc/init.d/ntpd

#!/sbin/runscript

# Copyright 1999-2004 Gentoo Foundation

# Distributed under the terms of the GNU General Public License v2

$Header: /var/cvsroot/gentoo-x86/net-misc/ntp/files/ntpd.rc,v 1.23 2007/02/23 11:26:26 uberlord Exp $

 

NTPD_OPTS='-g'

 

depend() {

        need net

        use dns logger

        after ntp-client

}


3. NTP 데몬 재시작

Bash

Devanix ~ #  /etc/init.d/ntpd restart

 * Stopping ntpd ...                                                          [ ok ]

 * Starting ntpd ...                                                            [ ok ]


4. 프로세스 확인

-g 옵션이 붙어 있는것을 확인하자

Bash

Devanix ~ #  ps -ef | grep -i ntpd
root     15577     1  0 05:59 ?        00:00:00 /usr/sbin/ntpd -p /var/run/ntpd.pid -g


 5. 테스트

date 명령으로 임의날짜로 변경 하여 동기화 되는지 확인해 보자.

NTP 는 동기화하기까지 5~10분의 시간이 걸리니 여유를 갖도록 하자.

Bash

Devanix ~ #  date 11111111

2017. 11. 11. (토) 11:11:00 KST

 

/var/log/message를 통해서 정상적으로 동기화가 되면 다음과 같이 확인이 가능하다

Nov 11 11:19:28 ISIGN_HA1 ntpd[18613]: synchronized to 203.248.240.140, stratum 2

Mar 28 15:13:22 ISIGN_HA1 ntpd[18613]: time reset -19685166.831597 s

Mar 28 15:13:22 ISIGN_HA1 ntpd[18613]: kernel time sync status change 0001



Posted by devanix
2012. 3. 18. 19:59
<< add-apt-repository를 이용하여 /etc/apt-sources.list 저장소에 jdk 추가하기 >>
$ sudo add-apt-repository ppa:ferramroberto/java
$ sudo apt-get update (/etc/apt/sources.list 업데이트)

<< java 설치하기 >>
$ sudo apt-get install sun-java<version>-jdk

<< 설치된 모든 자바 목록 확인 >>
$ sudo update-alternatives --list java




< 여러 버전의 자바가 설치된 경우 우선순위 설정>
$ update-alternatives --config java 
 There are 3 alternatives which provide `java'.

 

  Selection    Alternative

-----------------------------------------------

*         1    /usr/lib/jvm/java-1.5.0-sun/jre/bin/java

 +        2    /usr/lib/jvm/java-6-sun/jre/bin/java

          3    /usr/lib/jvm/java-1.5.0-sun-1.5.0.19/bin/java

 

Press enter to keep the default[*], or type selection number: 1

 

 1~3 중 원하시는 버전의 번호를 누르면 설정 됩니다. 
 


< apt-get 설치시 기본적 심볼릭 링크 >
/usr/bin/java ==> /etc/alternatives/java ==> /usr/lib/jvm/java-<version>-sun/jre/bin/java (실제 설치된 자바)

< 자바 환경설정 >
vi ~/.profile
 ... <중략> ....

### JAVA Settings ###
export JAVA_HOME = /usr/lib/jvm/java-<version>-sun/
export PATH=$PATH:$JAVA_HOME/bin

$ sudo source ~/.profile 




'Linux' 카테고리의 다른 글

리눅스 디렉토리 구조  (0) 2010.07.29
[centOS5.5]bonding 설정  (0) 2010.06.11
서버 데몬 유형  (1) 2010.05.29
[CentOS]Consol Network 설정  (0) 2010.05.26
Job 스케줄링  (0) 2010.05.18
Posted by devanix
2011. 11. 3. 00:52

#include <stdlib.h>

/* _exit(2) */

void _exit(int status);

return: 없음

#include <unistd.h>

/* exit(3) */

void exit(int status);

return: 없음

#include <stdlib.h>

/* exit(3) */

int atexit(void (*function)(void));

 

return: 성공 0, 실패 -1

◎  _exit()는 호출 프로세스를 "즉시" 종료합니다.

프로세스에 속한 열린 파일 디스크립터들이 모두 닫히고, 프로세스의 자식들은

프로세스 1번인 init프로세스 에게 승계하며 프로세스 부모에게는 SIGCHLD 시그널이 갑니다.

값 status을 부모 프로세스에게 프로세스의 종료 상태로 반환합니다.

(함수 _Exit()는 _exit()과 동등함)

 

 exit()는 일종의 라이브러리로 먼저 표준 입출력 라이브러리들에서 사용한 버퍼를 모두 방출(flush)

시키고 atexit()에서 등록시킨 exit 핸들러들을 모두 실행시킨후 _exit()를 호출하게 된다.

(main()에서의 return()은 exit()와 동등함)

 

C 표준에서는 두 상수 EXIT_SUCCESS와 EXIT_FAILURE를 명세하고 있는데,

이를 exit()에게 전달해서 각각 성공적인 종료과 성공적이지 못한 종료를 나타낼 수 있습니다.

 

 atexit() 함수는 exit(3)이나 프로그램 main()에서의 반환을 통한 정상적 프로세스 종료시 주어진

함수 function을 호출하도록 등록합니다. 그렇게 등록한 함수들은 등록 역순으로 호출하며 아무

인자도 전달하지 않습니다.

 (같은 함수를 여러 번 등록하는 것도 가능. 각 등록마다 한 번씩 호출)

   

POSIX.1-2001에서는 구현체가 적어도 ATEXIT_MAX (32)개까지의 함수 등록을 허용해야 한다고 요구

하고 있습니다. 구현체가 지원하는 실제 제한치는 sysconf(3)를 이용해 얻을 수 있습니다.

   

fork(2)를 통해 자식 프로세스가 생기면 부모의 등록 함수들 사본을 물려받습니다.

exec(3)군 함수 중 하나의 호출이 성공하면 등록 항목 모두가 지워집니다.

 

(exit 핸들러란, 프로그램 종료 시에 실행시킬 일종의 작업을 일컫는 것으로 atexit()에 의해 등록)

Posted by devanix
2011. 10. 23. 23:07

◎ 시스템들은 한계들(Lmists)을 다음과 같이 세 종류로 분류:

1. 컴파일 시점 한계들 (헤더)

2. 파일이나 디렉터리와는 무관한 실행시점 한계들(sysconf 함수)

3. 파일이나 디렉터리와 연관된 실행시점 한계들(pathconf, fpathconf 함수)

 

◎ Compile-time limits (헤더):

ISO C Limits : <limits.h> <stdio.h>

POSIX Limits : 일부<limits.h>-><bits/posix1_lim.h>,<bits/posix2_lim.h>

XSI Limits : 일부 <limits.h>-><bits/xopen_lim.h>

(우분투 kernel 3.0.x는 </usr/include/i386-linux-gnu/bits/*lim.h>에 정의)

 

◎ Runtime limits

특정한 시스템이 실제로 지원하는 한계를 알아내려면 일부는 컴파일 시점에서 알 수 있으나

어떤 것들은 반드시 실행시점에서 파악해야 한다. 또한 어떤 한계들은 주어진 한 시스템에서

변하지 않지만, 파일이나 디렉터리에 연관된 일부 한계들은 상황에 따라 변한다.

실행시점 한계들을 알고자 할 때 사용할 수 있는 함수들은 다음 세 가지이다.

#include <unistd.h>

long sysconf(int *name);

long pathconf(char *pathname, int name);

long fpathconf(int *filedes, int name);

 

all three return: 성공 해당 , 오류 -1.

name 인수에 적절한 상수가 지정되지 않으면 -1, errno EINVAL 설정.

ㆍ미결정인 한계의 경우 -1 반환되나 errno 설정하지 않음.

@ pathconf, fpathconf 두 함수는 기능은 동일하되,

하나는 pathname(경로명) 이며, 하나는 filedes(파일 디스크립터)를 받는다는 점에서 구별.

@ name : sysconf는 _SC_*로 시작, (f)pathconf는 _PC_*로 시작.

 

[ sysconf로 얻을 수 있는 한계들과 그에 해당하는 name 인수 값]

name argument

Description

_SC_ARG_MAX

exec* 함수들에 대한 인수들의 최대 길이 (바이트 단위)

_SC_ATEXIT_MAX

atexit 함수로 등록할 수 있는 함수들의 최대 개수

_SC_CHILD_MAX

실제 사용자 ID당 자식 프로세스 개수

_SC_CLK_TCK

1초 동안의 클록 틱 개수

_SC_COLL_WEIGHTS_MAX

로케일 정의 파일의 LC_COLLATE 순서 키워드의 한 항목에

배정할 수 있는 가중치들의 최대 개수

_SC_HOST_NAME_MAX

gethostname이 돌려주는 호스트 이름의 최대 길이

_SC_IOV_MAX

readv or writev에 사용할 수 있는 iovec 구조체의 최대 개수

_SC_LINE_MAX

utility의 입력 라인의 최대 길이

_SC_LOGIN_NAME_MAX

login 이름의 최대 길이

_SC_NGROUPS_MAX

프로세스당 동시적인 추가 그룹 ID 최대 개수

_SC_OPEN_MAX

프로세스당 열린 파일 최대 개수

_SC_PAGESIZE

시스템 메모리 페이지 크기(바이트 단위)

_SC_PAGE_SIZE

시스템 메모리 페이지 크기(바이트 단위)

_SC_RE_DUP_MAX

regexec 함수와 regcomp 함수에 구간 표기 \{m,n\}를 사용할 때

허용되는, 기본 정규표현식 안의 반복된 출현 횟수

_SC_STREAM_MAX

프로세스가 동시에 열어둘 수 있는 표준 I/O 스트림 최대 개수

(FOPEN_MAX와 같아야 함)

_SC_SYMLOOP_MAX

경로이름 해소 도중 운행될 수 있는 심볼릭 링크 개수

_SC_TTY_NAME_MAX

터미널 장치 이름의 길이(종료 널 문자 포함)

_SC_TZNAME_MAX

시간대 이름의 최대 바이트 수

 

[ (f)pathconf로 얻을 수 있는 한계들과 그에 해당하는 name 인수 값 ]

name argument

Description

_PC_FILESIZEBITS

지정된 디렉터리에 존재할 수 있는 정규 파일의 최대 크기를 하나의

부호 있는 정수 값으로 나타내는 데 필요한 최소 비트 수

_PC_LINK_MAX

파일의 최대 링크 개수

_PC_MAX_CANON

터미널의 표준 입력 대기열의 최대 바이트 수

_PC_MAX_INPUT

터미널의 입력 대기열에 사용할 수 있는 공간의 최대 바이트 수

_PC_NAME_MAX

파일이름의 최대 바이트 수(종료 널 문자는 뺀)

_PC_PATH_MAX

상대 경로이름의 최대 바이트 수(종료 널 문자 포함)

_PC_PIPE_BUF

파이프에 원자적으로 기록될 수 있는 최대 바이트 수

_PC_SYMLINK_MA

심볼릭 링크의 최대 바이트 수

 

@ (f)pathconf 인수인 pathnamefiledes 인수의 제약 사항. (제약 위반 시 결과는 정의되지 않음)

▶ _PC_MAX_CANON과 _PC_MAX_INPUT에 대해 지정된 파일은 반드시 터미널 파일이어야 함.

▶ _PC_LINK_MAX에 대해 지정된 파일이 디렉터리이면 반환 값은 그 디렉터리 안의 파일이름 항목들이

아니라 디렉터리 자체에 대한 것이다.

▶ _PC_FILESIZEBITS와 _PC_NAME_MAX에 대해 지정된 파일은 반드시 디렉터리이어야 한다.

반환값은 그 디렉터리 안의 파일이름들에 대한 것이다.

▶ PC_PATH_MAX에 대해 지정된 파일은 반드시 디렉터리이어야 한다.

반환값은 지정된 디렉터리가 작업 디렉터리일 때의 상대 경로이름의 최대 길이이다.

(안타깝게도 이 값이 우리가 알고자 하는 절대 경로 이름의 실제 최대 길이는 아니다.)

▶ _PC_PIPE_BUF에 대해 지정된 파일은 반드시 파이프, FIFO, 디렉터리이어야 한다.

파이프나 FIFO의 경우 반환값은 지정된 파이프 또는 FIFO에 대한 한계이고, 디렉터리의 경우 반환값은

그 디렉터리안에 생성된 임의의 FIFO에 대한 한계이다.

▶ _PC_SYMLINK_MAX에 대해 지정된 파일은 반드시 디렉터리이어야 한다.

반환값은 그 디렉터리 안의 심볼릭 링크가 담을 수 있는 문자열의 최대 길이이다.

 

Posted by devanix
2011. 10. 23. 16:29

#include <sys/types.h>

#include <utime.h>

int utime(const char *filename, const struct utimbuf *times);

 

반환값: 성공 0, 실패 -1(errno 설정)

@filename: 변경할 파일 이름

@times :

- NULL이면 접근 시간과 수정 시간 모두 현재 시간으로 설정.

(유효 사용자 ID가 파일의 소유자 ID와 같거나, 프로세스가 파일에 대해 쓰기 권한 필요)

- NULL이 아니면 접근 시간과 수정 시간이 times가 가리키는 구조체에 있는 값들로 설정.

(유효 사용자 ID가 파일의 소유자 ID와 같거나, 프로세스가 슈퍼 사용자 프로세스여야 함)

 

utimbuf 구조체:

struct utimbuf {

    time_t actime;

    time_t modtime;

}

 

/* access time */

/* modification time */

※ 구조체에 상태 변경 시간(st_ctime, i노드가 마지막으로 변경된 시간)에 대한 필드가 없는 것은

utime 함수가 호출되면 어차피 자동으로 갱신되기 때문이다.

 

[ Example ]

/data/workspace/linux-src/example/file/zap.c.html
 
/* zap.c 
 * 
 * O_TRUNC를 지정한 open을 이용해서 주어진 파일들의 
 * 크기를 0으로 줄이되, 파일들의 접근 시간이나 수정 
 * 시간은 변경하지 않는다. 이를 위해 프로그램은 우선 
 * stat 함수로 시간들을 얻고, 파일을 크기 0으로 자르고, 
 * utime 함수로 시간들을 복원한다. 
 */ 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <utime.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <errno.h> 
 
int main(int argc, char *argv[]) {
    int	i, fd;
    struct stat	    statbuf;
    struct utimbuf  timebuf;
 
    if (argc < 2) {
	fprintf(stderr, "Usage: %s <files>...\n", argv[0]);
	return 0;
    }
 
    for (i=1; i<argc; i++) {
	/* 현재 시간을 얻는다 */ 
	if (stat(argv[i], &statbuf) < 0) {
	    fprintf(stderr, "%s: state error: %s\n",
		    argv[i], strerror(errno));
	    continue;
	}
	/* 크기를 0으로 자른다 */ 
	if ((fd = open(argv[i], O_RDWR | O_TRUNC)) < 0) {
	    fprintf(stderr, "%s: open error: %s\n",
		    argv[i], strerror(errno));
	    continue;
	}
	close(fd);
	/* 시간들을 복원한다 */ 
	timebuf.actime	= statbuf.st_atime;
	timebuf.modtime	= statbuf.st_mtime;
	if (utime(argv[1], &timebuf) < 0) {
	    fprintf(stderr, "%s: utime error: %s\n",
		    argv[i], strerror(errno));
	    continue;
	}
    }
 
    return 0;
}

[실행 ]

$ ls -l changemod times           크기와 최종 수정 시간 확인

     -rwxrwxr-x 1 sar   15019   Nov  18  18:53  changemod

     -rwxrwxr-x 1 sar   16172   Nov  19  20:05  times

$ ls -lu changemod times           최종 접근 시간 확인

     -rwxrwxr-x 1 sar   15019   Nov  18  18:53  changemod

     -rwxrwxr-x 1 sar   16172   Nov  19  20:05  times

 

$ date                            print today's date

     Thu Jan 22 06:55:17 EST 2004

 

$ ./zap changemod times         예제 실행

$ ls -l changemod times           and check the results

     -rwxrwxr-x 1 sar        0  Nov  18  18:53  changemod

     -rwxrwxr-x 1 sar        0  Nov  19  20:05  times

$ ls -lu changemod times          최종 접근 시간 확인

     -rwxrwxr-x 1 sar        0  Nov  18  18:53  changemod

     -rwxrwxr-x 1 sar        0  Nov  19  20:05  times

$ ls -lc changemod times          상태 변경 시간을 확인

     -rwxrwxr-x 1 sar        0  Jan  22  06:55  changemod

     -rwxrwxr-x 1 sar        0  Jan  22  06:55  times

최종 수정 시간과 최종 접근 시간이 변경되지 않았다.

그러나 상태 변경 시간은 프로그램을 실행한 시간으로 바뀌었다.

Posted by devanix
2011. 10. 23. 16:29

각 파일마다 세 개의 시간 필드들이 커널에 의해 관리 된다.

 

[각 파일에 연관된 세 가지 시간 값들]

Field

Description

Example

ls(1) option

st_atime

last-access time of file data

read, exec

-u

st_mtime

last-modification time of file data

write, truncate

default

st_ctime

last-change time of i-node status

chmod, chown

-c

 

@ 파일수정시간과 상태 변경 시간의 차이를 주의:

• 파일 수정 시간(st_mtime) : 파일의 내용이 마지막으로 수정된 시간.

• 상태 변경 시간(st_ctime) : 파일의 i노드가 마지막으로 수정된 시간.

i노드의 모든 정보는 파일의 실제 내용과는 개별적으로 저장되기 때문에,

파일 수정 시간뿐만 아니라 상태 변경 시간(changed-status time)도 따로

유지할 필요가 있다. (내용이 변경된 파일 또는 i노드가 수정된 파일들만 따로 보관할 때 유용)

 

[여러 함수들의 파일 접근 시간, 수정 시간, 상태 변경 시간 갱신 여부]

Function

참조된 파일 or

디렉터리

참조된 파일 or

디렉터리의

부모 디렉터리

Note

a

m

c

a

m

c

chmod, fchmod

   

     

  

chown, fchown

   

     

  

creat

 

O_CREAT new file

creat

 

     

O_TRUNC existing file

exec

         

  

lchown

   

     

  

link

   

 

둘째 인수의 부모

mkdir

 

  

mkfifo

 

  

open

 

O_CREAT new file

open

 

     

O_TRUNC existing file

pipe

     

  

read

         

  

remove

   

 

파일 제거 = unlink

remove

       

디렉토리 제거 = rmdir

rename

   

 

for both arguments

rmdir

       

  

truncate, ftruncate

 

     

  

unlink

   

 

  

utime

     

  

write

 

     

  

touch(1)

 

새로운 파일 생성

touch(1)

     

기존 파일 업데이트

※ 디렉터리에 연관된 그 부모 디렉터리에 연관된 세 시간 값들까지 나와 있는 것은

디렉터리 항목들을 추가, 삭제, 수정하면 그 디렉터리에 연관된 세 시간 값들이 변할 수 있다.

디렉터리라는 것은 단지 디렉터리 항목(파일이름과 해당 i노드 번호)들을 담은 파일 뿐이다.

 

Posted by devanix