cbfstool: Use flock() when accessing CBFS files

Trying to do multiple operations on the same CBFS image at the same time
likely leads to data corruption. For this reason, add BSD advisory file
locking (flock()) to cbfstool (and ifittool which is using the same file
I/O library), so that only one process will operate on the same file at
the same time and the others will wait in line. This should help resolve
parallel build issues with the INTERMEDIATE target on certain platforms.

Unfortunately, some platforms use the INTERMEDIATE target to do a direct
dd into the CBFS image. This should generally be discouraged and future
platforms should aim to clearly deliminate regions that need to be
written directly by platform scripts with custom FMAP sections, so that
they can be written with `cbfstool write`. For the time being, update
the legacy platforms that do this with explicit calls to the `flock`
utility.

Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I022468f6957415ae68a7a7e70428ae6f82d23b06
Reviewed-on: https://review.coreboot.org/c/coreboot/+/49190
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
Julius Werner 2021-01-06 14:41:08 -08:00 committed by Patrick Georgi
parent 7e06a9044a
commit 1153b2ef5c
5 changed files with 8 additions and 6 deletions

View File

@ -22,7 +22,7 @@ ifeq ($(CONFIG_KBC1126_FIRMWARE),y)
printf " Building kbc1126_ec_insert.\n"
$(MAKE) -C util/kbc1126
printf " KBC1126 Inserting KBC1126 firmware blobs.\n"
$(KBC1126_EC_INSERT) $(obj)/coreboot.pre \
flock $< $(KBC1126_EC_INSERT) $(obj)/coreboot.pre \
$(CONFIG_KBC1126_FW1_OFFSET) $(CONFIG_KBC1126_FW2_OFFSET)
endif

View File

@ -172,7 +172,7 @@ STONEYRIDGE_FWM_ROM_POSITION=$(call int-add, \
add_amdfw: $(obj)/coreboot.pre $(obj)/amdfw.rom
printf " DD Adding AMD Firmware at ROM offset 0x%x\n" \
"$(STONEYRIDGE_FWM_ROM_POSITION)"
dd if=$(obj)/amdfw.rom \
flock $< dd if=$(obj)/amdfw.rom \
of=$(obj)/coreboot.pre conv=notrunc bs=1 \
seek=$(STONEYRIDGE_FWM_ROM_POSITION) >/dev/null 2>&1

View File

@ -162,7 +162,7 @@ INTERMEDIATE+=add_amdfw
add_amdfw: $(obj)/coreboot.pre $(obj)/amdfw.rom
printf " DD Adding AMD Firmware\n"
dd if=$(obj)/amdfw.rom \
flock $< dd if=$(obj)/amdfw.rom \
of=$(obj)/coreboot.pre conv=notrunc bs=1 seek=131072 >/dev/null 2>&1
else # ifeq ($(CONFIG_AMDFW_OUTSIDE_CBFS),y)

View File

@ -35,7 +35,7 @@ add_intel_firmware: $(call strip_quotes,$(CONFIG_EC_BIN_PATH))
endif
add_intel_firmware: $(obj)/coreboot.pre $(IFDTOOL)
printf " DD Adding Intel Firmware Descriptor\n"
dd if=$(IFD_BIN_PATH) \
flock $< dd if=$(IFD_BIN_PATH) \
of=$(obj)/coreboot.pre conv=notrunc >/dev/null 2>&1
ifeq ($(CONFIG_VALIDATE_INTEL_DESCRIPTOR),y)
$(objutil)/ifdtool/ifdtool \

View File

@ -8,6 +8,7 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
struct partitioned_file {
struct fmap *fmap;
@ -57,7 +58,7 @@ static partitioned_file_t *reopen_flat_file(const char *filename,
access_mode = write_access ? "rb+" : "rb";
file->stream = fopen(filename, access_mode);
if (!file->stream) {
if (!file->stream || flock(fileno(file->stream), LOCK_EX)) {
perror(filename);
partitioned_file_close(file);
return NULL;
@ -78,7 +79,7 @@ partitioned_file_t *partitioned_file_create_flat(const char *filename,
}
file->stream = fopen(filename, "wb");
if (!file->stream) {
if (!file->stream || flock(fileno(file->stream), LOCK_EX)) {
perror(filename);
free(file);
return NULL;
@ -268,6 +269,7 @@ void partitioned_file_close(partitioned_file_t *file)
file->fmap = NULL;
buffer_delete(&file->buffer);
if (file->stream) {
flock(fileno(file->stream), LOCK_UN);
fclose(file->stream);
file->stream = NULL;
}