Esempio n. 1
0
    def deactivate(dbg, cow_path, parent_cow_path):
        leaf_cow_cache_path = os.path.join(IntelliCache.ROOT_PATH,
                                           cow_path[20:])

        tap = tapdisk.load_tapdisk_metadata(dbg, leaf_cow_cache_path)

        with RefCounter('tapdisk', tap.uuid) as rc:
            if rc.get_count() > 1 or not rc.will_decrease(leaf_cow_cache_path):
                raise RuntimeError("Leaf cache COW already open: {}".format(
                    leaf_cow_cache_path))

            rc.decrement(leaf_cow_cache_path, tap.close, dbg)

        try:
            os.unlink(leaf_cow_cache_path)
        except OSError as exc:
            if exc.errno != errno.EEXIST:
                raise

        parent_cow_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            parent_cow_path[20:]  # remove /var/run/sr-mount, but keep the rest
        )  # TODO: 20 should be 18; the path starts with 2 extra slashes!!

        tap = tapdisk.load_tapdisk_metadata(dbg, parent_cow_cache_path)

        with RefCounter('tapdisk', tap.uuid) as rc:
            rc.decrement(parent_cow_cache_path, tap.close, dbg)
Esempio n. 2
0
    def activate(dbg, cow_path, parent_cow_path, nonpersistent):
        parent_cow_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            parent_cow_path[20:]  # remove /var/run/sr-mount, but keep the rest
        )

        leaf_cow_cache_path = os.path.join(IntelliCache.ROOT_PATH,
                                           cow_path[20:])

        parent_cache_tap = tapdisk.load_tapdisk_metadata(
            dbg, parent_cow_cache_path)

        with RefCounter('tapdisk', parent_cache_tap.uuid) as rc:
            # ['/usr/sbin/tap-ctl', 'allocate']
            # ['/usr/sbin/tap-ctl', 'spawn']
            # ['/usr/sbin/tap-ctl', 'attach', '-p', '5382', '-m', '0']
            # ['/usr/sbin/tap-ctl', 'open',
            #  '-p', '5382',
            #  '-m', '0',
            #  '-a', 'vhd:/var/run/sr-mount/ext3_sr/base_img.vhdcache',
            #  '-r', '-D']
            rc.increment(leaf_cow_cache_path, parent_cache_tap.open_2,
                         'Open parent COW cache', 'vhd', parent_cow_cache_path,
                         {
                             'o_direct': False,
                             'leaf_cache': True
                         })

        tapdisk.save_tapdisk_metadata(dbg, parent_cow_cache_path,
                                      parent_cache_tap)

        leaf_cache_tap = tapdisk.load_tapdisk_metadata(dbg,
                                                       leaf_cow_cache_path)

        with RefCounter('tapdisk', leaf_cache_tap.uuid) as rc:
            if rc.get_count() > 0:
                raise RuntimeError("Leaf cache COW already open: {}".format(
                    leaf_cow_cache_path))

            # ['/usr/sbin/tap-ctl', 'open', '-p', '5394', '-m', '1',
            # '-a', 'vhd:/var/run/sr-mount/ext3_sr/leaf.vhdcache',
            # '-e', '0', '-2', 'vhd:/var/run/sr-mount/nfs_sr/leaf.vhd',
            # '-D']
            rc.increment(
                leaf_cow_cache_path, leaf_cache_tap.open_2,
                'Open leaf COW cache', 'vhd', leaf_cow_cache_path, {
                    'o_direct': False,
                    'existing_parent': str(parent_cache_tap.minor),
                    'standby': nonpersistent,
                    'secondary': {
                        'type': 'vhd',
                        'file_path': cow_path
                    }
                })

        tapdisk.save_tapdisk_metadata(dbg, leaf_cow_cache_path, leaf_cache_tap)
    def activate(dbg, uri, domain, cb):
        this_host_label = util.get_current_host()
        sr, key = _parse_uri(uri)
        opq = cb.volumeStartOperations(sr, 'w')
        meta_path = cb.volumeMetadataGetPath(opq)
        db = VHDMetabase(meta_path)

        with Lock(opq, 'gl', cb):
            with db.write_context():
                vdi = db.get_vdi_by_id(key)
                db.update_vdi_active_on(vdi.uuid, this_host_label)
                vol_path = cb.volumeGetPath(opq, str(vdi.vhd.id))
                img = image.Vhd(vol_path)

                if vdi.vhd.parent_id is not None and vdi_enable_intellicache:
                    parent_vhd_path = cb.volumeGetPath(
                        opq,
                        str(vdi.vhd.parent_id)
                    )

                    IntelliCache.activate(
                        vol_path,
                        parent_vhd_path,
                        vdi.nonpersistent
                    )
                else:
                    tap = tapdisk.load_tapdisk_metadata(dbg, vol_path)
                    tap.open(dbg, img)
                    tapdisk.save_tapdisk_metadata(dbg, vol_path, tap)

        db.close()
        cb.volumeStopOperations(opq)
