2019独角兽企业重金招聘Python工程师标准>>>

命令参数定义:

$ cat tools/command.h
...xx(lvextend,"Add space to a logical volume",0,"lvextend\n""\t[-A|--autobackup y|n]\n""\t[--alloc AllocationPolicy]\n""\t[--commandprofile ProfileName]\n""\t[-d|--debug]\n""\t[-f|--force]\n""\t[-h|--help]\n""\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n""\t{-l|--extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE|ORIGIN}] |\n""\t -L|--size [+]LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n""\t --poolmetadatasize [+]MetadataVolumeSize[bBsSkKmMgG]}\n""\t[-m|--mirrors Mirrors]\n""\t[--nosync]\n""\t[--use-policies]\n""\t[-n|--nofsck]\n""\t[--noudevsync]\n""\t[--reportformat {basic|json}]\n""\t[-r|--resizefs]\n""\t[-t|--test]\n""\t[--type VolumeType]\n""\t[-v|--verbose]\n""\t[--version]\n""\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, mirrors_ARG,nofsck_ARG, nosync_ARG, noudevsync_ARG, poolmetadatasize_ARG,reportformat_ARG, resizefs_ARG, size_ARG, stripes_ARG, stripesize_ARG,test_ARG, type_ARG, usepolicies_ARG)...

命令入口,调用lvresize:

$ cat tools/lvextend.c
...#include "tools.h"int lvextend(struct cmd_context *cmd, int argc, char **argv)
{return lvresize(cmd, argc, argv);
}...

lvresize函数入口:

$ cat tools/lvresize.c
...int lvresize(struct cmd_context *cmd, int argc, char **argv)
{struct processing_handle *handle;struct lvresize_params lp = { 0 };int ret;if (!_lvresize_params(cmd, argc, argv, &lp)) {stack;return EINVALID_CMD_LINE;}if (!(handle = init_processing_handle(cmd, NULL))) {log_error("Failed to initialize processing handle.");return ECMD_FAILED;}handle->custom_handle = &lp;ret = process_each_vg(cmd, 0, NULL, lp.vg_name, NULL, READ_FOR_UPDATE, 0, handle,&_lvresize_single);destroy_processing_handle(cmd, handle);return ret;
}...
...static int _lvresize_single(struct cmd_context *cmd, const char *vg_name,struct volume_group *vg, struct processing_handle *handle)
{struct lvresize_params *lp = (struct lvresize_params *) handle->custom_handle;struct dm_list *pvh;struct logical_volume *lv;int ret = ECMD_FAILED;/* Does LV exist? */if (!(lv = find_lv(vg, lp->lv_name))) {log_error("Logical volume %s not found in volume group %s.",lp->lv_name, vg->name);goto out;}if (!(pvh = lp->argc ? create_pv_list(cmd->mem, vg, lp->argc, lp->argv, 1) : &vg->pvs))goto_out;if (!lv_resize(lv, lp, pvh))goto_out;ret = ECMD_PROCESSED;
out:return ret;
}...

lv_resize关键部分:

$ cat lib/metadata/lv_mainp.c
...int lv_resize(struct logical_volume *lv,struct lvresize_params *lp,struct dm_list *pvh)
{struct volume_group *vg = lv->vg;struct cmd_context *cmd = vg->cmd;struct logical_volume *lock_lv = (struct logical_volume*) lv_lock_holder(lv);struct logical_volume *aux_lv = NULL; /* Note: aux_lv never resizes fs */struct lvresize_params aux_lp;int activated = 0;int ret = 0;if (!_lvresize_check(lv, lp))return_0;if (lp->use_policies) {lp->extents = 0;lp->sign = SIGN_PLUS;lp->percent = PERCENT_LV;aux_lp = *lp;if (!_lvresize_adjust_policy(lv, &lp->extents, &aux_lp.extents))return_0;if (!lp->extents) {if (!aux_lp.extents)return 1;  /* Nothing to do *//* Resize thin-pool metadata as mainlv */lv = first_seg(lv)->metadata_lv; /* metadata LV */lp->extents = aux_lp.extents;} else if (aux_lp.extents) {/* Also resize thin-pool metadata */aux_lv = _lvresize_setup_aux(first_seg(lv)->metadata_lv, &aux_lp);}} else if (lp->poolmetadata_size) {if (!lp->extents && !lp->size) {/* When only --poolmetadatasize give and not --size* swith directly to resize metadata LV */lv = first_seg(lv)->metadata_lv;lp->size = lp->poolmetadata_size;lp->sign = lp->poolmetadata_sign;} else {aux_lp = *lp;aux_lv = _lvresize_setup_aux(first_seg(lv)->metadata_lv, &aux_lp);aux_lp.size = lp->poolmetadata_size;aux_lp.sign = lp->poolmetadata_sign;}}if (aux_lv && !_lvresize_prepare(&aux_lv, &aux_lp, pvh))return_0;if (!_lvresize_prepare(&lv, lp, pvh))return_0;if (lv_is_thin_pool(lock_lv) &&  /* Lock holder is thin-pool */!lv_is_active(lock_lv)) {if (!activation()) {log_error("Cannot resize %s without using ""device-mapper kernel driver.",display_lvname(lock_lv));return 0;}/** Active 'hidden' -tpool can be waiting for resize, but the* pool LV itself might be inactive.* Here plain suspend/resume would not work.* So active temporarily pool LV (with on disk metadata)* then use suspend and resume and deactivate pool LV,* instead of searching for an active thin volume.*/if (!activate_lv_excl(cmd, lock_lv)) {log_error("Failed to activate %s.", display_lvname(lock_lv));return 0;}activated = 1;}/** If the LV is locked from activation, this lock call is a no-op.* Otherwise, this acquires a transient lock on the lv (not PERSISTENT).*/if (!lockd_lv(cmd, lock_lv, "ex", 0))return_0;if (aux_lv) {if (!_lvresize_volume(aux_lv, &aux_lp, pvh))goto_bad;/* store vg on disk(s) */if (!lv_update_and_reload(lock_lv))goto_bad;}if (!_lvresize_volume(lv, lp, pvh))goto_bad;/* store vg on disk(s) */if (!lv_update_and_reload(lock_lv))goto_bad;if (lv_is_cow_covering_origin(lv))if (!monitor_dev_for_events(cmd, lv, 0, 0))stack;if (lv_is_thin_pool(lock_lv)) {/* Update lvm pool metadata (drop messages). */if (!update_pool_lv(lock_lv, 0))goto_bad;backup(vg);}log_print_unless_silent("Logical volume %s successfully resized.",display_lvname(lv));if (lp->resizefs && (lp->resize == LV_EXTEND) &&!_fsadm_cmd(FSADM_CMD_RESIZE, lv, lp->extents, lp->force, NULL))return_0;ret = 1;
bad:if (activated && !deactivate_lv(cmd, lock_lv)) {log_error("Problem deactivating %s.", display_lvname(lock_lv));ret = 0;}return ret;
}...
$ cat lib/locking/file_locking.c
...static int _file_lock_resource(struct cmd_context *cmd, const char *resource,uint32_t flags, const struct logical_volume *lv)
{...case LCK_UNLOCK:log_very_verbose("Unlocking LV %s%s%s", resource, origin_only ? " without snapshots" : "", revert ? " (reverting)" : "");if (!lv_resume_if_active(cmd, resource, origin_only, 0, revert, lv_committed(lv)))return 0;break;...case LCK_WRITE:log_very_verbose("Locking LV %s (W)%s", resource, origin_only ? " without snapshots" : "");if (!lv_suspend_if_active(cmd, resource, origin_only, 0, lv_committed(lv), lv))return 0;break;...return 1;
}...
$ cat lib/active/active.c
.../** In a cluster, set exclusive to indicate that only one node is using the* device.  Any preloaded tables may then use non-clustered targets.** Returns success if the device is not active*/
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,const struct logical_volume *lv, const struct logical_volume *lv_pre)
{struct lv_activate_opts laopts = {.origin_only = origin_only,.exclusive = exclusive};return _lv_suspend(cmd, lvid_s, &laopts, 0, lv, lv_pre);
}.../** In a cluster, set exclusive to indicate that only one node is using the* device.  Any tables loaded may then use non-clustered targets.** @origin_only* @exclusive   This parameter only has an affect in cluster-context.*              It forces local target type to be used (instead of*              cluster-aware type).* Returns success if the device is not active*/
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,unsigned origin_only, unsigned exclusive,unsigned revert, const struct logical_volume *lv)
{struct lv_activate_opts laopts = {.origin_only = origin_only,.exclusive = exclusive,.revert = revert};return _lv_resume(cmd, lvid_s, &laopts, 0, lv);
}...

