Merge lp:~salgado/linaro-image-tools/bug-673412 into lp:linaro-image-tools/11.11

Proposed by Guilherme Salgado
Status: Merged
Merged at revision: 231
Proposed branch: lp:~salgado/linaro-image-tools/bug-673412
Merge into: lp:linaro-image-tools/11.11
Prerequisite: lp:~salgado/linaro-image-tools/port-install_hwpacks
Diff against target: 161 lines (+62/-13)
2 files modified
media_create/partitions.py (+34/-7)
media_create/tests/test_media_create.py (+28/-6)
To merge this branch: bzr merge lp:~salgado/linaro-image-tools/bug-673412
Reviewer Review Type Date Requested Status
James Westby (community) Needs Information
Review via email: mp+45266@code.launchpad.net

Description of the change

Fix bug 673412 by ensuring boot/root filesystems are umounted before we attempt to mkfs them.

To post a comment you must log in.
Revision history for this message
James Westby (james-w) wrote :

29 + if filesystem in open('/proc/mounts').read():

Is that a bit broad? It would cause an error if the filesystem showed
up in there in a strange place wouldn't it?

Thanks,

James

review: Needs Information
Revision history for this message
Guilherme Salgado (salgado) wrote :

On Wed, 2011-01-05 at 17:32 +0000, James Westby wrote:
> Review: Needs Information
> 29 + if filesystem in open('/proc/mounts').read():
>
> Is that a bit broad? It would cause an error if the filesystem showed
> up in there in a strange place wouldn't it?

I find it highly unlikely that a /dev/{sdXX,mmcblkNpN,loopN} string
(which is usually what the function will be given) ends up there unless
the filesystem is mounted, but I can use UDisks to do a more specific
check.

232. By Guilherme Salgado

Use the UDisks dbus interface to check whether or not a given partition is mounted

Revision history for this message
James Westby (james-w) wrote :

On Wed, 05 Jan 2011 18:22:51 -0000, Guilherme Salgado <email address hidden> wrote:
> On Wed, 2011-01-05 at 17:32 +0000, James Westby wrote:
> > Review: Needs Information
> > 29 + if filesystem in open('/proc/mounts').read():
> >
> > Is that a bit broad? It would cause an error if the filesystem showed
> > up in there in a strange place wouldn't it?
>
> I find it highly unlikely that a /dev/{sdXX,mmcblkNpN,loopN} string
> (which is usually what the function will be given) ends up there unless
> the filesystem is mounted, but I can use UDisks to do a more specific
> check.

Yeah, it's rare. I'm happy with this going in as is and we can see if we
get any fallout.

Thanks,

James

Revision history for this message
Guilherme Salgado (salgado) wrote :

http://bazaar.launchpad.net/~salgado/linaro-image-tools/bug-673412/revision/232 has the changes to use the UDisks dbus interface instead of /proc/mounts

Revision history for this message
James Westby (james-w) wrote :

On Wed, 05 Jan 2011 19:37:52 -0000, Guilherme Salgado <email address hidden> wrote:
> http://bazaar.launchpad.net/~salgado/linaro-image-tools/bug-673412/revision/232
> has the changes to use the UDisks dbus interface instead of
> /proc/mounts

Oh, great. Looks good, thanks.

