[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
[lvm-devel] [PATCH] pvcreate: conditionally wipe swap signatures
- From: Petr Rockai <prockai redhat com>
- To: lvm-devel redhat com
- Subject: [lvm-devel] [PATCH] pvcreate: conditionally wipe swap signatures
- Date: Mon, 16 Mar 2009 19:56:40 +0100
Hi,
this should address https://bugzilla.redhat.com/show_bug.cgi?id=443062 -- the
first patch implements the actual check, in the spirit of dev_is_md (it also
gets a check in the testsuite). The code is based on swap signature detection
in swapon implementation of util-linux-ng:
http://git.kernel.org/?p=utils/util-linux-ng/util-linux-ng.git;a=blob_plain;f=mount/swapon.c
The latter patch just throws in some checks that the old code misses. They
might as well be redundant (or not, depends on how you look at it). Personally,
I am ambivalent -- advice about (non-)inclusion sought.
Mon Mar 16 19:45:02 CET 2009 Petr Rockai <me mornfall net>
* Detect and wipe swap signatures in pvcreate.
diff -rN -u -p old-swap-check/lib/device/device.h new-swap-check/lib/device/device.h
--- old-swap-check/lib/device/device.h 2009-03-16 19:51:08.067884748 +0100
+++ new-swap-check/lib/device/device.h 2009-03-16 19:51:08.231882756 +0100
@@ -93,6 +93,7 @@ const char *dev_name_confirmed(struct de
/* Does device contain md superblock? If so, where? */
int dev_is_md(struct device *dev, uint64_t *sb);
+int dev_is_swap(struct device *dev, uint64_t *signature);
unsigned long dev_md_chunk_size(const char *sysfs_dir, struct device *dev);
int is_partitioned_dev(struct device *dev);
diff -rN -u -p old-swap-check/lib/device/dev-swap.c new-swap-check/lib/device/dev-swap.c
--- old-swap-check/lib/device/dev-swap.c 1970-01-01 01:00:00.000000000 +0100
+++ new-swap-check/lib/device/dev-swap.c 2009-03-16 19:51:08.227882596 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "lib.h"
+#include "metadata.h"
+#include "xlate.h"
+#include "filter.h"
+
+#ifdef linux
+
+#define MAX_PAGESIZE (64 * 1024)
+#define SIGNATURE_SIZE 10
+
+static int
+_swap_detect_signature(const char *buf)
+{
+ if (memcmp(buf, "SWAP-SPACE", 10) == 0 ||
+ memcmp(buf, "SWAPSPACE2", 10) == 0)
+ return 1;
+
+ if (memcmp(buf, "S1SUSPEND", 9) == 0 ||
+ memcmp(buf, "S2SUSPEND", 9) == 0 ||
+ memcmp(buf, "ULSUSPEND", 9) == 0 ||
+ memcmp(buf, "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8) == 0)
+ return 1;
+
+ return 0;
+}
+
+int dev_is_swap(struct device *dev, uint64_t *signature)
+{
+ char buf[10];
+ uint64_t size;
+ int page;
+
+ if (!dev_get_size(dev, &size)) {
+ stack;
+ return -1;
+ }
+
+ if (!dev_open(dev)) {
+ stack;
+ return -1;
+ }
+
+ *signature = 0;
+
+ for (page = 0x1000; page <= MAX_PAGESIZE; page <<= 1) {
+ /*
+ * skip 32k pagesize since this does not seem to be supported
+ */
+ if (page == 0x8000)
+ continue;
+ if (size < page)
+ break;
+ if (!dev_read(dev, page - SIGNATURE_SIZE,
+ SIGNATURE_SIZE, buf)) {
+ stack;
+ return -1;
+ }
+ if (_swap_detect_signature(buf)) {
+ *signature = page - SIGNATURE_SIZE;
+ break;
+ }
+ }
+
+ if (!dev_close(dev))
+ stack;
+
+ if (*signature)
+ return 1;
+
+ return 0;
+}
+
+#endif
diff -rN -u -p old-swap-check/lib/Makefile.in new-swap-check/lib/Makefile.in
--- old-swap-check/lib/Makefile.in 2009-03-16 19:51:08.067884748 +0100
+++ new-swap-check/lib/Makefile.in 2009-03-16 19:51:08.211882309 +0100
@@ -42,6 +42,7 @@ SOURCES =\
device/dev-cache.c \
device/dev-io.c \
device/dev-md.c \
+ device/dev-swap.c \
device/device.c \
display/display.c \
error/errseg.c \
diff -rN -u -p old-swap-check/test/t-pvcreate-operation.sh new-swap-check/test/t-pvcreate-operation.sh
--- old-swap-check/test/t-pvcreate-operation.sh 2009-03-16 19:51:08.067884748 +0100
+++ new-swap-check/test/t-pvcreate-operation.sh 2009-03-16 19:51:08.423884253 +0100
@@ -108,3 +108,10 @@ not pvcreate --uuid $uuid1 --restorefile
pvcreate --uuid $uuid1 $dev1
vgcfgbackup -f $backupfile
not pvcreate --uuid $uuid2 --restorefile $backupfile $dev2
+
+# pvcreate wipes swap signature when forced
+dd if=/dev/zero of=$dev1 bs=1024 count=64
+mkswap $dev1
+file -s $dev1 | grep "swap file"
+pvcreate -f $dev1
+file -s $dev1 | not grep "swap file"
diff -rN -u -p old-swap-check/tools/pvcreate.c new-swap-check/tools/pvcreate.c
--- old-swap-check/tools/pvcreate.c 2009-03-16 19:51:08.067884748 +0100
+++ new-swap-check/tools/pvcreate.c 2009-03-16 19:51:08.523885580 +0100
@@ -45,7 +45,7 @@ static int pvcreate_check(struct cmd_con
{
struct physical_volume *pv;
struct device *dev;
- uint64_t md_superblock;
+ uint64_t md_superblock, swap_signature;
/* FIXME Check partition type is LVM unless --force is given */
@@ -129,6 +129,17 @@ static int pvcreate_check(struct cmd_con
}
}
+ if (dev_is_swap(dev, &swap_signature) &&
+ ((!pp->idp && !pp->restorefile) || pp->yes ||
+ (yes_no_prompt("Swap signature detected on %s. Wipe it? [y/n] ",
+ name) == 'y'))) {
+ log_print("Wiping swap signature on %s", name);
+ if (!dev_set(dev, swap_signature, 10, 0)) {
+ log_error("Failed to wipe swap signature on %s", name);
+ return 0;
+ }
+ }
+
if (sigint_caught())
return 0;
Mon Mar 16 19:49:33 CET 2009 Petr Rockai <me mornfall net>
* Some extra (paranoid) checks on dev_is_{md,swap} result.
diff -rN -u -p old-swap-check/tools/pvcreate.c new-swap-check/tools/pvcreate.c
--- old-swap-check/tools/pvcreate.c 2009-03-16 19:51:15.095886212 +0100
+++ new-swap-check/tools/pvcreate.c 2009-03-16 19:51:15.471884837 +0100
@@ -46,6 +46,7 @@ static int pvcreate_check(struct cmd_con
struct physical_volume *pv;
struct device *dev;
uint64_t md_superblock, swap_signature;
+ int wipe_md, wipe_swap;
/* FIXME Check partition type is LVM unless --force is given */
@@ -117,7 +118,7 @@ static int pvcreate_check(struct cmd_con
}
/* Wipe superblock? */
- if (dev_is_md(dev, &md_superblock) &&
+ if ((wipe_md = dev_is_md(dev, &md_superblock)) == 1 &&
((!pp->idp && !pp->restorefile) || pp->yes ||
(yes_no_prompt("Software RAID md superblock "
"detected on %s. Wipe it? [y/n] ", name) == 'y'))) {
@@ -129,7 +130,13 @@ static int pvcreate_check(struct cmd_con
}
}
- if (dev_is_swap(dev, &swap_signature) &&
+ if (wipe_md == -1) {
+ log_error("Fatal error while trying to detect software "
+ "RAID md superblock on %s", name);
+ return 0;
+ }
+
+ if ((wipe_swap = dev_is_swap(dev, &swap_signature)) == 1 &&
((!pp->idp && !pp->restorefile) || pp->yes ||
(yes_no_prompt("Swap signature detected on %s. Wipe it? [y/n] ",
name) == 'y'))) {
@@ -140,6 +147,12 @@ static int pvcreate_check(struct cmd_con
}
}
+ if (wipe_swap == -1) {
+ log_error("Fatal error while trying to detect swap "
+ "signature on %s", name);
+ return 0;
+ }
+
if (sigint_caught())
return 0;
Yours,
Petr.
--
Peter Rockai | me()mornfall!net | prockai()redhat!com
http://blog.mornfall.net | http://web.mornfall.net
"In My Egotistical Opinion, most people's C programs should be
indented six feet downward and covered with dirt."
-- Blair P. Houghton on the subject of C program indentation
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]