转载于:https://my.oschina.net/LastRitter/blog/1535842

LVM源码分析3-lvextend相关推荐

  1. LVM源码分析1-概览

    获取CentOS LVM源码 $ which lvmetad /usr/sbin/lvmetad $ rpm -qf /usr/sbin/lvmetad lvm2-2.02.130-5.el7_2.5 ...

  2. LVM源码分析2-libdaemon

    2019独角兽企业重金招聘Python工程师标准>>> LVM的libdaemon库实现了守护进程与命令工具之间使用UNIX本地套接字进行CS通信的基础模型. 报文 配置树结构 $ ...

  3. openstack冷迁移/Resize源码分析(二)

    接上一篇 openstack冷迁移/Resize源码分析(一) 执行冷迁移/Resize /nova_queens/nova/compute/manager.py @wrap_exception()@ ...

  4. Lua源码分析 - 虚拟机篇 - 语义解析之Opcode执行(18)

    目录 一.虚拟机篇 - 指令执行状态机luaV_execute 二.虚拟机篇 - 状态机的具体实现原理 一.虚拟机篇 - 指令执行状态机luaV_execute 在<Lua源码分析 - 主流程篇 ...

  5. Openstack liberty 云主机迁移源码分析之在线迁移3

    这是在线迁移 源码分析的第三篇,Openstack liberty 云主机迁移源码分析之在线迁移2中分析了prepare准备阶段nova-compute的处理过程,本文将会分析execute执行阶段的 ...

  6. 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析

    目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...

  7. SpringBoot-web开发(四): SpringMVC的拓展、接管(源码分析)

    [SpringBoot-web系列]前文: SpringBoot-web开发(一): 静态资源的导入(源码分析) SpringBoot-web开发(二): 页面和图标定制(源码分析) SpringBo ...

  8. SpringBoot-web开发(二): 页面和图标定制(源码分析)

    [SpringBoot-web系列]前文: SpringBoot-web开发(一): 静态资源的导入(源码分析) 目录 一.首页 1. 源码分析 2. 访问首页测试 二.动态页面 1. 动态资源目录t ...

  9. SpringBoot-web开发(一): 静态资源的导入(源码分析)

    目录 方式一:通过WebJars 1. 什么是webjars? 2. webjars的使用 3. webjars结构 4. 解析源码 5. 测试访问 方式二:放入静态资源目录 1. 源码分析 2. 测 ...

