summaryrefslogtreecommitdiffstats
path: root/mount/swapon.c
diff options
context:
space:
mode:
authorKarel Zak2009-03-02 16:41:03 +0100
committerKarel Zak2009-03-03 15:21:38 +0100
commit617d8a3bf4516924a73a02c5cb7bf4195a7f2c66 (patch)
tree9aed2aeed3685235bd332a745f22c6e1d58c7f1f /mount/swapon.c
parentswapon: do_swapon() refactoring (split into two functions) (diff)
downloadkernel-qcow2-util-linux-617d8a3bf4516924a73a02c5cb7bf4195a7f2c66.tar.gz
kernel-qcow2-util-linux-617d8a3bf4516924a73a02c5cb7bf4195a7f2c66.tar.xz
kernel-qcow2-util-linux-617d8a3bf4516924a73a02c5cb7bf4195a7f2c66.zip
swapon: rewrite SWSUSPEND signature rather than exec mkswap
> On Thu, Jan 22, 2009 at 04:46:57PM +0000, Hugh Dickins wrote: > Though your swapon may mkswap for suspend reasons: hmm, wouldn't it > do very much better just to rewrite the swap signature, than exec > mkswap - maybe nobody ever uses the badpages list, but it really > should be respected. CC: Hugh Dickins <hugh@veritas.com> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'mount/swapon.c')
-rw-r--r--mount/swapon.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/mount/swapon.c b/mount/swapon.c
index 1c337c266..d61ff7437 100644
--- a/mount/swapon.c
+++ b/mount/swapon.c
@@ -48,6 +48,9 @@ enum {
SIG_SWSUSPEND
};
+#define SWAP_SIGNATURE "SWAPSPACE2"
+#define SWAP_SIGNATURE_SZ (sizeof(SWAP_SIGNATURE) - 1)
+
int all;
int priority = -1; /* non-prioritized swap by default */
@@ -229,6 +232,30 @@ swap_reinitialize(const char *device) {
}
static int
+swap_rewrite_signature(const char *devname, unsigned int pagesize)
+{
+ int fd, rc = -1;
+
+ fd = open(devname, O_WRONLY);
+ if (fd == -1) {
+ warn(_("%s: open failed"), devname);
+ return -1;
+ }
+
+ if (lseek(fd, pagesize - SWAP_SIGNATURE_SZ, SEEK_SET) < 0)
+ goto err;
+
+ if (write(fd, (void *) SWAP_SIGNATURE,
+ SWAP_SIGNATURE_SZ) != SWAP_SIGNATURE_SZ)
+ goto err;
+
+ rc = 0;
+err:
+ close(fd);
+ return rc;
+}
+
+static int
swap_detect_signature(const char *buf, int *sig)
{
if (memcmp(buf, "SWAP-SPACE", 10) == 0 ||
@@ -271,9 +298,9 @@ swap_get_header(int fd, int *sig, unsigned int *pagesize)
continue;
/* the smallest swap area is PAGE_SIZE*10, it means
* 40k, that's less than MAX_PAGESIZE */
- if (datasz < (page - 10))
+ if (datasz < (page - SWAP_SIGNATURE_SZ))
break;
- if (swap_detect_signature(buf + page - 10, sig)) {
+ if (swap_detect_signature(buf + page - SWAP_SIGNATURE_SZ, sig)) {
*pagesize = page;
break;
}
@@ -318,7 +345,6 @@ swap_get_size(const char *hdr, const char *devname, unsigned int pagesize)
static int
swapon_checks(const char *special)
{
- int reinitialize = 0;
struct stat st;
int fd = -1, sig;
char *hdr = NULL;
@@ -384,7 +410,8 @@ swapon_checks(const char *special)
warn(_("%s: swap format pagesize does not match."
" Reinitializing the swap."),
special);
- reinitialize = 1;
+ if (swap_reinitialize(special) < 0)
+ goto err;
}
} else if (sig == SIG_SWSUSPEND) {
/* We have to reinitialize swap with old (=useless) software suspend
@@ -392,20 +419,15 @@ swapon_checks(const char *special)
* corruption the next time an attempt at unsuspending is made.
*/
warnx(_("%s: software suspend data detected. "
- "Reinitializing the swap."),
+ "Rewriting the swap signature."),
special);
- reinitialize = 1;
- }
-
- if (reinitialize) {
- if (swap_reinitialize(special) < 0)
+ if (swap_rewrite_signature(special, pagesize) < 0)
goto err;
}
free(hdr);
close(fd);
return 0;
-
err:
if (fd != -1)
close(fd);