]> git.pld-linux.org Git - packages/util-linux.git/blob - util-linux-swapon-suspend.patch
- rel. 2
[packages/util-linux.git] / util-linux-swapon-suspend.patch
1 - swsusp swaps should be reinitialized
2
3 --- util-linux-2.13-pre2/mount/swapon.c.swsuspend       2005-09-02 14:32:53.000000000 +0200
4 +++ util-linux-2.13-pre2/mount/swapon.c 2005-09-02 16:29:43.000000000 +0200
5 @@ -11,6 +11,9 @@
6  #include <mntent.h>
7  #include <errno.h>
8  #include <sys/stat.h>
9 +#include <sys/types.h>
10 +#include <sys/wait.h>
11 +#include <fcntl.h>
12  #include "xmalloc.h"
13  #include "swap_constants.h"
14  #include "swapargs.h"
15 @@ -22,6 +25,7 @@
16  
17  #define        _PATH_FSTAB     "/etc/fstab"
18  #define PROC_SWAPS      "/proc/swaps"
19 +#define PATH_MKSWAP    "/sbin/mkswap"
20  
21  #define SWAPON_NEEDS_TWO_ARGS
22  
23 @@ -173,6 +177,84 @@
24         return 0 ;
25  }
26  
27 +/*
28 + * It's better do swsuspend detection by follow routine than
29 + * include huge mount_guess_fstype.o to swapon. We need only
30 + * swsuspend and no the others filesystems.
31 + */
32 +#ifdef HAVE_LIBBLKID
33 +static int
34 +swap_is_swsuspend(const char *device) {
35 +       const char *type = blkid_get_tag_value(blkid, "TYPE", device);
36 +       
37 +       if (type && strcmp(type, "swsuspend")==0)
38 +               return 0;
39 +       return 1;
40 +}
41 +#else
42 +static int
43 +swap_is_swsuspend(const char *device) {
44 +       int fd, re = 1, n = getpagesize() - 10;
45 +       char buf[10];
46 +       
47 +       fd = open(device, O_RDONLY);
48 +       if (fd < 0)
49 +               return -1;
50 +
51 +       if (lseek(fd, n, SEEK_SET) >= 0 &&
52 +           read(fd, buf, sizeof buf) == sizeof buf &&
53 +           (memcmp("S1SUSPEND", buf, 9)==0 ||
54 +                       memcmp("S2SUSPEND", buf, 9)==0))
55 +               re = 0;
56 +
57 +       close(fd);
58 +       return re;
59 +}
60 +#endif
61 +
62 +/* calls mkswap */
63 +static int
64 +swap_reinitialize(const char *device) {
65 +       const char *label = mount_get_volume_label_by_spec(device);
66 +       pid_t pid;
67 +       
68 +       switch((pid=fork())) {
69 +               case -1: /* fork error */
70 +                       fprintf(stderr, _("%s: cannot fork: %s\n"),
71 +                               progname, strerror(errno));
72 +                       return -1;
73 +                       
74 +               case 0: /* child */
75 +                       if (label && *label)
76 +                               execl(PATH_MKSWAP, PATH_MKSWAP, "-L", label, device, NULL);
77 +                       else
78 +                               execl(PATH_MKSWAP, PATH_MKSWAP, device, NULL);
79 +                       exit(1); /* error  */
80 +                       
81 +               default: /* parent */
82 +               {
83 +                       int status;
84 +                       int ret;
85 +
86 +                       do {
87 +                               if ((ret = waitpid(pid, &status, 0)) < 0 
88 +                                               && errno == EINTR)
89 +                                       continue;
90 +                               else if (ret < 0) {
91 +                                       fprintf(stderr, _("%s: waitpid: %s\n"),
92 +                                               progname, strerror(errno));
93 +                                       return -1;
94 +                               }
95 +                       } while (0);
96 +
97 +                       /* mkswap returns: 0=suss, 1=error */
98 +                       if (WIFEXITED(status) && WEXITSTATUS(status)==0)
99 +                               return 0; /* ok */
100 +               }
101 +       }
102 +       return -1; /* error */
103 +}
104 +       
105  static int
106  do_swapon(const char *orig_special, int prio) {
107         int status;
108 @@ -196,6 +278,18 @@
109                 return -1;
110         }
111  
112 +       /* We have to reinitialize swap with old (=useless) software suspend 
113 +        * data. The problem is that if we don't do it, then we get data 
114 +        * corruption the next time with suspended on.
115 +        */
116 +       if (swap_is_swsuspend(special)==0) {
117 +               fprintf(stdout, _("%s: %s: software suspend data detected. "
118 +                                       "Reinitializing the swap.\n"), 
119 +                       progname, special);
120 +               if (swap_reinitialize(special) < 0)
121 +                       return -1;
122 +       }
123 +       
124         /* people generally dislike this warning - now it is printed
125            only when `verbose' is set */
126         if (verbose) {
127 --- util-linux-2.13-pre2/mount/get_label_uuid.c.swsuspend       2005-09-02 14:32:53.000000000 +0200
128 +++ util-linux-2.13-pre2/mount/get_label_uuid.c 2005-09-02 16:21:20.000000000 +0200
129 @@ -129,7 +129,24 @@
130         }
131         return 0;
132  }
133 -           
134 +
135 +static int
136 +is_swsuspend_partition(int fd, char **label, char *uuid) {
137 +       int n = getpagesize();
138 +       char *buf = xmalloc(n);
139 +       struct swap_header_v1_2 *p = (struct swap_header_v1_2 *) buf;
140 +
141 +       if (lseek(fd, 0, SEEK_SET) == 0
142 +           && read(fd, buf, n) == n
143 +           && (strncmp(buf+n-10, "S1SUSPEND", 9)==0 || 
144 +                   strncmp(buf+n-10, "S2SUSPEND", 9)==0)
145 +           && p->version == 1) {
146 +               store_uuid(uuid, p->uuid);
147 +               store_label(label, p->volume_name, 16);
148 +               return 1;
149 +       }
150 +       return 0;
151 +}
152  
153  /*
154   * Get both label and uuid.
155 @@ -162,6 +179,8 @@
156  
157         if (is_v1_swap_partition(fd, label, uuid))
158                 goto done;
159 +       if (is_swsuspend_partition(fd, label, uuid))
160 +               goto done;
161  
162         if (lseek(fd, 1024, SEEK_SET) == 1024
163             && read(fd, (char *) &e2sb, sizeof(e2sb)) == sizeof(e2sb)
This page took 0.255643 seconds and 3 git commands to generate.