Merge lp:~psusi/ubuntu/precise/parted/fixloop into lp:ubuntu/precise/parted

Proposed by Phillip Susi
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
Reviewer Review Type Date Requested Status
Colin Watson Approve
Phillip Susi (community) Needs Resubmitting
Ubuntu branches Pending
Review via email: mp+84385@code.launchpad.net

Description of the change

Fixes partitionable loop devices, and support for > 16 partitions, and skips probing floppy drives.

To post a comment you must log in.
Revision history for this message
Luke Yelavich (themuso) wrote :

Looks ok to me, but I'd rather get COlin's opinion on whether this is ok to merge.

Revision history for this message
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.

review: Needs Fixing
Revision history for this message
Phillip Susi (psusi) wrote :

Nevermind, I didn't backport that part of the patch to Ubuntu, so this should be fine.

review: Needs Resubmitting
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)

Revision history for this message
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 ...

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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, &params);
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, &params);
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))

Subscribers

People subscribed via source and target branches

to all changes: