#define ODE_EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */
#define ODE_EXT2_MIN_BLOCK_SIZE (1 << ODE_EXT2_MIN_BLOCK_LOG_SIZE)
-static unsigned int divCeilSafely(unsigned int a, unsigned int b)
+#define ODE_EXT2_MAGIC 0xEF53
+
+namespace {
+
+unsigned int divCeilSafely(unsigned int a, unsigned int b)
{
if (!a)
return 0;
return ((a - 1) / b) + 1;
}
+void execAndWait(const std::string &path, std::vector<std::string> &args)
+{
+ runtime::Process proc(path, args);
+
+ int ret = proc.execute();
+ if (ret < 0)
+ throw runtime::Exception(path + " failed for " + args.back());
+
+ ret = proc.waitForFinished();
+ if (ret < 0 || !WIFEXITED(ret) || WEXITSTATUS(ret) != 0)
+ throw runtime::Exception(path + " failed for " + args.back());
+}
+
+} // namespace
+
Ext4Tool::Ext4Tool(const std::string &src) :
source(src), blockSize(0), totalBlockCount(0)
{
+ if (!isExt(src))
+ throw runtime::Exception(source + " is not an ext2/3/4 filesystem");
+
+ readInfo();
+}
+
+Ext4Tool::~Ext4Tool()
+{
+}
+
+bool Ext4Tool::isExt(const std::string &src)
+{
+ unsigned short magic;
+ runtime::File device(src);
+ bool ret;
+
+ if (!device.exists())
+ throw runtime::Exception(src + " doesn't exist");
+
+ device.open(O_RDONLY);
+
+ device.lseek(ODE_SUPERBLOCK_OFFSET + 56, SEEK_SET);
+ device.read(&magic, 2);
+
+ if (magic == ODE_EXT2_MAGIC)
+ ret = true;
+ else
+ ret = false;
+
+ device.close();
+
+ return ret;
+}
+
+void Ext4Tool::readInfo()
+{
unsigned int firstDataBlock = 0;
unsigned int blocksPerGroup = 0;
unsigned int clustersPerGroup = 0;
runtime::File device(source);
- if (device.exists() == false)
- throw runtime::Exception("Source doesn't exist");
+ if (!device.exists())
+ throw runtime::Exception(source + " doesn't exist");
device.open(O_RDONLY);
device.close();
}
-Ext4Tool::~Ext4Tool()
-{
-}
-
unsigned int Ext4Tool::getBlockSize()
{
return blockSize;
return false;
}
+void Ext4Tool::mkfs(const std::string &src)
+{
+ static const char *mkfsPath = "/sbin/mkfs.ext4";
+ std::vector<std::string> args = {
+ mkfsPath,
+ "-F",
+ "-q",
+ src
+ };
+
+ execAndWait(mkfsPath, args);
+}
+
void Ext4Tool::forceCleanUp()
{
+ static const char *fsckPath = "/sbin/fsck.ext4";
std::vector<std::string> args = {
+ fsckPath,
"-f",
"-y",
source
};
- runtime::Process proc("/sbin/e2fsck", args);
- proc.execute();
- proc.waitForFinished();
+ execAndWait(fsckPath, args);
}
} // namespace ode