Skip to content

Commit

Permalink
read /etc/cachefilesd.conf
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxKellermann committed Dec 3, 2024
1 parent c47304d commit 2c6ae70
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 24 deletions.
8 changes: 8 additions & 0 deletions cachefilesd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
dir /var/cache/fscache
tag mycache
brun 10%
bcull 7%
bstop 3%
frun 10%
fcull 7%
fstop 3%
1 change: 1 addition & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
cm4all-cash (0.2) unstable; urgency=low

* read /etc/cachefilesd.conf
* open /dev/cachefiles before opening the cache directory
* systemd: add "RequiresMountsFor" and "CacheDirectory"
* systemd: change "WantedBy" to "remote-fs.target"
Expand Down
3 changes: 3 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ configure_file(output: 'config.h', configuration: conf)
executable('cm4all-cash',
'src/system/SetupProcess.cxx',
'src/Main.cxx',
'src/Config.cxx',
'src/Cull.cxx',
'src/DevCachefiles.cxx',
include_directories: inc,
Expand All @@ -142,3 +143,5 @@ executable('cm4all-cash',
install: true,
install_dir: 'sbin',
)

install_data('cachefilesd.conf', install_dir: get_option('sysconfdir'))
92 changes: 92 additions & 0 deletions src/Config.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: BSD-2-Clause
// Copyright CM4all GmbH
// author: Max Kellermann <[email protected]>

#include "Config.hxx"
#include "io/BufferedReader.hxx"
#include "io/FdReader.hxx"
#include "io/Open.hxx"
#include "io/UniqueFileDescriptor.hxx"
#include "util/CharUtil.hxx"
#include "util/StringStrip.hxx"

#include <charconv>
#include <stdexcept>

using std::string_view_literals::operator""sv;

static constexpr bool
IsCommandChar(char ch) noexcept
{
return IsLowerAlphaASCII(ch);
}

static std::pair<std::string_view, std::string_view>
ExtractCommandValue(const char *line)
{
const char *p = line;

while (IsCommandChar(*p))
++p;

const std::string_view command{line, p};
if (command.empty())
throw std::runtime_error{"No command"};

if (IsWhitespaceNotNull(*p))
p = StripLeft(p + 1);
else if (*p != 0)
throw std::runtime_error{"Malformed command"};

return {command, StripRight(std::string_view{p})};
}

static uint_least8_t
ParsePercent(std::string_view s)
{
if (!s.ends_with('%'))
throw std::runtime_error{"Value must end with '%'"};

const char *const first = s.data(), *const last = first + s.size() - 1;

uint_least8_t value;
auto [ptr, ec] = std::from_chars(first, last, value, 10);
if (ptr == first || ptr != last || ec != std::errc{})
throw std::runtime_error{"Malformed number"};

return value;
}

Config
LoadConfigFile(const char *path)
{
Config config;
auto kernel_config_iterator = config.kernel_config.before_begin();

const auto fd = OpenReadOnly(path);
FdReader fd_reader{fd};
BufferedReader r{fd_reader};

while (const char *line = r.ReadLine()) {
line = StripLeft(line);
if (*line == 0 || *line == '#')
continue;

const auto [command, value] = ExtractCommandValue(line);
if (command == "dir"sv)
config.dir = value;
else if (command == "brun"sv)
config.brun = ParsePercent(value);
else if (command == "frun"sv)
config.frun = ParsePercent(value);

kernel_config_iterator =
config.kernel_config.emplace_after(kernel_config_iterator,
command.begin(), value.end());
}

if (config.dir.empty())
throw std::runtime_error{"No 'dir' setting"};

return config;
}
20 changes: 20 additions & 0 deletions src/Config.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: BSD-2-Clause
// Copyright CM4all GmbH
// author: Max Kellermann <[email protected]>

#pragma once

#include <cstdint>
#include <forward_list>
#include <string>

struct Config {
std::string dir;

std::forward_list<std::string> kernel_config;

uint_least8_t brun = 10, frun = 10;
};

Config
LoadConfigFile(const char *path);
8 changes: 7 additions & 1 deletion src/Instance.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
#include "event/systemd/Watchdog.hxx"
#endif

#include <cstdint>

struct Config;

class Instance {
EventLoop event_loop;
ShutdownListener shutdown_listener{event_loop, BIND_THIS_METHOD(OnShutdown)};
Expand All @@ -32,8 +36,10 @@ class Instance {

std::optional<Cull> cull;

const uint_least8_t brun, frun;

public:
Instance();
explicit Instance(const Config &config);
~Instance() noexcept;

void Run();
Expand Down
35 changes: 12 additions & 23 deletions src/Main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// author: Max Kellermann <[email protected]>

#include "Instance.hxx"
#include "Config.hxx"
#include "system/Error.hxx"
#include "system/SetupProcess.hxx"
#include "io/Open.hxx"
Expand Down Expand Up @@ -34,43 +35,29 @@

using std::string_view_literals::operator""sv;

// TODO hard-coded configuration
static constexpr unsigned brun = 10, frun = 10;

static UniqueFileDescriptor
OpenDevCachefiles()
OpenDevCachefiles(const Config &config)
{
UniqueFileDescriptor fd;
if (!fd.Open("/dev/cachefiles", O_RDWR))
throw MakeErrno("Failed to open /dev/cachefiles");

// TODO hard-coded configuration
static constexpr const char *configure_cachefiles[] = {
"dir /var/cache/fscache",
"tag mycache",
"brun 10%",
"brun 10%",
"bcull 7%",
"bstop 3%",
"frun 10%",
"fcull 7%",
"fstop 3%",
"bind",
};
for (const auto &line : config.kernel_config)
fd.FullWrite(AsBytes(line));

for (const char *s : configure_cachefiles)
fd.FullWrite(AsBytes(std::string_view{s}));
fd.FullWrite(AsBytes("bind"sv));

return fd;
}

inline
Instance::Instance()
Instance::Instance(const Config &config)
:brun(config.brun), frun(config.frun)
{
dev_cachefiles.Open(OpenDevCachefiles().Release());
dev_cachefiles.Open(OpenDevCachefiles(config).Release());
dev_cachefiles.ScheduleRead();

const auto fscache_fd = OpenPath("/var/cache/fscache", O_DIRECTORY);
const auto fscache_fd = OpenPath(config.dir.c_str(), O_DIRECTORY);
cache_fd = OpenPath(fscache_fd, "cache", O_DIRECTORY);
graveyard_fd = OpenPath(fscache_fd, "graveyard", O_DIRECTORY);

Expand Down Expand Up @@ -152,7 +139,9 @@ Instance::Run()
static int
Run()
{
Instance instance;
Instance instance{
LoadConfigFile("/etc/cachefilesd.conf"),
};

#ifdef HAVE_LIBCAP
/* drop all capabilities, we don't need them anymore */
Expand Down

0 comments on commit 2c6ae70

Please sign in to comment.