lkml.org 
[lkml]   [1999]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    Subject[question/comment/help] pseudo function-call from kernel to a user-process
    hi

    I want to have a pseudo-function-call initiated by the kernel in a
    system-call. The following code(source see below), a systemcall, do the
    following:

    1. a user-process register itself to the kernel. (dkm_csd_pid)
    2. in a system-call (eg. sys_execve) I send the signal SIGUSR2 to the
    process to initiate the communication.
    3. the process has a signal-handler for the signal.
    4. [pseudo-function call begins] the process calls dkmctl with
    DKM_MAP_REQ with a buffer, the kernel copies its argument via
    copy_to_user using the buffer to the process. down a global
    kernel-semaphore to protect this area.
    5. [in the pseudo-function-call] the process is still in the
    signal-handler and process an answer for the request.
    6. [pseudo-function-call returns] the process use the system-call dkmctl
    with DKM_MAP_RESP to return the return-value of the
    pseudo-function-call.
    7. up the global kernel-semaphore to allow other tasks the same.
    8. now the origin system-call goes on...
    ( while development, I use the cmd DKM_DOSIG to initiate the
    communication, in real life it's done in the real-syscall (execve...))

    OK. This works. My Questions:
    - can I do this in an other way ? Is there any functionality in the
    kernel to do somethin like this?
    - as you can see int the code, I tried to use a self-defined spinlock to
    protect the area, but that doesn't work, why? aren't spinlocks like
    semaphores or mutex'es?
    - are there any pitfalls ?

    Thanks in advance
    marcel

    -------------- code -----------------------------------
    MY SYSTEMCALL dkmctl(int cmd, void* arg, coid* resp):
    <snip>
    #define DKM_MAP_REQ 1
    #define DKM_CSD_REG 2
    #define DKM_CSD_DEREG 3
    #define DKM_DOSIG 4
    #define DKM_MAP_RESP 5

    pid_t dkm_csd_pid;
    /*spinlock_t dkm_map_lock = SPIN_LOCK_UNLOCKED;*/

    struct semaphore dkm_map_sema = MUTEX;
    dkm_csd_pid = -1;

    asmlinkage int sys_dkmctl(int cmd, void *arg, void *resp)
    {
    char* node_name;
    node_name = (char*) kmalloc(64, GFP_KERNEL);

    switch(cmd) {
    case DKM_MAP_REQ: /*spin_lock_irqsave(&dkm_map_lock,
    flags);*/
    down(&dkm_map_sema);
    copy_to_user((char*)arg, "filename", 9);
    break;

    case DKM_MAP_RESP: strncpy_from_user(node_name, arg,
    strlen_user(arg));
    printk("node to name is: %s\n",
    node_name);
    /*spin_unlock_irq(&dkm_map_lock);*/
    up(&dkm_map_sema);
    break;

    case DKM_CSD_REG: dkm_csd_pid = *(int*)arg;
    break;

    case DKM_CSD_DEREG: dkm_csd_pid = -1;
    break;

    case DKM_DOSIG: if(dkm_csd_pid > 0)
    force_sig(SIGUSR2,
    find_task_by_pid(dkm_csd_pid));
    break;
    default: break;
    } /* switch */

    printk("csd_pid is: %d, current->pid is: %d\n", dkm_csd_pid,
    current->pid);
    kfree(node_name);

    return 0;
    }
    </snip>

    MY SIGNALHANDLER: on_siguser2(int signal):
    <snip>
    void on_sigusr2(int signal)
    {
    char* node_name;
    char* buff;

    node_name = (char*) malloc(64);
    buff = (char*) malloc(64);

    printf("sigusr2 from kernel reveived\n");
    dkmctl(DKM_MAP_REQ, buff, NULL);
    printf("buff is: %s\n", buff);
    strcpy(node_name, "orinoco");
    dkmctl(DKM_MAP_RESP, node_name);

    free(node_name);
    free(buff);
    }
    </snip>

    greetings
    marcel
    --
    Marcel Lanz <marcel.lanz@ds9.ch>

    PGP-Key fingerprint = 71 BE AC 43 04 53 F9 2D 4F B7 B1 47 E5 9B 91 72

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:54    [W:0.023 / U:0.080 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site