Akrog / cinderlib

Cinder Library allows using storage drivers outside of Cinder
Apache License 2.0
14 stars 5 forks source link

How to attach a remote connection for ibm svc san storage? #18

Closed tanshaolong closed 1 year ago

tanshaolong commented 5 years ago

Hi,

I create a LPAR at IBM power. I know the wwpn of the lpar. How to attach a volume in IBM SVC that is created by cinderlib by cinderlib? Provided that cinderlib use a sqlite database to storage metadata persistence.

I refer cinderlib connections docs. I think I need to do three steps, but I have some questions for the steps. 1.As a host connect to volume by fibre-channel, how to get its connector information? According to the sample in docs, I get below error exception. “10.10.2.99” is my target host that need to attach volume.

connector_dict = cl.get_connector_properties('sudo', '10.10.2.99', True, False) Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/site-packages/os_brick/utils.py", line 137, in trace_logging_wrapper return f(*args, *kwargs) File "/usr/lib/python2.7/site-packages/os_brick/initiator/connector.py", line 256, in get_connector_properties enforce_multipath=enforce_multipath, File "/usr/lib/python2.7/site-packages/os_brick/initiator/connectors/base.py", line 56, in get_connector_properties execute=kwargs.get('execute'))) File "/usr/lib/python2.7/site-packages/os_brick/initiator/linuxscsi.py", line 161, in is_multipath_running run_as_root=True, root_helper=root_helper) File "/usr/lib/python2.7/site-packages/os_brick/privileged/rootwrap.py", line 169, in execute return execute_root(cmd, **kwargs) File "/usr/lib/python2.7/site-packages/oslo_privsep/priv_context.py", line 204, in _wrap self.start() File "/usr/lib/python2.7/site-packages/oslo_privsep/priv_context.py", line 215, in start channel = daemon.RootwrapClientChannel(context=self) File "/usr/lib/python2.7/site-packages/oslo_privsep/daemon.py", line 327, in init raise FailedToDropPrivileges(msg) oslo_privsep.daemon.FailedToDropPrivileges: privsep helper command exited non-zero (1)

2.If we have known the LPAR wwpn value, whether or not we can directly create a connector dictionary and append the wwpn value to the dictionary? If yes, what is key of wwpn?

3.I mock a connector_info to get conn_info, but I get below exception.

connector_info {'wwpn': 'c0507605ff190012 c0507605ff190013', 'wwpns': 'c0507605ff190012 c0507605ff190013', 'host': '10.10.2.99', 'target_wwn': 'c0507605ff190012 c0507605ff190013', u'target_wwpn': u'c0507605ff190012'} vol.connect(connector_info, attached_host=1) Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/site-packages/cinderlib/objects.py", line 562, in connect self._raise_with_resource() File "/usr/lib/python2.7/site-packages/cinderlib/objects.py", line 222, in _raise_with_resource six.reraise(*exc_info) File "/usr/lib/python2.7/site-packages/cinderlib/objects.py", line 553, in connect conn = Connection.connect(self, connector_dict, ovo_fields) File "/usr/lib/python2.7/site-packages/cinderlib/objects.py", line 618, in connect volume._ovo, connector) File "/usr/lib/python2.7/site-packages/cinder/zonemanager/utils.py", line 80, in decorator conn_info = initialize_connection(self, *args, *kwargs) File "/usr/lib/python2.7/site-packages/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_fc.py", line 123, in initialize_connection return _do_initialize_connection_locked() File "/usr/lib/python2.7/site-packages/oslo_concurrency/lockutils.py", line 271, in inner return f(args, kwargs) File "/usr/lib/python2.7/site-packages/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_fc.py", line 122, in _do_initialize_connection_locked return self._do_initialize_connection(volume, connector) File "/usr/lib/python2.7/site-packages/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_fc.py", line 142, in _do_initialize_connection host_name = self._helpers.get_host_from_connector(connector) File "/usr/lib/python2.7/site-packages/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py", line 874, in get_host_from_connector host_name = None File "/usr/lib/python2.7/site-packages/cinder/volume/drivers/ibm/storwize_svc/storwize_svccommon.py", line 278, in lsfabric msg = (('Must pass wwpn or host to lsfabric.')) File "/usr/lib/python2.7/site-packages/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py", line 165, in run_ssh_info raw = self._run_ssh(ssh_cmd) File "/usr/lib/python2.7/site-packages/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py", line 161, in _run_ssh raise exception.VolumeBackendAPIException(data=msg) cinder.exception.VolumeBackendAPIException: Bad or unexpected response from the storage volume backend API: CLI Exception output: command: ['svcinfo', 'lsfabric', '-delim', '!', '-wwpn', 'c'] stdout: stderr: Error running SSH command.

