Merge branch 'main' into inode-ref

This commit is contained in:
Christian Brauner
2026-04-23 19:10:15 +02:00
committed by GitHub
292 changed files with 4562 additions and 3072 deletions
+51 -46
View File
@@ -284,7 +284,7 @@ Compression compression_detect_from_magic(const uint8_t data[static COMPRESSION_
return _COMPRESSION_INVALID;
}
int dlopen_xz(void) {
int dlopen_xz(int log_level) {
#if HAVE_XZ
SD_ELF_NOTE_DLOPEN(
"lzma",
@@ -294,7 +294,7 @@ int dlopen_xz(void) {
return dlopen_many_sym_or_warn(
&lzma_dl,
"liblzma.so.5", LOG_DEBUG,
"liblzma.so.5", log_level,
DLSYM_ARG(lzma_code),
DLSYM_ARG(lzma_easy_encoder),
DLSYM_ARG(lzma_end),
@@ -302,11 +302,12 @@ int dlopen_xz(void) {
DLSYM_ARG(lzma_lzma_preset),
DLSYM_ARG(lzma_stream_decoder));
#else
return -EOPNOTSUPP;
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
"lzma support is not compiled in.");
#endif
}
int dlopen_lz4(void) {
int dlopen_lz4(int log_level) {
#if HAVE_LZ4
SD_ELF_NOTE_DLOPEN(
"lz4",
@@ -316,7 +317,7 @@ int dlopen_lz4(void) {
return dlopen_many_sym_or_warn(
&lz4_dl,
"liblz4.so.1", LOG_DEBUG,
"liblz4.so.1", log_level,
DLSYM_ARG(LZ4F_compressBegin),
DLSYM_ARG(LZ4F_compressBound),
DLSYM_ARG(LZ4F_compressEnd),
@@ -333,11 +334,12 @@ int dlopen_lz4(void) {
DLSYM_ARG(LZ4_decompress_safe_partial),
DLSYM_ARG(LZ4_versionNumber));
#else
return -EOPNOTSUPP;
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
"lz4 support is not compiled in.");
#endif
}
int dlopen_zstd(void) {
int dlopen_zstd(int log_level) {
#if HAVE_ZSTD
SD_ELF_NOTE_DLOPEN(
"zstd",
@@ -347,7 +349,7 @@ int dlopen_zstd(void) {
return dlopen_many_sym_or_warn(
&zstd_dl,
"libzstd.so.1", LOG_DEBUG,
"libzstd.so.1", log_level,
DLSYM_ARG(ZSTD_getErrorCode),
DLSYM_ARG(ZSTD_compress),
DLSYM_ARG(ZSTD_getFrameContentSize),
@@ -365,11 +367,12 @@ int dlopen_zstd(void) {
DLSYM_ARG(ZSTD_createDCtx),
DLSYM_ARG(ZSTD_createCCtx));
#else
return -EOPNOTSUPP;
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
"zstd support is not compiled in.");
#endif
}
int dlopen_zlib(void) {
int dlopen_zlib(int log_level) {
#if HAVE_ZLIB
SD_ELF_NOTE_DLOPEN(
"zlib",
@@ -379,7 +382,7 @@ int dlopen_zlib(void) {
return dlopen_many_sym_or_warn(
&zlib_dl,
"libz.so.1", LOG_DEBUG,
"libz.so.1", log_level,
DLSYM_ARG(deflateInit2_),
DLSYM_ARG(deflate),
DLSYM_ARG(deflateEnd),
@@ -387,11 +390,12 @@ int dlopen_zlib(void) {
DLSYM_ARG(inflate),
DLSYM_ARG(inflateEnd));
#else
return -EOPNOTSUPP;
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
"zlib support is not compiled in.");
#endif
}
int dlopen_bzip2(void) {
int dlopen_bzip2(int log_level) {
#if HAVE_BZIP2
SD_ELF_NOTE_DLOPEN(
"bzip2",
@@ -401,7 +405,7 @@ int dlopen_bzip2(void) {
return dlopen_many_sym_or_warn(
&bzip2_dl,
"libbz2.so.1", LOG_DEBUG,
"libbz2.so.1", log_level,
DLSYM_ARG(BZ2_bzCompressInit),
DLSYM_ARG(BZ2_bzCompress),
DLSYM_ARG(BZ2_bzCompressEnd),
@@ -409,7 +413,8 @@ int dlopen_bzip2(void) {
DLSYM_ARG(BZ2_bzDecompress),
DLSYM_ARG(BZ2_bzDecompressEnd));
#else
return -EOPNOTSUPP;
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
"bzip2 support is not compiled in.");
#endif
}
@@ -440,7 +445,7 @@ static int compress_blob_xz(
size_t out_pos = 0;
int r;
r = dlopen_xz();
r = dlopen_xz(LOG_DEBUG);
if (r < 0)
return r;
@@ -485,7 +490,7 @@ static int compress_blob_lz4(
#if HAVE_LZ4
int r;
r = dlopen_lz4();
r = dlopen_lz4(LOG_DEBUG);
if (r < 0)
return r;
/* Returns < 0 if we couldn't compress the data or the
@@ -533,7 +538,7 @@ static int compress_blob_zstd(
size_t k;
int r;
r = dlopen_zstd();
r = dlopen_zstd(LOG_DEBUG);
if (r < 0)
return r;
@@ -560,7 +565,7 @@ static int compress_blob_gzip(const void *src, uint64_t src_size,
#if HAVE_ZLIB
int r;
r = dlopen_zlib();
r = dlopen_zlib(LOG_DEBUG);
if (r < 0)
return r;
@@ -609,7 +614,7 @@ static int compress_blob_bzip2(
#if HAVE_BZIP2
int r;
r = dlopen_bzip2();
r = dlopen_bzip2(LOG_DEBUG);
if (r < 0)
return r;
@@ -677,7 +682,7 @@ static int decompress_blob_xz(
#if HAVE_XZ
int r;
r = dlopen_xz();
r = dlopen_xz(LOG_DEBUG);
if (r < 0)
return r;
@@ -744,7 +749,7 @@ static int decompress_blob_lz4(
char* out;
int r, size; /* LZ4 uses int for size */
r = dlopen_lz4();
r = dlopen_lz4(LOG_DEBUG);
if (r < 0)
return r;
@@ -790,7 +795,7 @@ static int decompress_blob_zstd(
uint64_t size;
int r;
r = dlopen_zstd();
r = dlopen_zstd(LOG_DEBUG);
if (r < 0)
return r;
@@ -847,7 +852,7 @@ static int decompress_blob_gzip(
#if HAVE_ZLIB
int r;
r = dlopen_zlib();
r = dlopen_zlib(LOG_DEBUG);
if (r < 0)
return r;
@@ -914,7 +919,7 @@ static int decompress_blob_bzip2(
#if HAVE_BZIP2
int r;
r = dlopen_bzip2();
r = dlopen_bzip2(LOG_DEBUG);
if (r < 0)
return r;
@@ -1010,7 +1015,7 @@ int decompress_zlib_raw(
#if HAVE_ZLIB
int r;
r = dlopen_zlib();
r = dlopen_zlib(LOG_DEBUG);
if (r < 0)
return r;
@@ -1061,7 +1066,7 @@ static int decompress_startswith_xz(
#if HAVE_XZ
int r;
r = dlopen_xz();
r = dlopen_xz(LOG_DEBUG);
if (r < 0)
return r;
@@ -1128,7 +1133,7 @@ static int decompress_startswith_lz4(
size_t allocated;
int r;
r = dlopen_lz4();
r = dlopen_lz4(LOG_DEBUG);
if (r < 0)
return r;
@@ -1200,7 +1205,7 @@ static int decompress_startswith_zstd(
#if HAVE_ZSTD
int r;
r = dlopen_zstd();
r = dlopen_zstd(LOG_DEBUG);
if (r < 0)
return r;
@@ -1257,7 +1262,7 @@ static int decompress_startswith_gzip(
#if HAVE_ZLIB
int r;
r = dlopen_zlib();
r = dlopen_zlib(LOG_DEBUG);
if (r < 0)
return r;
@@ -1324,7 +1329,7 @@ static int decompress_startswith_bzip2(
#if HAVE_BZIP2
int r;
r = dlopen_bzip2();
r = dlopen_bzip2(LOG_DEBUG);
if (r < 0)
return r;
@@ -1561,7 +1566,7 @@ static int decompressor_new(Decompressor **ret, Compression type) {
#if HAVE_XZ
case COMPRESSION_XZ:
r = dlopen_xz();
r = dlopen_xz(LOG_DEBUG);
if (r < 0)
return r;
@@ -1572,7 +1577,7 @@ static int decompressor_new(Decompressor **ret, Compression type) {
#if HAVE_LZ4
case COMPRESSION_LZ4: {
r = dlopen_lz4();
r = dlopen_lz4(LOG_DEBUG);
if (r < 0)
return r;
@@ -1586,7 +1591,7 @@ static int decompressor_new(Decompressor **ret, Compression type) {
#if HAVE_ZSTD
case COMPRESSION_ZSTD:
r = dlopen_zstd();
r = dlopen_zstd(LOG_DEBUG);
if (r < 0)
return r;
@@ -1598,7 +1603,7 @@ static int decompressor_new(Decompressor **ret, Compression type) {
#if HAVE_ZLIB
case COMPRESSION_GZIP:
r = dlopen_zlib();
r = dlopen_zlib(LOG_DEBUG);
if (r < 0)
return r;
@@ -1610,7 +1615,7 @@ static int decompressor_new(Decompressor **ret, Compression type) {
#if HAVE_BZIP2
case COMPRESSION_BZIP2:
r = dlopen_bzip2();
r = dlopen_bzip2(LOG_DEBUG);
if (r < 0)
return r;
@@ -1791,7 +1796,7 @@ int decompressor_detect(Decompressor **ret, const void *data, size_t size) {
#if HAVE_XZ
case COMPRESSION_XZ: {
r = dlopen_xz();
r = dlopen_xz(LOG_DEBUG);
if (r < 0)
return r;
@@ -1805,7 +1810,7 @@ int decompressor_detect(Decompressor **ret, const void *data, size_t size) {
#if HAVE_LZ4
case COMPRESSION_LZ4: {
r = dlopen_lz4();
r = dlopen_lz4(LOG_DEBUG);
if (r < 0)
return r;
@@ -1819,7 +1824,7 @@ int decompressor_detect(Decompressor **ret, const void *data, size_t size) {
#if HAVE_ZSTD
case COMPRESSION_ZSTD: {
r = dlopen_zstd();
r = dlopen_zstd(LOG_DEBUG);
if (r < 0)
return r;
@@ -1833,7 +1838,7 @@ int decompressor_detect(Decompressor **ret, const void *data, size_t size) {
#if HAVE_ZLIB
case COMPRESSION_GZIP: {
r = dlopen_zlib();
r = dlopen_zlib(LOG_DEBUG);
if (r < 0)
return r;
@@ -1847,7 +1852,7 @@ int decompressor_detect(Decompressor **ret, const void *data, size_t size) {
#if HAVE_BZIP2
case COMPRESSION_BZIP2: {
r = dlopen_bzip2();
r = dlopen_bzip2(LOG_DEBUG);
if (r < 0)
return r;
@@ -2092,7 +2097,7 @@ int compressor_new(Compressor **ret, Compression type) {
#if HAVE_XZ
case COMPRESSION_XZ: {
r = dlopen_xz();
r = dlopen_xz(LOG_DEBUG);
if (r < 0)
return r;
@@ -2107,7 +2112,7 @@ int compressor_new(Compressor **ret, Compression type) {
#if HAVE_LZ4
case COMPRESSION_LZ4: {
r = dlopen_lz4();
r = dlopen_lz4(LOG_DEBUG);
if (r < 0)
return r;
@@ -2133,7 +2138,7 @@ int compressor_new(Compressor **ret, Compression type) {
#if HAVE_ZSTD
case COMPRESSION_ZSTD:
r = dlopen_zstd();
r = dlopen_zstd(LOG_DEBUG);
if (r < 0)
return r;
@@ -2156,7 +2161,7 @@ int compressor_new(Compressor **ret, Compression type) {
#if HAVE_ZLIB
case COMPRESSION_GZIP:
r = dlopen_zlib();
r = dlopen_zlib(LOG_DEBUG);
if (r < 0)
return r;
@@ -2176,7 +2181,7 @@ int compressor_new(Compressor **ret, Compression type) {
#if HAVE_BZIP2
case COMPRESSION_BZIP2:
r = dlopen_bzip2();
r = dlopen_bzip2(LOG_DEBUG);
if (r < 0)
return r;
+5 -5
View File
@@ -80,11 +80,11 @@ int compress_stream(Compression type, int fdf, int fdt, uint64_t max_bytes, uint
int decompress_stream(Compression type, int fdf, int fdt, uint64_t max_bytes);
int decompress_stream_by_filename(const char *filename, int fdf, int fdt, uint64_t max_bytes);
int dlopen_xz(void);
int dlopen_lz4(void);
int dlopen_zstd(void);
int dlopen_zlib(void);
int dlopen_bzip2(void);
int dlopen_xz(int log_level);
int dlopen_lz4(int log_level);
int dlopen_zstd(int log_level);
int dlopen_zlib(int log_level);
int dlopen_bzip2(int log_level);
static inline const char* default_compression_extension(void) {
return compression_extension_to_string(DEFAULT_COMPRESSION) ?: "";
+5 -6
View File
@@ -47,7 +47,7 @@ int dlsym_many_or_warn_sentinel(void *dl, int log_level, ...) {
return r;
}
int dlopen_verbose(void **dlp, const char *filename) {
int dlopen_verbose(void **dlp, const char *filename, int log_level) {
int r;
assert(dlp);
@@ -58,10 +58,9 @@ int dlopen_verbose(void **dlp, const char *filename) {
_cleanup_(dlclosep) void *dl = NULL;
const char *dle = NULL;
r = dlopen_safe(filename, &dl, &dle);
if (r < 0) {
log_debug_errno(r, "Shared library '%s' is not available: %s", filename, dle ?: STRERROR(r));
return -EOPNOTSUPP; /* Turn into recognizable error */
}
if (r < 0)
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
"Shared library '%s' is not available: %s", filename, dle ?: STRERROR(r));
log_debug("Loaded shared library '%s' via dlopen().", filename);
*dlp = TAKE_PTR(dl);
@@ -77,7 +76,7 @@ int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_l
return 0; /* Already loaded */
_cleanup_(dlclosep) void *dl = NULL;
r = dlopen_verbose(&dl, filename);
r = dlopen_verbose(&dl, filename, log_level);
if (r < 0)
return r;
+1 -1
View File
@@ -11,7 +11,7 @@ static inline void dlclosep(void **dlp) {
safe_dlclose(*dlp);
}
int dlopen_verbose(void **dlp, const char *filename);
int dlopen_verbose(void **dlp, const char *filename, int log_level);
int dlsym_many_or_warn_sentinel(void *dl, int log_level, ...) _sentinel_;
int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_level, ...) _sentinel_;
+6 -4
View File
@@ -5,6 +5,7 @@
#include "sd-dlopen.h"
#include "gcrypt-util.h"
#include "log.h" /* IWYU pragma: keep */
#if HAVE_GCRYPT
@@ -44,7 +45,7 @@ DLSYM_PROTOTYPE(gcry_randomize) = NULL;
DLSYM_PROTOTYPE(gcry_strerror) = NULL;
#endif
int dlopen_gcrypt(void) {
int dlopen_gcrypt(int log_level) {
#if HAVE_GCRYPT
SD_ELF_NOTE_DLOPEN(
"gcrypt",
@@ -54,7 +55,7 @@ int dlopen_gcrypt(void) {
return dlopen_many_sym_or_warn(
&gcrypt_dl,
"libgcrypt.so.20", LOG_DEBUG,
"libgcrypt.so.20", log_level,
DLSYM_ARG(gcry_control),
DLSYM_ARG(gcry_check_version),
DLSYM_ARG(gcry_md_close),
@@ -88,7 +89,8 @@ int dlopen_gcrypt(void) {
DLSYM_ARG(gcry_randomize),
DLSYM_ARG(gcry_strerror));
#else
return -EOPNOTSUPP;
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
"gcrypt support is not compiled in.");
#endif
}
@@ -96,7 +98,7 @@ int initialize_libgcrypt(bool secmem) {
#if HAVE_GCRYPT
int r;
r = dlopen_gcrypt();
r = dlopen_gcrypt(LOG_DEBUG);
if (r < 0)
return r;
+1 -1
View File
@@ -4,7 +4,7 @@
#include "basic-forward.h"
int dlopen_gcrypt(void);
int dlopen_gcrypt(int log_level);
int initialize_libgcrypt(bool secmem);
+12 -8
View File
@@ -21,35 +21,39 @@ size_t iovec_total_size(const struct iovec *iovec, size_t n) {
assert(iovec || n == 0);
FOREACH_ARRAY(j, iovec, n)
FOREACH_ARRAY(j, iovec, n) {
if (j->iov_len > SIZE_MAX - sum)
return SIZE_MAX; /* Indicate overflow. */
sum += j->iov_len;
}
return sum;
}
bool iovec_increment(struct iovec *iovec, size_t n, size_t k) {
bool iovec_inc_many(struct iovec *iovec, size_t n, size_t k) {
assert(iovec || n == 0);
/* Returns true if there is nothing else to send (bytes written cover all of the iovec),
* false if there's still work to do. */
bool have = false;
FOREACH_ARRAY(j, iovec, n) {
size_t sub;
if (j->iov_len == 0)
continue;
if (k == 0)
return false;
sub = MIN(j->iov_len, k);
j->iov_len -= sub;
j->iov_base = (uint8_t*) j->iov_base + sub;
size_t sub = MIN(j->iov_len, k);
iovec_inc(j, sub);
k -= sub;
have = have || iovec_is_set(j);
}
assert(k == 0); /* Anything else would mean that we wrote more bytes than available,
* or the kernel reported writing more bytes than sent. */
return true;
return !have;
}
struct iovec* iovec_make_string(struct iovec *iovec, const char *s) {
+4 -1
View File
@@ -11,7 +11,7 @@ extern const struct iovec iovec_empty; /* Points to an empty, but valid (i.e.
size_t iovec_total_size(const struct iovec *iovec, size_t n) _nonnull_if_nonzero_(1, 2);
bool iovec_increment(struct iovec *iovec, size_t n, size_t k) _nonnull_if_nonzero_(1, 2);
bool iovec_inc_many(struct iovec *iovec, size_t n, size_t k) _nonnull_if_nonzero_(1, 2);
struct iovec* iovec_make_string(struct iovec *iovec, const char *s);
@@ -38,6 +38,9 @@ char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const ch
void iovec_array_free(struct iovec *iovec, size_t n_iovec) _nonnull_if_nonzero_(1, 2);
int iovec_memcmp(const struct iovec *a, const struct iovec *b) _pure_;
static inline bool iovec_equal(const struct iovec *a, const struct iovec *b) {
return iovec_memcmp(a, b) == 0;
}
struct iovec* iovec_memdup(const struct iovec *source, struct iovec *ret);
+1 -1
View File
@@ -557,7 +557,7 @@ static int write_to_syslog(
if (!syslog_is_stream)
break;
if (iovec_increment(iovec, ELEMENTSOF(iovec), n))
if (iovec_inc_many(iovec, ELEMENTSOF(iovec), n))
break;
}
+24 -9
View File
@@ -1099,25 +1099,40 @@ int strdup_to_full(char **ret, const char *src) {
}
};
bool string_is_safe(const char *p) {
if (!p)
bool string_is_safe(const char *p, StringSafeFlags flags) {
/* Baseline checks are:
* • No control characters (i.e. 0…31 + 127)
* • UTF-8 valid (well, technically we skip this test if STRING_ASCII is set, since that is a tighter test)
*/
if (FLAGS_SET(flags, STRING_ALLOW_EMPTY) ? !p : isempty(p))
return false;
/* Checks if the specified string contains no quotes or control characters */
if (!FLAGS_SET(flags, STRING_ASCII) && !utf8_is_valid(p))
return false;
for (const char *t = p; *t; t++) {
if (*t > 0 && *t < ' ') /* no control characters */
if ((*t > 0 && *t < ' ') || *t == 0x7f) /* never allow control characters */
return false;
if (strchr(QUOTES "\\\x7f", *t))
if (!FLAGS_SET(flags, STRING_ALLOW_BACKSLASHES) && *t == '\\')
return false;
if (!FLAGS_SET(flags, STRING_ALLOW_QUOTES) && strchr(QUOTES, *t))
return false;
if (!FLAGS_SET(flags, STRING_ALLOW_GLOBS) && strchr(GLOB_CHARS, *t))
return false;
if (FLAGS_SET(flags, STRING_ASCII) && (uint8_t) *t >= 0x80)
return false;
}
return true;
}
if (FLAGS_SET(flags, STRING_FILENAME) && !filename_is_valid(p))
return false;
bool string_is_safe_ascii(const char *p) {
return ascii_is_valid(p) && string_is_safe(p);
return true;
}
char* str_realloc(char *p) {
+10 -2
View File
@@ -220,8 +220,16 @@ static inline int strdup_to(char **ret, const char *src) {
return r < 0 ? r : 0; /* Suppress return value of 1. */
}
bool string_is_safe(const char *p) _pure_;
bool string_is_safe_ascii(const char *p) _pure_;
typedef enum StringSafeFlags {
STRING_ASCII = 1 << 0, /* Verify string is 7-Bit ASCII (rather than just UTF-8) */
STRING_ALLOW_EMPTY = 1 << 1, /* Allow empty strings */
STRING_ALLOW_BACKSLASHES = 1 << 2, /* Allow backslashes (\) */
STRING_ALLOW_QUOTES = 1 << 3, /* Allow quotes (" or ') */
STRING_ALLOW_GLOBS = 1 << 4, /* Allow globs (?, * or [) */
STRING_FILENAME = 1 << 5, /* Verify the string is valid as regular filename */
} StringSafeFlags;
bool string_is_safe(const char *p, StringSafeFlags flags) _pure_;
DISABLE_WARNING_STRINGOP_TRUNCATION;
static inline void strncpy_exact(char *buf, const char *src, size_t buf_len) {
+2 -10
View File
@@ -4,9 +4,7 @@
#include "sd-id128.h"
#include "glob-util.h"
#include "hexdecoct.h"
#include "path-util.h"
#include "string-table.h"
#include "string-util.h"
#include "syslog-util.h"
@@ -111,7 +109,8 @@ bool log_namespace_name_valid(const char *s) {
* (so that /var/log/journal/<machine-id>.<namespace> can be created based on it). Also make sure it
* is suitable as unit instance name, and does not contain fishy characters. */
if (!filename_is_valid(s))
/* Let's avoid globbing for now */
if (!string_is_safe(s, STRING_FILENAME))
return false;
if (strlen(s) > LOG_NAMESPACE_MAX)
@@ -120,12 +119,5 @@ bool log_namespace_name_valid(const char *s) {
if (!unit_instance_is_valid(s))
return false;
if (!string_is_safe(s))
return false;
/* Let's avoid globbing for now */
if (string_is_glob(s))
return false;
return true;
}
+8
View File
@@ -72,6 +72,14 @@ const char* unit_dbus_interface_from_name(const char *name) {
return unit_dbus_interface_from_type(t);
}
const char* unit_type_to_capitalized_string(UnitType t) {
const char *di = unit_dbus_interface_from_type(t);
if (!di)
return NULL;
return ASSERT_PTR(startswith(di, "org.freedesktop.systemd1."));
}
static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
[UNIT_SERVICE] = "service",
[UNIT_SOCKET] = "socket",
+1
View File
@@ -321,6 +321,7 @@ void unit_types_list(void);
DECLARE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);
DECLARE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
const char* unit_type_to_capitalized_string(UnitType t);
DECLARE_STRING_TABLE_LOOKUP(freezer_state, FreezerState);
FreezerState freezer_state_finish(FreezerState state) _const_;