การสังเกตการเขียนฮาร์ดดิสก์ในพื้นที่เคอร์เนล (พร้อมไดรเวอร์ / โมดูล)


13

ขออภัยล่วงหน้าหากโพสต์นี้ค่อนข้างหนาแน่น / ยุ่ง แต่ฉันมีเวลายากที่จะกำหนดได้ดีกว่า ... โดยทั่วไปฉันต้องการที่จะศึกษาว่าเกิดอะไรขึ้นกับการเขียนฮาร์ดดิสก์และฉันต้องการที่จะรู้ว่า:

  • ความเข้าใจของฉันด้านล่างถูกต้องหรือไม่ถ้าไม่ฉันจะไปไหนผิด
  • มีเครื่องมือที่ดีกว่าในการ "บันทึก" บันทึกข้อมูลเกี่ยวกับทุกด้านที่เกิดขึ้นบนพีซีระหว่างการเขียนดิสก์หรือไม่?

รายละเอียดเพิ่มเติม - ก่อนอื่นระบบปฏิบัติการที่ฉันใช้คือ:

$ uname -a
Linux mypc 2.6.38-16-generic #67-Ubuntu SMP Thu Sep 6 18:00:43 UTC 2012 i686 i686 i386 GNU/Linux

ดังนั้นฉันมีดังต่อไปนี้ง่าย ๆ (เช่นการตรวจสอบตามปกติสำหรับความล้มเหลวของการดำเนินงานจะถูกข้าม) โปรแกรม C พื้นที่ผู้ใช้wtest.c:

#include <stdio.h>
#include <fcntl.h>  // O_CREAT, O_WRONLY, S_IRUSR

int main(void) {
  char filename[] = "/tmp/wtest.txt";
  char buffer[] = "abcd";
  int fd;
  mode_t perms = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;

  fd = open(filename, O_RDWR|O_CREAT, perms);
  write(fd,buffer,4);
  close(fd);

  return 0;
}

gcc -g -O0 -o wtest wtest.cฉันสร้างนี้กับ ตอนนี้เนื่องจากฉันพยายามเขียนถึง/tmpฉันทราบว่ามันเป็นไดเรกทอรีภายใต้ราก/- ดังนั้นฉันตรวจสอบmount:

$ mount
/dev/sda5 on / type ext4 (rw,errors=remount-ro,commit=0)
...
/dev/sda6 on /media/disk1 type ext4 (rw,uhelper=hal,commit=0)
/dev/sda7 on /media/disk2 type ext3 (rw,nosuid,nodev,uhelper=udisks,commit=0,commit=0,commit=0,commit=0,commit=0,commit=0)
...

ดังนั้นระบบไฟล์รูทของฉัน/คือหนึ่งพาร์ติชั่นของ/dev/sdaอุปกรณ์ (และฉันใช้พาร์ติชั่นอื่นเป็นดิสก์ "สแตนด์อะโลน" / mounts ด้วย) ในการค้นหาไดรเวอร์สำหรับอุปกรณ์นี้ฉันใช้hwinfo:

$ hwinfo --disk
...
19: IDE 00.0: 10600 Disk
...
  SysFS ID: /class/block/sda
  SysFS BusID: 0:0:0:0
...
  Hardware Class: disk
  Model: "FUJITSU MHY225RB"
...
  Driver: "ata_piix", "sd"
  Driver Modules: "ata_piix"
  Device File: /dev/sda
...
  Device Number: block 8:0-8:15
...

ดังนั้นจึง/dev/sdaเห็นได้ชัดว่าฮาร์ดดิสก์ถูกจัดการโดยata_piix(และsd) ไดรเวอร์

