版权声明:本博客欢迎转载,转载时请以超链接形式标明文章原始出处!谢谢!
博客地址:http://blog.csdn.net/i_chips
一、问题现象
Cinder是H版代码,对接的存储是Ceph。
使用cinder命令可以成功创建数据卷并备份数据卷。
但是,使用cinder backup-restore命令恢复备份卷时,如果指定了恢复到源卷,会导致源卷的状态变为error_restoring:
# cinder backup-restore --volume-id <volume-id> <backup-id>
二、问题分析
在日志/var/log/cinder/backup.log中,有如下报错:
2014-06-26 15:53:26.456 28145 DEBUG cinder.backup.drivers.ceph [req-b873021e-b757-4d7d-be4c-235db3949930 admin 23770234f509405dbe5de13faf5bb976] dest volume is original volume - forcing full copy _diff_restore_allowed /usr/lib/python2.6/site-packages/cinder/backup/drivers/ceph.py:914
2014-06-26 15:53:26.643 28145 ERROR cinder.openstack.common.rpc.amqp [req-b873021e-b757-4d7d-be4c-235db3949930 admin 23770234f509405dbe5de13faf5bb976] Exception during message handling
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp Traceback (most recent call last):
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib/python2.6/site-packages/cinder/openstack/common/rpc/amqp.py", line 441, in _process_data
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp **args)
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib/python2.6/site-packages/cinder/openstack/common/rpc/dispatcher.py", line 148, in dispatch
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp return getattr(proxyobj, method)(ctxt, **kwargs)
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib/python2.6/site-packages/cinder/utils.py", line 808, in wrapper
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp return func(self, *args, **kwargs)
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib/python2.6/site-packages/cinder/backup/manager.py", line 346, in restore_backup
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp {'status': 'available'})
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib64/python2.6/contextlib.py", line 23, in __exit__
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp self.gen.next()
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib/python2.6/site-packages/cinder/backup/manager.py", line 340, in restore_backup
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp backup_service)
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib/python2.6/site-packages/cinder/volume/drivers/rbd.py", line 800, in restore_backup
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp backup_service.restore(backup, volume['id'], rbd_fd)
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib/python2.6/site-packages/cinder/backup/drivers/ceph.py", line 986, in restore
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp self._restore_volume(backup, target_volume, volume_file)
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib/python2.6/site-packages/cinder/backup/drivers/ceph.py", line 976, in _restore_volume
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp volume_name, length, src_snap=restore_point)
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib/python2.6/site-packages/cinder/backup/drivers/ceph.py", line 775, in _full_restore
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp snapshot=src_snap, read_only=True)
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp File "/usr/lib/python2.6/site-packages/rbd.py", line 353, in __init__
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp raise make_ex(ret, 'error opening image %s at snapshot %s' % (name, snapshot))
2014-06-26 15:53:26.643 28145 TRACE cinder.openstack.common.rpc.amqp ImageNotFound: error opening image volume-1b04df30-2bdf-47d2-ad02-11ca22839790.backup.0b01d3ec-27d4-4d85-be51-197d4021b137 at snapshot None
根据上面的最后一行日志,在cinder.backup.drivers.ceph:CephBackupDriver._full_restore中:
src_rbd = self.rbd.Image(client.ioctx, backup_name, snapshot=src_snap, read_only=True)
这行代码的snapshot=src_snap为None值,所以导致报错。
往上回溯,snapshot=src_snap(即src_snap=restore_point)的值是在cinder.backup.drivers.ceph:CephBackupDriver._restore_volume中被赋值的:
diff_allowed, restore_point = self._diff_restore_allowed(base_name, backup, volume, volume_file, client)
我们进入到cinder.backup.drivers.ceph:CephBackupDriver._diff_restore_allowed中,看到这样几行代码:
not_allowed = (False, None)
# If the volume we are restoring to is the volume the backup was made
# from, force a full restore since a diff will not work in this case.
if volume['id'] == backup['volume_id']:
LOG.debug(_("dest volume is original volume - forcing full copy"))
return not_allowed
很明显,参考注释,这就是restore_point为什么是None的原因。
三、解决办法
据检索,该问题和该链接中所描述的情况表现一致:
https://bugs.launchpad.net/cinder/+bug/1276977
该问题已经在Cinder的I版中修复了,修改代码如下:
https://git.openstack.org/cgit/openstack/cinder/commit/?id=4d1d9349fed815b37b0675d6f3936243a3909125