Python Hivex problem - device or resource busy

I am trying to do the following:

  • Install the root partition (C: drive) of the Windows RAW image (.img) to the mount point say /mnt/mnt-swapniku
  • Register the RunOnce service in the registry
  • Then the umount /mnt/mnt-swapnikuclosed loop device

An example code is given below. Everything works fine until unmounted. Operations kpartx -dand losetup -dnot performed.

The same issue is discussed here: http://www.redhat.com/archives/libguestfs/2011-July/msg00007.html

This problem was fixed in Hivex back in 2011. Unfortunately, it does not seem to work on my machine. Surprisingly, when I'm doing kpartx -d /dev/loop0and losetup -d /dev/loop0manually at the terminal, it works fine. Initially, I thought Hivex took some time to free up resources, so I also introduced a delay. But to no avail.

Can someone help me with this issue in Python?


Environment:

CentOs 6.5 + hivex-1.3.3-4.2.el6.x86_64 + python-hivex-1.3.3-4.2.el6.x86_64

Code (runonce_registry.py):

import hivex
import os
import time

cfg_root = '/mnt/mnt-swapniku/'

win_install_run_once_service_reg_keys = [
    {'key':"Foo Service", 't':1, 'value':"C:\Windows\Temp\foo.exe\0".encode('utf-16le')}
]

def win_add_run_once_service(config_root, service_keys, silent = False):
    '''
    Add RunOnce Windows service registry

    config_root:
        Path of the C drive
    silent:
        Set True/False for logging info

    Ref - http://libguestfs.org/hivex.3.html

    '''
    try:        
        h = hivex.Hivex(config_root + '/Windows/System32/config/SOFTWARE', write = True)
        key = h.root()

        for child in ('Microsoft', 'Windows', 'CurrentVersion'):
            key = h.node_get_child(key, child)
            runonce = h.node_get_child(key, "RunOnce")

        if runonce is None:
            runonce = h.node_add_child(key, "RunOnce")

        h.node_set_values(runonce, service_keys)

        h.commit(None)

        if not silent:
            print("Added Windows RunOnce service")

        # Hivex cleanup
        del h # or h.close()

        time.sleep(1)

    except RuntimeError:
        print("Hivex encountered RuntimeError while adding Windows RunOnce service")
        return False

    return True

if __name__ == '__main__':
    win_add_run_once_service(cfg_root, win_install_run_once_service_reg_keys)
    os.system('umount ' + cfg_root)
    os.system('kpartx -d /dev/loop0')
    os.system('losetup -d /dev/loop0')

Conclusion:

[root@dhcp-xxx-xx-xx-xx Windows_Registry]# losetup /dev/loop0 win2k8r2.x86_64.img
[root@dhcp-xxx-xx-xx-xx Windows_Registry]# kpartx -a /dev/loop0
[root@dhcp-xxx-xx-xx-xx Windows_Registry]# mount /dev/mapper/loop0p2 /mnt/mnt-swapniku/
[root@dhcp-xxx-xx-xx-xx Windows_Registry]# python runonce_registry.py
Added Windows RunOnce service
device-mapper: remove ioctl on loop0p2 failed: Device or resource busy
loop: can't delete device /dev/loop0: Device or resource busy
+3
source share

All Articles