API와 에러 메시지

본 장에서는 실제 애플리케이션 개발을 위한 API 사용법과 에러 메시지에 대해서 소개한다.

1. API

다음은 RCA API 목록이다.

API 설명

tpsetfd

소켓 FD를 UCS 프로세스의 스케줄러에 등록하는 함수이다.

tpclrfd

UCS 프로세스 내부의 fdset의 소켓 FD를 off시키는 데 사용되는 함수이다.

tpissetfd

UCS 서버 프로세스에서 소켓 FD로 데이터가 도착했는지를 검사하는 함수이다.

tpschedule

UCS 서버 프로세스에서 데이터의 도착을 기다리는 함수이다.

tpuschedule

UCS 서버 프로세스에서 데이터의 도착을 입력한 시간 동안 기다리는 함수이다.

tpremoteconnect

리모트와 TCP/IP로 연결하는 함수로, 특정 시간 동안 연결을 시도한다.

tpgetrcahseqno

tpgetsvrseqno API와 동일하게 RCAH 프로세스 번호를 반환하는 함수이다.

tpgetrcainfo

RCAH의 스레드 정보를 조회하는 함수이다.

1.1. tpsetfd

소켓 fd를 UCS 프로세스의 외부 소켓 스케줄러에 등록하는 함수로 UCS 방식 프로세스를 사용한 소켓 fd를 켤 때 사용된다. UCS 스케줄러는 TMM, CLH 뿐만 아니라 해당 소켓 fd에 도착한 메시지도 같이 검사한다. 사용자가 지정한 소켓에 메시지가 도착했을 경우 tpschedule()은 별도의 처리없이 정상 결과(UCS_USER_MSG)를 반환하며 어떤 소켓에 메시지가 도착했는지를 알기 위해서는 아래에 설명된 tpisetfd()를 사용해야 한다.

  • 프로토타입

    #include <ucs.h>
    int  tpsetfd (int  fd)
  • 파라미터

    파라미터 설명

    fd

    등록할 소켓 fd를 설정한다.

  • 반환값

    반환값 설명

    1

    함수 호출에 성공한 경우이다.

    -1

    함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.

  • 오류

    tpsetfd()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드 설명

    [TPESYSTEM]

    Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.

    [TPEOS]

    운영 시스템에 에러가 발생하였다.

  • 예제

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <usrinc/ucs.h>
    ...
    #define SERV_ADDR “168.126.185.129”
    #define SERV_PORT 1500
    
    int fd_read(int, char *, int);
    extern int errno;
    
    int usermain(int argc, char *argv[])
    {
        ...
        int listen_fd, n, newfd;
        struct sockaddr_in my_addr, child_addr;
        socklen_t child_len;
        buf = tpalloc(“STRING”, NULL, 0);
        if (buf == NULL){
            error processing
        }
    
        memset((void *)&my_addr, NULL, sizeof(my_addr));
        memset((void *)&child_addr, NULL, sizeof(child_addr));
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_fd == -1){
            error processing
        }
    
        my_addr.sin_family = AF_INET;
        inaddr = inet_addr(SERV_ADDR);
        my_addr.sin_port = htons((unsigned short)SERV_PORT);
    
        if (inaddr != -1){
            memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));
        }
        ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
        if (ret == -1){
            error processing
        }
        ret = listen(listen_fd, 5);
        if (ret == -1){
            error processing
        }
    
        ret = tpsetfd(listen_fd);
        if (ret == -1){
            error processing
        }
        ...
    
        while(1) {
            n = tpschedule(10);
            ...
            if (n == UCS_USER_MSG){
                if (tpissetfd(listen_fd)) {
                    child_len = sizeof(child_addr);
                    newfd = accept(listen_fd, &child_addr, &child_len);
                    if (newfd == -1){
                        error processing
                    }
    
                ret = tpsetfd(newfd);
                if (ret == -1){
                    error processing
                }
            }
    
            if (tpissetfd(newfd)){
                /* 소켓으로부터 버퍼를 읽는다 */
                fd_read(newfd, buf, 1024);
                ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf,
                               (long *)&rlen, TPNOFLAGS);
                if (ret == -1){
                    error processing
                }
                ...
                tpclrfd(newfd);
                close(newfd);
            }
            ...
        }
        return 1;
    }
  • 관련 함수

    tpclrfd(), tpissetfd()

1.2. tpclrfd

