SYSCTL_ADD_OID(9)

명칭
sysctl_add_oid, sysctl_remove_oid - 런타임 sysctl 트리 조작

서식
<sys/sysctl.h> struct sysctl_oid * sysctl_add_oid(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, char *name, int kind, void *arg1, int arg2, int (*handler) (SYSCTL_HANDLER_ARGS), char *format, char *descr) int sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse) struct sysctl_oid_list * SYSCTL_CHILDREN(struct sysctl_oid *oidp) struct sysctl_oid_list * SYSCTL_STATIC_CHILDREN(OID_NAME) struct sysctl_oid * SYSCTL_ADD_OID(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, NAME, int kind, void *arg1, int arg2, int (*handler) (SYSCTL_HANDLER_ARGS), char *format, char *descr) struct sysctl_oid * SYSCTL_ADD_NODE(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, NAME, int access, int (*handler) (SYSCTL_HANDLER_ARGS), char *descr) struct sysctl_oid * SYSCTL_ADD_STRING(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, NAME, int access, char *arg, 0, char *descr) struct sysctl_oid * SYSCTL_ADD_INT(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, NAME, int access, int *arg, 0, char *descr) struct sysctl_oid * SYSCTL_ADD_UINT(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, NAME, int access, unsigned int *arg, 0, char *descr) struct sysctl_oid * SYSCTL_ADD_LONG(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, NAME, int access, long *arg, 0, char *descr) struct sysctl_oid * SYSCTL_ADD_ULONG(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, NAME, int access, unsigned long *arg, 0, char *descr) struct sysctl_oid * SYSCTL_ADD_OPAQUE(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, NAME, int access, void *arg, size_t *len, char *descr) struct sysctl_oid * SYSCTL_ADD_STRUCT(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, NAME, int access, struct TYPE *arg, TYPE, char *descr) struct sysctl_oid * SYSCTL_ADD_PROC(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, NAME, int access, 0, 0, int (*handler) (SYSCTL_HANDLER_ARGS), char *format, char *descr)

해설
이러한 함수 및 매크로는 sysctl oid 의 런타임 (예를 들면 모듈의 존재 기간)에서의 작성과 삭제를 위한 인터페이스를 제공합니다. 링커 세트 (자세한 것은 <sys/linker_set.h> 및 src/sys/kern/kern_sysctl.c (을)를 참조) 에 근거하는 대신 방법은, 각각의 모듈의 로드시 및 언로드시의 작성과 삭제만을 가능하게 합니다.

형 CTLTYPE_NODE 의 동적인 oid 는 재이용 가능하기 때문에, 복수의 코드 섹션이, oid 를 작성 및 삭제하는 것이 가능합니다. 실제로는, 참조 카운트에 근거해, 그 할당 및 해방을 합니다. 그 결과적으로, 2 개(살) 이상의 코드 섹션이, 부분적과 겹쳐져, 양자가 사용할 수 있는 트리를 작성 가능하게 합니다. 겹치는 잎의 작성이나, 동일한 이름과 부모를 가지는 다른 형태의 아이의 작성은, 불가능합니다.

새롭게 작성된 oid 는 부모의 노드에 접속됩니다. 이것들 모든 함수 및 매크로 ((sysctl_remove_oid) (은)는 예외)에 두어, 필수 파라미터의 1 개 parent (은)는, 아이의 친리스트의 선두를 가리킵니다.

대부분의 톱 레벨의 카테고리는 정적으로 작성됩니다. 기존의 정적인 oid 에 접속할 경우에, 이 포인터는 SYSCTL_STATIC_CHILDREN() 매크로에 의해 취득하는 것이 가능해, 그 OID_NAME 인수는 CTLTYPE_NODE 형태의 친 oid 의 이름 (즉, sysctl(8) 에 의해 표시되는 이름에, 언더스코어를 전치 해, 모든 닷을 안다스코아로 옮겨놓은 이름)입니다.

기존의 동적인 oid 에 접속할 경우에, 이 포인터는 SYSCTL_CHILDREN() 매크로에 의해 취득하는 것이 가능해, 그 oidp 인수는 CTLTYPE_NODE 형태의 친 oid 를 가리킵니다.

sysctl_add_oid() 함수는 모든 형태의 생의 oid 를 작성합니다. oid 의 작성이 성공했을 경우에는, 이 함수는 그 oid 에의 포인터를 돌려줍니다. 그렇지 않은 경우에는, NULL (을)를 돌려줍니다. sysctl_add_oid() (을)를 위한 인수의 상당수는 매크로와 공통입니다. 인수는 이하대로입니다.

ctx 옵션의 sysctl 문맥에의 포인터, 또는 NULL 입니다. 자세한 것은 sysctl_ctx_init(9) (을)를 참조해 주세요. 특별한 작성 및 삭제의 순차 순서가 요구되므로 없으면, 작성하는 동적인 oid 를 조직 하기 위해서 문맥을 사용하는 것을, 프로그래머는 강하게 권고되고 있습니다. ctx 하지만 NULL (이)가 아닌 경우에는, 새롭게 작성되는 oid 는 최초의 엔트리로서 이 문맥에 추가됩니다.

parent
    아이의 친리스트의 선두이다 struct sysctl_oid_list 에의 포인터입니다.

number
    이 oid 에 할당할 수 있는 oid 번호입니다. 대부분 모든 경우, 이것은 할당시에 다음의 이용 가능한 oid 번호가 된다 OID_AUTO (으)로 설정되어야 합니다.

name
    이 oid 의 이름입니다. 새롭게 작성된 oid 는 이름의 카피를 포함하고 있습니다.

kind
    oid 의 종류로, <sys/sysctl.h> 헤더 파일 중(안)에서 정의되는 형태와 액세스치의 비트 마스크로서 명시됩니다. 동적으로 작성된 oid 는 항상 CTLTYPE_DYN 플래그가 설정됩니다. 액세스 플래그는 이 oid 가 읽어내 전용이나 읽고 쓰기 가능한가, 및 모든 유저에 의해 또는 슈퍼 유저에 의해서만 수정 가능한가를 명시합니다.

arg1
    oid 가 참조해야 할 모든 데이터에의 포인터, 또는 NULL 입니다.

arg2
    arg1 의 크기, 또는 arg1 하지만 NULL 이면 0 입니다.

handler
    이 oid 에의 읽고 쓰기 요구를 취급할 책임이 있는 함수에의 포인터입니다. 노드, 정수, 캐릭터 라인, 및 불투명한 오브젝트의 조작을 서포트한다 몇개의 표준 핸들러가 존재하고 있습니다. SYSCTL_ADD_PROC() 매크로를 사용해 새로운 핸들러를 정의하는 일도 가능합니다.

format
    oid 의 포맷을 기호적으로 명시하는 캐릭터 라인에의 포인터입니다. 이 포맷은, 표시 목적을 위한 적절한 데이터 포맷을 적용하기 위해서 sysctl(8) 에 의해 힌트로서 사용됩니다. 현재 사용되고 있는 포맷명은 이하대로입니다. “N” (은)는 노드, “A” 하 char * 형태, “I” 하 int 형태, “IU” 하 unsigned int 형태, “L” 하 long 형태, “LU” 하 unsigned long 형태, 및 “S, TYPE” 하 struct TYPE 구조체입니다.

descr
    이 oid 의 해설 텍스트에의 포인터입니다.

sysctl_remove_oid() 함수는 동적으로 작성된 oid 를 트리로부터 삭제해, 옵션으로 그 리소스를 해방합니다. 이것은 이하의 인수를 취합니다.

oidp
    삭제되어야 한다 동적인 oid 에의 포인터입니다. oid 가 동적이지 않은, 또는 포인터가 NULL 의 경우에는, 이 함수는 EINVAL (을)를 돌려줍니다.

del 0 이 아닌 경우에는, oid 의 참조 카운트가 0 이 되었을 때에, sysctl_remove_oid() (은)는 oid 의 리소스를 해방하려고 합니다. 그렇지만 del 하지만 0 으로 설정되어 있는 경우에는, 이 routine는 oid 의 리소스의 해방을 하지 않고 트리로부터 oid 의 등록 말소만을 행합니다. 이 행동은, 호출측이 다음에 (혹시 부분적으로 실패한다) 다수의 oid 의 삭제의 롤백(rollback)를 예기 하고 있을 때에, 유용합니다.

recurse
    0 이 아닌 경우에는, 그 노드와 그 아이를 삭제하려고 합니다. recurse 하지만 0 으로 설정되어 있는 경우에는, 모든 아이를 포함한 노드의 삭제의 시도는 ENOTEMPTY 에러를 발생시킵니다. 경고: 재귀적인 삭제는 대단한 주위를 기울여 사용하는 것! 통상, 문맥이 사용되고 있으면, 필요하게 되어야 하는 것이 아닙니다. 문맥은 트리의 이용자 사이의 의존성의 추적에 주의하고 있습니다. 그렇지만, 있는 극단적인 경우에는, 있는 다른 리소스를 해방하기 위해서, 그것이 어떻게 작성된 것이든, 서브 트리의 일부를 삭제하는 것이 필요하게 되는 일이 있습니다. 그렇지만, 이것은, 다른 코드 섹션이 삭제된 서브 트리를 계속 사용하는 경우에, 시스템의 panic(9) (을)를 일으키는 일이 있는 것을 알고 있어 주세요.

재차 말합니다만, 대부분(거의)의 경우, 작성된 oid 를 잃지 않게 하기 위한(해), 및 다음에 정연하게 한 유파의 의식으로 그것들을 삭제하기 위해(때문에), sysctl_ctx_init(9) 그리고 해설되고 있도록(듯이), 프로그래머는 문맥을 사용해야 합니다.

주어진 형태의 oid 의 작성을 돕는 정의 끝난 매크로 세트가 있습니다.
그것들을 이하에 나타냅니다.

SYSCTL_ADD_OID()
    (은)는 생의 oid 를 작성합니다. 이 매크로는 기능적으로는 sysctl_add_oid() 함수로 동등합니다.

SYSCTL_ADD_NODE()
    (은)는 형태 CTLTYPE_NODE 의 oid 를 작성합니다. 이 oid 에 대해서, 아이의 oid 를 추가 가능합니다.

SYSCTL_ADD_STRING()
    (은)는 0 으로 종단 된 캐릭터 라인을 취급하는 oid 를 작성합니다.

SYSCTL_ADD_INT()
    하 int 변수를 취급하는 oid 를 작성합니다.

SYSCTL_ADD_UINT()
    하 unsigned int 변수를 취급하는 oid 를 작성합니다.

SYSCTL_ADD_LONG()
    하 long 변수를 취급하는 oid 를 작성합니다.

SYSCTL_ADD_ULONG()
    하 unsigned long 변수를 취급하는 oid 를 작성합니다.

SYSCTL_ADD_OPAQUE()
    하 size_t * 에의 포인터이다 len 인수에 의해 명시된 크기의 모든 불투명한 데이터의 덩어리를 취급하는 oid 를 작성합니다.

SYSCTL_ADD_STRUCT()
    하 struct TYPE 구조체를 취급하는 oid 를 작성합니다. format 인수는 sysctl(8) 유틸리티에의 적절한 힌트를 제공하기 위해서 “S, TYPE” (으)로 설정됩니다.

SYSCTL_ADD_PROC()
    (은)는 명시되었다 handler 핸들러 함수를 가지는 oid 를 작성합니다. 핸들러는 oid 에 대해서의 읽고 쓰기 요구를 취급할 책임을 가집니다. 커널 데이터가 간단하게 액세스 할 수 없는 경우, 또는 꺼내지기 전에 처리된다 필요가 있는 경우에, 이 oid 형은 특히 유용합니다.

사용예
이하는, 어떻게 새로운 톱 레벨의 카테고리를 작성하는지, 및 어떻게 기존의 정적인 노드에 다른 서브 트리를 걸까 (을)를 나타내는 사용예입니다. 이 사용예는 문맥을 사용하고 있지 않습니다. 이것은 모든 다음에 그것들을 해방한다고 한, 중간의 oid 의 지루한 관리를 결과적으로 생기게 합니다.

    #include <sys/sysctl.h>
     ...
    /* 새롭게 작성한 서브 트리에의 포인터는, 다음에 그것들을 해방하기 위해서
     * 보존해 둘 필요가 있습니다.
     */
    struct sysctl_oid *root1, *root2, *oidp;
    int a_int;
    char *string = "dynamic sysctl";
     ...
    root1 = SYSCTL_ADD_NODE( NULL, SYSCTL_STATIC_CHILDREN(/* tree top */),
    	OID_AUTO, newtree, CTFLAG_RW, 0, "new top level tree");
    oidp = SYSCTL_ADD_INT( NULL, SYSCTL_CHILDREN(root1),
    	OID_AUTO, newint, CTLFLAG_RW, &a_int, 0, "new int leaf");
     ...
    root2 = SYSCTL_ADD_NODE( NULL, SYSCTL_STATIC_CHILDREN(_debug),
    	OID_AUTO, newtree, CTFLAG_RW, 0, "new tree under debug");
    oidp = SYSCTL_ADD_STRING( NULL, SYSCTL_CHILDREN(root2),
    	OID_AUTO, newstring, CTLFLAG_R, string, 0, "new string leaf");

이 사용예는 이하의 서브 트리를 작성합니다.

    debug.newtree.newstring
    newtree.newint

더 이상 필요하지 않게 된 모든 oid 는 해방 되는 것이 당연한 것에 주의!

관련 항목
sysctl(8), sysctl_ctx_free(9), sysctl_ctx_init(9)

역사
이러한 함수는 FreeBSD 4.2 그리고 처음 등장했습니다.

저자
Andrzej Bialecki <abial@FreeBSD.org>

버그
많은 코드 섹션간에 노드를 공유하는 것은, 가끔 리소스를 잠그는 일이 있는 상호의존을 일으킵니다. 예를 들면, 모듈 B 에 의해 작성된 oid 에 대해, 모듈 A 가 서브 트리를 걸었을 경우에는, 모듈 B 는 그 oid 를 삭제할 수 없을 것입니다. 이러한 문제는 sysctl 문맥에 의해 적절히 취급됩니다.

트리상이 많은 조작은 링크 리스트를 횡단하는 것을 필요로 합니다. 이 이유이기 때문에, oid 의 작성과 삭제는 상대적으로 코스트가 듭니다.