0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-27 07:54:05 +01:00

ircd::fs::dev: Eliminate the static map; refactor interface; add console cmd.

This commit is contained in:
Jason Volk 2020-06-08 12:22:35 -07:00
parent 27d52c660b
commit bc3ad3f89c
5 changed files with 126 additions and 128 deletions

View file

@ -13,9 +13,9 @@
namespace ircd::fs::dev namespace ircd::fs::dev
{ {
struct init; struct blk;
struct blkdev;
using major_minor = std::pair<ulong, ulong>; using major_minor = std::pair<ulong, ulong>;
using blk_closure = std::function<bool (const ulong &id, const blk &)>;
// Convert device ID's with the major(3) / minor(3) / makedev(3) // Convert device ID's with the major(3) / minor(3) / makedev(3)
ulong id(const major_minor &); ulong id(const major_minor &);
@ -27,15 +27,23 @@ namespace ircd::fs::dev
// Read data for a device from sysfs; path is relative to /sys/dev/block/$id/... // 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); 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, const T &def = 0);
extern std::map<major_minor, blkdev> block; // Read data for a device lexical_cast'ed to type
template<class R = size_t,
size_t bufmax = 32>
R
sysfs(const ulong &id,
const string_view &path,
const R &def = 0);
bool for_each(const string_view &devtype, const blk_closure &);
bool for_each(const blk_closure &);
} }
struct ircd::fs::dev::blkdev struct ircd::fs::dev::blk
{ {
bool is_device {false}; static string_view devtype(const mutable_buffer &, const ulong &id);
bool is_queue {false};
std::string type; std::string type;
std::string vendor; std::string vendor;
std::string model; std::string model;
@ -45,14 +53,8 @@ struct ircd::fs::dev::blkdev
size_t nr_requests {0}; size_t nr_requests {0};
bool rotational {false}; bool rotational {false};
blkdev(const ulong &id); blk(const ulong &id);
blkdev() = default; blk() = default;
};
struct ircd::fs::dev::init
{
init();
~init() noexcept;
}; };
/// Return a lex_cast'able (an integer) from a sysfs target. /// Return a lex_cast'able (an integer) from a sysfs target.

View file

