def locked_volume_id_operation(f, external=False):
 def lvo_inner1(inst, *args, **kwargs):
  lock_tag = inst.driver_prefix
  call_args = inspect.getcallargs(f, inst, *args, **kwargs)
  if call_args.get('volume'):
   volume_id = call_args['volume'].id
  elif call_args.get('snapshot'):
   volume_id = call_args['snapshot'].volume.id
  else:
   err_msg = _('The decorated method must accept either a volume or a snapshot object')
   raise exception.VolumeBackendAPIException(data=err_msg)
  @utils.synchronized(('%s-%s' % (lock_tag, volume_id)), external=external)
  def lvo_inner2():
   return f(inst, *args, **kwargs)
  return lvo_inner2()
 return lvo_inner1

def locked_volume_id_operation ( f , external = False ) : def lvo_inner1 ( inst , * args , ** kwargs ) : lock_tag = inst . driver_prefix call_args = inspect . getcallargs ( f , inst , * args , ** kwargs ) if call_args . get ( 'volume' ) : volume_id = call_args [ 'volume' ] . id elif call_args . get ( 'snapshot' ) : volume_id = call_args [ 'snapshot' ] . volume . id else : err_msg = _ ( 'The decorated method must accept either a volume or a snapshot object' ) raise exception . VolumeBackendAPIException ( data = err_msg ) @ utils . synchronized ( ( '%s-%s' % ( lock_tag , volume_id ) ) , external = external ) def lvo_inner2 ( ) : return f ( inst , * args , ** kwargs ) return lvo_inner2 ( ) return lvo_inner1
lock decorator for volume operations .