Esempio n. 4
0
def detach(dbg, uri, domain, cb):
    sr,name = parse_datapath_uri(uri)
    opq = cb.volumeStartOperations(sr, 'r')
    # deactivate LVs chain here
    vol_path = cb.volumeGetPath(opq, name)
    tap = tapdisk.load_tapdisk_metadata(dbg, vol_path)
    tap.destroy(dbg)
    tapdisk.forget_tapdisk_metadata(dbg, vol_path)
Esempio n. 5
0
 def detach_internal(dbg, opq, vdi, cb):
     if vdi.volume.parent_id is not None and vdi_enable_intellicache:
         parent_cow_path = cb.volumeGetPath(opq, str(vdi.volume.parent_id))
         vol_path = cb.volumeGetPath(opq, str(vdi.volume.id))
         IntelliCache.detach(dbg, vol_path, parent_cow_path)
     else:
         vdi_meta_path = cb.get_data_metadata_path(opq, vdi.uuid)
         tap = tapdisk.load_tapdisk_metadata(dbg, vdi_meta_path)
         tap.destroy(dbg)
         tapdisk.forget_tapdisk_metadata(dbg, vdi_meta_path)
Esempio n. 6
0
    def detach(dbg, cow_path, parent_cow_path):
        leaf_cow_cache_path = os.path.join(IntelliCache.ROOT_PATH,
                                           cow_path[20:])

        tap = tapdisk.load_tapdisk_metadata(dbg, leaf_cow_cache_path)

        with RefCounter('tapdisk', tap.uuid) as rc:
            if rc.get_count() == 0:
                tap.destroy(dbg)
                tapdisk.forget_tapdisk_metadata(dbg, leaf_cow_cache_path)

        parent_cow_cache_path = os.path.join(IntelliCache.ROOT_PATH,
                                             parent_cow_path[20:])

        tap = tapdisk.load_tapdisk_metadata(dbg, parent_cow_cache_path)

        with RefCounter('tapdisk', tap.uuid) as rc:
            if rc.get_count() == 0:
                tap.destroy(dbg)
                tapdisk.forget_tapdisk_metadata(dbg, parent_cow_cache_path)
