unshare_fs_struct()用于给当前任务描述符current的fs字段设置新的地址,实现不共享的拷贝,即用以前的fs字段的值为新分配的fs字段地址空间赋值,然后将以前的fs字段的引用计数减1,如果引用计数值变为0,则释放以前的fs字段的地址空间。
unshare_fs_struct文件包含
#include <linux/fs_struct.h>
unshare_fs_struct函数定义
在内核源码中的位置:linux-3.19.3/fs/fs_struct.c
函数定义格式:
int unshare_fs_struct(void)
unshare_fs_struct输入参数说明
unshare_fs_struct()
函数无输入参数。
unshare_fs_struct返回参数说明
unshare_fs_struct()
函数返回值是整型变量,可能的取值是0或-12。若返回0,则表示为当前任务current重新分配fs字段的空间,实现不共享的拷贝成功;若返回-12(-ENOMEM的值,宏ENOMEM在linux-3.19.3/include/uapi/asm-generic/errno-base.h中定义),则表示为当前任务current重新分配fs字段的空间失败。
unshare_fs_struct实例解析
编写测试文件:unshare_fs_struct.c
头文件声明如下:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/fs_struct.h>
#include <linux/path.h>
#include <linux/sched.h>
MODULE_LICENSE("GPL");
模块初始化函数:
int unshare_fs_struct_init(void)
{
printk("the current fs users is:%d\n", current->fs->users);
// 显示当前任务的fs的引用计数
printk("the address of the current fs is:0x%x\n", current->fs);
// 显示当前任务的fs的起始地址空间
// 调用函数重新分配fs的空间
int data1 = unshare_fs_struct();
printk("the returned value of \"unshare_fs_struct\" is %d.\n", data1);
// 显示函数返回结果
printk("the address of the current fs is:0x%x\n", current->fs);
// 显示新fs字段的起始地址空间
printk("the current fs users is:%d\n", current->fs->users); //显示新fs的引用计数
return 0;
}
模块退出函数:
void unshare_fs_struct_exit(void)
{
printk("Goodbye unshare_fs_struct\n");
}
模块初始化及退出函数调用:
module_init(unshare_fs_struct_init);
module_exit(unshare_fs_struct_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod unshare_fs_struct.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。
结果分析:
由图中可以看出函数调用前后current变量的fs字段的起始地址空间不同,但其users字段的值相同。其实二者的所有字段的值都是相同的,新fs字段中的字段都是用旧fs字段中的字段的值赋值的,实现二者的不共享拷贝。函数unshare_fs_struct()的返回结果是0,也说明函数此次执行完成了重新分配fs字段的地址空间。