日期:2014-05-16 浏览次数:21228 次
?
?了解分布式存储的朋友 一定知道 lvm2 , PV LV VG等 ,简单看看lvm2是如何和内核交互的,为下一步开发自己的lvm 做准备
?
?
首先看 lvcreate 的调用走向 ?希望你自己摸索过lvm 也熟悉vfs ,fs子系统 ,这样可以一看就知道什么意思,然后大家一起交流。
?
lvm: dev_manager.c
?
?
/*
* Add LV and any known dependencies
*/
static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, struct logical_volume *lv)
{
//...
if (!_add_dev_to_dtree(dm, dtree, lv, NULL))
return_0;
//...
return 1;
}
?_add_dev_to_dtree ---》int _info() ---》 dm_task_run()
?
然后就是 dm 库
?
?
int dm_task_run(struct dm_task *dmt)
{
repeat_ioctl:/*关键就是这个*/
if (!(dmi = _do_dm_ioctl(dmt, command, _ioctl_buffer_double_factor)))
return 0;
if (dmi->flags & DM_BUFFER_FULL_FLAG) {
switch (dmt->type) {
case DM_DEVICE_LIST_VERSIONS:
case DM_DEVICE_LIST:
case DM_DEVICE_DEPS:
case DM_DEVICE_STATUS:
case DM_DEVICE_TABLE:
case DM_DEVICE_WAITEVENT:
_ioctl_buffer_double_factor++;
dm_free(dmi);
goto repeat_ioctl;/*这里其实是在循环决定操作*/
default:
log_error("WARNING: libdevmapper buffer too small for data");
}
//...
}
?
?
?
?
static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
unsigned repeat_count)
{
struct dm_ioctl *dmi;
dmi = _flatten(dmt, repeat_count);/*dm_task结构字段合法性检查*/
if (!dmi) {
log_error("Couldn't create ioctl argument.");
return NULL;
}
if (dmt->type == DM_DEVICE_TABLE)
dmi->flags |= DM_STATUS_TABLE_FLAG;
dmi->flags |= DM_EXISTS_FLAG; /* FIXME */
if (dmt->no_open_count)
dmi->flags |= DM_SKIP_BDGET_FLAG;
//...
#ifdef DM_IOCTLS
if (ioctl(_control_fd, command, dmi) < 0) {/*注意这里的dmi */
if (errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) ||
(dmt->type == DM_DEVICE_MKNODES) ||
(dmt->type == DM_DEVICE_STATUS)))
dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */
else {
if (_log_suppress)
log_verbose("device-mapper: %s ioctl "
"failed: %s",
_cmd_data_v4[dmt->type].name,
strerror(errno));
else
log_error("device-mapper: %s ioctl "
"failed: %s",
_cmd_data_v4[dmt->type].name,
strerror(errno));
dm_free(dmi);
return NULL;
}
}
#else /* Userspace alternative for testing */
#endif
return dmi;
}
?
?
?
看一下 command的取值:
?
int dm_task_run(struct dm_task *dmt)
{
struct dm_ioctl *dmi;
unsigned command;
//...
command = _cmd_data_v4[dmt->type].cmd;
//...
}
?
?
对应一个全局数组
?
?
static struct cmd_data _cmd_data_v4[] = {
{"create", DM_DEV_CREATE, {4, 0, 0}},
{"reload", DM_TABLE_LOAD, {4, 0, 0}},
{"remove", DM_DEV_REMOVE, {4, 0, 0}},
{"remove_all", DM_REMOVE_ALL, {4, 0, 0}},
{"suspend", DM_DEV_SUSPEND, {4, 0, 0}},
{"resume", DM_DEV_SUSPEND, {4, 0, 0}},
{"info", DM_DEV_STATUS, {4, 0, 0}},
{"deps", DM_TABLE_DEPS, {4, 0, 0}},
{"rename", DM_DEV_RENAME, {4, 0, 0}},
{"version", DM_VERSION, {4, 0, 0}},
{"status", DM_TABLE_STATUS, {4, 0, 0}},
{"table", DM_TABLE_STATUS, {4, 0, 0}},
{"waitevent", DM_DEV_WAIT, {4, 0, 0}},
{"names", DM_LIST_DEVICES, {4, 0, 0}},
{"clear", DM_TABLE_CLEAR, {4, 0, 0}},
{"mknodes", DM_DEV_STATUS, {4, 0, 0}},
#ifdef DM_LIST_VERSIONS
{"versions", DM_LIST_VERSIONS, {4, 1, 0}},
#endif
#ifdef DM_TARGET_MSG
{"message", DM_TARGET_MSG, {4, 2, 0}},
#endif
#ifdef DM_DEV_SET_GEOMETRY
{"setgeometry", DM_DEV_SET_GEOMETRY, {4, 6, 0}},
#endif
};
?
前面就是 shell输入的命令。 关键就是?
?