我试图从kern_path()函数获取父路径,它在新的amazon linux kernels 4.4.*机器中返回error-2。
如何在4.4.*Linux内核中获取父路径?
/tmp/TestFVT/files/fileXX-12345678989 ===> /tmp/TestFVT/files
类似于this issue
下面是显示的源代码和输出。
你好,C

#include <linux/module.h>    // included for all kernel modules
#include <linux/kernel.h>    // included for KERN_INFO
#include <linux/init.h>      // included for __init and __exit macros
#include <linux/mount.h>
#include <linux/path.h>
#include <linux/namei.h>
#include <linux/fs.h>
#include <linux/string.h>

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A Simple Hello World module");

char *path_name1 = "/tmp/TestFVT/files/fileXX-1234567898"; //Existing FIle
char *path_name3 = "/tmp/TestFVT/files/fileXX-12345678989"; //NON Existing FILE
static int __init hello_init(void)
{
    struct path path1, path3;
    int err = kern_path(path_name1, LOOKUP_PARENT, &path1);
    printk("Path name1 : %s, err: %d\n", path_name1, err);
    err = kern_path(path_name3, LOOKUP_DIRECTORY, &path3);
    printk("Path name3-1 : %s, err: %d\n", path_name3, err);
    err = kern_path(path_name3, LOOKUP_PARENT, &path3);
    printk("Path name3-2 : %s, err: %d\n", path_name3, err);
    return 0;    // Non-zero return means that the module couldn't be loaded.
}

static void __exit hello_cleanup(void)
{
    printk(KERN_INFO "Cleaning up module.\n");
}

module_init(hello_init);
module_exit(hello_cleanup);

输出:
[  120.167328] Path name1 : /tmp/TestFVT/files/fileXX-1234567898, err: 0
[  120.184955] Path name3-1 : /tmp/TestFVT/files/fileXX-12345678989, err: -2
[  120.189614] Path name3-2 : /tmp/TestFVT/files/fileXX-12345678989, err: -2

预期产量:
用于不存在的文件,在以前的版本中运行良好。

最佳答案

===>修改的代码

#include <linux/fs_struct.h>
static int __init hello_init(void){
    struct path path1, path3;
    int err = kern_path(path_name1, LOOKUP_PARENT, &path1);
    printk("Path name1 : %s, err: %d\n", path_name1, err);
    if(err == -2)
            err = checkParentPathExist(path_name1, &path1);
    printk("Path name1 : %s, err: %d\n", path_name1, err);
    return 0;    // Non-zero return means that the module couldn't be loaded.
}

===>在代码下面实现,但进程内存正在损坏和崩溃。不明白为什么会坠毁?请告诉我,下面的代码或kern_path()中有什么问题?是的。
static int checkParentPathExist(char *tmpPath, struct path*  path){
    char *tmpPath4 = NULL;
    int err, flag = 0;

    switch(tmpPath[0]){
            case '/':
            case '.':
                    break;
            default:{
                    char *fname = (char *) __get_free_page(GFP_KERNEL);
                    if (!fname){
                            return -1;
                    }
                    memset(fname, 0, PAGE_SIZE);
                    struct path pwd = current->fs->pwd;
                    path_get(&pwd);

                    tmpPath4 = d_path(&pwd, fname, PAGE_SIZE);
                    path_put(&pwd);
                    strcat(tmpPath4,"/");
                    strcat(tmpPath4,tmpPath);
                    free_page(((unsigned long) fname));
            }
    }

    if(tmpPath4 == NULL){
            flag = 1;
            tmpPath4 = (char *) kmalloc(strlen(tmpPath)+1, GFP_KERNEL);
            if (!tmpPath4)
                    return -1;
            memset(tmpPath4, 0, strlen(tmpPath)+1);
            strcpy(tmpPath4, tmpPath);
    }

    int indx=0, setIndx=0;
    for(;tmpPath4[indx];indx++)
            if(tmpPath4[indx] == '/')
                    setIndx = indx;
    tmpPath4[setIndx] = 0;

    /*================ Getting Issue ================
       Below line issue is (err = kern_path(tmpPath4, LOOKUP_DIRECTORY, path);)
       1. Working fine, and returning success with parent path.
       2. Problem is other process memory is getting corrupted.
       3. Getting continues crashes with bellow message
          i.  BUG: Bad page state in process
          ii. BUG: Bad page map in process
       Message from syslogd@ip-172-31-30-235 at Aug  3 07:20:44 ...
       kernel:[   24.017598] page:ffffea0000eb8380 count:-1 mapcount:0 mapping:          (null) index:0x0
       4. No crashes if below line is commented
    */

    err = kern_path(tmpPath4, LOOKUP_DIRECTORY, path);

    if(flag) {
            kfree(tmpPath4);
    }
    return err;
}

09-26 00:18