[question/comment/help] pseudo function-call from kernel to a

Marcel Lanz (marcel.lanz@ds9.ch)
Tue, 09 Nov 1999 18:54:52 +0100


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/