$ grep 'ata_piix\| sd' <(gunzip </var/log/syslog.2.gz)
Jan 20 09:28:31 mypc kernel: [    1.963846] ata_piix 0000:00:1f.2: version 2.13
Jan 20 09:28:31 mypc kernel: [    1.963901] ata_piix 0000:00:1f.2: PCI INT B -> GSI 19 (level, low) -> IRQ 19
Jan 20 09:28:31 mypc kernel: [    1.963912] ata_piix 0000:00:1f.2: MAP [ P0 P2 P1 P3 ]
Jan 20 09:28:31 mypc kernel: [    2.116038] ata_piix 0000:00:1f.2: setting latency timer to 64
Jan 20 09:28:31 mypc kernel: [    2.116817] scsi0 : ata_piix
Jan 20 09:28:31 mypc kernel: [    2.117068] scsi1 : ata_piix
Jan 20 09:28:31 mypc kernel: [    2.529065] sd 0:0:0:0: [sda] 488397168 512-byte logical blocks: (250 GB/232 GiB)
Jan 20 09:28:31 mypc kernel: [    2.529104] sd 0:0:0:0: Attached scsi generic sg0 type 0
Jan 20 09:28:31 mypc kernel: [    2.529309] sd 0:0:0:0: [sda] Write Protect is off
Jan 20 09:28:31 mypc kernel: [    2.529319] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
Jan 20 09:28:31 mypc kernel: [    2.529423] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
Jan 20 09:28:31 mypc kernel: [    2.674783]  sda: sda1 sda2 < sda5 sda6 sda7 sda8 sda9 sda10 >
Jan 20 09:28:31 mypc kernel: [    2.676075] sd 0:0:0:0: [sda] Attached SCSI disk
Jan 20 09:28:31 mypc kernel: [    4.145312] sd 2:0:0:0: Attached scsi generic sg1 type 0
Jan 20 09:28:31 mypc kernel: [    4.150596] sd 2:0:0:0: [sdb] Attached SCSI removable disk

ฉันต้องดึงออกจาก syslog รุ่นเก่าในขณะที่ฉันพักการทำงานเยอะ แต่ข้างบนดูเหมือนว่าตัวอย่างที่เหมาะสมจาก syslog ตอนบูตซึ่งผู้ขับata_piix(และsd) เตะเป็นครั้งแรก

จุดสับสนแรกของฉันคือฉันไม่สามารถสังเกตata_piixหรือsdไดรเวอร์:

$ lsmod | grep 'ata_piix\| sd'
$
$ modinfo sd
ERROR: modinfo: could not find module sd
$ modinfo ata_piix
ERROR: modinfo: could not find module ata_piix

ดังนั้นคำถามแรกของฉันคือ - ทำไมฉันไม่สามารถสังเกตata_piixโมดูลที่นี่เฉพาะในบันทึกเวลาบูต? เป็นเพราะata_piix(และsd) ถูกสร้างขึ้นเป็นไดรเวอร์ในตัวในเคอร์เนล (เสาหิน) เมื่อเทียบกับการสร้างเป็นโมดูล.koเคอร์เนล(โหลดได้) ?

ถูกต้อง - ตอนนี้ฉันกำลังพยายามสังเกตสิ่งที่เกิดขึ้นเมื่อใช้งานโปรแกรมด้วยftraceฟังก์ชันติดตามตัวใน Linux

sudo bash -c '
KDBGPATH="/sys/kernel/debug/tracing"
echo function_graph > $KDBGPATH/current_tracer
echo funcgraph-abstime > $KDBGPATH/trace_options
echo funcgraph-proc > $KDBGPATH/trace_options
echo 0 > $KDBGPATH/tracing_on
echo > $KDBGPATH/trace
echo 1 > $KDBGPATH/tracing_on ; ./wtest ; echo 0 > $KDBGPATH/tracing_on
cat $KDBGPATH/trace > wtest.ftrace
'

... และนี่คือตัวอย่างของftraceบันทึกที่เกี่ยวข้องกับwrite:

