TI中文支持网
TI专业的中文技术问题搜集分享网站

AM335X linux3.2.0 内核紧急文件系统保护机制不起作用

内核有一个机制,在重启前可以将文件系统重新MOUNT为只读分区,用来确保系统重启时,禁止文件系统写操作。
我的产品使用NAND FLASH + UBIFS文件系统,一个MTD分区作为UBI文件系统,这个MTD又分为两个UBI卷(volume)
其中一个MOUNT为只读的根文件系统,另一个MOUNT为读写的DATA分区。
内核可通过以下系统请求,触发内核执行一个紧急的REMOUNT的操作
     echo u > /proc/sysrq-trigger
内核的这个代码在fs/super.c
static void do_emergency_remount(struct work_struct *work)

{
 struct super_block *sb, *p = NULL;
 int ret;

 printk("==>do_emergency_remount\n");
 
 spin_lock(&sb_lock);
 list_for_each_entry(sb, &super_blocks, s_list) {
  
  printk("poll id=%s bdev=%s root=%s mtd=%s\n",   sb->s_id,   sb->s_bdev ? "yes" : "no",   sb->s_root ? "yes" : "no",
   sb->s_mtd ? "yes" : "null");
  
  if (list_empty(&sb->s_instances))
   continue;
  sb->s_count++;
  spin_unlock(&sb_lock);
  down_write(&sb->s_umount);
  if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) {
   /*
    * What lock protects sb->s_flags??
    */
   ret = do_remount_sb(sb, MS_RDONLY, NULL, 1); 
   //printk("do_remount_sb(%s) return %d", sb->s_root->d_iname, ret);
  }
  up_write(&sb->s_umount);
  spin_lock(&sb_lock);
  if (p)
   __put_super(p);
  p = sb;
 }
 if (p)
  __put_super(p);
 spin_unlock(&sb_lock);
 kfree(work);
 printk("Emergency Remount complete\n");
}

以上函数第一个红色部分是我添加的调试信息,通过函数分析,只读superblock的s_bdev (应该是块设备属性)不为空时,才有可能执行真正的Remount操作

但通过打印信息显示,所有的superblock的s_bdev都为空,所以其实系统什么也没有做。

添加打印信息后,执行结果如下:
# echo u > /proc/sysrq-trigger
[  989.335025] SysRq : Emergency Remount R/O
[  989.339279] ==>do_emergency_remount
[  989.342935] poll: fs=tmpfs, id=tmpfs bdev=no root=yes mtd=null
[  989.349067] poll: fs=ubifs, id=ubifs bdev=no root=yes mtd=null
[  989.355186] poll: fs=tmpfs, id=tmpfs bdev=no root=yes mtd=null
[  989.361292] poll: fs=tmpfs, id=tmpfs bdev=no root=yes mtd=null
[  989.367403] poll: fs=tmpfs, id=tmpfs bdev=no root=yes mtd=null
[  989.373507] poll: fs=sysfs, id=sysfs bdev=no root=yes mtd=null
[  989.379620] poll: fs=tmpfs, id=tmpfs bdev=no root=yes mtd=null
[  989.385730] poll: fs=ubifs, id=ubifs bdev=no root=yes mtd=null
[  989.391836] poll: fs=mtd_inodefs, id=mtd_inodefs bdev=no root=yes mtd=null
[  989.399040] poll: fs=mqueue, id=mqueue bdev=no root=yes mtd=null
[  989.405334] poll: fs=devpts, id=devpts bdev=no root=yes mtd=null
[  989.411621] poll: fs=usbfs, id=usbfs bdev=no root=yes mtd=null
[  989.417733] poll: fs=anon_inodefs, id=anon_inodefs bdev=no root=yes mtd=null
[  989.425121] poll: fs=pipefs, id=pipefs bdev=no root=yes mtd=null
[  989.431407] poll: fs=sockfs, id=sockfs bdev=no root=yes mtd=null
[  989.437701] poll: fs=debugfs, id=debugfs bdev=no root=yes mtd=null
[  989.444171] poll: fs=tmpfs, id=tmpfs bdev=no root=yes mtd=null
[  989.450282] poll: fs=proc, id=proc bdev=no root=yes mtd=null
[  989.456213] poll: fs=bdev, id=bdev bdev=no root=yes mtd=null
[  989.462136] poll: fs=rootfs, id=rootfs bdev=no root=yes mtd=null
[  989.468429] poll: fs=sysfs, id=sysfs bdev=no root=yes mtd=null
[  989.474534] Emergency Remount complete
通过打印这个函数遍历的文件系统,是有两个ubifs,但是其s_bdev 都指向空,所以不会执行do_remount_sb(sb, MS_RDONLY, NULL, 1) 函数。
也就是,即使系统有可读写的块设备,但是这个系统请求什么也没做。
执行完后,执行mount命令发现data分区还是可以读写的。
# mount
rootfs / rootfs rw 0 0
ubi0:rootfs / ubifs ro,relatime 0 0
tmpfs /dev tmpfs rw,nosuid,relatime,mode=755 0 0
devpts /dev/pts devpts rw,relatime,mode=600 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,relatime 0 0
debugfs /sys/kernel/debug debugfs rw,relatime 0 0
tmpfs /mnt/secure tmpfs rw,relatime,mode=700 0 0
tmpfs /mnt/asec tmpfs rw,relatime,mode=755,gid=1000 0 0
tmpfs /mnt/obb tmpfs rw,relatime,mode=777,gid=1000 0 0
ubi0:data/data ubifs rw,nosuid,noatime 0 0
请问这个问题要怎么处理呢。谢谢
Steven Liu1:

没太清楚问题,你的根文件系统是只读的,进去了后,决定是否挂载另一个UBIFS,然后执行你的命令之后,会主动去挂那个UBIFS。
所以现在你的remount不成功的意思,就是指,现在进入到内核启动的时候,挂载另一个UBIFS不成功?
手动mount的时候还是可以读写的话,也就是UBIFS本身没问题,只是操作层面上的问题。
所以这问题本质上就是如何在内核中通过代码去成功挂载另一个UBIFS?是这个意思么

赞(0)
未经允许不得转载:TI中文支持网 » AM335X linux3.2.0 内核紧急文件系统保护机制不起作用
分享到: 更多 (0)