forked from pool/util-linux
129 lines
3.2 KiB
Diff
129 lines
3.2 KiB
Diff
## 30swsusp-resume.dpatch by Jeff Bailey <jbailey@ubuntu.com>
|
|
Index: util-linux-ng-2.12r+git20070330/mount/swapon.c
|
|
===================================================================
|
|
--- util-linux-ng-2.12r+git20070330.orig/mount/swapon.c
|
|
+++ util-linux-ng-2.12r+git20070330/mount/swapon.c
|
|
@@ -10,7 +10,9 @@
|
|
#include <string.h>
|
|
#include <mntent.h>
|
|
#include <errno.h>
|
|
+#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
+#include <fcntl.h>
|
|
#include "xmalloc.h"
|
|
#include "swap_constants.h"
|
|
#include "swapargs.h"
|
|
@@ -23,6 +25,7 @@
|
|
|
|
#define _PATH_FSTAB "/etc/fstab"
|
|
#define PROC_SWAPS "/proc/swaps"
|
|
+#define PATH_MKSWAP "/sbin/mkswap"
|
|
|
|
#define SWAPON_NEEDS_TWO_ARGS
|
|
|
|
@@ -179,6 +182,85 @@ display_summary(void)
|
|
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;
|
|
@@ -202,6 +284,18 @@ do_swapon(const char *orig_special, int
|
|
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) {
|