最新文章

  1. 偏差、方差、贝叶斯误差
  2. Java小青蛙跳台街,青蛙跳台阶问题:Java版,递归算法和循环
  3. 最新的20多个JMS面试问答(2020)
  4. Python eval 与 exec 函数 - Python零基础入门教程
  5. xmind 笔记
  6. 内存分配器ptmalloc,jemalloc,tcmalloc调研与对比
  7. 【有内鬼,终止交易】风靡朋友圈的壁纸,实现代码竟如此简单 | 原力计划
  8. python机器学习案例系列教程——基于规则的分类器
  9. Installer - 使用Maven自动布署至外部Tomcat
  10. ASP.NET MVC 3 Beta初体验之WebGrid
  11. matlab分段拟合程序,如何用matlab拟合出分段函数?
  12. Python 3.7.1 模块 文本处理 正则表达式 re
  13. 拼多多卖家必知:店铺评分和评价那点事
  14. Java面试题(一) 题目:输入某年某月某日,判断这一天是这一年的第几天
  15. java脚本引擎parseint方法_autojs脚本引擎调用java的jsoup爬取科学网博客的指定id的好友名字...
  16. 操作系统为什么需要驱动? 驱动程序是什么?为什么有的硬件“免驱”?
  17. Ubuntu 22.04下安装配置rime五笔输入法
  18. 老程序员到40、50岁该怎么办?是继续留在软件行业还是转行?是默默死去还是向中层管理者蜕变?美国在老程序员的职业发展上的经验?...
  19. 快速打造微信小程序(超详细)
  20. 超微服务器怎么开虚拟化,超微6016TT-IBXF服务器Supermicro开启虚拟化支持

热门文章

  1. 吴恩达深度学习笔记(四)——深度学习的实践层面
  2. 你是独一无二你是生命的奇迹
  3. 移动端js调试工具:eruda
  4. Bresenham画圆算法
  5. 【c++】战斗1.1
  6. JavaScript 执行— 事件循环、宏观任务、微观任务
  7. 如何防范 PHP安全的方式-session会话劫持与会话固定 ?
  8. idea中文件编码方式_idea设置编码格式为utf8
  9. JVM监控:python脚本JMX获取JVM状态
  10. html h1 不自动加粗,HTML之h1 h2 h3 h4标签知识经验篇