午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

Linux Debugfs文件系統(tǒng)介紹及使用 — Windows Live

 jijo 2010-06-28

Linux Debugfs文件系統(tǒng)介紹及使用

author: jonathan

本文檔的CopyRight歸jonathan所有,可自由轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)保持文檔的完整性。
/*---------------------------------------------------------------------------------------------------------------------*/

什么是不常見的文件系統(tǒng)?其實(shí)我也說不清,如ramfs->rootfs -> tmpfs ->initramfs->romfs->...等等,這些算不算呢?哎,算了,看到那里就算那里了。

1 Debugfs簡介

Debugfs文件系統(tǒng)目的是為開發(fā)人員提供更多內(nèi)核數(shù)據(jù),方便調(diào)試內(nèi)容. 我們知道/proc文件系統(tǒng)關(guān)注的是進(jìn)程信息,/sysfs關(guān)注是one-value-per-file策略集,而Debugfs文件系統(tǒng)沒有如此多限制,可是任何內(nèi)核要輸出的信息。

2 Debugfs使用

2.1 安裝文件系統(tǒng)

Debugfs沒有物理設(shè)備,其掛載方式:

mount -t debugfs none /sys/kernel/debug

2.2 編程使用

2.2.1 要使用Debugfs的模塊需要包含<linux/debugfs.h>

2.2.2 具體步驟

a 創(chuàng)建目錄。所有該模塊輸出的信息都在該目錄下面。

struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);

b 創(chuàng)建文件。在上面創(chuàng)建的目錄下面創(chuàng)建文件。

struct dentry *debugfs_create_file(const char *name, mode_t mode, struct dentry *parent, void *data,
const struct file_operations *fops);

通過fops操作文件的讀寫等請(qǐng)求,文件一般用來傳遞字符創(chuàng)等信息。

c 對(duì)于數(shù)字情況下,就沒有必須通過文件來傳遞信息了。Debugfs提供了針對(duì)數(shù)字的接口:


struct dentry *debugfs_create_u8(const char *name, mode_t mode, struct dentry *parent, u8 *value);
struct dentry *debugfs_create_u16(const char *name, mode_t mode, struct dentry *parent, u16 *value);
struct dentry *debugfs_create_u32(const char *name, mode_t mode, struct dentry *parent, u32 *value);
struct dentry *debugfs_create_u64(const char *name, mode_t mode, struct dentry *parent, u64 *value);
struct dentry *debugfs_create_bool(const char *name, mode_t mode, struct dentry *parent, u32 *value);
struct dentry *debugfs_create_blob(const char *name, mode_t mode, struct dentry *parent,
struct debugfs_blob_wrapper *blob);

d 模塊卸載,需要主動(dòng)刪除目錄下的文件。

void debugfs_remove_recursive(struct dentry *dentry);

3 Debugfs內(nèi)核代碼分析

3.1 初始化和釋放資源

static int __init debugfs_init(void)
{
int retval;

/* 創(chuàng)建kobject */
debug_kobj = kobject_create_and_add("debug", kernel_kobj);
if (!debug_kobj)
return -EINVAL;

/* 注冊(cè)文件系統(tǒng) */
retval = register_filesystem(&debug_fs_type);
if (retval)
kobject_put(debug_kobj);
else
debugfs_registered = true;

return retval;
}

static void __exit debugfs_exit(void)
{
debugfs_registered = false;

simple_release_fs(&debugfs_mount, &debugfs_mount_count);
unregister_filesystem(&debug_fs_type);
kobject_put(debug_kobj);
}


3.2 關(guān)鍵函數(shù)

debugfs_create_file函數(shù)是關(guān)鍵函數(shù),其他接口基本都是該接口的wrapper。

3.2.1 變參數(shù)宏的定義

#define pr_debug(fmt, ...) do { \
dynamic_pr_debug(fmt, ##__VA_ARGS__); \
} while (0)

dynamic_pr_debug 也是變參數(shù)的.

3.2.2 debugfs_create_file

/* 掛載點(diǎn) */
static struct vfsmount *debugfs_mount;
/* 引用計(jì)數(shù) */
static int debugfs_mount_count;
static bool debugfs_registered;

/* 多條目數(shù)據(jù)結(jié)構(gòu) */
struct debugfs_blob_wrapper {
void *data;
unsigned long size;
};

static struct file_system_type debug_fs_type = {
.owner = THIS_MODULE,
.name = "debugfs",
.get_sb = debug_get_sb,
.kill_sb = kill_litter_super,
};

struct dentry *debugfs_create_file(const char *name, mode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops)
{
struct dentry *dentry = NULL;
int error;

pr_debug("debugfs: creating file '%s'\n",name);

/* 如果文件系統(tǒng)沒有掛載,首先掛載文件系統(tǒng);否則增加掛載點(diǎn)引用計(jì)數(shù) */
error = simple_pin_fs(&debug_fs_type, &debugfs_mount,
&debugfs_mount_count);
if (error)
goto exit;

/* 根據(jù)名稱創(chuàng)建文件或者目錄 */
error = debugfs_create_by_name(name, mode, parent, &dentry);
if (error) {
dentry = NULL;
simple_release_fs(&debugfs_mount, &debugfs_mount_count);
goto exit;
}

if (dentry->d_inode) {
/* 給私有數(shù)據(jù)和文件操作接口 */
if (data)
dentry->d_inode->i_private = data;
if (fops)
dentry->d_inode->i_fop = fops;
}
exit:
return dentry;
}

