2016-03-29 17 views
0

私は単純なLKM(Linuxカーネルモジュール)を、カーネルレベルの情報を持つユーザーレベルのMPIアプリケーション(1つの計算ノードあたりのマルチプロセス)とやりとりするようにします。実行時にカーネルからユーザーレベルのアプリケーションにデータを抽出する必要があります。私のMPIアプリケーションでは、同じ計算ノード上で同時に実行されるプロセスはほとんどありません。LKMマルチプロセスを安全にする方法は?

私のLKMは、/procに2つのファイルを提供しています。ファイル/proc/mylkm_inputは、LKMにいくつかの仮想アドレスを提供するために使用されます。 /proc/mylkm_outputファイルは、MPIアプリケーションによってLKMから情報を読み取るために使用されます。

アプリケーションは複数のプロセスです。少なくとも2つのプロセスがLKMにデータを提供し、特定のプロセスに固有のデータを持つLKMからの応答を期待します(/proc/mylkm_output経由)。

また、ファイル/proc/mylkm_outputは、異なるプロセスで同時に読み取ることができます。情報を読むにはlseek(fileId, 0, SEEK_SET)、次にread(fileId, buffer, size)

LKMマルチプロセスを安全にするソリューションはありますか?

は、以下の提案として、私は次のコードを実装し

更新

セルゲイ

、ありがとうございました。これがLKMをプロセスセーフにするのに役立つことを願っています。

#define CPES_MAX_PPN 128 

typedef struct CPESProcessInfoT { 
    pid_t localPID; 
    unsigned long virtualAddress; 
} CPESProcessInfo; 

static CPESProcessInfo addrVA[CPES_MAX_PPN];//using this due many processes use this LKM on the machine (PPN>1) 
static int maxItemInAddrVA = 0;//number of cells allocated by the process PID 

CPESProcessInfo *findAddress(void) { 
    int i = 0; 
    struct task_struct *callerTask = current; 
    for(i = 0; i < CPES_MAX_PPN; ++i) { 
     CPESProcessInfo *walkAddr = addrVA + i; 
     if(walkAddr) { 
      if(walkAddr->localPID == callerTask->pid) { 
       return walkAddr; 
      } 
      if(0 == walkAddr->localPID) { 
       walkAddr->localPID = callerTask->pid; 
       ++maxItemInAddrVA; 
       return walkAddr; 
      } 
     } else { 
      printk(KERN_WARNING "CPES LKM error in findAddress PPN %d maxUsed %d", CPES_MAX_PPN, maxItemInAddrVA); 
     } 
    } 
    return 0; 
} 
+1

つまり、カーネルモジュールが**同じ*ファイルにアクセスする異なるプロセスを区別するようにしますか?その場合は、ファイル操作の実装で現在実行されているスレッドを返す 'current'変数(* getter *)を利用してください。 – Tsyvarev

+0

はい、特定のプロセスが正しい情報を取得することを保証する必要があります。 たとえば、** process 1 **はファイルに対して 'lseek'を行いますが、** process 2 **には' lseek'を渡して 'read'します。この場合、** process 2 **によってファイル記述子が変更されたため、** process 1 **は失敗します。 「現在の変数(ゲッタ)」は何か分かりません いくつかの例を教えてください。 ありがとうございました Sergey –

答えて

1

カーネルモジュールは、変数currentを使用して、ファイルにアクセスするプロセスを、区別することがあります。もちろん

struct task_struct* accessor = NULL; 

ssize_t my_write(...) 
{ 
    accessor = current; 
    ... 
} 

ssize_t my_read(...) 
{ 
    if(accessor != current) { 
     // This is not a process which performed .write before 
     return -EBUSY; 
    } 
    ... 
} 

を、に格納しaccessor変数からロードすると、例えば(同時アクセスから何とか保護しなければなりませんミューテックス)。

関連する問題