forked from pool/grub2
Accepting request 1071066 from home:michael-chang:branches:Base:System
- Discard cached key from grub shell and editor mode * 0001-clean-up-crypttab-and-linux-modules-dependency.patch * 0002-discard-cached-key-before-entering-grub-shell-and-ed.patch - Make grub more robust against storage race condition causing system boot failures (bsc#1189036) * 0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch OBS-URL: https://build.opensuse.org/request/show/1071066 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=443
This commit is contained in:
parent
f6a335c91f
commit
d9083613d3
197
0001-clean-up-crypttab-and-linux-modules-dependency.patch
Normal file
197
0001-clean-up-crypttab-and-linux-modules-dependency.patch
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
From e9422d6869f1b2d78a7cfbfcae1610953d87705b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Chang <mchang@suse.com>
|
||||||
|
Date: Thu, 16 Feb 2023 21:28:07 +0800
|
||||||
|
Subject: [PATCH 1/2] clean up crypttab and linux modules dependency
|
||||||
|
|
||||||
|
The linux module could have quite a few dependency to other modules, the
|
||||||
|
i386-pc build in particular has many.
|
||||||
|
|
||||||
|
linux: normal vbe video boot cmdline relocator mmap
|
||||||
|
|
||||||
|
That will be easy to cause loop dependency if one of these modules has
|
||||||
|
to require function from linux. To avoid falling into the pitfall in
|
||||||
|
future extension, we move away the key publish related function from
|
||||||
|
linux to crypttab module in that it is also a right thing to do.
|
||||||
|
|
||||||
|
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||||
|
---
|
||||||
|
grub-core/commands/crypttab.c | 48 +++++++++++++++++++++++++++++-
|
||||||
|
grub-core/disk/cryptodisk.c | 2 +-
|
||||||
|
grub-core/loader/linux.c | 55 +----------------------------------
|
||||||
|
include/grub/crypttab.h | 22 ++++++++++++++
|
||||||
|
include/grub/linux.h | 3 --
|
||||||
|
5 files changed, 71 insertions(+), 59 deletions(-)
|
||||||
|
create mode 100644 include/grub/crypttab.h
|
||||||
|
|
||||||
|
--- a/grub-core/commands/crypttab.c
|
||||||
|
+++ b/grub-core/commands/crypttab.c
|
||||||
|
@@ -3,10 +3,52 @@
|
||||||
|
#include <grub/command.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
-#include <grub/linux.h>
|
||||||
|
+#include <grub/mm.h>
|
||||||
|
+#include <grub/list.h>
|
||||||
|
+#include <grub/crypttab.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
+struct grub_key_publisher *kpuber;
|
||||||
|
+
|
||||||
|
+grub_err_t
|
||||||
|
+grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path)
|
||||||
|
+{
|
||||||
|
+ struct grub_key_publisher *cur = grub_named_list_find (GRUB_AS_NAMED_LIST (kpuber), uuid);
|
||||||
|
+
|
||||||
|
+ if (!cur)
|
||||||
|
+ cur = grub_zalloc (sizeof (*cur));
|
||||||
|
+ if (!cur)
|
||||||
|
+ return grub_errno;
|
||||||
|
+
|
||||||
|
+ if (key && key_len)
|
||||||
|
+ {
|
||||||
|
+ grub_free (cur->key);
|
||||||
|
+ cur->key = grub_malloc (key_len);
|
||||||
|
+ if (!cur->key)
|
||||||
|
+ {
|
||||||
|
+ grub_free (cur);
|
||||||
|
+ return grub_errno;
|
||||||
|
+ }
|
||||||
|
+ grub_memcpy (cur->key, key, key_len);
|
||||||
|
+ cur->key_len = key_len;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (path)
|
||||||
|
+ {
|
||||||
|
+ grub_free (cur->path);
|
||||||
|
+ cur->path = grub_strdup (path);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!cur->name)
|
||||||
|
+ {
|
||||||
|
+ cur->name = grub_strdup (uuid);
|
||||||
|
+ grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return GRUB_ERR_NONE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char **argv)
|
||||||
|
--- a/grub-core/disk/cryptodisk.c
|
||||||
|
+++ b/grub-core/disk/cryptodisk.c
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
#ifdef GRUB_UTIL
|
||||||
|
#include <grub/emu/hostdisk.h>
|
||||||
|
#else
|
||||||
|
-#include <grub/linux.h>
|
||||||
|
+#include <grub/crypttab.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
--- a/grub-core/loader/linux.c
|
||||||
|
+++ b/grub-core/loader/linux.c
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
#include <grub/list.h>
|
||||||
|
+#include <grub/crypttab.h>
|
||||||
|
|
||||||
|
struct newc_head
|
||||||
|
{
|
||||||
|
@@ -40,18 +41,6 @@
|
||||||
|
struct dir *child;
|
||||||
|
};
|
||||||
|
|
||||||
|
-struct grub_key_publisher
|
||||||
|
-{
|
||||||
|
- struct grub_key_publisher *next;
|
||||||
|
- struct grub_key_publisher **prev;
|
||||||
|
- char *name; /* UUID */
|
||||||
|
- char *path;
|
||||||
|
- char *key;
|
||||||
|
- grub_size_t key_len;
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static struct grub_key_publisher *kpuber;
|
||||||
|
-
|
||||||
|
static char
|
||||||
|
hex (grub_uint8_t val)
|
||||||
|
{
|
||||||
|
@@ -423,41 +412,3 @@
|
||||||
|
root = 0;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
-grub_err_t
|
||||||
|
-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path)
|
||||||
|
-{
|
||||||
|
- struct grub_key_publisher *cur = grub_named_list_find (GRUB_AS_NAMED_LIST (kpuber), uuid);
|
||||||
|
-
|
||||||
|
- if (!cur)
|
||||||
|
- cur = grub_zalloc (sizeof (*cur));
|
||||||
|
- if (!cur)
|
||||||
|
- return grub_errno;
|
||||||
|
-
|
||||||
|
- if (key && key_len)
|
||||||
|
- {
|
||||||
|
- grub_free (cur->key);
|
||||||
|
- cur->key = grub_malloc (key_len);
|
||||||
|
- if (!cur->key)
|
||||||
|
- {
|
||||||
|
- grub_free (cur);
|
||||||
|
- return grub_errno;
|
||||||
|
- }
|
||||||
|
- grub_memcpy (cur->key, key, key_len);
|
||||||
|
- cur->key_len = key_len;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (path)
|
||||||
|
- {
|
||||||
|
- grub_free (cur->path);
|
||||||
|
- cur->path = grub_strdup (path);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!cur->name)
|
||||||
|
- {
|
||||||
|
- cur->name = grub_strdup (uuid);
|
||||||
|
- grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return GRUB_ERR_NONE;
|
||||||
|
-}
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/grub/crypttab.h
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+#ifndef GRUB_CRYPTTAB_HEADER
|
||||||
|
+#define GRUB_CRYPTTAB_HEADER 1
|
||||||
|
+
|
||||||
|
+#include <grub/types.h>
|
||||||
|
+#include <grub/err.h>
|
||||||
|
+
|
||||||
|
+struct grub_key_publisher
|
||||||
|
+{
|
||||||
|
+ struct grub_key_publisher *next;
|
||||||
|
+ struct grub_key_publisher **prev;
|
||||||
|
+ char *name; /* UUID */
|
||||||
|
+ char *path;
|
||||||
|
+ char *key;
|
||||||
|
+ grub_size_t key_len;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+extern struct grub_key_publisher *EXPORT_VAR (kpuber);
|
||||||
|
+
|
||||||
|
+grub_err_t
|
||||||
|
+grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path);
|
||||||
|
+
|
||||||
|
+#endif /* ! GRUB_CRYPTTAB_HEADER */
|
||||||
|
--- a/include/grub/linux.h
|
||||||
|
+++ b/include/grub/linux.h
|
||||||
|
@@ -22,6 +22,3 @@
|
||||||
|
grub_err_t
|
||||||
|
grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
|
||||||
|
char *argv[], void *target);
|
||||||
|
-
|
||||||
|
-grub_err_t
|
||||||
|
-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path);
|
126
0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch
Normal file
126
0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
From b99c45820f228ff5b881700eda95a017abf2e198 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mukesh Kumar Chaurasiya <mchauras@linux.vnet.ibm.com>
|
||||||
|
Date: Wed, 1 Mar 2023 15:08:05 +0530
|
||||||
|
Subject: [PATCH] ieee1275/ofdisk: retry on open and read failure
|
||||||
|
|
||||||
|
Sometimes, when booting from a very busy SAN, the access to the
|
||||||
|
disk can fail and then grub will eventually drop to grub prompt.
|
||||||
|
This scenario is more frequent when deploying many machines at
|
||||||
|
the same time using the same SAN.
|
||||||
|
This patch aims to force the ofdisk module to retry the open or
|
||||||
|
read function after it fails. We use MAX_RETRIES to specify the
|
||||||
|
amount of times it will try to access the disk before it
|
||||||
|
definitely fails.
|
||||||
|
|
||||||
|
Signed-off-by: Mukesh Kumar Chaurasiya <mchauras@linux.vnet.ibm.com>
|
||||||
|
---
|
||||||
|
grub-core/disk/ieee1275/ofdisk.c | 65 +++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 63 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||||
|
index c6cba0c8a..f4183a531 100644
|
||||||
|
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||||
|
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||||
|
@@ -24,6 +24,9 @@
|
||||||
|
#include <grub/ieee1275/ofdisk.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
+#include <grub/env.h>
|
||||||
|
+
|
||||||
|
+#define RETRY_DEFAULT_TIMEOUT 15000
|
||||||
|
|
||||||
|
static char *last_devpath;
|
||||||
|
static grub_ieee1275_ihandle_t last_ihandle;
|
||||||
|
@@ -452,7 +455,7 @@ compute_dev_path (const char *name)
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
-grub_ofdisk_open (const char *name, grub_disk_t disk)
|
||||||
|
+grub_ofdisk_open_real (const char *name, grub_disk_t disk)
|
||||||
|
{
|
||||||
|
grub_ieee1275_phandle_t dev;
|
||||||
|
char *devpath;
|
||||||
|
@@ -525,6 +528,41 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static grub_uint64_t
|
||||||
|
+grub_ofdisk_disk_timeout(void)
|
||||||
|
+{
|
||||||
|
+ if(grub_env_get("ofdisk_retry_timeout") != NULL)
|
||||||
|
+ {
|
||||||
|
+ grub_uint64_t retry = grub_strtoul(grub_env_get("ofdisk_retry_timeout"), 0, 10);
|
||||||
|
+ if(retry)
|
||||||
|
+ return retry;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return RETRY_DEFAULT_TIMEOUT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static grub_err_t
|
||||||
|
+grub_ofdisk_open (const char *name, grub_disk_t disk)
|
||||||
|
+{
|
||||||
|
+ grub_err_t err;
|
||||||
|
+ grub_uint64_t timeout = grub_get_time_ms () + grub_ofdisk_disk_timeout();
|
||||||
|
+
|
||||||
|
+ retry:
|
||||||
|
+ err = grub_ofdisk_open_real (name, disk);
|
||||||
|
+
|
||||||
|
+ if (err == GRUB_ERR_UNKNOWN_DEVICE)
|
||||||
|
+ {
|
||||||
|
+ if (grub_get_time_ms () < timeout)
|
||||||
|
+ {
|
||||||
|
+ grub_dprintf ("ofdisk","Failed to open disk %s. Retrying...\n", name);
|
||||||
|
+ grub_errno = GRUB_ERR_NONE;
|
||||||
|
+ goto retry;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
grub_ofdisk_close (grub_disk_t disk)
|
||||||
|
{
|
||||||
|
@@ -568,7 +606,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector)
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
-grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
+grub_ofdisk_read_real (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
grub_size_t size, char *buf)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
@@ -587,6 +625,29 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static grub_err_t
|
||||||
|
+grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
+ grub_size_t size, char *buf)
|
||||||
|
+{
|
||||||
|
+ grub_err_t err;
|
||||||
|
+ grub_uint64_t timeout = grub_get_time_ms () + grub_ofdisk_disk_timeout();
|
||||||
|
+
|
||||||
|
+ retry:
|
||||||
|
+ err = grub_ofdisk_read_real (disk, sector, size, buf);
|
||||||
|
+
|
||||||
|
+ if (err == GRUB_ERR_READ_ERROR)
|
||||||
|
+ {
|
||||||
|
+ if (grub_get_time_ms () < timeout)
|
||||||
|
+ {
|
||||||
|
+ grub_dprintf ("ofdisk","Failed to read disk %s. Retrying...\n", (char*)disk->data);
|
||||||
|
+ grub_errno = GRUB_ERR_NONE;
|
||||||
|
+ goto retry;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static grub_err_t
|
||||||
|
grub_ofdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
grub_size_t size, const char *buf)
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
@ -0,0 +1,88 @@
|
|||||||
|
From 2271da7522d8406c528d2a9079d810e140f8041a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Chang <mchang@suse.com>
|
||||||
|
Date: Fri, 3 Feb 2023 19:40:31 +0800
|
||||||
|
Subject: [PATCH 2/2] discard cached key before entering grub shell and editor
|
||||||
|
mode
|
||||||
|
|
||||||
|
The cached key is cleared in case of anyone poking around it by means of
|
||||||
|
the interactive shell offerings.
|
||||||
|
|
||||||
|
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||||
|
---
|
||||||
|
grub-core/commands/crypttab.c | 16 ++++++++++++++++
|
||||||
|
grub-core/normal/main.c | 2 ++
|
||||||
|
grub-core/normal/menu_entry.c | 3 +++
|
||||||
|
include/grub/crypttab.h | 2 ++
|
||||||
|
4 files changed, 23 insertions(+)
|
||||||
|
|
||||||
|
--- a/grub-core/commands/crypttab.c
|
||||||
|
+++ b/grub-core/commands/crypttab.c
|
||||||
|
@@ -49,6 +49,22 @@
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+grub_initrd_discard_key (void)
|
||||||
|
+{
|
||||||
|
+ struct grub_key_publisher *cur, *nxt;
|
||||||
|
+
|
||||||
|
+ FOR_LIST_ELEMENTS_SAFE (cur, nxt, kpuber)
|
||||||
|
+ {
|
||||||
|
+ grub_list_remove (GRUB_AS_LIST (cur));
|
||||||
|
+ grub_memset (cur->key, 0, cur->key_len);
|
||||||
|
+ grub_free (cur->name);
|
||||||
|
+ grub_free (cur->path);
|
||||||
|
+ grub_free (cur->key);
|
||||||
|
+ grub_free (cur);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char **argv)
|
||||||
|
--- a/grub-core/normal/main.c
|
||||||
|
+++ b/grub-core/normal/main.c
|
||||||
|
@@ -37,6 +37,7 @@
|
||||||
|
#ifdef GRUB_MACHINE_IEEE1275
|
||||||
|
#include <grub/ieee1275/ieee1275.h>
|
||||||
|
#endif
|
||||||
|
+#include <grub/crypttab.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@@ -477,6 +478,7 @@
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ grub_initrd_discard_key ();
|
||||||
|
grub_normal_reader_init (nested);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
--- a/grub-core/normal/menu_entry.c
|
||||||
|
+++ b/grub-core/normal/menu_entry.c
|
||||||
|
@@ -28,6 +28,7 @@
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/charset.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
+#include <grub/crypttab.h>
|
||||||
|
|
||||||
|
enum update_mode
|
||||||
|
{
|
||||||
|
@@ -1262,6 +1263,8 @@
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ grub_initrd_discard_key();
|
||||||
|
+
|
||||||
|
screen = make_screen (entry);
|
||||||
|
if (! screen)
|
||||||
|
return;
|
||||||
|
--- a/include/grub/crypttab.h
|
||||||
|
+++ b/include/grub/crypttab.h
|
||||||
|
@@ -19,4 +19,6 @@
|
||||||
|
grub_err_t
|
||||||
|
grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path);
|
||||||
|
|
||||||
|
+void
|
||||||
|
+grub_initrd_discard_key (void);
|
||||||
|
#endif /* ! GRUB_CRYPTTAB_HEADER */
|
@ -1,3 +1,17 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Mar 6 06:31:09 UTC 2023 - Michael Chang <mchang@suse.com>
|
||||||
|
|
||||||
|
- Discard cached key from grub shell and editor mode
|
||||||
|
* 0001-clean-up-crypttab-and-linux-modules-dependency.patch
|
||||||
|
* 0002-discard-cached-key-before-entering-grub-shell-and-ed.patch
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Mar 3 07:48:56 UTC 2023 - Michael Chang <mchang@suse.com>
|
||||||
|
|
||||||
|
- Make grub more robust against storage race condition causing system boot
|
||||||
|
failures (bsc#1189036)
|
||||||
|
* 0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Mar 1 02:58:07 UTC 2023 - Michael Chang <mchang@suse.com>
|
Wed Mar 1 02:58:07 UTC 2023 - Michael Chang <mchang@suse.com>
|
||||||
|
|
||||||
|
@ -498,6 +498,10 @@ Patch970: grub2-add-module-for-boot-loader-interface.patch
|
|||||||
Patch971: 0001-ieee1275-Further-increase-initially-allocated-heap-f.patch
|
Patch971: 0001-ieee1275-Further-increase-initially-allocated-heap-f.patch
|
||||||
Patch972: 0002-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch
|
Patch972: 0002-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch
|
||||||
Patch973: 0001-RISC-V-Handle-R_RISCV_CALL_PLT-reloc.patch
|
Patch973: 0001-RISC-V-Handle-R_RISCV_CALL_PLT-reloc.patch
|
||||||
|
Patch974: 0001-clean-up-crypttab-and-linux-modules-dependency.patch
|
||||||
|
Patch975: 0002-discard-cached-key-before-entering-grub-shell-and-ed.patch
|
||||||
|
# Make grub more robust against storage race condition causing system boot failures (bsc#1189036)
|
||||||
|
Patch976: 0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch
|
||||||
|
|
||||||
Requires: gettext-runtime
|
Requires: gettext-runtime
|
||||||
%if 0%{?suse_version} >= 1140
|
%if 0%{?suse_version} >= 1140
|
||||||
|
Loading…
Reference in New Issue
Block a user