As the error message “Must pass wwpn or host to lsfabric.”, I think that the cause of the issue is the incorrectly wwpn value. I have tried various “wwpn” key at connector_info. Don’t you know the wwpn key?

I know there some questions have exceeded cinderlib. I don’t have development experience for cinder and os-brick . I don’t know how to get the knowledge quickly. If you would give some help or quick refer doc. I will be very grateful.

Best regards Ray

rollandf commented 5 years ago

Hi, You can try with ansible: https://ansible-storage.readthedocs.io/en/master/

tanshaolong commented 5 years ago

@rollandf Thanks Fred for your quick response. I will try your suggestion.

tanshaolong commented 5 years ago

@rollandf Hi Fred, I have another question if we use ansible. As Ansible work by ssh connection. In other words, the consumer host must have OS and IP address. If we want to attach volume to a bare machine, how would we operate it? Thanks for you.

Akrog commented 5 years ago

@tanshaolong Since you are also working with cinderlib directly, and doing advanced stuff like importing existing volumes from the backend, I wouldn't change to Ansible. The cinderlib library is more robust and better maintained at this point than the Ansible role.

I have recently written some documentation on attach/detach scenarios: https://docs.openstack.org/cinderlib/latest/topics/connections.html

I believe your case is the 3rd one: you want to map the volume in a "controller node" (has credentials and access to the storage management network) and then you want to attach that volume to a different node that only has access to the storage data network, and the 2 nodes don't share the metadata persistence backend (if you were using a MySQL database they could both get the required data from there).

In this case you have to:

The Ansible code is an example of this, but it may be difficult to follow, so you'll probably want to read the specific doc section: https://docs.openstack.org/cinderlib/latest/topics/connections.html#no-access-to-the-metadata-persistence-storage

tanshaolong commented 5 years ago

@Akrog Actually, I had read the connections doc that you mentioned at above. I had used a sqlite database as the metadata persistence storage(not mysql that you mentioned). So, I think my case is 2nd one - "With access to the metadata persistence storage".

No matter case 3rd or 2nd it is, I stuck at 2nd step - Pass that information to the "controller node". In case 2nd, I manual construct the connector information because I get an exception as I referred sample. In case 3rd, I can get connector information but it don’t include wwpns info. If I manual append the wwpns to connector dictionary, I will get above exception.

So, would you give me more cue how to pass the connector information to controller? Thanks you very much.

tanshaolong commented 5 years ago

Check cinder code, I think I find the cause of exception when pass the connector information to controller. The wwpns formation in connector is incorrectly. The correctly information dictionary is below and it work now.

connector_dict {'wwpns': ['c0507605ff190012', 'c0507605ff190013'], 'host': '10.10.2.99'}

Currently, I find a new issue when attach the volume to consume node. We can’t get valid volume path. Although the attach function is failure, the volume has been attached to consumer node when check from SVC managment web site. The below is error exception.

connection.attach() Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/site-packages/cinderlib/objects.py", line 780, in attach device = self.connector.connect_volume(self.conn_info['data']) File "/usr/lib/python2.7/site-packages/os_brick/utils.py", line 137, in trace_logging_wrapper return f(*args, *kwargs) File "/usr/lib/python2.7/site-packages/oslo_concurrency/lockutils.py", line 271, in inner return f(args, **kwargs) File "/usr/lib/python2.7/site-packages/os_brick/initiator/connectors/fibre_channel.py", line 136, in connect_volume raise exception.NoFibreChannelHostsFound() os_brick.exception.NoFibreChannelHostsFound: We are unable to locate any Fibre Channel devices.