Esempio n. 7
0
 def deactivate_internal(dbg, opq, vdi, img, cb):
     """
     Do the tapdisk specific deactivate
     """
     if vdi.volume.parent_id is not None and vdi_enable_intellicache:
         parent_cow_path = cb.volumeGetPath(opq, str(vdi.volume.parent_id))
         IntelliCache.deactivate(dbg, img.path, parent_cow_path)
     else:
         tap = tapdisk.load_tapdisk_metadata(
             dbg, cb.get_data_metadata_path(opq, vdi.uuid))
         tap.close(dbg)
    def deactivate(dbg, vhd_path, parent_vhd_path):
        leaf_vhd_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            vhd_path[20:]
        )

        tap = tapdisk.load_tapdisk_metadata(dbg, leaf_vhd_cache_path)

        with RefCounter('tapdisk', tap.uuid) as rc:
            if rc.get_count() > 1 or not rc.will_decrease(leaf_vhd_cache_path):
                raise RuntimeError(
                    "Leaf cache VHD already open: {}".format(
                        leaf_vhd_cache_path
                    )
                )

            rc.decrement(
                leaf_vhd_cache_path,
                tap.close,
                dbg
            )

        try:
            os.unlink(leaf_vhd_cache_path)
        except OSError as exc:
            if exc.errno != errno.EEXIST:
                raise

        parent_vhd_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            parent_vhd_path[20:] # remove /var/run/sr-mount, but keep the rest
        ) # TODO: 20 should be 18; the path starts with 2 extra slashes!!

        tap = tapdisk.load_tapdisk_metadata(dbg, parent_vhd_cache_path)

        with RefCounter('tapdisk', tap.uuid) as rc:
            rc.decrement(
                parent_vhd_cache_path,
                tap.close,
                dbg
            )
Esempio n. 9
0
    def activate_internal(dbg, opq, vdi, img, cb):
        if vdi.volume.parent_id is not None and vdi_enable_intellicache:
            parent_cow_path = cb.volumeGetPath(opq, str(vdi.volume.parent_id))

            IntelliCache.activate(img.path, parent_cow_path, vdi.nonpersistent)
        else:
            vdi_meta_path = cb.get_data_metadata_path(opq, vdi.uuid)
            tap = tapdisk.load_tapdisk_metadata(dbg, vdi_meta_path)
            # enable read caching by default since this is
            # goint to be used from licensed SRs
            tap.open(dbg, img, False)
            tapdisk.save_tapdisk_metadata(dbg, vdi_meta_path, tap)
    def detach(dbg, vhd_path, parent_vhd_path):
        leaf_vhd_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            vhd_path[20:]
        )

        tap = tapdisk.load_tapdisk_metadata(dbg, leaf_vhd_cache_path)

        with RefCounter('tapdisk', tap.uuid) as rc:
            if rc.get_count() == 0:
                tap.destroy(dbg)
                tapdisk.forget_tapdisk_metadata(dbg, leaf_vhd_cache_path)

        parent_vhd_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            parent_vhd_path[20:]
        )

        tap = tapdisk.load_tapdisk_metadata(dbg, parent_vhd_cache_path)

        with RefCounter('tapdisk', tap.uuid) as rc:
            if rc.get_count() == 0:
                tap.destroy(dbg)
                tapdisk.forget_tapdisk_metadata(dbg, parent_vhd_cache_path)
Esempio n. 11
0
def deactivate(dbg, uri, domain, cb):
    sr,name = parse_datapath_uri(uri)
    opq = cb.volumeStartOperations(sr, 'w')
    vol_path = cb.volumeGetPath(opq, name)
    meta_path = cb.volumeMetadataGetPath(opq)

    conn = connectSQLite3(meta_path)
    with write_context(conn):
        res = conn.execute("update VDI set active_on = (?) where rowid = (?)",
                           ("", int(name),) )

        tap = tapdisk.load_tapdisk_metadata(dbg, vol_path)
        tap.close(dbg)

    conn.close()
Esempio n. 12
0
def activate(dbg, uri, domain, cb):
    import platform
    sr,name = parse_datapath_uri(uri)
    opq = cb.volumeStartOperations(sr, 'w')
    vol_path = cb.volumeGetPath(opq, name)
    meta_path = cb.volumeMetadataGetPath(opq)

    conn = connectSQLite3(meta_path)
    with write_context(conn):
        res = conn.execute("update VDI set active_on = (?) where rowid = (?)",
                           (platform.node(), int(name),) )

        img = image.Vhd(vol_path)
        tap = tapdisk.load_tapdisk_metadata(dbg, vol_path)
        tap.open(dbg, img)
        tapdisk.save_tapdisk_metadata(dbg, vol_path, tap)

    conn.close()
