상세 컨텐츠

본문 제목

UNIX - IPC facilities, Permission Structure, Identifiers and Keys, ftok system call, IPC get / ctl operations

개발/UNIX

by 2021. 11. 14. 09:21

본문

반응형

Advanced IPC facilities

IPC는 프로세스간 정보교환의 매커니즘을 제공한다. 

 

IPC는 다음과 같은 세 가지로 이루어져 있다.

 

message queues는 pipe와 비슷한 개념이다.

semaphores는 변수를 공유할 때 프로세스 간 동기(synchronization)를 맞추는 역할을 한다. 

shared memory는 프로세스간 변수 즉 메모리를 공유할 수 있도록 도와준다. 

 

 

message queue와 semaphore는 file을 사용하는 방법과 유사하다.

file message queue semaphore shared memory
file name : “filename” key : key_t key : key_t key : key_t
file descriptor : int identifier : int identifier : int identifier : int
open() msqget() semget() shmget()
fcntl() msqctl() semctl() shmctl()
struct stat
(i-node 구조)
struct msqid_ds struct semid_ds struct shmid_ds
read() msqrcv()
message queue receive
- -
write() msqsnd()
message queue send
- -
- - semop() -
- - - shmat()
(shared memory attach)
- - - shmdt()
(shared memory detach)

위 표에서와 같이 file에서 사용하는 각각의 요소들에 대응하는 것들이 있다. 

 

 

Permission Structure

file의 i-node의 경우 struct stat안에 st_mode로 permission을 관리했듯,

msq(message queue), sem(semaphore), shm(shared memory)에 각각 해당하는 msqid_ds, semid_ds, shmid_ds에 모두 ipc_perm이 존재한다. 

struct ipc_perm {  
	uid_t  uid;  /* owner's effective user id */
	gid_t  gid;  /* owner's effective group id */
	uid_t  cuid; /* creator's effective user id */
	gid_t  cgid; /* creator's effective group id */
	mode_t mode; /* access modes */
	…
};  /* a field of xxx_ds */

ipc_perm에는 st_mode 같은 역할의 mode가 있어 mode를 통해 permission을 관리한다. 

 

IPC에는 이와 같이 read, write만이 필요하고 execute bit는 사용하지 않는다. 

 

  • uid, gid의 경우 owner의 id이고, cuid, cgid는 creator의 id이다.
    creator는 생성한 프로세스의 euid이고, owner의 경우 creator와 같지만, owner를 변경하는 경우도 있다.
  • IPC facility를 생성할 때 umask는 영향을 미치지 않는다. 
  • uid, gid, mode는 msgctl, semctl, shmctl 을 호출함으로써 변경할 수 있다. (creator 또는 superuser만 가능)

 

Identifiers and Keys

IPC에서는 file의 filename에 해당되는 것이 key이다. 

key

IPC object에서 External name으로 사용된다.

IPC structure가 msgget, semget, shmget등으로 생성될 때, key가 특정되어야 한다. 

key는 <sys/types.h>에 key_t(long integer)라는 data type으로 정의되어 있다. 

 

Identifier

IPC object에서 Internal name으로 된다. 

non-negative integer이며, get 연산들 (msgget, semget, shmget)의 return값이다. 

file descriptor처럼 행동하지만, file descriptor와는 달리 IPC facility identifier가 unique하다.

즉 다른 프로세스에서 같은 IPC object에 대해 같은 값을 사용한다. 

 

The ftok(2) system call

#include <sys/ipc.h>
key_t ftok(const char *path, int id);

// Returns: key if OK, (key_t)-1 on error

filename은 같을 수 있지만, absloute pathname은 unique하다.

하지만 Identifier의 key는 직접설정하므로 unique하지 않을 수 있다. 그래서 unique한 key를 생성하지 위한 역할을 하는 것이 ftok이다. 

 path와 자신만의 id를 통해서 key_t를 생성하여 반환한다(path와 id가 모두 같은 경우에는 같은 키가 생성). path는 존재하는 file, id는 lower 8 bit 즉 0~255의 수를 이용한다. 

 

if ((thekey = ftok("tmp/trouble.c", 1)) == (key_t)-1)) 	
perror("Failed to derive key from /tmp/trouble.c");

위와 같이 사용하여 path와 id의 조합인 key로 unique한 IPC object를 식별하게 한다. 

path가 존재하지 않거나 호출하는 process에 접근할 수 없으면 ftok은 -1를 return한다. 

 

 

IPC get operations

#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
int msgget(key_t key, int permflags);
int semget(key_t key, int nsems, int permflags); 
int shmget(key_t key, size_t size, int permflags); 

// Returns: identifier if OK, -1 on error

