Messages in this thread | | | Date | Tue, 09 Nov 1999 18:54:52 +0100 | From | Marcel Lanz <> | 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/
| |