Merge pull request #10825 from keszybz/advertize-followup

udev link advertizing followup
This commit is contained in:
Lennart Poettering
2018-11-19 11:05:18 +01:00
committed by GitHub
7 changed files with 82 additions and 33 deletions
-7
View File
@@ -1577,11 +1577,4 @@ enum ethtool_link_mode_bit_indices {
#endif
#endif
/* Strictly speaking, this is not a missing field. Just for our convention. */
#if !HAVE_ETHTOOL_LINK_MODE_FEC_NONE_BIT
#define _ETHTOOL_LINK_MODE_MAX 52
#else
#define _ETHTOOL_LINK_MODE_MAX (__ETHTOOL_LINK_MODE_LAST + 1)
#endif
#include "missing_syscall.h"
+22
View File
@@ -165,6 +165,28 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
return NULL;
}
bool memeqzero(const void *data, size_t length) {
/* Does the buffer consist entirely of NULs?
* Copied from https://github.com/systemd/casync/, copied in turn from
* https://github.com/rustyrussell/ccan/blob/master/ccan/mem/mem.c#L92,
* which is licensed CC-0.
*/
const uint8_t *p = data;
size_t i;
/* Check first 16 bytes manually */
for (i = 0; i < 16; i++, length--) {
if (length == 0)
return true;
if (p[i])
return false;
}
/* Now we know first 16 bytes are NUL, memcmp with self. */
return memcmp(data, p + i, length) == 0;
}
int on_ac_power(void) {
bool found_offline = false, found_online = false;
_cleanup_closedir_ DIR *d = NULL;
+4
View File
@@ -159,6 +159,10 @@ int on_ac_power(void);
#define zero(x) (memzero(&(x), sizeof(x)))
bool memeqzero(const void *data, size_t length);
#define eqzero(x) memeqzero(x, sizeof(x))
static inline void *mempset(void *s, int c, size_t n) {
memset(s, c, n);
return (uint8_t*)s + n;
+43 -2
View File
@@ -13,11 +13,14 @@
#include "raw-clone.h"
#include "rm-rf.h"
#include "string-util.h"
#include "tests.h"
#include "util.h"
static void test_align_power2(void) {
unsigned long i, p2;
log_info("/* %s */", __func__);
assert_se(ALIGN_POWER2(0) == 0);
assert_se(ALIGN_POWER2(1) == 1);
assert_se(ALIGN_POWER2(2) == 2);
@@ -60,6 +63,8 @@ static void test_max(void) {
void *p = (void *)str;
void *q = (void *)&str[16];
log_info("/* %s */", __func__);
assert_cc(sizeof(val1.b) == sizeof(int) * 100);
/* CONST_MAX returns (void) instead of a value if the passed arguments
@@ -135,6 +140,8 @@ static void test_container_of(void) {
uint32_t v2;
} _packed_ myval = { };
log_info("/* %s */", __func__);
assert_cc(sizeof(myval) == 17);
assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
@@ -150,6 +157,8 @@ static void test_container_of(void) {
static void test_div_round_up(void) {
int div;
log_info("/* %s */", __func__);
/* basic tests */
assert_se(DIV_ROUND_UP(0, 8) == 0);
assert_se(DIV_ROUND_UP(1, 8) == 1);
@@ -181,6 +190,8 @@ static void test_div_round_up(void) {
}
static void test_u64log2(void) {
log_info("/* %s */", __func__);
assert_se(u64log2(0) == 0);
assert_se(u64log2(8) == 3);
assert_se(u64log2(9) == 3);
@@ -191,6 +202,8 @@ static void test_u64log2(void) {
}
static void test_protect_errno(void) {
log_info("/* %s */", __func__);
errno = 12;
{
PROTECT_ERRNO;
@@ -200,6 +213,8 @@ static void test_protect_errno(void) {
}
static void test_in_set(void) {
log_info("/* %s */", __func__);
assert_se(IN_SET(1, 1));
assert_se(IN_SET(1, 1, 2, 3, 4));
assert_se(IN_SET(2, 1, 2, 3, 4));
@@ -210,6 +225,8 @@ static void test_in_set(void) {
}
static void test_log2i(void) {
log_info("/* %s */", __func__);
assert_se(log2i(1) == 0);
assert_se(log2i(2) == 1);
assert_se(log2i(3) == 1);
@@ -220,9 +237,25 @@ static void test_log2i(void) {
assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
}
static void test_eqzero(void) {
const uint32_t zeros[] = {0, 0, 0};
const uint32_t ones[] = {1, 1};
const uint32_t mixed[] = {0, 1, 0, 0, 0};
const uint8_t longer[] = {[55] = 255};
log_info("/* %s */", __func__);
assert_se(eqzero(zeros));
assert_se(!eqzero(ones));
assert_se(!eqzero(mixed));
assert_se(!eqzero(longer));
}
static void test_raw_clone(void) {
pid_t parent, pid, pid2;
log_info("/* %s */", __func__);
parent = getpid();
log_info("before clone: getpid()→"PID_FMT, parent);
assert_se(raw_getpid() == parent);
@@ -253,6 +286,8 @@ static void test_physical_memory(void) {
uint64_t p;
char buf[FORMAT_BYTES_MAX];
log_info("/* %s */", __func__);
p = physical_memory();
assert_se(p > 0);
assert_se(p < UINT64_MAX);
@@ -264,6 +299,8 @@ static void test_physical_memory(void) {
static void test_physical_memory_scale(void) {
uint64_t p;
log_info("/* %s */", __func__);
p = physical_memory();
assert_se(physical_memory_scale(0, 100) == 0);
@@ -298,6 +335,8 @@ static void test_physical_memory_scale(void) {
static void test_system_tasks_max(void) {
uint64_t t;
log_info("/* %s */", __func__);
t = system_tasks_max();
assert_se(t > 0);
assert_se(t < UINT64_MAX);
@@ -308,6 +347,8 @@ static void test_system_tasks_max(void) {
static void test_system_tasks_max_scale(void) {
uint64_t t;
log_info("/* %s */", __func__);
t = system_tasks_max();
assert_se(system_tasks_max_scale(0, 100) == 0);
@@ -333,8 +374,7 @@ static void test_system_tasks_max_scale(void) {
}
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
test_setup_logging(LOG_INFO);
test_align_power2();
test_max();
@@ -344,6 +384,7 @@ int main(int argc, char *argv[]) {
test_protect_errno();
test_in_set();
test_log2i();
test_eqzero();
test_raw_clone();
test_physical_memory();
test_physical_memory_scale();
+11 -21
View File
@@ -56,7 +56,7 @@ static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
[NET_DEV_FEAT_TSO6] = "tx-tcp6-segmentation",
};
static const char* const ethtool_link_mode_bit_table[_ETHTOOL_LINK_MODE_MAX] = {
static const char* const ethtool_link_mode_bit_table[] = {
[ETHTOOL_LINK_MODE_10baseT_Half_BIT] = "10baset-half",
[ETHTOOL_LINK_MODE_10baseT_Full_BIT] = "10baset-full",
[ETHTOOL_LINK_MODE_100baseT_Half_BIT] = "100baset-half",
@@ -110,6 +110,8 @@ static const char* const ethtool_link_mode_bit_table[_ETHTOOL_LINK_MODE_MAX] = {
[ETHTOOL_LINK_MODE_FEC_RS_BIT] = "fec-rs",
[ETHTOOL_LINK_MODE_FEC_BASER_BIT] = "fec-baser",
};
/* Make sure the array is large enough to fit all bits */
assert_cc((ELEMENTSOF(ethtool_link_mode_bit_table)-1) / 32 < ELEMENTSOF(((struct link_config){}).advertise));
DEFINE_STRING_TABLE_LOOKUP(ethtool_link_mode_bit, enum ethtool_link_mode_bit_indices);
@@ -612,8 +614,11 @@ int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *l
u->base.autoneg = link->autonegotiation;
if (link->advertise)
memcpy(&u->link_modes.advertising, link->advertise, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES);
if (!eqzero(link->advertise)) {
memcpy(&u->link_modes.advertising, link->advertise, sizeof(link->advertise));
memzero((uint8_t*) &u->link_modes.advertising + sizeof(link->advertise),
ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES - sizeof(link->advertise));
}
if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
r = set_slinksettings(*fd, &ifr, u);
@@ -737,8 +742,6 @@ int config_parse_advertise(const char *unit,
const char *rvalue,
void *data,
void *userdata) {
uint32_t a[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32] = {};
enum ethtool_link_mode_bit_indices mode;
link_config *config = data;
const char *p;
int r;
@@ -751,12 +754,13 @@ int config_parse_advertise(const char *unit,
if (isempty(rvalue)) {
/* Empty string resets the value. */
config->advertise = mfree(config->advertise);
zero(config->advertise);
return 0;
}
for (p = rvalue;;) {
_cleanup_free_ char *w = NULL;
enum ethtool_link_mode_bit_indices mode;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
@@ -774,21 +778,7 @@ int config_parse_advertise(const char *unit,
continue;
}
a[mode / 32] |= 1UL << (mode % 32);
}
if (!config->advertise) {
config->advertise = new(uint32_t, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32);
if (!config->advertise)
return log_oom();
memcpy(config->advertise, a, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES);
} else {
unsigned i;
for (i = 0; i < ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32; i++)
config->advertise[i] |= a[i];
config->advertise[mode / 32] |= 1UL << (mode % 32);
}
return 0;
+1 -2
View File
@@ -69,7 +69,6 @@ static void link_config_free(link_config *link) {
free(link->name_policy);
free(link->name);
free(link->alias);
free(link->advertise);
free(link);
}
@@ -373,7 +372,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
if (config->port != _NET_DEV_PORT_INVALID)
log_warning_errno(r, "Could not set port (%s) of %s: %m", port_to_string(config->port), old_name);
if (config->advertise)
if (!eqzero(config->advertise))
log_warning_errno(r, "Could not set advertise mode: %m"); /* TODO: include modes in the log message. */
if (config->speed) {
+1 -1
View File
@@ -55,7 +55,7 @@ struct link_config {
size_t speed;
Duplex duplex;
int autonegotiation;
uint32_t *advertise;
uint32_t advertise[2];
WakeOnLan wol;
NetDevPort port;
int features[_NET_DEV_FEAT_MAX];