get은 key를 매개변수로 하여 identifies를 반환한다. permflags를 통해 permission을 준다. 

semaphore의 경우 nsems는 semaphore set에 들어갈 semaphore의 개수이다. 

sharedmemory의 size는 share하는 memory의 크기를 의미한다. 

 

get함수의 key값을 주는 방법은 다음과 같이 3가지가 있다.

  • IPC_PRIVATE 상수, 즉 key 선택 시스템을 이용한다. (셋 중 100% unique)
  • key값을 직접 지정한다. 
  • ftok을 통해 key값을 생성한다. 

 

permflags의 경우 IPC전용으로 옵션들이 다음과 같은 방식으로 있다.

  • IPC_CREAT → O_CREAT
  • IPC_EXCL → O_EXCL

CREAT는 file이 없으면 get, EXCL은 file이 있다면 error 등 기존 옵션들과 내용은 일치한다. 

 

 

header <sys/msg.h>, <sys/sem.h>, <sys/shm.h> 에 포함된 IPC permission은 다음과 같다.

Numeric
(octal)
Symbolic values Description
Message
queue
Semaphore Shared
memory
0400
0200
MSG_R
MSG_W
SEM_R
SEM_A
SHM_R
SHM_W
user-read
user-write (alter)
0040
0020
MSG_R >> 3
MSG_W >> 3
SEM_R >> 3
SEM_A >> 3
SHM_R >> 3
SHM_W >> 3
group-read
group-write (alter)
0004
0002
MSG_R >> 6
MSG_W >> 6
SEM_R >> 6
SEM_A
>> 6
SHM_R >> 6
SHM_W >> 6
other-read
other-write (alter)

semaphore의 _A는 alter의 A로 write와 의미상 같다. 

IPC의 permission에는 execute에 해당하는 permission은 없다.

 

 

IPC ctl operations

#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
int msgctl(int msqid, int command, struct msqid_ds *buf ); 
int semctl(int semid, int semnum, int command,…/*union semun arg*/);
int shmctl(int shmid, int command, struct shmid_ds *buf); 

// Returns: 0 if OK, -1 on error

ctl은 file의 fcntl 및 stat 명령어를 한 번에 하는 명령어이다. 

get을 통해 얻은 id를 매개변수로 하며, command 매개변수를 통해 작업할 명령어를 전달한다. 

 

command의 종류는 다음과 같다.

command description
IPC_STAT Return the referenced IPC resource status information. When specifying IPC_STAT, the ctl system call must pass a pointer to an allocated structure of the appropriate type to store the returned information

struct msgid_ds, semid_ds, shmid_ds와 같은 status info struct를 반환한다. 
IPC_SET Change the owner, group, or mode for the IPC resource. In addition, as with IPC_STAT, a pointer to a structure of the appropriate type (with the changed member information) must be passed 

IPC_STAT로 가져온 정보 중 일부를 변경할 수 있다. 
IPC_RMID Destroy the contents of the IPC resource and remove it from the system

id가 가리키는 IPC object를 remove 한다. 

 

 

Generating IPC indentifiers from IPC keys

ftok, IPC_PRIVATE, user-define의 세 방식으로 key를 지정하고, 

key를 매개변수로 get를 실행하여 id를 얻는다.

얻은 id를 통해 ctl, send, receive, attach 등 각종 명령어를 사용한다. 

 

 

Accessing IPC resources from the shell

SYNOPSIS 
ipcs [-qms][-a | -bcopt] 

ipcrm [-q msgid | -Q msgkey | -s semid | -S semkey |
-m shmid | -M shmkey] ....
                                     
// POSIX:XSI,Shell and Utilities

ipcs (ipc status) 명령어로 IPC에 대한 정보를 command line에서 확인할 수 있다.

ipcrm 명령어로 command line에서 IPC object를 삭제할 수 있다.

 

$ ipcs

------ Shared Memory Segments ------
key       shmid     owner     perms     bytes     nattch   status   
0x00000000 25198594  root      666       247264    3

------ Semaphore Arrays ------
key       semid     owner     perms     nsems     status
0x00000000 65537     root      666       4
0x00000000 98306     root      666       16          
0x00000000 131075    root      666       16
0x00000000 163844    root      666       16

------ Message Queues ------
key       msqid     owner     perms     used-bytes  messages  

$ ipcrm –s 65537
$ ipcrm -q 25198594

ipcs 명령어를 사용한 결과는 위와 같다. 옵션없이 실행하면 shared memory, semaphore, message queue의 각종 정보를 알 수 있다. 

ipcrm명령어를 통해 semaphore, message queue를 삭제하는 것을 확인할 수 있다. 

반응형

관련글 더보기