lvm代码分析(五)

 回到lvm2_main():
  1. if (_lvm1_fallback(cmd)) {
  2.         /* Attempt to run equivalent LVM1 tool instead */
  3.         if (!alias) {
  4.             argv++;
  5.             argc--;
  6.             alias = 0;
  7.         }
  8.         if (!argc) {
  9.             log_error("Falling back to LVM1 tools, but no "
  10.                   "command specified.");
  11.             return ECMD_FAILED;
  12.         }
  13.         _exec_lvm1_command(argv);
  14.         return ECMD_FAILED;
  15.     }
  16. #ifdef READLINE_SUPPORT
  17.     if (!alias && argc == 1) {
  18.         _nonroot_warning();
  19.         ret = lvm_shell(cmd, &_cmdline);
  20.         goto out;
  21.     }
  22. #endif
  23.     if (!alias) {
  24.         if (argc < 2) {
  25.             log_fatal("Please supply an LVM command.");
  26.             _display_help();
  27.             ret = EINVALID_CMD_LINE;
  28.             goto out;
  29.         }
  30.         argc--;
  31.         argv++;
  32.     }
  33.     _nonroot_warning();
以上部分大概是看输入的命令能否转化为lvm1的命令执行,以及是否支持readline,还有对命令解析判断是否可执行。_noroot_warning是对非root用户执行lvm命令的警告。
  1.  ret = lvm_run_command(cmd, argc, argv);
  2.     if ((ret == ENO_SUCH_CMD) && (!alias))
  3.         ret = _run_script(cmd, argc, argv);
  4.     if (ret == ENO_SUCH_CMD)
  5.         log_error("No such command.  Try 'help'.");
  6.     if ((ret != ECMD_PROCESSED) && !error_message_produced()) {
  7.         log_debug("Internal error: Failed command did not use log_error");
  8.         log_error("Command failed with status code %d.", ret);
  9.     }
前面的都准备就绪了,终于到lvm_run_command了,执行用户输入的命令。先看看他的全貌:
  1. int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
  2. {
  3.     int ret = 0;
  4.     int locking_type;
  5.     init_error_message_produced(0);
  6.     /* each command should start out with sigint flag cleared */
  7.     sigint_clear();
  8.     if (!(cmd->cmd_line = _copy_command_line(cmd, argc, argv)))
  9.         return ECMD_FAILED;
  10.     log_debug("Parsing: %s", cmd->cmd_line);
  11.     if (!(cmd->command = _find_command(argv[0])))
  12.         return ENO_SUCH_CMD;
  13.     if (!_process_command_line(cmd, &argc, &argv)) {
  14.         log_error("Error during parsing of command line.");
  15.         return EINVALID_CMD_LINE;
  16.     }
  17.     set_cmd_name(cmd->command->name);
  18.     if (arg_count(cmd, config_ARG))
  19.         if ((ret = _override_settings(cmd)))
  20.             goto_out;
  21.     if (arg_count(cmd, config_ARG) || !cmd->config_valid || config_files_changed(cmd)) {
  22.         /* Reinitialise various settings inc. logging, filters */
  23.         if (!refresh_toolcontext(cmd)) {
  24.             log_error("Updated config file invalid. Aborting.");
  25.             return ECMD_FAILED;
  26.         }
  27.     }
  28.     if ((ret = _get_settings(cmd)))
  29.         goto_out;
  30.     _apply_settings(cmd);
  31.     log_debug("Processing: %s", cmd->cmd_line);
  32. #ifdef O_DIRECT_SUPPORT
  33.     log_debug("O_DIRECT will be used");
  34. #endif
  35.     if ((ret = _process_common_commands(cmd)))
  36.         goto_out;
  37.     if (arg_count(cmd, nolocking_ARG))
  38.         locking_type = 0;
  39.     else
  40.         locking_type = find_config_tree_int(cmd,
  41.                            "global/locking_type", 1);
  42.     if (!init_locking(locking_type, cmd)) {
  43.         log_error("Locking type %d initialisation failed.",
  44.               locking_type);
  45.         ret = ECMD_FAILED;
  46.         goto out;
  47.     }
  48.     ret = cmd->command->fn(cmd, argc, argv);
  49.     fin_locking();
  50.       out:
  51.     if (test_mode()) {
  52.         log_verbose("Test mode: Wiping internal cache");
  53.         lvmcache_destroy(cmd, 1);
  54.     }
  55.     if (cmd->cft_override) {
  56.         destroy_config_tree(cmd->cft_override);
  57.         cmd->cft_override = NULL;
  58.         /* Move this? */
  59.         if (!refresh_toolcontext(cmd))
  60.             stack;
  61.     }
  62.     /* FIXME Move this? */
  63.     cmd->current_settings = cmd->default_settings;
  64.     _apply_settings(cmd);
  65.     /*
  66.      * free off any memory the command used.
  67.      */
  68.     dm_pool_empty(cmd->mem);
  69.     if (ret == EINVALID_CMD_LINE && !_cmdline.interactive)
  70.         _short_usage(cmd->command->name);
  71.     log_debug("Completed: %s", cmd->cmd_line);
  72.     return ret;
  73. }
比较主要的就两个函数把,就是 _find_command和ret = cmd->command->fn(cmd, argc, argv)。顾名思义,先找到要执行的代码函数所在的位置,然后进行操作。 (cmd->cmd_line = _copy_command_line(cmd, argc, argv)是把命令携带的参数进行copy,在命令执行之前,调用 _process_command_line(cmd, &argc, &argv)对命令的参数进行处理。
  1. static struct command *_find_command(const char *name)
  2. {
  3.     int i;
  4.     char *base;
  5.     base = last_path_component(name);
  6.     for (i = 0; i < _cmdline.num_commands; i++) {
  7.         if (!strcmp(base, _cmdline.commands[i].name))
  8.             break;
  9.     }
  10.     if (i >= _cmdline.num_commands)
  11.         return 0;
  12.     return _cmdline.commands + i;
  13. }
在_find_command中,就是将name和静态变量_cmdline的元素进行比较,找到对应的命令入口。
然后调用ret = cmd->command->fn(cmd, argc, argv);执行cmd对应的函数。至此,lvm初始化及其对命令的解析完毕,转入到不同命令的执行中。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值