当前位置:   article > 正文

Linux内核进程详解之一:sync_supers_sync进程

sync进程

先说下环境,CentOS 6.0/Linux kernel 2.6.38.8/X86-64,后面提到的代码也都来之kernel 2.6.38.8。这个环节下的进程列表具体如下所示,后续将有一系列的文章分析各个进程(主要是内核进程)的功能:

  1. [root@localhost ~]# cat /etc/issue
  2. CentOS Linux release 6.0 (Final)
  3. Kernel \r on an \m
  4. [root@localhost ~]# uname -a
  5. Linux localhost.localdomain 2.6.38.8 #4 SMP Mon Oct 31 20:49:48 CST 2011 x86_64 x86_64 x86_64 GNU/Linux
  6. [root@localhost ~]# ps aux
  7. USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
  8. root 1 0.0 0.1 19284 1368 ? Ss Feb06 0:02 /sbin/init
  9. root 2 0.0 0.0 0 0 ? S Feb06 0:00 [kthreadd]
  10. root 3 0.0 0.0 0 0 ? S Feb06 0:00 [ksoftirqd/0]
  11. root 5 0.0 0.0 0 0 ? S Feb06 0:20 [kworker/u:0]
  12. root 6 0.0 0.0 0 0 ? S Feb06 0:00 [migration/0]
  13. root 7 0.0 0.0 0 0 ? S Feb06 0:00 [migration/1]
  14. root 9 0.0 0.0 0 0 ? S Feb06 0:00 [ksoftirqd/1]
  15. root 11 0.0 0.0 0 0 ? S< Feb06 0:00 [cpuset]
  16. root 12 0.0 0.0 0 0 ? S< Feb06 0:00 [khelper]
  17. root 13 0.0 0.0 0 0 ? S< Feb06 0:00 [netns]
  18. root 14 0.0 0.0 0 0 ? S Feb06 0:01 [sync_supers]
  19. root 15 0.0 0.0 0 0 ? S Feb06 0:00 [bdi-default]
  20. root 16 0.0 0.0 0 0 ? S< Feb06 0:00 [kintegrityd]
  21. root 17 0.0 0.0 0 0 ? S< Feb06 0:00 [kblockd]
  22. root 18 0.0 0.0 0 0 ? S< Feb06 0:00 [kacpid]
  23. root 19 0.0 0.0 0 0 ? S< Feb06 0:00 [kacpi_notify]
  24. root 20 0.0 0.0 0 0 ? S< Feb06 0:00 [kacpi_hotplug]
  25. root 21 0.0 0.0 0 0 ? S< Feb06 0:00 [ata_sff]
  26. root 22 0.0 0.0 0 0 ? S Feb06 0:00 [khubd]
  27. root 23 0.0 0.0 0 0 ? S< Feb06 0:00 [md]
  28. root 24 0.0 0.0 0 0 ? S Feb06 0:00 [khungtaskd]
  29. root 25 0.0 0.0 0 0 ? S Feb06 0:05 [kswapd0]
  30. root 26 0.0 0.0 0 0 ? SN Feb06 0:00 [ksmd]
  31. root 27 0.0 0.0 0 0 ? SN Feb06 0:02 [khugepaged]
  32. root 28 0.0 0.0 0 0 ? S Feb06 0:00 [fsnotify_mark]
  33. root 29 0.0 0.0 0 0 ? S< Feb06 0:00 [aio]
  34. root 30 0.0 0.0 0 0 ? S< Feb06 0:00 [crypto]
  35. root 35 0.0 0.0 0 0 ? S Feb06 0:20 [kworker/u:1]
  36. root 37 0.0 0.0 0 0 ? S< Feb06 0:00 [kpsmoused]
  37. root 175 0.0 0.0 0 0 ? S Feb06 0:00 [scsi_eh_0]
  38. root 176 0.0 0.0 0 0 ? S Feb06 0:42 [scsi_eh_1]
  39. root 182 0.0 0.0 0 0 ? S< Feb06 0:00 [mpt_poll_0]
  40. root 183 0.0 0.0 0 0 ? S< Feb06 0:00 [mpt/0]
  41. root 184 0.0 0.0 0 0 ? S Feb06 0:00 [scsi_eh_2]
  42. root 240 0.0 0.0 0 0 ? S< Feb06 0:00 [kdmflush]
  43. root 247 0.0 0.0 0 0 ? S< Feb06 0:00 [kdmflush]
  44. root 259 0.0 0.0 0 0 ? S Feb06 0:19 [jbd2/dm-0-8]
  45. root 260 0.0 0.0 0 0 ? S< Feb06 0:00 [ext4-dio-unwrit]
  46. root 297 0.0 0.0 0 0 ? S Feb06 0:01 [kauditd]
  47. root 346 0.0 0.1 11700 1820 ? S<s Feb06 0:00 /sbin/udevd -d
  48. root 565 0.0 0.0 0 0 ? S Feb06 0:05 [flush-253:0]
  49. root 681 0.0 0.0 0 0 ? S< Feb06 0:00 [vmmemctl]
  50. root 757 0.0 0.0 0 0 ? S< Feb06 0:00 [kdmflush]
  51. root 801 0.0 0.0 0 0 ? S Feb06 0:00 [jbd2/sda1-8]
  52. root 802 0.0 0.0 0 0 ? S< Feb06 0:00 [ext4-dio-unwrit]
  53. root 803 0.0 0.0 0 0 ? S Feb06 0:00 [jbd2/dm-2-8]
  54. root 804 0.0 0.0 0 0 ? S< Feb06 0:00 [ext4-dio-unwrit]
  55. root 912 0.0 0.3 12880 3108 ? S< Feb06 0:00 /sbin/udevd -d
  56. root 924 0.0 0.2 12356 2648 ? S< Feb06 0:00 /sbin/udevd -d
  57. root 1114 0.0 0.1 242492 1540 ? Sl Feb06 0:05 /sbin/rsyslogd -c 4
  58. root 1143 0.0 0.0 9104 428 ? Ss Feb06 1:04 irqbalance
  59. rpc 1162 0.0 0.0 18920 816 ? Ss Feb06 0:01 rpcbind
  60. root 1176 0.0 0.0 6604 260 ? Ss Feb06 0:00 mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid
  61. dbus 1185 0.0 0.1 29964 1448 ? Ssl Feb06 0:00 dbus-daemon --system
  62. root 1196 0.0 0.3 95412 3468 ? Ssl Feb06 0:00 NetworkManager --pid-file=/var/run/NetworkManager/NetworkManager.pid
  63. root 1202 0.0 0.1 55792 2000 ? S Feb06 0:00 /usr/sbin/modem-manager
  64. avahi 1212 0.0 0.1 27820 1392 ? S Feb06 0:00 avahi-daemon: running [linux.local]
  65. avahi 1213 0.0 0.0 27696 188 ? Ss Feb06 0:00 avahi-daemon: chroot helper
  66. root 1221 0.0 0.1 9064 1360 ? S Feb06 0:04 /sbin/dhclient -d -4 -sf /usr/libexec/nm-dhcp-client.action -pf /var/run/dhclient-eth3.pid -lf /var/lib/dhclient/dhclient-aacaa3a9-81be-441d-ba72-cec0c023b1f8-eth3.lease -cf /var/run/nm-dhclient-eth3.conf eth3
  67. root 1235 0.0 0.0 39232 388 ? Ss Feb06 0:00 /usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -B -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid
  68. rpcuser 1236 0.0 0.1 23088 1124 ? Ss Feb06 0:00 rpc.statd
  69. root 1251 0.0 0.0 4020 508 tty1 Ss+ Feb11 0:00 /sbin/mingetty /dev/tty1
  70. root 1280 0.0 0.0 0 0 ? S< Feb06 0:00 [rpciod]
  71. root 1287 0.0 0.0 27336 396 ? Ss Feb06 0:00 rpc.idmapd
  72. root 1297 0.0 0.2 178584 2840 ? Ss Feb06 0:00 cupsd -C /etc/cups/cupsd.conf
  73. root 1322 0.0 0.0 4036 604 ? Ss Feb06 0:00 /usr/sbin/acpid
  74. 68 1331 0.0 0.3 26184 3252 ? Ss Feb06 0:03 hald
  75. root 1332 0.0 0.1 18068 1136 ? S Feb06 0:00 hald-runner
  76. root 1375 0.0 0.0 20184 832 ? S Feb06 0:00 hald-addon-input: Listening on /dev/input/event0 /dev/input/event1
  77. root 1376 0.0 0.0 20180 856 ? S Feb06 0:18 hald-addon-storage: no polling on /dev/fd0 because it is explicitly disabled
  78. 68 1377 0.0 0.0 17760 988 ? S Feb06 0:00 hald-addon-acpi: listening on acpid socket /var/run/acpid.socket
  79. root 1380 0.0 0.0 20180 856 ? S Feb06 1:29 hald-addon-storage: polling /dev/sr0 (every 2 sec)
  80. root 1397 0.0 0.1 89180 1420 ? Ssl Feb06 0:00 pcscd
  81. root 1418 0.0 0.3 381500 3368 ? Ssl Feb06 0:38 automount --pid-file /var/run/autofs.pid
  82. root 1452 0.0 0.1 63804 1316 ? Ss Feb06 0:00 /usr/sbin/sshd
  83. root 1478 0.0 0.0 22020 880 ? Ss Feb06 0:00 xinetd -stayalive -pidfile /var/run/xinetd.pid
  84. root 1579 0.0 0.2 62020 2716 ? Ss Feb06 0:03 /usr/libexec/postfix/master
  85. postfix 1586 0.0 0.2 62168 2436 ? S Feb06 0:00 qmgr -l -t fifo -u
  86. root 1590 0.0 0.8 263516 8848 ? Ss Feb06 1:25 /usr/sbin/abrtd
  87. root 1604 0.0 0.0 108292 944 ? S Feb06 0:47 /bin/bash /usr/sbin/ksmtuned
  88. qpidd 1616 0.0 0.2 314868 3052 ? Ssl Feb06 0:27 /usr/sbin/qpidd --data-dir /var/lib/qpidd --daemon
  89. root 1646 0.0 0.1 117072 1324 ? Ss Feb06 0:06 crond
  90. root 1657 0.0 0.0 21360 156 ? Ss Feb06 0:00 /usr/sbin/atd
  91. root 1668 0.0 1.0 268400 10880 ? Sl Feb06 0:01 libvirtd --daemon
  92. root 1733 0.0 0.0 4020 504 tty2 Ss+ Feb06 0:00 /sbin/mingetty /dev/tty2
  93. root 1737 0.0 0.0 4020 508 tty3 Ss+ Feb06 0:00 /sbin/mingetty /dev/tty3
  94. root 1740 0.0 0.0 4020 504 tty4 Ss+ Feb06 0:00 /sbin/mingetty /dev/tty4
  95. root 1742 0.0 0.0 4020 504 tty5 Ss+ Feb06 0:00 /sbin/mingetty /dev/tty5
  96. root 1745 0.0 0.0 4020 500 tty6 Ss+ Feb06 0:00 /sbin/mingetty /dev/tty6
  97. nobody 1761 0.0 0.0 12840 564 ? S Feb06 0:00 /usr/sbin/dnsmasq --strict-order --bind-interfaces --pid-file=/var/run/libvirt/network/default.pid --conf-file= --listen-address 192.168.122.1 --except-interface lo --dhcp-range 192.168.122.2,192.168.122.254 --dhcp-lease-max=253 --dhcp-no-override
  98. root 1780 0.0 0.2 4111744 2592 ? Sl Feb06 0:00 /usr/sbin/console-kit-daemon --no-daemon
  99. root 1886 0.0 0.0 25536 704 ? S<sl Feb06 0:01 auditd
  100. root 14757 0.0 0.3 97484 3636 ? Ss 14:57 0:00 sshd: root@pts/0
  101. root 14761 0.0 0.1 108296 1832 pts/0 Ss 14:57 0:00 -bash
  102. root 14858 0.0 0.3 97484 3640 ? Ss 15:01 0:00 sshd: root@pts/1
  103. root 14862 0.0 0.1 108424 1868 pts/1 Ss+ 15:01 0:00 -bash
  104. root 14987 0.0 0.3 97484 3636 ? Ss 15:04 0:00 sshd: root@pts/2
  105. root 14991 0.0 0.1 108296 1680 pts/2 Ss+ 15:04 0:00 -bash
  106. root 15049 0.0 0.0 0 0 ? S 15:08 0:00 [kworker/1:0]
  107. postfix 15321 0.0 0.2 62100 2656 ? S 15:31 0:00 pickup -l -t fifo -u
  108. root 15401 0.1 0.0 0 0 ? S 15:38 0:01 [kworker/0:1]
  109. root 15518 0.0 0.0 0 0 ? S 15:48 0:00 [kworker/0:0]
  110. root 15556 0.0 0.0 0 0 ? S 15:50 0:00 [kworker/1:2]
  111. root 15582 0.0 0.0 0 0 ? S 15:53 0:00 [kworker/0:2]
  112. root 15727 0.0 0.0 0 0 ? S 16:03 0:00 [kworker/1:1]
  113. root 15791 0.0 0.0 100864 456 ? S 16:07 0:00 sleep 60
  114. root 15793 0.0 0.1 107968 1052 pts/0 R+ 16:07 0:00 ps aux
  115. root 25845 0.0 0.0 0 0 ? S Feb07 0:00 [jbd2/sdb1-8]
  116. root 25846 0.0 0.0 0 0 ? S< Feb07 0:00 [ext4-dio-unwrit]