4604.352690 | 0) wtest-31632 | | sys_write () {
 4604.352690 | 0) wtest-31632 | 0.750 เรา | fget_light ();
 4604.352692 | 0) wtest-31632 | | vfs_write () {
 4604.352693 | 0) wtest-31632 | | rw_verify_area () {
 4604.352693 | 0) wtest-31632 | | security_file_permission () {
 4604.352694 | 0) wtest-31632 | | apparmor_file_permission () {
 4604.352695 | 0) wtest-31632 | 0.811 เรา | common_file_perm ();
 4604.352696 | 0) wtest-31632 | 2.198 เรา | }
 4604.352697 | 0) wtest-31632 | 3.573 เรา | }
 4604.352697 | 0) wtest-31632 | 4.979 เรา | }
 4604.352698 | 0) wtest-31632 | | do_sync_write () {
 4604.352699 | 0) wtest-31632 | | ext4_file_write () {
 4604.352700 | 0) wtest-31632 | | generic_file_aio_write () {
 4604.352701 | 0) wtest-31632 | | mutex_lock () {
 4604.352701 | 0) wtest-31632 | 0.666 เรา | _cond_resched ();
 4604.352703 | 0) wtest-31632 | 1.994 เรา | }
 4604.352704 | 0) wtest-31632 | | __generic_file_aio_write () {
...
 4604.352728 | 0) wtest-31632 | | file_update_time () {
...
 4604.352732 | 0) wtest-31632 | 0.756 เรา | mnt_want_write_file ();
 4604.352734 | 0) wtest-31632 | | __mark_inode_dirty () {
...
 4604.352750 | 0) wtest-31632 | | ext4_mark_inode_dirty () {
 4604.352750 | 0) wtest-31632 | 0.679 เรา | _cond_resched ();
 4604.352752 | 0) wtest-31632 | | ext4_reserve_inode_write () {
...
 4604.352777 | 0) wtest-31632 | | __ext4_journal_get_write_access () {
...
 4604.352795 | 0) wtest-31632 | | ext4_mark_iloc_dirty () {
...
 4604.352806 | 0) wtest-31632 | | __ext4_journal_stop () {
...
 4604.352821 | 0) wtest-31632 | 0.684 เรา | mnt_drop_write ();
 4604.352822 | 0) wtest-31632 | + 93.541 เรา | }
 4604.352823 | 0) wtest-31632 | | generic_file_buffered_write () {
 4604.352824 | 0) wtest-31632 | 0.654 เรา | iov_iter_advance ();
 4604.352825 | 0) wtest-31632 | | generic_perform_write () {
 4604.352826 | 0) wtest-31632 | 0.709 เรา | iov_iter_fault_in_readable ();
 4604.352828 | 0) wtest-31632 | | ext4_da_write_begin () {
 4604.352829 | 0) wtest-31632 | | ext4_journal_start_sb () {
...
 4604.352847 | 0) wtest-31632 | 1.453 เรา | __block_write_begin ();
 4604.352849 | 0) wtest-31632 | + 21.128 เรา | }
 4604.352849 | 0) wtest-31632 | | iov_iter_copy_from_user_atomic () {
 4604.352850 | 0) wtest-31632 | | __kmap_atomic () {
...
 4604.352863 | 0) wtest-31632 | 0.672 เรา | mark_page_accessed ();
 4604.352864 | 0) wtest-31632 | | ext4_da_write_end () {
 4604.352865 | 0) wtest-31632 | | generic_write_end () {
 4604.352866 | 0) wtest-31632 | | block_write_end () {
...
 4604.352893 | 0) wtest-31632 | | __ext4_journal_stop () {
...
 4604.352909 | 0) wtest-31632 | 0.655 เรา | mutex_unlock ();
 4604.352911 | 0) wtest-31632 | 0.727 เรา | generic_write_sync ();
 4604.352912 | 0) wtest-31632 | ! 212.259 เรา | }
 4604.352913 | 0) wtest-31632 | ! 213.845 เรา | }
 4604.352914 | 0) wtest-31632 | ! 215.286 เรา | }
 4604.352914 | 0) wtest-31632 | 0.685 เรา | __fsnotify_parent ();
 4604.352916 | 0) wtest-31632 | | fsnotify () {
 4604.352916 | 0) wtest-31632 | 0.907 เรา | __srcu_read_lock ();
 4604.352918 | 0) wtest-31632 | 0.685 เรา | __srcu_read_unlock ();
 4604.352920 | 0) wtest-31632 | 3.958 เรา | }
 4604.352920 | 0) wtest-31632 | ! 228.409 เรา | }
 4604.352921 | 0) wtest-31632 | ! 231.334 เรา | }

นี่เป็นจุดที่สองของฉันสับสน - ฉันสามารถสังเกตพื้นที่ผู้ใช้ที่write()เกิดกับเคอร์เนลพื้นที่sys_write()ตามที่คาดไว้ และภายในsys_write(), ฉันสังเกตเห็นฟังก์ชั่นที่เกี่ยวข้องกับความปลอดภัย (เช่นapparmor_file_permission()), ฟังก์ชั่นการเขียน "ทั่วไป" (เช่นgeneric_file_aio_write()), ext4ฟังก์ชั่นที่เกี่ยวข้องกับระบบไฟล์ (เช่นext4_journal_start_sb()) - แต่ฉันไม่ได้สังเกตสิ่งที่เกี่ยวข้องกับไดรเวอร์ata_piix(หรือsd)!

