Merge lp:~psusi/ubuntu/raring/multipath-tools/fix-extended-partitions into lp:ubuntu/raring/multipath-tools
- Raring (13.04)
- fix-extended-partitions
- Merge into raring
Proposed by
Phillip Susi
Status: | Merged |
---|---|
Merged at revision: | 49 |
Proposed branch: | lp:~psusi/ubuntu/raring/multipath-tools/fix-extended-partitions |
Merge into: | lp:ubuntu/raring/multipath-tools |
Diff against target: |
890 lines (+814/-6) 8 files modified
.pc/0010-fix-extended-partitions.patch/kpartx/dos.c (+105/-0) .pc/0010-fix-extended-partitions.patch/kpartx/kpartx.c (+648/-0) .pc/applied-patches (+1/-0) debian/changelog (+7/-0) debian/patches/0010-fix-extended-partitions.patch (+47/-0) debian/patches/series (+1/-0) kpartx/dos.c (+2/-0) kpartx/kpartx.c (+3/-6) |
To merge this branch: | bzr merge lp:~psusi/ubuntu/raring/multipath-tools/fix-extended-partitions |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Luke Yelavich (community) | Approve | ||
Ubuntu branches | Pending | ||
Review via email: mp+142050@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory '.pc/0010-fix-extended-partitions.patch' |
2 | === added file '.pc/0010-fix-extended-partitions.patch/.timestamp' |
3 | === added directory '.pc/0010-fix-extended-partitions.patch/kpartx' |
4 | === added file '.pc/0010-fix-extended-partitions.patch/kpartx/dos.c' |
5 | --- .pc/0010-fix-extended-partitions.patch/kpartx/dos.c 1970-01-01 00:00:00 +0000 |
6 | +++ .pc/0010-fix-extended-partitions.patch/kpartx/dos.c 2013-01-06 23:42:23 +0000 |
7 | @@ -0,0 +1,105 @@ |
8 | +/* |
9 | + * Source: copy of util-linux' partx dos.c |
10 | + * |
11 | + * Copyrights of the original file apply |
12 | + * Copyright (c) 2005 Bastian Blank |
13 | + */ |
14 | +#include "kpartx.h" |
15 | +#include "byteorder.h" |
16 | +#include <stdio.h> |
17 | +#include <string.h> |
18 | +#include "dos.h" |
19 | + |
20 | +static int |
21 | +is_extended(int type) { |
22 | + return (type == 5 || type == 0xf || type == 0x85); |
23 | +} |
24 | + |
25 | +static int |
26 | +read_extended_partition(int fd, struct partition *ep, int en, |
27 | + struct slice *sp, int ns) |
28 | +{ |
29 | + struct partition p; |
30 | + unsigned long start, here, next; |
31 | + unsigned char *bp; |
32 | + int loopct = 0; |
33 | + int moretodo = 1; |
34 | + int i, n=0; |
35 | + |
36 | + next = start = le32_to_cpu(ep->start_sect); |
37 | + |
38 | + while (moretodo) { |
39 | + here = next; |
40 | + moretodo = 0; |
41 | + if (++loopct > 100) |
42 | + return n; |
43 | + |
44 | + bp = (unsigned char *)getblock(fd, here); |
45 | + if (bp == NULL) |
46 | + return n; |
47 | + |
48 | + if (bp[510] != 0x55 || bp[511] != 0xaa) |
49 | + return n; |
50 | + |
51 | + for (i=0; i<2; i++) { |
52 | + memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); |
53 | + if (is_extended(p.sys_type)) { |
54 | + if (p.nr_sects && !moretodo) { |
55 | + next = start + le32_to_cpu(p.start_sect); |
56 | + moretodo = 1; |
57 | + } |
58 | + continue; |
59 | + } |
60 | + if (n < ns) { |
61 | + sp[n].start = here + le32_to_cpu(p.start_sect); |
62 | + sp[n].size = le32_to_cpu(p.nr_sects); |
63 | + sp[n].container = en + 1; |
64 | + n++; |
65 | + } else { |
66 | + fprintf(stderr, |
67 | + "dos_extd_partition: too many slices\n"); |
68 | + return n; |
69 | + } |
70 | + loopct = 0; |
71 | + } |
72 | + } |
73 | + return n; |
74 | +} |
75 | + |
76 | +static int |
77 | +is_gpt(int type) { |
78 | + return (type == 0xEE); |
79 | +} |
80 | + |
81 | +int |
82 | +read_dos_pt(int fd, struct slice all, struct slice *sp, int ns) { |
83 | + struct partition p; |
84 | + unsigned long offset = all.start; |
85 | + int i, n=4; |
86 | + unsigned char *bp; |
87 | + |
88 | + bp = (unsigned char *)getblock(fd, offset); |
89 | + if (bp == NULL) |
90 | + return -1; |
91 | + |
92 | + if (bp[510] != 0x55 || bp[511] != 0xaa) |
93 | + return -1; |
94 | + |
95 | + for (i=0; i<4; i++) { |
96 | + memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); |
97 | + if (is_gpt(p.sys_type)) |
98 | + return 0; |
99 | + if (i < ns) { |
100 | + sp[i].start = le32_to_cpu(p.start_sect); |
101 | + sp[i].size = le32_to_cpu(p.nr_sects); |
102 | + } else { |
103 | + fprintf(stderr, |
104 | + "dos_partition: too many slices\n"); |
105 | + break; |
106 | + } |
107 | + if (is_extended(p.sys_type)) { |
108 | + n += read_extended_partition(fd, &p, i, sp+n, ns-n); |
109 | + } |
110 | + } |
111 | + return n; |
112 | +} |
113 | |
114 | === added file '.pc/0010-fix-extended-partitions.patch/kpartx/kpartx.c' |
115 | --- .pc/0010-fix-extended-partitions.patch/kpartx/kpartx.c 1970-01-01 00:00:00 +0000 |
116 | +++ .pc/0010-fix-extended-partitions.patch/kpartx/kpartx.c 2013-01-06 23:42:23 +0000 |
117 | @@ -0,0 +1,648 @@ |
118 | +/* |
119 | + * Source: copy of util-linux' partx partx.c |
120 | + * |
121 | + * Copyrights of the original file applies |
122 | + * Copyright (c) 2004, 2005 Christophe Varoqui |
123 | + * Copyright (c) 2005 Kiyoshi Ueda |
124 | + * Copyright (c) 2005 Lars Soltau |
125 | + */ |
126 | + |
127 | +/* |
128 | + * Given a block device and a partition table type, |
129 | + * try to parse the partition table, and list the |
130 | + * contents. Optionally add or remove partitions. |
131 | + * |
132 | + * Read wholedisk and add all partitions: |
133 | + * kpartx [-a|-d|-l] [-v] wholedisk |
134 | + * |
135 | + * aeb, 2000-03-21 |
136 | + * cva, 2002-10-26 |
137 | + */ |
138 | + |
139 | +#include <stdio.h> |
140 | +#include <fcntl.h> |
141 | +#include <errno.h> |
142 | +#include <stdlib.h> |
143 | +#include <string.h> |
144 | +#include <unistd.h> |
145 | +#include <stdint.h> |
146 | +#include <sys/stat.h> |
147 | +#include <sys/types.h> |
148 | +#include <ctype.h> |
149 | +#include <libdevmapper.h> |
150 | + |
151 | +#include "devmapper.h" |
152 | +#include "crc32.h" |
153 | +#include "lopart.h" |
154 | +#include "kpartx.h" |
155 | + |
156 | +#define SIZE(a) (sizeof(a)/sizeof((a)[0])) |
157 | + |
158 | +#define READ_SIZE 1024 |
159 | +#define MAXTYPES 64 |
160 | +#define MAXSLICES 256 |
161 | +#define DM_TARGET "linear" |
162 | +#define LO_NAME_SIZE 64 |
163 | +#define PARTNAME_SIZE 128 |
164 | +#define DELIM_SIZE 8 |
165 | + |
166 | +struct slice slices[MAXSLICES]; |
167 | + |
168 | +enum action { LIST, ADD, DELETE }; |
169 | + |
170 | +struct pt { |
171 | + char *type; |
172 | + ptreader *fn; |
173 | +} pts[MAXTYPES]; |
174 | + |
175 | +int ptct = 0; |
176 | + |
177 | +static void |
178 | +addpts(char *t, ptreader f) |
179 | +{ |
180 | + if (ptct >= MAXTYPES) { |
181 | + fprintf(stderr, "addpts: too many types\n"); |
182 | + exit(1); |
183 | + } |
184 | + pts[ptct].type = t; |
185 | + pts[ptct].fn = f; |
186 | + ptct++; |
187 | +} |
188 | + |
189 | +static void |
190 | +initpts(void) |
191 | +{ |
192 | + addpts("gpt", read_gpt_pt); |
193 | + addpts("dos", read_dos_pt); |
194 | + addpts("bsd", read_bsd_pt); |
195 | + addpts("solaris", read_solaris_pt); |
196 | + addpts("unixware", read_unixware_pt); |
197 | + addpts("dasd", read_dasd_pt); |
198 | + addpts("mac", read_mac_pt); |
199 | + addpts("sun", read_sun_pt); |
200 | +} |
201 | + |
202 | +static char short_opts[] = "rladgvp:t:s"; |
203 | + |
204 | +/* Used in gpt.c */ |
205 | +int force_gpt=0; |
206 | + |
207 | +static int |
208 | +usage(void) { |
209 | + printf("usage : kpartx [-a|-d|-l] [-v] wholedisk\n"); |
210 | + printf("\t-a add partition devmappings\n"); |
211 | + printf("\t-r devmappings will be readonly\n"); |
212 | + printf("\t-d del partition devmappings\n"); |
213 | + printf("\t-l list partitions devmappings that would be added by -a\n"); |
214 | + printf("\t-p set device name-partition number delimiter\n"); |
215 | + printf("\t-g force GUID partition table (GPT)\n"); |
216 | + printf("\t-v verbose\n"); |
217 | + printf("\t-s sync mode. Don't return until the partitions are created\n"); |
218 | + return 1; |
219 | +} |
220 | + |
221 | +static void |
222 | +set_delimiter (char * device, char * delimiter) |
223 | +{ |
224 | + char * p = device; |
225 | + |
226 | + while (*(p++) != 0x0) |
227 | + continue; |
228 | + |
229 | + if (isdigit(*(p - 2))) |
230 | + *delimiter = 'p'; |
231 | +} |
232 | + |
233 | +static void |
234 | +strip_slash (char * device) |
235 | +{ |
236 | + char * p = device; |
237 | + |
238 | + while (*(p++) != 0x0) { |
239 | + |
240 | + if (*p == '/') |
241 | + *p = '!'; |
242 | + } |
243 | +} |
244 | + |
245 | +static int |
246 | +find_devname_offset (char * device) |
247 | +{ |
248 | + char *p, *q = NULL; |
249 | + |
250 | + p = device; |
251 | + |
252 | + while (*p++) |
253 | + if (*p == '/') |
254 | + q = p; |
255 | + |
256 | + return (int)(q - device) + 1; |
257 | +} |
258 | + |
259 | +static char * |
260 | +get_hotplug_device(void) |
261 | +{ |
262 | + unsigned int major, minor, off, len; |
263 | + const char *mapname; |
264 | + char *devname = NULL; |
265 | + char *device = NULL; |
266 | + char *var = NULL; |
267 | + struct stat buf; |
268 | + |
269 | + var = getenv("ACTION"); |
270 | + |
271 | + if (!var || strcmp(var, "add")) |
272 | + return NULL; |
273 | + |
274 | + /* Get dm mapname for hotpluged device. */ |
275 | + if (!(devname = getenv("DEVNAME"))) |
276 | + return NULL; |
277 | + |
278 | + if (stat(devname, &buf)) |
279 | + return NULL; |
280 | + |
281 | + major = (unsigned int)MAJOR(buf.st_rdev); |
282 | + minor = (unsigned int)MINOR(buf.st_rdev); |
283 | + |
284 | + if (!(mapname = dm_mapname(major, minor))) /* Not dm device. */ |
285 | + return NULL; |
286 | + |
287 | + off = find_devname_offset(devname); |
288 | + len = strlen(mapname); |
289 | + |
290 | + /* Dirname + mapname + \0 */ |
291 | + if (!(device = (char *)malloc(sizeof(char) * (off + len + 1)))) |
292 | + return NULL; |
293 | + |
294 | + /* Create new device name. */ |
295 | + snprintf(device, off + 1, "%s", devname); |
296 | + snprintf(device + off, len + 1, "%s", mapname); |
297 | + |
298 | + if (strlen(device) != (off + len)) |
299 | + return NULL; |
300 | + |
301 | + return device; |
302 | +} |
303 | + |
304 | +int |
305 | +main(int argc, char **argv){ |
306 | + int fd, i, j, m, n, op, off, arg, c, d, ro=0; |
307 | + struct slice all; |
308 | + struct pt *ptp; |
309 | + enum action what = LIST; |
310 | + char *type, *diskdevice, *device, *progname; |
311 | + int verbose = 0; |
312 | + char partname[PARTNAME_SIZE], params[PARTNAME_SIZE + 16]; |
313 | + char * loopdev = NULL; |
314 | + char * delim = NULL; |
315 | + char *uuid = NULL; |
316 | + char *mapname = NULL; |
317 | + int loopro = 0; |
318 | + int hotplug = 0; |
319 | + int loopcreated = 0; |
320 | + int sync = 0; |
321 | + struct stat buf; |
322 | + uint32_t cookie = 0; |
323 | + |
324 | + initpts(); |
325 | + init_crc32(); |
326 | + |
327 | + type = device = diskdevice = NULL; |
328 | + memset(&all, 0, sizeof(all)); |
329 | + memset(&partname, 0, sizeof(partname)); |
330 | + |
331 | + /* Check whether hotplug mode. */ |
332 | + progname = strrchr(argv[0], '/'); |
333 | + |
334 | + if (!progname) |
335 | + progname = argv[0]; |
336 | + else |
337 | + progname++; |
338 | + |
339 | + if (!strcmp(progname, "kpartx.dev")) { /* Hotplug mode */ |
340 | + hotplug = 1; |
341 | + |
342 | + /* Setup for original kpartx variables */ |
343 | + if (!(device = get_hotplug_device())) |
344 | + exit(1); |
345 | + |
346 | + diskdevice = device; |
347 | + what = ADD; |
348 | + } else if (argc < 2) { |
349 | + usage(); |
350 | + exit(1); |
351 | + } |
352 | + |
353 | + while ((arg = getopt(argc, argv, short_opts)) != EOF) switch(arg) { |
354 | + case 'r': |
355 | + ro=1; |
356 | + break; |
357 | + case 'g': |
358 | + force_gpt=1; |
359 | + break; |
360 | + case 't': |
361 | + type = optarg; |
362 | + break; |
363 | + case 'v': |
364 | + verbose = 1; |
365 | + break; |
366 | + case 'p': |
367 | + delim = optarg; |
368 | + break; |
369 | + case 'l': |
370 | + what = LIST; |
371 | + break; |
372 | + case 'a': |
373 | + what = ADD; |
374 | + break; |
375 | + case 'd': |
376 | + what = DELETE; |
377 | + break; |
378 | + case 's': |
379 | + sync = 1; |
380 | + break; |
381 | + default: |
382 | + usage(); |
383 | + exit(1); |
384 | + } |
385 | + |
386 | + if (!sync) |
387 | + dm_udev_set_sync_support(0); |
388 | + |
389 | + if (dm_prereq(DM_TARGET, 0, 0, 0) && (what == ADD || what == DELETE)) { |
390 | + fprintf(stderr, "device mapper prerequisites not met\n"); |
391 | + exit(1); |
392 | + } |
393 | + |
394 | + if (hotplug) { |
395 | + /* already got [disk]device */ |
396 | + } else if (optind == argc-2) { |
397 | + device = argv[optind]; |
398 | + diskdevice = argv[optind+1]; |
399 | + } else if (optind == argc-1) { |
400 | + diskdevice = device = argv[optind]; |
401 | + } else { |
402 | + usage(); |
403 | + exit(1); |
404 | + } |
405 | + |
406 | + if (stat(device, &buf)) { |
407 | + printf("failed to stat() %s\n", device); |
408 | + exit (1); |
409 | + } |
410 | + |
411 | + if (S_ISREG (buf.st_mode)) { |
412 | + /* already looped file ? */ |
413 | + loopdev = find_loop_by_file(device); |
414 | + |
415 | + if (!loopdev && what == DELETE) |
416 | + exit (0); |
417 | + |
418 | + if (!loopdev) { |
419 | + loopdev = find_unused_loop_device(); |
420 | + |
421 | + if (set_loop(loopdev, device, 0, &loopro)) { |
422 | + fprintf(stderr, "can't set up loop\n"); |
423 | + exit (1); |
424 | + } |
425 | + loopcreated = 1; |
426 | + } |
427 | + device = loopdev; |
428 | + } |
429 | + |
430 | + off = find_devname_offset(device); |
431 | + |
432 | + if (!loopdev) { |
433 | + uuid = dm_mapuuid((unsigned int)MAJOR(buf.st_rdev), |
434 | + (unsigned int)MINOR(buf.st_rdev)); |
435 | + mapname = dm_mapname((unsigned int)MAJOR(buf.st_rdev), |
436 | + (unsigned int)MINOR(buf.st_rdev)); |
437 | + } |
438 | + |
439 | + if (!uuid) |
440 | + uuid = device + off; |
441 | + |
442 | + if (!mapname) |
443 | + mapname = device + off; |
444 | + |
445 | + if (delim == NULL) { |
446 | + delim = malloc(DELIM_SIZE); |
447 | + memset(delim, 0, DELIM_SIZE); |
448 | + set_delimiter(mapname, delim); |
449 | + } |
450 | + |
451 | + fd = open(device, O_RDONLY); |
452 | + |
453 | + if (fd == -1) { |
454 | + perror(device); |
455 | + exit(1); |
456 | + } |
457 | + |
458 | + /* add/remove partitions to the kernel devmapper tables */ |
459 | + int r = 0; |
460 | + for (i = 0; i < ptct; i++) { |
461 | + ptp = &pts[i]; |
462 | + |
463 | + if (type && strcmp(type, ptp->type)) |
464 | + continue; |
465 | + |
466 | + /* here we get partitions */ |
467 | + n = ptp->fn(fd, all, slices, SIZE(slices)); |
468 | + |
469 | +#ifdef DEBUG |
470 | + if (n >= 0) |
471 | + printf("%s: %d slices\n", ptp->type, n); |
472 | +#endif |
473 | + |
474 | + if (n > 0) |
475 | + close(fd); |
476 | + else |
477 | + continue; |
478 | + |
479 | + switch(what) { |
480 | + case LIST: |
481 | + for (j = 0, c = 0, m = 0; j < n; j++) { |
482 | + if (slices[j].size == 0) |
483 | + continue; |
484 | + if (slices[j].container > 0) { |
485 | + c++; |
486 | + continue; |
487 | + } |
488 | + |
489 | + slices[j].minor = m++; |
490 | + |
491 | + printf("%s%s%d : 0 %" PRIu64 " %s %" PRIu64"\n", |
492 | + mapname, delim, j+1, |
493 | + slices[j].size, device, |
494 | + slices[j].start); |
495 | + } |
496 | + /* Loop to resolve contained slices */ |
497 | + d = c; |
498 | + while (c) { |
499 | + for (j = 0; j < n; j++) { |
500 | + uint64_t start; |
501 | + int k = slices[j].container - 1; |
502 | + |
503 | + if (slices[j].size == 0) |
504 | + continue; |
505 | + if (slices[j].minor > 0) |
506 | + continue; |
507 | + if (slices[j].container == 0) |
508 | + continue; |
509 | + slices[j].minor = m++; |
510 | + |
511 | + start = slices[j].start - slices[k].start; |
512 | + printf("%s%s%d : 0 %" PRIu64 " /dev/dm-%d %" PRIu64 "\n", |
513 | + mapname, delim, j+1, |
514 | + slices[j].size, |
515 | + slices[k].minor, start); |
516 | + c--; |
517 | + } |
518 | + /* Terminate loop if nothing more to resolve */ |
519 | + if (d == c) |
520 | + break; |
521 | + } |
522 | + |
523 | + if (loopcreated && S_ISREG (buf.st_mode)) { |
524 | + if (del_loop(device)) { |
525 | + if (verbose) |
526 | + printf("can't del loop : %s\n", |
527 | + device); |
528 | + exit(1); |
529 | + } |
530 | + printf("loop deleted : %s\n", device); |
531 | + } |
532 | + break; |
533 | + |
534 | + case DELETE: |
535 | + for (j = n-1; j >= 0; j--) { |
536 | + if (safe_sprintf(partname, "%s%s%d", |
537 | + mapname, delim, j+1)) { |
538 | + fprintf(stderr, "partname too small\n"); |
539 | + exit(1); |
540 | + } |
541 | + strip_slash(partname); |
542 | + |
543 | + if (!slices[j].size || !dm_map_present(partname)) |
544 | + continue; |
545 | + |
546 | + if (!dm_simplecmd(DM_DEVICE_REMOVE, partname, |
547 | + 0, &cookie)) { |
548 | + r++; |
549 | + continue; |
550 | + } |
551 | + if (verbose) |
552 | + printf("del devmap : %s\n", partname); |
553 | + } |
554 | + |
555 | + if (S_ISREG (buf.st_mode)) { |
556 | + if (del_loop(device)) { |
557 | + if (verbose) |
558 | + printf("can't del loop : %s\n", |
559 | + device); |
560 | + exit(1); |
561 | + } |
562 | + printf("loop deleted : %s\n", device); |
563 | + } |
564 | + break; |
565 | + |
566 | + case ADD: |
567 | + for (j = 0, c = 0; j < n; j++) { |
568 | + if (slices[j].size == 0) |
569 | + continue; |
570 | + |
571 | + /* Skip all contained slices */ |
572 | + if (slices[j].container > 0) { |
573 | + c++; |
574 | + continue; |
575 | + } |
576 | + |
577 | + if (safe_sprintf(partname, "%s%s%d", |
578 | + mapname, delim, j+1)) { |
579 | + fprintf(stderr, "partname too small\n"); |
580 | + exit(1); |
581 | + } |
582 | + strip_slash(partname); |
583 | + |
584 | + if (safe_sprintf(params, "%s %" PRIu64 , |
585 | + device, slices[j].start)) { |
586 | + fprintf(stderr, "params too small\n"); |
587 | + exit(1); |
588 | + } |
589 | + |
590 | + op = (dm_map_present(partname) ? |
591 | + DM_DEVICE_RELOAD : DM_DEVICE_CREATE); |
592 | + |
593 | + if (!dm_addmap(op, partname, DM_TARGET, params, |
594 | + slices[j].size, ro, uuid, j+1, |
595 | + buf.st_mode & 0777, buf.st_uid, |
596 | + buf.st_gid, &cookie)) { |
597 | + fprintf(stderr, "create/reload failed on %s\n", |
598 | + partname); |
599 | + r++; |
600 | + } |
601 | + if (op == DM_DEVICE_RELOAD && |
602 | + !dm_simplecmd(DM_DEVICE_RESUME, partname, |
603 | + 1, &cookie)) { |
604 | + fprintf(stderr, "resume failed on %s\n", |
605 | + partname); |
606 | + r++; |
607 | + } |
608 | + dm_devn(partname, &slices[j].major, |
609 | + &slices[j].minor); |
610 | + |
611 | + if (verbose) |
612 | + printf("add map %s (%d:%d): 0 %" PRIu64 " %s %s\n", |
613 | + partname, slices[j].major, |
614 | + slices[j].minor, slices[j].size, |
615 | + DM_TARGET, params); |
616 | + } |
617 | + /* Loop to resolve contained slices */ |
618 | + d = c; |
619 | + while (c) { |
620 | + for (j = 0; j < n; j++) { |
621 | + uint64_t start; |
622 | + int k = slices[j].container - 1; |
623 | + |
624 | + if (slices[j].size == 0) |
625 | + continue; |
626 | + |
627 | + /* Skip all existing slices */ |
628 | + if (slices[j].minor > 0) |
629 | + continue; |
630 | + |
631 | + /* Skip all simple slices */ |
632 | + if (slices[j].container == 0) |
633 | + continue; |
634 | + |
635 | + /* Check container slice */ |
636 | + if (slices[k].size == 0) |
637 | + fprintf(stderr, "Invalid slice %d\n", |
638 | + k); |
639 | + |
640 | + if (safe_sprintf(partname, "%s%s%d", |
641 | + mapname, delim, j+1)) { |
642 | + fprintf(stderr, "partname too small\n"); |
643 | + exit(1); |
644 | + } |
645 | + strip_slash(partname); |
646 | + |
647 | + start = slices[j].start - slices[k].start; |
648 | + if (safe_sprintf(params, "%d:%d %" PRIu64, |
649 | + slices[k].major, |
650 | + slices[k].minor, |
651 | + start)) { |
652 | + fprintf(stderr, "params too small\n"); |
653 | + exit(1); |
654 | + } |
655 | + |
656 | + op = (dm_map_present(partname) ? |
657 | + DM_DEVICE_RELOAD : DM_DEVICE_CREATE); |
658 | + |
659 | + dm_addmap(op, partname, DM_TARGET, params, |
660 | + slices[j].size, ro, uuid, j+1, |
661 | + buf.st_mode & 0777, |
662 | + buf.st_uid, buf.st_gid, |
663 | + &cookie); |
664 | + |
665 | + if (op == DM_DEVICE_RELOAD) |
666 | + dm_simplecmd(DM_DEVICE_RESUME, |
667 | + partname, 1, |
668 | + &cookie); |
669 | + |
670 | + dm_devn(partname, &slices[j].major, |
671 | + &slices[j].minor); |
672 | + |
673 | + if (verbose) |
674 | + printf("add map %s : 0 %" PRIu64 " %s %s\n", |
675 | + partname, slices[j].size, |
676 | + DM_TARGET, params); |
677 | + c--; |
678 | + } |
679 | + /* Terminate loop */ |
680 | + if (d == c) |
681 | + break; |
682 | + } |
683 | + break; |
684 | + |
685 | + default: |
686 | + break; |
687 | + |
688 | + } |
689 | + if (n > 0) |
690 | + break; |
691 | + } |
692 | + dm_udev_wait(cookie); |
693 | + dm_lib_release(); |
694 | + dm_lib_exit(); |
695 | + |
696 | + return r; |
697 | +} |
698 | + |
699 | +void * |
700 | +xmalloc (size_t size) { |
701 | + void *t; |
702 | + |
703 | + if (size == 0) |
704 | + return NULL; |
705 | + |
706 | + t = malloc (size); |
707 | + |
708 | + if (t == NULL) { |
709 | + fprintf(stderr, "Out of memory\n"); |
710 | + exit(1); |
711 | + } |
712 | + |
713 | + return t; |
714 | +} |
715 | + |
716 | +/* |
717 | + * sseek: seek to specified sector |
718 | + */ |
719 | + |
720 | +static int |
721 | +sseek(int fd, unsigned int secnr) { |
722 | + off64_t in, out; |
723 | + in = ((off64_t) secnr << 9); |
724 | + out = 1; |
725 | + |
726 | + if ((out = lseek64(fd, in, SEEK_SET)) != in) |
727 | + { |
728 | + fprintf(stderr, "llseek error\n"); |
729 | + return -1; |
730 | + } |
731 | + return 0; |
732 | +} |
733 | + |
734 | +static |
735 | +struct block { |
736 | + unsigned int secnr; |
737 | + char *block; |
738 | + struct block *next; |
739 | +} *blockhead; |
740 | + |
741 | +char * |
742 | +getblock (int fd, unsigned int secnr) { |
743 | + struct block *bp; |
744 | + |
745 | + for (bp = blockhead; bp; bp = bp->next) |
746 | + |
747 | + if (bp->secnr == secnr) |
748 | + return bp->block; |
749 | + |
750 | + if (sseek(fd, secnr)) |
751 | + return NULL; |
752 | + |
753 | + bp = xmalloc(sizeof(struct block)); |
754 | + bp->secnr = secnr; |
755 | + bp->next = blockhead; |
756 | + blockhead = bp; |
757 | + bp->block = (char *) xmalloc(READ_SIZE); |
758 | + |
759 | + if (read(fd, bp->block, READ_SIZE) != READ_SIZE) { |
760 | + fprintf(stderr, "read error, sector %d\n", secnr); |
761 | + bp->block = NULL; |
762 | + } |
763 | + |
764 | + return bp->block; |
765 | +} |
766 | |
767 | === modified file '.pc/applied-patches' |
768 | --- .pc/applied-patches 2012-01-09 04:04:07 +0000 |
769 | +++ .pc/applied-patches 2013-01-06 23:42:23 +0000 |
770 | @@ -9,3 +9,4 @@ |
771 | 1000--set-umask-in-multipathd.patch |
772 | 1001--fix-linking-command.patch |
773 | 0009-fix-delim.patch |
774 | +0010-fix-extended-partitions.patch |
775 | |
776 | === modified file 'debian/changelog' |
777 | --- debian/changelog 2012-10-05 14:00:37 +0000 |
778 | +++ debian/changelog 2013-01-06 23:42:23 +0000 |
779 | @@ -1,3 +1,10 @@ |
780 | +multipath-tools (0.4.9-3ubuntu7) raring; urgency=low |
781 | + |
782 | + * Add 0010-fix-extended-partitions.patch: Only expose the |
783 | + first two sectors of the extended partition (LP: #1093918). |
784 | + |
785 | + -- Phillip Susi <psusi@ubuntu.com> Fri, 04 Jan 2013 16:14:34 -0500 |
786 | + |
787 | multipath-tools (0.4.9-3ubuntu6) quantal; urgency=low |
788 | |
789 | * Rebuild for new armel compiler default of ARMv5t. |
790 | |
791 | === added file 'debian/patches/0010-fix-extended-partitions.patch' |
792 | --- debian/patches/0010-fix-extended-partitions.patch 1970-01-01 00:00:00 +0000 |
793 | +++ debian/patches/0010-fix-extended-partitions.patch 2013-01-06 23:42:23 +0000 |
794 | @@ -0,0 +1,47 @@ |
795 | +From: Phillip Susi <psusi@ubuntu.com> |
796 | +Subject: fix extended partition mapping |
797 | +Description: The linux kernel maps the extended partition only |
798 | + so that LILO can be installed there. The length is always set |
799 | + to two sectors to allow this, and most tools know to ignore the |
800 | + device. kpartx was mapping the entire extended partition, then |
801 | + stacking the logical partitions on top of it. This presented |
802 | + a device that looked like an entirely separate disk that |
803 | + contains only the logical partitions. This patch fixes kpartx |
804 | + to conform with the normal Linux behavior. |
805 | + |
806 | +--- a/kpartx/dos.c |
807 | ++++ b/kpartx/dos.c |
808 | +@@ -98,6 +98,8 @@ |
809 | + break; |
810 | + } |
811 | + if (is_extended(p.sys_type)) { |
812 | ++ sp[i].size = 2; /* extended partitions only get two |
813 | ++ sectors mapped for LILO to install */ |
814 | + n += read_extended_partition(fd, &p, i, sp+n, ns-n); |
815 | + } |
816 | + } |
817 | +--- a/kpartx/kpartx.c |
818 | ++++ b/kpartx/kpartx.c |
819 | +@@ -501,7 +501,6 @@ |
820 | + d = c; |
821 | + while (c) { |
822 | + for (j = 0; j < n; j++) { |
823 | +- uint64_t start; |
824 | + int k = slices[j].container - 1; |
825 | + |
826 | + if (slices[j].size == 0) |
827 | +@@ -527,11 +526,9 @@ |
828 | + } |
829 | + strip_slash(partname); |
830 | + |
831 | +- start = slices[j].start - slices[k].start; |
832 | +- if (safe_sprintf(params, "%d:%d %" PRIu64, |
833 | +- slices[k].major, |
834 | +- slices[k].minor, |
835 | +- start)) { |
836 | ++ if (safe_sprintf(params, "%s %" PRIu64, |
837 | ++ device, |
838 | ++ slices[j].start)) { |
839 | + fprintf(stderr, "params too small\n"); |
840 | + exit(1); |
841 | + } |
842 | |
843 | === modified file 'debian/patches/series' |
844 | --- debian/patches/series 2012-01-09 04:04:07 +0000 |
845 | +++ debian/patches/series 2013-01-06 23:42:23 +0000 |
846 | @@ -9,3 +9,4 @@ |
847 | 1000--set-umask-in-multipathd.patch |
848 | 1001--fix-linking-command.patch |
849 | 0009-fix-delim.patch |
850 | +0010-fix-extended-partitions.patch |
851 | |
852 | === modified file 'kpartx/dos.c' |
853 | --- kpartx/dos.c 2009-02-12 15:07:42 +0000 |
854 | +++ kpartx/dos.c 2013-01-06 23:42:23 +0000 |
855 | @@ -98,6 +98,8 @@ |
856 | break; |
857 | } |
858 | if (is_extended(p.sys_type)) { |
859 | + sp[i].size = 2; /* extended partitions only get two |
860 | + sectors mapped for LILO to install */ |
861 | n += read_extended_partition(fd, &p, i, sp+n, ns-n); |
862 | } |
863 | } |
864 | |
865 | === modified file 'kpartx/kpartx.c' |
866 | --- kpartx/kpartx.c 2012-01-09 04:04:07 +0000 |
867 | +++ kpartx/kpartx.c 2013-01-06 23:42:23 +0000 |
868 | @@ -501,7 +501,6 @@ |
869 | d = c; |
870 | while (c) { |
871 | for (j = 0; j < n; j++) { |
872 | - uint64_t start; |
873 | int k = slices[j].container - 1; |
874 | |
875 | if (slices[j].size == 0) |
876 | @@ -527,11 +526,9 @@ |
877 | } |
878 | strip_slash(partname); |
879 | |
880 | - start = slices[j].start - slices[k].start; |
881 | - if (safe_sprintf(params, "%d:%d %" PRIu64, |
882 | - slices[k].major, |
883 | - slices[k].minor, |
884 | - start)) { |
885 | + if (safe_sprintf(params, "%s %" PRIu64, |
886 | + device, |
887 | + slices[j].start)) { |
888 | fprintf(stderr, "params too small\n"); |
889 | exit(1); |
890 | } |
Thanks for your work, uploading.