Update to efivar 34, and include a patch to avoid upstream rate limiting.
Signed-off-by: Peter Jones <pjones@redhat.com>
This commit is contained in:
parent
c5680d4539
commit
1cf335fff3
117
0001-efivarfs-vars-usleep-before-reading-from-efivarfs-if.patch
Normal file
117
0001-efivarfs-vars-usleep-before-reading-from-efivarfs-if.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From 5ea8c3400693b30c2b65a887899dc2a8e36a9688 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Fri, 23 Feb 2018 15:49:02 -0500
|
||||
Subject: [PATCH] efivarfs / vars: usleep() before reading from efivarfs if
|
||||
euid != 0
|
||||
|
||||
There's a kernel rate limiter on efi variable reads now for
|
||||
non-root users, and we'd rather just not hit it than have to dig out
|
||||
from having hit it. So this adds a 10ms sleep before each read call.
|
||||
|
||||
If you do have 50 variables, efibootmgr will do 100 reads, which would
|
||||
trigger the rate limit. In that case, this patch adds 1 second (plus
|
||||
lossage due to calling, etc.), so it should stay just below the
|
||||
triggering threshold. That will definitely be /smoother/ than hitting
|
||||
it, and almost certainly faster as well, because the extra calls will
|
||||
re-enforce the limit.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
src/efivarfs.c | 12 ++++++++++++
|
||||
src/vars.c | 11 +++++++++++
|
||||
src/util.h | 7 +++++++
|
||||
3 files changed, 30 insertions(+)
|
||||
|
||||
diff --git a/src/efivarfs.c b/src/efivarfs.c
|
||||
index d1458a24d1e..38e4074e977 100644
|
||||
--- a/src/efivarfs.c
|
||||
+++ b/src/efivarfs.c
|
||||
@@ -220,6 +220,16 @@ efivarfs_get_variable(efi_guid_t guid, const char *name, uint8_t **data,
|
||||
int fd = -1;
|
||||
char *path = NULL;
|
||||
int rc;
|
||||
+ int ratelimit;
|
||||
+
|
||||
+ /*
|
||||
+ * The kernel rate limiter hits us if we go faster than 100 efi
|
||||
+ * variable reads per second as non-root. So if we're not root, just
|
||||
+ * delay this long after each read. The user is not going to notice.
|
||||
+ *
|
||||
+ * 1s / 100 = 10000us.
|
||||
+ */
|
||||
+ ratelimit = geteuid() == 0 ? 0 : 10000;
|
||||
|
||||
rc = make_efivarfs_path(&path, guid, name);
|
||||
if (rc < 0) {
|
||||
@@ -233,12 +243,14 @@ efivarfs_get_variable(efi_guid_t guid, const char *name, uint8_t **data,
|
||||
goto err;
|
||||
}
|
||||
|
||||
+ usleep(ratelimit);
|
||||
rc = read(fd, &ret_attributes, sizeof (ret_attributes));
|
||||
if (rc < 0) {
|
||||
efi_error("read failed");
|
||||
goto err;
|
||||
}
|
||||
|
||||
+ usleep(ratelimit);
|
||||
rc = read_file(fd, &ret_data, &size);
|
||||
if (rc < 0) {
|
||||
efi_error("read_file failed");
|
||||
diff --git a/src/vars.c b/src/vars.c
|
||||
index a7b5e2387f9..8522725a51f 100644
|
||||
--- a/src/vars.c
|
||||
+++ b/src/vars.c
|
||||
@@ -305,6 +305,16 @@ vars_get_variable(efi_guid_t guid, const char *name, uint8_t **data,
|
||||
char *path = NULL;
|
||||
int rc;
|
||||
int fd = -1;
|
||||
+ int ratelimit;
|
||||
+
|
||||
+ /*
|
||||
+ * The kernel rate limiter hits us if we go faster than 100 efi
|
||||
+ * variable reads per second as non-root. So if we're not root, just
|
||||
+ * delay this long after each read. The user is not going to notice.
|
||||
+ *
|
||||
+ * 1s / 100 = 10000us.
|
||||
+ */
|
||||
+ ratelimit = geteuid() == 0 ? 0 : 10000;
|
||||
|
||||
rc = asprintf(&path, "%s%s-" GUID_FORMAT "/raw_var",
|
||||
get_vars_path(),
|
||||
@@ -322,6 +332,7 @@ vars_get_variable(efi_guid_t guid, const char *name, uint8_t **data,
|
||||
goto err;
|
||||
}
|
||||
|
||||
+ usleep(ratelimit);
|
||||
rc = read_file(fd, &buf, &bufsize);
|
||||
if (rc < 0) {
|
||||
efi_error("read_file(%s) failed", path);
|
||||
diff --git a/src/util.h b/src/util.h
|
||||
index deef7e71bc4..69042d3cf9a 100644
|
||||
--- a/src/util.h
|
||||
+++ b/src/util.h
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
+#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@@ -137,6 +138,12 @@ read_file(int fd, uint8_t **buf, size_t *bufsize)
|
||||
* before doing so. */
|
||||
s = read(fd, p, size - filesize);
|
||||
if (s < 0 && errno == EAGAIN) {
|
||||
+ /*
|
||||
+ * if we got EAGAIN, there's a good chance we've hit
|
||||
+ * the kernel rate limiter. Doing more reads is just
|
||||
+ * going to make it worse, so instead, give it a rest.
|
||||
+ */
|
||||
+ sched_yield();
|
||||
continue;
|
||||
} else if (s < 0) {
|
||||
int saved_errno = errno;
|
||||
--
|
||||
2.15.0
|
||||
|
12
efivar.spec
12
efivar.spec
@ -1,6 +1,6 @@
|
||||
Name: efivar
|
||||
Version: 33
|
||||
Release: 3%{?dist}
|
||||
Version: 34
|
||||
Release: 1%{?dist}
|
||||
Summary: Tools to manage UEFI variables
|
||||
License: LGPLv2.1
|
||||
URL: https://github.com/rhboot/efivar
|
||||
@ -8,7 +8,10 @@ Requires: %{name}-libs = %{version}-%{release}
|
||||
ExclusiveArch: %{ix86} x86_64 aarch64 %{arm}
|
||||
|
||||
BuildRequires: popt-devel git glibc-static libabigail
|
||||
Source0: https://github.com/rhboot/efivar/archive/%{version}.tar.bz2
|
||||
# please don't fix this to reflect github's incomprehensible url that goes
|
||||
# to a different tarball.
|
||||
Source0: https://github.com/rhboot/efivar/archive/efivar-%{version}.tar.bz2
|
||||
Patch0001: 0001-efivarfs-vars-usleep-before-reading-from-efivarfs-if.patch
|
||||
|
||||
%description
|
||||
efivar provides a simple command line interface to the UEFI variable facility.
|
||||
@ -70,6 +73,9 @@ make libdir=%{_libdir} bindir=%{_bindir} CFLAGS="$RPM_OPT_FLAGS -flto" LDFLAGS="
|
||||
%{_libdir}/*.so.*
|
||||
|
||||
%changelog
|
||||
* Tue Feb 27 2018 Peter Jones <pjones@redhat.com> - 34-1
|
||||
- Update to efivar 34, and include a patch to avoid upstream rate limiting.
|
||||
|
||||
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 33-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||
|
||||
|
2
sources
2
sources
@ -1 +1 @@
|
||||
SHA512 (33.tar.bz2) = 76c053b38b6293e79eff2dcaaaed35c87e875fb7ab67163f91190085c2733c105b351d062b6f95786f95597396be5137284ab7537ba8b9968da4b648247862f3
|
||||
SHA512 (efivar-34.tar.bz2) = 6baa02e1ad919f84d129a032a4631126d6f43dfc247f63c247624cc2af697fb627fd76fe0ffed069b42b835d862582877644fb19843361ef9ced62aa7cd518c4
|
||||
|
Loading…
Reference in New Issue
Block a user