หน้าการติดตามและการทำโปรไฟล์ - โครงการ Yoctoแนะนำให้ใช้blkตัวติดตามftraceเพื่อรับข้อมูลเพิ่มเติมเกี่ยวกับการทำงานของอุปกรณ์บล็อก แต่จะไม่มีการรายงานอะไรสำหรับฉันด้วยตัวอย่างนี้ นอกจากนี้ไดรเวอร์ระบบไฟล์ Linux - Annon Inglorion (tutorfs)แสดงให้เห็นว่าระบบไฟล์นั้นสามารถทำได้ (สามารถ) นำไปใช้เป็นเคอร์เนลโมดูล / ไดรเวอร์และฉันเดาว่าเป็นext4เช่นนั้น

ในที่สุดฉันอาจสาบานได้ว่าก่อนหน้านี้ฉันสังเกตเห็นชื่อคนขับในวงเล็บเหลี่ยมถัดจากฟังก์ชั่นที่แสดงโดยผู้function_graphติดตาม แต่ฉันเดาว่าฉันมีสิ่งต่าง ๆ ปะปนอยู่ - มันอาจจะดูเหมือนว่าในร่องรอยกอง (ด้านหลัง) แต่ไม่ใช่ ในกราฟฟังก์ชั่น นอกจากนี้ฉันสามารถตรวจสอบ/proc/kallsyms:

$ grep 'piix\| sd\|psmouse' /proc/kallsyms
...
00000000 d sd_ctl_dir
00000000 d sd_ctl_root
00000000 d sdev_class
00000000 d sdev_attr_queue_depth_rw
00000000 d sdev_attr_queue_ramp_up_period
00000000 d sdev_attr_queue_type_rw
00000000 d sd_disk_class
...
00000000 t piix_init_sata_map
00000000 t piix_init_sidpr
00000000 t piix_init_one
00000000 t pci_fixup_piix4_acpi
...
00000000 t psmouse_show_int_attr        [psmouse]
00000000 t psmouse_protocol_by_type     [psmouse]
00000000 r psmouse_protocols    [psmouse]
00000000 t psmouse_get_maxproto [psmouse]
...

... และการตรวจสอบกับแหล่งที่มาของลินุกซ์ / ไดรเวอร์ / ATA / ata_piix.cยืนยันว่าเช่นย่อมเป็นฟังก์ชั่นในpiix_init_sata_map ata_piixซึ่งน่าจะบอกฉันได้ว่า: โมดูลที่รวบรวมในเคอร์เนล (ดังนั้นพวกเขากลายเป็นส่วนหนึ่งของเคอร์เนลเสาหิน) "เสีย" ข้อมูลเกี่ยวกับโมดูลที่พวกเขามาจาก; อย่างไรก็ตามโมดูลที่โหลดได้ซึ่งสร้างขึ้นเป็น.koวัตถุเคอร์เนลแยกต่างหากเก็บรักษาข้อมูลนั้น (เช่น[psmouse]แสดงไว้ข้างต้นในวงเล็บเหลี่ยม) ดังนั้นยังftraceสามารถแสดงข้อมูล "โมดูลต้นทาง" เท่านั้นสำหรับฟังก์ชันเหล่านั้นที่มาจากโมดูลเคอร์เนลที่โหลดได้ ถูกต้องหรือไม่

