summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/cgroup-util.c16
-rw-r--r--src/basic/cgroup-util.h16
-rw-r--r--src/basic/ether-addr-util.c69
-rw-r--r--src/basic/ether-addr-util.h2
-rw-r--r--src/basic/rm-rf.h6
-rw-r--r--src/basic/string-util.h1
6 files changed, 107 insertions, 3 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index ff57cf30b7..7cdc97ee3c 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -2269,6 +2269,22 @@ int cg_weight_parse(const char *s, uint64_t *ret) {
return 0;
}
+const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX] = {
+ [CGROUP_IO_RBPS_MAX] = CGROUP_LIMIT_MAX,
+ [CGROUP_IO_WBPS_MAX] = CGROUP_LIMIT_MAX,
+ [CGROUP_IO_RIOPS_MAX] = CGROUP_LIMIT_MAX,
+ [CGROUP_IO_WIOPS_MAX] = CGROUP_LIMIT_MAX,
+};
+
+static const char* const cgroup_io_limit_type_table[_CGROUP_IO_LIMIT_TYPE_MAX] = {
+ [CGROUP_IO_RBPS_MAX] = "IOReadBandwidthMax",
+ [CGROUP_IO_WBPS_MAX] = "IOWriteBandwidthMax",
+ [CGROUP_IO_RIOPS_MAX] = "IOReadIOPSMax",
+ [CGROUP_IO_WIOPS_MAX] = "IOWriteIOPSMax",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(cgroup_io_limit_type, CGroupIOLimitType);
+
int cg_cpu_shares_parse(const char *s, uint64_t *ret) {
uint64_t u;
int r;
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index a696c1fa60..4bb5291296 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -72,6 +72,22 @@ static inline bool CGROUP_WEIGHT_IS_OK(uint64_t x) {
(x >= CGROUP_WEIGHT_MIN && x <= CGROUP_WEIGHT_MAX);
}
+/* IO limits on unified hierarchy */
+typedef enum CGroupIOLimitType {
+ CGROUP_IO_RBPS_MAX,
+ CGROUP_IO_WBPS_MAX,
+ CGROUP_IO_RIOPS_MAX,
+ CGROUP_IO_WIOPS_MAX,
+
+ _CGROUP_IO_LIMIT_TYPE_MAX,
+ _CGROUP_IO_LIMIT_TYPE_INVALID = -1
+} CGroupIOLimitType;
+
+extern const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX];
+
+const char* cgroup_io_limit_type_to_string(CGroupIOLimitType t) _const_;
+CGroupIOLimitType cgroup_io_limit_type_from_string(const char *s) _pure_;
+
/* Special values for the cpu.shares attribute */
#define CGROUP_CPU_SHARES_INVALID ((uint64_t) -1)
#define CGROUP_CPU_SHARES_MIN UINT64_C(2)
diff --git a/src/basic/ether-addr-util.c b/src/basic/ether-addr-util.c
index a4d8d656da..5697e8d132 100644
--- a/src/basic/ether-addr-util.c
+++ b/src/basic/ether-addr-util.c
@@ -23,6 +23,7 @@
#include "ether-addr-util.h"
#include "macro.h"
+#include "string-util.h"
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
assert(addr);
@@ -54,3 +55,71 @@ bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
a->ether_addr_octet[4] == b->ether_addr_octet[4] &&
a->ether_addr_octet[5] == b->ether_addr_octet[5];
}
+
+int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset) {
+ size_t pos = 0, n, field;
+ char sep = '\0';
+ const char *hex = HEXDIGITS, *hexoff;
+ size_t x;
+ bool touched;
+
+#define parse_fields(v) \
+ for (field = 0; field < ELEMENTSOF(v); field++) { \
+ touched = false; \
+ for (n = 0; n < (2 * sizeof(v[0])); n++) { \
+ if (s[pos] == '\0') \
+ break; \
+ hexoff = strchr(hex, s[pos]); \
+ if (hexoff == NULL) \
+ break; \
+ assert(hexoff >= hex); \
+ x = hexoff - hex; \
+ if (x >= 16) \
+ x -= 6; /* A-F */ \
+ assert(x < 16); \
+ touched = true; \
+ v[field] <<= 4; \
+ v[field] += x; \
+ pos++; \
+ } \
+ if (!touched) \
+ return -EINVAL; \
+ if (field < (ELEMENTSOF(v)-1)) { \
+ if (s[pos] != sep) \
+ return -EINVAL; \
+ else \
+ pos++; \
+ } \
+ }
+
+ assert(s);
+ assert(ret);
+
+ sep = s[strspn(s, hex)];
+ if (sep == '\n')
+ return -EINVAL;
+ if (strchr(":.-", sep) == NULL)
+ return -EINVAL;
+
+ if (sep == '.') {
+ uint16_t shorts[3] = { 0 };
+
+ parse_fields(shorts);
+
+ for (n = 0; n < ELEMENTSOF(shorts); n++) {
+ ret->ether_addr_octet[2*n] = ((shorts[n] & (uint16_t)0xff00) >> 8);
+ ret->ether_addr_octet[2*n + 1] = (shorts[n] & (uint16_t)0x00ff);
+ }
+ } else {
+ struct ether_addr out = { .ether_addr_octet = { 0 } };
+
+ parse_fields(out.ether_addr_octet);
+
+ for (n = 0; n < ELEMENTSOF(out.ether_addr_octet); n++)
+ ret->ether_addr_octet[n] = out.ether_addr_octet[n];
+ }
+
+ if (offset)
+ *offset = pos;
+ return 0;
+}
diff --git a/src/basic/ether-addr-util.h b/src/basic/ether-addr-util.h
index 074363793e..74e125a95f 100644
--- a/src/basic/ether-addr-util.h
+++ b/src/basic/ether-addr-util.h
@@ -35,3 +35,5 @@ bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b);
static inline bool ether_addr_is_null(const struct ether_addr *addr) {
return ether_addr_equal(addr, &ETHER_ADDR_NULL);
}
+
+int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset);
diff --git a/src/basic/rm-rf.h b/src/basic/rm-rf.h
index 40b5b527d5..f693a5bb7c 100644
--- a/src/basic/rm-rf.h
+++ b/src/basic/rm-rf.h
@@ -32,10 +32,10 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev);
int rm_rf(const char *path, RemoveFlags flags);
/* Useful for usage with _cleanup_(), destroys a directory and frees the pointer */
-static inline void rm_rf_and_free(char *p) {
+static inline void rm_rf_physical_and_free(char *p) {
if (!p)
return;
- (void) rm_rf(p, REMOVE_ROOT);
+ (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
free(p);
}
-DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rm_rf_and_free);
+DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rm_rf_physical_and_free);
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index ad0c813761..139cc8c91b 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -37,6 +37,7 @@
#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS
#define ALPHANUMERICAL LETTERS DIGITS
+#define HEXDIGITS DIGITS "abcdefABCDEF"
#define streq(a,b) (strcmp((a),(b)) == 0)
#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)