system call을 이용해서 callback function을 등록하고 사용하려

강윤식의 이미지

커널에 callback 함수를 등록했다가 나중에 필요할 때 모두 수행을 하려고 합니다.

즉 커널에 함수 포인터 배열을 만들고, callback함수를 매개 변수로 받는 system call을 이용해 배열에 함수 포인터를 저장 합니다.

그리고, 나중에 조건이 되면 등록된 함수들을 일괄적으로 수행을 하려고 합니다.

전에 kernel-2.4.25에서는 잘 되던 것이 이번에 2.6.5-1 에서 수행을 하려고 하니 general protection fault 라고 에러를 내면서 수행이 되지를 않습니다.

일단 커널의 sys.c 에 다음과 같은 코드를 넣었고요.

#define MAX_AUTOFS_CALLBACKFC 20
typedef void (*autofscallbackfc)(char*, char*);
autofscallbackfc autofscallbackarray[MAX_AUTOFS_CALLBACKFC];
int autofsfcarrayindex = 0;

asmlinkage int sys_add_autofs_callback(autofscallbackfc func)
{
// the array has no more space
if (autofsfcarrayindex == 20) return 0;

autofscallbackarray[autofsfcarrayindex] = func;
autofsfcarrayindex++;
return autofsfcarrayindex;
}

asmlinkage int sys_run_autofs_callback(void)
{
int i = 0;
while(i < autofsfcarrayindex)
{
autofscallbackfc function = autofscallbackarray[i];
function("device name", "mount_point");
i++;
}

return i;
}

********************************************************************************

아래와 같은 프로그램을 하나 만들어서 실행을 하였습니다.

#include <linux/unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>

typedef int (*callback_func)(char*, char*);

_syscall1(int, add_autofs_callback, callback_func, cb_func1 );
_syscall0(int, run_autofs_callback);

int cb_func(char* device_name, char* mount_point)
{
printf(device_name);
printf("\n");
printf(mount_point);
return 0;
}

int main()
{
add_autofs_callback(cb_func);
run_autofs_callback();
return;
}

물론 시스템 콜에 대한 등록 등등은 다 제대로 하였고 커널 컴파일도 에러없이 잘 되었습니다.
제가 무었을 잘못하였는지 고수님들의 고견을 기다리겠습니다.

감사 합니다...

sjpark의 이미지

정확한 도움이 될거 같진 않지만 집히는 것이 있어서..

고수님들이 답변해 주시겠지만... 제 생각을 한번 적어 보겠습니다. :)

커널 레벨에서 수행되는 코드 세그먼트하고 사용자 레벨에서 수행되는 코드 세그먼트의 특권레벨이 맞지 않아서, GP를 내는것 같습니다.

앞서 말했지만 정확한건 아닙니다.

혹시 시스템콜로 등록한 사용자 레벨 함수(이하 등록함수로 지칭)에서 커널레벨에서만 수행되는 즉, 권한을 벗어나는 일을 하게 되나요?

등록함수에서 커널에서 동작하는 함수를 호출하게 되면 등록함수의 레벨과 커널내에 있는 함수의 레벨이 맞지 않아 GP를 낼 수 있다고 보거든요..

하지만, 2.4.5 버전에서 무리 없이 작동했다니... 맞는 것인지는 ...;;

또 한가지

이건 이 문제(GP)와 관계 없을듯 한데요..

수행중인 응용 프로그램이 커널에 특정함수를 등록한 후 종료하게 되면, 함수 포인터를 잃어 버리지 않나요? 제출하신 문제와는 관계 없어보이지만.. 혹시나 해서요...

또 만약 하나 이상의 동일 응용 프로그램이 수행되어 커널에 콜백함수를 각각의 응용이 등록하게 되면

아.. 여기까지 쓰고 나니 이것 참 재미있네요.

A 라는 응용 프로그램이 콜백함수 A1을 등록하였다면,
B 라는 응용 프로그램에서 Run_callback을 호출하게 되면 A가 등록한 함수 A1도 수행 되게 되는것인가요?

글을 읽고 정확한 답변이 떠오르진 않았지만 몇가지가 문득 생각나서 적어 보았습니다

ps. 뻘쭘...^^;

ezsimple의 이미지

강윤식 wrote:

int global = 0;

int cb_func(char* device_name, char* mount_point)
{

global++;
// printf(device_name);
// printf("\n");
// printf(mount_point);

return 0;
}

int main()
{

add_autofs_callback(cb_func);

printf("global = %d\n",global); // 0이 출력 됩니다.
run_autofs_callback();
printf("global = %d\n",global); // 1을 출력 합니다.
return;
}

printf 를 없애고서 수행해 보세요.
코드를 보면
실제 cb_func 수행은 커널레벨에서 수행이 되는데,
printf 함수는 유저레벨에서 수행하는 함수 입니다.

기능은 수행 하지만, 흠...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.