Akrog commented 5 years ago

@tanshaolong This is an actual bug!! Thank you for reporting it. The get_connector_properties method in cinderlib is pointing to the normal OS-Brick method, which uses privsep, instead of pointing to our own version of it.

I have created a bug report on the official OpenStack project and proposed a fix.

It should work if you replace your current nos_brick.py file with https://review.openstack.org/cat/649552%2C1%2Ccinderlib/nos_brick.py%5E0

But I think I'm misunderstanding something, because if you are sharing the SQLite database (which is just a file) then it means that both processes are in the same node, or that you are storing the database file on a NFS mount or some other shared file system. Is this correct?

If they are running on the same node you should just be able to do:

   attach = vol.attach()
   print('Path is ' + attach.path)
tanshaolong commented 5 years ago

@Akrog Hi Gorka,

You don’t misunderstand. I think I have some confusion for cinderlib usage. I misunderstand we can operate all steps in controller node. I read the cinderlib connections doc again. Below is my understand for cinderlib usage.

Pretend I have three nodes: 1.Consumer node: It is IBM power LPAR. It don’t install cinderlib and cannot access to SQLite database. The node will need to attach a new volume. 2.Controller node: It is installed cinderlib and cinder pike. It used a SQLite as the persistence storage and the SQLite just be used by the controller node. 3.Storage device: IBM SVC V7000, consumer node can attach its volume by fibre channel.

Because consumer node cannot access to the matedata by SQLite database, we only can refer “No access to the metadata persistence storage” to attach the volume. I think correctly attaching steps are below. Please let me if some misunderstand. 1.Get connector information by os-brick on consumer node. 2.Manual copy connector information to controller node to map/export volume to connection information 3.Manual copy the connection information to consumer node to attach volume.

If the usage is correctly, I have some new questions. 1.Because we attach volume by os-brick, whether or not this mean that the consume node must install os-brick and its dependant packages? 2.If the 1st question is yes, the target machine is bare or can’t install os-brick, how to resolve this situation? 3.I made all steps in controller node yesterday. Although I get an exception when attached volume, why did the consume node attache the volume that seen from SVC management web site?

Also, I try your fix for yesterday’s bug. It work well. Thanks you.

Best regards Ray

Akrog commented 5 years ago

@tanshaolong Thank you for the detailed explanation.

Your understanding of the steps for your specific architecture is correct, but you are missing the last step, which is storing the device information returned by the connect_volume method for the detaching process. This info can be stored in the consumer node or in the controller node:

conn = vol.connections[0]
conn.device = device
conn.save()

You are also correct when you say that you need os-brick and its dependencies if you want to have the library do the attach and detach for you.

If you have a bare system and you cannot install the os-brick library, then you have 2 options:

You can do that custom code in Bash, but I would recommend doing it in Python, since you can use the os-brick FC code as reference.

The controller should not be attaching the volume, only mapping/exporting it, which is done by the connect method (and which should not be attaching the volume unless there is a bug):

vol = storage.Volume.get_by_id(volume_id)
conn = vol.connect(connector_info, attached_host=node_id)
connection_info = conn.connection_info

If you want to speed up the conversation you can come by IRC and ping me (geguileo) on Freenode's #openstack-cinder

If you don't have an IRC client, you can use a webclient such as https://kiwiirc.com/client/irc.freenode.net/openstack-cinder

tanshaolong commented 5 years ago

@Akrog Thanks Gorka for your great help. I think you have given me all of answers that I want. How to attach/detach volume at bare system or the system that cannot install the os-brick library, I would prefer option 2. I will make some research how to resolve it. If I meet new questions, I will ask your help again. Thank you for your help again.