Esempio n. 13
0
    def activate(self, dbg, uri, domain):
        u = urlparse.urlparse(uri)
        # XXX need some datapath-specific errors below
        if not (os.path.exists(u.path)):
            raise xapi.storage.api.volume.Volume_does_not_exist(u.path)
        if u.scheme[:3] == "vhd":
            img = image.Vhd(u.path)
        elif u.scheme[:3] == "raw":
            img = image.Raw(u.path)
        else:
            raise

        # See whether we should open it O_DIRECT
        o_direct = self._get_uri_param(dbg, uri, 'o_direct', "true")
        o_direct = o_direct in ['true', 't', 'on', '1', 'yes']
        log.debug("o_direct = %s" % (o_direct))

        tap = tapdisk.load_tapdisk_metadata(dbg, u.path)
        tap.open(dbg, img, o_direct)
        tapdisk.save_tapdisk_metadata(dbg, u.path, tap)
Esempio n. 14
0
    def activate(self, dbg, uri, domain):
        u = urlparse.urlparse(uri)
        # XXX need some datapath-specific errors below
        if not(os.path.exists(u.path)):
            raise xapi.storage.api.volume.Volume_does_not_exist(u.path)
        if u.scheme[:3] == "vhd":
            img = image.Vhd(u.path)
        elif u.scheme[:3] == "raw":
            img = image.Raw(u.path)
        else:
            raise

        # See whether we should open it O_DIRECT
        o_direct = self._get_uri_param(dbg, uri, 'o_direct', "true")
        o_direct = o_direct in ['true', 't', 'on', '1', 'yes']
        log.debug("o_direct = %s" % (o_direct))

        tap = tapdisk.load_tapdisk_metadata(dbg, u.path)
        tap.open(dbg, img, o_direct)
        tapdisk.save_tapdisk_metadata(dbg, u.path, tap)
    def deactivate(dbg, uri, domain, cb):
        sr, key = _parse_uri(uri)
        opq = cb.volumeStartOperations(sr, 'w')
        meta_path = cb.volumeMetadataGetPath(opq)
        db = VHDMetabase(meta_path)

        with Lock(opq, 'gl', cb):
            with db.write_context():
                vdi = db.get_vdi_by_id(key)
                db.update_vdi_active_on(vdi.uuid, None)
                vol_path = cb.volumeGetPath(opq, str(vdi.vhd.id))

                if vdi.vhd.parent_id is not None and vdi_enable_intellicache:
                    parent_vhd_path = cb.volumeGetPath(opq, str(vdi.vhd.parent_id))
                    IntelliCache.deactivate(dbg, vol_path, parent_vhd_path)
                else:
                    tap = tapdisk.load_tapdisk_metadata(dbg, vol_path)
                    tap.close(dbg)

        db.close()
        cb.volumeStopOperations(opq)
    def detach(dbg, uri, domain, cb):
        sr, key = _parse_uri(uri)
        opq = cb.volumeStartOperations(sr, 'r')

        meta_path = cb.volumeMetadataGetPath(opq)
        db = VHDMetabase(meta_path)
        with db.write_context():
            vdi = db.get_vdi_by_id(key)
        # deactivate LVs chain here
        db.close()

        vol_path = cb.volumeGetPath(opq, str(vdi.vhd.id))

        if vdi.vhd.parent_id is not None and vdi_enable_intellicache:
            parent_vhd_path = cb.volumeGetPath(opq, str(vdi.vhd.parent_id))
            IntelliCache.detach(dbg, vol_path, parent_vhd_path)
        else:
            tap = tapdisk.load_tapdisk_metadata(dbg, vol_path)
            tap.destroy(dbg)
            tapdisk.forget_tapdisk_metadata(dbg, vol_path)

        cb.volumeStopOperations(opq)