int simple_pin_fs(struct file_system_type *type, struct vfsmount **mount, int *count)
{
struct vfsmount *mnt = NULL;
spin_lock(&pin_fs_lock);

/* 如果沒有掛載文件系統(tǒng),這里會(huì)自動(dòng)掛載文件系統(tǒng) */
if (unlikely(!*mount)) {
spin_unlock(&pin_fs_lock);
mnt = vfs_kern_mount(type, 0, type->name, NULL);
if (IS_ERR(mnt))
return PTR_ERR(mnt);
spin_lock(&pin_fs_lock);
if (!*mount)
*mount = mnt;
}

/* 增加掛載點(diǎn)引用計(jì)數(shù) */
mntget(*mount);
++*count;
spin_unlock(&pin_fs_lock);
mntput(mnt);
return 0;
}

static int debugfs_create_by_name(const char *name, mode_t mode,
struct dentry *parent,
struct dentry **dentry)
{
int error = 0;

/* If the parent is not specified, we create it in the root.
* We need the root dentry to do this, which is in the super
* block. A pointer to that is in the struct vfsmount that we
* have around.
*/
/* 英文說和很明白了 */
if (!parent) {
if (debugfs_mount && debugfs_mount->mnt_sb) {
parent = debugfs_mount->mnt_sb->s_root;
}
}
if (!parent) {
pr_debug("debugfs: Ah! can not find a parent!\n");
return -EFAULT;
}

*dentry = NULL;
mutex_lock(&parent->d_inode->i_mutex);

/* namei.c中根據(jù)名稱查找目錄, 在以前的文件系統(tǒng)分析中有介紹,這里不再累贅.
* 主要過程: 根據(jù)name,計(jì)算hash; 在name_hash_table查找dentry;如果沒有找到,則d_alloc;遍歷到結(jié)尾得到該文件的dentry
*/
*dentry = lookup_one_len(name, parent, strlen(name));
if (!IS_ERR(*dentry)) {
/* 以下三函數(shù)首先對(duì)mode設(shè)置合時(shí)的模式,然后都最終調(diào)用debugfs_get_inode,建立dentry與inode的聯(lián)系*/
switch (mode & S_IFMT) {
case S_IFDIR:
error = debugfs_mkdir(parent->d_inode, *dentry, mode);
break;
case S_IFLNK:
error = debugfs_link(parent->d_inode, *dentry, mode);
break;
default:
error = debugfs_create(parent->d_inode, *dentry, mode);
break;
}
dput(*dentry);
} else
error = PTR_ERR(*dentry);
mutex_unlock(&parent->d_inode->i_mutex);

return error;
}

/* 根據(jù)超級(jí)塊分配新的inode */
static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev)
{
struct inode *inode = new_inode(sb);

if (inode) {
inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
switch (mode & S_IFMT) {
default:
init_special_inode(inode, mode, dev);
break;
case S_IFREG:
inode->i_fop = &debugfs_file_operations;
break;
case S_IFLNK:
inode->i_op = &debugfs_link_operations;
break;
case S_IFDIR:
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;

/* directory inodes start off with i_nlink == 2
* (for "." entry) */
inc_nlink(inode);
break;
}
}
return inode;
}

const struct file_operations debugfs_file_operations = {
.read = default_read_file,
.write = default_write_file,
.open = default_open,
};

const struct file_operations simple_dir_operations = {
.open = dcache_dir_open,
.release = dcache_dir_close,
.llseek = dcache_dir_lseek,
.read = generic_read_dir,
.readdir = dcache_readdir,
.fsync = simple_sync_file,
};

const struct inode_operations simple_dir_inode_operations = {
.lookup = simple_lookup,
};

3.3 其他函數(shù)

struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
{
return debugfs_create_file(name,
S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
parent, NULL, NULL);
}

struct dentry *debugfs_create_bool(const char *name, mode_t mode,
struct dentry *parent, u32 *value)
{
return debugfs_create_file(name, mode, parent, value, &fops_bool);
}

由以上可以看出,其他的輸出信息都是debugfs_create_file的包裝,這里主要是debugfs_create_file函數(shù)最后一個(gè)參數(shù)struct file_operations不同而已。

這里以bool類型為例:

static ssize_t read_file_bool(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
char buf[3];

/* 存儲(chǔ)內(nèi)部保存的數(shù)據(jù) */
u32 *val = file->private_data;

if (*val)
buf[0] = 'Y';
else
buf[0] = 'N';
buf[1] = '\n';
buf[2] = 0x00;
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}


static ssize_t write_file_bool(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
char buf[32];
int buf_size;

/* 存儲(chǔ)內(nèi)部保存的數(shù)據(jù) */
u32 *val = file->private_data;

buf_size = min(count, (sizeof(buf)-1));
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;

switch (buf[0]) {
case 'y':
case 'Y':
case '1':
*val = 1;
break;
case 'n':
case 'N':
case '0':
*val = 0;
break;
}

return count;
}

static const struct file_operations fops_bool = {
.read = read_file_bool,
.write = write_file_bool,
.open = default_open,

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多