summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/tmpfiles.d.xml16
-rw-r--r--src/basic/btrfs-util.c18
-rw-r--r--src/basic/btrfs-util.h4
-rw-r--r--src/basic/hashmap.c2
-rw-r--r--src/basic/siphash24.c7
-rw-r--r--src/basic/siphash24.h4
-rw-r--r--src/basic/unaligned.h47
-rw-r--r--src/import/pull-common.c2
-rw-r--r--src/journal/journald-rate-limit.c4
-rw-r--r--src/libsystemd-network/dhcp-identifier.c10
-rw-r--r--src/libsystemd-network/network-internal.c2
-rw-r--r--src/libsystemd-network/network-internal.h2
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c2
-rw-r--r--src/libsystemd-network/sd-ipv4ll.c6
-rw-r--r--src/libsystemd-network/test-dhcp-server.c2
-rw-r--r--src/libsystemd/sd-bus/bus-bloom.c6
-rw-r--r--src/network/networkd-ipv4ll.c6
-rw-r--r--src/network/networkd-netdev.c6
-rw-r--r--src/nspawn/nspawn-network.c6
-rw-r--r--src/test/test-siphash24.c6
-rw-r--r--src/test/test-unaligned.c74
-rw-r--r--src/tmpfiles/tmpfiles.c24
-rw-r--r--src/udev/net/link-config.c6
23 files changed, 210 insertions, 52 deletions
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index 3f6128cb5b..5bf1f2956b 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -169,13 +169,15 @@
<varlistentry>
<term><varname>v</varname></term>
<listitem><para>Create a subvolume if the path does not
- exist yet and the file system supports this
- (btrfs). Otherwise, create a normal directory, in the same
- way as <varname>d</varname>. A subvolume created with this
- line type is not assigned to any higher-level quota
- group. For that, use <varname>q</varname> or
- <varname>Q</varname>, which allow creating simple quota group
- hierarchies, see below.</para></listitem>
+ exist yet, the file system supports subvolumes (btrfs), and
+ the system itself is installed into a subvolume
+ (specifically: the root directory <filename>/</filename> is
+ itself a subvolume). Otherwise, create a normal directory, in
+ the same way as <varname>d</varname>. A subvolume created
+ with this line type is not assigned to any higher-level
+ quota group. For that, use <varname>q</varname> or
+ <varname>Q</varname>, which allow creating simple quota
+ group hierarchies, see below.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c
index 8c2d76b8aa..be40dc5702 100644
--- a/src/basic/btrfs-util.c
+++ b/src/basic/btrfs-util.c
@@ -105,7 +105,7 @@ int btrfs_is_filesystem(int fd) {
return F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC);
}
-int btrfs_is_subvol(int fd) {
+int btrfs_is_subvol_fd(int fd) {
struct stat st;
assert(fd >= 0);
@@ -121,6 +121,18 @@ int btrfs_is_subvol(int fd) {
return btrfs_is_filesystem(fd);
}
+int btrfs_is_subvol(const char *path) {
+ _cleanup_close_ int fd = -1;
+
+ assert(path);
+
+ fd = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
+ if (fd < 0)
+ return -errno;
+
+ return btrfs_is_subvol_fd(fd);
+}
+
int btrfs_subvol_make(const char *path) {
struct btrfs_ioctl_vol_args args = {};
_cleanup_close_ int fd = -1;
@@ -1686,7 +1698,7 @@ int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlag
assert(old_fd >= 0);
assert(new_path);
- r = btrfs_is_subvol(old_fd);
+ r = btrfs_is_subvol_fd(old_fd);
if (r < 0)
return r;
if (r == 0) {
@@ -1872,7 +1884,7 @@ int btrfs_subvol_auto_qgroup_fd(int fd, uint64_t subvol_id, bool insert_intermed
*/
if (subvol_id == 0) {
- r = btrfs_is_subvol(fd);
+ r = btrfs_is_subvol_fd(fd);
if (r < 0)
return r;
if (!r)
diff --git a/src/basic/btrfs-util.h b/src/basic/btrfs-util.h
index fc9efd72d5..8c11ce35d2 100644
--- a/src/basic/btrfs-util.h
+++ b/src/basic/btrfs-util.h
@@ -56,7 +56,9 @@ typedef enum BtrfsRemoveFlags {
} BtrfsRemoveFlags;
int btrfs_is_filesystem(int fd);
-int btrfs_is_subvol(int fd);
+
+int btrfs_is_subvol_fd(int fd);
+int btrfs_is_subvol(const char *path);
int btrfs_reflink(int infd, int outfd);
int btrfs_clone_range(int infd, uint64_t in_offset, int ofd, uint64_t out_offset, uint64_t sz);
diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c
index 4109a08c6c..d88ceb40aa 100644
--- a/src/basic/hashmap.c
+++ b/src/basic/hashmap.c
@@ -380,7 +380,7 @@ static unsigned base_bucket_hash(HashmapBase *h, const void *p) {
h->hash_ops->hash(p, &state);
- siphash24_finalize((uint8_t*)&hash, &state);
+ siphash24_finalize(&hash, &state);
return (unsigned) (hash % n_buckets(h));
}
diff --git a/src/basic/siphash24.c b/src/basic/siphash24.c
index 3b61961389..d7640d395d 100644
--- a/src/basic/siphash24.c
+++ b/src/basic/siphash24.c
@@ -20,6 +20,7 @@
#include "sparse-endian.h"
#include "siphash24.h"
+#include "unaligned.h"
#include "util.h"
static inline uint64_t rotate_left(uint64_t x, uint8_t b) {
@@ -104,7 +105,7 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
end -= ( state->inlen % sizeof (uint64_t) );
for ( ; in < end; in += 8 ) {
- m = le64toh(*(le64_t*) in);
+ m = unaligned_read_le64(in);
#ifdef DEBUG
printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
@@ -140,7 +141,7 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
}
}
-void siphash24_finalize(uint8_t out[8], struct siphash *state) {
+void siphash24_finalize(uint64_t *out, struct siphash *state) {
uint64_t b;
b = state->padding | (( ( uint64_t )state->inlen ) << 56);
@@ -173,7 +174,7 @@ void siphash24_finalize(uint8_t out[8], struct siphash *state) {
}
/* SipHash-2-4 */
-void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) {
+void siphash24(uint64_t *out, const void *_in, size_t inlen, const uint8_t k[16]) {
struct siphash state;
siphash24_init(&state, k);
diff --git a/src/basic/siphash24.h b/src/basic/siphash24.h
index 6c5cd98ee8..dc08077d53 100644
--- a/src/basic/siphash24.h
+++ b/src/basic/siphash24.h
@@ -14,6 +14,6 @@ struct siphash {
void siphash24_init(struct siphash *state, const uint8_t k[16]);
void siphash24_compress(const void *in, size_t inlen, struct siphash *state);
-void siphash24_finalize(uint8_t out[8], struct siphash *state);
+void siphash24_finalize(uint64_t *out, struct siphash *state);
-void siphash24(uint8_t out[8], const void *in, size_t inlen, const uint8_t k[16]);
+void siphash24(uint64_t *out, const void *in, size_t inlen, const uint8_t k[16]);
diff --git a/src/basic/unaligned.h b/src/basic/unaligned.h
index d6181dd9a9..a8115eaa1f 100644
--- a/src/basic/unaligned.h
+++ b/src/basic/unaligned.h
@@ -21,8 +21,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <endian.h>
#include <stdint.h>
+/* BE */
+
static inline uint16_t unaligned_read_be16(const void *_u) {
const uint8_t *u = _u;
@@ -64,3 +67,47 @@ static inline void unaligned_write_be64(void *_u, uint64_t a) {
unaligned_write_be32(u, (uint32_t) (a >> 32));
unaligned_write_be32(u + 4, (uint32_t) a);
}
+
+/* LE */
+
+static inline uint16_t unaligned_read_le16(const void *_u) {
+ const uint8_t *u = _u;
+
+ return (((uint16_t) u[1]) << 8) |
+ ((uint16_t) u[0]);
+}
+
+static inline uint32_t unaligned_read_le32(const void *_u) {
+ const uint8_t *u = _u;
+
+ return (((uint32_t) unaligned_read_le16(u + 2)) << 16) |
+ ((uint32_t) unaligned_read_le16(u));
+}
+
+static inline uint64_t unaligned_read_le64(const void *_u) {
+ const uint8_t *u = _u;
+
+ return (((uint64_t) unaligned_read_le32(u + 4)) << 32) |
+ ((uint64_t) unaligned_read_le32(u));
+}
+
+static inline void unaligned_write_le16(void *_u, uint16_t a) {
+ uint8_t *u = _u;
+
+ u[0] = (uint8_t) a;
+ u[1] = (uint8_t) (a >> 8);
+}
+
+static inline void unaligned_write_le32(void *_u, uint32_t a) {
+ uint8_t *u = _u;
+
+ unaligned_write_le16(u, (uint16_t) a);
+ unaligned_write_le16(u + 2, (uint16_t) (a >> 16));
+}
+
+static inline void unaligned_write_le64(void *_u, uint64_t a) {
+ uint8_t *u = _u;
+
+ unaligned_write_le32(u, (uint32_t) a);
+ unaligned_write_le32(u + 4, (uint32_t) (a >> 32));
+}
diff --git a/src/import/pull-common.c b/src/import/pull-common.c
index d6567ba7ee..16b0c6160f 100644
--- a/src/import/pull-common.c
+++ b/src/import/pull-common.c
@@ -165,7 +165,7 @@ static int hash_url(const char *url, char **ret) {
assert(url);
- siphash24((uint8_t *) &h, url, strlen(url), k.bytes);
+ siphash24(&h, url, strlen(url), k.bytes);
if (asprintf(ret, "%"PRIx64, h) < 0)
return -ENOMEM;
diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c
index 434ddc8ac9..ad78d09294 100644
--- a/src/journal/journald-rate-limit.c
+++ b/src/journal/journald-rate-limit.c
@@ -162,7 +162,7 @@ static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r,
siphash24_init(&state, r->hash_key);
string_hash_func(g->id, &state);
- siphash24_finalize((uint8_t*)&g->hash, &state);
+ siphash24_finalize(&g->hash, &state);
journal_rate_limit_vacuum(r, ts);
@@ -230,7 +230,7 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u
siphash24_init(&state, r->hash_key);
string_hash_func(id, &state);
- siphash24_finalize((uint8_t*)&h, &state);
+ siphash24_finalize(&h, &state);
g = r->buckets[h % BUCKETS_MAX];
LIST_FOREACH(bucket, g, g)
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c
index 51ee7bcce4..368525c40a 100644
--- a/src/libsystemd-network/dhcp-identifier.c
+++ b/src/libsystemd-network/dhcp-identifier.c
@@ -35,6 +35,7 @@
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
sd_id128_t machine_id;
+ uint64_t hash;
int r;
assert(duid);
@@ -50,8 +51,9 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
*len = sizeof(duid->type) + sizeof(duid->en);
/* a bit of snake-oil perhaps, but no need to expose the machine-id
- directly */
- siphash24(duid->en.id, &machine_id, sizeof(machine_id), HASH_KEY.bytes);
+ directly; duid->en.id might not be aligned, so we need to copy */
+ siphash24(&hash, &machine_id, sizeof(machine_id), HASH_KEY.bytes);
+ memcpy(duid->en.id, &hash, sizeof(duid->en.id));
return 0;
}
@@ -84,10 +86,10 @@ int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_i
}
if (name)
- siphash24((uint8_t*)&id, name, strlen(name), HASH_KEY.bytes);
+ siphash24(&id, name, strlen(name), HASH_KEY.bytes);
else
/* fall back to MAC address if no predictable name available */
- siphash24((uint8_t*)&id, mac, mac_len, HASH_KEY.bytes);
+ siphash24(&id, mac, mac_len, HASH_KEY.bytes);
/* fold into 32 bits */
unaligned_write_be32(_id, (id & 0xffffffff) ^ (id >> 32));
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 52d76e443e..ab20b6065a 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -56,7 +56,7 @@ const char *net_get_name(struct udev_device *device) {
#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
-int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]) {
+int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result) {
size_t l, sz = 0;
const char *name = NULL;
int r;
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index d5d4ef42f2..d516f2dafd 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -62,7 +62,7 @@ int config_parse_ifalias(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
-int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]);
+int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result);
const char *net_get_name(struct udev_device *device);
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size);
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 8d0d9955c3..eeb59bb3da 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -753,7 +753,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
siphash24_init(&state, HASH_KEY.bytes);
client_id_hash_func(&req->client_id, &state);
- siphash24_finalize((uint8_t*)&hash, &state);
+ siphash24_finalize(&hash, &state);
next_offer = hash % server->pool_size;
for (i = 0; i < server->pool_size; i++) {
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
index 0d915e20e7..e69b1864d7 100644
--- a/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/libsystemd-network/sd-ipv4ll.c
@@ -143,15 +143,15 @@ int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) {
assert_return(ll, -EINVAL);
if (!ll->random_data) {
- uint8_t seed[8];
+ uint64_t seed;
/* If no random data is set, generate some from the MAC */
- siphash24(seed, &addr->ether_addr_octet,
+ siphash24(&seed, &addr->ether_addr_octet,
ETH_ALEN, HASH_KEY.bytes);
assert_cc(sizeof(unsigned) <= 8);
- r = sd_ipv4ll_set_address_seed(ll, *(unsigned*)seed);
+ r = sd_ipv4ll_set_address_seed(ll, (unsigned)seed);
if (r < 0)
return r;
}
diff --git a/src/libsystemd-network/test-dhcp-server.c b/src/libsystemd-network/test-dhcp-server.c
index 1a5c8c4605..62fdec46da 100644
--- a/src/libsystemd-network/test-dhcp-server.c
+++ b/src/libsystemd-network/test-dhcp-server.c
@@ -204,7 +204,7 @@ static uint64_t client_id_hash_helper(DHCPClientId *id, uint8_t key[HASH_KEY_SIZ
siphash24_init(&state, key);
client_id_hash_func(id, &state);
- siphash24_finalize((uint8_t*)&hash, &state);
+ siphash24_finalize(&hash, &state);
return hash;
}
diff --git a/src/libsystemd/sd-bus/bus-bloom.c b/src/libsystemd/sd-bus/bus-bloom.c
index 91fab90cb0..a592ff50cf 100644
--- a/src/libsystemd/sd-bus/bus-bloom.c
+++ b/src/libsystemd/sd-bus/bus-bloom.c
@@ -45,7 +45,7 @@ static void bloom_add_data(
const void *data, /* Data to hash */
size_t n) { /* Size of data to hash in bytes */
- uint8_t h[8];
+ uint64_t h;
uint64_t m;
unsigned w, i, c = 0;
unsigned hash_index;
@@ -72,11 +72,11 @@ static void bloom_add_data(
for (d = 0; d < w; d++) {
if (c <= 0) {
- siphash24(h, data, n, hash_keys[hash_index++].bytes);
+ siphash24(&h, data, n, hash_keys[hash_index++].bytes);
c += 8;
}
- p = (p << 8ULL) | (uint64_t) h[8 - c];
+ p = (p << 8ULL) | (uint64_t) ((uint8_t *)&h)[8 - c];
c--;
}
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index ed0d861e7a..506654b5d7 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -201,7 +201,7 @@ static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
}
int ipv4ll_configure(Link *link) {
- uint8_t seed[8];
+ uint64_t seed;
int r;
assert(link);
@@ -215,11 +215,11 @@ int ipv4ll_configure(Link *link) {
}
if (link->udev_device) {
- r = net_get_unique_predictable_data(link->udev_device, seed);
+ r = net_get_unique_predictable_data(link->udev_device, &seed);
if (r >= 0) {
assert_cc(sizeof(unsigned) <= 8);
- r = sd_ipv4ll_set_address_seed(link->ipv4ll, *(unsigned *)seed);
+ r = sd_ipv4ll_set_address_seed(link->ipv4ll, (unsigned)seed);
if (r < 0)
return r;
}
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index dd0b400c6a..081e299d82 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -411,7 +411,7 @@ int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *message) {
int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
_cleanup_free_ struct ether_addr *mac = NULL;
- uint8_t result[8];
+ uint64_t result;
size_t l, sz;
uint8_t *v;
int r;
@@ -438,10 +438,10 @@ int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
/* Let's hash the host machine ID plus the container name. We
* use a fixed, but originally randomly created hash key here. */
- siphash24(result, v, sz, HASH_KEY.bytes);
+ siphash24(&result, v, sz, HASH_KEY.bytes);
assert_cc(ETH_ALEN <= sizeof(result));
- memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+ memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
/* see eth_random_addr in the kernel */
mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */
diff --git a/src/nspawn/nspawn-network.c b/src/nspawn/nspawn-network.c
index c71552879d..92dfb945e0 100644
--- a/src/nspawn/nspawn-network.c
+++ b/src/nspawn/nspawn-network.c
@@ -47,7 +47,7 @@ static int generate_mac(
sd_id128_t hash_key,
uint64_t idx) {
- uint8_t result[8];
+ uint64_t result;
size_t l, sz;
uint8_t *v, *i;
int r;
@@ -74,10 +74,10 @@ static int generate_mac(
/* Let's hash the host machine ID plus the container name. We
* use a fixed, but originally randomly created hash key here. */
- siphash24(result, v, sz, hash_key.bytes);
+ siphash24(&result, v, sz, hash_key.bytes);
assert_cc(ETH_ALEN <= sizeof(result));
- memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+ memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
/* see eth_random_addr in the kernel */
mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */
diff --git a/src/test/test-siphash24.c b/src/test/test-siphash24.c
index 2402da6a6f..e5a989cdad 100644
--- a/src/test/test-siphash24.c
+++ b/src/test/test-siphash24.c
@@ -34,7 +34,7 @@ int main(int argc, char *argv[]) {
uint64_t out = 0;
unsigned i, j;
- siphash24((uint8_t *)&out, in, sizeof(in), key);
+ siphash24(&out, in, sizeof(in), key);
assert_se(out == htole64(0xa129ca6149be45e5));
/* verify the internal state as given in the above paper */
@@ -48,7 +48,7 @@ int main(int argc, char *argv[]) {
assert_se(state.v1 == 0x0d52f6f62a4f59a4);
assert_se(state.v2 == 0x634cb3577b01fd3d);
assert_se(state.v3 == 0xa5224d6f55c7d9c8);
- siphash24_finalize((uint8_t*)&out, &state);
+ siphash24_finalize(&out, &state);
assert_se(out == htole64(0xa129ca6149be45e5));
assert_se(state.v0 == 0xf6bcd53893fecff1);
assert_se(state.v1 == 0x54b9964c7ea0d937);
@@ -63,7 +63,7 @@ int main(int argc, char *argv[]) {
siphash24_compress(in, i, &state);
siphash24_compress(&in[i], j - i, &state);
siphash24_compress(&in[j], sizeof(in) - j, &state);
- siphash24_finalize((uint8_t*)&out, &state);
+ siphash24_finalize(&out, &state);
assert_se(out == htole64(0xa129ca6149be45e5));
}
}
diff --git a/src/test/test-unaligned.c b/src/test/test-unaligned.c
index 1754d06b2d..ec52db262c 100644
--- a/src/test/test-unaligned.c
+++ b/src/test/test-unaligned.c
@@ -26,7 +26,7 @@ static uint8_t data[] = {
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
-int main(int argc, const char *argv[]) {
+static void test_be(void) {
uint8_t scratch[16];
assert_se(unaligned_read_be16(&data[0]) == 0x0001);
@@ -91,3 +91,75 @@ int main(int argc, const char *argv[]) {
unaligned_write_be64(&scratch[7], 0x0708090a0b0c0d0e);
assert_se(memcmp(&scratch[7], &data[7], sizeof(uint64_t)) == 0);
}
+
+static void test_le(void) {
+ uint8_t scratch[16];
+
+ assert_se(unaligned_read_le16(&data[0]) == 0x0100);
+ assert_se(unaligned_read_le16(&data[1]) == 0x0201);
+
+ assert_se(unaligned_read_le32(&data[0]) == 0x03020100);
+ assert_se(unaligned_read_le32(&data[1]) == 0x04030201);
+ assert_se(unaligned_read_le32(&data[2]) == 0x05040302);
+ assert_se(unaligned_read_le32(&data[3]) == 0x06050403);
+
+ assert_se(unaligned_read_le64(&data[0]) == 0x0706050403020100);
+ assert_se(unaligned_read_le64(&data[1]) == 0x0807060504030201);
+ assert_se(unaligned_read_le64(&data[2]) == 0x0908070605040302);
+ assert_se(unaligned_read_le64(&data[3]) == 0x0a09080706050403);
+ assert_se(unaligned_read_le64(&data[4]) == 0x0b0a090807060504);
+ assert_se(unaligned_read_le64(&data[5]) == 0x0c0b0a0908070605);
+ assert_se(unaligned_read_le64(&data[6]) == 0x0d0c0b0a09080706);
+ assert_se(unaligned_read_le64(&data[7]) == 0x0e0d0c0b0a090807);
+
+ zero(scratch);
+ unaligned_write_le16(&scratch[0], 0x0100);
+ assert_se(memcmp(&scratch[0], &data[0], sizeof(uint16_t)) == 0);
+ zero(scratch);
+ unaligned_write_le16(&scratch[1], 0x0201);
+ assert_se(memcmp(&scratch[1], &data[1], sizeof(uint16_t)) == 0);
+
+ zero(scratch);
+ unaligned_write_le32(&scratch[0], 0x03020100);
+
+ assert_se(memcmp(&scratch[0], &data[0], sizeof(uint32_t)) == 0);
+ zero(scratch);
+ unaligned_write_le32(&scratch[1], 0x04030201);
+ assert_se(memcmp(&scratch[1], &data[1], sizeof(uint32_t)) == 0);
+ zero(scratch);
+ unaligned_write_le32(&scratch[2], 0x05040302);
+ assert_se(memcmp(&scratch[2], &data[2], sizeof(uint32_t)) == 0);
+ zero(scratch);
+ unaligned_write_le32(&scratch[3], 0x06050403);
+ assert_se(memcmp(&scratch[3], &data[3], sizeof(uint32_t)) == 0);
+
+ zero(scratch);
+ unaligned_write_le64(&scratch[0], 0x0706050403020100);
+ assert_se(memcmp(&scratch[0], &data[0], sizeof(uint64_t)) == 0);
+ zero(scratch);
+ unaligned_write_le64(&scratch[1], 0x0807060504030201);
+ assert_se(memcmp(&scratch[1], &data[1], sizeof(uint64_t)) == 0);
+ zero(scratch);
+ unaligned_write_le64(&scratch[2], 0x0908070605040302);
+ assert_se(memcmp(&scratch[2], &data[2], sizeof(uint64_t)) == 0);
+ zero(scratch);
+ unaligned_write_le64(&scratch[3], 0x0a09080706050403);
+ assert_se(memcmp(&scratch[3], &data[3], sizeof(uint64_t)) == 0);
+ zero(scratch);
+ unaligned_write_le64(&scratch[4], 0x0B0A090807060504);
+ assert_se(memcmp(&scratch[4], &data[4], sizeof(uint64_t)) == 0);
+ zero(scratch);
+ unaligned_write_le64(&scratch[5], 0x0c0b0a0908070605);
+ assert_se(memcmp(&scratch[5], &data[5], sizeof(uint64_t)) == 0);
+ zero(scratch);
+ unaligned_write_le64(&scratch[6], 0x0d0c0b0a09080706);
+ assert_se(memcmp(&scratch[6], &data[6], sizeof(uint64_t)) == 0);
+ zero(scratch);
+ unaligned_write_le64(&scratch[7], 0x0e0d0c0b0a090807);
+ assert_se(memcmp(&scratch[7], &data[7], sizeof(uint64_t)) == 0);
+}
+
+int main(int argc, const char *argv[]) {
+ test_be();
+ test_le();
+}
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 74b6b91593..f9a759e223 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -1226,8 +1226,28 @@ static int create_item(Item *i) {
mkdir_parents_label(i->path, 0755);
if (IN_SET(i->type, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) {
- RUN_WITH_UMASK((~i->mode) & 0777)
- r = btrfs_subvol_make(i->path);
+
+ if (btrfs_is_subvol(isempty(arg_root) ? "/" : arg_root) <= 0)
+
+ /* Don't create a subvolume unless the
+ * root directory is one, too. We do
+ * this under the assumption that if
+ * the root directory is just a plain
+ * directory (i.e. very light-weight),
+ * we shouldn't try to split it up
+ * into subvolumes (i.e. more
+ * heavy-weight). Thus, chroot()
+ * environments and suchlike will get
+ * a full brtfs subvolume set up below
+ * their tree only if they
+ * specifically set up a btrfs
+ * subvolume for the root dir too. */
+
+ r = -ENOTTY;
+ else {
+ RUN_WITH_UMASK((~i->mode) & 0777)
+ r = btrfs_subvol_make(i->path);
+ }
} else
r = 0;
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 776674e994..77d9bf995a 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -354,14 +354,14 @@ static int get_mac(struct udev_device *device, bool want_random,
if (want_random)
random_bytes(mac->ether_addr_octet, ETH_ALEN);
else {
- uint8_t result[8];
+ uint64_t result;
- r = net_get_unique_predictable_data(device, result);
+ r = net_get_unique_predictable_data(device, &result);
if (r < 0)
return r;
assert_cc(ETH_ALEN <= sizeof(result));
- memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+ memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
}
/* see eth_random_addr in the kernel */