Esempio n. 17
0
def activate(dbg, uri, domain, cb):
    inventory = xcp.environ.readInventory()
    session = XenAPI.xapi_local()
    session.xenapi.login_with_password("root", "")
    this_host = session.xenapi.host.get_by_uuid(inventory.get("INSTALLATION_UUID"))
    this_host_label = session.xenapi.host.get_name_label(this_host)

    sr,name = parse_datapath_uri(uri)
    opq = cb.volumeStartOperations(sr, 'w')
    vol_path = cb.volumeGetPath(opq, name)
    meta_path = cb.volumeMetadataGetPath(opq)

    with Lock(opq, "gl", cb):
        conn = connectSQLite3(meta_path)
        with write_context(conn):
            res = conn.execute("update VDI set active_on = (?) where rowid = (?)",
                               (this_host_label, int(name),) )

            img = image.Vhd(vol_path)
            tap = tapdisk.load_tapdisk_metadata(dbg, vol_path)
            tap.open(dbg, img)
            tapdisk.save_tapdisk_metadata(dbg, vol_path, tap)

        conn.close()
Esempio n. 18
0
 def deactivate(self, dbg, uri, domain):
     u = urlparse.urlparse(uri)
     tap = tapdisk.load_tapdisk_metadata(dbg, u.path)
     tap.close(dbg)
Esempio n. 19
0
 def detach(self, dbg, uri, domain):
     u = urlparse.urlparse(uri)
     tap = tapdisk.load_tapdisk_metadata(dbg, u.path)
     tap.destroy(dbg)
     tapdisk.forget_tapdisk_metadata(dbg, u.path)
Esempio n. 20
0
 def detach(self, dbg, uri, domain):
     u = urlparse.urlparse(uri)
     tap = tapdisk.load_tapdisk_metadata(dbg, u.path)
     tap.destroy(dbg)
     tapdisk.forget_tapdisk_metadata(dbg, u.path)
