mschorm / rpms / util-linux

Forked from rpms/util-linux 2 years ago
Clone
2ac050e
--- util-linux-2.13-pre2/mount/swapon.c.swsuspend	2005-09-02 14:32:53.000000000 +0200
2ac050e
+++ util-linux-2.13-pre2/mount/swapon.c	2005-09-02 16:29:43.000000000 +0200
2ac050e
@@ -11,6 +11,9 @@
2ac050e
 #include <mntent.h>
2ac050e
 #include <errno.h>
2ac050e
 #include <sys/stat.h>
2ac050e
+#include <sys/types.h>
2ac050e
+#include <sys/wait.h>
2ac050e
+#include <fcntl.h>
2ac050e
 #include "xmalloc.h"
2ac050e
 #include "swap_constants.h"
2ac050e
 #include "swapargs.h"
2ac050e
@@ -22,6 +25,7 @@
2ac050e
 
2ac050e
 #define	_PATH_FSTAB     "/etc/fstab"
2ac050e
 #define PROC_SWAPS      "/proc/swaps"
2ac050e
+#define PATH_MKSWAP	"/sbin/mkswap"
2ac050e
 
2ac050e
 #define SWAPON_NEEDS_TWO_ARGS
2ac050e
 
2ac050e
@@ -173,6 +177,84 @@
2ac050e
        return 0 ;
2ac050e
 }
2ac050e
 
2ac050e
+/*
2ac050e
+ * It's better do swsuspend detection by follow routine than
2ac050e
+ * include huge mount_guess_fstype.o to swapon. We need only
2ac050e
+ * swsuspend and no the others filesystems.
2ac050e
+ */
2ac050e
+#ifdef HAVE_LIBBLKID
2ac050e
+static int
2ac050e
+swap_is_swsuspend(const char *device) {
2ac050e
+	const char *type = blkid_get_tag_value(blkid, "TYPE", device);
2ac050e
+	
2ac050e
+	if (type && strcmp(type, "swsuspend")==0)
2ac050e
+		return 0;
2ac050e
+	return 1;
2ac050e
+}
2ac050e
+#else
2ac050e
+static int
2ac050e
+swap_is_swsuspend(const char *device) {
2ac050e
+	int fd, re = 1, n = getpagesize() - 10;
2ac050e
+	char buf[10];
2ac050e
+	
2ac050e
+	fd = open(device, O_RDONLY);
2ac050e
+	if (fd < 0)
2ac050e
+		return -1;
2ac050e
+
2ac050e
+	if (lseek(fd, n, SEEK_SET) >= 0 &&
2ac050e
+	    read(fd, buf, sizeof buf) == sizeof buf &&
2ac050e
+	    (memcmp("S1SUSPEND", buf, 9)==0 ||
2ac050e
+			memcmp("S2SUSPEND", buf, 9)==0))
2ac050e
+		re = 0;
2ac050e
+
2ac050e
+	close(fd);
2ac050e
+	return re;
2ac050e
+}
2ac050e
+#endif
2ac050e
+
2ac050e
+/* calls mkswap */
2ac050e
+static int
2ac050e
+swap_reinitialize(const char *device) {
2ac050e
+	const char *label = mount_get_volume_label_by_spec(device);
2ac050e
+	pid_t pid;
2ac050e
+	
2ac050e
+	switch((pid=fork())) {
2ac050e
+		case -1: /* fork error */
2ac050e
+			fprintf(stderr, _("%s: cannot fork: %s\n"),
2ac050e
+				progname, strerror(errno));
2ac050e
+			return -1;
2ac050e
+			
2ac050e
+		case 0:	/* child */
2ac050e
+			if (label && *label)
2ac050e
+				execl(PATH_MKSWAP, PATH_MKSWAP, "-L", label, device, NULL);
2ac050e
+			else
2ac050e
+				execl(PATH_MKSWAP, PATH_MKSWAP, device, NULL);
2ac050e
+			exit(1); /* error  */
2ac050e
+			
2ac050e
+		default: /* parent */
2ac050e
+		{
2ac050e
+			int status;
2ac050e
+			int ret;
2ac050e
+
2ac050e
+			do {
2ac050e
+				if ((ret = waitpid(pid, &status, 0)) < 0 
2ac050e
+						&& errno == EINTR)
2ac050e
+					continue;
2ac050e
+				else if (ret < 0) {
2ac050e
+					fprintf(stderr, _("%s: waitpid: %s\n"),
2ac050e
+						progname, strerror(errno));
2ac050e
+					return -1;
2ac050e
+		      		}
2ac050e
+			} while (0);
2ac050e
+
2ac050e
+			/* mkswap returns: 0=suss, 1=error */
2ac050e
+			if (WIFEXITED(status) && WEXITSTATUS(status)==0)
2ac050e
+				return 0; /* ok */
2ac050e
+		}
2ac050e
+	}
2ac050e
+	return -1; /* error */
2ac050e
+}
2ac050e
+	
2ac050e
 static int
