diff options
| author | Khem Raj <raj.khem@gmail.com> | 2017-04-19 19:31:47 -0700 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-05-11 16:59:18 +0100 |
| commit | 63bafcca5d4c0b5d6481f5f64fe2c9d1f3d9e6fe (patch) | |
| tree | 7c49d7aae8d946b0ebbdb826a17538c2193782e0 /meta/recipes-extended/mdadm | |
| parent | 7f5437ac91a66901d71828fe648a8a470af877a3 (diff) | |
| download | poky-63bafcca5d4c0b5d6481f5f64fe2c9d1f3d9e6fe.tar.gz | |
mdadm: Backport and make fixes for building with gcc7
(From OE-Core rev: c901af4574693ede5f1dcbccccc7c5a820b3d659)
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-extended/mdadm')
6 files changed, 337 insertions, 0 deletions
diff --git a/meta/recipes-extended/mdadm/files/0001-mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch b/meta/recipes-extended/mdadm/files/0001-mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch new file mode 100644 index 0000000000..ce15170c75 --- /dev/null +++ b/meta/recipes-extended/mdadm/files/0001-mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | From aa09af0fe2ec0737fa04ffd00957532684e257b9 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Xiao Ni <xni@redhat.com> | ||
| 3 | Date: Fri, 17 Mar 2017 19:55:42 +0800 | ||
| 4 | Subject: [PATCH 1/5] mdadm: Add Wimplicit-fallthrough=0 in Makefile | ||
| 5 | |||
| 6 | There are many errors like 'error: this statement may fall through'. | ||
| 7 | But the logic is right. So add the flag Wimplicit-fallthrough=0 | ||
| 8 | to disable the error messages. The method I use is from | ||
| 9 | https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html | ||
| 10 | #index-Wimplicit-fallthrough-375 | ||
| 11 | |||
| 12 | Signed-off-by: Xiao Ni <xni@redhat.com> | ||
| 13 | Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com> | ||
| 14 | --- | ||
| 15 | Upstream-Status: Backport | ||
| 16 | Makefile | 5 +++++ | ||
| 17 | 1 file changed, 5 insertions(+) | ||
| 18 | |||
| 19 | diff --git a/Makefile b/Makefile | ||
| 20 | index 0f307ec..e1a7058 100644 | ||
| 21 | --- a/Makefile | ||
| 22 | +++ b/Makefile | ||
| 23 | @@ -48,6 +48,11 @@ ifdef WARN_UNUSED | ||
| 24 | CWFLAGS += -Wp,-D_FORTIFY_SOURCE=2 -O3 | ||
| 25 | endif | ||
| 26 | |||
| 27 | +FALLTHROUGH := $(shell gcc -v --help 2>&1 | grep "implicit-fallthrough" | wc -l) | ||
| 28 | +ifneq "$(FALLTHROUGH)" "0" | ||
| 29 | +CWFLAGS += -Wimplicit-fallthrough=0 | ||
| 30 | +endif | ||
| 31 | + | ||
| 32 | ifdef DEBIAN | ||
| 33 | CPPFLAGS += -DDEBIAN | ||
| 34 | endif | ||
| 35 | -- | ||
| 36 | 2.12.2 | ||
| 37 | |||
diff --git a/meta/recipes-extended/mdadm/files/0002-mdadm-Specify-enough-length-when-write-to-buffer.patch b/meta/recipes-extended/mdadm/files/0002-mdadm-Specify-enough-length-when-write-to-buffer.patch new file mode 100644 index 0000000000..cbce053a3a --- /dev/null +++ b/meta/recipes-extended/mdadm/files/0002-mdadm-Specify-enough-length-when-write-to-buffer.patch | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | From bb4df273041ba206008bdb0ada75ccd97c29f623 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Xiao Ni <xni@redhat.com> | ||
| 3 | Date: Fri, 17 Mar 2017 19:55:43 +0800 | ||
| 4 | Subject: [PATCH 2/5] mdadm: Specify enough length when write to buffer | ||
| 5 | MIME-Version: 1.0 | ||
| 6 | Content-Type: text/plain; charset=UTF-8 | ||
| 7 | Content-Transfer-Encoding: 8bit | ||
| 8 | |||
| 9 | In Detail.c the buffer path in function Detail is defined as path[200], | ||
| 10 | in fact the max lenth of content which needs to write to the buffer is | ||
| 11 | 287. Because the length of dname of struct dirent is 255. | ||
| 12 | During building it reports error: | ||
| 13 | error: ā%sā directive writing up to 255 bytes into a region of size 189 | ||
| 14 | [-Werror=format-overflow=] | ||
| 15 | |||
| 16 | In function examine_super0 there is a buffer nb with length 5. | ||
| 17 | But it need to show a int type argument. The lenght of max | ||
| 18 | number of int is 10. So the buffer length should be 11. | ||
| 19 | |||
| 20 | In human_size function the length of buf is 30. During building | ||
| 21 | there is a error: | ||
| 22 | output between 20 and 47 bytes into a destination of size 30. | ||
| 23 | Change the length to 47. | ||
| 24 | |||
| 25 | Signed-off-by: Xiao Ni <xni@redhat.com> | ||
| 26 | Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com> | ||
| 27 | --- | ||
| 28 | Upstream-Status: Backport | ||
| 29 | Detail.c | 2 +- | ||
| 30 | super0.c | 2 +- | ||
| 31 | util.c | 2 +- | ||
| 32 | 3 files changed, 3 insertions(+), 3 deletions(-) | ||
| 33 | |||
| 34 | diff --git a/Detail.c b/Detail.c | ||
| 35 | index 509b0d4..cb33794 100644 | ||
| 36 | --- a/Detail.c | ||
| 37 | +++ b/Detail.c | ||
| 38 | @@ -575,7 +575,7 @@ This is pretty boring | ||
| 39 | printf(" Member Arrays :"); | ||
| 40 | |||
| 41 | while (dir && (de = readdir(dir)) != NULL) { | ||
| 42 | - char path[200]; | ||
| 43 | + char path[287]; | ||
| 44 | char vbuf[1024]; | ||
| 45 | int nlen = strlen(sra->sys_name); | ||
| 46 | dev_t devid; | ||
| 47 | diff --git a/super0.c b/super0.c | ||
| 48 | index 938cfd9..f5b4507 100644 | ||
| 49 | --- a/super0.c | ||
| 50 | +++ b/super0.c | ||
| 51 | @@ -231,7 +231,7 @@ static void examine_super0(struct supertype *st, char *homehost) | ||
| 52 | d++) { | ||
| 53 | mdp_disk_t *dp; | ||
| 54 | char *dv; | ||
| 55 | - char nb[5]; | ||
| 56 | + char nb[11]; | ||
| 57 | int wonly, failfast; | ||
| 58 | if (d>=0) dp = &sb->disks[d]; | ||
| 59 | else dp = &sb->this_disk; | ||
| 60 | diff --git a/util.c b/util.c | ||
| 61 | index f100972..32bd909 100644 | ||
| 62 | --- a/util.c | ||
| 63 | +++ b/util.c | ||
| 64 | @@ -811,7 +811,7 @@ unsigned long calc_csum(void *super, int bytes) | ||
| 65 | #ifndef MDASSEMBLE | ||
| 66 | char *human_size(long long bytes) | ||
| 67 | { | ||
| 68 | - static char buf[30]; | ||
| 69 | + static char buf[47]; | ||
| 70 | |||
| 71 | /* We convert bytes to either centi-M{ega,ibi}bytes or | ||
| 72 | * centi-G{igi,ibi}bytes, with appropriate rounding, | ||
| 73 | -- | ||
| 74 | 2.12.2 | ||
| 75 | |||
diff --git a/meta/recipes-extended/mdadm/files/0003-Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch b/meta/recipes-extended/mdadm/files/0003-Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch new file mode 100644 index 0000000000..dcec84ffcd --- /dev/null +++ b/meta/recipes-extended/mdadm/files/0003-Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | From bc87af1314325b00c6ac002a60a2b0f0caa81e34 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Xiao Ni <xni@redhat.com> | ||
| 3 | Date: Sat, 18 Mar 2017 10:33:44 +0800 | ||
| 4 | Subject: [PATCH 3/5] Replace snprintf with strncpy at some places to avoid | ||
| 5 | truncation | ||
| 6 | |||
| 7 | In gcc7 there are some building errors like: | ||
| 8 | directive output may be truncated writing up to 31 bytes into a region of size 24 | ||
| 9 | snprintf(str, MPB_SIG_LEN, %s, mpb->sig); | ||
| 10 | |||
| 11 | It just need to copy one string to target. So use strncpy to replace it. | ||
| 12 | |||
| 13 | For this line code: snprintf(str, MPB_SIG_LEN, %s, mpb->sig); | ||
| 14 | Because mpb->sig has the content of version after magic, so | ||
| 15 | it's better to use strncpy to replace snprintf too. | ||
| 16 | |||
| 17 | Signed-off-by: Xiao Ni <xni@redhat.com> | ||
| 18 | Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com> | ||
| 19 | --- | ||
| 20 | Upstream-Status: Backport | ||
| 21 | super-intel.c | 9 ++++++--- | ||
| 22 | 1 file changed, 6 insertions(+), 3 deletions(-) | ||
| 23 | |||
| 24 | diff --git a/super-intel.c b/super-intel.c | ||
| 25 | index 57c7e75..5499098 100644 | ||
| 26 | --- a/super-intel.c | ||
| 27 | +++ b/super-intel.c | ||
| 28 | @@ -1811,7 +1811,8 @@ static void examine_super_imsm(struct supertype *st, char *homehost) | ||
| 29 | __u32 reserved = imsm_reserved_sectors(super, super->disks); | ||
| 30 | struct dl *dl; | ||
| 31 | |||
| 32 | - snprintf(str, MPB_SIG_LEN, "%s", mpb->sig); | ||
| 33 | + strncpy(str, (char *)mpb->sig, MPB_SIG_LEN); | ||
| 34 | + str[MPB_SIG_LEN-1] = '\0'; | ||
| 35 | printf(" Magic : %s\n", str); | ||
| 36 | snprintf(str, strlen(MPB_VERSION_RAID0), "%s", get_imsm_version(mpb)); | ||
| 37 | printf(" Version : %s\n", get_imsm_version(mpb)); | ||
| 38 | @@ -7142,14 +7143,16 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, | ||
| 39 | |||
| 40 | u->type = update_rename_array; | ||
| 41 | u->dev_idx = vol; | ||
| 42 | - snprintf((char *) u->name, MAX_RAID_SERIAL_LEN, "%s", name); | ||
| 43 | + strncpy((char *) u->name, name, MAX_RAID_SERIAL_LEN); | ||
| 44 | + u->name[MAX_RAID_SERIAL_LEN-1] = '\0'; | ||
| 45 | append_metadata_update(st, u, sizeof(*u)); | ||
| 46 | } else { | ||
| 47 | struct imsm_dev *dev; | ||
| 48 | int i; | ||
| 49 | |||
| 50 | dev = get_imsm_dev(super, vol); | ||
| 51 | - snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, "%s", name); | ||
| 52 | + strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN); | ||
| 53 | + dev->volume[MAX_RAID_SERIAL_LEN-1] = '\0'; | ||
| 54 | for (i = 0; i < mpb->num_raid_devs; i++) { | ||
| 55 | dev = get_imsm_dev(super, i); | ||
| 56 | handle_missing(super, dev); | ||
| 57 | -- | ||
| 58 | 2.12.2 | ||
| 59 | |||
diff --git a/meta/recipes-extended/mdadm/files/0004-mdadm-Forced-type-conversion-to-avoid-truncation.patch b/meta/recipes-extended/mdadm/files/0004-mdadm-Forced-type-conversion-to-avoid-truncation.patch new file mode 100644 index 0000000000..94fde42e99 --- /dev/null +++ b/meta/recipes-extended/mdadm/files/0004-mdadm-Forced-type-conversion-to-avoid-truncation.patch | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | From 5da889032e2d99751ed9fe60016146e9ae8114cd Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Xiao Ni <xni@redhat.com> | ||
| 3 | Date: Sat, 18 Mar 2017 10:33:45 +0800 | ||
| 4 | Subject: [PATCH 4/5] mdadm: Forced type conversion to avoid truncation | ||
| 5 | |||
| 6 | Gcc reports it needs 19 bytes to right to disk->serial. Because the | ||
| 7 | type of argument i is int. But the meaning of i is failed disk | ||
| 8 | number. So it doesn't need to use 19 bytes. Just add a type | ||
| 9 | conversion to avoid this building error | ||
| 10 | |||
| 11 | Signed-off-by: Xiao Ni <xni@redhat.com> | ||
| 12 | Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com> | ||
| 13 | --- | ||
| 14 | Upstream-Status: Backport | ||
| 15 | super-intel.c | 2 +- | ||
| 16 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 17 | |||
| 18 | diff --git a/super-intel.c b/super-intel.c | ||
| 19 | index 5499098..4e466ff 100644 | ||
| 20 | --- a/super-intel.c | ||
| 21 | +++ b/super-intel.c | ||
| 22 | @@ -5228,7 +5228,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, | ||
| 23 | disk->status = CONFIGURED_DISK | FAILED_DISK; | ||
| 24 | disk->scsi_id = __cpu_to_le32(~(__u32)0); | ||
| 25 | snprintf((char *) disk->serial, MAX_RAID_SERIAL_LEN, | ||
| 26 | - "missing:%d", i); | ||
| 27 | + "missing:%d", (__u8)i); | ||
| 28 | } | ||
| 29 | find_missing(super); | ||
| 30 | } else { | ||
| 31 | -- | ||
| 32 | 2.12.2 | ||
| 33 | |||
diff --git a/meta/recipes-extended/mdadm/files/0005-Add-a-comment-to-indicate-valid-fallthrough.patch b/meta/recipes-extended/mdadm/files/0005-Add-a-comment-to-indicate-valid-fallthrough.patch new file mode 100644 index 0000000000..3d9d3b9044 --- /dev/null +++ b/meta/recipes-extended/mdadm/files/0005-Add-a-comment-to-indicate-valid-fallthrough.patch | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | From 09014233bf10900f7bd8390b3b64ff82bca45222 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Khem Raj <raj.khem@gmail.com> | ||
| 3 | Date: Wed, 19 Apr 2017 12:04:15 -0700 | ||
| 4 | Subject: [PATCH 5/5] Add a comment to indicate valid fallthrough | ||
| 5 | |||
| 6 | gcc7 warns about code with fallthroughs, this patch adds | ||
| 7 | the comment to indicate a valid fallthrough, helps gcc7 | ||
| 8 | compiler warnings | ||
| 9 | |||
| 10 | This works in cross and native compilation case | ||
| 11 | |||
| 12 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
| 13 | --- | ||
| 14 | Upstream-Status: Submitted | ||
| 15 | |||
| 16 | Grow.c | 4 ++++ | ||
| 17 | bitmap.c | 8 ++++++++ | ||
| 18 | mdadm.c | 2 ++ | ||
| 19 | super-intel.c | 1 + | ||
| 20 | util.c | 1 + | ||
| 21 | 5 files changed, 16 insertions(+) | ||
| 22 | |||
| 23 | diff --git a/Grow.c b/Grow.c | ||
| 24 | index 455c5f9..27c73b1 100755 | ||
| 25 | --- a/Grow.c | ||
| 26 | +++ b/Grow.c | ||
| 27 | @@ -1257,6 +1257,7 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) | ||
| 28 | switch (info->new_level) { | ||
| 29 | case 4: | ||
| 30 | delta_parity = 1; | ||
| 31 | + /* fallthrough */ | ||
| 32 | case 0: | ||
| 33 | re->level = 4; | ||
| 34 | re->before.layout = 0; | ||
| 35 | @@ -1284,10 +1285,12 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) | ||
| 36 | |||
| 37 | case 4: | ||
| 38 | info->array.layout = ALGORITHM_PARITY_N; | ||
| 39 | + /* fallthrough */ | ||
| 40 | case 5: | ||
| 41 | switch (info->new_level) { | ||
| 42 | case 0: | ||
| 43 | delta_parity = -1; | ||
| 44 | + /* fallthrough */ | ||
| 45 | case 4: | ||
| 46 | re->level = info->array.level; | ||
| 47 | re->before.data_disks = info->array.raid_disks - 1; | ||
| 48 | @@ -1343,6 +1346,7 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) | ||
| 49 | case 4: | ||
| 50 | case 5: | ||
| 51 | delta_parity = -1; | ||
| 52 | + /* fallthrough */ | ||
| 53 | case 6: | ||
| 54 | re->level = 6; | ||
| 55 | re->before.data_disks = info->array.raid_disks - 2; | ||
| 56 | diff --git a/bitmap.c b/bitmap.c | ||
| 57 | index ccedfd3..a6ff091 100644 | ||
| 58 | --- a/bitmap.c | ||
| 59 | +++ b/bitmap.c | ||
| 60 | @@ -82,13 +82,21 @@ static inline int count_dirty_bits_byte(char byte, int num_bits) | ||
| 61 | |||
| 62 | switch (num_bits) { /* fall through... */ | ||
| 63 | case 8: if (byte & 128) num++; | ||
| 64 | + /* fallthrough */ | ||
| 65 | case 7: if (byte & 64) num++; | ||
| 66 | + /* fallthrough */ | ||
| 67 | case 6: if (byte & 32) num++; | ||
| 68 | + /* fallthrough */ | ||
| 69 | case 5: if (byte & 16) num++; | ||
| 70 | + /* fallthrough */ | ||
| 71 | case 4: if (byte & 8) num++; | ||
| 72 | + /* fallthrough */ | ||
| 73 | case 3: if (byte & 4) num++; | ||
| 74 | + /* fallthrough */ | ||
| 75 | case 2: if (byte & 2) num++; | ||
| 76 | + /* fallthrough */ | ||
| 77 | case 1: if (byte & 1) num++; | ||
| 78 | + /* fallthrough */ | ||
| 79 | default: break; | ||
| 80 | } | ||
| 81 | |||
| 82 | diff --git a/mdadm.c b/mdadm.c | ||
| 83 | index c3a265b..2d06d3b 100644 | ||
| 84 | --- a/mdadm.c | ||
| 85 | +++ b/mdadm.c | ||
| 86 | @@ -148,6 +148,7 @@ int main(int argc, char *argv[]) | ||
| 87 | mode == CREATE || mode == GROW || | ||
| 88 | mode == INCREMENTAL || mode == MANAGE) | ||
| 89 | break; /* b means bitmap */ | ||
| 90 | + /* fallthrough */ | ||
| 91 | case Brief: | ||
| 92 | c.brief = 1; | ||
| 93 | continue; | ||
| 94 | @@ -828,6 +829,7 @@ int main(int argc, char *argv[]) | ||
| 95 | |||
| 96 | case O(INCREMENTAL,NoDegraded): | ||
| 97 | pr_err("--no-degraded is deprecated in Incremental mode\n"); | ||
| 98 | + /* fallthrough */ | ||
| 99 | case O(ASSEMBLE,NoDegraded): /* --no-degraded */ | ||
| 100 | c.runstop = -1; /* --stop isn't allowed for --assemble, | ||
| 101 | * so we overload slightly */ | ||
| 102 | diff --git a/super-intel.c b/super-intel.c | ||
| 103 | index 4e466ff..00a2925 100644 | ||
| 104 | --- a/super-intel.c | ||
| 105 | +++ b/super-intel.c | ||
| 106 | @@ -3271,6 +3271,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, | ||
| 107 | << SECT_PER_MB_SHIFT; | ||
| 108 | } | ||
| 109 | } | ||
| 110 | + /* fallthrough */ | ||
| 111 | case MIGR_VERIFY: | ||
| 112 | /* we could emulate the checkpointing of | ||
| 113 | * 'sync_action=check' migrations, but for now | ||
| 114 | diff --git a/util.c b/util.c | ||
| 115 | index 32bd909..f2a4d19 100644 | ||
| 116 | --- a/util.c | ||
| 117 | +++ b/util.c | ||
| 118 | @@ -335,6 +335,7 @@ unsigned long long parse_size(char *size) | ||
| 119 | switch (*c) { | ||
| 120 | case 'K': | ||
| 121 | c++; | ||
| 122 | + /* fallthrough */ | ||
| 123 | default: | ||
| 124 | s *= 2; | ||
| 125 | break; | ||
| 126 | -- | ||
| 127 | 2.12.2 | ||
| 128 | |||
diff --git a/meta/recipes-extended/mdadm/mdadm_4.0.bb b/meta/recipes-extended/mdadm/mdadm_4.0.bb index 62614f060f..98a10a8b15 100644 --- a/meta/recipes-extended/mdadm/mdadm_4.0.bb +++ b/meta/recipes-extended/mdadm/mdadm_4.0.bb | |||
| @@ -16,6 +16,11 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/utils/raid/mdadm/${BPN}-${PV}.tar.xz \ | |||
| 16 | file://run-ptest \ | 16 | file://run-ptest \ |
| 17 | file://0001-mdadm.h-Undefine-dprintf-before-redefining.patch \ | 17 | file://0001-mdadm.h-Undefine-dprintf-before-redefining.patch \ |
| 18 | file://0001-include-sys-sysmacros.h-for-major-minor-defintions.patch \ | 18 | file://0001-include-sys-sysmacros.h-for-major-minor-defintions.patch \ |
| 19 | file://0001-mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch \ | ||
| 20 | file://0002-mdadm-Specify-enough-length-when-write-to-buffer.patch \ | ||
| 21 | file://0003-Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch \ | ||
| 22 | file://0004-mdadm-Forced-type-conversion-to-avoid-truncation.patch \ | ||
| 23 | file://0005-Add-a-comment-to-indicate-valid-fallthrough.patch \ | ||
| 19 | " | 24 | " |
| 20 | SRC_URI[md5sum] = "2cb4feffea9167ba71b5f346a0c0a40d" | 25 | SRC_URI[md5sum] = "2cb4feffea9167ba71b5f346a0c0a40d" |
| 21 | SRC_URI[sha256sum] = "1d6ae7f24ced3a0fa7b5613b32f4a589bb4881e3946a5a2c3724056254ada3a9" | 26 | SRC_URI[sha256sum] = "1d6ae7f24ced3a0fa7b5613b32f4a589bb4881e3946a5a2c3724056254ada3a9" |