sync_supers内核线程功能专一,用来同步操作系统当前挂载的各个文件系统的超级块数据,由于超级块对于文件系统的特殊性,所以这对保证文件系统的完整性至关重要。
在源文件mm/backing-dev.c内可以看到sync_supers内核线程的创建:

  1. static int __init default_bdi_init(void)
  2. {
  3. int err;
  4. sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers");
  5. BUG_ON(IS_ERR(sync_supers_tsk));
  6. setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
  7. bdi_arm_supers_timer();
  8. err = bdi_init(&default_backing_dev_info);
  9. if (!err)
  10. bdi_register(&default_backing_dev_info, NULL, "default");
  11. err = bdi_init(&noop_backing_dev_info);
  12. return err;
  13. }
  14. subsys_initcall(default_bdi_init);
  15. void bdi_arm_supers_timer(void)
  16. {
  17. unsigned long next;
  18. if (!dirty_writeback_interval)
  19. return;
  20. next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies;
  21. mod_timer(&sync_supers_timer, round_jiffies_up(next));
  22. }
  23. /*
  24. * The interval between `kupdate'-style writebacks
  25. */
  26. unsigned int dirty_writeback_interval = 5 * 100; /* centiseconds */

通过函数bdi_arm_supers_timer()设置定时器,默认每隔5秒唤醒sync_supers内核线程执行具体的操作函数sync_supers():

  1. /*
  2. * kupdated() used to do this. We cannot do it from the bdi_forker_thread()
  3. * or we risk deadlocking on ->s_umount. The longer term solution would be
  4. * to implement sync_supers_bdi() or similar and simply do it from the
  5. * bdi writeback thread individually.
  6. */
  7. static int bdi_sync_supers(void *unused)
  8. {
  9. set_user_nice(current, 0);
  10. while (!kthread_should_stop()) {
  11. set_current_state(TASK_INTERRUPTIBLE);
  12. schedule();
  13. /*
  14. * Do this periodically, like kupdated() did before.
  15. */
  16. sync_supers();
  17. }
  18. return 0;
  19. }
  20. /**
  21. * sync_supers - helper for periodic superblock writeback
  22. *
  23. * Call the write_super method if present on all dirty superblocks in
  24. * the system. This is for the periodic writeback used by most older
  25. * filesystems. For data integrity superblock writeback use
  26. * sync_filesystems() instead.
  27. *
  28. * Note: check the dirty flag before waiting, so we don't
  29. * hold up the sync while mounting a device. (The newly
  30. * mounted device won't need syncing.)
  31. */
  32. void sync_supers(void)
  33. {
  34. struct super_block *sb, *p = NULL;
  35. spin_lock(&sb_lock);
  36. list_for_each_entry(sb, &super_blocks, s_list) {
  37. if (list_empty(&sb->s_instances))
  38. continue;
  39. if (sb->s_op->write_super && sb->s_dirt) {
  40. sb->s_count++;
  41. spin_unlock(&sb_lock);
  42. down_read(&sb->s_umount);
  43. if (sb->s_root && sb->s_dirt)
  44. sb->s_op->write_super(sb);
  45. up_read(&sb->s_umount);
  46. spin_lock(&sb_lock);
  47. if (p)
  48. __put_super(p);
  49. p = sb;
  50. }
  51. }
  52. if (p)
  53. __put_super(p);
  54. spin_unlock(&sb_lock);
  55. }