James

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'media_create/partitions.py'
2--- media_create/partitions.py 2011-01-04 14:27:26 +0000
3+++ media_create/partitions.py 2011-01-05 19:35:20 +0000
4@@ -15,6 +15,8 @@
5 SECTORS = 63
6 SECTOR_SIZE = 512 # bytes
7 CYLINDER_SIZE = HEADS * SECTORS * SECTOR_SIZE
8+DBUS_PROPERTIES = 'org.freedesktop.DBus.Properties'
9+UDISKS = "org.freedesktop.UDisks"
10
11
12 # I wonder if it'd make sense to convert this into a small shim which calls
13@@ -56,6 +58,10 @@
14
15 if should_format_bootfs:
16 print "\nFormating boot partition\n"
17+ # It looks like KDE somehow automounts the partitions after you
18+ # repartition a disk so we need to unmount them here to create the
19+ # filesystem.
20+ ensure_partition_is_not_mounted(bootfs)
21 proc = cmd_runner.run(
22 ['mkfs.vfat', '-F', str(fat_size), bootfs, '-n', bootfs_label],
23 as_root=True)
24@@ -64,6 +70,7 @@
25 if should_format_rootfs:
26 print "\nFormating root partition\n"
27 mkfs = 'mkfs.%s' % rootfs_type
28+ ensure_partition_is_not_mounted(rootfs)
29 proc = cmd_runner.run(
30 [mkfs, '-U', rootfs_uuid, rootfs, '-L', rootfs_label],
31 as_root=True)
32@@ -72,6 +79,23 @@
33 return bootfs, rootfs
34
35
36+def ensure_partition_is_not_mounted(partition):
37+ """Ensure the given partition is not mounted, umounting if necessary."""
38+ if is_partition_mounted(partition):
39+ cmd_runner.run(['umount', partition], as_root=True).wait()
40+
41+
42+def is_partition_mounted(partition):
43+ """Is the given partition mounted?"""
44+ device_path = _get_udisks_device_path(partition)
45+ device = dbus.SystemBus().get_object(UDISKS, device_path)
46+ is_partition = device.Get(
47+ device_path, 'DeviceIsPartition', dbus_interface=DBUS_PROPERTIES)
48+ assert is_partition, "%s is not a partition" % partition
49+ return device.Get(
50+ device_path, 'DeviceIsMounted', dbus_interface=DBUS_PROPERTIES)
51+
52+
53 def get_boot_and_root_loopback_devices(image_file):
54 """Return the boot and root loopback devices for the given image file.
55
56@@ -156,15 +180,18 @@
57 """Return the number of partitions on the given media."""
58 # We could do the same easily using python-parted but it requires root
59 # rights to read block devices, so we use UDisks here.
60+ device_path = _get_udisks_device_path(media.path)
61+ device = dbus.SystemBus().get_object(UDISKS, device_path)
62+ return device.Get(
63+ device_path, 'PartitionTableCount', dbus_interface=DBUS_PROPERTIES)
64+
65+
66+def _get_udisks_device_path(device):
67+ """Return the UDisks path for the given device."""
68 bus = dbus.SystemBus()
69 udisks = dbus.Interface(
70- bus.get_object("org.freedesktop.UDisks", "/org/freedesktop/UDisks"),
71- 'org.freedesktop.UDisks')
72- device_path = udisks.get_dbus_method('FindDeviceByDeviceFile')(media.path)
73- device = bus.get_object("org.freedesktop.UDisks", device_path)
74- return device.Get(
75- device_path, 'partition-table-count',
76- dbus_interface='org.freedesktop.DBus.Properties')
77+ bus.get_object(UDISKS, "/org/freedesktop/UDisks"), UDISKS)
78+ return udisks.get_dbus_method('FindDeviceByDeviceFile')(device)
79
80
81 def convert_size_to_bytes(size):
82
83=== modified file 'media_create/tests/test_media_create.py'
84--- media_create/tests/test_media_create.py 2011-01-05 14:36:26 +0000
85+++ media_create/tests/test_media_create.py 2011-01-05 19:35:20 +0000
86@@ -29,6 +29,7 @@
87 calculate_partition_size_and_offset,
88 convert_size_to_bytes,
89 create_partitions,
90+ ensure_partition_is_not_mounted,
91 get_boot_and_root_loopback_devices,
92 get_boot_and_root_partitions_for_media,
93 Media,
94@@ -423,6 +424,21 @@
95 self.assertIn('Successfully wrote the new partition table', stdout)
96 return tempfile
97
98+ def test_ensure_partition_is_not_mounted_for_mounted_partition(self):
99+ self.useFixture(MockSomethingFixture(
100+ partitions, 'is_partition_mounted', lambda part: True))
101+ popen_fixture = self.useFixture(MockCmdRunnerPopenFixture())
102+ ensure_partition_is_not_mounted('/dev/whatever')
103+ self.assertEqual(
104+ [['sudo', 'umount', '/dev/whatever']], popen_fixture.mock.calls)
105+
106+ def test_ensure_partition_is_not_mounted_for_umounted_partition(self):
107+ self.useFixture(MockSomethingFixture(
108+ partitions, 'is_partition_mounted', lambda part: False))
109+ popen_fixture = self.useFixture(MockCmdRunnerPopenFixture())
110+ ensure_partition_is_not_mounted('/dev/whatever')
111+ self.assertEqual(None, popen_fixture.mock.calls)
112+
113 def test_get_boot_and_root_loopback_devices(self):
114 tempfile = self._create_qemu_img_with_partitions(',1,0x0C,*\n,,,-')
115 popen_fixture = self.useFixture(MockCmdRunnerPopenFixture())
116@@ -446,6 +462,11 @@
117 popen_fixture = self.useFixture(MockCmdRunnerPopenFixture())
118 self.useFixture(MockSomethingFixture(
119 sys, 'stdout', open('/dev/null', 'w')))
120+ self.useFixture(MockSomethingFixture(
121+ partitions, 'is_partition_mounted', lambda part: False))
122+ self.useFixture(MockSomethingFixture(
123+ partitions, 'get_boot_and_root_loopback_devices',
124+ lambda image: ('/dev/loop99', '/dev/loop98')))
125 uuid = '2e82008e-1af3-4699-8521-3bf5bac1e67a'
126 bootfs, rootfs = setup_partitions(
127 'beagle', Media(tempfile), 32, '2G', 'boot', 'root', 'ext3',
128@@ -458,12 +479,6 @@
129 tempfile],
130 # Make sure changes are written to disk.
131 ['sync'],
132- # Register boot/root loopback devices so that we can just copy
133- # their contents over and have it written to the image file.
134- ['sudo', 'losetup', '-f', '--show', tempfile, '--offset',
135- '32256', '--sizelimit', '129024'],
136- ['sudo', 'losetup', '-f', '--show', tempfile, '--offset',
137- '161280', '--sizelimit', '10321920'],
138 ['sudo', 'mkfs.vfat', '-F', '32', bootfs, '-n', 'boot'],
139 ['sudo', 'mkfs.ext3', '-U', uuid, rootfs, '-L', 'root']],
140 popen_fixture.mock.calls)
141@@ -473,6 +488,9 @@
142 sys, 'stdout', open('/dev/null', 'w')))
143 self.useFixture(MockSomethingFixture(
144 partitions, '_get_partition_count', lambda media: 2))
145+ # Pretend the partitions are mounted.
146+ self.useFixture(MockSomethingFixture(
147+ partitions, 'is_partition_mounted', lambda part: True))
148 tempfile = self._create_qemu_img_with_partitions(',1,0x0C,*\n,,,-')
149 media = Media(tempfile)
150 # Pretend our tempfile is a block device.
151@@ -486,7 +504,11 @@
152 [['sudo', 'parted', '-s', tempfile, 'mklabel', 'msdos'],
153 ['sudo', 'sfdisk', '-D', '-H', '255', '-S', '63', tempfile],
154 ['sync'],
155+ # Since the partitions are mounted, setup_partitions will umount
156+ # them before running mkfs.
157+ ['sudo', 'umount', bootfs],
158 ['sudo', 'mkfs.vfat', '-F', '32', bootfs, '-n', 'boot'],
159+ ['sudo', 'umount', rootfs],
160 ['sudo', 'mkfs.ext3', '-U', uuid, rootfs, '-L', 'root']],
161 popen_fixture.mock.calls)
162

Subscribers

People subscribed via source and target branches