mirror of
https://github.com/matrix-construct/construct
synced 2024-11-25 16:22:35 +01:00
ircd::util: Move syscall() templates out of util; minor reorg includes.
ircd::sys: Add abstract sysfs tool and template from fs::dev.
This commit is contained in:
parent
d9bfdc9678
commit
eb00134100
6 changed files with 236 additions and 42 deletions
|
@ -56,11 +56,8 @@
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "nacl.h"
|
|
||||||
#include "rand.h"
|
#include "rand.h"
|
||||||
#include "crh.h"
|
#include "crh.h"
|
||||||
#include "ed25519.h"
|
|
||||||
#include "color.h"
|
|
||||||
#include "lex_cast.h"
|
#include "lex_cast.h"
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
#include "stringops.h"
|
#include "stringops.h"
|
||||||
|
@ -72,9 +69,12 @@
|
||||||
#include "iov.h"
|
#include "iov.h"
|
||||||
#include "grammar.h"
|
#include "grammar.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
|
#include "color.h"
|
||||||
#include "rfc1459.h"
|
#include "rfc1459.h"
|
||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
#include "cbor/cbor.h"
|
#include "cbor/cbor.h"
|
||||||
|
#include "nacl.h"
|
||||||
|
#include "ed25519.h"
|
||||||
#include "openssl.h"
|
#include "openssl.h"
|
||||||
#include "pbc.h"
|
#include "pbc.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
|
@ -83,6 +83,7 @@
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "magic.h"
|
#include "magic.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
|
#include "sys.h"
|
||||||
#include "prof/prof.h"
|
#include "prof/prof.h"
|
||||||
#include "fs/fs.h"
|
#include "fs/fs.h"
|
||||||
#include "ios.h"
|
#include "ios.h"
|
||||||
|
|
168
include/ircd/sys.h
Normal file
168
include/ircd/sys.h
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
// The Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define HAVE_IRCD_SYS_H
|
||||||
|
|
||||||
|
namespace ircd::sys
|
||||||
|
{
|
||||||
|
enum call :uint;
|
||||||
|
|
||||||
|
template<enum call = (enum call)0,
|
||||||
|
class function,
|
||||||
|
class... args>
|
||||||
|
long call(function&&, args&&...);
|
||||||
|
|
||||||
|
template<long number,
|
||||||
|
enum call = (enum call)0,
|
||||||
|
class... args>
|
||||||
|
long call(args&&... a);
|
||||||
|
|
||||||
|
// sysfs read to buffer
|
||||||
|
string_view get(const mutable_buffer &out, const string_view &path);
|
||||||
|
|
||||||
|
// sysfs read cast to type or defaults
|
||||||
|
template<class R = size_t,
|
||||||
|
size_t bufmax = 32>
|
||||||
|
R get(const string_view &path, const R &def = 0);
|
||||||
|
|
||||||
|
extern log::log log;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// System call template options; changes behaviors.
|
||||||
|
enum ircd::sys::call
|
||||||
|
:uint
|
||||||
|
{
|
||||||
|
NOTHROW = 0x01,
|
||||||
|
UNINTERRUPTIBLE = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Return a lex_cast'able (an integer) from a sysfs target.
|
||||||
|
template<class T,
|
||||||
|
size_t bufmax>
|
||||||
|
inline T
|
||||||
|
ircd::sys::get(const string_view &path,
|
||||||
|
const T &def)
|
||||||
|
{
|
||||||
|
char buf[bufmax];
|
||||||
|
const string_view val
|
||||||
|
{
|
||||||
|
get(buf, path)
|
||||||
|
};
|
||||||
|
|
||||||
|
return lex_castable<T>(val)?
|
||||||
|
lex_cast<T>(val):
|
||||||
|
def;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This template requires a system call number in the parameters. The
|
||||||
|
/// arguments are only the actual arguments passed to the syscall because
|
||||||
|
/// the number is given in the template.
|
||||||
|
///
|
||||||
|
template<long number,
|
||||||
|
enum ircd::sys::call opts,
|
||||||
|
class... args>
|
||||||
|
inline long
|
||||||
|
ircd::sys::call(args&&... a)
|
||||||
|
{
|
||||||
|
return call<opts>(::syscall, number, std::forward<args>(a)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Posix system call template to check for returned error value and throw the
|
||||||
|
/// approps errno in the proper std::system_error exception. Note the usage
|
||||||
|
/// here, the libc wrapper function is the first argument i.e:
|
||||||
|
/// syscall(::foo, bar, baz) not syscall(::foo(bar, baz));
|
||||||
|
///
|
||||||
|
/// when uninterruptible posix system call template; the syscall is
|
||||||
|
/// restarted until it no longer returns with EINTR.
|
||||||
|
///
|
||||||
|
template<enum ircd::sys::call opts,
|
||||||
|
class function,
|
||||||
|
class... args>
|
||||||
|
inline long
|
||||||
|
ircd::sys::call(function&& f,
|
||||||
|
args&&... a)
|
||||||
|
{
|
||||||
|
constexpr auto uninterruptible
|
||||||
|
{
|
||||||
|
opts & call::UNINTERRUPTIBLE
|
||||||
|
};
|
||||||
|
|
||||||
|
long ret; do
|
||||||
|
{
|
||||||
|
ret = f(std::forward<args>(a)...);
|
||||||
|
}
|
||||||
|
while(unlikely(uninterruptible && ret == -1 && errno == EINTR));
|
||||||
|
|
||||||
|
constexpr auto nothrow
|
||||||
|
{
|
||||||
|
opts & call::NOTHROW
|
||||||
|
};
|
||||||
|
|
||||||
|
if(unlikely(!nothrow && ret == -1L))
|
||||||
|
throw std::system_error
|
||||||
|
{
|
||||||
|
errno, std::system_category()
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Legacy convenience forwarder interface
|
||||||
|
//
|
||||||
|
namespace ircd {
|
||||||
|
|
||||||
|
template<class function,
|
||||||
|
class... args>
|
||||||
|
inline auto
|
||||||
|
syscall(function&& f,
|
||||||
|
args&&... a)
|
||||||
|
{
|
||||||
|
return sys::call(std::forward<function>(f), std::forward<args>(a)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<long number,
|
||||||
|
class... args>
|
||||||
|
inline auto
|
||||||
|
syscall(args&&... a)
|
||||||
|
{
|
||||||
|
return sys::call<number>(std::forward<args>(a)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class function,
|
||||||
|
class... args>
|
||||||
|
inline auto
|
||||||
|
syscall_nointr(function&& f,
|
||||||
|
args&&... a)
|
||||||
|
{
|
||||||
|
constexpr enum sys::call opts
|
||||||
|
{
|
||||||
|
sys::call::UNINTERRUPTIBLE
|
||||||
|
};
|
||||||
|
|
||||||
|
return sys::call<opts>(std::forward<function>(f), std::forward<args>(a)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<long number,
|
||||||
|
class... args>
|
||||||
|
inline auto
|
||||||
|
syscall_nointr(args&&... a)
|
||||||
|
{
|
||||||
|
constexpr enum sys::call opts
|
||||||
|
{
|
||||||
|
sys::call::UNINTERRUPTIBLE
|
||||||
|
};
|
||||||
|
|
||||||
|
return sys::call<number, opts>(std::forward<args>(a)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ircd
|
|
@ -39,7 +39,6 @@ namespace ircd
|
||||||
#include "reentrance.h"
|
#include "reentrance.h"
|
||||||
#include "enum.h"
|
#include "enum.h"
|
||||||
#include "custom_ptr.h"
|
#include "custom_ptr.h"
|
||||||
#include "syscall.h"
|
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
#include "va_rtti.h"
|
#include "va_rtti.h"
|
||||||
#include "unique_iterator.h"
|
#include "unique_iterator.h"
|
||||||
|
|
|
@ -169,6 +169,7 @@ endif
|
||||||
if IOU
|
if IOU
|
||||||
libircd_la_SOURCES += fs_iou.cc
|
libircd_la_SOURCES += fs_iou.cc
|
||||||
endif
|
endif
|
||||||
|
libircd_la_SOURCES += sys.cc
|
||||||
libircd_la_SOURCES += mods.cc
|
libircd_la_SOURCES += mods.cc
|
||||||
if LINUX
|
if LINUX
|
||||||
libircd_la_SOURCES += mods_ldso.cc
|
libircd_la_SOURCES += mods_ldso.cc
|
||||||
|
|
|
@ -60,51 +60,16 @@ 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,
|
||||||
const string_view &relpath)
|
const string_view &relpath)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
|
thread_local char path_buf[1024];
|
||||||
const string_view path{fmt::sprintf
|
const string_view path{fmt::sprintf
|
||||||
{
|
{
|
||||||
path_scratch, "%s/%s/%s",
|
path_buf, "dev/block/%s/%s",
|
||||||
blk::BASE_PATH,
|
|
||||||
sysfs_id(name_scratch, id),
|
sysfs_id(name_scratch, id),
|
||||||
relpath
|
relpath
|
||||||
}};
|
}};
|
||||||
|
|
||||||
fs::fd::opts fdopts;
|
return sys::get(out, path);
|
||||||
fdopts.errlog = false;
|
|
||||||
const fs::fd fd
|
|
||||||
{
|
|
||||||
path, fdopts
|
|
||||||
};
|
|
||||||
|
|
||||||
fs::read_opts ropts;
|
|
||||||
ropts.aio = false;
|
|
||||||
string_view ret
|
|
||||||
{
|
|
||||||
fs::read(fd, out, ropts)
|
|
||||||
};
|
|
||||||
|
|
||||||
ret = rstrip(ret, '\n');
|
|
||||||
ret = rstrip(ret, ' ');
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
catch(const ctx::interrupted &)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch(const std::exception &e)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
log::derror
|
|
||||||
{
|
|
||||||
log, "sysfs query dev_id:%lu `%s' :%s",
|
|
||||||
id,
|
|
||||||
relpath,
|
|
||||||
e.what(),
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ircd::string_view
|
ircd::string_view
|
||||||
|
|
60
ircd/sys.cc
Normal file
60
ircd/sys.cc
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
// The Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
decltype(ircd::sys::log)
|
||||||
|
ircd::sys::log
|
||||||
|
{
|
||||||
|
"sys"
|
||||||
|
};
|
||||||
|
|
||||||
|
ircd::string_view
|
||||||
|
ircd::sys::get(const mutable_buffer &out,
|
||||||
|
const string_view &relpath)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
thread_local char buf[1024];
|
||||||
|
string_view path(relpath);
|
||||||
|
path = lstrip(relpath, "/sys/"_sv); // tolerate any errant /sys/ prefix
|
||||||
|
path = strlcpy(buf, "/sys/"_sv);
|
||||||
|
path = strlcat(buf, relpath);
|
||||||
|
|
||||||
|
fs::fd::opts fdopts;
|
||||||
|
fdopts.errlog = false;
|
||||||
|
const fs::fd fd
|
||||||
|
{
|
||||||
|
path, fdopts
|
||||||
|
};
|
||||||
|
|
||||||
|
string_view ret
|
||||||
|
{
|
||||||
|
data(out), sys::call(::read, fd, data(out), size(out))
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = rstrip(ret, '\n');
|
||||||
|
ret = rstrip(ret, ' ');
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
catch(const ctx::interrupted &)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
log::derror
|
||||||
|
{
|
||||||
|
log, "sysfs query `%s' :%s",
|
||||||
|
relpath,
|
||||||
|
e.what(),
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
Loading…
Reference in a new issue