From patchwork Wed Jul 29 09:28:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 6891491 Return-Path: X-Original-To: patchwork-ceph-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 79D609F358 for ; Wed, 29 Jul 2015 09:28:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 61310205BC for ; Wed, 29 Jul 2015 09:28:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E8243205BA for ; Wed, 29 Jul 2015 09:28:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751387AbbG2J2G (ORCPT ); Wed, 29 Jul 2015 05:28:06 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50872 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750887AbbG2J2E (ORCPT ); Wed, 29 Jul 2015 05:28:04 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 3F0D48E694; Wed, 29 Jul 2015 09:28:04 +0000 (UTC) Received: from [10.10.60.109] (vpn-60-109.rdu2.redhat.com [10.10.60.109]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t6T9S3DG004397; Wed, 29 Jul 2015 05:28:03 -0400 Message-ID: <55B89CA2.1050807@redhat.com> Date: Wed, 29 Jul 2015 04:28:02 -0500 From: Mike Christie User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: "ceph-devel@vger.kernel.org >> Ceph Development" , "target-devel@vger.kernel.org >> target-devel" Subject: [PATCH 0/18] lio rbd support X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_TVD_MIME_EPI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The following patches implement a LIO RBD backend. Instead of having LIO send bios/requests through the block layer and having rbd translate them to ceph/rados requests, this implements a LIO RBD backend module that translates LIO se_cmds directly to ceph/rados requests. This patchset also implements native ceph/rados support for WRITE_SAME and COMPARE_AND_WRITE commands. We execute them on the OSD similar to how we execute UNMAP/TRIM/DISCARD requests. This patchset just only implements single node support. The cluster support will be posted soon. I am currently redoing my patches against Doug's locking API and redoing my PR hooks. The patches were made over linus's tree pulled today (last commit 956325bd55bb020e574129c443a2c2c66a8316e7), plus Nick's target-pending tree (last commit 7a14e3c1cfcbdf377098542ba440e1ebb0eeafa4), and Doug's wip-djf-watch-notify2 branch in the ceph client tree which can be found here https://github.com/ceph/ceph-client. Attached at the patches for rtslib and targetlci to be able to use the rbd module. It was made over Andy's fb branch. diff -aurp rtslib-fb-2.1.fb57/rtslib/tcm.py rtslib-fb-2.1.fb57.work/rtslib/tcm.py --- rtslib-fb-2.1.fb57/rtslib/tcm.py 2015-06-23 11:21:11.000000000 -0500 +++ rtslib-fb-2.1.fb57.work/rtslib/tcm.py 2015-07-29 02:58:24.882204555 -0500 @@ -735,6 +734,107 @@ class BlockStorageObject(StorageObject): d['dev'] = self.udev_path return d +class RBDStorageObject(StorageObject): + ''' + An interface to configFS storage objects for RBD backstore. + ''' + + # RBDStorageObject private stuff + + def __init__(self, name, dev=None, wwn=None, readonly=False, + write_back=False): + ''' + A RBDIOStorageObject can be instantiated in two ways: + - B{Creation mode}: If I{dev} is specified, the underlying configFS + object will be created with that parameter. + No RBDIOStorageObject with the same I{name} can pre-exist in + the parent Backstore in that mode. + - B{Lookup mode}: If I{dev} is not set, then the + RBDIOStorageObject will be bound to the existing configFS + object in the parent Backstore having the specified + I{name}. The underlying configFS object must already exist in + that mode, or instantiation will fail. + + @param name: The name of the RBDIOStorageObject. + @type name: string + @param dev: The path to the backend rbd device to be used. + - Example: I{dev="/dev/sda"}. + - The only device type that is accepted I{TYPE_DISK}. + For other device types, use pscsi. + @type dev: string + @param wwn: T10 WWN Unit Serial, will generate if None + @type wwn: string + @return: A RBDIOStorageObject object. + ''' + + if dev is not None: + super(RBDStorageObject, self).__init__(name, 'create') + try: + self._configure(dev, wwn, readonly) + except: + self.delete() + raise + else: + super(RBDStorageObject, self).__init__(name, 'lookup') + + def _configure(self, dev, wwn, readonly): + self._check_self() + if get_blockdev_type(dev) != 0: + raise RTSLibError("Device %s is not a TYPE_DISK rbd device" % dev) + if is_dev_in_use(dev): + raise RTSLibError("Cannot configure StorageObject because " + + "device %s is already in use" % dev) + self._set_udev_path(dev) + self._control("udev_path=%s" % dev) + self._control("readonly=%d" % readonly) + self._enable() + + super(RBDStorageObject, self)._configure(wwn) + + def _get_major(self): + self._check_self() + return int(self._parse_info('Major')) + + def _get_minor(self): + self._check_self() + return int(self._parse_info('Minor')) + + def _get_size(self): + # udev_path doesn't work here, what if LV gets renamed? + return get_size_for_disk_name(self._parse_info('device')) * int(self._parse_info('SectorSize')) + + def _get_wb_enabled(self): + self._check_self() + return bool(int(self.get_attribute("emulate_write_cache"))) + + def _get_readonly(self): + self._check_self() + # 'readonly' not present before kernel 3.6 + try: + return bool(int(self._parse_info('readonly'))) + except AttributeError: + return False + + # RBDStorageObject public stuff + + major = property(_get_major, + doc="Get the block device major number") + minor = property(_get_minor, + doc="Get the block device minor number") + size = property(_get_size, + doc="Get the block device size") + write_back = property(_get_wb_enabled, + doc="True if write-back, False if write-through (write cache disabled)") + readonly = property(_get_readonly, + doc="True if the device is read-only, False if read/write") + + def dump(self): + d = super(RBDStorageObject, self).dump() + d['write_back'] = self.write_back + d['readonly'] = self.readonly + d['wwn'] = self.wwn + d['dev'] = self.udev_path + return d class UserBackedStorageObject(StorageObject): ''' @@ -850,6 +950,7 @@ so_mapping = { "fileio": FileIOStorageObject, "iblock": BlockStorageObject, "block": BlockStorageObject, + "rbd": RBDStorageObject, "user": UserBackedStorageObject, } @@ -860,6 +961,7 @@ bs_params = { FileIOStorageObject: dict(name='fileio'), BlockStorageObject: dict(name='block', alt_dirprefix='iblock'), UserBackedStorageObject: dict(name='user'), + RBDStorageObject: dict(name='rbd'), } bs_cache = {}