package/systemd: fix build on mips32
authorFabrice Fontaine <fontaine.fabrice@gmail.com>
Tue, 29 Jan 2019 14:46:58 +0000 (15:46 +0100)
committerThomas Petazzoni <thomas.petazzoni@bootlin.com>
Mon, 4 Feb 2019 13:54:51 +0000 (14:54 +0100)
Fixes:
 - http://autobuild.buildroot.org/results/e484bc976266633029b26c8e21959ae4e9137da3

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Reviewed-by: Titouan Christophe <titouan.christophe@railnova.eu>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
package/systemd/0013-Pass-separate-dev_t-var-to-device_path_parse_major_minor.patch [new file with mode: 0644]

diff --git a/package/systemd/0013-Pass-separate-dev_t-var-to-device_path_parse_major_minor.patch b/package/systemd/0013-Pass-separate-dev_t-var-to-device_path_parse_major_minor.patch
new file mode 100644 (file)
index 0000000..eb7e0a2
--- /dev/null
@@ -0,0 +1,116 @@
+From f5855697aa19fb92637e72ab02e4623abe77f288 Mon Sep 17 00:00:00 2001
+From: YunQiang Su <syq@debian.org>
+Date: Tue, 25 Dec 2018 19:01:17 +0800
+Subject: [PATCH] Pass separate dev_t var to device_path_parse_major_minor
+
+MIPS/O32's st_rdev member of struct stat is unsigned long, which
+is 32bit, while dev_t is defined as 64bit, which make some problems
+in device_path_parse_major_minor.
+
+Don't pass st.st_rdev, st_mode to device_path_parse_major_minor,
+while pass 2 seperate variables. The result of stat is alos copied
+out into these 2 variables. Fixes: #11247
+
+[Retrieved from:
+https://github.com/systemd/systemd/commit/f5855697aa19fb92637e72ab02e4623abe77f288]
+Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+---
+ src/core/cgroup.c | 35 ++++++++++++++++++++++-------------
+ 1 file changed, 22 insertions(+), 13 deletions(-)
+
+diff --git a/src/core/cgroup.c b/src/core/cgroup.c
+index 7b817dc225e..ed2f331b33e 100644
+--- a/src/core/cgroup.c
++++ b/src/core/cgroup.c
+@@ -396,26 +396,31 @@ static void cgroup_xattr_apply(Unit *u) {
+ }
+ static int lookup_block_device(const char *p, dev_t *ret) {
+-        struct stat st = {};
++        dev_t rdev, dev = 0;
++        mode_t mode;
+         int r;
+         assert(p);
+         assert(ret);
+-        r = device_path_parse_major_minor(p, &st.st_mode, &st.st_rdev);
++        r = device_path_parse_major_minor(p, &mode, &rdev);
+         if (r == -ENODEV) { /* not a parsable device node, need to go to disk */
++                struct stat st;
+                 if (stat(p, &st) < 0)
+                         return log_warning_errno(errno, "Couldn't stat device '%s': %m", p);
++                rdev = (dev_t)st.st_rdev;
++                dev = (dev_t)st.st_dev;
++                mode = st.st_mode;
+         } else if (r < 0)
+                 return log_warning_errno(r, "Failed to parse major/minor from path '%s': %m", p);
+-        if (S_ISCHR(st.st_mode)) {
++        if (S_ISCHR(mode)) {
+                 log_warning("Device node '%s' is a character device, but block device needed.", p);
+                 return -ENOTBLK;
+-        } else if (S_ISBLK(st.st_mode))
+-                *ret = st.st_rdev;
+-        else if (major(st.st_dev) != 0)
+-                *ret = st.st_dev; /* If this is not a device node then use the block device this file is stored on */
++        } else if (S_ISBLK(mode))
++                *ret = rdev;
++        else if (major(dev) != 0)
++                *ret = dev; /* If this is not a device node then use the block device this file is stored on */
+         else {
+                 /* If this is btrfs, getting the backing block device is a bit harder */
+                 r = btrfs_get_block_device(p, ret);
+@@ -436,7 +441,8 @@ static int lookup_block_device(const char *p, dev_t *ret) {
+ }
+ static int whitelist_device(BPFProgram *prog, const char *path, const char *node, const char *acc) {
+-        struct stat st = {};
++        dev_t rdev;
++        mode_t mode;
+         int r;
+         assert(path);
+@@ -445,11 +451,12 @@ static int whitelist_device(BPFProgram *prog, const char *path, const char *node
+         /* Some special handling for /dev/block/%u:%u, /dev/char/%u:%u, /run/systemd/inaccessible/chr and
+          * /run/systemd/inaccessible/blk paths. Instead of stat()ing these we parse out the major/minor directly. This
+          * means clients can use these path without the device node actually around */
+-        r = device_path_parse_major_minor(node, &st.st_mode, &st.st_rdev);
++        r = device_path_parse_major_minor(node, &mode, &rdev);
+         if (r < 0) {
+                 if (r != -ENODEV)
+                         return log_warning_errno(r, "Couldn't parse major/minor from device path '%s': %m", node);
++                struct stat st;
+                 if (stat(node, &st) < 0)
+                         return log_warning_errno(errno, "Couldn't stat device %s: %m", node);
+@@ -457,22 +464,24 @@ static int whitelist_device(BPFProgram *prog, const char *path, const char *node
+                         log_warning("%s is not a device.", node);
+                         return -ENODEV;
+                 }
++                rdev = (dev_t) st.st_rdev;
++                mode = st.st_mode;
+         }
+         if (cg_all_unified() > 0) {
+                 if (!prog)
+                         return 0;
+-                return cgroup_bpf_whitelist_device(prog, S_ISCHR(st.st_mode) ? BPF_DEVCG_DEV_CHAR : BPF_DEVCG_DEV_BLOCK,
+-                                                   major(st.st_rdev), minor(st.st_rdev), acc);
++                return cgroup_bpf_whitelist_device(prog, S_ISCHR(mode) ? BPF_DEVCG_DEV_CHAR : BPF_DEVCG_DEV_BLOCK,
++                                                   major(rdev), minor(rdev), acc);
+         } else {
+                 char buf[2+DECIMAL_STR_MAX(dev_t)*2+2+4];
+                 sprintf(buf,
+                         "%c %u:%u %s",
+-                        S_ISCHR(st.st_mode) ? 'c' : 'b',
+-                        major(st.st_rdev), minor(st.st_rdev),
++                        S_ISCHR(mode) ? 'c' : 'b',
++                        major(rdev), minor(rdev),
+                         acc);
+                 /* Changing the devices list of a populated cgroup might result in EINVAL, hence ignore EINVAL here. */