mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 17:06:39 +09:00
As is usually the case, the bitfields don't create the expected space savings,
because the field that follows needs to be aligned. But we don't want to fully
drop the bitfields here, because then ConditionType and ConditionResult are
each 4 bytes, and the whole struct grows from 32 to 40 bytes (on amd64). We
potentially have lots of little Conditions and that'd waste some memory.
Make each of the four fields one byte. This still allows the compiler to
generate simpler code without changing the struct size:
E.g. in condition_test:
c->result = CONDITION_ERROR;
- 78fab: 48 8b 45 e8 mov -0x18(%rbp),%rax
- 78faf: 0f b6 50 01 movzbl 0x1(%rax),%edx
- 78fb3: 83 e2 03 and $0x3,%edx
- 78fb6: 83 ca 0c or $0xc,%edx
- 78fb9: 88 50 01 mov %dl,0x1(%rax)
+ 78f8b: 48 8b 45 e8 mov -0x18(%rbp),%rax
+ 78f8f: c6 40 03 03 movb $0x3,0x3(%rax)
115 lines
3.9 KiB
C
115 lines
3.9 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
#pragma once
|
|
|
|
#include "list.h"
|
|
#include "forward.h"
|
|
|
|
typedef enum ConditionType {
|
|
CONDITION_ARCHITECTURE,
|
|
CONDITION_FIRMWARE,
|
|
CONDITION_VIRTUALIZATION,
|
|
CONDITION_HOST,
|
|
CONDITION_KERNEL_COMMAND_LINE,
|
|
CONDITION_VERSION,
|
|
CONDITION_CREDENTIAL,
|
|
CONDITION_SECURITY,
|
|
CONDITION_CAPABILITY,
|
|
CONDITION_AC_POWER,
|
|
CONDITION_MEMORY,
|
|
CONDITION_CPUS,
|
|
CONDITION_ENVIRONMENT,
|
|
CONDITION_CPU_FEATURE,
|
|
CONDITION_OS_RELEASE,
|
|
CONDITION_MEMORY_PRESSURE,
|
|
CONDITION_CPU_PRESSURE,
|
|
CONDITION_IO_PRESSURE,
|
|
|
|
CONDITION_NEEDS_UPDATE,
|
|
CONDITION_FIRST_BOOT,
|
|
|
|
CONDITION_PATH_EXISTS,
|
|
CONDITION_PATH_EXISTS_GLOB,
|
|
CONDITION_PATH_IS_DIRECTORY,
|
|
CONDITION_PATH_IS_SYMBOLIC_LINK,
|
|
CONDITION_PATH_IS_MOUNT_POINT,
|
|
CONDITION_PATH_IS_READ_WRITE,
|
|
CONDITION_PATH_IS_ENCRYPTED,
|
|
CONDITION_DIRECTORY_NOT_EMPTY,
|
|
CONDITION_FILE_NOT_EMPTY,
|
|
CONDITION_FILE_IS_EXECUTABLE,
|
|
|
|
CONDITION_USER,
|
|
CONDITION_GROUP,
|
|
|
|
CONDITION_CONTROL_GROUP_CONTROLLER,
|
|
CONDITION_KERNEL_MODULE_LOADED,
|
|
|
|
_CONDITION_TYPE_MAX,
|
|
_CONDITION_TYPE_INVALID = -EINVAL,
|
|
} ConditionType;
|
|
|
|
typedef enum ConditionResult {
|
|
CONDITION_UNTESTED,
|
|
CONDITION_SUCCEEDED,
|
|
CONDITION_FAILED,
|
|
CONDITION_ERROR,
|
|
_CONDITION_RESULT_MAX,
|
|
_CONDITION_RESULT_INVALID = -EINVAL,
|
|
} ConditionResult;
|
|
|
|
typedef struct Condition {
|
|
/* Use bitfields for ConditionType and ConditionResult to keep the whole struct in 32 bytes. */
|
|
ConditionType type:8;
|
|
|
|
bool trigger;
|
|
bool negate;
|
|
|
|
ConditionResult result:8;
|
|
|
|
char *parameter;
|
|
|
|
LIST_FIELDS(struct Condition, conditions);
|
|
} Condition;
|
|
|
|
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate);
|
|
Condition* condition_free(Condition *c);
|
|
Condition* condition_free_list_type(Condition *first, ConditionType type);
|
|
static inline Condition* condition_free_list(Condition *first) {
|
|
return condition_free_list_type(first, _CONDITION_TYPE_INVALID);
|
|
}
|
|
|
|
int condition_test(Condition *c, char **env);
|
|
|
|
typedef int (*condition_test_logger_t)(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) _printf_(7, 8);
|
|
typedef const char* (*condition_to_string_t)(ConditionType t) _const_;
|
|
bool condition_test_list(Condition *first, char **env, condition_to_string_t to_string, condition_test_logger_t logger, void *userdata);
|
|
|
|
void condition_dump(Condition *c, FILE *f, const char *prefix, condition_to_string_t to_string);
|
|
void condition_dump_list(Condition *c, FILE *f, const char *prefix, condition_to_string_t to_string);
|
|
|
|
const char* condition_type_to_string(ConditionType t) _const_;
|
|
ConditionType condition_type_from_string(const char *s) _pure_;
|
|
void condition_types_list(void);
|
|
|
|
const char* assert_type_to_string(ConditionType t) _const_;
|
|
ConditionType assert_type_from_string(const char *s) _pure_;
|
|
void assert_types_list(void);
|
|
|
|
const char* condition_result_to_string(ConditionResult r) _const_;
|
|
ConditionResult condition_result_from_string(const char *s) _pure_;
|
|
|
|
static inline bool condition_takes_path(ConditionType t) {
|
|
return IN_SET(t,
|
|
CONDITION_PATH_EXISTS,
|
|
CONDITION_PATH_EXISTS_GLOB,
|
|
CONDITION_PATH_IS_DIRECTORY,
|
|
CONDITION_PATH_IS_SYMBOLIC_LINK,
|
|
CONDITION_PATH_IS_MOUNT_POINT,
|
|
CONDITION_PATH_IS_READ_WRITE,
|
|
CONDITION_PATH_IS_ENCRYPTED,
|
|
CONDITION_DIRECTORY_NOT_EMPTY,
|
|
CONDITION_FILE_NOT_EMPTY,
|
|
CONDITION_FILE_IS_EXECUTABLE,
|
|
CONDITION_NEEDS_UPDATE);
|
|
}
|