mirror of
https://github.com/matrix-construct/construct
synced 2025-02-16 16:50:12 +01:00
ircd::fs::dev: Add block device information system w/ sysfs.
This commit is contained in:
parent
680c29601e
commit
22eb9b514b
3 changed files with 187 additions and 0 deletions
|
@ -13,6 +13,8 @@
|
|||
|
||||
namespace ircd::fs::dev
|
||||
{
|
||||
struct init;
|
||||
struct blkdev;
|
||||
using major_minor = std::pair<ulong, ulong>;
|
||||
|
||||
// Convert device ID's with the major(3) / minor(3) / makedev(3)
|
||||
|
@ -26,8 +28,33 @@ namespace ircd::fs::dev
|
|||
// Read data for a device from sysfs; path is relative to /sys/dev/block/$id/...
|
||||
string_view sysfs(const mutable_buffer &out, const ulong &id, const string_view &path);
|
||||
template<class T = size_t, size_t bufmax = 32> T sysfs(const ulong &id, const string_view &path);
|
||||
|
||||
extern std::map<major_minor, blkdev> block;
|
||||
}
|
||||
|
||||
struct ircd::fs::dev::blkdev
|
||||
{
|
||||
bool is_device {false};
|
||||
bool is_queue {false};
|
||||
std::string type;
|
||||
std::string vendor;
|
||||
std::string model;
|
||||
std::string rev;
|
||||
size_t size {0};
|
||||
size_t queue_depth {0};
|
||||
size_t nr_requests {0};
|
||||
bool rotational {false};
|
||||
|
||||
blkdev(const ulong &id);
|
||||
blkdev() = default;
|
||||
};
|
||||
|
||||
struct ircd::fs::dev::init
|
||||
{
|
||||
init();
|
||||
~init() noexcept;
|
||||
};
|
||||
|
||||
/// Return a lex_cast'able (an integer) from a sysfs target.
|
||||
template<class T,
|
||||
size_t bufmax>
|
||||
|
|
|
@ -78,6 +78,7 @@ namespace ircd::fs
|
|||
/// Filesystem interface init / fini held by ircd::main().
|
||||
struct ircd::fs::init
|
||||
{
|
||||
dev::init _dev_;
|
||||
iou::init _iou_;
|
||||
aio::init _aio_;
|
||||
|
||||
|
|
159
ircd/fs_dev.cc
159
ircd/fs_dev.cc
|
@ -10,6 +10,69 @@
|
|||
|
||||
#include <RB_INC_SYS_SYSMACROS_H
|
||||
|
||||
decltype(ircd::fs::dev::block)
|
||||
ircd::fs::dev::block;
|
||||
|
||||
//
|
||||
// init
|
||||
//
|
||||
|
||||
ircd::fs::dev::init::init()
|
||||
{
|
||||
#ifdef __linux__
|
||||
for(const auto &dir : fs::ls("/sys/dev/block"))
|
||||
{
|
||||
const auto &[major, minor]
|
||||
{
|
||||
split(filename(path_scratch, dir), ':')
|
||||
};
|
||||
|
||||
const major_minor device_major_minor
|
||||
{
|
||||
lex_cast<ulong>(major), lex_cast<ulong>(minor)
|
||||
};
|
||||
|
||||
const auto iit
|
||||
{
|
||||
block.emplace(device_major_minor, id(device_major_minor))
|
||||
};
|
||||
|
||||
assert(iit.second);
|
||||
const auto &bd(iit.first->second);
|
||||
if(!bd.is_device || bd.type != "disk")
|
||||
block.erase(iit.first);
|
||||
}
|
||||
#endif
|
||||
|
||||
for(const auto &[mm, bd] : block)
|
||||
{
|
||||
char pbuf[48];
|
||||
log::info
|
||||
{
|
||||
log, "%s %u:%2u %s %s %s %s queue depth:%zu requests:%zu",
|
||||
bd.type,
|
||||
std::get<0>(mm),
|
||||
std::get<1>(mm),
|
||||
bd.vendor,
|
||||
bd.model,
|
||||
bd.rev,
|
||||
pretty(pbuf, iec(bd.size)),
|
||||
bd.queue_depth,
|
||||
bd.nr_requests,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ircd::fs::dev::init::~init()
|
||||
noexcept
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// fs::dev
|
||||
//
|
||||
|
||||
#ifdef __linux__
|
||||
ircd::string_view
|
||||
ircd::fs::dev::sysfs(const mutable_buffer &out,
|
||||
|
@ -78,3 +141,99 @@ ircd::fs::dev::id(const ulong &id)
|
|||
major(id), minor(id)
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// dev::device
|
||||
//
|
||||
|
||||
ircd::fs::dev::blkdev::blkdev(const ulong &id)
|
||||
:is_device
|
||||
{
|
||||
fs::is_dir(fmt::sprintf
|
||||
{
|
||||
path_scratch, "/sys/dev/block/%s/device",
|
||||
sysfs_id(name_scratch, id),
|
||||
})
|
||||
}
|
||||
,is_queue
|
||||
{
|
||||
fs::is_dir(fmt::sprintf
|
||||
{
|
||||
path_scratch, "/sys/dev/block/%s/queue",
|
||||
sysfs_id(name_scratch, id),
|
||||
})
|
||||
}
|
||||
,type
|
||||
{
|
||||
!is_device? std::string{}:
|
||||
ircd::string(8, [&id]
|
||||
(const mutable_buffer &buf)
|
||||
{
|
||||
char tmp[128];
|
||||
string_view ret;
|
||||
tokens(sysfs(tmp, id, "uevent"), '\n', [&buf, &ret]
|
||||
(const string_view &kv)
|
||||
{
|
||||
const auto &[key, value]
|
||||
{
|
||||
split(kv, '=')
|
||||
};
|
||||
|
||||
if(key == "DEVTYPE")
|
||||
ret = strlcpy(buf, value);
|
||||
});
|
||||
|
||||
return ret;
|
||||
})
|
||||
}
|
||||
,vendor
|
||||
{
|
||||
!is_device? std::string{}:
|
||||
ircd::string(12, [&id]
|
||||
(const mutable_buffer &buf)
|
||||
{
|
||||
return sysfs(buf, id, "device/vendor");
|
||||
})
|
||||
}
|
||||
,model
|
||||
{
|
||||
!is_device? std::string{}:
|
||||
ircd::string(64, [&id]
|
||||
(const mutable_buffer &buf)
|
||||
{
|
||||
return sysfs(buf, id, "device/model");
|
||||
})
|
||||
}
|
||||
,rev
|
||||
{
|
||||
!is_device? std::string{}:
|
||||
ircd::string(12, [&id]
|
||||
(const mutable_buffer &buf)
|
||||
{
|
||||
return sysfs(buf, id, "device/rev");
|
||||
})
|
||||
}
|
||||
,size
|
||||
{
|
||||
sysfs(id, "size")
|
||||
}
|
||||
,queue_depth
|
||||
{
|
||||
is_device?
|
||||
sysfs(id, "device/queue_depth"):
|
||||
0UL
|
||||
}
|
||||
,nr_requests
|
||||
{
|
||||
is_queue?
|
||||
sysfs(id, "queue/nr_requests"):
|
||||
0UL
|
||||
}
|
||||
,rotational
|
||||
{
|
||||
is_queue?
|
||||
sysfs<bool>(id, "queue/rotational"):
|
||||
true
|
||||
}
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue