免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: turbo99cn
打印 上一主题 下一主题

进程所在的文件系统是根据什么确定的? [复制链接]

论坛徽章:
0
21 [报告]
发表于 2006-01-08 10:36 |只看该作者
原帖由 艾斯尼勒 于 2006-1-8 01:08 发表


原来是这个意思,我觉得若不是我误会楼主了就是楼主的说法还是欠妥呵呵
不过既然linux提供了vfs,那么底层到底什么fs对程序员来说应该当作透明的才对,关心它作什么?


搞不懂你问的什么啊?

论坛徽章:
0
22 [报告]
发表于 2006-01-09 09:12 |只看该作者
乱了乱了

论坛徽章:
0
23 [报告]
发表于 2006-01-09 10:08 |只看该作者
我也是不知道楼主到底想知道什么,不过如果你真的想知道某个文件属于那个文件系统(如ext2,ext3,jffs2),也是可以的。

因为在Linux中,肯定可以通过文件描述符知道的,因为每个文件系统的超级块记录了文件系统类型的信息。

在fs_struct中有一个struct dentry *pwd,表示当前工作目录的目录项(VFS的一个对象),它表示应用程序当前工作目录的信息,通过它我们可以找到与该目录项相关的超级块对象,在struct dentry中有个字段:struct super_block* d_sb指向该目录项所属的超级块,在超级块的结构中包含了文件系统类型信息:struct super_block---struct file_system_type *s_type,你通过该字段,就可以了解到当工作目录的文件系统类型。

不知道我的理解是否正确!可以继续讨论

如果你非要知道你的执行文件所在的文件系统(因为当前工作目录和应用程序文件所在的目录在某些时候可能不同),也是可以通过相同的方式找到。。

希望你能得到你想要得到的信息。

论坛徽章:
0
24 [报告]
发表于 2006-01-09 14:05 |只看该作者
看了各位发言,看了wheelz贴的代码,现在想学内核,就也查了一下源码
文件系统类型放super block里面
如wheelz所说,一般是进程继承的,这在
do_fork()->copy_process()->dup_task_struct()
中可以看到应该是直接memcpy过来的.
static struct task_struct *dup_task_struct(struct task_struct *orig)
{
        struct task_struct *tsk;
        int cpu = smp_processor_id();

        tsk = task_cache[cpu];
        task_cache[cpu] = NULL;

        if (!tsk) {
                tsk = __alloc_task_struct();
                if (!tsk)
                        return NULL;
        }

        memcpy(tsk, orig, sizeof(*tsk));
        atomic_set(&tsk->usage,1);
        return tsk;
}

而init进程是在init_mount_tree时候赋值(wheelz告诉我们的)
然后看了init_mount_tree(void)里面调用的do_kern_mount,就是这里拿到sb
在fs/super.c下面
struct vfsmount *
do_kern_mount(const char *fstype, int flags, char *name, void *data)
{
        struct file_system_type *type = get_fs_type(fstype);
        struct super_block *sb = ERR_PTR(-ENOMEM);
        struct vfsmount *mnt;

        if (!type)
                return ERR_PTR(-ENODEV);

        mnt = alloc_vfsmnt(name);
        if (!mnt)
                goto out;
        if (type->fs_flags & FS_REQUIRES_DEV)
                sb = get_sb_bdev(type, flags, name, data);
        else if (type->fs_flags & FS_SINGLE)
                sb = get_sb_single(type, flags, name, data);
        else
                sb = get_sb_nodev(type, flags, name, data);
        if (IS_ERR(sb))
                goto out_mnt;
        if (type->fs_flags & FS_NOMOUNT)
                sb->s_flags |= MS_NOUSER;
        mnt->mnt_sb = sb;
        mnt->mnt_root = dget(sb->s_root);
        mnt->mnt_mountpoint = sb->s_root;
        mnt->mnt_parent = mnt;
        up_write(&sb->s_umount);
        put_filesystem(type);
        return mnt;
out_mnt:
        free_vfsmnt(mnt);
out:
        put_filesystem(type);
        return (struct vfsmount *)sb;
}

注意到mnt->mnt_mountpoint = sb->s_root,是否因为这个mount point特殊,所以就用了sb的根目录并不增加其的引用记数呢?

如果是通过sys_chroot等系统调用,也是从vfsmount结构取出.
而这个vfsmount的值是在mount一个设备的时候读他的super_block得到的
看了一下 fs/namespace.c
do_mount()->do_add_mount()
发现也是调用
do_kern_mount()的,所以也就根据设备名取得了sb信息.
但之后会调用attach_mnt()来改变mount_point的信息.也增加了mount point 的dentry结构的引用记数.
static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
{
        mnt->mnt_parent = mntget(nd->mnt);
        mnt->mnt_mountpoint = dget(nd->dentry);
        list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
        list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
        nd->dentry->d_mounted++;
}

把vfsmount也抄出来
struct vfsmount
{
        struct list_head mnt_hash;
        struct vfsmount *mnt_parent;        /* fs we are mounted on */  
        struct dentry *mnt_mountpoint;        /* dentry of mountpoint */  
        struct dentry *mnt_root;        /* root of the mounted tree */   
        struct super_block *mnt_sb;        /* pointer to superblock */                 
        struct list_head mnt_mounts;        /* list of children, anchored here */
        struct list_head mnt_child;        /* and going through their mnt_child */  
        atomic_t mnt_count;
        int mnt_flags;
        char *mnt_devname;                /* Name of device e.g. /dev/dsk/hda1 */
        struct list_head mnt_list;
};
看了attach_mnt的代码,才知道,原来mnt_child是用于将结构本身链入mnt_parent的mnt_mounts.

我看的代码是linux-2.4.20-31.9, rh9带的.

本人新学入门,看到有各位大侠在讨论. 也来插一把嘴. 还有很多问题不懂. 比如altroot究竟是什么,会在什么系统调用的时候遇到呢. 还请各位大侠指教.

论坛徽章:
0
25 [报告]
发表于 2006-01-09 14:07 |只看该作者
文件系统?还是当前工作目录?

论坛徽章:
0
26 [报告]
发表于 2006-01-09 15:31 |只看该作者
root是根目录, pwd是当前目录, 那altroot是什么呢,什么时候会用到呢. 也许,某天用到时候才会发现哦^_^. 实在不懂 .

论坛徽章:
0
27 [报告]
发表于 2006-01-09 20:58 |只看该作者
task_struct中有struct fs_struct *fs   //进程的可执行影响所在的文件系统
struct fs_struct {
                          .....................
                         struct dentry *root,*pwd ,*altroot;
                        ............................
                       }
  root所指向的结构体代表着本进程所在的根目录,及用户登录进入系统所看到的根目录
  pwd指向进程当前所在目录
  altroot为用户设置的替换根目录
根据dentry可找到最终找到对应的struct super_block
struct super_block {.............
                                unsigned long s_magic  //魔数,具体文件系统区别于其他文件系统的标志
                              ........................
                             }

论坛徽章:
0
28 [报告]
发表于 2006-01-10 09:12 |只看该作者
man 2 chroot
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP