]> git.wh0rd.org Git - patches.git/blob - cryptsetup-1.0.6-svn-udev.patch
more random patches. who knows.
[patches.git] / cryptsetup-1.0.6-svn-udev.patch
1 Index: lib/setup.c
2 ===================================================================
3 --- lib/setup.c (revision 29)
4 +++ lib/setup.c (revision 32)
5 @@ -396,7 +396,7 @@ static int __crypt_remove_device(int arg
6                 return -EBUSY;
7         }
8  
9 -       return backend->remove(options);
10 +       return backend->remove(0, options);
11  }
12  
13  static int __crypt_luks_format(int arg, struct setup_backend *backend, struct crypt_options *options)
14 @@ -705,7 +705,10 @@ static int crypt_job(int (*job)(int arg,
15  
16         backend = get_setup_backend(default_backend);
17  
18 -       setup_enter(backend,options->icb->log);
19 +       if (setup_enter(backend,options->icb->log) < 0) {
20 +               r = -ENOSYS;
21 +               goto out;
22 +       }
23  
24         if (!backend) {
25                 set_error("No setup backend available");
26 Index: lib/internal.h
27 ===================================================================
28 --- lib/internal.h      (revision 29)
29 +++ lib/internal.h      (revision 32)
30 @@ -40,7 +40,7 @@ struct setup_backend {
31                                   const char *key);
32         int             (*status)(int details, struct crypt_options *options,
33                                   char **key);
34 -       int             (*remove)(struct crypt_options *options);
35 +       int             (*remove)(int force, struct crypt_options *options);
36  
37         const char *    (*dir)(void);
38  };
39 Index: lib/libdevmapper.c
40 ===================================================================
41 --- lib/libdevmapper.c  (revision 29)
42 +++ lib/libdevmapper.c  (revision 32)
43 @@ -17,13 +17,7 @@
44  #define DEVICE_DIR     "/dev"
45  
46  #define        CRYPT_TARGET    "crypt"
47 -
48 -#define UDEVSETTLE     "/sbin/udevsettle"
49 -
50 -static void run_udevsettle(void)
51 -{
52 -       system(UDEVSETTLE);
53 -}
54 +#define        RETRY_COUNT     5
55  
56  static void set_dm_error(int level, const char *file, int line,
57                           const char *f, ...)
58 @@ -38,9 +32,16 @@ static void set_dm_error(int level, cons
59         va_end(va);
60  }
61  
62 +static int _dm_simple(int task, const char *name);
63 +
64  static int dm_init(void)
65  {
66         dm_log_init(set_dm_error);
67 +       if (!_dm_simple(DM_DEVICE_LIST_VERSIONS, "test")) {
68 +               set_error("Cannot communicate with device-mapper. Is the dm_mod module loaded?");
69 +               return -1;
70 +       }
71 +
72         return 1;       /* unsafe memory */
73  }
74  
75 @@ -50,16 +51,6 @@ static void dm_exit(void)
76         dm_lib_release();
77  }
78  
79 -static void flush_dm_workqueue(void)
80 -{
81 -       /* 
82 -        * Unfortunately this is the only way to trigger libdevmapper's
83 -        * update_nodes function 
84 -        */ 
85 -       dm_exit(); 
86 -       dm_init();
87 -}
88 -
89  static char *__lookup_dev(char *path, dev_t dev)
90  {
91         struct dirent *entry;
92 @@ -152,6 +143,89 @@ out:
93         return params;
94  }
95  
96 +/* DM helpers */
97 +static int _dm_simple(int task, const char *name)
98 +{
99 +       int r = 0;
100 +       struct dm_task *dmt;
101 +
102 +       if (!(dmt = dm_task_create(task)))
103 +               return 0;
104 +
105 +       if (!dm_task_set_name(dmt, name))
106 +               goto out;
107 +
108 +       r = dm_task_run(dmt);
109 +
110 +      out:
111 +       dm_task_destroy(dmt);
112 +       return r;
113 +}
114 +
115 +static int _error_device(struct crypt_options *options)
116 +{
117 +       struct dm_task *dmt;
118 +       int r = 0;
119 +
120 +       if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
121 +               return 0;
122 +
123 +       if (!dm_task_set_name(dmt, options->name))
124 +               goto error;
125 +
126 +       if (!dm_task_add_target(dmt, UINT64_C(0), options->size, "error", ""))
127 +               goto error;
128 +
129 +       if (!dm_task_set_ro(dmt))
130 +               goto error;
131 +
132 +       if (!dm_task_no_open_count(dmt))
133 +               goto error;
134 +
135 +       if (!dm_task_run(dmt))
136 +               goto error;
137 +
138 +       if (!_dm_simple(DM_DEVICE_RESUME, options->name)) {
139 +               _dm_simple(DM_DEVICE_CLEAR, options->name);
140 +               goto error;
141 +       }
142 +
143 +       r = 1;
144 +
145 +error:
146 +       dm_task_destroy(dmt);
147 +       return r;
148 +}
149 +
150 +static int _dm_remove(struct crypt_options *options, int force)
151 +{
152 +       int r = -EINVAL;
153 +       int retries = force ? RETRY_COUNT : 1;
154 +
155 +       /* If force flag is set, replace device with error, read-only target.
156 +        * it should stop processes from reading it and also removed underlying
157 +        * device from mapping, so it is usable again.
158 +        * Force flag should be used only for temporary devices, which are
159 +        * intended to work inside cryptsetup only!
160 +        * Anyway, if some process try to read temporary cryptsetup device,
161 +        * it is bug - no other process should try touch it (e.g. udev).
162 +        */
163 +       if (force) {
164 +                _error_device(options);
165 +               retries = RETRY_COUNT;
166 +       }
167 +
168 +       do {
169 +               r = _dm_simple(DM_DEVICE_REMOVE, options->name) ? 0 : -EINVAL;
170 +               if (--retries)
171 +                       sleep(1);
172 +       } while (r == -EINVAL && retries);
173 +
174 +       dm_task_update_nodes();
175 +
176 +       return r;
177 +}
178 +
179  static int dm_create_device(int reload, struct crypt_options *options,
180                              const char *key)
181  {
182 @@ -191,24 +265,14 @@ static int dm_create_device(int reload, 
183         if (dmi.read_only)
184                 options->flags |= CRYPT_FLAG_READONLY;
185  
186 -       /* run udevsettle to avoid a race in libdevmapper causing busy dm devices */
187 -       run_udevsettle();
188 -
189         r = 0;
190 -       
191  out:
192         if (r < 0 && !reload) {
193                 char *error = (char *)get_error();
194                 if (error)
195                         error = strdup(error);
196 -               if (dmt)
197 -                       dm_task_destroy(dmt);
198  
199 -               if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
200 -                       goto out_restore_error;
201 -               if (!dm_task_set_name(dmt, options->name))
202 -                       goto out_restore_error;
203 -               if (!dm_task_run(dmt))
204 +               if (!_dm_remove(options, 0))
205                         goto out_restore_error;
206  
207  out_restore_error:
208 @@ -224,7 +288,7 @@ out_no_removal:
209                 dm_task_destroy(dmt);
210         if(dmt_query)
211                 dm_task_destroy(dmt_query);
212 -       flush_dm_workqueue();
213 +       dm_task_update_nodes();
214         return r;
215  }
216  
217 @@ -352,25 +416,12 @@ out:
218         return r;
219  }
220  
221 -static int dm_remove_device(struct crypt_options *options)
222 +static int dm_remove_device(int force, struct crypt_options *options)
223  {
224 -       struct dm_task *dmt;
225 -       int r = -EINVAL;
226 -
227 -       if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
228 -               goto out;
229 -       if (!dm_task_set_name(dmt, options->name))
230 -               goto out;
231 -       if (!dm_task_run(dmt))
232 -               goto out;
233 -
234 -       r = 0;
235 +       if (!options || !options->name)
236 +               return -EINVAL;
237  
238 -out:   
239 -       if (dmt)
240 -               dm_task_destroy(dmt);
241 -       flush_dm_workqueue();
242 -       return r;
243 +       return _dm_remove(options, force);;
244  }
245  
246  
247 Index: luks/keyencryption.c
248 ===================================================================
249 --- luks/keyencryption.c        (revision 29)
250 +++ luks/keyencryption.c        (revision 32)
251 @@ -45,6 +45,11 @@ static inline int round_up_modulo(int x,
252         return div_round_up(x, m) * m;
253  }
254  
255 +static struct setup_backend *cleaner_backend=NULL;
256 +static const char *cleaner_name=NULL;
257 +static uint64_t cleaner_size = 0;
258 +static int devfd=-1;
259 +
260  static int setup_mapping(const char *cipher, const char *name, 
261                          const char *device, unsigned int payloadOffset,
262                          const char *key, size_t keyLength, 
263 @@ -52,7 +57,7 @@ static int setup_mapping(const char *cip
264                          struct setup_backend *backend,
265                          int mode)
266  {
267 -       struct crypt_options k;
268 +       struct crypt_options k = {0};
269         struct crypt_options *options = &k;
270         int device_sector_size = sector_size_for_device(device);
271         int r;
272 @@ -66,6 +71,7 @@ static int setup_mapping(const char *cip
273                 return -EINVAL;
274         }
275         options->size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
276 +       cleaner_size = options->size;
277  
278         options->offset = sector;
279         options->cipher = cipher;
280 @@ -87,24 +93,21 @@ static int setup_mapping(const char *cip
281         return r;
282  }
283  
284 -static int clear_mapping(const char *name, struct setup_backend *backend)
285 +static int clear_mapping(const char *name, uint64_t size, struct setup_backend *backend)
286  {
287 -       struct crypt_options options;
288 +       struct crypt_options options = {0};
289         options.name=name;
290 -       return backend->remove(&options);
291 +       options.size = size;
292 +       return backend->remove(1, &options);
293  }
294  
295 -/* I miss closures in C! */
296 -static struct setup_backend *cleaner_backend=NULL;
297 -static const char *cleaner_name=NULL; 
298 -static int devfd=0;
299 -
300  static void sigint_handler(int sig)
301  {
302 -        if(devfd)
303 +        if(devfd >= 0)
304                  close(devfd);
305 +        devfd = -1;
306          if(cleaner_backend && cleaner_name) 
307 -                clear_mapping(cleaner_name, cleaner_backend);
308 +                clear_mapping(cleaner_name, cleaner_size, cleaner_backend);
309          signal(SIGINT, SIG_DFL);
310          kill(getpid(), SIGINT);
311  }
312 @@ -160,13 +163,14 @@ static int LUKS_endec_template(char *src
313         r = 0;
314   out3:
315         close(devfd);
316 -       devfd = 0;
317 +       devfd = -1;
318   out2:
319 -       clear_mapping(name,backend);
320 +       clear_mapping(cleaner_name, cleaner_size, cleaner_backend);
321   out1:
322         signal(SIGINT, SIG_DFL);
323         cleaner_name = NULL;
324         cleaner_backend = NULL;
325 +       cleaner_size = 0;
326         free(dmCipherSpec);
327         free(fullpath); 
328         free(name);