static int vgexport_single(struct cmd_context *cmd, // __attribute((unused)), const char *vg_name, struct volume_group *vg, int consistent, void *handle) // __attribute((unused))) { struct pv_list *pvl; struct physical_volume *pv; if (!vg) { log_error("Unable to find volume group \"%s\"", vg_name); goto error; } if (!consistent) { log_error("Volume group %s inconsistent", vg_name); goto error; } if (!vg_check_status(vg, EXPORTED_VG | LVM_WRITE)) { goto error; } if (lvs_in_vg_activated(vg)) { log_error("Volume group \"%s\" has active logical volumes", vg_name); goto error; } if (!archive(vg)) goto error; vg->status |= EXPORTED_VG; list_iterate_items(pvl, struct pv_list, &vg->pvs) { pv = pvl->pv; pv->status |= EXPORTED_VG; } if (!vg_write(vg) || !vg_commit(vg)) goto error; backup(vg); log_print("Volume group \"%s\" successfully exported", vg->name); return ECMD_PROCESSED; error: return ECMD_FAILED; }
static int _vgrename_single(struct cmd_context *cmd, const char *vg_name, struct volume_group *vg, struct processing_handle *handle) { struct vgrename_params *vp = (struct vgrename_params *) handle->custom_handle; struct lvmcache_vginfo *vginfo; char old_path[NAME_LEN]; char new_path[NAME_LEN]; struct id id; const char *name; char *dev_dir; /* * vg_name_old may be a UUID which process_each_vg * replaced with the real VG name. In that case, * vp->vg_name_old will be the UUID and vg_name will be * the actual VG name. Check again if the old and new * names match, using the real names. */ if (vp->old_name_is_uuid && !strcmp(vp->vg_name_new, vg_name)) { log_error("New VG name must differ from the old VG name."); return ECMD_FAILED; } /* * Check if a VG already exists with the new VG name. * * When not using lvmetad, it's essential that a full scan has * been done to ensure we see all existing VG names, so we * do not use an existing name. This has been done by * process_each_vg REQUIRES_FULL_LABEL_SCAN. * * (FIXME: We could look for the new name in the list of all * VGs that process_each_vg created, but we don't have access * to that list here, so we have to look in lvmcache. * This requires populating lvmcache when using lvmetad.) */ lvmcache_seed_infos_from_lvmetad(cmd); if ((vginfo = lvmcache_vginfo_from_vgname(vp->vg_name_new, NULL))) { log_error("New VG name \"%s\" already exists", vp->vg_name_new); return ECMD_FAILED; } if (id_read_format_try(&id, vp->vg_name_new) && (name = lvmcache_vgname_from_vgid(cmd->mem, (const char *)&id))) { log_error("New VG name \"%s\" matches the UUID of existing VG %s", vp->vg_name_new, name); return ECMD_FAILED; } /* * Lock the old VG name first: * . The old VG name has already been locked by process_each_vg. * . Now lock the new VG name here, second. * * Lock the new VG name first: * . The new VG name has already been pre-locked below, * before process_each_vg was called. * . process_each_vg then locked the old VG name second. * . Nothing to do here. * * Special case when the old VG name is a uuid: * . The old VG's real name wasn't known before process_each_vg, * so the correct lock ordering wasn't known beforehand, * so no pre-locking was done. * . The old VG's real name has been locked by process_each_vg. * . Now lock the new VG name here, second. * . Suppress lock ordering checks because the lock order may * have wanted the new name first, which wasn't possible in * this uuid-for-name case. */ if (vp->lock_vg_old_first || vp->old_name_is_uuid) { if (vp->old_name_is_uuid) lvmcache_lock_ordering(0); if (!_lock_new_vg_for_rename(cmd, vp->vg_name_new)) return ECMD_FAILED; lvmcache_lock_ordering(1); } dev_dir = cmd->dev_dir; if (!archive(vg)) goto error; /* Remove references based on old name */ if (!drop_cached_metadata(vg)) stack; if (!lockd_rename_vg_before(cmd, vg)) { stack; goto error; } /* Change the volume group name */ vg_rename(cmd, vg, vp->vg_name_new); /* store it on disks */ log_verbose("Writing out updated volume group"); if (!vg_write(vg) || !vg_commit(vg)) { goto error; } sprintf(old_path, "%s%s", dev_dir, vg_name); sprintf(new_path, "%s%s", dev_dir, vp->vg_name_new); if (activation() && dir_exists(old_path)) { log_verbose("Renaming \"%s\" to \"%s\"", old_path, new_path); if (test_mode()) log_verbose("Test mode: Skipping rename."); else if (lvs_in_vg_activated(vg)) { if (!vg_refresh_visible(cmd, vg)) { log_error("Renaming \"%s\" to \"%s\" failed", old_path, new_path); goto error; } } } lockd_rename_vg_final(cmd, vg, 1); if (!backup(vg)) stack; if (!backup_remove(cmd, vg_name)) stack; unlock_vg(cmd, vp->vg_name_new); vp->unlock_new_name = 0; log_print_unless_silent("Volume group \"%s\" successfully renamed to \"%s\"", vp->vg_name_old, vp->vg_name_new); return 1; error: unlock_vg(cmd, vp->vg_name_new); vp->unlock_new_name = 0; lockd_rename_vg_final(cmd, vg, 0); return 0; }