การพิจารณาข้างต้นนี้เป็นความเข้าใจที่ฉันมีของกระบวนการปัจจุบัน:

  • เมื่อถึงเวลาบูตata_piixไดรเวอร์จะสร้างการแมปหน่วยความจำ DMA (?) ระหว่าง/dev/sdaและฮาร์ดดิสก์
    • ด้วยเหตุนี้การเข้าถึง/dev/sdaผ่านทางอนาคตทั้งหมดata_piixจะทำให้เคอร์เนลโปร่งใส (นั่นคือไม่สามารถติดตามได้) - เนื่องจากเคอร์เนลทั้งหมดจะเห็นเพียงแค่อ่าน / เขียนไปยังตำแหน่งหน่วยความจำ (ไม่จำเป็นต้องเรียกใช้ฟังก์ชันเคอร์เนลที่ตรวจสอบย้อนกลับได้) ซึ่ง จะไม่ถูกรายงานโดยผู้function_graphติดตาม
  • ในเวลาบูตsdไดรเวอร์จะ "แยกวิเคราะห์" พาร์ติชัน/dev/sdaให้พร้อมใช้งานและอาจจัดการการแมปหน่วยความจำระหว่างพาร์ติชัน <-> อุปกรณ์ดิสก์
    • อีกครั้งนี้จะทำให้การดำเนินการเข้าถึงผ่านsdโปร่งใสให้เคอร์เนล
  • เนื่องจากทั้งคู่ata_piixและsdรวบรวมในเคอร์เนลแม้ว่าฟังก์ชั่นบางฟังก์ชั่นของพวกเขาจะถูกจับโดยftraceเราไม่สามารถรับข้อมูลที่โมดูลฟังก์ชั่นเหล่านั้นจะมาจาก (นอกเหนือจากความสัมพันธ์ "คู่มือ" กับไฟล์ต้นฉบับ)
  • ในภายหลังmountสร้างความสัมพันธ์ / การเชื่อมโยงระหว่างพาร์ติชันและโปรแกรมควบคุมระบบแฟ้มที่เกี่ยวข้อง(ในกรณีนี้ext4)
    • จากจุดนี้เป็นต้นไปการเข้าถึงระบบไฟล์ที่เมาท์ทั้งหมดจะถูกจัดการโดยext4ฟังก์ชั่น - ซึ่งสามารถติดตามได้โดยเคอร์เนล แต่ดังที่ext4คอมไพล์ในเคอร์เนลตัวติดตามไม่สามารถให้ข้อมูลโมดูลที่มากับเราได้
  • ดังนั้นการเขียน "ทั่วไป" ที่ถูกเรียกใช้ผ่านext4ฟังก์ชั่นในที่สุดจะเข้าถึงตำแหน่งหน่วยความจำซึ่งการแม็พถูกสร้างโดยata_piix- แต่นอกเหนือจากนั้นata_piixจะไม่รบกวนโดยตรงกับการถ่ายโอนข้อมูล (อาจถูกจัดการโดย DMA (ภายนอกโปรเซสเซอร์) (s) และทำให้โปร่งใสกับมัน)

ความเข้าใจนี้ถูกต้องหรือไม่

คำถามย่อยที่เกี่ยวข้อง:

  • ในการตั้งค่าของฉันด้านบนฉันสามารถระบุไดรเวอร์อุปกรณ์ PCI ( ata_piix) และไดรเวอร์ระบบไฟล์ ( ext4); แต่มีไดรเวอร์อักขระหรือบล็อกที่ใช้บางแห่งในเส้นทางการดำเนินการ "เขียน" และหากเป็นเช่นนั้น
  • ไดรเวอร์ใดบ้างที่จะจัดการกับแคช (ดังนั้นการดำเนินการของดิสก์ที่ไม่จำเป็นถูกข้ามหรือปรับให้เหมาะสม)
  • ฉันรู้ก่อนหน้า/dev/shmนี้ว่าเป็นระบบไฟล์ใน RAM; mount | grep shmสำหรับฉันรายงาน: none on /dev/shm type tmpfs (rw,nosuid,nodev). นั่นหมายความว่า - ตรงกันข้ามกับ/dev/sda- shmระบบไฟล์เพียงขาดการแมป (DMA) จากที่อยู่ "ของตัวเอง" ไปยังที่อยู่บัสไปยังอุปกรณ์ และทำให้ทุกการเข้าถึงผ่านทางtmpfsไดรเวอร์ระบบไฟล์ท้ายใน RAM จริง?

4
สวัสดี sdaau นี่เป็นคำถามที่ดี แต่ความยาวของโพสต์นี้มากเกินไปและมีคำถามมากมายในนั้น น่ายกย่องว่าคุณกำลังพยายามทำความเข้าใจกับสิ่งต่าง ๆ มากกว่าแค่ถามคำถามแผนกช่วยเหลือซึ่งเป็นสิ่งที่เราได้รับที่นี่เป็นส่วนใหญ่ คำถามแต่ละข้อเหล่านี้น่าจะได้คำตอบยาว ๆ ด้วยตัวเอง ฉันแนะนำอย่างน้อยให้แบ่งโพสต์ของคุณออกเป็นส่วน ๆ ที่กำหนดไว้อย่างชัดเจนและวางแต่ละคำถามแยกต่างหากดังนั้นสร้างคำถามหลายข้อ
Faheem Mitha