UCS 방식 프로세스 내부의 fdset의 소켓 fd를 off시키는 데 사용되는 함수로, UCS 방식 서버 프로세스의 외부 소켓을 스케줄링하는 경우에 사용한다.

  • 프로토타입

    #include <ucs.h>
    int  tpclrfd (int fd)
  • 파라미터

    파라미터 설명

    fd

    off할 내부 fdset의 소켓이다.

  • 반환값

    반환값 설명

    1

    함수 호출에 성공한 경우이다.

    -1

    함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.

  • 오류

    tpclrfd()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드 설명

    [TPESYSTEM]

    Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.

    [TPEOS]

    운영 시스템에 에러가 발생하였다.

  • 예제

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <usrinc/ucs.h>
    ….
    #define SERV_ADDR “168.126.185.129”
    #define SERV_PORT 1500
    
    int fd_read(int, char *, int);
    extern int errno;
    
    int usermain(int argc, char *argv[])
    {
        ...
        int listen_fd, n, newfd;
        struct sockaddr_in my_addr, child_addr;
        socklen_t child_len;
        buf = tpalloc(“STRING”, NULL, 0);
        if (buf == NULL){ error processing }
    
        memset((void *)&my_addr, NULL, sizeof(my_addr));
        memset((void *)&child_addr, NULL, sizeof(child_addr));
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_fd == -1){ error processing }
        my_addr.sin_family = AF_INET;
        inaddr = inet_addr(SERV_ADDR);
        my_addr.sin_port = htons((unsigned short)SERV_PORT);
        if (inaddr != -1){
            memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));
        }
    
        ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
        if (ret == -1){ error processing }
        ret = listen(listen_fd, 5);
        if (ret == -1){ error processing }
    
        tpsetfd(listen_fd);
        ...
        while(1) {
            n = tpschedule(10);
            ...
            if (n == UCS_USER_MSG){
            if (tpissetfd(listen_fd)) {
                child_len = sizeof(child_addr);
                newfd = accept(listen_fd, &child_addr, &child_len);
                if (newfd == -1){ error processing }
                tpsetfd(newfd);
            }
    
            if (tpissetfd(newfd)){
                /* 소켓으로부터 버퍼를 읽는다 */
                fd_read(newfd, buf, 1024);
                ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf,
                             (long *)&rlen, TPNOFLAGS);
                if (ret == -1){ error processing }
                    ...
                ret = tpclrfd(newfd);
                if (ret == -1){ error processing }
                close(newfd);
            }
            ...
       }
       return 1;
    }
  • 관련 함수

    tpissetfd()

1.3. tpissetfd

서버에서 UCS 프로세스에서 소켓 FD로 데이터가 도착했는지를 검사하는 함수로, UCS 방식 서버 프로세스의 외부 소켓을 스케줄링하는 데 사용한다.

  • 프로토타입

    #include <ucs.h>
    int  tpissetfd (int fd)
  • 파라미터

    파라미터 설명

    fd

    테스트할 fdset 내부의 FD를 설정한다.

  • 반환값

    반환값 설명

    양수

    메시지가 도착했을 경우이다.

    0

    메시지가 도착하지 않은 경우이다.

    -1

    함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.

  • 오류

    tpissetfd()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드 설명

    [TPESYSTEM]

    Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.

    [TPEOS]

    운영 시스템에 에러가 발생하였다.

  • 예제

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <usrinc/ucs.h>
    ...
    
    #define SERV_ADDR “168.126.185.129”
    #define SERV_PORT 1500
    
    int fd_read(int, char *, int);
    extern int errno;
    
    int usermain(int argc, char *argv[])
    {
        ...
        int listen_fd, n, newfd;
        struct sockaddr_in my_addr, child_addr;
        socklen_t child_len;
    
        buf = tpalloc(“STRING”, NULL, 0);
        if (buf == NULL){ error processing }
    
        memset((void *)&my_addr, NULL, sizeof(my_addr));
        memset((void *)&child_addr, NULL, sizeof(child_addr));
    
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_fd == -1){ error processing }
    
        my_addr.sin_family = AF_INET;
        inaddr = inet_addr(SERV_ADDR);
        my_addr.sin_port = htons((unsigned short)SERV_PORT);
        if (inaddr != -1)
            memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));
    
            ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
            if (ret == -1){ error processing }
            ret = listen(listen_fd, 5);
            if (ret == -1){ error processing }
    
            tpsetfd(listen_fd);
            ...
            while(1) {
                n = tpschedule(10);
                ...
                if (n == UCS_USER_MSG){
                    if (tpissetfd(listen_fd)) {
                        child_len = sizeof(child_addr);
                        newfd = accept(listen_fd, &child_addr, &child_len);
                        if (newfd == -1){ error processing }
                        tpsetfd(newfd);
                }
                if (tpissetfd(newfd)){
                    /* 소켓으로부터 버퍼를 읽는다 */
                    fd_read(newfd, buf, 1024);
                    ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf,
                                  (long *)&rlen, TPNOFLAGS);
                    if (ret == -1){ error processing }
                    ...
                    tpclrfd(newfd);
                    close(newfd);
                }
            ...
            }
        }
        return 1;
    }
  • 관련함수

    tpissetfd(), tpsetfd()

