Created attachment 786041 [details] Reproducer Description of problem: Creating LUKSDevice does not work. For more details, see below. Version-Release number of selected component (if applicable): python-blivet-0.19-1.fc20.noarch How reproducible: Always Steps to Reproduce: 1. Create a LUKS partition (/dev/vda12 in my case) 2. Run the reproducer (tweak partition/password if necessary) 3. Observe the error Actual results: Program output: DEBUG: d.format.device: /dev/vda12 DEBUG: luksdevice.format.device: /dev/mapper/luks-test-blivet DEBUG: luksdevice.format.device: /dev/mapper/luks-test-blivet DEBUG: d.format.device: /dev/mapper/luks-test-blivet and then a traceback: FormatSetupError Traceback (most recent call last) /usr/lib/python2.7/site-packages/IPython/utils/py3compat.pyc in execfile(fname, *where) 176 else: 177 filename = fname --> 178 __builtin__.execfile(filename, *where) /home/jsynacek/openlmi-storage-nfs/blivet-luks-bug2.py in <module>() 27 28 action = blivet.ActionCreateDevice(luksdevice) ---> 29 action.execute() /usr/lib/python2.7/site-packages/blivet/deviceaction.pyc in execute(self) 270 271 def execute(self): --> 272 self.device.create() 273 274 def requires(self, action): /usr/lib/python2.7/site-packages/blivet/devices.pyc in create(self) 784 """ Create the device. """ 785 log_method_call(self, self.name, status=self.status) --> 786 self._preCreate() 787 try: 788 self._create() /usr/lib/python2.7/site-packages/blivet/devices.pyc in _preCreate(self) 775 raise DeviceError("device has already been created", self.name) 776 --> 777 self.setupParents() 778 779 def _create(self): /usr/lib/python2.7/site-packages/blivet/devices.pyc in setupParents(self, orig) 839 # set up the formatting, if present 840 if _format.type and _format.exists: --> 841 _format.setup() 842 843 def _getSize(self): /usr/lib/python2.7/site-packages/blivet/formats/luks.pyc in setup(self, *args, **kwargs) 166 return 167 --> 168 DeviceFormat.setup(self, *args, **kwargs) 169 crypto.luks_open(self.device, self.mapName, 170 passphrase=self.__passphrase, /usr/lib/python2.7/site-packages/blivet/formats/__init__.pyc in setup(self, *args, **kwargs) 345 346 if not self.device or not os.path.exists(self.device): --> 347 raise FormatSetupError("invalid device specification") 348 349 def teardown(self, *args, **kwargs): Expected results: The LUKS device is opened as expected. Additional info: Why is d.format.device changed to /dev/mapper/luks-test-blivet after calling the LUKSDevice constructor? The conditional on line 346 then has to fail, since the path surely does not exist. If you uncomment the marked line in the reproducer, the LUKS device gets opened as expected. The output then looks like so: DEBUG: d.format.device: /dev/vda12 DEBUG: luksdevice.format.device: /dev/mapper/luks-test-blivet DEBUG: luksdevice.format.device: /dev/vda12 DEBUG: d.format.device: /dev/vda12 Howerver, it's possible to call it repeatedly without producing any error whatsoever, which I consider a bug too.
Some background how OpenLMI uses LUKS / Blivet: We want to be able separately control creation of LUKSFormat and opening it as LUKSDevice. I.e. remote application scans a system and finds empty partition. The application then creates LUKSFormat there, *without opening it*. As second step, (potentially different) remote application scans the same system and finds a LUKSFormat there and decides to *open* it - that's why we need working LUKSDevice() constructor and ActionCreateDevice. The same application might close the LUKSDevice later (ActionDestroyDevice with LUKSDevice), while leaving the LUKSFormat there to be opened again later. (and that's why we need blivet.reset() not to open any LUKS formats it finds, see bug #996118 - reset() should just scan the system, without modifying it).
(In reply to Jan Safranek from comment #1) > need working LUKSDevice() constructor and ActionCreateDevice. The same > application might close the LUKSDevice later (ActionDestroyDevice with > LUKSDevice), while leaving the LUKSFormat there to be opened again later. If you want to close a device, use device.teardown -- not device.destroy. StorageDevice.destroy permanently _destroys_ the device. Basically, there will always be a LUKSDevice associated with a device that contains a LUKS format. Whether or not that LUKS format can be opened is a different matter (decided by presence of a valid key/passphrase).
From your reproducer: luksdevice = blivet.devices.LUKSDevice('luks-test-blivet', size=d.size, uuid=d.format.uuid, sysfsPath=d.sysfsPath, format=d.format, # <-- here's your problem parents=[d], exists=False) Two devices cannot share the same DeviceFormat instance. Every block device contains its own DeviceFormat instance. The device that is formatted as luks has a LUKS instance as its format. The open/mapped device that represents the decrypted/usable luks device (eg: /dev/mapper/luks-whatever) has a format that represents what is on the decrypted device, such as an ext4 filesystem. Does this clarify things?
Does it mean that I have to know what filesystem there is underneath the luks layer and prepare the format accordingly? That doesn't sound right to me. I'm still confused about what to put into the format parameter.
You don't have to pass a format at all if you don't know what you'll be formatting it as or if you plan to leave it unformatted for the time being.
Ok, the following seems to work: import blivet b = blivet.Blivet() b.reset() d = b.devicetree.getDeviceByPath('/dev/vda12') d.format.passphrase = 'fiembi43mygf' d.format.mapName = 'luks-test-blivet' luksdevice = blivet.devices.LUKSDevice('luks-test-blivet', uuid=d.format.uuid, parents=[d]) action = blivet.ActionCreateDevice(luksdevice) action.execute() Is it supposed to work like that? I mean the part where I'm setting passphrase and mapName in the *original* format.
(In reply to Jan Synacek from comment #6) > Is it supposed to work like that? I mean the part where I'm setting > passphrase and mapName in the *original* format. Normally you would create a new luks format if you want to create a new luks device: # no need to set map name as it will get updated automatically fmt = blivet.formats.getFormat("luks", passphrase="blahblahblah") b.formatDevice(d, fmt) luksdevice = blivet.devices.LUKSDevice('luks-whatever', parents=[d]) b.createDevice(luksdevice) b.doIt() # or b.devicetree.processActions()
import blivet b = blivet.Blivet() b.reset() d = b.devicetree.getDeviceByPath('/dev/vda12') fmt = blivet.formats.getFormat("luks", passphrase='fiembi43mygf') b.formatDevice(d, fmt) luksdevice = blivet.devices.LUKSDevice('luks-test-blivet', parents=[d]) b.createDevice(luksdevice) b.doIt() This works, except that the LUKS device is opened as luks-<uuid>, not 'luks-test-blivet'. It seems that the first argument of LUKSDevice() gets somehow ignored. I even tried to set map name whereever it was possible, still ignored.
(In reply to Jan Synacek from comment #8) > This works, except that the LUKS device is opened as luks-<uuid>, not > 'luks-test-blivet'. It seems that the first argument of LUKSDevice() gets > somehow ignored. I even tried to set map name whereever it was possible, > still ignored. Right -- this is a relic from anaconda usage. I need to make the automatic transition to luks-$UUID for the map name installer-only behavior.
python-blivet-0.21-1.fc20 has been submitted as an update for Fedora 20. https://admin.fedoraproject.org/updates/python-blivet-0.21-1.fc20
Package python-blivet-0.21-1.fc20: * should fix your issue, * was pushed to the Fedora 20 testing repository, * should be available at your local mirror within two days. Update it with: # su -c 'yum update --enablerepo=updates-testing python-blivet-0.21-1.fc20' as soon as you are able to. Please go to the following url: https://admin.fedoraproject.org/updates/FEDORA-2013-15976/python-blivet-0.21-1.fc20 then log in and leave karma (feedback).
python-blivet-0.22-1.fc20 has been submitted as an update for Fedora 20. https://admin.fedoraproject.org/updates/python-blivet-0.22-1.fc20
Traceback (most recent call last): File "blivet-luks-bug2-bz.py", line 13, in <module> b.doIt() File "/usr/lib/python2.7/site-packages/blivet/__init__.py", line 310, in doIt self.devicetree.processActions() File "/usr/lib/python2.7/site-packages/blivet/devicetree.py", line 237, in processActions action.execute() File "/usr/lib/python2.7/site-packages/blivet/deviceaction.py", line 272, in execute self.device.create() File "/usr/lib/python2.7/site-packages/blivet/devices.py", line 786, in create self._preCreate() File "/usr/lib/python2.7/site-packages/blivet/devices.py", line 777, in _preCreate self.setupParents() File "/usr/lib/python2.7/site-packages/blivet/devices.py", line 841, in setupParents _format.setup() File "/usr/lib/python2.7/site-packages/blivet/formats/luks.py", line 164, in setup raise LUKSError("luks device not configured") blivet.errors.LUKSError: luks device not configured I'm getting this with the same code snipped as in comment 8. # rpm -q python-blivet python-blivet-0.22-1.fc21.noarch
This bug appears to have been reported against 'rawhide' during the Fedora 20 development cycle. Changing version to '20'. More information and reason for this action is here: https://fedoraproject.org/wiki/BugZappers/HouseKeeping/Fedora20
python-blivet-0.22-1.fc20 has been pushed to the Fedora 20 stable repository. If problems still persist, please make note of it in this bug report.
I'm still able to reproduce the crash reported in comment #13 using python-blivet-0.23-1.fc21.noarch. blivet creates the LUKS on the right device, but fails shortly after that, still in devicetree.processActions().
(In reply to Jan Synacek from comment #8) > fmt = blivet.formats.getFormat("luks", passphrase='fiembi43mygf') > b.formatDevice(d, fmt) > luksdevice = blivet.devices.LUKSDevice('luks-test-blivet', > parents=[d]) You should pass the name to the LUKS constructor as well as the LUKSDevice constructor. Your getFormat call should look like this: fmt = blivet.formats.getFormat("luks", passphrase='fiembi43mygf', name='luks-test-blivet')