2013-05-01 16 views
6
  • Dato un inode che esiste in /proc/**/fd/*
  • e un modulo kernel di Linux che ha bisogno di trovare il percorso eseguibile dal link simbolico /proc/**/exe

Come potrebbe Implemento questo in modo che da un numero di inode ho ottenuto il percorso dell'eseguibile usando il fd?percorso eseguibile da inode fd in un modulo del kernel linux

+1

Nelle mie ricerche ho trovato un metodo 'proc_fd_link' (http: //lxr.free-electrons.com/source/fs/proc/fd.c?a=avr32#L140) ma non è accessibile dal mio modulo del kernel (metodo non trovato nella compilazione. – ZedTuX

+1

Ho trovato anche macro 'PDE' e 'PROC_I' (http://lxr.free-electrons.com/source/include/linux/proc_fs.h) ma poi non so come trovare l'oggetto'/proc/**/exe'. – ZedTuX

+1

Un inode potrebbe non avere nessuno o più di un percorso e gli spazi dei nomi potrebbero generare percorsi diversi in processi diversi. A cosa serve il percorso e perché questo deve essere fatto da un modulo del kernel? –

risposta

0

Gli proc_inode struct e PROC_I macro sono entrambi interni. Vedi [PATCH 27/28] proc: Make the PROC_I() and PDE() macros internal toprocfs [RFC].

Invece, che dire di iterare sulla lista di dentici dell'inode? Si potrebbe utilizzare dentry_path_raw() per trovare un nome /*/fd/* percorso:

//struct inode *proc_inode; 

struct dentry *dentry; 
pid_t pid; 
int found_match = 0; 

printk(KERN_DEBUG "superblock type name: %s\n", proc_inode->i_sb->s_type->name); 

// An inode's dentry list is protected by the i_lock. See: 
// - "dcache->d_inode->i_lock protects: i_dentry, d_u.d_alias, d_inode of aliases" 
// http://lxr.free-electrons.com/source/fs/dcache.c?v=4.0#L48 
// - The implementation of d_prune_aliases() 
// http://lxr.free-electrons.com/source/fs/dcache.c?v=4.0#L882 
spin_lock(&proc_inode->i_lock); 
hlist_for_each_entry(dentry, &proc_inode->i_dentry, d_u.d_alias) { 
    char buf[64]; 
    const char *path_raw; 
    char c; 

    path_raw = dentry_path_raw(dentry, buf, sizeof(buf)); 

    // dentry_path_raw() places the path into `buf'. If `buf' is not large 
    // enough, then continue on to the next dentry. 
    if (!(buf <= path_raw && path_raw <= buf + sizeof(buf) - 1)) { 
     printk(KERN_DEBUG "`buf' not large enough, dentry_path_raw() returned %ld\n", PTR_ERR(path_raw)); 
     continue; 
    } 

    printk(KERN_DEBUG "path_raw = %s\n", path_raw); 

    // We're looking to match: ^/(\d*)/fd/ 

    if (*path_raw++ != '/') continue; 

    pid = 0; 
    for (c = *path_raw; c; c = *++path_raw) { 
     if ('0' <= c && c <= '9') { 
      pid = 10 * pid + (c - '0'); 
     } else { 
      break; 
     } 
    } 

    if (*path_raw++ != '/') continue; 
    if (*path_raw++ != 'f') continue; 
    if (*path_raw++ != 'd') continue; 
    if (*path_raw != '/' && *path_raw != '\0') continue; 

    // Found a match. Break the dentry list loop. 
    found_match = 1; 
    printk(KERN_DEBUG "breaking dentry list loop\n"); 
    break; 
} 
spin_unlock(&proc_inode->i_lock); 

if (found_match) { 
    printk(KERN_DEBUG "pid = %d\n", (int)pid); 
} 

EDIT: ho caricato un progetto dimostrativo per GitHub:
https://github.com/dtrebbien/so16317923-proc-fs-kernel-module

+0

Grazie! darò un'occhiata – ZedTuX

Problemi correlati