## 30swsusp-resume.dpatch by Jeff Bailey <jbailey@ubuntu.com>
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) {