จากนั้นคุณสามารถโพสต์คำถามเหล่านี้เข้าด้วยกันหรือตามลำดับ ฉันคิดว่าถ้าคุณอ้างอิงคำถามอื่น (หรือคำถาม) ภายในคำถาม
Faheem Mitha

1
หากคุณต้องการเคล็ดลับในการทำความสะอาดคำถามของคุณฉันขอแนะนำให้คุณกระโดดเข้าไปในห้องสนทนาและพูดคุยกับผู้คนที่นั่น เราได้พูดถึงมันที่นี่แล้ว :-)
Faheem Mitha

ขอบคุณมากสำหรับความคิดเห็น @FaheemMitha - ฉันยังมีข้อสงสัยคล้ายกัน แต่ฉันไม่แน่ใจจริงๆว่าจะตัดคำถามได้อย่างไร - และไม่รู้ตัวจนกระทั่งตอนนี้ฉันสามารถใช้แชทได้เลย (และฉันไม่กระตือรือร้น ใช้เมตาสำหรับถามเกี่ยวกับคำแนะนำประเภทนั้น); จะลองใช้การแชทในครั้งต่อไป โชคดีที่ครั้งนี้ได้ผลตอบรับที่ดีมาก ... ไชโย!
sdaau

@sdaau คุณทราบวิธีการตรวจสอบการเข้าถึงดิสก์หรือไม่
ransh

คำตอบ:


10

คุณได้ถามคำถามมากเกินไป - ในทางเทคนิคแล้วฉันคิดว่า "ความเข้าใจนี้ถูกต้อง" หรือไม่สามารถตอบได้อย่างรวดเร็ว: ไม่ แต่นั่นไม่ใช่คำตอบที่มีประโยชน์

ก่อนอื่นคุณพูดถูกata_piixและsd_modคอมไพล์อินเคอร์เนลของคุณ นั่นเป็นตัวเลือกที่คุณเลือกกำหนดค่าเคอร์เนล - คุณสามารถละเว้นรวมหรือรวมเป็นโมดูลได้ (เหมือนกับ ext4)

ประการที่สองคุณถือว่าการเขียนนั้นง่ายกว่าที่เป็นจริง โครงร่างพื้นฐานของวิธีการทำงานของการเขียนคือรหัสระบบไฟล์ทำให้ข้อมูลถูกเขียนในหน่วยความจำซึ่งเป็นส่วนหนึ่งของบัฟเฟอร์แคชและทำเครื่องหมายว่าต้องการเขียน ("สกปรก") (เว้นเสียแต่ว่ามีแรมอยู่ใน RAM มากเกินไปซึ่งในกรณีนี้มันถูกบังคับให้ต้องเขียน ... )

หลังจากนั้นสิ่งต่าง ๆ (เช่นbdflushเคอร์เนลเธรด) จะล้างข้อมูลสกปรกในดิสก์ นี่คือเมื่อคุณเห็นการโทรผ่าน sd, scsi, libata, ata_piix, io schedulers, PCI และอื่น ๆ ในขณะที่มี DMA น่าจะเกี่ยวข้องกับการตัดออกนั้นเป็นข้อมูลที่จะถ่ายโอนและอาจเป็นคำสั่ง แต่การเขียนดิสก์อย่างน้อยที่สุดใน SATA จะได้รับการจัดการโดยการส่งคำสั่งซึ่งโดยทั่วไปหมายถึง "การเขียนเซกเตอร์ X พร้อมข้อมูล Y" แต่ไม่ได้จัดการโดยการแมปหน่วยความจำทั้งดิสก์ (พิจารณา: คุณสามารถใช้ดิสก์ที่มีขนาดใหญ่กว่า 4GiB บนเครื่อง 32- บิต)

การแคชถูกจัดการโดยระบบย่อยการจัดการหน่วยความจำ (ไม่ใช่ไดรเวอร์) ร่วมกับระบบไฟล์, เลเยอร์บล็อก ฯลฯ

tmpfsเป็นพิเศษมันเป็นพื้นแคชทั้งหมด แคชพิเศษเพียงอย่างเดียวที่ไม่เคยทิ้งหรือเขียนกลับมา (แม้ว่าจะสามารถสลับออกได้) คุณสามารถค้นหารหัสในmm/shmem.cและที่อื่น ๆ (ลองack-grep --cc CONFIG_TMPFSค้นหา)

