1 using System;
2 using System.Collections;
3 using System.IO;
4
5 namespace cmsx.kernel
6 {
7 public const uint DRIVE_UNKNOWN = 0u;
8 public const uint DRIVE_NO_ROOT_DIR = 1u;
9 public const uint DRIVE_REMOVABLE = 2u;
10 public const uint DRIVE_FIXED = 3u;
11 public const uint DRIVE_REMOTE = 4u;
12 public const uint DRIVE_CDROM = 5u;
13 public const uint DRIVE_RAMDISK = 6u;
14
15 public class MountTable
16 {
17 static MountTable() : instance(new MountTable())
18 {
19 }
20 public static nothrow MountTable& Instance()
21 {
22 return *instance;
23 }
24 public FileSystem* GetFileSystem(int fsNumber) const
25 {
26 int fileSystemIndex = GetFileSystemIndex(fsNumber);
27 if (fileSystemIndex < 0 || fileSystemIndex >= fileSystems.Count())
28 {
29 throw SystemError(EINVAL, "invalid file system number");
30 }
31 return fileSystems[fileSystemIndex].Get();
32 }
33 public FileSystem* GetMountedFileSystem(const string& dirPath, const INodeKey& mountDirKey) const
34 {
35 for (UniquePtr<FileSystem>& fs : fileSystems)
36 {
37 if (fs->HasMountDirKey(mountDirKey))
38 {
39 if (Log())
40 {
41 LogMessage("fs.mountTable", "getmountedfilesystem.fs=" + fs->Name());
42 }
43 return fs.Get();
44 }
45 }
46 throw SystemError(EFAIL, "file system mounted on directory '" + dirPath + "' not found");
47 }
48 private MountTable()
49 {
50 }
51 public void Init()
52 {
53 if (Log())
54 {
55 LogMessage("fs.mountTable", "init");
56 }
57 string cmajorRootDir = RtGetEnvironmentVariable("CMAJOR_ROOT");
58 if (cmajorRootDir.IsEmpty())
59 {
60 throw Exception("CMAJOR_ROOT environment variable not set. Please set it to contain /path/to/cmajor directory");
61 }
62 string cmsxDir = Path.Combine(Path.Combine(cmajorRootDir, "projects"), "cmsx");
63 fileSystems.Add(UniquePtr<FileSystem>(new RootFileSystem(0)));
64 char[4096] logicalDrivesBuf;
65 bool retval = OsGetLogicalDrives(&logicalDrivesBuf[0], cast<int>(logicalDrivesBuf.Length()));
66 if (!retval)
67 {
68 throw SystemError(EFAIL, "could not get logical drives from system");
69 }
70 int fileSystemIndex = 1;
71 string logicalDrivesStr = &logicalDrivesBuf[0];
72 List<string> logicalDrives = logicalDrivesStr.Split(';');
73 for (const string& drive : logicalDrives)
74 {
75 uint driveType = OsGetDriveType(drive.Chars());
76 if (driveType == DRIVE_FIXED)
77 {
78 string hostPath = GetFullPath(drive);
79 string mountDirPath = "/mnt/" + ToLower(hostPath.Substring(0, 1));
80 HostFileSystem* hostFileSystem = new HostFileSystem(fileSystemIndex++, hostPath, mountDirPath);
81 fileSystems.Add(UniquePtr<FileSystem>(hostFileSystem));
82 }
83 }
84 string cmajorRootHostPath = GetFullPath(cmajorRootDir);
85 string cmajorMountDirPath = "/mnt/cmajor";
86 HostFileSystem* cmajorHostFileSystem = new HostFileSystem(fileSystemIndex++, cmajorRootHostPath, cmajorMountDirPath);
87 fileSystems.Add(UniquePtr<FileSystem>(cmajorHostFileSystem));
88 string cmsxHostPath = GetFullPath(cmsxDir);
89 string cmsxMountDirPath = "/mnt/cmsx";
90 HostFileSystem* cmsxHostFileSystem = new HostFileSystem(fileSystemIndex++, cmsxHostPath, cmsxMountDirPath);
91 fileSystems.Add(UniquePtr<FileSystem>(cmsxHostFileSystem));
92 InitializeFileSystems();
93 }
94 public void Flush()
95 {
96 for (UniquePtr<FileSystem>& fs : fileSystems)
97 {
98 fs->GetBlockManager()->Flush();
99 }
100 }
101 private void InitializeFileSystems()
102 {
103 for (UniquePtr<FileSystem>& fs : fileSystems)
104 {
105 fs->Init();
106 }
107 }
108 private static UniquePtr<MountTable> instance;
109 private List<UniquePtr<FileSystem>> fileSystems;
110 }
111
112 public nothrow MountTable& GetMountTable()
113 {
114 return MountTable.Instance();
115 }
116 }