Update to efivar 35
fixes for older compilers efi_get_variable_exists() Lots of stuff to make CI work. use usleep() to avoid hitting the kernel rate limiter on efivarfs better EFI_GUID macro add efi_guid_fwupdate (0abba7dc-e516-4167-bbf5-4d9d1c739416) Signed-off-by: Peter Jones <pjones@redhat.com>
This commit is contained in:
parent
1cf335fff3
commit
a5e29614d5
@ -1,117 +0,0 @@
|
||||
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,5 +1,5 @@
|
||||
Name: efivar
|
||||
Version: 34
|
||||
Version: 35
|
||||
Release: 1%{?dist}
|
||||
Summary: Tools to manage UEFI variables
|
||||
License: LGPLv2.1
|
||||
@ -11,7 +11,6 @@ BuildRequires: popt-devel git glibc-static libabigail
|
||||
# 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.
|
||||
@ -73,6 +72,15 @@ make libdir=%{_libdir} bindir=%{_bindir} CFLAGS="$RPM_OPT_FLAGS -flto" LDFLAGS="
|
||||
%{_libdir}/*.so.*
|
||||
|
||||
%changelog
|
||||
* Mon Apr 09 2018 Peter Jones <pjones@redhat.com> - 35-1
|
||||
- Update to efivar 35
|
||||
- fixes for older compilers
|
||||
- efi_get_variable_exists()
|
||||
- Lots of stuff to make CI work.
|
||||
- use usleep() to avoid hitting the kernel rate limiter on efivarfs
|
||||
- better EFI_GUID macro
|
||||
- add efi_guid_fwupdate (0abba7dc-e516-4167-bbf5-4d9d1c739416)
|
||||
|
||||
* Tue Feb 27 2018 Peter Jones <pjones@redhat.com> - 34-1
|
||||
- Update to efivar 34, and include a patch to avoid upstream rate limiting.
|
||||
|
||||
|
2
sources
2
sources
@ -1 +1 @@
|
||||
SHA512 (efivar-34.tar.bz2) = 6baa02e1ad919f84d129a032a4631126d6f43dfc247f63c247624cc2af697fb627fd76fe0ffed069b42b835d862582877644fb19843361ef9ced62aa7cd518c4
|
||||
SHA512 (efivar-35.tar.bz2) = c7ba60b2112053f088ad0b74aaa834860601b7fe17118c35b012050176f5205d948fba9c4b6de35991249f702e3bc24832539e2eb3c235c4188e1eabc78965ee
|
||||
|
Loading…
Reference in New Issue
Block a user