/* * _determine_cache_argument * @vg * @lp * * 'lp->origin' is set with an LV that could be either the origin * or the cache_pool of the cached LV which is being created. This * function determines which it is and sets 'lp->origin' or * 'lp->pool' appropriately. */ static int _determine_cache_argument(struct volume_group *vg, struct lvcreate_params *lp) { struct lv_list *lvl; if (!seg_is_cache(lp)) { log_error(INTERNAL_ERROR "Unable to determine cache argument on %s segtype", lp->segtype->name); return 0; } if (!lp->origin) { log_error(INTERNAL_ERROR "Origin LV is not defined."); return 0; } if (!(lvl = find_lv_in_vg(vg, lp->origin))) { log_error("LV %s not found in Volume group %s.", lp->origin, vg->name); return 0; } if (lv_is_cache_pool(lvl->lv)) { lp->pool = lp->origin; lp->origin = NULL; } else { lp->pool = NULL; lp->create_pool = 1; } return 1; }
/* * Normal snapshot or thinly-provisioned snapshot? */ static int _determine_snapshot_type(struct volume_group *vg, struct lvcreate_params *lp) { struct lv_list *lvl; if (!(lvl = find_lv_in_vg(vg, lp->origin))) { log_error("Snapshot origin LV %s not found in Volume group %s.", lp->origin, vg->name); return 0; } if (!arg_count(vg->cmd, extents_ARG) && !arg_count(vg->cmd, size_ARG)) { if (!lv_is_thin_volume(lvl->lv)) { log_error("Please specify either size or extents with snapshots."); return 0; } lp->thin = 1; if (!(lp->segtype = get_segtype_from_string(vg->cmd, "thin"))) return_0; lp->pool = first_seg(lvl->lv)->pool_lv->name; } return 1; }
/* * FIXME: This function should probably not commit to disk but require calling * lvm_vg_write. However, this appears to be non-trivial change until * lv_create_single is refactored by segtype. */ lv_t lvm_vg_create_lv_linear(vg_t vg, const char *name, uint64_t size) { struct lvcreate_params lp; uint64_t extents; struct lv_list *lvl; if (vg_read_error(vg)) return NULL; if (!vg_check_write_mode(vg)) return NULL; memset(&lp, 0, sizeof(lp)); extents = extents_from_size(vg->cmd, size, vg->extent_size); _lv_set_default_params(&lp, vg, name, extents); _lv_set_default_linear_params(vg->cmd, &lp); if (!lv_create_single(vg, &lp)) return NULL; lvl = find_lv_in_vg(vg, name); if (!lvl) return NULL; return (lv_t) lvl->lv; }
/* * lvrename command implementation. * Check arguments and call lv_rename() to execute the request. */ int lvrename(struct cmd_context *cmd, int argc, char **argv) { size_t maxlen; char *lv_name_old, *lv_name_new; const char *vg_name, *vg_name_new, *vg_name_old; char *st; int r = ECMD_FAILED; struct volume_group *vg = NULL; struct lv_list *lvl; if (argc == 3) { vg_name = skip_dev_dir(cmd, argv[0], NULL); lv_name_old = argv[1]; lv_name_new = argv[2]; if (strchr(lv_name_old, '/') && (vg_name_old = extract_vgname(cmd, lv_name_old)) && strcmp(vg_name_old, vg_name)) { log_error("Please use a single volume group name " "(\"%s\" or \"%s\")", vg_name, vg_name_old); return EINVALID_CMD_LINE; } } else if (argc == 2) { lv_name_old = argv[0]; lv_name_new = argv[1]; vg_name = extract_vgname(cmd, lv_name_old); } else { log_error("Old and new logical volume names required"); return EINVALID_CMD_LINE; } if (!validate_name(vg_name)) { log_error("Please provide a valid volume group name"); return EINVALID_CMD_LINE; } if (strchr(lv_name_new, '/') && (vg_name_new = extract_vgname(cmd, lv_name_new)) && strcmp(vg_name, vg_name_new)) { log_error("Logical volume names must " "have the same volume group (\"%s\" or \"%s\")", vg_name, vg_name_new); return EINVALID_CMD_LINE; } if ((st = strrchr(lv_name_old, '/'))) lv_name_old = st + 1; if ((st = strrchr(lv_name_new, '/'))) lv_name_new = st + 1; /* Check sanity of new name */ maxlen = NAME_LEN - strlen(vg_name) - strlen(cmd->dev_dir) - 3; if (strlen(lv_name_new) > maxlen) { log_error("New logical volume path exceeds maximum length " "of %" PRIsize_t "!", maxlen); return ECMD_FAILED; } if (!*lv_name_new) { log_error("New logical volume name may not be blank"); return ECMD_FAILED; } if (!apply_lvname_restrictions(lv_name_new)) { stack; return ECMD_FAILED; } if (!validate_name(lv_name_new)) { log_error("New logical volume name \"%s\" is invalid", lv_name_new); return EINVALID_CMD_LINE; } if (!strcmp(lv_name_old, lv_name_new)) { log_error("Old and new logical volume names must differ"); return EINVALID_CMD_LINE; } log_verbose("Checking for existing volume group \"%s\"", vg_name); vg = vg_read_for_update(cmd, vg_name, NULL, 0); if (vg_read_error(vg)) { release_vg(vg); stack; return ECMD_FAILED; } if (!(lvl = find_lv_in_vg(vg, lv_name_old))) { log_error("Existing logical volume \"%s\" not found in " "volume group \"%s\"", lv_name_old, vg_name); goto error; } if (!lv_rename(cmd, lvl->lv, lv_name_new)) goto error; log_print("Renamed \"%s\" to \"%s\" in volume group \"%s\"", lv_name_old, lv_name_new, vg_name); r = ECMD_PROCESSED; error: unlock_and_release_vg(cmd, vg, vg_name); return r; }