Revision 3f78eef2 lib/backend.py

b/lib/backend.py
620 620
  return True
621 621

  
622 622

  
623
def CreateBlockDevice(disk, size, on_primary, info):
623
def CreateBlockDevice(disk, size, owner, on_primary, info):
624 624
  """Creates a block device for an instance.
625 625

  
626 626
  Args:
......
638 638
  clist = []
639 639
  if disk.children:
640 640
    for child in disk.children:
641
      crdev = _RecursiveAssembleBD(child, on_primary)
641
      crdev = _RecursiveAssembleBD(child, owner, on_primary)
642 642
      if on_primary or disk.AssembleOnSecondary():
643 643
        # we need the children open in case the device itself has to
644 644
        # be assembled
......
664 664
    device.SetSyncSpeed(constants.SYNC_SPEED)
665 665
    if on_primary or disk.OpenOnSecondary():
666 666
      device.Open(force=True)
667
    DevCacheManager.UpdateCache(device.dev_path, owner,
668
                                on_primary, disk.iv_name)
667 669

  
668 670
  device.SetInfo(info)
669 671

  
......
686 688
    logger.Info("Can't attach to device %s in remove" % disk)
687 689
    rdev = None
688 690
  if rdev is not None:
691
    r_path = rdev.dev_path
689 692
    result = rdev.Remove()
693
    if result:
694
      DevCacheManager.RemoveCache(r_path)
690 695
  else:
691 696
    result = True
692 697
  if disk.children:
......
695 700
  return result
696 701

  
697 702

  
698
def _RecursiveAssembleBD(disk, as_primary):
703
def _RecursiveAssembleBD(disk, owner, as_primary):
699 704
  """Activate a block device for an instance.
700 705

  
701 706
  This is run on the primary and secondary nodes for an instance.
......
715 720
  children = []
716 721
  if disk.children:
717 722
    for chld_disk in disk.children:
718
      children.append(_RecursiveAssembleBD(chld_disk, as_primary))
723
      children.append(_RecursiveAssembleBD(chld_disk, owner, as_primary))
719 724

  
720 725
  if as_primary or disk.AssembleOnSecondary():
721 726
    r_dev = bdev.AttachOrAssemble(disk.dev_type, disk.physical_id, children)
......
725 730
      r_dev.Open()
726 731
    else:
727 732
      r_dev.Close()
733
    DevCacheManager.UpdateCache(r_dev.dev_path, owner,
734
                                as_primary, disk.iv_name)
735

  
728 736
  else:
729 737
    result = True
730 738
  return result
731 739

  
732 740

  
733
def AssembleBlockDevice(disk, as_primary):
741
def AssembleBlockDevice(disk, owner, as_primary):
734 742
  """Activate a block device for an instance.
735 743

  
736 744
  This is a wrapper over _RecursiveAssembleBD.
......
740 748
    True for secondary nodes
741 749

  
742 750
  """
743
  result = _RecursiveAssembleBD(disk, as_primary)
751
  result = _RecursiveAssembleBD(disk, owner, as_primary)
744 752
  if isinstance(result, bdev.BlockDev):
745 753
    result = result.dev_path
746 754
  return result
......
759 767
  """
760 768
  r_dev = _RecursiveFindBD(disk)
761 769
  if r_dev is not None:
770
    r_path = r_dev.dev_path
762 771
    result = r_dev.Shutdown()
772
    if result:
773
      DevCacheManager.RemoveCache(r_path)
763 774
  else:
764 775
    result = True
765 776
  if disk.children:
......
1356 1367
      result = False
1357 1368
      continue
1358 1369
    try:
1370
      old_rpath = dev.dev_path
1359 1371
      dev.Rename(unique_id)
1372
      new_rpath = dev.dev_path
1373
      if old_rpath != new_rpath:
1374
        DevCacheManager.RemoveCache(old_rpath)
1375
        # FIXME: we should add the new cache information here, like:
1376
        # DevCacheManager.UpdateCache(new_rpath, owner, ...)
1377
        # but we don't have the owner here - maybe parse from existing
1378
        # cache? for now, we only lose lvm data when we rename, which
1379
        # is less critical than DRBD or MD
1360 1380
    except errors.BlockDeviceError, err:
1361 1381
      logger.Error("Can't rename device '%s' to '%s': %s" %
1362 1382
                   (dev, unique_id, err))
......
1473 1493
      rr.append(("%s/%s" % (subdir, relname), rrval, output))
1474 1494

  
1475 1495
    return rr
1496

  
1497

  
1498
class DevCacheManager(object):
1499
  """Simple class for managing a chache of block device information.
1500

  
1501
  """
1502
  _DEV_PREFIX = "/dev/"
1503
  _ROOT_DIR = constants.BDEV_CACHE_DIR
1504

  
1505
  @classmethod
1506
  def _ConvertPath(cls, dev_path):
1507
    """Converts a /dev/name path to the cache file name.
1508

  
1509
    This replaces slashes with underscores and strips the /dev
1510
    prefix. It then returns the full path to the cache file
1511

  
1512
    """
1513
    if dev_path.startswith(cls._DEV_PREFIX):
1514
      dev_path = dev_path[len(cls._DEV_PREFIX):]
1515
    dev_path = dev_path.replace("/", "_")
1516
    fpath = "%s/bdev_%s" % (cls._ROOT_DIR, dev_path)
1517
    return fpath
1518

  
1519
  @classmethod
1520
  def UpdateCache(cls, dev_path, owner, on_primary, iv_name):
1521
    """Updates the cache information for a given device.
1522

  
1523
    """
1524
    fpath = cls._ConvertPath(dev_path)
1525
    if on_primary:
1526
      state = "primary"
1527
    else:
1528
      state = "secondary"
1529
    if iv_name is None:
1530
      iv_name = "not_visible"
1531
    fdata = "%s %s %s\n" % (str(owner), state, iv_name)
1532
    try:
1533
      utils.WriteFile(fpath, data=fdata)
1534
    except EnvironmentError, err:
1535
      logger.Error("Can't update bdev cache for %s, error %s" %
1536
                   (dev_path, str(err)))
1537

  
1538
  @classmethod
1539
  def RemoveCache(cls, dev_path):
1540
    """Remove data for a dev_path.
1541

  
1542
    """
1543
    fpath = cls._ConvertPath(dev_path)
1544
    try:
1545
      utils.RemoveFile(fpath)
1546
    except EnvironmentError, err:
1547
      logger.Error("Can't update bdev cache for %s, error %s" %
1548
                   (dev_path, str(err)))

Also available in: Unified diff