1. 8556395.925003] XFS (sdi): xfs_log_force: error - returned.
  2. [8556407.425047] INFO: task umount: blocked for more than seconds.----这个默认是120,该环境上是被人为设置1200
  3. [8556407.425653] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
  4. [8556407.426050] umount D ffff881fffdd47c0 0x00000080------------------------19286pid19283ppid
  5. [8556407.426056] ffff883e39587d80 ffff883e39587fd8 ffff883e39587fd8
  6. [8556407.426066] ffff883e39587fd8 00000000000147c0 ffff881fd3260000 ffff881f860fec80
  7. [8556407.426072] ffff883ed79e1a20 ffff881f860fecc0 ffff881f860fece8 ffff881f860fec90------------这1264位的值为栈里的值
  8. [8556407.426078] Call Trace:
  9. [8556407.426092] [<ffffffff8163e879>] schedule+0x29/0x70
  10. [8556407.426137] [<ffffffffa07c6cd1>] xfs_ail_push_all_sync+0xc1/0x110 [xfs]
  11. [8556407.426143] [<ffffffff810a7610>] ? wake_up_atomic_t+0x30/0x30
  12. [8556407.426165] [<ffffffffa07b1b98>] xfs_unmountfs+0x68/0x190 [xfs]
  13. [8556407.426186] [<ffffffffa07b267b>] ? xfs_mru_cache_destroy+0x6b/0x90 [xfs]
  14. [8556407.426204] [<ffffffffa07b4a52>] xfs_fs_put_super+0x32/0x90 [xfs]
  15. [8556407.426211] [<ffffffff811e3026>] generic_shutdown_super+0x56/0xe0-------已经执行完fsnotify_umount_inodes
  16. [8556407.426215] [<ffffffff811e3477>] kill_block_super+0x27/0x70
  17. [8556407.426218] [<ffffffff811e37b9>] deactivate_locked_super+0x49/0x60
  18. [8556407.426222] [<ffffffff811e3db6>] deactivate_super+0x46/0x60
  19. [8556407.426229] [<ffffffff81200d25>] mntput_no_expire+0xc5/0x120
  20. [8556407.426234] [<ffffffff812025cb>] SyS_umount+0x15b/0x5b0
  21. [8556407.426239] [<ffffffff81649909>] system_call_fastpath+0x16/0x1b
  22. [8556407.426242] sending NMI to all CPUs:

对应的函数为:

  1. /*
  2. * Push out all items in the AIL immediately and wait until the AIL is empty.
  3. */
  4. void
  5. xfs_ail_push_all_sync(
  6. struct xfs_ail *ailp)
  7. {
  8. struct xfs_log_item *lip;
  9. DEFINE_WAIT(wait);
  10.  
  11. spin_lock(&ailp->xa_lock);
  12. while ((lip = xfs_ail_max(ailp)) != NULL) {
  13. prepare_to_wait(&ailp->xa_empty, &wait, TASK_UNINTERRUPTIBLE);
  14. ailp->xa_target = lip->li_lsn;
  15. wake_up_process(ailp->xa_task);
  16. spin_unlock(&ailp->xa_lock);
  17. schedule();
  18. spin_lock(&ailp->xa_lock);
  19. }
  20. spin_unlock(&ailp->xa_lock);
  21.  
  22. finish_wait(&ailp->xa_empty, &wait);
  23. }

排查的时候走了弯路,因为看的是:

  1. crash> dis -l xfs_ail_push_all_sync+0xc1
  2. /usr/src/debug/kernel-3.10.-327.22..el7/linux-3.10.-327.22..el7.x86_64/include/linux/spinlock.h:
  3. 0xffffffffa07c6cd1 <xfs_ail_push_all_sync+>: mov %r13,%rdi