2ac050e
 do_swapon(const char *orig_special, int prio) {
2ac050e
 	int status;
2ac050e
@@ -196,6 +278,18 @@
2ac050e
 		return -1;
2ac050e
 	}
2ac050e
 
2ac050e
+	/* We have to reinitialize swap with old (=useless) software suspend 
2ac050e
+	 * data. The problem is that if we don't do it, then we get data 
2ac050e
+	 * corruption the next time with suspended on.
2ac050e
+	 */
2ac050e
+	if (swap_is_swsuspend(special)==0) {
2ac050e
+		fprintf(stdout, _("%s: %s: software suspend data detected. "
2ac050e
+					"Reinitializing the swap.\n"), 
2ac050e
+			progname, special);
2ac050e
+		if (swap_reinitialize(special) < 0)
2ac050e
+			return -1;
2ac050e
+	}
2ac050e
+	
2ac050e
 	/* people generally dislike this warning - now it is printed
2ac050e
 	   only when `verbose' is set */
2ac050e
 	if (verbose) {
2ac050e
--- util-linux-2.13-pre2/mount/get_label_uuid.c.swsuspend	2005-09-02 14:32:53.000000000 +0200
2ac050e
+++ util-linux-2.13-pre2/mount/get_label_uuid.c	2005-09-02 16:21:20.000000000 +0200
2ac050e
@@ -129,7 +129,24 @@
2ac050e
 	}
2ac050e
 	return 0;
2ac050e
 }
2ac050e
-	    
2ac050e
+
2ac050e
+static int
2ac050e
+is_swsuspend_partition(int fd, char **label, char *uuid) {
2ac050e
+	int n = getpagesize();
2ac050e
+	char *buf = xmalloc(n);
2ac050e
+	struct swap_header_v1_2 *p = (struct swap_header_v1_2 *) buf;
2ac050e
+
2ac050e
+	if (lseek(fd, 0, SEEK_SET) == 0
2ac050e
+	    && read(fd, buf, n) == n
2ac050e
+	    && (strncmp(buf+n-10, "S1SUSPEND", 9)==0 || 
2ac050e
+		    strncmp(buf+n-10, "S2SUSPEND", 9)==0)
2ac050e
+	    && p->version == 1) {
2ac050e
+		store_uuid(uuid, p->uuid);
2ac050e
+		store_label(label, p->volume_name, 16);
2ac050e
+		return 1;
2ac050e
+	}
2ac050e
+	return 0;
2ac050e
+}
2ac050e
 
2ac050e
 /*
2ac050e
  * Get both label and uuid.
2ac050e
@@ -162,6 +179,8 @@
2ac050e
 
2ac050e
 	if (is_v1_swap_partition(fd, label, uuid))
2ac050e
 		goto done;
2ac050e
+	if (is_swsuspend_partition(fd, label, uuid))
2ac050e
+		goto done;
2ac050e
 
2ac050e
 	if (lseek(fd, 1024, SEEK_SET) == 1024
2ac050e
 	    && read(fd, (char *) &e2sb, sizeof(e2sb)) == sizeof(e2sb)