1.4. tpschedule

UCS 형태의 서버 프로세스에서만 사용 가능한 함수로 UCS 서버 프로세스에서 데이터의 도착을 기다린다. 최대 타임아웃 시간 동안 sleep하다가 그 안에 데이터가 도착하면 즉시 반환한다.

tpschedule() 함수는 데이터가 도착했을 때 해당되는 서비스가 자동적으로 수행되고 난 후에 반환된다. 그러므로 데이터가 도착한 후에 사용자가 임의로 서비스를 수행하면 안 된다.

서비스는 무조건 시스템에 의해서 항상 수행되므로 UCS 형태의 서비스 프로그램이라도 이점을 주의해야 한다.

  • 프로토타입

    #include <ucs.h>
    int  tpschedule(int timeout)
  • 파라미터

    파라미터 설명

    timeout

    기다리고자 하는 시간을 초 단위로 입력해야 한다.

    • -1 : 데이터가 도착했는지 체크만 한 후 즉시 반환한다.

    • 0 : 데이터가 도착할 때까지 무한 대기한다.

  • 반환값

    반환값 설명

    양의 정수

    함수가 수행에 성공해서 데이터가 도착한 경우이다.

    -1

    타임아웃 시간까지 데이터가 도착하지 않은 경우 또는 함수가 수행에 실패해서 에러가 발생한 경우이다. 타임아웃 시간까지 데이터가 도착하지 않으면 -1을 반환하고, tperrno에13번(TPETIME)이 설정된다. 그 외의 경우 tperrno에 에러 코드가 설정된다.

  • 오류

    tpschedule()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드 설명

    [TPESYSTEM]

    Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.

    [TPEOS]

    운영 시스템에 에러가 발생하였다.

    [TPETIME]

    타임아웃 시간까지 데이터가 도착하지 않았다.

    [TPEPROTO]

    함수가 부적절한 상황에서 호출되었을 경우이다. 예를 들어 서비스 내에서 호출하는 경우 발생한다.

  • 예제

    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include <usrinc/ucs.h>
    int usermain(int argc, char *argv[])
    {
        ...
        while(1)
        {
            ...
            tpschedule(3);
            ret = tpcall(“SERVICE”, (char *)buf, strlen(buf), (char **)&buf,
                          (long *)&rlen, TPNOFLAGS);
            if (ret == -1) { error processing}
            ...
        }
    }
  • 관련 함수

    tpsleep(), tp_sleep(), tp_usleep()

1.5. tpuschedule

UCS 서버 프로세스에서 데이터의 도착을 microsecond 단위로 입력한 시간동안 기다리는 함수이다. tpuschedule()은 UCS 형태의 서버 프로세스에서만 사용 가능한 함수로, 최대 타임아웃(timeout) 시간동안 대기하다가 정해진 시간 안에 데이터가 도착하면 즉시 반환한다.

  • 프로토타입

    #include <ucs.h>
    int tpuschedule (int timeout)
  • 파라미터

    파라미터 설명

    timeout

    대기할 시간을 시간을 microsecond 단위로 입력해야 한다.

    • –1 : 데이터가 도착했는지 체크만 하고 즉시 종료한다.

    • 0 : 데이터가 도착할 때까지 대기한다.

  • 반환값

    반환값 설명

    0

    타임아웃 시간까지 데이터가 도착하지 않는 경우이다.

    양의 정수

    타임아웃 시간까지 데이터가 도착한 경우이다.

    -1

    함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.

  • 오류

    tpuschedule()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드 설명

    [TPESYSTEM]

    Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.

    [TPEOS]

    운영 시스템에 에러가 발생하였다.

  • 예제

    ...
    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include <usrinc/ucs.h>
    
    int usermain(int argc, char *argv[])
    {
        ...
        while(1)
        {
            ...
            tpuschedule(3000000);
            ret = tpcall(“SERVICE”, (char *)buf, strlen(buf), (char **)&buf,
                          (long *)&rlen, TPNOFLAGS);
            if (ret == -1) { error processing }
            ...
         }
    }
  • 관련 함수

    tpschedule()

1.6. tpremoteconnect

리모트와 TCP로 연결하는 함수로서 sec가 주어지면 해당 시간동안 연결을 시도한다. 시간 초과의 경우 연결 오류가 발생한다.

  • 프로토타입

    #include <ucs.h>
    int tpremoteconnect(char *host, int portno, int sec)
  • 반환값

    반환값 설명

    0

    소켓 번호이다.

    -1

    함수 호출에 실패한 경우이다. tperrno에 에러 상황에 해당되는 값이 설정된다.

