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:
parent
27d52c660b
commit
bc3ad3f89c
5 changed files with 126 additions and 128 deletions
|
@ -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.
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
169
ircd/fs_dev.cc
169
ircd/fs_dev.cc
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue