日期:2014-05-16 浏览次数:20818 次
?
?了解分布式存储的朋友 一定知道 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输入的命令。 关键就是?
?