@ -78,7 +78,6 @@ namespace ircd::fs
/// Filesystem interface init / fini held by ircd::main(). /// Filesystem interface init / fini held by ircd::main().
struct ircd::fs::init struct ircd::fs::init
{ {
dev::init _dev_;
iou::init _iou_; iou::init _iou_;
aio::init _aio_; aio::init _aio_;

View file

@ -100,13 +100,17 @@ ircd::fs::aio::init::init()
// tune to it. The caveat here is that if the application makes heavy use // tune to it. The caveat here is that if the application makes heavy use
// of an inferior device on the same system, it wont be optimally utilized. // of an inferior device on the same system, it wont be optimally utilized.
if(max_events == 0UL) if(max_events == 0UL)
for(const auto &[mm, bd] : fs::dev::block) fs::dev::for_each("disk", []
if(bd.is_device && bd.type == "disk") (const ulong &id, const fs::dev::blk &device)
{
max_events._value = std::clamp max_events._value = std::clamp
( (
bd.queue_depth, size_t(max_events), MAX_EVENTS device.queue_depth, size_t(max_events), MAX_EVENTS
); );
return true;
});
// If max_events is still not determined here set a sane default. // If max_events is still not determined here set a sane default.
if(max_events == 0UL) if(max_events == 0UL)
{ {

View file

@ -10,16 +10,16 @@
#include <RB_INC_SYS_SYSMACROS_H #include <RB_INC_SYS_SYSMACROS_H
decltype(ircd::fs::dev::block) bool
ircd::fs::dev::block; ircd::fs::dev::for_each(const blk_closure &closure)
{
// return for_each(string_view{}, closure);
// init }
//
bool
ircd::fs::dev::init::init() ircd::fs::dev::for_each(const string_view &type,
const blk_closure &closure)
{ {
#ifdef __linux__
for(const auto &dir : fs::ls("/sys/dev/block")) try for(const auto &dir : fs::ls("/sys/dev/block")) try
{ {
const auto &[major, minor] const auto &[major, minor]
@ -27,62 +27,35 @@ ircd::fs::dev::init::init()
split(filename(path_scratch, dir), ':') split(filename(path_scratch, dir), ':')
}; };
const major_minor device_major_minor const ulong id
{ {
lex_cast<ulong>(major), lex_cast<ulong>(minor) dev::id({lex_cast<ulong>(major), lex_cast<ulong>(minor)})
}; };
const auto iit char dtbuf[32];
{ if(type && blk::devtype(dtbuf, id) != type)
block.emplace(device_major_minor, id(device_major_minor)) continue;
};
assert(iit.second); if(!closure(id, blk(id)))
const auto &bd(iit.first->second); return false;
if(!bd.is_device || bd.type != "disk") }
block.erase(iit.first); catch(const ctx::interrupted &)
{
throw;
} }
catch(const std::exception &e) catch(const std::exception &e)
{ {
log::derror log::error
{ {
log, "%s :%s", log, "%s :%s",
dir, dir,
e.what(), e.what(),
}; };
} }
#endif
for(const auto &[mm, bd] : block) return true;
{
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::string_view
ircd::fs::dev::sysfs(const mutable_buffer &out, ircd::fs::dev::sysfs(const mutable_buffer &out,
const ulong &id, const ulong &id,
@ -96,11 +69,18 @@ try
relpath relpath
}}; }};
fs::read_opts opts; fs::fd::opts fdopts;
opts.aio = false; fdopts.errlog = false;
const fs::fd fd
{
path, fdopts
};
fs::read_opts ropts;
ropts.aio = false;
string_view ret string_view ret
{ {
fs::read(path, out, opts) fs::read(fd, out, ropts)
}; };
ret = rstrip(ret, '\n'); ret = rstrip(ret, '\n');
@ -113,6 +93,7 @@ catch(const ctx::interrupted &)
} }
catch(const std::exception &e) catch(const std::exception &e)
{ {
#if 0
log::derror log::derror
{ {
log, "sysfs query dev_id:%lu `%s' :%s", log, "sysfs query dev_id:%lu `%s' :%s",
@ -120,21 +101,10 @@ catch(const std::exception &e)
relpath, relpath,
e.what(), e.what(),
}; };
#endif
return {}; return {};
} }
#else
ircd::string_view
ircd::fs::dev::sysfs(const mutable_buffer &out,
const ulong &id,
const string_view &relpath)
{
throw panic
{
"sysfs(5) is not available."
};
}
#endif
ircd::string_view ircd::string_view
ircd::fs::dev::sysfs_id(const mutable_buffer &out, ircd::fs::dev::sysfs_id(const mutable_buffer &out,
@ -169,53 +139,21 @@ ircd::fs::dev::id(const ulong &id)
} }
// //
// dev::device // dev::blk
// //
ircd::fs::dev::blkdev::blkdev(const ulong &id) ircd::fs::dev::blk::blk(const ulong &id)
:is_device :type
{ {
fs::is_dir(fmt::sprintf ircd::string(15, [&id]
{
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) (const mutable_buffer &buf)
{ {
char tmp[128]; return devtype(buf, id);
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 ,vendor
{ {
!is_device? std::string{}: ircd::string(15, [&id]
ircd::string(12, [&id]
(const mutable_buffer &buf) (const mutable_buffer &buf)
{ {
return sysfs(buf, id, "device/vendor"); return sysfs(buf, id, "device/vendor");
@ -223,7 +161,6 @@ ircd::fs::dev::blkdev::blkdev(const ulong &id)
} }
,model ,model
{ {
!is_device? std::string{}:
ircd::string(64, [&id] ircd::string(64, [&id]
(const mutable_buffer &buf) (const mutable_buffer &buf)
{ {
@ -232,8 +169,7 @@ ircd::fs::dev::blkdev::blkdev(const ulong &id)
} }
,rev ,rev
{ {
!is_device? std::string{}: ircd::string(15, [&id]
ircd::string(12, [&id]
(const mutable_buffer &buf) (const mutable_buffer &buf)
{ {
return sysfs(buf, id, "device/rev"); return sysfs(buf, id, "device/rev");
@ -253,7 +189,28 @@ ircd::fs::dev::blkdev::blkdev(const ulong &id)
} }
,rotational ,rotational
{ {
sysfs<bool>(id, "queue/rotational", true) sysfs<bool>(id, "queue/rotational", false)
} }
{ {
} }
ircd::string_view
ircd::fs::dev::blk::devtype(const mutable_buffer &buf,
const ulong &id)
{
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;
}

View file

@ -913,6 +913,42 @@ console_cmd__fs__ls(opt &out, const string_view &line)
return true; return true;
} }
bool
console_cmd__fs__dev(opt &out, const string_view &line)
{
const params param{line, " ",
{
"type"
}};
const string_view type
{
param["type"]
};
fs::dev::for_each(type, [&out]
(const ulong &id, const fs::dev::blk &dev)
{
const auto mm(fs::dev::id(id));
char pbuf[48];
out
<< std::setw(16) << dev.type << ' '
<< std::setw(3) << std::right << std::get<0>(mm) << ':'
<< std::setw(3) << std::left << std::get<1>(mm) << ' '
<< std::setw(16) << dev.vendor << ' '
<< std::setw(20) << dev.model << ' '
<< std::setw(10) << dev.rev << ' '
<< "qd:" << std::setw(3) << dev.queue_depth << ' '
<< "nr:" << std::setw(3) << dev.nr_requests << ' '
<< pretty(pbuf, iec(dev.size)) << ' '
<< std::endl;
return true;
});
return true;
}
bool bool
console_cmd__ls(opt &out, const string_view &line) console_cmd__ls(opt &out, const string_view &line)
{ {