Merge pull request #13096 from keszybz/unit-loading

Preparatory work for the unit loading rework
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2019-07-19 21:47:10 +02:00
committed by GitHub
44 changed files with 760 additions and 503 deletions
+3
View File
@@ -10,6 +10,9 @@ void string_hash_func(const char *p, struct siphash *state) {
}
DEFINE_HASH_OPS(string_hash_ops, char, string_hash_func, string_compare_func);
DEFINE_HASH_OPS_FULL(string_hash_ops_free_free,
char, string_hash_func, string_compare_func, free,
char, free);
void path_hash_func(const char *q, struct siphash *state) {
size_t n;
+1
View File
@@ -76,6 +76,7 @@ struct hash_ops {
void string_hash_func(const char *p, struct siphash *state);
#define string_compare_func strcmp
extern const struct hash_ops string_hash_ops;
extern const struct hash_ops string_hash_ops_free_free;
void path_hash_func(const char *p, struct siphash *state);
int path_compare_func(const char *a, const char *b) _pure_;
+28 -2
View File
@@ -733,8 +733,8 @@ bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const v
return true;
}
bool set_iterate(Set *s, Iterator *i, void **value) {
return internal_hashmap_iterate(HASHMAP_BASE(s), i, value, NULL);
bool set_iterate(const Set *s, Iterator *i, void **value) {
return internal_hashmap_iterate(HASHMAP_BASE((Set*) s), i, value, NULL);
}
#define HASHMAP_FOREACH_IDX(idx, h, i) \
@@ -1768,6 +1768,32 @@ int set_consume(Set *s, void *value) {
return r;
}
int hashmap_put_strdup(Hashmap **h, const char *k, const char *v) {
int r;
r = hashmap_ensure_allocated(h, &string_hash_ops_free_free);
if (r < 0)
return r;
_cleanup_free_ char *kdup = NULL, *vdup = NULL;
kdup = strdup(k);
vdup = strdup(v);
if (!kdup || !vdup)
return -ENOMEM;
r = hashmap_put(*h, kdup, vdup);
if (r < 0) {
if (r == -EEXIST && streq(v, hashmap_get(*h, kdup)))
return 0;
return r;
}
assert(r > 0); /* 0 would mean vdup is already in the hashmap, which cannot be */
kdup = vdup = NULL;
return 0;
}
int set_put_strdup(Set *s, const char *p) {
char *c;
+2
View File
@@ -147,6 +147,8 @@ static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *
return hashmap_put(PLAIN_HASHMAP(h), key, value);
}
int hashmap_put_strdup(Hashmap **h, const char *k, const char *v);
int hashmap_update(Hashmap *h, const void *key, void *value);
static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {
return hashmap_update(PLAIN_HASHMAP(h), key, value);
+58 -46
View File
@@ -207,6 +207,18 @@ int path_make_relative(const char *from_dir, const char *to_path, char **_r) {
return 0;
}
char* path_startswith_strv(const char *p, char **set) {
char **s, *t;
STRV_FOREACH(s, set) {
t = path_startswith(p, *s);
if (t)
return t;
}
return NULL;
}
int path_strv_make_absolute_cwd(char **l) {
char **s;
int r;
@@ -382,6 +394,52 @@ char *path_simplify(char *path, bool kill_dots) {
return path;
}
int path_simplify_and_warn(
char *path,
unsigned flag,
const char *unit,
const char *filename,
unsigned line,
const char *lvalue) {
bool fatal = flag & PATH_CHECK_FATAL;
assert(!FLAGS_SET(flag, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE));
if (!utf8_is_valid(path))
return log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path);
if (flag & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) {
bool absolute;
absolute = path_is_absolute(path);
if (!absolute && (flag & PATH_CHECK_ABSOLUTE))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is not absolute%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
if (absolute && (flag & PATH_CHECK_RELATIVE))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is absolute%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
}
path_simplify(path, true);
if (!path_is_valid(path))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path has invalid length (%zu bytes)%s.",
lvalue, strlen(path), fatal ? "" : ", ignoring");
if (!path_is_normalized(path))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is not normalized%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
return 0;
}
char* path_startswith(const char *path, const char *prefix) {
assert(path);
assert(prefix);
@@ -1058,49 +1116,3 @@ bool empty_or_root(const char *root) {
return root[strspn(root, "/")] == 0;
}
int path_simplify_and_warn(
char *path,
unsigned flag,
const char *unit,
const char *filename,
unsigned line,
const char *lvalue) {
bool fatal = flag & PATH_CHECK_FATAL;
assert(!FLAGS_SET(flag, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE));
if (!utf8_is_valid(path))
return log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path);
if (flag & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) {
bool absolute;
absolute = path_is_absolute(path);
if (!absolute && (flag & PATH_CHECK_ABSOLUTE))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is not absolute%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
if (absolute && (flag & PATH_CHECK_RELATIVE))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is absolute%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
}
path_simplify(path, true);
if (!path_is_valid(path))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path has invalid length (%zu bytes)%s.",
lvalue, strlen(path), fatal ? "" : ", ignoring");
if (!path_is_normalized(path))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is not normalized%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
return 0;
}
+10 -19
View File
@@ -54,6 +54,14 @@ char* path_join_internal(const char *first, ...);
char* path_simplify(char *path, bool kill_dots);
enum {
PATH_CHECK_FATAL = 1 << 0, /* If not set, then error message is appended with 'ignoring'. */
PATH_CHECK_ABSOLUTE = 1 << 1,
PATH_CHECK_RELATIVE = 1 << 2,
};
int path_simplify_and_warn(char *path, unsigned flag, const char *unit, const char *filename, unsigned line, const char *lvalue);
static inline bool path_equal_ptr(const char *a, const char *b) {
return !!a == !!b && (!a || path_equal(a, b));
}
@@ -71,17 +79,8 @@ static inline bool path_equal_ptr(const char *a, const char *b) {
_found; \
})
#define PATH_STARTSWITH_SET(p, ...) \
({ \
const char *_p = (p); \
char *_found = NULL, **_i; \
STRV_FOREACH(_i, STRV_MAKE(__VA_ARGS__)) { \
_found = path_startswith(_p, *_i); \
if (_found) \
break; \
} \
_found; \
})
char* path_startswith_strv(const char *p, char **set);
#define PATH_STARTSWITH_SET(p, ...) path_startswith_strv(p, STRV_MAKE(__VA_ARGS__))
int path_strv_make_absolute_cwd(char **l);
char** path_strv_resolve(char **l, const char *root);
@@ -178,11 +177,3 @@ bool empty_or_root(const char *root);
static inline const char *empty_to_root(const char *path) {
return isempty(path) ? "/" : path;
}
enum {
PATH_CHECK_FATAL = 1 << 0, /* If not set, then error message is appended with 'ignoring'. */
PATH_CHECK_ABSOLUTE = 1 << 1,
PATH_CHECK_RELATIVE = 1 << 2,
};
int path_simplify_and_warn(char *path, unsigned flag, const char *unit, const char *filename, unsigned line, const char *lvalue);
+10 -10
View File
@@ -28,13 +28,13 @@ int internal_set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHM
int set_put(Set *s, const void *key);
/* no set_update */
/* no set_replace */
static inline void *set_get(Set *s, void *key) {
return internal_hashmap_get(HASHMAP_BASE(s), key);
static inline void *set_get(const Set *s, void *key) {
return internal_hashmap_get(HASHMAP_BASE((Set *) s), key);
}
/* no set_get2 */
static inline bool set_contains(Set *s, const void *key) {
return internal_hashmap_contains(HASHMAP_BASE(s), key);
static inline bool set_contains(const Set *s, const void *key) {
return internal_hashmap_contains(HASHMAP_BASE((Set *) s), key);
}
static inline void *set_remove(Set *s, const void *key) {
@@ -59,19 +59,19 @@ static inline int set_move_one(Set *s, Set *other, const void *key) {
return internal_hashmap_move_one(HASHMAP_BASE(s), HASHMAP_BASE(other), key);
}
static inline unsigned set_size(Set *s) {
return internal_hashmap_size(HASHMAP_BASE(s));
static inline unsigned set_size(const Set *s) {
return internal_hashmap_size(HASHMAP_BASE((Set *) s));
}
static inline bool set_isempty(Set *s) {
static inline bool set_isempty(const Set *s) {
return set_size(s) == 0;
}
static inline unsigned set_buckets(Set *s) {
return internal_hashmap_buckets(HASHMAP_BASE(s));
static inline unsigned set_buckets(const Set *s) {
return internal_hashmap_buckets(HASHMAP_BASE((Set *) s));
}
bool set_iterate(Set *s, Iterator *i, void **value);
bool set_iterate(const Set *s, Iterator *i, void **value);
static inline void set_clear(Set *s) {
internal_hashmap_clear(HASHMAP_BASE(s), NULL, NULL);
+60
View File
@@ -889,3 +889,63 @@ int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
return 0;
}
static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const char *value) {
char **l;
int r;
l = hashmap_get(h, key);
if (l) {
/* A list for this key already exists, let's append to it if it is not listed yet */
if (strv_contains(l, value))
return 0;
r = strv_extend(&l, value);
if (r < 0)
return r;
assert_se(hashmap_update(h, key, l) >= 0);
} else {
/* No list for this key exists yet, create one */
_cleanup_strv_free_ char **l2 = NULL;
_cleanup_free_ char *t = NULL;
t = strdup(key);
if (!t)
return -ENOMEM;
r = strv_extend(&l2, value);
if (r < 0)
return r;
r = hashmap_put(h, t, l2);
if (r < 0)
return r;
TAKE_PTR(t);
TAKE_PTR(l2);
}
return 1;
}
int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value) {
int r;
r = hashmap_ensure_allocated(h, &string_strv_hash_ops);
if (r < 0)
return r;
return string_strv_hashmap_put_internal(*h, key, value);
}
int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value) {
int r;
r = ordered_hashmap_ensure_allocated(h, &string_strv_hash_ops);
if (r < 0)
return r;
return string_strv_hashmap_put_internal(PLAIN_HASHMAP(*h), key, value);
}
DEFINE_HASH_OPS_FULL(string_strv_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free);
+5
View File
@@ -9,6 +9,7 @@
#include "alloc-util.h"
#include "extract-word.h"
#include "hashmap.h"
#include "macro.h"
#include "string-util.h"
@@ -188,3 +189,7 @@ int fputstrv(FILE *f, char **l, const char *separator, bool *space);
(b) = NULL; \
0; \
})
extern const struct hash_ops string_strv_hash_ops;
int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value);
int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value);
+11 -10
View File
@@ -140,12 +140,10 @@ int unit_name_to_prefix(const char *n, char **ret) {
return 0;
}
int unit_name_to_instance(const char *n, char **instance) {
int unit_name_to_instance(const char *n, char **ret) {
const char *p, *d;
char *i;
assert(n);
assert(instance);
if (!unit_name_is_valid(n, UNIT_NAME_ANY))
return -EINVAL;
@@ -153,8 +151,9 @@ int unit_name_to_instance(const char *n, char **instance) {
/* Everything past the first @ and before the last . is the instance */
p = strchr(n, '@');
if (!p) {
*instance = NULL;
return 0;
if (ret)
*ret = NULL;
return UNIT_NAME_PLAIN;
}
p++;
@@ -163,12 +162,14 @@ int unit_name_to_instance(const char *n, char **instance) {
if (!d)
return -EINVAL;
i = strndup(p, d-p);
if (!i)
return -ENOMEM;
if (ret) {
char *i = strndup(p, d-p);
if (!i)
return -ENOMEM;
*instance = i;
return 1;
*ret = i;
}
return d > p ? UNIT_NAME_INSTANCE : UNIT_NAME_TEMPLATE;
}
int unit_name_to_prefix_and_instance(const char *n, char **ret) {
+7 -9
View File
@@ -10,9 +10,9 @@
typedef enum UnitNameFlags {
UNIT_NAME_PLAIN = 1 << 0, /* Allow foo.service */
UNIT_NAME_INSTANCE = 1 << 1, /* Allow foo@bar.service */
UNIT_NAME_TEMPLATE = 1 << 2, /* Allow foo@.service */
UNIT_NAME_ANY = UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE,
UNIT_NAME_TEMPLATE = 1 << 1, /* Allow foo@.service */
UNIT_NAME_INSTANCE = 1 << 2, /* Allow foo@bar.service */
UNIT_NAME_ANY = UNIT_NAME_PLAIN|UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE,
} UnitNameFlags;
bool unit_name_is_valid(const char *n, UnitNameFlags flags) _pure_;
@@ -20,13 +20,11 @@ bool unit_prefix_is_valid(const char *p) _pure_;
bool unit_instance_is_valid(const char *i) _pure_;
bool unit_suffix_is_valid(const char *s) _pure_;
static inline int unit_prefix_and_instance_is_valid(const char *p) {
/* For prefix+instance and instance the same rules apply */
return unit_instance_is_valid(p);
int unit_name_to_prefix(const char *n, char **ret);
int unit_name_to_instance(const char *n, char **ret);
static inline int unit_name_classify(const char *n) {
return unit_name_to_instance(n, NULL);
}
int unit_name_to_prefix(const char *n, char **prefix);
int unit_name_to_instance(const char *n, char **instance);
int unit_name_to_prefix_and_instance(const char *n, char **ret);
UnitType unit_name_to_type(const char *n) _pure_;