diff --git a/util-linux-2.12r-mount_swapon_swsuspend_resume.patch b/util-linux-2.12r-mount_swapon_swsuspend_resume.patch new file mode 100644 index 0000000..32ebc77 --- /dev/null +++ b/util-linux-2.12r-mount_swapon_swsuspend_resume.patch @@ -0,0 +1,156 @@ +## 30swsusp-resume.dpatch by Jeff Bailey +diff -urNad --exclude=CVS --exclude=.svn ./mount/get_label_uuid.c /tmp/dpep-work.5ak7Cm/util-linux/mount/get_label_uuid.c +--- ./mount/get_label_uuid.c 2004-12-22 08:44:32.000000000 -0700 ++++ /tmp/dpep-work.5ak7Cm/util-linux/mount/get_label_uuid.c 2005-12-06 11:54:33.000000000 -0700 +@@ -93,7 +93,25 @@ + } + return 0; + } +- ++ ++static int ++is_swsuspend_partition(int fd, char **label, char *uuid) { ++ int n = getpagesize(); ++ char *buf = xmalloc(n); ++ struct swap_header_v1_2 *p = (struct swap_header_v1_2 *) buf; ++ ++ if (lseek(fd, 0, SEEK_SET) == 0 ++ && read(fd, buf, n) == n ++ && (strncmp(buf+n-10, "S1SUSPEND", 9)==0 || ++ strncmp(buf+n-10, "S2SUSPEND", 9)==0 || ++ strncmp(buf+n-10, "ULSUSPEND", 9)==0) ++ && p->version == 1) { ++ store_uuid(uuid, p->uuid); ++ store_label(label, p->volume_name, 16); ++ return 1; ++ } ++ return 0; ++} + + /* + * Get both label and uuid. +@@ -126,6 +143,8 @@ + + if (is_v1_swap_partition(fd, label, uuid)) + goto done; ++ if (is_swsuspend_partition(fd, label, uuid)) ++ goto done; + + if (lseek(fd, 1024, SEEK_SET) == 1024 + && read(fd, (char *) &e2sb, sizeof(e2sb)) == sizeof(e2sb) +diff -urNad --exclude=CVS --exclude=.svn ./mount/swapon.c /tmp/dpep-work.5ak7Cm/util-linux/mount/swapon.c +--- ./mount/swapon.c 2004-12-22 08:44:32.000000000 -0700 ++++ /tmp/dpep-work.5ak7Cm/util-linux/mount/swapon.c 2005-12-06 11:54:33.000000000 -0700 +@@ -22,6 +25,7 @@ + + #define _PATH_FSTAB "/etc/fstab" + #define PROC_SWAPS "/proc/swaps" ++#define PATH_MKSWAP "/sbin/mkswap" + + #define SWAPON_NEEDS_TWO_ARGS + +@@ -164,6 +168,85 @@ + return 0 ; + } + ++/* ++ * It's better do swsuspend detection by follow routine than ++ * include huge mount_guess_fstype.o to swapon. We need only ++ * swsuspend and no the others filesystems. ++ */ ++#ifdef HAVE_LIBBLKID ++static int ++swap_is_swsuspend(const char *device) { ++ const char *type = blkid_get_tag_value(blkid, "TYPE", device); ++ ++ if (type && strcmp(type, "swsuspend")==0) ++ return 0; ++ return 1; ++} ++#else ++static int ++swap_is_swsuspend(const char *device) { ++ int fd, re = 1, n = getpagesize() - 10; ++ char buf[10]; ++ ++ fd = open(device, O_RDONLY); ++ if (fd < 0) ++ return -1; ++ ++ if (lseek(fd, n, SEEK_SET) >= 0 && ++ read(fd, buf, sizeof buf) == sizeof buf && ++ (memcmp("S1SUSPEND", buf, 9)==0 || ++ memcmp("S2SUSPEND", buf, 9)==0 || ++ memcmp("ULSUSPEND", buf, 9)==0)) ++ re = 0; ++ ++ close(fd); ++ return re; ++} ++#endif ++ ++/* calls mkswap */ ++static int ++swap_reinitialize(const char *device) { ++ const char *label = mount_get_volume_label_by_spec(device); ++ pid_t pid; ++ ++ switch((pid=fork())) { ++ case -1: /* fork error */ ++ fprintf(stderr, _("%s: cannot fork: %s\n"), ++ progname, strerror(errno)); ++ return -1; ++ ++ case 0: /* child */ ++ if (label && *label) ++ execl(PATH_MKSWAP, PATH_MKSWAP, "-L", label, device, NULL); ++ else ++ execl(PATH_MKSWAP, PATH_MKSWAP, device, NULL); ++ exit(1); /* error */ ++ ++ default: /* parent */ ++ { ++ int status; ++ int ret; ++ ++ 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 status; +@@ -187,6 +269,18 @@ + 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 with suspended on. ++ */ ++ if (swap_is_swsuspend(special)==0) { ++ 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) { diff --git a/util-linux.changes b/util-linux.changes index 5249a73..5bc7c13 100644 --- a/util-linux.changes +++ b/util-linux.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Mar 15 17:24:34 CET 2007 - mkoenig@suse.de + +- mount: Let swapon automatically reinitialize a suspended + swap partition [#254437] + ------------------------------------------------------------------- Thu Mar 9 11:00:11 CET 2007 - mkoenig@suse.de diff --git a/util-linux.spec b/util-linux.spec index 85b572a..d331f68 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -20,7 +20,7 @@ License: BSD License and BSD-like, GNU General Public License (GPL) Group: System/Base Autoreqprov: on Version: 2.12r -Release: 80 +Release: 82 Summary: A collection of basic system utilities Source: ftp://ftp.kernel.org/pub/linux/utils/util-linux/%name-%version.tar.bz2 Source2: nologin.c @@ -112,6 +112,7 @@ Patch110: util-linux-2.12r-mkfs_open_exclusive.patch Patch111: util-linux-2.12r-fdisk_remove_bogus_warnings.patch Patch112: util-linux-2.12r-mount_racy_loop.patch Patch113: util-linux-2.12r-partx_gpt_warning.patch +Patch114: util-linux-2.12r-mount_swapon_swsuspend_resume.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build PreReq: %insserv_prereq %fillup_prereq /bin/sed @@ -189,6 +190,7 @@ cd - %patch111 -p1 %patch112 -p1 %patch113 -p1 +%patch114 -p1 # setctsid cp %{S:22} %{S:23} . # nologin and guessfstype @@ -622,6 +624,9 @@ fi %endif %changelog +* Thu Mar 15 2007 - mkoenig@suse.de +- mount: Let swapon automatically reinitialize a suspended + swap partition [#254437] * Fri Mar 09 2007 - mkoenig@suse.de - mount: fix mtablock patch to avoid mtab corruption [#226783] * Thu Mar 08 2007 - mkoenig@suse.de