sync_supers函数逻辑非常简单,遍历所有超级块(通过内核提供的全局链表super_blocks,这个全局链表保存了操作系统当前所有挂载文件系统的super_block实例),如果实例不存在则continue下一个,如果实例存在则接着判断同步回写函数write_super是否存在(有些文件系统,例如虚拟的文件系统或基于物理内存的文件系统并不需要进行同步操作,所以可以不提供回写函数write_super,典型示例就是/proc文件系统)以及超级块是否脏而需要进行同步。
各个需要进行超级块数据同步的文件系统都会提供适当的回写函数,比如ext4:

  1. static void ext4_write_super(struct super_block *sb)
  2. {
  3. lock_super(sb);
  4. ext4_commit_super(sb, 1);
  5. unlock_super(sb);
  6. }
  7. static int ext4_commit_super(struct super_block *sb, int sync)
  8. {
  9. struct ext4_super_block *es = EXT4_SB(sb)->s_es;
  10. struct buffer_head *sbh = EXT4_SB(sb)->s_sbh;
  11. int error = 0;
  12. if (!sbh)
  13. return error;
  14. if (buffer_write_io_error(sbh)) {
  15. /*
  16. * Oh, dear. A previous attempt to write the
  17. * superblock failed. This could happen because the
  18. * USB device was yanked out. Or it could happen to
  19. * be a transient write error and maybe the block will
  20. * be remapped. Nothing we can do but to retry the
  21. * write and hope for the best.
  22. */
  23. ext4_msg(sb, KERN_ERR, "previous I/O error to "
  24. "superblock detected");
  25. clear_buffer_write_io_error(sbh);
  26. set_buffer_uptodate(sbh);
  27. }
  28. /*
  29. * If the file system is mounted read-only, don't update the
  30. * superblock write time. This avoids updating the superblock
  31. * write time when we are mounting the root file system
  32. * read/only but we need to replay the journal; at that point,
  33. * for people who are east of GMT and who make their clock
  34. * tick in localtime for Windows bug-for-bug compatibility,
  35. * the clock is set in the future, and this will cause e2fsck
  36. * to complain and force a full file system check.
  37. */
  38. if (!(sb->s_flags & MS_RDONLY))
  39. es->s_wtime = cpu_to_le32(get_seconds());
  40. if (sb->s_bdev->bd_part)
  41. es->s_kbytes_written =
  42. cpu_to_le64(EXT4_SB(sb)->s_kbytes_written +
  43. ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
  44. EXT4_SB(sb)->s_sectors_written_start) >> 1));
  45. else
  46. es->s_kbytes_written =
  47. cpu_to_le64(EXT4_SB(sb)->s_kbytes_written);
  48. ext4_free_blocks_count_set(es, percpu_counter_sum_positive(
  49. &EXT4_SB(sb)->s_freeblocks_counter));
  50. es->s_free_inodes_count =
  51. cpu_to_le32(percpu_counter_sum_positive(
  52. &EXT4_SB(sb)->s_freeinodes_counter));
  53. sb->s_dirt = 0;
  54. BUFFER_TRACE(sbh, "marking dirty");
  55. mark_buffer_dirty(sbh);
  56. if (sync) {
  57. error = sync_dirty_buffer(sbh);
  58. if (error)
  59. return error;
  60. error = buffer_write_io_error(sbh);
  61. if (error) {
  62. ext4_msg(sb, KERN_ERR, "I/O error while writing "
  63. "superblock");
  64. clear_buffer_write_io_error(sbh);
  65. set_buffer_uptodate(sbh);
  66. }
  67. }
  68. return error;
  69. }
  70. int sync_dirty_buffer(struct buffer_head *bh)
  71. {
  72. return __sync_dirty_buffer(bh, WRITE_SYNC);
  73. }
  74. EXPORT_SYMBOL(sync_dirty_buffer);

转载请保留地址:http://lenky.info/2012/02/15/linux%e5%86%85%e6%a0%b8%e8%bf%9b%e7%a8%8b%e8%af%a6%e8%a7%a3%e4%b9%8b%e4%b8%80%ef%bc%9async_supers/http://lenky.info/?p=1095


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/969025
推荐阅读
相关标签
  

闽ICP备14008679号