Drop the -fundamental suffix from src/fundamental/ headers in favor of names
that match their src/basic/ or src/shared/ counterparts (e.g.
macro-fundamental.h -> macro.h, assert-fundamental.h -> assert-util.h,
cleanup-fundamental.h -> cleanup-util.h). Rename src/basic/{btrfs,label}.{c,h}
to use the -util suffix to match the existing shared/btrfs-util and
shared/label-util siblings. Rename src/shared/mkdir-label.{c,h} to mkdir.{c,h}
and src/shared/tmpfile-util-label.{c,h} to tmpfile-util.{c,h} to match the
corresponding src/basic names.
This saves us from having to come up with separate names for files that do
the same thing across tiers, and it makes it easier to move stuff between
src/fundamental, src/basic and src/shared: consumers just #include "foo.h"
and pick up whichever tier their -I path resolves to first, so call sites
don't need to be updated when an API moves between layers.
Where a higher-tier wrapper exists (e.g. src/basic/macro.h wrapping
src/fundamental/macro.h), the wrapper uses an explicit "../fundamental/foo.h"
or "../basic/foo.h" relative include for the lower-tier header. We can't use
GCC's #include_next directive for this — when the wrapper is reachable both
via same-dir-as-source lookup and via -I (e.g. -Isrc/shared) for the
directory it lives in, #include_next advances by exactly one slot in libcpp's
internal directory chain and lands on the same physical directory it was
already in, never reaching the lower-tier sibling (see make_cpp_dir() in
gcc/libcpp/files.cc:1986).
To make sure the right headers are always picked up, the include directories
are reordered so that e.g. src/shared always takes priority over src/basic and
similar for the other directories.
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
72 lines
2.5 KiB
C
72 lines
2.5 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
#pragma once
|
|
|
|
#include "sd-json.h"
|
|
|
|
#include "string-util.h"
|
|
|
|
/* This closely follows the kernel's inode type naming, i.e. is supposed to be a subset of what
|
|
* inode_type_from_string() parses. */
|
|
typedef enum VolumeType {
|
|
VOLUME_BLK,
|
|
VOLUME_REG,
|
|
VOLUME_DIR,
|
|
_VOLUME_TYPE_MAX,
|
|
_VOLUME_TYPE_INVALID = -EINVAL,
|
|
} VolumeType;
|
|
|
|
typedef enum CreateMode {
|
|
CREATE_ANY,
|
|
CREATE_NEW,
|
|
CREATE_OPEN,
|
|
_CREATE_MODE_MAX,
|
|
_CREATE_MODE_INVALID = -EINVAL,
|
|
} CreateMode;
|
|
|
|
DECLARE_STRING_TABLE_LOOKUP(volume_type, VolumeType);
|
|
DECLARE_STRING_TABLE_LOOKUP(create_mode, CreateMode);
|
|
|
|
int json_dispatch_volume_type(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
|
int json_dispatch_create_mode(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
|
|
|
static inline bool storage_volume_name_is_valid(const char *n) {
|
|
return string_is_safe(n, /* flags= */ 0);
|
|
}
|
|
|
|
static inline bool storage_template_name_is_valid(const char *n) {
|
|
return string_is_safe(n, /* flags= */ 0);
|
|
}
|
|
|
|
static inline bool storage_provider_name_is_valid(const char *n) {
|
|
return string_is_safe(n, STRING_FILENAME);
|
|
}
|
|
|
|
typedef struct StorageAcquireReply {
|
|
int fd;
|
|
VolumeType type;
|
|
int read_only;
|
|
uid_t base_uid;
|
|
gid_t base_gid;
|
|
} StorageAcquireReply;
|
|
|
|
#define STORAGE_ACQUIRE_REPLY_INIT \
|
|
(StorageAcquireReply) { \
|
|
.fd = -EBADF, \
|
|
.type = _VOLUME_TYPE_INVALID, \
|
|
.read_only = -1, \
|
|
.base_uid = UID_INVALID, \
|
|
.base_gid = GID_INVALID, \
|
|
}
|
|
|
|
void storage_acquire_reply_done(StorageAcquireReply *reply);
|
|
|
|
/* On varlink failure, reterr_error_id (if non-NULL) is set to the io.systemd.StorageProvider.*
|
|
* error name. The reply is untouched on any error. */
|
|
typedef struct BindVolume BindVolume;
|
|
int storage_acquire_volume(
|
|
RuntimeScope scope,
|
|
const BindVolume *bv,
|
|
bool allow_interactive_auth,
|
|
char **reterr_error_id,
|
|
StorageAcquireReply *ret);
|