Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 152288 Details for
Bug 174701
pvcreate should automatically make a backup of what it overwrites
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
lvm2-pvcreate-undo-prelim
lvm2-pvcreate-undo-prelim.diff (text/plain), 21.41 KB, created by
Petr Rockai
on 2007-04-11 16:43:35 UTC
(
hide
)
Description:
lvm2-pvcreate-undo-prelim
Filename:
MIME Type:
Creator:
Petr Rockai
Created:
2007-04-11 16:43:35 UTC
Size:
21.41 KB
patch
obsolete
>Wed Apr 11 18:25:20 CEST 2007 me@mornfall.net > * style cleanups >Wed Apr 11 18:18:00 CEST 2007 me@mornfall.net > * improve messages >Wed Apr 11 18:17:00 CEST 2007 me@mornfall.net > * get rid of stderr debugging >Wed Apr 11 18:04:05 CEST 2007 me@mornfall.net > * fix temporary and permanent backup filename >Wed Apr 11 18:03:33 CEST 2007 me@mornfall.net > * output of eof indicates completed dev_backup >Wed Apr 11 17:40:23 CEST 2007 me@mornfall.net > * shuffle backup creation so we can back up bits pv_create overwrites >Wed Apr 11 17:40:09 CEST 2007 me@mornfall.net > * more _backup'd calls >Wed Apr 11 17:40:05 CEST 2007 me@mornfall.net > * formatting >Wed Apr 11 17:39:37 CEST 2007 me@mornfall.net > * debug output in dev backup/restore >Wed Apr 11 15:14:12 CEST 2007 me@mornfall.net > * back up zeroed bits of device >Wed Apr 11 15:13:56 CEST 2007 me@mornfall.net > * open/close the device around dev_restore >Wed Apr 11 15:13:15 CEST 2007 me@mornfall.net > * format_text pv_write now uses label_write_backup >Wed Apr 11 15:12:58 CEST 2007 me@mornfall.net > * add dev_set_backup >Wed Apr 11 15:12:27 CEST 2007 me@mornfall.net > * make dev_restore actually work >Wed Apr 11 14:18:21 CEST 2007 me@mornfall.net > * fix typo >Wed Apr 11 14:17:52 CEST 2007 me@mornfall.net > * write out the blocks in reverse order in dev_restore >Wed Apr 11 14:17:36 CEST 2007 me@mornfall.net > * fix the write loop in dev_backup >Wed Apr 11 14:02:48 CEST 2007 me@mornfall.net > * more retval check fixes >Wed Apr 11 14:01:21 CEST 2007 me@mornfall.net > * fix return value checks >Wed Apr 11 13:59:24 CEST 2007 me@mornfall.net > * fix close retval check >Wed Apr 11 13:58:16 CEST 2007 me@mornfall.net > * remove obsolete TODO >Wed Apr 11 13:57:33 CEST 2007 me@mornfall.net > * close the backup file >Wed Apr 11 13:57:22 CEST 2007 me@mornfall.net > * free buffer memory, fsync backup file >Wed Apr 11 13:54:39 CEST 2007 me@mornfall.net > * fix pvcreate to write/restore backups >Wed Apr 11 13:54:09 CEST 2007 me@mornfall.net > * add device_backup_fd to toolcontext and use it in text_format's pv_write >Wed Apr 11 13:53:45 CEST 2007 me@mornfall.net > * fix prototypes >Wed Apr 11 13:41:34 CEST 2007 me@mornfall.net > * implement label_remove_backup, drop label_restore_backup >Wed Apr 11 13:24:06 CEST 2007 me@mornfall.net > * implement dev_restore and adjust dev_backup > > dev_backup now writes [offset][length][block] into the filedescriptor > dev_restore reads in complete backupfile, writing each [length] [block] at > [offset] on the target device >Wed Apr 11 12:43:36 CEST 2007 me@mornfall.net > * initial implementation of pvcreate --undo >Wed Apr 11 12:43:21 CEST 2007 me@mornfall.net > * add --undo to pvcreate params >Wed Apr 11 12:43:08 CEST 2007 me@mornfall.net > * move archive_params to archiver.h for reuse >Tue Apr 10 23:57:35 CEST 2007 me@mornfall.net > * add todo comments >Tue Apr 10 23:57:14 CEST 2007 me@mornfall.net > * first go at label_restore_backup >Tue Apr 10 22:22:19 CEST 2007 me@mornfall.net > * prototypes >Tue Apr 10 22:20:45 CEST 2007 me@mornfall.net > * label_write_backup >Tue Apr 10 22:18:12 CEST 2007 me@mornfall.net > * first go on dev_backup and dev_write_backup >diff -rN -u old-work/lib/commands/toolcontext.c new-work/lib/commands/toolcontext.c >--- old-work/lib/commands/toolcontext.c 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/lib/commands/toolcontext.c 2007-04-11 18:29:17.562705610 +0200 >@@ -927,6 +927,7 @@ > cmd->is_static = is_static; > cmd->is_long_lived = is_long_lived; > cmd->hosttags = 0; >+ cmd->device_backup_fd = -1; > list_init(&cmd->formats); > list_init(&cmd->segtypes); > list_init(&cmd->tags); >@@ -1063,6 +1064,8 @@ > > cmd->config_valid = 0; > >+ cmd->device_backup_fd = -1; >+ > cmd->hosttags = 0; > > if (!_init_lvm_conf(cmd)) >diff -rN -u old-work/lib/commands/toolcontext.h new-work/lib/commands/toolcontext.h >--- old-work/lib/commands/toolcontext.h 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/lib/commands/toolcontext.h 2007-04-11 18:29:17.562705610 +0200 >@@ -87,6 +87,8 @@ > char sys_dir[PATH_MAX]; > char dev_dir[PATH_MAX]; > char proc_dir[PATH_MAX]; >+ >+ int device_backup_fd; > }; > > struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static, unsigned is_long_lived); >diff -rN -u old-work/lib/device/device.h new-work/lib/device/device.h >--- old-work/lib/device/device.h 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/lib/device/device.h 2007-04-11 18:29:17.562705610 +0200 >@@ -79,8 +79,14 @@ > > int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer); > int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer); >+int dev_backup(struct device *dev, uint64_t offset, size_t len, int fd); >+int dev_restore(struct device *dev, const char *file); >+int dev_write_backup(struct device *dev, uint64_t offset, size_t len, >+ void *buffer, int backupfd); > int dev_append(struct device *dev, size_t len, void *buffer); > int dev_set(struct device *dev, uint64_t offset, size_t len, int value); >+int dev_set_backup(struct device *dev, uint64_t offset, size_t len, int value, >+ int backupfd); > void dev_flush(struct device *dev); > > struct device *dev_create_file(const char *filename, struct device *dev, >diff -rN -u old-work/lib/device/dev-io.c new-work/lib/device/dev-io.c >--- old-work/lib/device/dev-io.c 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/lib/device/dev-io.c 2007-04-11 18:29:17.562705610 +0200 >@@ -605,8 +605,135 @@ > return _aligned_io(&where, buffer, 1); > } > >+int dev_backup(struct device *dev, uint64_t offset, size_t len, int fd) >+{ >+ char *buffer = dm_malloc(len + 2*sizeof(uint64_t)); >+ if (!buffer) >+ return 0; >+ *(uint64_t *)buffer = /*htonl(*/offset/*)*/; >+ *((uint64_t *)buffer + 1) = len; >+ if (!dev_read(dev, offset, len, buffer + 2*sizeof(uint64_t))) { >+ dm_free(buffer); >+ return 0; >+ } >+ int wrote = 0; >+ int total = len + 2*sizeof(uint64_t); >+ while (wrote < total) { >+ int w = write(fd, buffer + wrote, total - wrote); >+ if (w < 0) >+ return 0; >+ wrote += w; >+ assert(wrote <= total); >+ } >+ dm_free(buffer); >+ if (fsync(fd)) { >+ return 0; >+ } >+ return 1; >+} >+ >+/* write the blocks from the backup file in reverse order */ >+int dev_restore(struct device *dev, const char *file) >+{ >+ int fd; >+ int r; >+ int eof = 0; >+ int limsz = 2*sizeof(uint64_t); >+ char lims[limsz]; >+ int blocks = -1; >+ int pass = 0, current = -1; >+ uint64_t off, len; >+ char *buf; >+ int bytes; >+ >+ if ((fd = open(file, O_RDONLY)) < 0) { >+ log_error("Failed to open %s for reading", file); >+ return 0; >+ } >+ >+ while (1) { >+ next: >+ ++ pass; >+ assert(pass >= 1); >+ r = 0; >+ /* read in the limits */ >+ while (r < limsz) { >+ bytes = read(fd, lims + r, limsz - r); >+ if (bytes < 0) { >+ log_error("Failed read in %s", file); >+ close(fd); >+ return 0; >+ } >+ if (bytes == 0) { >+ assert(blocks == -1); >+ blocks = pass - 1; >+ current = blocks; >+ pass = 0; >+ lseek(fd, 0, SEEK_SET); >+ goto next; >+ } >+ r += bytes; >+ } >+ off = *(uint64_t *)lims; >+ len = *((uint64_t *)lims + 1); >+ /* we want to write this block now */ >+ if (pass == current) { >+ /* we start looking for the previous block in >+ next iteration */ >+ pass = 0; >+ -- current; >+ buf = dm_malloc(len); >+ if (!buf) { >+ close(fd); >+ return 0; >+ } >+ r = 0; >+ while (r < len) { >+ bytes = read(fd, buf + r, len - r); >+ if (bytes <= 0) { >+ log_error("Failed read in %s", file); >+ close(fd); >+ return 0; >+ } >+ r += bytes; >+ } >+ if (!dev_write(dev, off, len, buf)) { >+ log_error("Failed writing to device"); >+ dm_free(buf); >+ close(fd); >+ return 0; >+ } >+ lseek(fd, 0, SEEK_SET); >+ dm_free(buf); >+ } else { >+ /* skip this block for now */ >+ if (lseek(fd, len, SEEK_CUR) == -1) >+ log_error("Failed seeking %d bytes forward", len); >+ } >+ /* done */ >+ if (blocks >= 0 && current == 0) >+ break; >+ } >+ return 1; >+} >+ >+int dev_write_backup(struct device *dev, uint64_t offset, size_t len, >+ void *buffer, int backupfd) >+{ >+ if (backupfd > 0) >+ if (!dev_backup(dev, offset, len, backupfd)) >+ return 0; >+ return dev_write(dev, offset, len, buffer); >+} >+ > int dev_set(struct device *dev, uint64_t offset, size_t len, int value) > { >+ return dev_set_backup(dev, offset, len, value, -1); >+} >+ >+int dev_set_backup(struct device *dev, uint64_t offset, size_t len, int value, >+ int backupfd) >+{ > size_t s; > char buffer[4096] __attribute((aligned(8))); > >@@ -626,7 +753,7 @@ > memset(buffer, value, sizeof(buffer)); > while (1) { > s = len > sizeof(buffer) ? sizeof(buffer) : len; >- if (!dev_write(dev, offset, s, buffer)) >+ if (!dev_write_backup(dev, offset, s, buffer, backupfd)) > break; > > len -= s; >diff -rN -u old-work/lib/format_text/archiver.c new-work/lib/format_text/archiver.c >--- old-work/lib/format_text/archiver.c 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/lib/format_text/archiver.c 2007-04-11 18:29:17.562705610 +0200 >@@ -23,13 +23,6 @@ > > #include <unistd.h> > >-struct archive_params { >- int enabled; >- char *dir; >- unsigned int keep_days; >- unsigned int keep_number; >-}; >- > struct backup_params { > int enabled; > char *dir; >diff -rN -u old-work/lib/format_text/archiver.h new-work/lib/format_text/archiver.h >--- old-work/lib/format_text/archiver.h 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/lib/format_text/archiver.h 2007-04-11 18:29:17.562705610 +0200 >@@ -18,6 +18,13 @@ > > #include "metadata.h" > >+struct archive_params { >+ int enabled; >+ char *dir; >+ unsigned int keep_days; >+ unsigned int keep_number; >+}; >+ > /* > * There are two operations that come under the general area of > * backups. 'Archiving' occurs just before a volume group >diff -rN -u old-work/lib/format_text/format-text.c new-work/lib/format_text/format-text.c >--- old-work/lib/format_text/format-text.c 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/lib/format_text/format-text.c 2007-04-11 18:29:17.562705610 +0200 >@@ -197,7 +197,8 @@ > MDA_HEADER_SIZE - > sizeof(mdah->checksum_xl))); > >- if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) { >+ if (!dev_write_backup(dev, start_byte, MDA_HEADER_SIZE, mdah, >+ fmt->cmd->device_backup_fd)) { > stack; > dm_pool_free(fmt->cmd->mem, mdah); > return 0; >@@ -1087,9 +1088,10 @@ > mda_size1)) > return 0; > >- if (!dev_set((struct device *) pv->dev, start1, >- (size_t) (mda_size1 > >- wipe_size ? : mda_size1), 0)) { >+ if (!dev_set_backup((struct device *) pv->dev, start1, >+ (size_t) (mda_size1 > >+ wipe_size ? : mda_size1), 0, >+ fmt->cmd->device_backup_fd)) { > log_error("Failed to wipe new metadata area"); > return 0; > } >@@ -1132,9 +1134,11 @@ > if (mda_size2) { > if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start2, > mda_size2)) return 0; >- if (!dev_set(pv->dev, start2, >- (size_t) (mda_size1 > >- wipe_size ? : mda_size1), 0)) { >+ if (!dev_set_backup(pv->dev, start2, >+ (size_t) (mda_size1 > >+ wipe_size ? : mda_size1), 0, >+ fmt->cmd->device_backup_fd) >+ ) { > log_error("Failed to wipe new metadata area"); > return 0; > } >@@ -1239,7 +1243,7 @@ > } > } > >- label_write(pv->dev, label); >+ label_write_backup(pv->dev, label, fmt->cmd->device_backup_fd); > > if (!dev_close(pv->dev)) { > stack; >diff -rN -u old-work/lib/label/label.c new-work/lib/label/label.c >--- old-work/lib/label/label.c 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/lib/label/label.c 2007-04-11 18:29:17.562705610 +0200 >@@ -183,9 +183,14 @@ > return r; > } > >-/* FIXME Also wipe associated metadata area headers? */ > int label_remove(struct device *dev) > { >+ return label_remove_backup(dev, -1); >+} >+ >+/* FIXME Also wipe associated metadata area headers? */ >+int label_remove_backup(struct device *dev, int backupfd) >+{ > char buf[LABEL_SIZE] __attribute((aligned(8))); > char readbuf[LABEL_SCAN_SIZE] __attribute((aligned(8))); > int r = 1; >@@ -238,8 +243,8 @@ > if (wipe) { > log_info("%s: Wiping label at sector %" PRIu64, > dev_name(dev), sector); >- if (!dev_write(dev, sector << SECTOR_SHIFT, LABEL_SIZE, >- buf)) { >+ if (!dev_write_backup(dev, sector << SECTOR_SHIFT, >+ LABEL_SIZE, buf, backupfd)) { > log_error("Failed to remove label from %s at " > "sector %" PRIu64, dev_name(dev), > sector); >@@ -288,7 +293,7 @@ > } > > /* Caller may need to use label_get_handler to create label struct! */ >-int label_write(struct device *dev, struct label *label) >+int label_write_backup(struct device *dev, struct label *label, int backupfd) > { > char buf[LABEL_SIZE] __attribute((aligned(8))); > struct label_header *lh = (struct label_header *) buf; >@@ -326,7 +331,8 @@ > > log_info("%s: Writing label to sector %" PRIu64, dev_name(dev), > label->sector); >- if (!dev_write(dev, label->sector << SECTOR_SHIFT, LABEL_SIZE, buf)) { >+ if (!dev_write_backup(dev, label->sector << SECTOR_SHIFT, LABEL_SIZE, >+ buf, backupfd)) { > log_debug("Failed to write label to %s", dev_name(dev)); > r = 0; > } >@@ -337,6 +343,11 @@ > return r; > } > >+int label_write(struct device *dev, struct label *label) >+{ >+ return label_write_backup(dev, label, -1); >+} >+ > /* Unused */ > int label_verify(struct device *dev) > { >diff -rN -u old-work/lib/label/label.h new-work/lib/label/label.h >--- old-work/lib/label/label.h 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/lib/label/label.h 2007-04-11 18:29:17.562705610 +0200 >@@ -96,7 +96,9 @@ > struct labeller *label_get_handler(const char *name); > > int label_remove(struct device *dev); >+int label_remove_backup(struct device *dev, int backupfd); > int label_read(struct device *dev, struct label **result); >+int label_write_backup(struct device *dev, struct label *label, int backupfd); > int label_write(struct device *dev, struct label *label); > int label_verify(struct device *dev); > struct label *label_create(struct labeller *labeller); >diff -rN -u old-work/make.tmpl.in new-work/make.tmpl.in >--- old-work/make.tmpl.in 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/make.tmpl.in 2007-04-11 18:29:17.562705610 +0200 >@@ -66,7 +66,7 @@ > ifeq ("@DEBUG@", "yes") > CFLAGS += -g -fno-omit-frame-pointer > DEFS += -DDEBUG >- DEFS += -DDEBUG_MEM >+ #DEFS += -DDEBUG_MEM > endif > > ifeq ("@INTL@", "yes") >diff -rN -u old-work/tools/args.h new-work/tools/args.h >--- old-work/tools/args.h 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/tools/args.h 2007-04-11 18:29:17.562705610 +0200 >@@ -123,6 +123,7 @@ > arg(resizeable_ARG, 'x', "resizeable", yes_no_arg) > arg(yes_ARG, 'y', "yes", NULL) > arg(zero_ARG, 'Z', "zero", yes_no_arg) >+arg(undo_ARG, '\0', "undo", NULL) > > /* this should always be last */ > arg(ARG_COUNT, '-', "", NULL) >diff -rN -u old-work/tools/commands.h new-work/tools/commands.h >--- old-work/tools/commands.h 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/tools/commands.h 2007-04-11 18:29:17.562705610 +0200 >@@ -433,12 +433,13 @@ > "\t[-v|--verbose] " "\n" > "\t[-y|--yes]" "\n" > "\t[-Z|--zero {y|n}]\n" >+ "\t[--undo]\n" > "\t[--version] " "\n" > "\tPhysicalVolume [PhysicalVolume...]\n", > > force_ARG, test_ARG, labelsector_ARG, metadatatype_ARG, metadatacopies_ARG, > metadatasize_ARG, physicalvolumesize_ARG, restorefile_ARG, uuidstr_ARG, >- yes_ARG, zero_ARG) >+ yes_ARG, zero_ARG, undo_ARG) > > xx(pvdata, > "Display the on-disk metadata for physical volume(s)", >diff -rN -u old-work/tools/pvcreate.c new-work/tools/pvcreate.c >--- old-work/tools/pvcreate.c 2007-04-11 18:29:17.562705610 +0200 >+++ new-work/tools/pvcreate.c 2007-04-11 18:29:17.562705610 +0200 >@@ -14,6 +14,7 @@ > */ > > #include "tools.h" >+#include "archiver.h" > > struct pvcreate_params { > int zero; >@@ -22,6 +23,123 @@ > const char _really_init[] = > "Really INITIALIZE physical volume \"%s\" of volume group \"%s\" [y/n]? "; > >+const char _really_undo[] = >+ "Really WIPE LABELS and restore backup of physical volume \"%s\" of volume group \"%s\" [y/n]? "; >+ >+static int pvcreate_undo_check(struct cmd_context *cmd, const char *name, >+ char **back) >+{ >+ struct physical_volume *pv; >+ >+ /* is the partition type set correctly ? */ >+ if ((arg_count(cmd, force_ARG) < 1) && !is_lvm_partition(name)) { >+ log_error("%s: Not LVM partition type: use -f to override", >+ name); >+ return 0; >+ } >+ >+ /* Is there a pv here already? */ >+ /* If not, this is an error unless you used -f. */ >+ if (!(pv = pv_read(cmd, name, NULL, NULL, 1))) { >+ if (arg_count(cmd, force_ARG)) >+ return 1; >+ log_error("Physical Volume %s not found", name); >+ return 0; >+ } >+ >+ *back = dm_malloc(strlen(cmd->archive_params->dir) >+ + ID_LEN + 5); >+ strcpy(*back, cmd->archive_params->dir); >+ strcat(*back, "/"); >+ strncat(*back, pv->id.uuid, ID_LEN); >+ strcat(*back, ".pv"); >+ if (access(*back, R_OK) < 0) { >+ log_error("Can't access archive file %s", *back); >+ return 1; >+ } >+ >+ /* orphan ? */ >+ if (!pv->vg_name[0]) >+ return 1; >+ >+ /* Allow partial & exported VGs to be destroyed. */ >+ /* we must have -ff to overwrite a non orphan */ >+ if (arg_count(cmd, force_ARG) < 2) { >+ log_error("Can't pvremove physical volume \"%s\" of " >+ "volume group \"%s\" without -ff", name, pv->vg_name); >+ return 0; >+ } >+ >+ /* prompt */ >+ if (!arg_count(cmd, yes_ARG) && >+ yes_no_prompt(_really_undo, name, pv->vg_name) == 'n') { >+ log_print("%s: physical volume label not removed", name); >+ return 0; >+ } >+ >+ if (arg_count(cmd, force_ARG)) { >+ log_print("WARNING: Wiping physical volume label from " >+ "%s%s%s%s and restoring backup", name, >+ pv->vg_name[0] ? " of volume group \"" : "", >+ pv->vg_name[0] ? pv->vg_name : "", >+ pv->vg_name[0] ? "\"" : ""); >+ } >+ >+ return 1; >+} >+ >+static int pvcreate_undo(struct cmd_context *cmd, const char *name) >+{ >+ struct device *dev; >+ char *back; >+ >+ if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) { >+ log_error("Can't get lock for orphan PVs"); >+ return ECMD_FAILED; >+ } >+ >+ if (!pvcreate_undo_check(cmd, name, &back)) >+ goto error; >+ >+ if (!(dev = dev_cache_get(name, cmd->filter))) { >+ log_error("%s: Couldn't find device. Check your filters?", >+ name); >+ goto error; >+ } >+ >+ if (!dev_test_excl(dev)) { >+ log_error("Can't open %s exclusively - not removing. " >+ "Mounted filesystem?", dev_name(dev)); >+ goto error; >+ } >+ >+ if (!dev_open(dev)) { >+ log_error("Failed opening %s", dev_name(dev)); >+ goto error; >+ } >+ >+ /* Wipe existing label(s) */ >+ if (!dev_restore(dev, back)) { >+ log_error("Failed to restore backup of %s", name); >+ goto error; >+ } >+ >+ if (!dev_close(dev)) { >+ log_error("Failed to close device %s", name); >+ goto error; >+ } >+ >+ log_print("Device \"%s\" successfully restored from backup", >+ name); >+ >+ unlock_vg(cmd, ORPHAN); >+ return ECMD_PROCESSED; >+ >+ error: >+ unlock_vg(cmd, ORPHAN); >+ return ECMD_FAILED; >+} >+ > /* > * See if we may pvcreate on this device. > * 0 indicates we may not. >@@ -96,6 +214,7 @@ > (yes_no_prompt("Software RAID md superblock " > "detected on %s. Wipe it? [y/n] ", name) == 'y'))) { > log_print("Wiping software RAID md superblock on %s", name); >+ /* TODO back up the raid md superblock! */ > if (!dev_set(dev, md_superblock, 4, 0)) { > log_error("Failed to wipe RAID md superblock on %s", > name); >@@ -130,6 +249,8 @@ > const char *restorefile; > uint64_t pe_start = 0; > uint32_t extent_count = 0, extent_size = 0; >+ char *back, *permback; >+ int backupfd; > > if (arg_count(cmd, uuidstr_ARG)) { > uuid = arg_str_value(cmd, uuidstr_ARG, ""); >@@ -201,6 +322,23 @@ > goto error; > } > >+ back = dm_malloc(strlen(cmd->archive_params->dir) + 32); >+ strcpy(back, cmd->archive_params->dir); >+ strcat(back, "/"); >+ strcat(back, "pvcreate-backup.XXXXXX"); >+ >+ backupfd = mkstemp(back); >+ >+ if (backupfd < 0) { >+ log_error("Failed to create backup file %s", back); >+ goto error; >+ } >+ >+ cmd->device_backup_fd = backupfd; >+ >+ /* note that pv_create writes some bits to the device... evil, >+ evil thing */ >+ > list_init(&mdas); > if (!(pv = pv_create(cmd->fmt, dev, idp, size, pe_start, > extent_count, extent_size, >@@ -208,12 +346,30 @@ > log_error("Failed to setup physical volume \"%s\"", pv_name); > goto error; > } >+ >+ permback = dm_malloc(strlen(cmd->archive_params->dir) >+ + ID_LEN + 5); >+ strcpy(permback, cmd->archive_params->dir); >+ strcat(permback, "/"); >+ strncat(permback, pv->id.uuid, ID_LEN); >+ strcat(permback, ".pv"); >+ >+ if (link(back, permback) < 0) { >+ log_error("Failed to create %s", permback); >+ } >+ >+ if (unlink(back) < 0) { >+ log_error("Failed to unlink %s", back); >+ } >+ >+ dm_free(back); >+ dm_free(permback); > > log_verbose("Set up physical volume for \"%s\" with %" PRIu64 > " available sectors", pv_name, pv->size); > > /* Wipe existing label first */ >- if (!label_remove(pv->dev)) { >+ if (!label_remove_backup(pv->dev, backupfd)) { > log_error("Failed to wipe existing label on %s", pv_name); > goto error; > } >@@ -225,8 +381,8 @@ > goto error; > } > >- if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) { >- log_error("%s not wiped: aborting", pv_name); >+ if (!dev_set_backup(dev, UINT64_C(0), (size_t) 2048, 0, backupfd)) { >+ log_error("%s not restored: aborting", pv_name); > dev_close(dev); > goto error; > } >@@ -240,6 +396,10 @@ > log_error("Failed to write physical volume \"%s\"", pv_name); > goto error; > } >+ cmd->device_backup_fd = -1; >+ if (close(backupfd) < 0) { >+ log_error("Failed to close backup file"); >+ } > > log_print("Physical volume \"%s\" successfully created", pv_name); > >@@ -255,6 +415,7 @@ > { > int i, r; > int ret = ECMD_PROCESSED; >+ int undo = 0; > struct pvcreate_params pp; > > if (!argc) { >@@ -303,8 +464,14 @@ > else > pp.zero = 1; > >+ if (arg_count(cmd, undo_ARG)) >+ undo = 1; >+ > for (i = 0; i < argc; i++) { >- r = pvcreate_single(cmd, argv[i], &pp); >+ if (undo) >+ r = pvcreate_undo(cmd, argv[i]); >+ else >+ r = pvcreate_single(cmd, argv[i], &pp); > if (r > ret) > ret = r; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 174701
:
152288
|
152529