Esempio n. 21
0
    def attach(dbg, cow_path, parent_cow_path):
        log.debug("parent_cow_path: {}".format(parent_cow_path))

        parent_cow_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            parent_cow_path[20:]  # remove /var/run/sr-mount, but keep the rest
        )  # TODO: 20 should be 18; the path starts with 2 extra slashes!!
        log.debug("parent_cow_cache_path: {}".format(parent_cow_cache_path))

        try:
            os.makedirs(parent_cow_cache_path.rsplit('/', 1)[0])
        except OSError as exc:
            if exc.errno != errno.EEXIST:
                raise

        # Only snapshot parent if it doesn't exist
        if not os.path.isfile(parent_cow_cache_path):
            # ['/usr/bin/vhd-util', 'snapshot', '--debug',
            # '-n', '/var/run/sr-mount/ext3_sr/base_img.vhdcache',
            # '-p', '/var/run/sr-mount/nfs_sr/base_img.vhd']
            log.debug("parent cache does not exist; snapshotting")
            COWUtil.snapshot(dbg, parent_cow_cache_path, parent_cow_path,
                             False)
        else:
            log.debug("parent cache exists; no action")

        leaf_cow_cache_path = os.path.join(IntelliCache.ROOT_PATH,
                                           cow_path[20:])
        log.debug("leaf_cow_cache_path: {}".format(leaf_cow_cache_path))

        try:
            os.makedirs(leaf_cow_cache_path.rsplit('/', 1)[0])
        except OSError as exc:
            if exc.errno != errno.EEXIST:
                raise

        try:
            # Maybe deleting is redundant?
            os.unlink(leaf_cow_cache_path)
            log.debug("leaf cache exists; deleting")
        except OSError as exc:
            if exc.errno == errno.ENOENT:
                log.debug("leaf cache does not exist")
            else:
                raise

        # ['/usr/bin/vhd-util', 'snapshot', '--debug',
        # '-n', '/var/run/sr-mount/ext3_sr/leaf.vhdcache',
        # '-p', '/var/run/sr-mount/ext3_sr/base_img.vhdcache',
        # '-S', '24576', '-e']
        log.debug("snapshotting leaf cache")
        COWUtil.snapshot(dbg, leaf_cow_cache_path, parent_cow_cache_path, True)

        # HANDLE VDI RESIZING

        try:
            # See if 'parent_cow_cache_path' exists
            tapdisk.load_tapdisk_metadata('', parent_cow_cache_path)
        except IOError as exc:
            if exc.errno == errno.ENOENT:
                parent_cache_tap = tapdisk.create(
                    "create 'parent_cache_tap' tapdisk")
                tapdisk.save_tapdisk_metadata('', parent_cow_cache_path,
                                              parent_cache_tap)
            else:
                raise

        try:
            # This should not exist
            tapdisk.load_tapdisk_metadata('', leaf_cow_cache_path)
        except IOError as exc:
            if exc.errno == errno.ENOENT:
                leaf_cache_tap = tapdisk.create(
                    "create 'leaf_cache_tap' tapdisk")
                tapdisk.save_tapdisk_metadata('', leaf_cow_cache_path,
                                              leaf_cache_tap)
            else:
                raise
        else:
            raise RuntimeError(
                "Tapdisk metadata file for '{}' exists; Aborting".format(
                    leaf_cow_cache_path))

        return leaf_cache_tap.block_device()
    def attach(dbg, vhd_path, parent_vhd_path):
        log.debug("parent_vhd_path: {}".format(parent_vhd_path))

        parent_vhd_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            parent_vhd_path[20:] # remove /var/run/sr-mount, but keep the rest
        ) # TODO: 20 should be 18; the path starts with 2 extra slashes!!
        log.debug("parent_vhd_cache_path: {}".format(parent_vhd_cache_path))

        try:
            os.makedirs(parent_vhd_cache_path.rsplit('/', 1)[0])
        except OSError as exc:
            if exc.errno != errno.EEXIST:
                raise

        # Only snapshot parent if it doesn't exist
        if not os.path.isfile(parent_vhd_cache_path):
            # ['/usr/bin/vhd-util', 'snapshot', '--debug',
            # '-n', '/var/run/sr-mount/ext3_sr/base_img.vhdcache',
            # '-p', '/var/run/sr-mount/nfs_sr/base_img.vhd']
            log.debug("parent cache does not exist; snapshotting")
            VHDUtil.snapshot(dbg, parent_vhd_cache_path, parent_vhd_path, False)
        else:
            log.debug("parent cache exists; no action")

        leaf_vhd_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            vhd_path[20:]
        )
        log.debug("leaf_vhd_cache_path: {}".format(leaf_vhd_cache_path))

        try:
            os.makedirs(leaf_vhd_cache_path.rsplit('/', 1)[0])
        except OSError as exc:
            if exc.errno != errno.EEXIST:
                raise

        try:
            # Maybe deleting is redundant?
            os.unlink(leaf_vhd_cache_path)
            log.debug("leaf cache exists; deleting")
        except OSError as exc:
            if exc.errno == errno.ENOENT:
                log.debug("leaf cache does not exist")
            else:
                raise

        # ['/usr/bin/vhd-util', 'snapshot', '--debug',
        # '-n', '/var/run/sr-mount/ext3_sr/leaf.vhdcache',
        # '-p', '/var/run/sr-mount/ext3_sr/base_img.vhdcache',
        # '-S', '24576', '-e']
        log.debug("snapshotting leaf cache")
        VHDUtil.snapshot(dbg, leaf_vhd_cache_path, parent_vhd_cache_path, True)

        # HANDLE VDI RESIZING

        try:
            # See if 'parent_vhd_cache_path' exists
            tapdisk.load_tapdisk_metadata('', parent_vhd_cache_path)
        except IOError as exc:
            if exc.errno == errno.ENOENT:
                parent_cache_tap = tapdisk.create(
                    "create 'parent_cache_tap' tapdisk"
                )
                tapdisk.save_tapdisk_metadata(
                    '',
                    parent_vhd_cache_path,
                    parent_cache_tap
                )
            else:
                raise

        try:
            # This should not exist
            tapdisk.load_tapdisk_metadata('', leaf_vhd_cache_path)
        except IOError as exc:
            if exc.errno == errno.ENOENT:
                leaf_cache_tap = tapdisk.create(
                    "create 'leaf_cache_tap' tapdisk"
                )
                tapdisk.save_tapdisk_metadata(
                    '',
                    leaf_vhd_cache_path,
                    leaf_cache_tap
                )
            else:
                raise
        else:
            raise RuntimeError(
                "Tapdisk metadata file for '{}' exists; Aborting".format(
                    leaf_vhd_cache_path
                )
            )

        return leaf_cache_tap.block_device()
