diff options
Diffstat (limited to 'tools/vgck.c')
-rw-r--r-- | tools/vgck.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/tools/vgck.c b/tools/vgck.c index 54bc9d649..aa1f2e387 100644 --- a/tools/vgck.c +++ b/tools/vgck.c @@ -35,9 +35,114 @@ static int vgck_single(struct cmd_context *cmd __attribute__((unused)), return ECMD_PROCESSED; } +/* + * vgck --repairmetadata [--sourcedevice PV_src] VG [PV_dst ...] + * + * PV_src: if specified, the metadata from this PV is written to + * the PVs needing repair. If not specified, a copy of the metadata + * with the largest seqno is used. + * + * PV_dst: if specified, new metadata is written to these PVs. + */ + +static int _repair_metadata(struct cmd_context *cmd, int argc, char **argv) +{ + const char *dev_src_name = NULL; + const char *file_src_name = NULL; + const char *vgname; + struct device_list *devl; + struct dm_list dev_dst_list; + int ret = 1; + int i; + + dm_list_init(&dev_dst_list); + + vgname = cmd->position_argv[0]; + /* TODO: verify valid vgname */ + + if (!lock_vol(cmd, vgname, LCK_VG_WRITE, NULL)) + return ECMD_FAILED; + + lvmcache_label_scan(cmd); + + /* + * specific PVs to repair + */ + for (i = 1; i < cmd->position_argc; i++) { + if (!(devl = malloc(sizeof(*devl)))) + return ECMD_FAILED; + if (!(devl->dev = dev_cache_get(cmd->position_argv[i], NULL))) { + log_error("Device not found to repair: %s", cmd->position_argv[i]); + return ECMD_FAILED; + } + dm_list_add(&dev_dst_list, &devl->list); + } + + /* + * specific PV or file to use as source of metadata to use for repair + */ + if (arg_is_set(cmd, sourcedevice_ARG)) { + if (!(dev_src_name = arg_str_value(cmd, sourcedevice_ARG, NULL))) + return ECMD_FAILED; + + } else if (arg_is_set(cmd, file_ARG)) { + if (!(file_src_name = arg_str_value(cmd, file_ARG, NULL))) + return ECMD_FAILED; + } + + ret = vg_repair_metadata(cmd, vgname, dev_src_name, file_src_name, &dev_dst_list); + + unlock_vg(cmd, NULL, vgname); + + if (!ret) + return ECMD_FAILED; + return ECMD_PROCESSED; +} + +static int _dump_metadata(struct cmd_context *cmd, int argc, char **argv) +{ + const char *dev_src_name = NULL; + const char *vgname; + const char *tofile = NULL; + int ret = 1; + + vgname = cmd->position_argv[0]; + /* TODO: verify valid vgname */ + + if (!lock_vol(cmd, vgname, LCK_VG_READ, NULL)) + return ECMD_FAILED; + + lvmcache_label_scan(cmd); + + if (arg_is_set(cmd, sourcedevice_ARG)) { + if (!(dev_src_name = arg_str_value(cmd, sourcedevice_ARG, NULL))) + return ECMD_FAILED; + } + + if (arg_is_set(cmd, file_ARG)) { + if (!(tofile = arg_str_value(cmd, file_ARG, NULL))) + return ECMD_FAILED; + } + + ret = vg_dump_metadata(cmd, vgname, dev_src_name, arg_is_set(cmd, force_ARG), tofile); + + unlock_vg(cmd, NULL, vgname); + + if (!ret) + return ECMD_FAILED; + return ECMD_PROCESSED; +} + int vgck(struct cmd_context *cmd, int argc, char **argv) { lvmetad_make_unused(cmd); + + if (arg_is_set(cmd, repairmetadata_ARG)) + return _repair_metadata(cmd, argc, argv); + + if (arg_is_set(cmd, dumpmetadata_ARG)) + return _dump_metadata(cmd, argc, argv); + return process_each_vg(cmd, argc, argv, NULL, NULL, 0, 0, NULL, &vgck_single); } |