int vgremove(struct cmd_context *cmd, int argc, char **argv) { int ret; if (!argc && !arg_is_set(cmd, select_ARG)) { log_error("Please enter one or more volume group paths " "or use --select for selection."); return EINVALID_CMD_LINE; } /* * Needed to change the global VG namespace, * and to change the set of orphan PVs. */ if (!lockd_gl(cmd, "ex", LDGL_UPDATE_NAMES)) return ECMD_FAILED; /* * This is a special case: if vgremove is given a tag, it causes * process_each_vg to do lockd_gl(sh) when getting a list of all * VG names. We don't want the gl converted to sh, so disable it. */ cmd->lockd_gl_disable = 1; cmd->handles_missing_pvs = 1; ret = process_each_vg(cmd, argc, argv, READ_FOR_UPDATE, NULL, &vgremove_single); return ret; }
int vgexport(struct cmd_context *cmd, int argc, char **argv) { if (!argc && !arg_count(cmd, all_ARG)) { log_error("Please supply volume groups or use -a for all."); return ECMD_FAILED; } if (argc && arg_count(cmd, all_ARG)) { log_error("No arguments permitted when using -a for all."); return ECMD_FAILED; } return process_each_vg(cmd, argc, argv, LCK_VG_WRITE, 1, NULL, &vgexport_single); }
int vgremove(struct cmd_context *cmd, int argc, char **argv) { int ret; if (!argc && !arg_is_set(cmd, select_ARG)) { log_error("Please enter one or more volume group paths " "or use --select for selection."); return EINVALID_CMD_LINE; } cmd->handles_missing_pvs = 1; ret = process_each_vg(cmd, argc, argv, READ_FOR_UPDATE, NULL, &vgremove_single); return ret; }
static int _report(struct cmd_context *cmd, int argc, char **argv, report_type_t report_type) { void *report_handle; const char *opts; char *str; const char *keys = NULL, *options = NULL, *separator; int r = ECMD_PROCESSED; int aligned, buffered, headings; unsigned args_are_pvs; aligned = find_config_tree_int(cmd, "report/aligned", DEFAULT_REP_ALIGNED); buffered = find_config_tree_int(cmd, "report/buffered", DEFAULT_REP_BUFFERED); headings = find_config_tree_int(cmd, "report/headings", DEFAULT_REP_HEADINGS); separator = find_config_tree_str(cmd, "report/separator", DEFAULT_REP_SEPARATOR); args_are_pvs = (report_type == PVS || report_type == PVSEGS) ? 1 : 0; switch (report_type) { case LVS: keys = find_config_tree_str(cmd, "report/lvs_sort", DEFAULT_LVS_SORT); if (!arg_count(cmd, verbose_ARG)) options = find_config_tree_str(cmd, "report/lvs_cols", DEFAULT_LVS_COLS); else options = find_config_tree_str(cmd, "report/lvs_cols_verbose", DEFAULT_LVS_COLS_VERB); break; case VGS: keys = find_config_tree_str(cmd, "report/vgs_sort", DEFAULT_VGS_SORT); if (!arg_count(cmd, verbose_ARG)) options = find_config_tree_str(cmd, "report/vgs_cols", DEFAULT_VGS_COLS); else options = find_config_tree_str(cmd, "report/vgs_cols_verbose", DEFAULT_VGS_COLS_VERB); break; case PVS: keys = find_config_tree_str(cmd, "report/pvs_sort", DEFAULT_PVS_SORT); if (!arg_count(cmd, verbose_ARG)) options = find_config_tree_str(cmd, "report/pvs_cols", DEFAULT_PVS_COLS); else options = find_config_tree_str(cmd, "report/pvs_cols_verbose", DEFAULT_PVS_COLS_VERB); break; case SEGS: keys = find_config_tree_str(cmd, "report/segs_sort", DEFAULT_SEGS_SORT); if (!arg_count(cmd, verbose_ARG)) options = find_config_tree_str(cmd, "report/segs_cols", DEFAULT_SEGS_COLS); else options = find_config_tree_str(cmd, "report/segs_cols_verbose", DEFAULT_SEGS_COLS_VERB); break; case PVSEGS: keys = find_config_tree_str(cmd, "report/pvsegs_sort", DEFAULT_PVSEGS_SORT); if (!arg_count(cmd, verbose_ARG)) options = find_config_tree_str(cmd, "report/pvsegs_cols", DEFAULT_PVSEGS_COLS); else options = find_config_tree_str(cmd, "report/pvsegs_cols_verbose", DEFAULT_PVSEGS_COLS_VERB); break; } /* If -o supplied use it, else use default for report_type */ if (arg_count(cmd, options_ARG)) { opts = arg_str_value(cmd, options_ARG, ""); if (!opts || !*opts) { log_error("Invalid options string: %s", opts); return 0; } if (*opts == '+') { if (!(str = dm_pool_alloc(cmd->mem, strlen(options) + strlen(opts) + 1))) { log_error("options string allocation failed"); return 0; } strcpy(str, options); strcat(str, ","); strcat(str, opts + 1); options = str; } else options = opts; } /* -O overrides default sort settings */ if (arg_count(cmd, sort_ARG)) keys = arg_str_value(cmd, sort_ARG, ""); if (arg_count(cmd, separator_ARG)) separator = arg_str_value(cmd, separator_ARG, " "); if (arg_count(cmd, separator_ARG)) aligned = 0; if (arg_count(cmd, aligned_ARG)) aligned = 1; if (arg_count(cmd, unbuffered_ARG) && !arg_count(cmd, sort_ARG)) buffered = 0; if (arg_count(cmd, noheadings_ARG)) headings = 0; if (!(report_handle = report_init(cmd, options, keys, &report_type, separator, aligned, buffered, headings))) return_0; /* Ensure options selected are compatible */ if (report_type & SEGS) report_type |= LVS; if (report_type & PVSEGS) report_type |= PVS; if ((report_type & LVS) && (report_type & PVS)) { log_error("Can't report LV and PV fields at the same time"); dm_report_free(report_handle); return 0; } /* Change report type if fields specified makes this necessary */ if (report_type & SEGS) report_type = SEGS; else if (report_type & LVS) report_type = LVS; else if (report_type & PVSEGS) report_type = PVSEGS; else if (report_type & PVS) report_type = PVS; switch (report_type) { case LVS: r = process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle, &_lvs_single); break; case VGS: r = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0, report_handle, &_vgs_single); break; case PVS: if (args_are_pvs) r = process_each_pv(cmd, argc, argv, NULL, report_handle, &_pvs_single); else r = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0, report_handle, &_pvs_in_vg); break; case SEGS: r = process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle, &_lvsegs_single); break; case PVSEGS: if (args_are_pvs) r = process_each_pv(cmd, argc, argv, NULL, report_handle, &_pvsegs_single); else r = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0, report_handle, &_pvsegs_in_vg); break; } dm_report_output(report_handle); dm_report_free(report_handle); return r; }
int vgrename(struct cmd_context *cmd, int argc, char **argv) { struct vgrename_params vp = { 0 }; struct processing_handle *handle; const char *vg_name_new; const char *vg_name_old; struct id id; int ret; if (argc != 2) { log_error("Old and new volume group names need specifying"); return EINVALID_CMD_LINE; } vg_name_old = skip_dev_dir(cmd, argv[0], NULL); vg_name_new = skip_dev_dir(cmd, argv[1], NULL); if (!validate_vg_rename_params(cmd, vg_name_old, vg_name_new)) return_0; if (!(vp.vg_name_old = dm_pool_strdup(cmd->mem, vg_name_old))) return_ECMD_FAILED; if (!(vp.vg_name_new = dm_pool_strdup(cmd->mem, vg_name_new))) return_ECMD_FAILED; /* Needed change the global VG namespace. */ if (!lockd_gl(cmd, "ex", LDGL_UPDATE_NAMES)) return_ECMD_FAILED; /* * Special case where vg_name_old may be a UUID: * If vg_name_old is a UUID, then process_each may * translate it to an actual VG name that we don't * yet know. The lock ordering, and pre-locking, * needs to be done based on VG names. When * vg_name_old is a UUID, do not do any pre-locking * based on it, since it's likely to be wrong, and * defer all the locking to the _single function. * * When it's not a UUID, we know the two VG names, * and we can pre-lock the new VG name if the lock * ordering wants it locked before the old VG name * which will be locked by process_each. If lock * ordering wants the old name locked first, then * the _single function will lock the new VG name. */ if (!(vp.old_name_is_uuid = id_read_format_try(&id, vg_name_old))) { if (strcmp(vg_name_new, vg_name_old) < 0) { vp.lock_vg_old_first = 0; vp.unlock_new_name = 1; if (!_lock_new_vg_for_rename(cmd, vg_name_new)) return ECMD_FAILED; } else { /* The old VG is locked by process_each_vg. */ vp.lock_vg_old_first = 1; } } if (!(handle = init_processing_handle(cmd))) { log_error("Failed to initialize processing handle."); return ECMD_FAILED; } handle->custom_handle = &vp; ret = process_each_vg(cmd, 0, NULL, vg_name_old, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, handle, _vgrename_single); /* Needed if process_each_vg returns error before calling _single. */ if (vp.unlock_new_name) unlock_vg(cmd, vg_name_new); destroy_processing_handle(cmd, handle); return ret; }