โดยทั่วไปการเขียนลงดิสก์จะผ่านส่วนย่อยที่ดีของระบบย่อยของเคอร์เนล การสร้างเครือข่ายเป็นสิ่งสำคัญอย่างเดียวที่ฉันสามารถนึกได้ว่านั่นไม่ได้เกี่ยวข้องกับตัวอย่างของคุณ การอธิบายอย่างถูกต้องต้องใช้ความยาวหนังสือ ฉันแนะนำให้มองหาหนึ่ง


สวัสดี @derobert - ขอบคุณมากสำหรับคำตอบของคุณ; มันมีข้อมูลประเภทที่แน่นอนที่ฉันหายไป! ตอนแรกฉันเริ่มต้นด้วยการมองหาภาพประกอบอย่างง่ายของผู้ใช้เทียบกับเนื้อที่เคอร์เนล แต่ฉันรู้ทันทีว่าการเขียนฮาร์ดดิสก์ไม่ใช่สิ่งที่ฉันเข้าใจอย่างถ่องแท้และไม่ใช่เรื่องเล็กน้อย - ขอบคุณสำหรับการยืนยันว่าเป็นหนังสือ ความพยายามยาว! ไชโย!
sdaau

บันทึกย่อขนาดเล็ก: คำอธิบายบางอย่างในคำตอบนี้ (เช่นหน้ากระดาษสกปรก) จะสามารถสังเกตได้ถ้าในsudo bash...สคริปต์ใน OP: หน่วยความจำ ftrace เพิ่มขึ้น ( echo 8192 > $KDBGPATH/buffer_size_kb); และsync ;ถูกเพิ่มหลังจากการ./wtest ;โทร แล้วฉันสามารถดูflush-8, kworker(ใต้kthreaddในps axf) และsyncตัวเองเป็นกระบวนการในftraceการเรียกฟังก์ชั่นเหมือนเช่นata_bmdma_setup()(ซึ่งเป็นส่วนหนึ่งของlibataที่ata_piixสร้างขึ้นบน) get_nr_dirty_inodes()หรือ
sdaau

4

ดังนั้นคำถามแรกของฉันคือ - ทำไมฉันไม่สามารถสังเกตโมดูล ata_piix ที่นี่เฉพาะในบันทึกเวลาบูต? เป็นเพราะ ata_piix (และ sd) ถูกสร้างขึ้นเป็นไดรเวอร์ในตัวในเคอร์เนล (เสาหิน) เมื่อเทียบกับการสร้างเป็น (โหลดได้) โมดูลเคอร์เนล. ko?

คุณไม่ต้องเดาว่าการกำหนดค่าของคุณคืออะไร บนเครื่องของฉันฉันมี

$ uname -a
Linux orwell 3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64 GNU/Linux

/boot/config-3.2.0-4-amd64แฟ้มปรับแต่งสำหรับเคอร์เนลนี้ตั้งอยู่ที่

ata_piixคุณถามเกี่ยวกับ ค้นหาข้างต้นไฟล์ที่เราเห็น.config CONFIG_ATA_PIIX=mเราสามารถยืนยันสิ่งนี้ได้โดยการทำ

dlocate ata_piix.ko   

อีกทางเลือกหนึ่ง

dpkg -S ata_piix.ko

linux-image-3.2.0-4-amd64: /lib/modules/3.2.0-4-amd64/kernel/drivers/ata/ata_piix.ko

อย่างน้อยในเคอร์เนลของฉันมันเป็นโมดูล


ขอบคุณมากสำหรับสิ่งนั้น @FaheemMitha - ในขณะที่ฉันเคยได้ยิน (และใช้) ไฟล์ปรับแต่งก่อนหน้านี้ด้วยเหตุผลบางอย่างที่ฉันลืมไปแล้วในตัวอย่างนี้ เห็นเป็นอย่างดี! :)ในระบบของฉันgrep ATA_PIIX /boot/config-2.6.38-16-genericพูดว่าCONFIG_ATA_PIIX=yซึ่งน่าจะมีความหมายในเคอร์เนลนี้ata_piixคือการสร้าง "ในเคอร์เนล" และไม่เป็นโมดูล ไชโย!
sdaau
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.