Esempio n. 23
0
 def deactivate(self, dbg, uri, domain):
     u = urlparse.urlparse(uri)
     tap = tapdisk.load_tapdisk_metadata(dbg, u.path)
     tap.close(dbg)
    def activate(dbg, vhd_path, parent_vhd_path, nonpersistent):
        parent_vhd_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            parent_vhd_path[20:] # remove /var/run/sr-mount, but keep the rest
        )

        leaf_vhd_cache_path = os.path.join(
            IntelliCache.ROOT_PATH,
            vhd_path[20:]
        )

        parent_cache_tap = tapdisk.load_tapdisk_metadata(
            dbg,
            parent_vhd_cache_path
        )

        with RefCounter('tapdisk', parent_cache_tap.uuid) as rc:
            # ['/usr/sbin/tap-ctl', 'allocate']
            # ['/usr/sbin/tap-ctl', 'spawn']
            # ['/usr/sbin/tap-ctl', 'attach', '-p', '5382', '-m', '0']
            # ['/usr/sbin/tap-ctl', 'open',
            #  '-p', '5382',
            #  '-m', '0',
            #  '-a', 'vhd:/var/run/sr-mount/ext3_sr/base_img.vhdcache',
            #  '-r', '-D']
            rc.increment(
                leaf_vhd_cache_path,
                parent_cache_tap.open_2,
                'Open parent VHD cache',
                'vhd',
                parent_vhd_cache_path, {
                    'o_direct': False,
                    'leaf_cache': True
                }
            )

        tapdisk.save_tapdisk_metadata(
            dbg,
            parent_vhd_cache_path,
            parent_cache_tap
        )

        leaf_cache_tap = tapdisk.load_tapdisk_metadata(
            dbg,
            leaf_vhd_cache_path
        )

        with RefCounter('tapdisk', leaf_cache_tap.uuid) as rc:
            if rc.get_count() > 0:
                raise RuntimeError(
                    "Leaf cache VHD already open: {}".format(
                        leaf_vhd_cache_path
                    )
                )

            #['/usr/sbin/tap-ctl', 'open', '-p', '5394', '-m', '1',
            # '-a', 'vhd:/var/run/sr-mount/ext3_sr/leaf.vhdcache',
            # '-e', '0', '-2', 'vhd:/var/run/sr-mount/nfs_sr/leaf.vhd',
            # '-D']
            rc.increment(
                leaf_vhd_cache_path,
                leaf_cache_tap.open_2,
                'Open leaf VHD cache',
                'vhd',
                leaf_vhd_cache_path, {
                    'o_direct': False,
                    'existing_parent': str(parent_cache_tap.minor),
                    'standby': nonpersistent,
                    'secondary': {
                        'type': 'vhd',
                        'file_path': vhd_path
                    }
                }
            )

        tapdisk.save_tapdisk_metadata(
            dbg,
            leaf_vhd_cache_path,
            leaf_cache_tap
        )