mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +01:00
ircd::fs::dev: Eliminate the static map; refactor interface; add console cmd.
This commit is contained in:
parent
27d52c660b
commit
bc3ad3f89c
5 changed files with 126 additions and 128 deletions
|
@ -13,9 +13,9 @@
|
|||
|
||||
namespace ircd::fs::dev
|
||||
{
|
||||
struct init;
|
||||
struct blkdev;
|
||||
struct blk;
|
||||
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)
|
||||
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/...
|
||||
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};
|
||||
bool is_queue {false};
|
||||
static string_view devtype(const mutable_buffer &, const ulong &id);
|
||||
|
||||
std::string type;
|
||||
std::string vendor;
|
||||
std::string model;
|
||||
|
@ -45,14 +53,8 @@ struct ircd::fs::dev::blkdev
|
|||
size_t nr_requests {0};
|
||||
bool rotational {false};
|
||||
|
||||
blkdev(const ulong &id);
|
||||
blkdev() = default;
|
||||
};
|
||||
|
||||
struct ircd::fs::dev::init
|
||||
{
|
||||
init();
|
||||
~init() noexcept;
|
||||
blk(const ulong &id);
|
||||
blk() = default;
|
||||
};
|
||||
|
||||
/// Return a lex_cast'able (an integer) from a sysfs target.
|
||||
|
|
|
@ -78,7 +78,6 @@ namespace ircd::fs
|
|||
/// Filesystem interface init / fini held by ircd::main().
|
||||
struct ircd::fs::init
|
||||
{
|
||||
dev::init _dev_;
|
||||
iou::init _iou_;
|
||||
aio::init _aio_;
|
||||
|
||||
|
|
|
@ -100,13 +100,17 @@ ircd::fs::aio::init::init()
|
|||
// 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.
|
||||
if(max_events == 0UL)
|
||||
for(const auto &[mm, bd] : fs::dev::block)
|
||||
if(bd.is_device && bd.type == "disk")
|
||||
fs::dev::for_each("disk", []
|
||||
(const ulong &id, const fs::dev::blk &device)
|
||||
{
|
||||
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 == 0UL)
|
||||
{
|
||||
|
|
169
ircd/fs_dev.cc
169
ircd/fs_dev.cc
|
@ -10,16 +10,16 @@
|
|||
|
||||
#include <RB_INC_SYS_SYSMACROS_H
|
||||
|
||||
decltype(ircd::fs::dev::block)
|
||||
ircd::fs::dev::block;
|
||||
|
||||
//
|
||||
// init
|
||||
//
|
||||
|
||||
ircd::fs::dev::init::init()
|
||||
bool
|
||||
ircd::fs::dev::for_each(const blk_closure &closure)
|
||||
{
|
||||
return for_each(string_view{}, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
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
|
||||
{
|
||||
const auto &[major, minor]
|
||||
|
@ -27,62 +27,35 @@ ircd::fs::dev::init::init()
|
|||
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
|
||||
{
|
||||
block.emplace(device_major_minor, id(device_major_minor))
|
||||
};
|
||||
char dtbuf[32];
|
||||
if(type && blk::devtype(dtbuf, id) != type)
|
||||
continue;
|
||||
|
||||
assert(iit.second);
|
||||
const auto &bd(iit.first->second);
|
||||
if(!bd.is_device || bd.type != "disk")
|
||||
block.erase(iit.first);
|
||||
if(!closure(id, blk(id)))
|
||||
return false;
|
||||
}
|
||||
catch(const ctx::interrupted &)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::derror
|
||||
log::error
|
||||
{
|
||||
log, "%s :%s",
|
||||
dir,
|
||||
e.what(),
|
||||
};
|
||||
}
|
||||
#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,
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ircd::fs::dev::init::~init()
|
||||
noexcept
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// fs::dev
|
||||
//
|
||||
|
||||
#ifdef __linux__
|
||||
ircd::string_view
|
||||
ircd::fs::dev::sysfs(const mutable_buffer &out,
|
||||
const ulong &id,
|
||||
|
@ -96,11 +69,18 @@ try
|
|||
relpath
|
||||
}};
|
||||
|
||||
fs::read_opts opts;
|
||||
opts.aio = false;
|
||||
fs::fd::opts fdopts;
|
||||
fdopts.errlog = false;
|
||||
const fs::fd fd
|
||||
{
|
||||
path, fdopts
|
||||
};
|
||||
|
||||
fs::read_opts ropts;
|
||||
ropts.aio = false;
|
||||
string_view ret
|
||||
{
|
||||
fs::read(path, out, opts)
|
||||
fs::read(fd, out, ropts)
|
||||
};
|
||||
|
||||
ret = rstrip(ret, '\n');
|
||||
|
@ -113,6 +93,7 @@ catch(const ctx::interrupted &)
|
|||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
#if 0
|
||||
log::derror
|
||||
{
|
||||
log, "sysfs query dev_id:%lu `%s' :%s",
|
||||
|
@ -120,21 +101,10 @@ catch(const std::exception &e)
|
|||
relpath,
|
||||
e.what(),
|
||||
};
|
||||
#endif
|
||||
|
||||
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::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)
|
||||
:is_device
|
||||
ircd::fs::dev::blk::blk(const ulong &id)
|
||||
:type
|
||||
{
|
||||
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]
|
||||
ircd::string(15, [&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;
|
||||
return devtype(buf, id);
|
||||
})
|
||||
}
|
||||
,vendor
|
||||
{
|
||||
!is_device? std::string{}:
|
||||
ircd::string(12, [&id]
|
||||
ircd::string(15, [&id]
|
||||
(const mutable_buffer &buf)
|
||||
{
|
||||
return sysfs(buf, id, "device/vendor");
|
||||
|
@ -223,7 +161,6 @@ ircd::fs::dev::blkdev::blkdev(const ulong &id)
|
|||
}
|
||||
,model
|
||||
{
|
||||
!is_device? std::string{}:
|
||||
ircd::string(64, [&id]
|
||||
(const mutable_buffer &buf)
|
||||
{
|
||||
|
@ -232,8 +169,7 @@ ircd::fs::dev::blkdev::blkdev(const ulong &id)
|
|||
}
|
||||
,rev
|
||||
{
|
||||
!is_device? std::string{}:
|
||||
ircd::string(12, [&id]
|
||||
ircd::string(15, [&id]
|
||||
(const mutable_buffer &buf)
|
||||
{
|
||||
return sysfs(buf, id, "device/rev");
|
||||
|
@ -253,7 +189,28 @@ ircd::fs::dev::blkdev::blkdev(const ulong &id)
|
|||
}
|
||||
,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;
|
||||
}
|
||||
|
|
|
@ -913,6 +913,42 @@ console_cmd__fs__ls(opt &out, const string_view &line)
|
|||
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
|
||||
console_cmd__ls(opt &out, const string_view &line)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue