353 lines
8.2 KiB
Diff
353 lines
8.2 KiB
Diff
Index: LVM2.2.02.39/tools/pvremove.c
|
|
===================================================================
|
|
--- LVM2.2.02.39.orig/tools/pvremove.c 2007-11-22 02:25:06.000000000 +0100
|
|
+++ LVM2.2.02.39/tools/pvremove.c 2008-09-11 16:10:31.000000000 +0200
|
|
@@ -18,6 +18,32 @@
|
|
const char _really_wipe[] =
|
|
"Really WIPE LABELS from physical volume \"%s\" of volume group \"%s\" [y/n]? ";
|
|
|
|
+static const char* pv_remove_symlink(struct cmd_context* cmd, const char* name)
|
|
+{
|
|
+ struct physical_volume *pv;
|
|
+ char *pvuuid;
|
|
+ char pvuuid_link[70];
|
|
+
|
|
+ init_partial(1);
|
|
+ if (!(pv = pv_read(cmd, name, NULL, NULL, 1))) {
|
|
+ return NULL;
|
|
+ }
|
|
+ init_partial(0);
|
|
+
|
|
+ pvuuid = malloc(sizeof(char)*40);
|
|
+ if (pvuuid == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ id_write_format(&pv->id, pvuuid, 40);
|
|
+
|
|
+ snprintf(pvuuid_link, 70, "/dev/disk/by-id/lvm2-pvuuid-%s", pvuuid);
|
|
+ unlink(pvuuid_link); //we really don't care if it successed or not.
|
|
+
|
|
+ free(pvuuid);
|
|
+ return pvuuid;
|
|
+}
|
|
+
|
|
/*
|
|
* Decide whether it is "safe" to wipe the labels on this device.
|
|
* 0 indicates we may not.
|
|
@@ -108,6 +134,8 @@
|
|
log_print("Labels on physical volume \"%s\" successfully wiped",
|
|
pv_name);
|
|
|
|
+ pv_remove_symlink(cmd, pv_name);
|
|
+
|
|
ret = ECMD_PROCESSED;
|
|
|
|
error:
|
|
Index: LVM2.2.02.39/tools/pvcreate.c
|
|
===================================================================
|
|
--- LVM2.2.02.39.orig/tools/pvcreate.c 2008-06-24 22:10:32.000000000 +0200
|
|
+++ LVM2.2.02.39/tools/pvcreate.c 2008-09-11 16:11:04.000000000 +0200
|
|
@@ -23,6 +23,95 @@
|
|
const char _really_init[] =
|
|
"Really INITIALIZE physical volume \"%s\" of volume group \"%s\" [y/n]? ";
|
|
|
|
+static const char* pv_follow_if_link (const char* path)
|
|
+{
|
|
+ int r;
|
|
+ int len = 60;
|
|
+ char *fpath = NULL;
|
|
+ char *npath = NULL;
|
|
+ struct stat st;
|
|
+
|
|
+ r = lstat(path, &st);
|
|
+ if (r == -1) return NULL; //shouldn't happen
|
|
+
|
|
+ if (S_ISLNK(st.st_mode)) {
|
|
+ while (1) {
|
|
+ npath = realloc(fpath, sizeof(char)*len);
|
|
+ if (npath == NULL) {
|
|
+ if (fpath != NULL) free(fpath);
|
|
+ return NULL;
|
|
+ }
|
|
+ fpath = npath;
|
|
+
|
|
+ memset(fpath, 0, sizeof(char)*len);
|
|
+ r = readlink(path, fpath, len);
|
|
+ if (r != -1 && fpath[len-1] == 0) break;
|
|
+ if (r == -1) {
|
|
+ free(fpath);
|
|
+ return NULL;
|
|
+ } else {
|
|
+ len = len * 2;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ fpath = strdup(path);
|
|
+ }
|
|
+ return fpath;
|
|
+}
|
|
+
|
|
+
|
|
+static const char* pv_symlink_handle(struct cmd_context* cmd, const char* name, int create)
|
|
+{
|
|
+ struct physical_volume *pv;
|
|
+ char *pvuuid;
|
|
+ char *pvuuid_link;
|
|
+ int old_partial;
|
|
+
|
|
+ pvuuid_link = malloc(70);
|
|
+ if (pvuuid_link == NULL) return NULL;
|
|
+
|
|
+ old_partial = partial_mode();
|
|
+
|
|
+ init_partial(1);
|
|
+ if (!(pv = pv_read(cmd, name, NULL, NULL, 1))) {
|
|
+ free(pvuuid_link);
|
|
+ init_partial(old_partial);
|
|
+ return NULL;
|
|
+ }
|
|
+ init_partial(old_partial);
|
|
+
|
|
+ pvuuid = malloc(sizeof(char)*40);
|
|
+ if (pvuuid == NULL) {
|
|
+ free(pvuuid_link);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ id_write_format(&pv->id, pvuuid, 40);
|
|
+
|
|
+ snprintf(pvuuid_link, 70, "/dev/disk/by-id/lvm2-pvuuid-%s", pvuuid);
|
|
+
|
|
+ //we really don't care if it successed or not.
|
|
+ if (create) {
|
|
+ const char* tname = NULL;
|
|
+ int r;
|
|
+ tname = pv_follow_if_link(name);
|
|
+ if (tname != NULL) {
|
|
+ r = symlink(tname, pvuuid_link);
|
|
+ free(tname);
|
|
+ }
|
|
+ else {
|
|
+ symlink(name, pvuuid_link);
|
|
+ }
|
|
+ } else {
|
|
+ //pvuuid_link is saved for future unlink
|
|
+ //unlink(pvuuid_link);
|
|
+ }
|
|
+
|
|
+ free(pvuuid);
|
|
+ return pvuuid_link;
|
|
+}
|
|
+
|
|
/*
|
|
* See if we may pvcreate on this device.
|
|
* 0 indicates we may not.
|
|
@@ -42,6 +131,7 @@
|
|
|
|
/* Is there a pv here already? */
|
|
/* FIXME Use partial mode here? */
|
|
+ init_partial(1);
|
|
pv = pv_read(cmd, name, NULL, NULL, 0);
|
|
|
|
/*
|
|
@@ -55,6 +145,7 @@
|
|
return_0;
|
|
pv = pv_read(cmd, name, NULL, NULL, 0);
|
|
}
|
|
+ init_partial(0);
|
|
|
|
/* Allow partial & exported VGs to be destroyed. */
|
|
/* We must have -ff to overwrite a non orphan */
|
|
@@ -151,6 +242,7 @@
|
|
const char *restorefile;
|
|
uint64_t pe_start = 0;
|
|
uint32_t extent_count = 0, extent_size = 0;
|
|
+ const char *oldsymlink;
|
|
|
|
if (arg_count(cmd, uuidstr_ARG)) {
|
|
uuid = arg_str_value(cmd, uuidstr_ARG, "");
|
|
@@ -258,13 +350,23 @@
|
|
|
|
log_very_verbose("Writing physical volume data to disk \"%s\"",
|
|
pv_name);
|
|
+
|
|
+ oldsymlink = pv_symlink_handle(cmd, pv_name, 0);
|
|
+
|
|
if (!(pv_write(cmd, (struct physical_volume *)pv, &mdas,
|
|
arg_int64_value(cmd, labelsector_ARG,
|
|
DEFAULT_LABELSECTOR)))) {
|
|
log_error("Failed to write physical volume \"%s\"", pv_name);
|
|
+ if (oldsymlink) free(oldsymlink);
|
|
goto error;
|
|
}
|
|
|
|
+ pv_symlink_handle(cmd, pv_name, 1);
|
|
+ if (oldsymlink) {
|
|
+ unlink(oldsymlink);
|
|
+ free(oldsymlink);
|
|
+ }
|
|
+
|
|
log_print("Physical volume \"%s\" successfully created", pv_name);
|
|
|
|
unlock_vg(cmd, VG_ORPHANS);
|
|
Index: LVM2.2.02.39/tools/pvchange.c
|
|
===================================================================
|
|
--- LVM2.2.02.39.orig/tools/pvchange.c 2008-02-06 16:47:28.000000000 +0100
|
|
+++ LVM2.2.02.39/tools/pvchange.c 2008-09-11 16:11:27.000000000 +0200
|
|
@@ -15,6 +15,95 @@
|
|
|
|
#include "tools.h"
|
|
|
|
+static const char* pv_follow_if_link (const char* path)
|
|
+{
|
|
+ int r;
|
|
+ int len = 60;
|
|
+ char *fpath = NULL;
|
|
+ char *npath = NULL;
|
|
+ struct stat st;
|
|
+
|
|
+ r = lstat(path, &st);
|
|
+ if (r == -1) return NULL; //shouldn't happen
|
|
+
|
|
+ if (S_ISLNK(st.st_mode)) {
|
|
+ while (1) {
|
|
+ npath = realloc(fpath, sizeof(char)*len);
|
|
+ if (npath == NULL) {
|
|
+ if (fpath != NULL) free(fpath);
|
|
+ return NULL;
|
|
+ }
|
|
+ fpath = npath;
|
|
+
|
|
+ memset(fpath, 0, sizeof(char)*len);
|
|
+ r = readlink(path, fpath, len);
|
|
+ if (r != -1 && fpath[len-1] == 0) break;
|
|
+ if (r == -1) {
|
|
+ free(fpath);
|
|
+ return NULL;
|
|
+ } else {
|
|
+ len = len * 2;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ fpath = strdup(path);
|
|
+ }
|
|
+ return fpath;
|
|
+}
|
|
+
|
|
+static const char* pv_symlink_handle(struct cmd_context* cmd, const char* name, int create)
|
|
+{
|
|
+ struct physical_volume *pv;
|
|
+ char *pvuuid;
|
|
+ char *pvuuid_link;
|
|
+ int old_partial;
|
|
+
|
|
+ pvuuid_link = malloc(70);
|
|
+ if (pvuuid_link == NULL) return NULL;
|
|
+
|
|
+ old_partial = partial_mode();
|
|
+
|
|
+ init_partial(1);
|
|
+ if (!(pv = pv_read(cmd, name, NULL, NULL, 1))) {
|
|
+ free(pvuuid_link);
|
|
+ init_partial(old_partial);
|
|
+ return NULL;
|
|
+ }
|
|
+ init_partial(old_partial);
|
|
+
|
|
+ pvuuid = malloc(sizeof(char)*40);
|
|
+ if (pvuuid == NULL) {
|
|
+ free(pvuuid_link);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ id_write_format(&pv->id, pvuuid, 40);
|
|
+
|
|
+ snprintf(pvuuid_link, 70, "/dev/disk/by-id/lvm2-pvuuid-%s", pvuuid);
|
|
+
|
|
+ //we really don't care if it successed or not.
|
|
+ if (create) {
|
|
+ const char* tname = NULL;
|
|
+ int r;
|
|
+ tname = pv_follow_if_link(name);
|
|
+ if (tname != NULL) {
|
|
+ r = symlink(tname, pvuuid_link);
|
|
+ free(tname);
|
|
+ }
|
|
+ else {
|
|
+ symlink(name, pvuuid_link);
|
|
+ }
|
|
+ } else {
|
|
+ //pvuuid_link is saved for future unlink
|
|
+ //unlink(pvuuid_link);
|
|
+ }
|
|
+
|
|
+ free(pvuuid);
|
|
+ return pvuuid_link;
|
|
+}
|
|
+
|
|
+
|
|
/* FIXME Locking. PVs in VG. */
|
|
|
|
static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
|
|
@@ -169,16 +258,28 @@
|
|
}
|
|
log_verbose("Changing uuid of %s to %s.", pv_name, uuid);
|
|
if (!is_orphan(pv)) {
|
|
+ const char* oldsymlink;
|
|
+
|
|
orig_vg_name = pv_vg_name(pv);
|
|
orig_pe_alloc_count = pv_pe_alloc_count(pv);
|
|
pv->vg_name = pv->fmt->orphan_vg_name;
|
|
pv->pe_alloc_count = 0;
|
|
+ oldsymlink = pv_symlink_handle(cmd, pv_name, 0);
|
|
+
|
|
if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
|
|
log_error("pv_write with new uuid failed "
|
|
"for %s.", pv_name);
|
|
+ if (oldsymlink) free(oldsymlink);
|
|
unlock_vg(cmd, vg_name);
|
|
return 0;
|
|
}
|
|
+
|
|
+ pv_symlink_handle(cmd, pv_name, 1);
|
|
+ if (oldsymlink) {
|
|
+ unlink(oldsymlink);
|
|
+ free(oldsymlink);
|
|
+ }
|
|
+
|
|
pv->vg_name = orig_vg_name;
|
|
pv->pe_alloc_count = orig_pe_alloc_count;
|
|
}
|
|
@@ -193,11 +294,23 @@
|
|
return 0;
|
|
}
|
|
backup(vg);
|
|
- } else if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
|
|
- unlock_vg(cmd, vg_name);
|
|
- log_error("Failed to store physical volume \"%s\"",
|
|
- pv_name);
|
|
- return 0;
|
|
+ } else {
|
|
+ const char* oldsymlink;
|
|
+ oldsymlink = pv_symlink_handle(cmd, pv_name, 0);
|
|
+
|
|
+ if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
|
|
+ unlock_vg(cmd, vg_name);
|
|
+ log_error("Failed to store physical volume \"%s\"",
|
|
+ pv_name);
|
|
+ if (oldsymlink) free(oldsymlink);
|
|
+ return 0;
|
|
+ }
|
|
+ pv_symlink_handle(cmd, pv_name, 1);
|
|
+ if (oldsymlink) {
|
|
+ unlink(oldsymlink);
|
|
+ free(oldsymlink);
|
|
+ }
|
|
+
|
|
}
|
|
|
|
unlock_vg(cmd, vg_name);
|