Skip to content

Latest commit

 

History

History
100 lines (84 loc) · 3.21 KB

md-moduleioctl-runarray.md

File metadata and controls

100 lines (84 loc) · 3.21 KB

ioctl-RUN_ARRAY

RUN_ARRAY는 드디어 md 디스크를 생성하는 명령입니다. do_md_run함수가 처리합니다.

static int md_ioctl(struct block_device *bdev, fmode_t mode,
            unsigned int cmd, unsigned long arg)
{
......
    case RUN_ARRAY:
        err = do_md_run(mddev);
        goto unlock;

do_md_run

  • call md_run()
  • set disk size at mddev->gendisk
  • revalidate_disk
    • md_alloc(): gendisk->fops = md_fops
    • disk->fops->revalidate_disk = md_revalidate
    • check_disk_size_change(): print message "md100: detected capacity change from 0 to 104726528"
  • throw uevent KBOJ_CHANGE for user-level event handler

md_run

do_md_run에서 첫번째로 호출하는 함수는 md_run입니다. md_run은 다음과 같은 일을 합니다.

  • mddev->disks 리스트에 아무런 장치가 없으면 -EINVAL 반환
  • mddev->pers, mddev->sysfs_active 값이 0이 아니면 새로 생성되는 디스크가 아니므로 -EBUSY 반환
  • analyze_sbs 호출: mddev에 연결된 md_rdev 디스크들의 슈퍼블럭을 읽어서 정상적인 슈퍼블럭인지 확인
  • pers = &raid1_personality
  • pers->run = run() in raid1.c
    • setup_conf() creates conf object
      • conf->mirrors[0].rdev: pointer to md_rdev of /dev/vda
      • conf->mirrors[1].rdev: pointer to md_rdev of /dev/vdb
      • conf->mirrors[2,3]: for replacement, in case when vda or vdb is faulty
      • conf object keeps information of raid-disks
    • "md/raid1:md100: active with 2 out of 2 mirrors\n"
      • md100: device file name
      • 2 out of: mddev->raid_disks - mddev->degraded, if all devices are clean
      • 2 mirrors: mddev->raid_disks, the number of all raid-disks
    • mddev->thread = conf->thread: md100_raid1 thread
      • run raid1d() function
        • call md_check_recovery(): check MD_RECOVERY_NEEDED bit and do recovery or resync
      • this thread is not started yet, will start after md_run() is finished
        • see do_md_run(): md_wakeup_thread(mddev->thread)
      • We will look into what raid1d() does in later chapter
    • mddev->private = conf
  • mddev->in_sync = 1
  • mddev->pers = pers;
  • mddev->ready = 1
  • set MD_RECOVORY_NEEDED bit at mddev->recovery
    • comment in md.h: NEEDED: we might need to start a resync/recover
    • After creating md, md100_raid1 thread will start resync

struct md_personality

md_run:

  • mddev->level = 1
	pers = find_pers(mddev->level, mddev->clevel);

raid1.c:

  • raid1.ko is a module to support RAID-1
  • If that module does not exist or is not loaded, find_pers would fails and md module results "md: personality for level %d is not loaded!" error.
static struct md_personality raid1_personality =
{
	.name		= "raid1",
	.level		= 1,
	.owner		= THIS_MODULE,
	.make_request	= make_request,
	.run		= run,
	.free		= raid1_free,
	.status		= status,
	.error_handler	= error,
	.hot_add_disk	= raid1_add_disk,
	.hot_remove_disk= raid1_remove_disk,
	.spare_active	= raid1_spare_active,
	.sync_request	= sync_request,
	.resize		= raid1_resize,
	.size		= raid1_size,
	.check_reshape	= raid1_reshape,
	.quiesce	= raid1_quiesce,
	.takeover	= raid1_takeover,
	.congested	= raid1_congested,
};

static int __init raid_init(void)
{
	return register_md_personality(&raid1_personality);
}