AutoLoadEntry.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. using DiskAccessLibrary;
  2. using DiskAccessLibrary.Mod;
  3. using ISCSI.Server;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Configuration;
  7. using System.Diagnostics;
  8. using System.Linq;
  9. using System.Xml;
  10. namespace ISCSIConsole.Mods
  11. {
  12. public class AutoLoadEntrySection : IConfigurationSectionHandler
  13. {
  14. public object Create(object parent, object configContext, XmlNode section)
  15. {
  16. var entries = new List<AutoLoadEntry>();
  17. foreach (XmlNode entryNode in section.ChildNodes)
  18. {
  19. Debug.Assert(entryNode.Attributes != null, "childNode.Attributes != null");
  20. var entry = new AutoLoadEntry
  21. {
  22. Iqn = entryNode.Attributes[nameof(AutoLoadEntry.Iqn)].Value,
  23. Enable = entryNode.Attributes[nameof(AutoLoadEntry.Enable)].Value == "true",
  24. };
  25. entry.Disks = new List<AutoLoadDisk>();
  26. foreach (XmlNode diskNode in entryNode.ChildNodes)
  27. {
  28. Debug.Assert(diskNode.Attributes != null, "diskNode.Attributes != null");
  29. var disk = new AutoLoadDisk
  30. {
  31. Type = (AutoLoadDiskType)Enum.Parse(typeof(AutoLoadDiskType), diskNode.Attributes[nameof(AutoLoadDisk.Type)].Value),
  32. FilePath = diskNode.Attributes[nameof(AutoLoadDisk.FilePath)].Value,
  33. ReadOnly = "true" == diskNode.Attributes[nameof(AutoLoadDisk.ReadOnly)]?.Value,
  34. Enable = "true" == diskNode.Attributes[nameof(AutoLoadDisk.Enable)]?.Value
  35. };
  36. entry.Disks.Add(disk);
  37. }
  38. entries.Add(entry);
  39. }
  40. return entries;
  41. }
  42. }
  43. internal class AutoLoadEntry
  44. {
  45. public bool Enable { get; set; }
  46. public string Iqn { get; set; }
  47. public List<AutoLoadDisk> Disks { get; set; }
  48. public ISCSITarget CreateTarget()
  49. {
  50. var disks = new List<Disk>();
  51. var target = new ISCSITarget(Iqn, disks);
  52. foreach (var disk in Disks.Where(p=>p.Enable))
  53. {
  54. disks.Add(disk.CreateDisk());
  55. }
  56. return target;
  57. }
  58. }
  59. internal class AutoLoadDisk
  60. {
  61. public bool Enable { get; set; }
  62. public AutoLoadDiskType Type { get; set; }
  63. public string FilePath { get; set; }
  64. public bool ReadOnly { get; set; }
  65. public Disk CreateDisk()
  66. {
  67. switch (Type)
  68. {
  69. case AutoLoadDiskType.RamDiskFromFile:
  70. var bdd = new BlockDifferencingDiskImage(FilePath, true);
  71. try
  72. {
  73. if (false == bdd.IsNoBaseImage) throw new ConfigurationErrorsException("RamDiskFromFile: Only ** No Base Image Mode ** supported");
  74. var ramDisk = new UnmanagedGigabyteBlockSeparatedRamDisk((int)Math.Ceiling(bdd.Size / (float)Consts.Gigabyte));
  75. ramDisk.Allocate();
  76. var buffer = new byte[bdd.BlockSize];
  77. for (var i = 0; i < bdd.NumberOfBlocks; i++)
  78. {
  79. if (false == bdd.IsBlockAllocated[i]) continue;
  80. bdd.ReadBlock(buffer, 0, buffer.Length, i, 0);
  81. ramDisk.WriteData((long)i * bdd.BlockSize, buffer);
  82. }
  83. return ramDisk;
  84. }
  85. finally
  86. {
  87. bdd.ReleaseLock();
  88. }
  89. case AutoLoadDiskType.AttachFile:
  90. var diskImage = DiskImage.GetDiskImage(FilePath, ReadOnly);
  91. diskImage.ExclusiveLock();
  92. return diskImage;
  93. default:
  94. throw new ArgumentOutOfRangeException($"Unknown type: {Type}");
  95. }
  96. }
  97. }
  98. internal enum AutoLoadDiskType
  99. {
  100. RamDiskFromFile,
  101. AttachFile
  102. }
  103. }