Merge lp:~psusi/ubuntu/precise/parted/fixloop into lp:ubuntu/precise/parted
- Precise (12.04)
- fixloop
- Merge into precise
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 103 | ||||||||||||
Proposed branch: | lp:~psusi/ubuntu/precise/parted/fixloop | ||||||||||||
Merge into: | lp:ubuntu/precise/parted | ||||||||||||
Diff against target: |
858 lines (+638/-118) 8 files modified
debian/changelog (+17/-0) debian/patches/16-dos-partitions.patch (+55/-0) debian/patches/dm-part-sync.patch (+268/-0) debian/patches/dmraid.patch (+73/-92) debian/patches/loop-partitions.patch (+201/-15) debian/patches/series (+4/-1) debian/patches/skip-floppy.patch (+17/-0) debian/patches/udevadm-settle.patch (+3/-10) |
||||||||||||
To merge this branch: | bzr merge lp:~psusi/ubuntu/precise/parted/fixloop | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Colin Watson | Approve | ||
Phillip Susi (community) | Needs Resubmitting | ||
Ubuntu branches | Pending | ||
Review via email:
|
Commit message
Description of the change
Fixes partitionable loop devices, and support for > 16 partitions, and skips probing floppy drives.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Luke Yelavich (themuso) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Phillip Susi (psusi) wrote : | # |
Hold off on this for a second, I think I found a problem with non 512 byte sector devices, need to correct.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Phillip Susi (psusi) wrote : | # |
Nevermind, I didn't backport that part of the patch to Ubuntu, so this should be fine.
- 103. By Phillip Susi
-
* Add 16-dos-
partitions. patch: Fix parted to correctly handle
more than 16 partitions on dos partition tables.
* Add dm-part-sync.patch: Backport fix to allow modifying partitions
on dmraid disks while other partitions are in use.
* Replace dmraid.patch: Reimplemented and forwarded upstream,
allows dmraid raid10 disks to show up (LP: #311179)
* Replace loop-partitions.patch: this patch used to make sure that
we don't try to partition loop devices. Now it backports a few
upstream changes to allow partitioning loop devices since that is
supported on Linux since 3.0. It includes a change that also fixes
support for > 16 partitions.
* Add skip-floppy.patch: don't probe floppy drives. (LP: #910379)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Colin Watson (cjwatson) wrote : | # |
Scary complex, but I don't see any obvious problems, and we have time to fix things, so I'm going to go ahead. Thanks!
We'll probably need to test Wubi with this, but I'm sure that will happen anyway ...
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2011-10-18 12:13:42 +0000 |
3 | +++ debian/changelog 2012-01-13 19:53:24 +0000 |
4 | @@ -1,3 +1,20 @@ |
5 | +parted (2.3-8ubuntu2) precise; urgency=low |
6 | + |
7 | + * Add 16-dos-partitions.patch: Fix parted to correctly handle |
8 | + more than 16 partitions on dos partition tables. |
9 | + * Add dm-part-sync.patch: Backport fix to allow modifying partitions |
10 | + on dmraid disks while other partitions are in use. |
11 | + * Replace dmraid.patch: Reimplemented and forwarded upstream, |
12 | + allows dmraid raid10 disks to show up (LP: #311179) |
13 | + * Replace loop-partitions.patch: this patch used to make sure that |
14 | + we don't try to partition loop devices. Now it backports a few |
15 | + upstream changes to allow partitioning loop devices since that is |
16 | + supported on Linux since 3.0. It includes a change that also fixes |
17 | + support for > 16 partitions. |
18 | + * Add skip-floppy.patch: don't probe floppy drives. (LP: #910379) |
19 | + |
20 | + -- Phillip Susi <psusi@ubuntu.com> Sat, 03 Dec 2011 09:50:05 -0500 |
21 | + |
22 | parted (2.3-8ubuntu1) precise; urgency=low |
23 | |
24 | * Resynchronise with Debian. Remaining changes: |
25 | |
26 | === added file 'debian/patches/16-dos-partitions.patch' |
27 | --- debian/patches/16-dos-partitions.patch 1970-01-01 00:00:00 +0000 |
28 | +++ debian/patches/16-dos-partitions.patch 2012-01-13 19:53:24 +0000 |
29 | @@ -0,0 +1,55 @@ |
30 | +From: Phillip Susi <psusi@ubuntu.com> |
31 | +Subject: Fix > 16 dos partitions |
32 | +Description: The msdos partition table claimed a maximum partition |
33 | + count of 16 but would allow you to go beyond that. This resulted |
34 | + in the kernel not being informed of those partitions. Corrected |
35 | + to enforce the limit and raise the limit to 64 partitions. |
36 | +Forwarded: Yes |
37 | + |
38 | +--- a/libparted/labels/dos.c |
39 | ++++ b/libparted/labels/dos.c |
40 | +@@ -104,7 +104,7 @@ static const char MBR_BOOT_CODE[] = { |
41 | + * (i.e. 1022 is sometimes used to indicate "use LBA"). |
42 | + */ |
43 | + #define MAX_CHS_CYLINDER 1021 |
44 | +-#define MAX_TOTAL_PART 16 |
45 | ++#define MAX_TOTAL_PART 64 |
46 | + |
47 | + typedef struct _DosRawPartition DosRawPartition; |
48 | + typedef struct _DosRawTable DosRawTable; |
49 | +@@ -2332,17 +2332,23 @@ next_primary (const PedDisk* disk) |
50 | + if (!ped_disk_get_partition (disk, i)) |
51 | + return i; |
52 | + } |
53 | +- return 0; |
54 | ++ return -1; |
55 | + } |
56 | + |
57 | + static int |
58 | + next_logical (const PedDisk* disk) |
59 | + { |
60 | + int i; |
61 | +- for (i=5; 1; i++) { |
62 | ++ for (i=5; i<=MAX_TOTAL_PART; i++) { |
63 | + if (!ped_disk_get_partition (disk, i)) |
64 | + return i; |
65 | + } |
66 | ++ ped_exception_throw ( |
67 | ++ PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, |
68 | ++ _("Can not create any more partitions"), |
69 | ++ disk->dev->path); |
70 | ++ return -1; |
71 | ++ |
72 | + } |
73 | + |
74 | + static int |
75 | +@@ -2361,7 +2367,8 @@ msdos_partition_enumerate (PedPartition* |
76 | + part->num = next_logical (part->disk); |
77 | + else |
78 | + part->num = next_primary (part->disk); |
79 | +- |
80 | ++ if (part->num == -1) |
81 | ++ return 0; |
82 | + return 1; |
83 | + } |
84 | + |
85 | |
86 | === added file 'debian/patches/dm-part-sync.patch' |
87 | --- debian/patches/dm-part-sync.patch 1970-01-01 00:00:00 +0000 |
88 | +++ debian/patches/dm-part-sync.patch 2012-01-13 19:53:24 +0000 |
89 | @@ -0,0 +1,268 @@ |
90 | +From: Phillip Susi <psusi@cfl.rr.com> |
91 | +Subject: refactor device-mapper partition sync code |
92 | +Forwarded: Yes |
93 | +Description: The device-mapper partition sync code was still using the remove |
94 | + all partitions, then add new partitions method. Refactor to use the same |
95 | + algorithm as regular disks: try to remove all, and ignore any that could not |
96 | + be removed but have not changed. |
97 | +Index: b/libparted/arch/linux.c |
98 | +=================================================================== |
99 | +--- a/libparted/arch/linux.c |
100 | ++++ b/libparted/arch/linux.c |
101 | +@@ -270,6 +270,16 @@ |
102 | + static int _partition_is_mounted_by_path (const char* path); |
103 | + static int |
104 | + _dm_is_part (const char *path); |
105 | ++static int |
106 | ++_dm_add_partition (PedDisk* disk, const PedPartition* part); |
107 | ++static int |
108 | ++_dm_remove_partition(PedDisk* disk, int partno); |
109 | ++static bool |
110 | ++_dm_get_partition_start_and_length(PedPartition const *part, |
111 | ++ unsigned long long *start, |
112 | ++ unsigned long long *length); |
113 | ++static int |
114 | ++_is_dmraid_device (char* devpath); |
115 | + |
116 | + |
117 | + static int |
118 | +@@ -2579,6 +2589,23 @@ |
119 | + PED_ASSERT(disk->dev != NULL, return 0); |
120 | + int lpn; |
121 | + |
122 | ++ int (*add_partition)(PedDisk* disk, const PedPartition *part); |
123 | ++ int (*remove_partition)(PedDisk* disk, int partno); |
124 | ++ bool (*get_partition_start_and_length)(PedPartition const *part, |
125 | ++ unsigned long long *start, |
126 | ++ unsigned long long *length); |
127 | ++ |
128 | ++ |
129 | ++ if (disk->dev->type == PED_DEVICE_DM) { |
130 | ++ add_partition = _dm_add_partition; |
131 | ++ remove_partition = _dm_remove_partition; |
132 | ++ get_partition_start_and_length = _dm_get_partition_start_and_length; |
133 | ++ } else { |
134 | ++ add_partition = _blkpg_add_partition; |
135 | ++ remove_partition = _blkpg_remove_partition; |
136 | ++ get_partition_start_and_length = _kernel_get_partition_start_and_length; |
137 | ++ } |
138 | ++ |
139 | + /* lpn = largest partition number. */ |
140 | + if (ped_disk_get_max_supported_partition_count(disk, &lpn)) |
141 | + lpn = PED_MIN(lpn, _device_get_partition_range(disk->dev)); |
142 | +@@ -2612,7 +2639,7 @@ |
143 | + int j; |
144 | + for (j = 0; j < lpn; j++) { |
145 | + if (!ok[j]) { |
146 | +- ok[j] = _blkpg_remove_partition (disk, j + 1); |
147 | ++ ok[j] = remove_partition (disk, j + 1); |
148 | + errnums[j] = errno; |
149 | + if (!ok[j] && errnums[j] == EBUSY) |
150 | + busy = true; |
151 | +@@ -2629,8 +2656,8 @@ |
152 | + unsigned long long length; |
153 | + unsigned long long start; |
154 | + /* get start and length of existing partition */ |
155 | +- if (!_kernel_get_partition_start_and_length(part, |
156 | +- &start, &length)) |
157 | ++ if (!get_partition_start_and_length(part, |
158 | ++ &start, &length)) |
159 | + goto cleanup; |
160 | + if (start == part->geom.start |
161 | + && length == part->geom.length) |
162 | +@@ -2643,7 +2670,7 @@ |
163 | + } |
164 | + |
165 | + /* add the (possibly modified or new) partition */ |
166 | +- if (!_blkpg_add_partition (disk, part)) { |
167 | ++ if (!add_partition (disk, part)) { |
168 | + ped_exception_throw ( |
169 | + PED_EXCEPTION_ERROR, |
170 | + PED_EXCEPTION_RETRY_CANCEL, |
171 | +@@ -2691,24 +2718,34 @@ |
172 | + |
173 | + #ifdef ENABLE_DEVICE_MAPPER |
174 | + static int |
175 | +-_dm_remove_map_name(char *name) |
176 | ++_dm_remove_partition(PedDisk* disk, int partno) |
177 | + { |
178 | + struct dm_task *task = NULL; |
179 | + int rc; |
180 | ++ char *part_name = _device_get_part_path (disk->dev, partno); |
181 | + |
182 | ++ int fd = open (part_name, O_RDONLY | O_EXCL); |
183 | ++ if (fd == -1) { |
184 | ++ if (errno == ENOENT) |
185 | ++ errno = ENXIO; /* nothing to remove, device already doesn't exist */ |
186 | ++ free (part_name); |
187 | ++ return 0; |
188 | ++ } |
189 | ++ close (fd); |
190 | + task = dm_task_create(DM_DEVICE_REMOVE); |
191 | +- if (!task) |
192 | +- return 1; |
193 | +- |
194 | +- dm_task_set_name (task, name); |
195 | +- |
196 | ++ if (!task) { |
197 | ++ free (part_name); |
198 | ++ return 0; |
199 | ++ } |
200 | ++ dm_task_set_name (task, part_name); |
201 | + rc = dm_task_run(task); |
202 | + dm_task_update_nodes(); |
203 | + dm_task_destroy(task); |
204 | ++ free (part_name); |
205 | + if (!rc) |
206 | +- return 1; |
207 | ++ return 0; |
208 | + |
209 | +- return 0; |
210 | ++ return 1; |
211 | + } |
212 | + |
213 | + /* We consider a dm device that is a linear mapping with a * |
214 | +@@ -2762,65 +2799,38 @@ |
215 | + return rc; |
216 | + } |
217 | + |
218 | +-static int |
219 | +-_dm_remove_parts (PedDevice* dev) |
220 | ++static bool |
221 | ++_dm_get_partition_start_and_length(PedPartition const *part, |
222 | ++ unsigned long long *start, |
223 | ++ unsigned long long *length) |
224 | + { |
225 | +- struct dm_task* task = NULL; |
226 | +- struct dm_info* info = alloca(sizeof *info); |
227 | +- struct dm_names* names = NULL; |
228 | +- unsigned int next = 0; |
229 | +- int rc; |
230 | +- LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev); |
231 | +- |
232 | +- task = dm_task_create(DM_DEVICE_LIST); |
233 | +- if (!task) |
234 | +- goto err; |
235 | +- |
236 | +- if (!dm_task_set_major_minor (task, arch_specific->major, |
237 | +- arch_specific->minor, 0)) |
238 | +- goto err; |
239 | ++ struct dm_task* task = NULL; |
240 | ++ int rc = 0; |
241 | ++ char *target_type = NULL; |
242 | ++ char *params; |
243 | ++ char *path; |
244 | ++ int major, minor; |
245 | + |
246 | ++ if (!(task = dm_task_create(DM_DEVICE_TABLE))) |
247 | ++ return 0; |
248 | ++ path = _device_get_part_path (part->disk->dev, part->num); |
249 | ++ PED_ASSERT(path, return false); |
250 | ++ dm_task_set_name(task, path); |
251 | + if (!dm_task_run(task)) |
252 | + goto err; |
253 | +- |
254 | +- memset(info, '\0', sizeof *info); |
255 | +- dm_task_get_info(task, info); |
256 | +- if (!info->exists) |
257 | +- goto err; |
258 | +- |
259 | +- names = dm_task_get_names(task); |
260 | +- if (!names) |
261 | ++ dm_get_next_target(task, NULL, (uint64_t *)start, (uint64_t *)length, &target_type, ¶ms); |
262 | ++ if (sscanf (params, "%d:%d %Ld", &major, &minor, start) != 3) |
263 | + goto err; |
264 | +- |
265 | +- rc = 0; |
266 | +- do { |
267 | +- names = (void *) ((char *) names + next); |
268 | +- |
269 | +- if (_dm_is_part(info, names->name)) |
270 | +- rc += _dm_remove_map_name(names->name); |
271 | +- |
272 | +- next = names->next; |
273 | +- } while (next); |
274 | +- |
275 | +- dm_task_update_nodes(); |
276 | +- dm_task_destroy(task); |
277 | +- task = NULL; |
278 | +- |
279 | +- if (!rc) |
280 | +- return 1; |
281 | ++ rc = 1; |
282 | + err: |
283 | +- if (task) |
284 | +- dm_task_destroy(task); |
285 | +- ped_exception_throw (PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE, |
286 | +- _("parted was unable to re-read the partition " |
287 | +- "table on %s (%s). This means Linux won't know " |
288 | +- "anything about the modifications you made. "), |
289 | +- dev->path, strerror (errno)); |
290 | +- return 0; |
291 | ++ free (path); |
292 | ++ dm_task_destroy(task); |
293 | ++ return rc; |
294 | + } |
295 | + |
296 | ++ |
297 | + static int |
298 | +-_dm_add_partition (PedDisk* disk, PedPartition* part) |
299 | ++_dm_add_partition (PedDisk* disk, const PedPartition* part) |
300 | + { |
301 | + char* vol_name = NULL; |
302 | + const char* dev_name = NULL; |
303 | +@@ -2873,7 +2883,7 @@ |
304 | + free(vol_name); |
305 | + return 1; |
306 | + } else { |
307 | +- _dm_remove_map_name(vol_name); |
308 | ++ _dm_remove_partition (disk, part->num); |
309 | + } |
310 | + err: |
311 | + dm_task_update_nodes(); |
312 | +@@ -2883,34 +2893,6 @@ |
313 | + free (vol_name); |
314 | + return 0; |
315 | + } |
316 | +- |
317 | +-static int |
318 | +-_dm_reread_part_table (PedDisk* disk) |
319 | +-{ |
320 | +- int largest_partnum = ped_disk_get_last_partition_num (disk); |
321 | +- if (largest_partnum <= 0) |
322 | +- return 1; |
323 | +- |
324 | +- int rc = 1; |
325 | +- int last = PED_MIN (largest_partnum, 16); |
326 | +- int i; |
327 | +- |
328 | +- sync(); |
329 | +- if (!_dm_remove_parts(disk->dev)) |
330 | +- rc = 0; |
331 | +- |
332 | +- for (i = 1; i <= last; i++) { |
333 | +- PedPartition* part; |
334 | +- |
335 | +- part = ped_disk_get_partition (disk, i); |
336 | +- if (!part) |
337 | +- continue; |
338 | +- |
339 | +- if (!_dm_add_partition (disk, part)) |
340 | +- rc = 0; |
341 | +- } |
342 | +- return rc; |
343 | +-} |
344 | + #endif |
345 | + |
346 | + static int |
347 | +@@ -2933,10 +2915,6 @@ |
348 | + if (!_has_partitions (disk)) |
349 | + return 1; |
350 | + |
351 | +-#ifdef ENABLE_DEVICE_MAPPER |
352 | +- if (disk->dev->type == PED_DEVICE_DM) |
353 | +- return _dm_reread_part_table (disk); |
354 | +-#endif |
355 | + if (disk->dev->type != PED_DEVICE_FILE) { |
356 | + |
357 | + /* We now require BLKPG support. If this assertion fails, |
358 | |
359 | === modified file 'debian/patches/dmraid.patch' |
360 | --- debian/patches/dmraid.patch 2011-09-06 16:42:40 +0000 |
361 | +++ debian/patches/dmraid.patch 2012-01-13 19:53:24 +0000 |
362 | @@ -1,76 +1,36 @@ |
363 | -From: Luke Yelavich <themuso@ubuntu.com> |
364 | -Forwarded: no |
365 | -Description: DM-RAID handling |
366 | - Ensure that device-mapper devices for DM-RAID arrays do not have extra |
367 | - nodes created needlessly, and make sure that partition nodes for DM-RAID |
368 | - devices are not probed. |
369 | +From: Phillip Susi <psusi@ubuntu.com> |
370 | +Subject: Hide non dmraid whole disk dm devices |
371 | +Description: Don't probe dm devices unless they are dmraid whole |
372 | + disk devices, not partitions. Also set UUID of newly created |
373 | + dmraid partition devices. |
374 | +Forwarded: yes |
375 | |
376 | Index: b/libparted/arch/linux.c |
377 | =================================================================== |
378 | --- a/libparted/arch/linux.c |
379 | +++ b/libparted/arch/linux.c |
380 | -@@ -269,6 +269,10 @@ |
381 | +@@ -268,6 +268,9 @@ |
382 | |
383 | static char* _device_get_part_path (PedDevice* dev, int num); |
384 | static int _partition_is_mounted_by_path (const char* path); |
385 | -+#ifdef ENABLE_DEVICE_MAPPER |
386 | -+static int _is_dmraid_device (char* devpath); |
387 | -+static int _is_dmraid_major (char* devpath); |
388 | -+#endif |
389 | ++static int |
390 | ++_dm_is_part (const char *path); |
391 | ++ |
392 | |
393 | static int |
394 | _read_fd (int fd, char **buf) |
395 | -@@ -486,8 +490,16 @@ |
396 | +@@ -485,13 +488,52 @@ |
397 | if (stat (buf, &st) != 0) |
398 | continue; |
399 | |
400 | - if (_is_dm_major(major(st.st_rdev))) |
401 | -- _ped_device_probe (buf); |
402 | -+ if (_is_dm_major(major(st.st_rdev))) { |
403 | -+ if (_is_dmraid_device (buf)) { |
404 | -+ if (_is_dmraid_major (buf)) { |
405 | -+ _ped_device_probe (buf); |
406 | -+ } |
407 | -+ } else { |
408 | -+ _ped_device_probe (buf); |
409 | -+ } |
410 | -+ } |
411 | -+ |
412 | ++ if (_is_dm_major(major(st.st_rdev)) && _is_dmraid_device (buf) |
413 | ++ && !_dm_is_part(buf)) |
414 | + _ped_device_probe (buf); |
415 | } |
416 | closedir (mapper_dir); |
417 | |
418 | -@@ -2697,6 +2709,8 @@ |
419 | - char* vol_name = NULL; |
420 | - const char* dev_name = NULL; |
421 | - char* params = NULL; |
422 | -+ char* dm_uuid = NULL; |
423 | -+ int uuid_len; |
424 | - LinuxSpecific* arch_specific = LINUX_SPECIFIC (disk->dev); |
425 | - |
426 | - if (!_has_partitions(disk)) |
427 | -@@ -2737,12 +2751,19 @@ |
428 | - dm_task_set_name (task, vol_name); |
429 | - dm_task_add_target (task, 0, part->geom.length, |
430 | - "linear", params); |
431 | -+ if (_is_dmraid_device (disk->dev->path)) { |
432 | -+ uuid_len = (strlen (vol_name) + 8); |
433 | -+ dm_uuid = (char*) ped_malloc (uuid_len); |
434 | -+ snprintf (dm_uuid, uuid_len, "DMRAID-%s", vol_name); |
435 | -+ dm_task_set_uuid (task, dm_uuid); |
436 | -+ } |
437 | - if (dm_task_run (task)) { |
438 | - //printf("0 %ld linear %s\n", part->geom.length, params); |
439 | - dm_task_update_nodes(); |
440 | - dm_task_destroy(task); |
441 | - free(params); |
442 | - free(vol_name); |
443 | -+ free(dm_uuid); |
444 | - return 1; |
445 | - } else { |
446 | - _dm_remove_map_name(vol_name); |
447 | -@@ -2783,6 +2804,81 @@ |
448 | - } |
449 | - return rc; |
450 | + return 1; |
451 | } |
452 | + |
453 | +/* Checks whether the given device-mapper device is part of a dmraid array, |
454 | @@ -110,43 +70,64 @@ |
455 | + dm_task_destroy (task); |
456 | + return rc; |
457 | +} |
458 | -+ |
459 | -+/* Checks whether the given dmraid device node is a partition node, or the |
460 | -+ * master node. This is done by checking the /sys/block directory for the node |
461 | -+ * in question, to determine whether it is a slave of another device-mapper |
462 | -+ * device. The node should be confirmed as a dmraid device by calling |
463 | -+ * _is_dmraid_device first. |
464 | -+ */ |
465 | -+static int |
466 | -+_is_dmraid_major (char* devpath) |
467 | -+{ |
468 | -+ DIR* sysfs_dir; |
469 | -+ struct dirent* dent; |
470 | -+ char dmraid_devpath [32]; |
471 | -+ struct stat st; |
472 | -+ |
473 | -+ if (stat (devpath, &st) != 0) |
474 | -+ return 0; |
475 | -+ |
476 | -+ snprintf (dmraid_devpath, 32, "/sys/block/dm-%d/slaves", minor (st.st_rdev)); |
477 | -+ |
478 | -+ sysfs_dir = opendir (dmraid_devpath); |
479 | -+ if (!sysfs_dir) |
480 | -+ return 0; |
481 | -+ |
482 | -+ while ((dent = readdir (sysfs_dir))) { |
483 | -+ if (strcmp (dent->d_name, ".") == 0 || |
484 | -+ strcmp (dent->d_name, "..") == 0) |
485 | -+ continue; |
486 | -+ |
487 | -+ if (strncmp (dent->d_name, "dm-", 3) == 0) |
488 | -+ return 0; |
489 | -+ } |
490 | -+ closedir (sysfs_dir); |
491 | -+ |
492 | -+ return 1; |
493 | -+} |
494 | -+ |
495 | #endif |
496 | |
497 | static int |
498 | +@@ -2669,20 +2711,26 @@ |
499 | + return 0; |
500 | + } |
501 | + |
502 | ++/* We consider a dm device that is a linear mapping with a * |
503 | ++ * single target that also is a dm device to be a partition */ |
504 | ++ |
505 | + static int |
506 | +-_dm_is_part (struct dm_info *this, char *name) |
507 | ++_dm_is_part (const char *path) |
508 | + { |
509 | + struct dm_task* task = NULL; |
510 | + struct dm_info* info = alloca(sizeof *info); |
511 | + struct dm_deps* deps = NULL; |
512 | + int rc = 0; |
513 | + unsigned int i; |
514 | ++ char *target_type = NULL; |
515 | ++ uint64_t start, length; |
516 | ++ char *params; |
517 | + |
518 | + task = dm_task_create(DM_DEVICE_DEPS); |
519 | + if (!task) |
520 | + return 0; |
521 | + |
522 | +- dm_task_set_name(task, name); |
523 | ++ dm_task_set_name(task, path); |
524 | + if (!dm_task_run(task)) |
525 | + goto err; |
526 | + |
527 | +@@ -2695,14 +2743,20 @@ |
528 | + if (!deps) |
529 | + goto err; |
530 | + |
531 | +- for (i = 0; i < deps->count; i++) { |
532 | +- unsigned int ma = major(deps->device[i]), |
533 | +- mi = minor(deps->device[i]); |
534 | +- |
535 | +- if (ma == this->major && mi == this->minor) |
536 | +- rc = 1; |
537 | +- } |
538 | +- |
539 | ++ if (deps->count != 1) |
540 | ++ goto err; |
541 | ++ if (!_is_dm_major(major(deps->device[0]))) |
542 | ++ goto err; |
543 | ++ dm_task_destroy(task); |
544 | ++ if (!(task = dm_task_create(DM_DEVICE_TABLE))) |
545 | ++ return 0; |
546 | ++ dm_task_set_name(task, path); |
547 | ++ if (!dm_task_run(task)) |
548 | ++ goto err; |
549 | ++ dm_get_next_target(task, NULL, &start, &length, &target_type, ¶ms); |
550 | ++ if (strcmp (target_type, "linear")) |
551 | ++ goto err; |
552 | ++ rc = 1; |
553 | + err: |
554 | + dm_task_destroy(task); |
555 | + return rc; |
556 | |
557 | === modified file 'debian/patches/loop-partitions.patch' |
558 | --- debian/patches/loop-partitions.patch 2011-06-16 06:31:51 +0000 |
559 | +++ debian/patches/loop-partitions.patch 2012-01-13 19:53:24 +0000 |
560 | @@ -1,21 +1,207 @@ |
561 | -From: Colin Watson <cjwatson@ubuntu.com> |
562 | +From: Phillip Susi <psusi@ubuntu.com> |
563 | Forwarded: no |
564 | -Last-Update: 2010-02-22 |
565 | -Description: Loop device naming |
566 | - Loop devices can only have one partition, so don't generate device names |
567 | - such as "/dev/loop0p1". |
568 | +Subject: Backport some changes to allow use of partitionable loop devices |
569 | +Description: Upstream has switched to using the newer sysfs attribute |
570 | + "ext_range" instead of "range" to read the maximum supported partitions |
571 | + of a device. This allows loop devices to be partitioned even without |
572 | + using the kernel max_part argument, as well as support for more than |
573 | + 16 partitions. Also added new PED_DEVICE_LOOP device type instead of |
574 | + pretending loop devices are files. |
575 | |
576 | Index: b/libparted/arch/linux.c |
577 | =================================================================== |
578 | --- a/libparted/arch/linux.c |
579 | +++ b/libparted/arch/linux.c |
580 | -@@ -2200,6 +2200,9 @@ |
581 | - /* replace /disc with /path%d */ |
582 | - strcpy (result, dev->path); |
583 | - snprintf (result + path_len - 5, 16, "/part%d", num); |
584 | -+ } else if (!strncmp (dev->path, "/dev/loop", 9)) { |
585 | -+ /* Loop devices can only have one partition. */ |
586 | -+ strcpy (result, dev->path); |
587 | - } else if (dev->type == PED_DEVICE_DAC960 |
588 | - || dev->type == PED_DEVICE_CPQARRAY |
589 | - || dev->type == PED_DEVICE_ATARAID |
590 | +@@ -575,7 +575,7 @@ |
591 | + } else if (_is_virtblk_major(dev_major)) { |
592 | + dev->type = PED_DEVICE_VIRTBLK; |
593 | + } else if (dev_major == LOOP_MAJOR) { |
594 | +- dev->type = PED_DEVICE_FILE; |
595 | ++ dev->type = PED_DEVICE_LOOP; |
596 | + } else if (dev_major == MD_MAJOR) { |
597 | + dev->type = PED_DEVICE_MD; |
598 | + } else { |
599 | +@@ -1400,6 +1400,11 @@ |
600 | + goto error_free_arch_specific; |
601 | + break; |
602 | + |
603 | ++ case PED_DEVICE_LOOP: |
604 | ++ if (!init_generic (dev, _("Loopback device"))) |
605 | ++ goto error_free_arch_specific; |
606 | ++ break; |
607 | ++ |
608 | + default: |
609 | + ped_exception_throw (PED_EXCEPTION_NO_FEATURE, |
610 | + PED_EXCEPTION_CANCEL, |
611 | +@@ -2393,6 +2398,95 @@ |
612 | + BLKPG_DEL_PARTITION); |
613 | + } |
614 | + |
615 | ++/* Read the unsigned long long from /sys/block/DEV_BASE/PART_BASE/ENTRY |
616 | ++ and set *VAL to that value, where DEV_BASE is the last component of path to |
617 | ++ block device corresponding to PART and PART_BASE is the sysfs name of PART. |
618 | ++ Upon success, return true. Otherwise, return false. */ |
619 | ++static bool |
620 | ++_sysfs_ull_entry_from_part(PedPartition const* part, const char *entry, |
621 | ++ unsigned long long *val) |
622 | ++{ |
623 | ++ char path[128]; |
624 | ++ char *part_name = linux_partition_get_path(part); |
625 | ++ if (!part_name) |
626 | ++ return false; |
627 | ++ |
628 | ++ int r = snprintf(path, sizeof(path), "/sys/block/%s/%s/%s", |
629 | ++ last_component(part->disk->dev->path), |
630 | ++ last_component(part_name), entry); |
631 | ++ free(part_name); |
632 | ++ if (r < 0 || r >= sizeof(path)) |
633 | ++ return false; |
634 | ++ |
635 | ++ FILE *fp = fopen(path, "r"); |
636 | ++ if (!fp) |
637 | ++ return false; |
638 | ++ |
639 | ++ bool ok = fscanf(fp, "%llu", val) == 1; |
640 | ++ fclose(fp); |
641 | ++ |
642 | ++ return ok; |
643 | ++} |
644 | ++ |
645 | ++ |
646 | ++/* Get the starting sector and length of a partition PART within a block device |
647 | ++ Use blkpg if available, then check sysfs and then use HDIO_GETGEO and |
648 | ++ BLKGETSIZE64 ioctls as fallback. Upon success, return true. Otherwise, |
649 | ++ return false. */ |
650 | ++static bool |
651 | ++_kernel_get_partition_start_and_length(PedPartition const *part, |
652 | ++ unsigned long long *start, |
653 | ++ unsigned long long *length) |
654 | ++{ |
655 | ++ PED_ASSERT(part, return false); |
656 | ++ PED_ASSERT(start, return false); |
657 | ++ PED_ASSERT(length, return false); |
658 | ++ |
659 | ++ char *dev_name = linux_partition_get_path (part); |
660 | ++ if (!dev_name) |
661 | ++ return false; |
662 | ++ |
663 | ++ int ok = _sysfs_ull_entry_from_part (part, "start", start); |
664 | ++ if (!ok) { |
665 | ++ struct hd_geometry geom; |
666 | ++ int dev_fd = open (dev_name, O_RDONLY); |
667 | ++ if (dev_fd != -1 && ioctl (dev_fd, HDIO_GETGEO, &geom)) { |
668 | ++ *start = geom.start; |
669 | ++ ok = true; |
670 | ++ } else { |
671 | ++ if (dev_fd != -1) |
672 | ++ close(dev_fd); |
673 | ++ free (dev_name); |
674 | ++ return false; |
675 | ++ } |
676 | ++ } |
677 | ++ *start = (*start * 512) / part->disk->dev->sector_size; |
678 | ++ ok = _sysfs_ull_entry_from_part (part, "size", length); |
679 | ++ |
680 | ++ int fd; |
681 | ++ if (!ok) { |
682 | ++ fd = open (dev_name, O_RDONLY); |
683 | ++ if (fd != -1 && ioctl (fd, BLKGETSIZE64, length)) |
684 | ++ ok = true; |
685 | ++ } else { |
686 | ++ fd = -1; |
687 | ++ *length *= 512; |
688 | ++ } |
689 | ++ *length /= part->disk->dev->sector_size; |
690 | ++ if (fd != -1) |
691 | ++ close (fd); |
692 | ++ |
693 | ++ if (!ok) |
694 | ++ ped_exception_throw ( |
695 | ++ PED_EXCEPTION_BUG, |
696 | ++ PED_EXCEPTION_CANCEL, |
697 | ++ _("Unable to determine the start and length of %s."), |
698 | ++ dev_name); |
699 | ++ free (dev_name); |
700 | ++ return ok; |
701 | ++} |
702 | ++ |
703 | ++ |
704 | + /* |
705 | + * The number of partitions that a device can have depends on the kernel. |
706 | + * If we don't find this value in /sys/block/DEV/range, we will use our own |
707 | +@@ -2406,7 +2500,7 @@ |
708 | + FILE* fp; |
709 | + bool ok; |
710 | + |
711 | +- r = snprintf(path, sizeof(path), "/sys/block/%s/range", |
712 | ++ r = snprintf(path, sizeof(path), "/sys/block/%s/ext_range", |
713 | + last_component(dev->path)); |
714 | + if (r < 0 || r >= sizeof(path)) |
715 | + return MAX_NUM_PARTS; |
716 | +@@ -2487,33 +2581,16 @@ |
717 | + } |
718 | + |
719 | + for (i = 1; i <= lpn; i++) { |
720 | +- const PedPartition *part = ped_disk_get_partition (disk, i); |
721 | ++ PedPartition *part = ped_disk_get_partition (disk, i); |
722 | + if (part) { |
723 | + if (!ok[i - 1] && errnums[i - 1] == EBUSY) { |
724 | +- struct hd_geometry geom; |
725 | +- unsigned long long length = 0; |
726 | ++ unsigned long long length; |
727 | ++ unsigned long long start; |
728 | + /* get start and length of existing partition */ |
729 | +- char *dev_name = _device_get_part_path (disk->dev, i); |
730 | +- if (!dev_name) |
731 | +- goto cleanup; |
732 | +- int fd = open (dev_name, O_RDONLY); |
733 | +- if (fd == -1 |
734 | +- || ioctl (fd, HDIO_GETGEO, &geom) |
735 | +- || ioctl (fd, BLKGETSIZE64, &length)) { |
736 | +- ped_exception_throw ( |
737 | +- PED_EXCEPTION_BUG, |
738 | +- PED_EXCEPTION_CANCEL, |
739 | +- _("Unable to determine the size and length of %s."), |
740 | +- dev_name); |
741 | +- if (fd != -1) |
742 | +- close (fd); |
743 | +- free (dev_name); |
744 | ++ if (!_kernel_get_partition_start_and_length(part, |
745 | ++ &start, &length)) |
746 | + goto cleanup; |
747 | +- } |
748 | +- free (dev_name); |
749 | +- length /= disk->dev->sector_size; |
750 | +- close (fd); |
751 | +- if (geom.start == part->geom.start |
752 | ++ if (start == part->geom.start |
753 | + && length == part->geom.length) |
754 | + ok[i - 1] = 1; |
755 | + /* If the new partition is unchanged and the |
756 | +Index: b/include/parted/device.h |
757 | +=================================================================== |
758 | +--- a/include/parted/device.h |
759 | ++++ b/include/parted/device.h |
760 | +@@ -48,7 +48,8 @@ |
761 | + PED_DEVICE_SDMMC = 14, |
762 | + PED_DEVICE_VIRTBLK = 15, |
763 | + PED_DEVICE_AOE = 16, |
764 | +- PED_DEVICE_MD = 17 |
765 | ++ PED_DEVICE_MD = 17, |
766 | ++ PED_DEVICE_LOOP = 18 |
767 | + } PedDeviceType; |
768 | + |
769 | + typedef struct _PedDevice PedDevice; |
770 | +Index: b/parted/parted.c |
771 | +=================================================================== |
772 | +--- a/parted/parted.c |
773 | ++++ b/parted/parted.c |
774 | +@@ -1398,7 +1398,7 @@ |
775 | + "cpqarray", "file", "ataraid", "i2o", |
776 | + "ubd", "dasd", "viodasd", "sx8", "dm", |
777 | + "xvd", "sd/mmc", "virtblk", "aoe", |
778 | +- "md"}; |
779 | ++ "md", "loop"}; |
780 | + char* peek_word; |
781 | + char* start; |
782 | + char* end; |
783 | |
784 | === modified file 'debian/patches/series' |
785 | --- debian/patches/series 2011-10-18 12:10:46 +0000 |
786 | +++ debian/patches/series 2012-01-13 19:53:24 +0000 |
787 | @@ -23,12 +23,15 @@ |
788 | tiny-disk-constraint.patch |
789 | dasd-sync.patch |
790 | linux-two-component.patch |
791 | +skip-floppy.patch |
792 | |
793 | # Ubuntu additions |
794 | gptsync.patch |
795 | loop-partitions.patch |
796 | +dmraid.patch |
797 | +dm-part-sync.patch |
798 | udevadm-settle.patch |
799 | -dmraid.patch |
800 | |
801 | # Symbols for this ABI (amd64 as reference) |
802 | update-abi-symbols.patch |
803 | +16-dos-partitions.patch |
804 | |
805 | === added file 'debian/patches/skip-floppy.patch' |
806 | --- debian/patches/skip-floppy.patch 1970-01-01 00:00:00 +0000 |
807 | +++ debian/patches/skip-floppy.patch 2012-01-13 19:53:24 +0000 |
808 | @@ -0,0 +1,17 @@ |
809 | +From: Phillip Susi <psusi@cfl.rr.com> |
810 | +Forwarded: yes |
811 | +Subject: Skip floppies when probing all devices |
812 | +Description: Floppies can't be partitioned anyhow, and some people |
813 | + have misconfigured bios that thinks there is a floppy when there |
814 | + actually isn't, and trying to scan it causes hanging. |
815 | + |
816 | +--- a/libparted/arch/linux.c |
817 | ++++ b/libparted/arch/linux.c |
818 | +@@ -2094,6 +2094,7 @@ |
819 | + { "dm-", sizeof ("dm-") - 1 }, |
820 | + { "loop", sizeof ("loop") - 1 }, |
821 | + { "ram", sizeof ("ram") - 1 }, |
822 | ++ { "fd", sizeof ("fd") - 1 }, |
823 | + { 0, 0 }, |
824 | + }; |
825 | + |
826 | |
827 | === modified file 'debian/patches/udevadm-settle.patch' |
828 | --- debian/patches/udevadm-settle.patch 2011-06-16 06:31:51 +0000 |
829 | +++ debian/patches/udevadm-settle.patch 2012-01-13 19:53:24 +0000 |
830 | @@ -19,7 +19,7 @@ |
831 | #include <ctype.h> |
832 | #include <errno.h> |
833 | #include <fcntl.h> |
834 | -@@ -2797,16 +2798,60 @@ |
835 | +@@ -2908,13 +2909,55 @@ |
836 | return have_blkpg = kver >= KERNEL_VERSION (2,4,0) ? 1 : 0; |
837 | } |
838 | |
839 | @@ -72,17 +72,10 @@ |
840 | + /* ignore failures */ |
841 | + } |
842 | + |
843 | - #ifdef ENABLE_DEVICE_MAPPER |
844 | -- if (disk->dev->type == PED_DEVICE_DM) |
845 | -- return _dm_reread_part_table (disk); |
846 | -+ if (disk->dev->type == PED_DEVICE_DM) { |
847 | -+ ret = _dm_reread_part_table (disk); |
848 | -+ goto out; |
849 | -+ } |
850 | - #endif |
851 | if (disk->dev->type != PED_DEVICE_FILE) { |
852 | |
853 | -@@ -2817,10 +2862,20 @@ |
854 | + /* We now require BLKPG support. If this assertion fails, |
855 | +@@ -2924,10 +2967,20 @@ |
856 | assert (_have_blkpg ()); |
857 | |
858 | if (!_disk_sync_part_table (disk)) |
Looks ok to me, but I'd rather get COlin's opinion on whether this is ok to merge.