diff --git a/SOURCES/0062-mdadm.8-add-note-information-for-raid0-growing-opera.patch b/SOURCES/0062-mdadm.8-add-note-information-for-raid0-growing-opera.patch new file mode 100644 index 0000000..ded44c0 --- /dev/null +++ b/SOURCES/0062-mdadm.8-add-note-information-for-raid0-growing-opera.patch @@ -0,0 +1,55 @@ +From 2551061c253b8fd45ee93d1aab3e91d2c7ac9c20 Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Mon, 24 Feb 2020 12:34:09 +0100 +Subject: [RHEL7.9 PATCH 62/77] mdadm.8: add note information for raid0 growing + operation + +When growing a raid0 device, if the new component disk size is not +big enough, the grow operation may fail due to lack of backup space. + +The minimum backup space should be larger than: + LCM(old, new) * chunk-size * 2 + +where LCM() is the least common multiple of the old and new count of +component disks, and "* 2" comes from the fact that mdadm refuses to +use more than half of a spare device for backup space. + +There are users reporting such failure when they grew a raid0 array +with small component disk. Neil Brown points out this is not a bug +and how the failure comes. This patch adds note information into +mdadm(8) man page in the Notes part of GROW MODE section to explain +the minimum size requirement of new component disk size or external +backup size. + +Reviewed-by: Petr Vorel +Cc: NeilBrown +Cc: Jes Sorensen +Cc: Paul Menzel +Cc: Wols Lists +Cc: Nix +Signed-off-by: Coly Li +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 5d00faf..a3494a1 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -2768,6 +2768,12 @@ option and it is transparent for assembly feature. + .IP \(bu 4 + Roaming between Windows(R) and Linux systems for IMSM metadata is not + supported during grow process. ++.IP \(bu 4 ++When growing a raid0 device, the new component disk size (or external ++backup size) should be larger than LCM(old, new) * chunk-size * 2, ++where LCM() is the least common multiple of the old and new count of ++component disks, and "* 2" comes from the fact that mdadm refuses to ++use more than half of a spare device for backup space. + + .SS SIZE CHANGES + Normally when an array is built the "size" is taken from the smallest +-- +2.7.5 + diff --git a/SOURCES/0062-Remove-the-legacy-whitespace.patch b/SOURCES/0063-Remove-the-legacy-whitespace.patch similarity index 69% rename from SOURCES/0062-Remove-the-legacy-whitespace.patch rename to SOURCES/0063-Remove-the-legacy-whitespace.patch index 31c764a..57890ee 100644 --- a/SOURCES/0062-Remove-the-legacy-whitespace.patch +++ b/SOURCES/0063-Remove-the-legacy-whitespace.patch @@ -1,15 +1,19 @@ -commit fd38b8ea80ff8e0317e12d1d70431148ceedd5fd -Author: Xiao Ni -Date: Tue Feb 11 21:44:15 2020 +0800 +From fd38b8ea80ff8e0317e12d1d70431148ceedd5fd Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Tue, 11 Feb 2020 21:44:15 +0800 +Subject: [RHEL7.9 PATCH 63/77] Remove the legacy whitespace - Remove the legacy whitespace - - The whitespace between Environment= and the true value causes confusion. - To avoid confusing other people in future, remove the whitespace to keep - it a simple, unambiguous syntax - - Signed-off-by: Xiao Ni - Signed-off-by: Jes Sorensen +The whitespace between Environment= and the true value causes confusion. +To avoid confusing other people in future, remove the whitespace to keep +it a simple, unambiguous syntax + +Signed-off-by: Xiao Ni +Signed-off-by: Jes Sorensen +--- + systemd/mdcheck_continue.service | 2 +- + systemd/mdcheck_start.service | 2 +- + systemd/mdmonitor-oneshot.service | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service index aa02dde..854317f 100644 @@ -50,3 +54,6 @@ index fd469b1..373955a 100644 EnvironmentFile=-/run/sysconfig/mdadm ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh ExecStart=BINDIR/mdadm --monitor --oneshot $MDADM_MONITOR_ARGS +-- +2.7.5 + diff --git a/SOURCES/0064-imsm-pass-subarray-id-to-kill_subarray-function.patch b/SOURCES/0064-imsm-pass-subarray-id-to-kill_subarray-function.patch new file mode 100644 index 0000000..9b9023b --- /dev/null +++ b/SOURCES/0064-imsm-pass-subarray-id-to-kill_subarray-function.patch @@ -0,0 +1,91 @@ +From 3364781b929f571a3dc3a6afed09eb1b03ce607c Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Wed, 19 Feb 2020 10:54:49 +0100 +Subject: [RHEL7.9 PATCH 64/77] imsm: pass subarray id to kill_subarray + function + +After patch b6180160f ("imsm: save current_vol number") +current_vol for imsm is not set and kill_subarray() +cannot determine which volume has to be deleted. +Volume has to be passed as "subarray_id". +The parameter affects only IMSM metadata. + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +--- + Kill.c | 2 +- + mdadm.h | 3 ++- + super-ddf.c | 2 +- + super-intel.c | 9 ++++----- + 4 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/Kill.c b/Kill.c +index d4767e2..bfd0efd 100644 +--- a/Kill.c ++++ b/Kill.c +@@ -119,7 +119,7 @@ int Kill_subarray(char *dev, char *subarray, int verbose) + st->update_tail = &st->updates; + + /* ok we've found our victim, drop the axe */ +- rv = st->ss->kill_subarray(st); ++ rv = st->ss->kill_subarray(st, subarray); + if (rv) { + if (verbose >= 0) + pr_err("Failed to delete subarray-%s from %s\n", +diff --git a/mdadm.h b/mdadm.h +index 9e98778..d94569f 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1038,7 +1038,8 @@ extern struct superswitch { + /* query the supertype for default geometry */ + void (*default_geometry)(struct supertype *st, int *level, int *layout, int *chunk); /* optional */ + /* Permit subarray's to be deleted from inactive containers */ +- int (*kill_subarray)(struct supertype *st); /* optional */ ++ int (*kill_subarray)(struct supertype *st, ++ char *subarray_id); /* optional */ + /* Permit subarray's to be modified */ + int (*update_subarray)(struct supertype *st, char *subarray, + char *update, struct mddev_ident *ident); /* optional */ +diff --git a/super-ddf.c b/super-ddf.c +index 7802063..7cd5702 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -4446,7 +4446,7 @@ static int _kill_subarray_ddf(struct ddf_super *ddf, const char *guid) + return 0; + } + +-static int kill_subarray_ddf(struct supertype *st) ++static int kill_subarray_ddf(struct supertype *st, char *subarray_id) + { + struct ddf_super *ddf = st->sb; + /* +diff --git a/super-intel.c b/super-intel.c +index 47809bc..e4d2122 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7600,18 +7600,17 @@ static void default_geometry_imsm(struct supertype *st, int *level, int *layout, + + static void handle_missing(struct intel_super *super, struct imsm_dev *dev); + +-static int kill_subarray_imsm(struct supertype *st) ++static int kill_subarray_imsm(struct supertype *st, char *subarray_id) + { +- /* remove the subarray currently referenced by ->current_vol */ ++ /* remove the subarray currently referenced by subarray_id */ + __u8 i; + struct intel_dev **dp; + struct intel_super *super = st->sb; +- __u8 current_vol = super->current_vol; ++ __u8 current_vol = strtoul(subarray_id, NULL, 10); + struct imsm_super *mpb = super->anchor; + +- if (super->current_vol < 0) ++ if (mpb->num_raid_devs == 0) + return 2; +- super->current_vol = -1; /* invalidate subarray cursor */ + + /* block deletions that would change the uuid of active subarrays + * +-- +2.7.5 + diff --git a/SOURCES/0065-imsm-Remove-dump-restore-implementation.patch b/SOURCES/0065-imsm-Remove-dump-restore-implementation.patch new file mode 100644 index 0000000..55cd2d7 --- /dev/null +++ b/SOURCES/0065-imsm-Remove-dump-restore-implementation.patch @@ -0,0 +1,91 @@ +From 45c43276d02a32876c7e1f9f0d04580595141b3d Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Wed, 19 Feb 2020 11:13:17 +0100 +Subject: [RHEL7.9 PATCH 65/77] imsm: Remove --dump/--restore implementation + +Functionalities --dump and --restore are not supported. +Remove dead code from imsm. + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +--- + super-intel.c | 56 -------------------------------------------------------- + 1 file changed, 56 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index e4d2122..c9a1af5 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2128,61 +2128,6 @@ static void export_examine_super_imsm(struct supertype *st) + printf("MD_DEVICES=%u\n", mpb->num_disks); + } + +-static int copy_metadata_imsm(struct supertype *st, int from, int to) +-{ +- /* The second last sector of the device contains +- * the "struct imsm_super" metadata. +- * This contains mpb_size which is the size in bytes of the +- * extended metadata. This is located immediately before +- * the imsm_super. +- * We want to read all that, plus the last sector which +- * may contain a migration record, and write it all +- * to the target. +- */ +- void *buf; +- unsigned long long dsize, offset; +- int sectors; +- struct imsm_super *sb; +- struct intel_super *super = st->sb; +- unsigned int sector_size = super->sector_size; +- unsigned int written = 0; +- +- if (posix_memalign(&buf, MAX_SECTOR_SIZE, MAX_SECTOR_SIZE) != 0) +- return 1; +- +- if (!get_dev_size(from, NULL, &dsize)) +- goto err; +- +- if (lseek64(from, dsize-(2*sector_size), 0) < 0) +- goto err; +- if ((unsigned int)read(from, buf, sector_size) != sector_size) +- goto err; +- sb = buf; +- if (strncmp((char*)sb->sig, MPB_SIGNATURE, MPB_SIG_LEN) != 0) +- goto err; +- +- sectors = mpb_sectors(sb, sector_size) + 2; +- offset = dsize - sectors * sector_size; +- if (lseek64(from, offset, 0) < 0 || +- lseek64(to, offset, 0) < 0) +- goto err; +- while (written < sectors * sector_size) { +- int n = sectors*sector_size - written; +- if (n > 4096) +- n = 4096; +- if (read(from, buf, n) != n) +- goto err; +- if (write(to, buf, n) != n) +- goto err; +- written += n; +- } +- free(buf); +- return 0; +-err: +- free(buf); +- return 1; +-} +- + static void detail_super_imsm(struct supertype *st, char *homehost, + char *subarray) + { +@@ -12270,7 +12215,6 @@ struct superswitch super_imsm = { + .reshape_super = imsm_reshape_super, + .manage_reshape = imsm_manage_reshape, + .recover_backup = recover_backup_imsm, +- .copy_metadata = copy_metadata_imsm, + .examine_badblocks = examine_badblocks_imsm, + .match_home = match_home_imsm, + .uuid_from_super= uuid_from_super_imsm, +-- +2.7.5 + diff --git a/SOURCES/0066-imsm-Correct-minimal-device-size.patch b/SOURCES/0066-imsm-Correct-minimal-device-size.patch new file mode 100644 index 0000000..377b7c7 --- /dev/null +++ b/SOURCES/0066-imsm-Correct-minimal-device-size.patch @@ -0,0 +1,32 @@ +From 06a6101c0a4d2658798dc42f461ace8e6900f840 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Wed, 11 Mar 2020 15:40:13 +0100 +Subject: [RHEL7.9 PATCH 66/77] imsm: Correct minimal device size. + +Check if given size of member drive is not less than 1 MibiByte. + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +--- + super-intel.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/super-intel.c b/super-intel.c +index c9a1af5..6680df2 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7425,7 +7425,10 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + verbose); + } + +- if (size && (size < 1024)) { ++ /* ++ * Size is given in sectors. ++ */ ++ if (size && (size < 2048)) { + pr_err("Given size must be greater than 1M.\n"); + /* Depends on algorithm in Create.c : + * if container was given (dev == NULL) return -1, +-- +2.7.5 + diff --git a/SOURCES/0067-Detail-show-correct-bitmap-info-for-cluster-raid-dev.patch b/SOURCES/0067-Detail-show-correct-bitmap-info-for-cluster-raid-dev.patch new file mode 100644 index 0000000..6fe3786 --- /dev/null +++ b/SOURCES/0067-Detail-show-correct-bitmap-info-for-cluster-raid-dev.patch @@ -0,0 +1,30 @@ +From 9e4494051de3f53228fabae56c116879bff5a0c8 Mon Sep 17 00:00:00 2001 +From: Lidong Zhong +Date: Mon, 16 Mar 2020 10:16:49 +0800 +Subject: [RHEL7.9 PATCH 67/77] Detail: show correct bitmap info for cluster + raid device + +Signed-off-by: Lidong Zhong +Signed-off-by: Jes Sorensen +--- + Detail.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Detail.c b/Detail.c +index 832485f..daec4f1 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -468,7 +468,9 @@ int Detail(char *dev, struct context *c) + if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) { + printf(" Intent Bitmap : %s\n", bmf.pathname); + printf("\n"); +- } else if (array.state & (1< +Date: Tue, 17 Mar 2020 10:20:12 +0100 +Subject: [RHEL7.9 PATCH 68/77] imsm: support the Array Creation Time field in + metadata + +Also present its value in --examine and --examine --export. + +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + super-intel.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 6680df2..8840fff 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -260,8 +260,9 @@ struct imsm_super { + * (starts at 1) + */ + __u16 filler1; /* 0x4E - 0x4F */ +-#define IMSM_FILLERS 34 +- __u32 filler[IMSM_FILLERS]; /* 0x50 - 0xD7 RAID_MPB_FILLERS */ ++ __u64 creation_time; /* 0x50 - 0x57 Array creation time */ ++#define IMSM_FILLERS 32 ++ __u32 filler[IMSM_FILLERS]; /* 0x58 - 0xD7 RAID_MPB_FILLERS */ + struct imsm_disk disk[1]; /* 0xD8 diskTbl[numDisks] */ + /* here comes imsm_dev[num_raid_devs] */ + /* here comes BBM logs */ +@@ -2014,6 +2015,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost) + __u32 sum; + __u32 reserved = imsm_reserved_sectors(super, super->disks); + struct dl *dl; ++ time_t creation_time; + + strncpy(str, (char *)mpb->sig, MPB_SIG_LEN); + str[MPB_SIG_LEN-1] = '\0'; +@@ -2022,6 +2024,9 @@ static void examine_super_imsm(struct supertype *st, char *homehost) + printf(" Orig Family : %08x\n", __le32_to_cpu(mpb->orig_family_num)); + printf(" Family : %08x\n", __le32_to_cpu(mpb->family_num)); + printf(" Generation : %08x\n", __le32_to_cpu(mpb->generation_num)); ++ creation_time = __le64_to_cpu(mpb->creation_time); ++ printf(" Creation Time : %.24s\n", ++ creation_time ? ctime(&creation_time) : "Unknown"); + printf(" Attributes : "); + if (imsm_check_attributes(mpb->attributes)) + printf("All supported\n"); +@@ -2126,6 +2131,7 @@ static void export_examine_super_imsm(struct supertype *st) + printf("MD_LEVEL=container\n"); + printf("MD_UUID=%s\n", nbuf+5); + printf("MD_DEVICES=%u\n", mpb->num_disks); ++ printf("MD_CREATION_TIME=%llu\n", __le64_to_cpu(mpb->creation_time)); + } + + static void detail_super_imsm(struct supertype *st, char *homehost, +@@ -5762,6 +5768,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, + sum += __gen_imsm_checksum(mpb); + mpb->family_num = __cpu_to_le32(sum); + mpb->orig_family_num = mpb->family_num; ++ mpb->creation_time = __cpu_to_le64((__u64)time(NULL)); + } + super->current_disk = dl; + return 0; +-- +2.7.5 + diff --git a/SOURCES/0069-imsm-show-Subarray-and-Volume-ID-in-examine-output.patch b/SOURCES/0069-imsm-show-Subarray-and-Volume-ID-in-examine-output.patch new file mode 100644 index 0000000..6d329bc --- /dev/null +++ b/SOURCES/0069-imsm-show-Subarray-and-Volume-ID-in-examine-output.patch @@ -0,0 +1,39 @@ +From ba1b3bc80ea555c288f1119e69d9273249967081 Mon Sep 17 00:00:00 2001 +From: Artur Paszkiewicz +Date: Tue, 17 Mar 2020 10:21:03 +0100 +Subject: [RHEL7.9 PATCH 69/77] imsm: show Subarray and Volume ID in --examine + output + +Show the index of the subarray as 'Subarray' and the value of the +my_vol_raid_dev_num field as 'Volume ID'. + +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + super-intel.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/super-intel.c b/super-intel.c +index 8840fff..562a58c 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1579,6 +1579,7 @@ static void print_imsm_dev(struct intel_super *super, + + printf("\n"); + printf("[%.16s]:\n", dev->volume); ++ printf(" Subarray : %d\n", super->current_vol); + printf(" UUID : %s\n", uuid); + printf(" RAID Level : %d", get_imsm_raid_level(map)); + if (map2) +@@ -1683,6 +1684,8 @@ static void print_imsm_dev(struct intel_super *super, + printf("Multiple PPLs on journaling drive\n"); + else + printf("\n", dev->rwh_policy); ++ ++ printf(" Volume ID : %u\n", dev->my_vol_raid_dev_num); + } + + static void print_imsm_disk(struct imsm_disk *disk, +-- +2.7.5 + diff --git a/SOURCES/0070-udev-Ignore-change-event-for-imsm.patch b/SOURCES/0070-udev-Ignore-change-event-for-imsm.patch new file mode 100644 index 0000000..c7ae249 --- /dev/null +++ b/SOURCES/0070-udev-Ignore-change-event-for-imsm.patch @@ -0,0 +1,35 @@ +From e1b92ee0de26576a33b20c9dd6ef6bd8cab8e283 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 8 Apr 2020 16:44:52 +0200 +Subject: [RHEL7.9 PATCH 70/77] udev: Ignore change event for imsm + +When adding a device to a container mdadm has to close its file +descriptor before sysfs_add_disk(). This generates change event. +There is race possibility because metadata is already written and other +-I process can place drive differently. As a result device can be added +to two containers simultaneously. +From IMSM perspective there is no need to react for change event. IMSM +doesn't support stacked devices. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + udev-md-raid-assembly.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules +index 9f055ed..d668cdd 100644 +--- a/udev-md-raid-assembly.rules ++++ b/udev-md-raid-assembly.rules +@@ -23,7 +23,7 @@ IMPORT{cmdline}="nodmraid" + ENV{nodmraid}=="?*", GOTO="md_inc_end" + ENV{ID_FS_TYPE}=="ddf_raid_member", GOTO="md_inc" + ENV{noiswmd}=="?*", GOTO="md_inc_end" +-ENV{ID_FS_TYPE}=="isw_raid_member", GOTO="md_inc" ++ENV{ID_FS_TYPE}=="isw_raid_member", ACTION!="change", GOTO="md_inc" + GOTO="md_inc_end" + + LABEL="md_inc" +-- +2.7.5 + diff --git a/SOURCES/0071-Monitor-improve-check_one_sharer-for-checking-duplic.patch b/SOURCES/0071-Monitor-improve-check_one_sharer-for-checking-duplic.patch new file mode 100644 index 0000000..7ded57c --- /dev/null +++ b/SOURCES/0071-Monitor-improve-check_one_sharer-for-checking-duplic.patch @@ -0,0 +1,109 @@ +From 185ec4397e61ad00dd68c841e15eaa8629eb9514 Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Sat, 11 Apr 2020 00:24:46 +0800 +Subject: [RHEL7.9 PATCH 71/77] Monitor: improve check_one_sharer() for + checking duplicated process + +When running mdadm monitor with scan mode, only one autorebuild process +is allowed. check_one_sharer() checks duplicated process by following +steps, +1) Read autorebuild.pid file, + - if file does not exist, no duplicated process, go to 3). + - if file exists, continue to next step. +2) Read pid number from autorebuild.pid file, then check procfs pid + directory /proc/, + - if the directory does not exist, no duplicated process, go to 3) + - if the directory exists, print error message for duplicated process + and exit this mdadm. +3) Write current pid into autorebuild.pid file, continue to monitor in + scan mode. + +The problem for the above step 2) is, if after system reboots and +another different process happens to have exact same pid number which +autorebuild.pid file records, check_one_sharer() will treat it as a +duplicated mdadm process and returns error with message "Only one +autorebuild process allowed in scan mode, aborting". + +This patch tries to fix the above same-pid-but-different-process issue +by one more step to check the process command name, +1) Read autorebuild.pid file + - if file does not exist, no duplicated process, go to 4). + - if file exists, continue to next step. +2) Read pid number from autorebuild.pid file, then check procfs file + comm with the specific pid directory /proc//comm + - if the file does not exit, it means the directory /proc/ does + not exist, go to 4) + - if the file exits, continue next step +3) Read process command name from /proc//comm, compare the command + name with "mdadm" process name, + - if not equal, no duplicated process, goto 4) + - if strings are equal, print error message for duplicated process + and exit this mdadm. +4) Write current pid into autorebuild.pid file, continue to monitor in + scan mode. + +Now check_one_sharer() returns error for duplicated process only when +the recorded pid from autorebuild.pid exists, and the process has exact +same command name as "mdadm". + +Reported-by: Shinkichi Yamazaki +Signed-off-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Monitor.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index b527165..2d6b3b9 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -301,26 +301,34 @@ static int make_daemon(char *pidfile) + + static int check_one_sharer(int scan) + { +- int pid, rv; ++ int pid; ++ FILE *comm_fp; + FILE *fp; +- char dir[20]; ++ char comm_path[100]; + char path[100]; +- struct stat buf; ++ char comm[20]; ++ + sprintf(path, "%s/autorebuild.pid", MDMON_DIR); + fp = fopen(path, "r"); + if (fp) { + if (fscanf(fp, "%d", &pid) != 1) + pid = -1; +- sprintf(dir, "/proc/%d", pid); +- rv = stat(dir, &buf); +- if (rv != -1) { +- if (scan) { +- pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); +- fclose(fp); +- return 1; +- } else { +- pr_err("Warning: One autorebuild process already running.\n"); ++ snprintf(comm_path, sizeof(comm_path), ++ "/proc/%d/comm", pid); ++ comm_fp = fopen(comm_path, "r"); ++ if (comm_fp) { ++ if (fscanf(comm_fp, "%s", comm) && ++ strncmp(basename(comm), Name, strlen(Name)) == 0) { ++ if (scan) { ++ pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); ++ fclose(comm_fp); ++ fclose(fp); ++ return 1; ++ } else { ++ pr_err("Warning: One autorebuild process already running.\n"); ++ } + } ++ fclose(comm_fp); + } + fclose(fp); + } +-- +2.7.5 + diff --git a/SOURCES/0072-Detail-adding-sync-status-for-cluster-device.patch b/SOURCES/0072-Detail-adding-sync-status-for-cluster-device.patch new file mode 100644 index 0000000..4b4faea --- /dev/null +++ b/SOURCES/0072-Detail-adding-sync-status-for-cluster-device.patch @@ -0,0 +1,85 @@ +From 1c294b5d960abeeb9e0f188af294d019bc82b20e Mon Sep 17 00:00:00 2001 +From: Lidong Zhong +Date: Tue, 14 Apr 2020 16:19:41 +0800 +Subject: [RHEL7.9 PATCH 72/77] Detail: adding sync status for cluster device + +On the node with /proc/mdstat is + +Personalities : [raid1] +md0 : active raid1 sdb[4] sdc[3] sdd[2] + 1046528 blocks super 1.2 [3/2] [UU_] + recover=REMOTE + bitmap: 1/1 pages [4KB], 65536KB chunk + +Let's change the 'State' of 'mdadm -Q -D' accordingly +State : clean, degraded +With this patch, it will be +State : clean, degraded, recovering (REMOTE) + +Signed-off-by: Lidong Zhong +Acked-by: Guoqing Jiang +Signed-off-by: Jes Sorensen +--- + Detail.c | 9 ++++++--- + mdadm.h | 3 ++- + mdstat.c | 2 ++ + 3 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/Detail.c b/Detail.c +index daec4f1..24eeba0 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -498,17 +498,20 @@ int Detail(char *dev, struct context *c) + } else + arrayst = "active"; + +- printf(" State : %s%s%s%s%s%s \n", ++ printf(" State : %s%s%s%s%s%s%s \n", + arrayst, st, + (!e || (e->percent < 0 && + e->percent != RESYNC_PENDING && +- e->percent != RESYNC_DELAYED)) ? ++ e->percent != RESYNC_DELAYED && ++ e->percent != RESYNC_REMOTE)) ? + "" : sync_action[e->resync], + larray_size ? "": ", Not Started", + (e && e->percent == RESYNC_DELAYED) ? + " (DELAYED)": "", + (e && e->percent == RESYNC_PENDING) ? +- " (PENDING)": ""); ++ " (PENDING)": "", ++ (e && e->percent == RESYNC_REMOTE) ? ++ " (REMOTE)": ""); + } else if (inactive && !is_container) { + printf(" State : inactive\n"); + } +diff --git a/mdadm.h b/mdadm.h +index d94569f..399478b 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1815,7 +1815,8 @@ enum r0layout { + #define RESYNC_NONE -1 + #define RESYNC_DELAYED -2 + #define RESYNC_PENDING -3 +-#define RESYNC_UNKNOWN -4 ++#define RESYNC_REMOTE -4 ++#define RESYNC_UNKNOWN -5 + + /* When using "GET_DISK_INFO" it isn't certain how high + * we need to check. So we impose an absolute limit of +diff --git a/mdstat.c b/mdstat.c +index 7e600d0..20577a3 100644 +--- a/mdstat.c ++++ b/mdstat.c +@@ -257,6 +257,8 @@ struct mdstat_ent *mdstat_read(int hold, int start) + ent->percent = RESYNC_DELAYED; + if (l > 8 && strcmp(w+l-8, "=PENDING") == 0) + ent->percent = RESYNC_PENDING; ++ if (l > 7 && strcmp(w+l-7, "=REMOTE") == 0) ++ ent->percent = RESYNC_REMOTE; + } else if (ent->percent == RESYNC_NONE && + w[0] >= '0' && + w[0] <= '9' && +-- +2.7.5 + diff --git a/SOURCES/0073-Manage-imsm-Write-metadata-before-add.patch b/SOURCES/0073-Manage-imsm-Write-metadata-before-add.patch new file mode 100644 index 0000000..463e9d8 --- /dev/null +++ b/SOURCES/0073-Manage-imsm-Write-metadata-before-add.patch @@ -0,0 +1,164 @@ +From 12724c018c964596aa277489fd287d5c3506361a Mon Sep 17 00:00:00 2001 +From: Tkaczyk Mariusz +Date: Fri, 17 Apr 2020 13:55:55 +0200 +Subject: [RHEL7.9 PATCH 73/77] Manage, imsm: Write metadata before add + +New drive in container always appears as spare. Manager is able to +handle that, and queues appropriative update to monitor. +No update from mdadm side has to be processed, just insert the drive and +ping the mdmon. Metadata has to be written if no mdmon is running (case +for Raid0 or container without arrays). + +If bare drive is added very early on startup (by custom bare rule), +there is possiblity that mdmon was not restarted after switch root. Old +one is not able to handle new drive. New one fails because there is +drive without metadata in container and metadata cannot be loaded. + +To prevent this, write spare metadata before adding device +to container. Mdmon will overwrite it (same case as spare migration, +if drive appears it writes the most recent metadata). +Metadata has to be written only on new drive before sysfs_add_disk(), +don't race with mdmon if running. + +Signed-off-by: Tkaczyk Mariusz +Signed-off-by: Jes Sorensen +--- + Manage.c | 6 +----- + super-intel.c | 66 ++++++++++++++++++++++++++++++++++++++--------------------- + 2 files changed, 44 insertions(+), 28 deletions(-) + +diff --git a/Manage.c b/Manage.c +index b22c396..0a5f09b 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -994,17 +994,13 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + + Kill(dv->devname, NULL, 0, -1, 0); + dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT); +- if (mdmon_running(tst->container_devnm)) +- tst->update_tail = &tst->updates; + if (tst->ss->add_to_super(tst, &disc, dfd, + dv->devname, INVALID_SECTORS)) { + close(dfd); + close(container_fd); + return -1; + } +- if (tst->update_tail) +- flush_metadata_updates(tst); +- else ++ if (!mdmon_running(tst->container_devnm)) + tst->ss->sync_metadata(tst); + + sra = sysfs_read(container_fd, NULL, 0); +diff --git a/super-intel.c b/super-intel.c +index 562a58c..3a73d2b 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -5809,6 +5809,9 @@ int mark_spare(struct dl *disk) + return ret_val; + } + ++ ++static int write_super_imsm_spare(struct intel_super *super, struct dl *d); ++ + static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk, + int fd, char *devname, + unsigned long long data_offset) +@@ -5938,9 +5941,13 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk, + dd->next = super->disk_mgmt_list; + super->disk_mgmt_list = dd; + } else { ++ /* this is called outside of mdmon ++ * write initial spare metadata ++ * mdmon will overwrite it. ++ */ + dd->next = super->disks; + super->disks = dd; +- super->updates_pending++; ++ write_super_imsm_spare(super, dd); + } + + return 0; +@@ -5979,15 +5986,15 @@ static union { + struct imsm_super anchor; + } spare_record __attribute__ ((aligned(MAX_SECTOR_SIZE))); + +-/* spare records have their own family number and do not have any defined raid +- * devices +- */ +-static int write_super_imsm_spares(struct intel_super *super, int doclose) ++ ++static int write_super_imsm_spare(struct intel_super *super, struct dl *d) + { + struct imsm_super *mpb = super->anchor; + struct imsm_super *spare = &spare_record.anchor; + __u32 sum; +- struct dl *d; ++ ++ if (d->index != -1) ++ return 1; + + spare->mpb_size = __cpu_to_le32(sizeof(struct imsm_super)); + spare->generation_num = __cpu_to_le32(1UL); +@@ -6000,28 +6007,41 @@ static int write_super_imsm_spares(struct intel_super *super, int doclose) + snprintf((char *) spare->sig, MAX_SIGNATURE_LENGTH, + MPB_SIGNATURE MPB_VERSION_RAID0); + +- for (d = super->disks; d; d = d->next) { +- if (d->index != -1) +- continue; ++ spare->disk[0] = d->disk; ++ if (__le32_to_cpu(d->disk.total_blocks_hi) > 0) ++ spare->attributes |= MPB_ATTRIB_2TB_DISK; + +- spare->disk[0] = d->disk; +- if (__le32_to_cpu(d->disk.total_blocks_hi) > 0) +- spare->attributes |= MPB_ATTRIB_2TB_DISK; ++ if (super->sector_size == 4096) ++ convert_to_4k_imsm_disk(&spare->disk[0]); + +- if (super->sector_size == 4096) +- convert_to_4k_imsm_disk(&spare->disk[0]); ++ sum = __gen_imsm_checksum(spare); ++ spare->family_num = __cpu_to_le32(sum); ++ spare->orig_family_num = 0; ++ sum = __gen_imsm_checksum(spare); ++ spare->check_sum = __cpu_to_le32(sum); + +- sum = __gen_imsm_checksum(spare); +- spare->family_num = __cpu_to_le32(sum); +- spare->orig_family_num = 0; +- sum = __gen_imsm_checksum(spare); +- spare->check_sum = __cpu_to_le32(sum); ++ if (store_imsm_mpb(d->fd, spare)) { ++ pr_err("failed for device %d:%d %s\n", ++ d->major, d->minor, strerror(errno)); ++ return 1; ++ } ++ ++ return 0; ++} ++/* spare records have their own family number and do not have any defined raid ++ * devices ++ */ ++static int write_super_imsm_spares(struct intel_super *super, int doclose) ++{ ++ struct dl *d; ++ ++ for (d = super->disks; d; d = d->next) { ++ if (d->index != -1) ++ continue; + +- if (store_imsm_mpb(d->fd, spare)) { +- pr_err("failed for device %d:%d %s\n", +- d->major, d->minor, strerror(errno)); ++ if (write_super_imsm_spare(super, d)) + return 1; +- } ++ + if (doclose) { + close(d->fd); + d->fd = -1; +-- +2.7.5 + diff --git a/SOURCES/0074-Assemble-print-error-message-if-mdadm-fails-assembli.patch b/SOURCES/0074-Assemble-print-error-message-if-mdadm-fails-assembli.patch new file mode 100644 index 0000000..7519aad --- /dev/null +++ b/SOURCES/0074-Assemble-print-error-message-if-mdadm-fails-assembli.patch @@ -0,0 +1,57 @@ +From 5cfb79dea26d9d7266f79c7c196a1a9f70c16a28 Mon Sep 17 00:00:00 2001 +From: Gioh Kim +Date: Tue, 16 Apr 2019 18:08:17 +0200 +Subject: [RHEL7.9 PATCH 74/77] Assemble: print error message if mdadm fails + assembling with --uuid option + +When mdadm tries to assemble one working device and one zeroed-out device, +it failed but print successful message because there is --uuid option. + +Following script always reproduce it. + +dd if=/dev/zero of=/dev/ram0 oflag=direct +dd if=/dev/zero of=/dev/ram1 oflag=direct +./mdadm -C /dev/md111 -e 1.2 --uuid="12345678:12345678:12345678:12345678" \ + -l1 -n2 /dev/ram0 /dev/ram1 +./mdadm -S /dev/md111 +dd if=/dev/zero of=/dev/ram1 oflag=direct +./mdadm -A /dev/md111 --uuid="12345678:12345678:12345678:12345678" \ + /dev/ram0 /dev/ram1 + +Following is message from mdadm. + +mdadm: No super block found on /dev/ram1 (Expected magic a92b4efc, got 00000000) +mdadm: no RAID superblock on /dev/ram1 +mdadm: /dev/md111 assembled from 1 drive - need all 2 to start it (use --run to insist). + +The mdadm say that it assembled but mdadm does not create /dev/md111. +The message is wrong. + +After applying this patch, mdadm reports error correctly as following. + +mdadm: No super block found on /dev/ram1 (Expected magic a92b4efc, got 00000000) +mdadm: no RAID superblock on /dev/ram1 +mdadm: /dev/ram1 has no superblock - assembly aborted + +Signed-off-by: Gioh Kim +Signed-off-by: Jes Sorensen +--- + Assemble.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Assemble.c b/Assemble.c +index 6b5a7c8..2ed5884 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -269,7 +269,7 @@ static int select_devices(struct mddev_dev *devlist, + if (auto_assem || !inargv) + /* Ignore unrecognised devices during auto-assembly */ + goto loop; +- if (ident->uuid_set || ident->name[0] || ++ if (ident->name[0] || + ident->super_minor != UnSet) + /* Ignore unrecognised device if looking for + * specific array */ +-- +2.7.5 + diff --git a/SOURCES/0075-clean-up-meaning-of-small-typo.patch b/SOURCES/0075-clean-up-meaning-of-small-typo.patch new file mode 100644 index 0000000..c5cd7f4 --- /dev/null +++ b/SOURCES/0075-clean-up-meaning-of-small-typo.patch @@ -0,0 +1,29 @@ +From ec7d7ceefc1c2b9ba82cac1ba0f6a34d41a4a913 Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Mon, 4 May 2020 12:27:45 -0400 +Subject: [RHEL7.9 PATCH 75/77] clean up meaning of small typo + +Clean up the typo which leads to wrong understanding. + +Signed-off-by: Nigel Croxon +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index a3494a1..9e7cb96 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -2878,7 +2878,7 @@ operation, as described below under LAYOUT CHANGES. + + .SS CHUNK-SIZE AND LAYOUT CHANGES + +-Changing the chunk-size of layout without also changing the number of ++Changing the chunk-size or layout without also changing the number of + devices as the same time will involve re-writing all blocks in-place. + To ensure against data loss in the case of a crash, a + .B --backup-file +-- +2.7.5 + diff --git a/SOURCES/0076-Assemble.c-respect-force-flag.patch b/SOURCES/0076-Assemble.c-respect-force-flag.patch new file mode 100644 index 0000000..44e825d --- /dev/null +++ b/SOURCES/0076-Assemble.c-respect-force-flag.patch @@ -0,0 +1,95 @@ +From 7b99edab2834d5d08ef774b4cff784caaa1a186f Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 5 May 2020 12:17:17 +0200 +Subject: [RHEL7.9 PATCH 76/77] Assemble.c: respect force flag. + +If the array is dirty handler will set resync_start to 0 to inform kernel +that resync is needed. RWH affects only raid456 module, for other +levels array will be started even array is degraded and resync cannot be +performed. + +Force is really meaningful for raid456. If array is degraded and resync +is requested, kernel will reject an attempt to start the array. To +respect force, it has to be marked as clean (this will be done for each +array without PPL) and remove the resync request (only for raid 456). +Data corruption may occur so proper warning is added. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Assemble.c | 51 ++++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 38 insertions(+), 13 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 2ed5884..3e5d4e6 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -2030,6 +2030,15 @@ int assemble_container_content(struct supertype *st, int mdfd, + free(avail); + return err; + } ++ } else if (c->force) { ++ /* Set the array as 'clean' so that we can proceed with starting ++ * it even if we don't have all devices. Mdmon doesn't care ++ * if the dirty flag is set in metadata, it will start managing ++ * it anyway. ++ * This is really important for raid456 (RWH case), other levels ++ * are started anyway. ++ */ ++ content->array.state |= 1; + } + + if (enough(content->array.level, content->array.raid_disks, +@@ -2049,20 +2058,36 @@ int assemble_container_content(struct supertype *st, int mdfd, + } + free(avail); + +- if (c->runstop <= 0 && +- (working + preexist + expansion) < +- content->array.working_disks) { +- if (c->export && result) +- *result |= INCR_UNSAFE; +- else if (c->verbose >= 0) { +- pr_err("%s assembled with %d device%s", +- chosen_name, preexist + working, +- preexist + working == 1 ? "":"s"); +- if (preexist) +- fprintf(stderr, " (%d new)", working); +- fprintf(stderr, " but not safe to start\n"); ++ if ((working + preexist + expansion) < content->array.working_disks) { ++ if (c->runstop <= 0) { ++ if (c->export && result) ++ *result |= INCR_UNSAFE; ++ else if (c->verbose >= 0) { ++ pr_err("%s assembled with %d device%s", ++ chosen_name, preexist + working, ++ preexist + working == 1 ? "":"s"); ++ if (preexist) ++ fprintf(stderr, " (%d new)", working); ++ fprintf(stderr, " but not safe to start\n"); ++ if (c->force) ++ pr_err("Consider --run to start array as degraded.\n"); ++ } ++ return 1; ++ } else if (content->array.level >= 4 && ++ content->array.level <= 6 && ++ content->resync_start != MaxSector && ++ c->force) { ++ /* Don't inform the kernel that the array is not ++ * clean and requires resync. ++ */ ++ content->resync_start = MaxSector; ++ err = sysfs_set_num(content, NULL, "resync_start", ++ MaxSector); ++ if (err) ++ return 1; ++ pr_err("%s array state forced to clean. It may cause data corruption.\n", ++ chosen_name); + } +- return 1; + } + + +-- +2.7.5 + diff --git a/SOURCES/0077-mdcheck-Log-when-done.patch b/SOURCES/0077-mdcheck-Log-when-done.patch new file mode 100644 index 0000000..d50c71a --- /dev/null +++ b/SOURCES/0077-mdcheck-Log-when-done.patch @@ -0,0 +1,45 @@ +From 3b7aae927bdb6e150d1aaf3aaf0d183a06abda0b Mon Sep 17 00:00:00 2001 +From: Donald Buczek +Date: Wed, 13 May 2020 15:16:46 +0200 +Subject: [RHEL7.9 PATCH 77/77] mdcheck: Log when done + +Currently mdcheck (when called with `--duration`) logs only the +beginning of the check, the pausing and the continuation but not the +completion. + +So, log the completion, too, so that it can be determined how long the +raid check took. + + 2020-05-08T18:00:02+02:00 deadpool root: mdcheck start checking /dev/md0 + 2020-05-08T18:00:02+02:00 deadpool root: mdcheck start checking /dev/md1 + 2020-05-09T15:32:04+02:00 deadpool root: mdcheck finished checking /dev/md1 + 2020-05-09T17:38:04+02:00 deadpool root: mdcheck finished checking /dev/md0 + +Cc: linux-raid@vger.kernel.org +Signed-off-by: Paul Menzel +Signed-off-by: Jes Sorensen +--- + misc/mdcheck | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/misc/mdcheck b/misc/mdcheck +index 42d4094..700c3e2 100644 +--- a/misc/mdcheck ++++ b/misc/mdcheck +@@ -125,11 +125,13 @@ do + do + eval fl=\$MD_${i}_fl + eval sys=\$MD_${i}_sys ++ eval dev=\$MD_${i}_dev + + if [ -z "$fl" ]; then continue; fi + + if [ "`cat $sys/md/sync_action`" != 'check' ] + then ++ logger -p daemon.info mdcheck finished checking $dev + eval MD_${i}_fl= + rm -f $fl + continue; +-- +2.7.5 + diff --git a/SPECS/mdadm.spec b/SPECS/mdadm.spec index 98733d2..19e6d8f 100644 --- a/SPECS/mdadm.spec +++ b/SPECS/mdadm.spec @@ -1,7 +1,7 @@ Summary: The mdadm program controls Linux md devices (software RAID arrays) Name: mdadm Version: 4.1 -Release: 13%{?dist} +Release: 14%{?dist} Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz Source1: mdmonitor.init Source2: raid-check @@ -75,7 +75,22 @@ Patch58: 0058-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch Patch59: 0059-imsm-Update-grow-manual.patch Patch60: 0060-Add-support-for-Tebibytes.patch Patch61: 0061-imsm-fill-working_disks-according-to-metadata.patch -Patch62: 0062-Remove-the-legacy-whitespace.patch +Patch62: 0062-mdadm.8-add-note-information-for-raid0-growing-opera.patch +Patch63: 0063-Remove-the-legacy-whitespace.patch +Patch64: 0064-imsm-pass-subarray-id-to-kill_subarray-function.patch +Patch65: 0065-imsm-Remove-dump-restore-implementation.patch +Patch66: 0066-imsm-Correct-minimal-device-size.patch +Patch67: 0067-Detail-show-correct-bitmap-info-for-cluster-raid-dev.patch +Patch68: 0068-imsm-support-the-Array-Creation-Time-field-in-metada.patch +Patch69: 0069-imsm-show-Subarray-and-Volume-ID-in-examine-output.patch +Patch70: 0070-udev-Ignore-change-event-for-imsm.patch +Patch71: 0071-Monitor-improve-check_one_sharer-for-checking-duplic.patch +Patch72: 0072-Detail-adding-sync-status-for-cluster-device.patch +Patch73: 0073-Manage-imsm-Write-metadata-before-add.patch +Patch74: 0074-Assemble-print-error-message-if-mdadm-fails-assembli.patch +Patch75: 0075-clean-up-meaning-of-small-typo.patch +Patch76: 0076-Assemble.c-respect-force-flag.patch +Patch77: 0077-mdcheck-Log-when-done.patch # RHEL customization patches Patch97: mdadm-3.3-udev.patch @@ -168,6 +183,21 @@ file can be used to help with some common tasks. %patch60 -p1 -b .0060 %patch61 -p1 -b .0061 %patch62 -p1 -b .0062 +%patch63 -p1 -b .0063 +%patch64 -p1 -b .0064 +%patch65 -p1 -b .0065 +%patch66 -p1 -b .0066 +%patch67 -p1 -b .0067 +%patch68 -p1 -b .0068 +%patch69 -p1 -b .0069 +%patch70 -p1 -b .0070 +%patch71 -p1 -b .0071 +%patch72 -p1 -b .0072 +%patch73 -p1 -b .0073 +%patch74 -p1 -b .0074 +%patch75 -p1 -b .0075 +%patch76 -p1 -b .0076 +%patch77 -p1 -b .0077 # RHEL customization patches %patch97 -p1 -b .udev @@ -239,6 +269,10 @@ rm -rf %{buildroot} /usr/lib/mdadm/mdadm_env.sh %changelog +* Fri Jun 05 2020 Xiao Ni - 4.1.14 +- Update to latest upstream +- Resolves rhbz#1780501 + * Fri Feb 28 2020 Xiao Ni - 4.1.13 - Remove the unnecessary whitespace in .service file - Resolves rhbz#1803470