所以想当然地认为在第一个 获取spinlock的地方,

  1. spin_lock(&ailp->xa_lock);---------以为在这hung
  2. while ((lip = xfs_ail_max(ailp)) != NULL) {

然后查找这把锁:

  1. crash> struct super_block.s_fs_info ffff883f7fe67800
  2. s_fs_info = 0xffff883f7fe67000
  3. crash> mod -s xfs
  4. MODULE NAME SIZE OBJECT FILE
  5. ffffffffa0803d40 xfs /lib/modules/3.10.-327.22..el7.x86_64/kernel/fs/xfs/xfs.ko
  6. crash> struct -xo xfs_mount.m_ail 0xffff883f7fe67000
  7. struct xfs_mount {
  8. [ffff883f7fe67010] struct xfs_ail *m_ail;
  9. }
  10.  
  11. struct xfs_mount.m_ail 0xffff883f7fe67000
  12. m_ail = 0xffff881f860fec80
  13.  
  14. crash> struct -xo xfs_ail.xa_lock 0xffff881f860fec80
  15. struct xfs_ail {
  16. [ffff881f860fecc0] spinlock_t xa_lock;
  17. }

而且这把锁的值是:

  1. crash> struct xfs_ail.xa_lock 0xffff881f860fec80
  2. xa_lock = {
  3. {
  4. rlock = {
  5. raw_lock = {
  6. {
  7. head_tail = ,
  8. tickets = {
  9. head = ,
  10. tail =
  11. }
  12. }
  13. }
  14. }
  15. }
  16. }

我一看到这个是非0值,想当然认为是被持有了,为了验证我的想法,我甚至随便找了一把锁查看它的值,点背的时候,喝凉水都塞牙,我随手选择的锁是:

  1. crash> p gc_lock
  2. gc_lock = $ = {
  3. {
  4. rlock = {
  5. raw_lock = {
  6. {
  7. head_tail = ,
  8. tickets = {
  9. head = ,
  10. tail =
  11. }
  12. }
  13. }
  14. }
  15. }
  16. }

后来仔细看了在没有开启 CONFIG_QUEUED_SPINLOCKS 的情况下,锁的定义才是如此,否则的话,是如下:

  1. #ifndef __GENKSYMS__
  2. typedef struct qspinlock {
  3. atomic_t val;
  4. } arch_spinlock_t;
  5. #else
  6. typedef u32 __ticketpair_t;
  7.  
  8. typedef struct arch_spinlock {
  9. union {
  10. __ticketpair_t head_tail;
  11. struct __raw_tickets {
  12. __ticket_t head, tail;
  13. } tickets;
  14. };
  15. } arch_spinlock_t;
  16. #endif

所以要么0,要么1的情况只适合于第一种定义,以前因为业务默认配置的config问题,查的锁相关的crash,大多是第一种定义,但是当时没注意到这个细节,只是简单扫了一眼,浪费我两个小时,所以下盘不稳总会摔。

查看running状态的都没有持有这把锁,(其实按照第二种定义,是正常的,因为此时本就没人持有这把锁,因为head和tail相等)比较奇怪,后来找同事讨论,同事认为是while循环没跳出,所以获取锁的那行是schedule下面那行,还没有执行。

想起来自己曾经写过的博客《https://www.cnblogs.com/10087622blog/p/9558024.html》,应该是如此

  1. void
  2. xfs_ail_push_all_sync(
  3. struct xfs_ail *ailp)
  4. {
  5. struct xfs_log_item *lip;
  6. DEFINE_WAIT(wait);
  7.  
  8. spin_lock(&ailp->xa_lock);
  9. while ((lip = xfs_ail_max(ailp)) != NULL) {
  10. prepare_to_wait(&ailp->xa_empty, &wait, TASK_UNINTERRUPTIBLE);
  11. ailp->xa_target = lip->li_lsn;
  12. wake_up_process(ailp->xa_task);
  13. spin_unlock(&ailp->xa_lock);
  14. schedule();--------------------这个和while循环一直跳不出去,
  15. spin_lock(&ailp->xa_lock);
  16. }
  17. spin_unlock(&ailp->xa_lock);
  18.  
  19. finish_wait(&ailp->xa_empty, &wait);
  20. }

跳不出去的原因跟io相关,也就是wake_up 相关的内核线程之后,内核线程还是没有完成对应的任务:

  1. crash> struct xfs_ail.xa_task 0xffff881f860fec80
  2. xa_task = 0xffff883f8901dc00
  3.  
  4. crash> task_struct.pid 0xffff883f8901dc00
  5. pid =
  6.  
  7. crash> set
  8. PID:
  9. COMMAND: "xfsaild/sdi"
  10. TASK: ffff883f8901dc00 [THREAD_INFO: ffff881f3d828000]
  11. CPU:
  12. STATE: TASK_INTERRUPTIBLE
  13. crash> bt
  14. PID: TASK: ffff883f8901dc00 CPU: COMMAND: "xfsaild/sdi"
  15. # [ffff881f3d82bcd0] __schedule at ffffffff8163df9b
  16. # [ffff881f3d82bd38] schedule at ffffffff8163e879
  17. # [ffff881f3d82bd48] schedule_timeout at ffffffff8163c295
  18. # [ffff881f3d82bdf8] xfsaild at ffffffffa07c6a4f [xfs]
  19. # [ffff881f3d82bec8] kthread at ffffffff810a661f
  20. # [ffff881f3d82bf50] ret_from_fork at ffffffff81649858

xfsaild 无法完成的原因也是因为IO异常:

附部分相关io异常的message日志:

  1. kernel: sd :::: [sdi] CDB: Read() 4c b0
  2. kernel: sd :::: [sdi] CDB: Read() 8a
  3. kernel: blk_update_request: I/O error, dev sdi, sector
  4. kernel: sd :::: rejecting I/O to offline device
  5. kernel: XFS (sdi): metadata I/O error: block 0xee173de0 ("xfs_trans_read_buf_map") error numblks
  6. kernel: XFS (sdi): metadata I/O error: block 0x15da29d90 ("xfs_trans_read_buf_map") error numblks
  7. kernel: sd :::: rejecting I/O to offline device
  8. kernel: XFS (sdi): xfs_imap_to_bp: xfs_trans_read_buf() returned error -.
  9. kernel: XFS (sdi): metadata I/O error: block 0xeca8a480 ("xfs_trans_read_buf_map") error numblks
  10. kernel: sd :::: rejecting I/O to offline device
  11. kernel: sd :::: rejecting I/O to offline device

对应的bug解决可以参照:https://bugzilla.redhat.com/show_bug.cgi?id=1267042

linux xfs的一次io异常导致的crash的更多相关文章

  1. 捉虫日记 | MySQL 5.7.20 try_acquire_lock_impl 异常导致mysql crash

    背景 近期线上MySQL 5.7.20集群不定期(多则三周,短则一两天)出现主库mysql crash.触发主从切换问题,堆栈信息如下: 从堆栈信息可以明显看出,在调用 try_acquire_loc ...

  2. 物理机异常断电,linux虚拟机系统磁盘mount失败,导致无法启动; kubectl 连接失败

    虚拟机 CentOS 7 挂载文件系统失败 上周五下班前没有关闭虚拟机和物理机, 今天周一开了虚拟机之后,发现操作系统启动失败. 原因跟 这篇文章描述的一模一样. 解决操作系统的文件系统挂载的问题之后 ...

  3. java.sql.SQLException: Io 异常: Connection reset

    当数据库连接池中的连接被创建而长时间不使用的情况下,该连接会自动回收并失效,但客户端并不知道,在进行数据库操作时仍然使用的是无效的数据库连接,这样,就导致客户端程序报“ java.sql.SQLExc ...

  4. Linux 下的五种 IO 模型

    概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的 ...

  5. spring+ibatis问题1—— 程序报错:java.sql.SQLException: Io 异常: Connection reset by peer, socket write error; ”或“java.sql.SQLException 关闭的连接”异常

    转自:http://blog.sina.com.cn/s/blog_1549fb0710102whz2.html spring+ibatis程序测试时报错:java.sql.SQLException: ...

  6. linux性能优化cpu 磁盘IO MEM

    系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长期和持续的过程,不 是说现在优化了,测试了,以后就可以一劳永逸了,也不是说书本上 ...

  7. Io 异常: The Network Adapter could not establish the connection

    新接触一个项目,导入源码,在本地启动的时候后台报了一个错误: Could not discover the dialect to use. java.sql.SQLException: Io 异常: ...

  8. oracle 数据库io 异常,错误代码17002 解决办法

    数据库使用一个月了,突然挂掉:错误代码17002 io异常:read timeout 解决: 1.登陆sql命令窗口 [oracle@hostname ~]$ sqlplus /nolog SQL*P ...

  9. 【Android开发】 HttpURLConnection.getOutputStream() IO异常

    HttpURLConnection.getOutputStream()  IO异常百度下,没找到想要的答案.网上的解决方案几乎都是从权限考虑的~最后找到个国外网站上找到答案~ http://stack ...

随机推荐

  1. MySQL事务锁问题-Lock wait timeout exceeded

    转载:https://cloud.tencent.com/developer/article/1356959 问题现象:   接口响应时间超长,耗时几十秒才返回错误提示,后台日志中出现Lock wai ...

  2. 两台Linux服务器之间复制文件

    一.scp 1.简介 scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的 2.软件安装 ...

  3. 树莓派3代B+安装mateubuntu16.04

    直接安装会卡在开机后的彩虹界面 所以先直接安装:2019-04-08-raspbian-stretch-lite.img 安装完毕后,直接在Linux环境下读取 /boot /系统分区(系统分区在wi ...

  4. MUI在项目中使用时遇到的问题的个人分享

    picker 添加年插件问题总结 1. 取消按钮点击事件无法获取 可以获取到取消按钮标签和确定按钮标签 但是只能获取去顶按钮事件,取消点击事件无法获取 通过判断picker的display状态也不能确 ...

  5. 【凡尘】---react-redux---【react】

    一.Redux与组件 react-redux是一个第三方插件使我们在react上更方便的来使用redux这个数据架构 React-Redux提供connect方法,用于从UI组件生成容器组件,conn ...

  6. Windows10上桌面共享

    Windows自带的桌面共享软件 命令行输入: Msra.exe

  7. LeetCode——295. Find Median from Data Stream

    一.题目链接: https://leetcode.com/problems/find-median-from-data-stream 二.题目大意: 给定一段数据流,要求求出数据流中的中位数,其中数据 ...

  8. Navicat premium 12破解版

    下载Navicat  Premium 12和破解补丁Navicat_Keygen_Patch,底部有下载地址.下载之后安装Navicat,安装成功后先不要打开,然后打开破解补丁,破解补丁不需要安装,双 ...

  9. Mono的CustomConditionAttribute使用

    1.Mono的CustomConditionAttribute使用有诸多的限制,没有在XML中定义来的灵活 2.CustomConditionAttribute定义的子类必须和ExtensionAtt ...

  10. Ubuntu下安装Snap

    介绍 Snap是一个全新的软件包架构,它与其它包管理器的区别在于snap安装的app互相之间是高度隔离的,减少了互相引用. 避免了很多冲突问题. 不过这也导致了其占用的磁盘比较多. 安装 apt in ...