diff options
author | Kees Cook | 2008-03-20 09:24:03 +0100 |
---|---|---|
committer | Karel Zak | 2008-03-20 14:42:59 +0100 |
commit | 6274b9877822c9e3ee9eebc5f38fe246ba13197c (patch) | |
tree | 35d6376d0c8ec7d876e84be1afffbf9eea960ce0 /mount | |
parent | build-sys: cleanup "x$foo" usage (diff) | |
download | kernel-qcow2-util-linux-6274b9877822c9e3ee9eebc5f38fe246ba13197c.tar.gz kernel-qcow2-util-linux-6274b9877822c9e3ee9eebc5f38fe246ba13197c.tar.xz kernel-qcow2-util-linux-6274b9877822c9e3ee9eebc5f38fe246ba13197c.zip |
swapon: Reinitialize software suspend areas to avoid future corruption.
This is based on the earlier swsuspend re-init patch carried by
RedHat, SuSE, and Ubuntu. It has been updated to include passing
the known UUID to mkswap, and fixing the fstype name.
Co-Author: Karel Zak <kzak@redhat.com>
Signed-off-by: Kees Cook <kees.cook@canonical.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'mount')
-rw-r--r-- | mount/swapon.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/mount/swapon.c b/mount/swapon.c index 37af9ee66..6fce6fd62 100644 --- a/mount/swapon.c +++ b/mount/swapon.c @@ -10,6 +10,9 @@ #include <errno.h> #include <sys/stat.h> #include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <fcntl.h> #include "xmalloc.h" #include "swap_constants.h" #include "nls.h" @@ -18,6 +21,8 @@ #include "pathnames.h" #include "sundries.h" +#define PATH_MKSWAP "/sbin/mkswap" + #ifdef HAVE_SYS_SWAP_H # include <sys/swap.h> #endif @@ -175,6 +180,64 @@ display_summary(void) } static int +swap_is_suspend(const char *device) { + const char *type = fsprobe_get_fstype_by_devname(device); + + return (type && strcmp(type, "suspend") == 0) ? 1 : 0; +} + +/* calls mkswap */ +static int +swap_reinitialize(const char *device) { + const char *label = fsprobe_get_label_by_devname(device); + const char *uuid = fsprobe_get_uuid_by_devname(device); + pid_t pid; + int status, ret; + char *cmd[7]; + int idx=0; + + switch((pid=fork())) { + case -1: /* fork error */ + fprintf(stderr, _("%s: cannot fork: %s\n"), + progname, strerror(errno)); + return -1; + + case 0: /* child */ + cmd[idx++] = PATH_MKSWAP; + if (label && *label) { + cmd[idx++] = "-L"; + cmd[idx++] = (char *) label; + } + if (uuid && *uuid) { + cmd[idx++] = "-U"; + cmd[idx++] = (char *) uuid; + } + cmd[idx++] = (char *) device; + cmd[idx++] = NULL; + execv(cmd[0], cmd); + perror("execv"); + exit(1); /* error */ + + default: /* parent */ + do { + if ((ret = waitpid(pid, &status, 0)) < 0 + && errno == EINTR) + continue; + else if (ret < 0) { + fprintf(stderr, _("%s: waitpid: %s\n"), + progname, strerror(errno)); + return -1; + } + } while (0); + + /* mkswap returns: 0=suss, 1=error */ + if (WIFEXITED(status) && WEXITSTATUS(status)==0) + return 0; /* ok */ + } + return -1; /* error */ +} + +static int do_swapon(const char *orig_special, int prio, int canonic) { int status; struct stat st; @@ -196,6 +259,18 @@ do_swapon(const char *orig_special, int prio, int canonic) { return -1; } + /* We have to reinitialize swap with old (=useless) software suspend + * data. The problem is that if we don't do it, then we get data + * corruption the next time an attempt at unsuspending is made. + */ + if (swap_is_suspend(special)) { + fprintf(stdout, _("%s: %s: software suspend data detected. " + "Reinitializing the swap.\n"), + progname, special); + if (swap_reinitialize(special) < 0) + return -1; + } + /* people generally dislike this warning - now it is printed only when `verbose' is set */ if (verbose) { |