1.7. tpgetrcahseqno

Tmax API인 tpgetsvrseqno API와 동일하게 RCAH 프로세스 번호를 반환하는 함수이다. 이 번호는 RCAL에서 순차적으로 부여한 번호이다.

  • 프로토타입

    #include <ucs.h>
    int tpgetrcahseqno()
  • 반환값

    반환값 설명

    0

    RCAH 프로세스 순서 번호이다.

1.8. tpgetrcainfo

RCAH의 스레드 정보를 알려주는 함수이다.

  • 프로토타입

    #include <ucs.h>
    void * tpgetrcainfo()
  • 반환값

    RCA header 파일의 RCAINFO에 대한 포인터를 반환한다.

2. 에러 메시지

RCA는 기본적으로 Tmax 클라이언트로 동작하기 때문에 Tmax 시스템에서 제공하는 함수를 사용하는 경우에 발생하는 에러 메시지는 Tmax Application Develoment Guide를 참고하며 Tmax 시스템 전체적으로 공통적인 에러 메시지에 대해서는 중복되는 관계로 언급하지 않는다.

본 장에서는 RCA 모듈에서만 나타나는 에러 메시지에 대해서 다룬다. 다음에서 찾을 수 없는 메시지는 Tmax Error Message Reference를 참고한다.

SVR0014 exec error: /user/tmax/appbin/rcah [No such file or directory]

구분

FATAL

설명

설정된 RCA_DIR에서 RCAH를 발견하지 못한 경우이다.

대응 방법

설정된 RCA_DIR에 RCAH 실행 파일이 존재하는지 확인한다.

SVR0019: no available thread slot

구분

ERROR

설명

새로운 스레드를 등록하는 중에 에러가 발생한 경우이다. 기동하려는 스레드가 RCA 기동할 때 설정된 RCA_NTHR 개수를 넘는 경우에 발생한다.

SVR0020: thread create error

구분

ERROR

설명

스레드 생성에 실패한 경우이다.

대응 방법

시스템 자원을 확인한다.

SVR0100: RCA_PORT env is not set: set to default port (8899)

구분

ERROR

설명

RCA_PORT가 지정되지 않아 기본값을 사용한 경우이다.

대응 방법

기본값을 사용하는 경우에는 상관없지만 원하는 포트로 RCA를 기동시키기를 원하는 경우에는 RCA_PORT를 지정한다.

SVR2016: register to RCAL errror

구분

FATAL

설명

RCAL에 등록 실패한 경우이다.

대응 방법

RCAL이 기동되어 있는지 확인한다.

SVR3001: rcah is not ready yet

구분

WARN

설명

RCAH가 기동되어 있지 않은 상태에서 클라이언트가 접속한 경우이다.

대응 방법

시스템이 부팅 중인 상태에서 서비스 요청이 발생하는 경우이거나 RCA가 기동중인 상태에서 서비스 요청이 발생하는 것으로 볼 수 있으므로 시스템이 완전히 기동된 후 혹은 RCA가 정상적으로 기동된 후에 서비스 요청이 발생할 수 있도록 조치한다.

SVR3003: rcah allocation error

구분

ERROR

설명

rcah가 기동되어 있지 않은 상태에서 클라이언트의 요청이 도달한 경우이다.

대응 방법

1) rcah가 모두 down된 경우에는 rcah의 클라이언트 모듈에 대한 타당성을 점검한다.

2) “send to rcah error”와 관련이 있을 수 있으므로 최종적으로 시스템 환경을 점검한다.

SVR3007: send to rcah error

구분

FATAL

설명

RCAL이 RCAH쪽으로 fd를 전달하다가 에러 발생가 발생한 경우이다.

대응 방법

기본적인 시스템 함수 사용에서 에러가 발생했으므로 시스템 환경을 점검한다.

SVR5103: unable to start RCAH

구분

FATAL

설명

RCAH를 기동시키는 과정에서 에러가 발생한 경우이다.

대응 방법

1) 설정된 RCA_DIR에 RCAH 실행 파일이 존재하는지 확인한다.

2) RCAH 클라이언트 모듈 부분 thrinit() 루틴에 대한 타당성을 확인한다.

SVR5109: rcah shutdown

구분

ERROR

설명

RCAH가 종료되는 경우이다.

대응 방법

RCAL이 강제 종료되는 경우, RCAH도 종료하게 되는데 이 경우에 발생하는 에러로서 RCAL이 종료되는 원인을 파악한다.