[Buildroot] [PATCH 1/1] systemd: fix build on mips32

Titouan Christophe titouan.christophe at railnova.eu
Mon Feb 4 13:08:31 UTC 2019


Hi Fabrice,

On Tue, 2019-01-29 at 15:46 +0100, Fabrice Fontaine wrote:
> Fixes:
>  - http://autobuild.buildroot.org/results/e484bc976266633029b26c8e219
> 59ae4e9137da3
> 
> Signed-off-by: Fabrice Fontaine <fontaine.fabrice at gmail.com>

Reviewed-by: Titouan Christophe <titouan.christophe at railnova.eu>

> ---
>  ...ev_t-var-to-device_path_parse_major_minor.patch | 116
> +++++++++++++++++++++
>  1 file changed, 116 insertions(+)
>  create mode 100644 package/systemd/0013-Pass-separate-dev_t-var-to-
> device_path_parse_major_minor.patch
> 
> 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
> index 0000000000..eb7e0a2705
> --- /dev/null
> +++ b/package/systemd/0013-Pass-separate-dev_t-var-to-
> device_path_parse_major_minor.patch
> @@ -0,0 +1,116 @@
> +From f5855697aa19fb92637e72ab02e4623abe77f288 Mon Sep 17 00:00:00
> 2001
> +From: YunQiang Su <syq at 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/f5855697aa19fb92637e72ab02
> e4623abe77f288]
> +Signed-off-by: Fabrice Fontaine <fontaine.fabrice at 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. */

(Note for future us: this patch should land in systemd 241, currently
in the rc)

Have a nice monday !


More information about the buildroot mailing list