[grub] - Handle tftp implementations that don't do TFTP_GET_FILE_SIZE correctly
Peter Jones
pjones at fedoraproject.org
Thu Oct 7 14:25:52 UTC 2010
commit 2a8fcd2436ad7a1d552dc6f2253889356cafea4a
Author: Peter Jones <pjones at redhat.com>
Date: Thu Oct 7 10:25:28 2010 -0400
- Handle tftp implementations that don't do TFTP_GET_FILE_SIZE correctly
grub-0.97-handle-bad-tftp.patch | 118 +++++++++++++++++++++++++++++++++++++++
1 files changed, 118 insertions(+), 0 deletions(-)
---
diff --git a/grub-0.97-handle-bad-tftp.patch b/grub-0.97-handle-bad-tftp.patch
new file mode 100644
index 0000000..5000e14
--- /dev/null
+++ b/grub-0.97-handle-bad-tftp.patch
@@ -0,0 +1,118 @@
+From e148522a6e0fd7aeebd3dfd7e162633a3ceb0a87 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones at redhat.com>
+Date: Wed, 6 Oct 2010 14:03:36 -0400
+Subject: [PATCH] Handle bad TFTP_GET_FILE_SIZE implementation by simulating it.
+
+Some platforms, most notably the one identified below, have a broken
+tftp implementation where TFTP_GET_FILE_SIZE returns EFI_BUFFER_TOO_SHORT,
+despite the fact that there's no documented reason for it to do so and
+no buffer that should be in use.
+
+The system I've seen this on says:
+
+BIOS Vendor American Megatrends
+Core Version 4.6.3.2
+Project Version 0ABPH 0.12 x64
+Build Date 03/05/2009 15:16:58
+MRC Version 01000000
+CSI Ref Code Version 0100
+
+This machine is a UEFI 2.0 machine.
+---
+ efi/efitftp.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ efi/pxe.c | 1 -
+ 2 files changed, 52 insertions(+), 2 deletions(-)
+
+diff --git a/efi/efitftp.c b/efi/efitftp.c
+index 7e449b9..4984c97 100644
+--- a/efi/efitftp.c
++++ b/efi/efitftp.c
+@@ -29,6 +29,55 @@ struct tftp_info tftp_info = {
+ * BootpBootFile: X86PC/UNDI/pxelinux/bootx64.efi
+ */
+
++static grub_efi_status_t tftp_get_file_size_defective_buffer_fallback(
++ char *Filename,
++ grub_efi_uintn_t *Size)
++{
++ EFI_PXE_BASE_CODE_TFTP_OPCODE OpCode = EFI_PXE_BASE_CODE_TFTP_READ_FILE;
++ char *Buffer = NULL;
++ grub_efi_boolean_t Overwrite = 0;
++ grub_efi_boolean_t DontUseBuffer = 0;
++ grub_efi_uint64_t BufferSize = 4096;
++ grub_efi_uintn_t BlockSize = 512;
++ grub_efi_status_t rc = GRUB_EFI_BUFFER_TOO_SMALL;
++ char *FullPath = NULL;
++
++ while (rc == GRUB_EFI_BUFFER_TOO_SMALL) {
++ char *NewBuffer;
++
++ if (Buffer) {
++ grub_free(Buffer);
++ Buffer = NULL;
++ }
++ BufferSize *= 2;
++ NewBuffer = grub_malloc(BufferSize);
++ if (!NewBuffer)
++ return GRUB_EFI_OUT_OF_RESOURCES;
++ Buffer = NewBuffer;
++
++ if (tftp_info.BasePath) {
++ int PathSize = 0;
++ PathSize = strlen(tftp_info.BasePath) + 2 +
++ strlen(Filename);
++ FullPath = grub_malloc(PathSize);
++ grub_sprintf(FullPath, "%s/%s", tftp_info.BasePath,
++ Filename);
++ } else {
++ FullPath = grub_malloc(strlen(Filename));
++ strcpy(FullPath, Filename);
++ }
++
++ rc = Call_Service_10(tftp_info.Pxe->Mtftp, tftp_info.Pxe,
++ OpCode, Buffer, Overwrite, &BufferSize, &BlockSize,
++ tftp_info.ServerIp, FullPath, NULL, DontUseBuffer);
++ if (rc == GRUB_EFI_SUCCESS || rc == GRUB_EFI_BUFFER_TOO_SMALL)
++ *Size = BufferSize;
++ }
++ grub_free(FullPath);
++ grub_free(Buffer);
++ return rc;
++}
++
+ grub_efi_status_t tftp_get_file_size(
+ char *Filename,
+ grub_efi_uintn_t *Size)
+@@ -55,6 +104,8 @@ grub_efi_status_t tftp_get_file_size(
+ rc = Call_Service_10(tftp_info.Pxe->Mtftp, tftp_info.Pxe, OpCode,
+ Buffer, Overwrite, &BufferSize, &BlockSize, tftp_info.ServerIp,
+ FullPath, NULL, DontUseBuffer);
++ if (rc == GRUB_EFI_BUFFER_TOO_SMALL)
++ rc = tftp_get_file_size_defective_buffer_fallback(Filename, Size);
+ if (rc == GRUB_EFI_SUCCESS)
+ *Size = BufferSize;
+ grub_free(FullPath);
+@@ -152,7 +203,7 @@ efi_tftp_dir (char *dirname)
+ filemax = -1;
+
+ rc = tftp_get_file_size(name, &size);
+- if (rc == 0) {
++ if (rc == GRUB_EFI_SUCCESS) {
+ tftp_info.LastPath = grub_malloc(strlen(name) + 1);
+ sprintf(tftp_info.LastPath, "%s", name);
+ filemax = size;
+diff --git a/efi/pxe.c b/efi/pxe.c
+index 8a15f20..185ad79 100644
+--- a/efi/pxe.c
++++ b/efi/pxe.c
+@@ -320,7 +320,6 @@ static char *get_pxe_file_dir(EFI_PXE_BASE_CODE *pxe)
+
+ *DirEnd = '\0';
+
+- printf("FileDir: \"%s\"\n", FileDir);
+ return FileDir;
+ }
+
+--
+1.7.3.1
+
More information about the scm-commits
mailing list