2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
19 #include <klay/filesystem.h>
20 #include <klay/exception.h>
22 #include "block-device.h"
26 BlockDevice::BlockDevice(const std::string &path) : name("")
29 runtime::File file(path);
31 throw runtime::Exception("target doesn't exist");
34 if (!file.isDevice()) {
42 int descriptor = ::open(name.c_str(), O_RDONLY);
44 ret = ::ioctl(descriptor, FIGETBSZ, &blockSize);
47 throw runtime::Exception("Failed to get block size");
52 throw runtime::Exception("Cannot find device name");
56 BlockDevice::~BlockDevice()
60 int BlockDevice::open(int flags)
65 descriptor = ::open(name.c_str(), flags);
72 void BlockDevice::close(int descriptor)
76 ret = ::close(descriptor);
78 throw runtime::Exception("Cannot close descriptor");
83 int BlockDevice::discard(const Block &block)
86 unsigned long long range[2];
88 devFd = BlockDevice::open(O_WRONLY);
93 range[0] = block.physicalOffset;
94 range[1] = block.length;
96 int ret = ::ioctl(devFd, BLKDISCARD, &range);
98 BlockDevice::close(devFd);
103 int BlockDevice::secDiscard(const Block &block)
106 unsigned long long range[2];
108 devFd = BlockDevice::open(O_WRONLY);
113 range[0] = block.physicalOffset;
114 range[1] = block.length;
116 int ret = ::ioctl(devFd, BLKSECDISCARD, &range);
118 BlockDevice::close(devFd);
123 const std::string &BlockDevice::getName() const
126 throw runtime::Exception("Cannot get device name");
131 int BlockDevice::getSize()
134 throw runtime::Exception("Cannot get device name");
139 void BlockDevice::createDeviceList()
141 char deviceName[PATH_MAX] = "";
142 char source[PATH_MAX] = "";
143 char filesystemType[PATH_MAX] = "";
144 std::string deviceInfo = "";
146 std::ifstream file("/etc/mtab");
148 throw runtime::Exception("/etc/mtab doesn't exist");
151 while (std::getline(file, deviceInfo)) {
152 if (::sscanf(deviceInfo.c_str(), "%s %s %s %*s %*d %*d",
153 deviceName, source, filesystemType) == 3) {
154 int fd = ::open(deviceName, O_WRONLY);
159 if (strcmp(filesystemType, "ext2") && strcmp(filesystemType, "ext3")
160 && strcmp(filesystemType, "ext4")) {
165 runtime::File device(deviceName);
166 if (!device.exists()) {
171 if (device.isDevice()) {
172 deviceList.insert(std::make_pair(source, deviceName));
181 void BlockDevice::evaluateDevice(const std::string &path)
183 DeviceListIterator matchedDevice = deviceList.find(path);
184 const std::string &subStr = path;
185 std::size_t pos = subStr.size();
187 if (matchedDevice != deviceList.end()) {
188 name = matchedDevice->second;
192 while ((pos = subStr.rfind('/', pos - 1)) != std::string::npos && pos != 0) {
193 std::string subPath = subStr.substr(0, pos);
194 matchedDevice = deviceList.find(subPath);
195 if (matchedDevice != deviceList.end()) {
196 name = matchedDevice->second;