[syslinux] PXE Error Reporting

Sebastian Herbszt herbszt at gmx.de
Thu Jan 15 15:19:02 PST 2015


Hello Andreas,

Andreas Gruenbacher wrote:
> Sebastian,
> 
> On 01/15/2015 12:49 AM, Sebastian Herbszt wrote:
> > which version of pxelinux were you trying? Looks like < 5.x.
> 
> the one from Fedora 20, syslinux-4.05.
> 
> It turns out that pxelinux.0 from Fedora 21, syslinux-6.03, reports 
> "Failed to load ldlinux.c32" when ldlinux.c32 can't be read, and

LDLINUX is special:

core/elflink/load_env32.c

170:out:
171:    writestr("\nFailed to load ");
172:    writestr(LDLINUX);

> "Loading <FILE>... failed: No such file or directory" when the TFTP 
> server replies with "Permission denied" for the kernel or initrd.

open() returns ENOENT for all errors:

com32/lib/sys/open.c

68:    handle = open_file(pathname, flags, &fp->i.fd);
69:    if (handle < 0) {
70:     close(fd);
71:     errno = ENOENT;

> So this problem has slightly changed, but it hasn't been fixed.

The (almost untested) patch below should fix this.

Sebastian

diff --git a/com32/lib/sys/open.c b/com32/lib/sys/open.c
index 1ed5bb4..8858f07 100644
--- a/com32/lib/sys/open.c
+++ b/com32/lib/sys/open.c
@@ -65,10 +65,12 @@ int open(const char *pathname, int flags, ...)
 
     fp = &__file_info[fd];
 
+    errno = 0;
     handle = open_file(pathname, flags, &fp->i.fd);
     if (handle < 0) {
 	close(fd);
-	errno = ENOENT;
+	if (!errno)
+	    errno = ENOENT;
 	return -1;
     }
 
diff --git a/core/fs/pxe/tftp.c b/core/fs/pxe/tftp.c
index 446da63..c89d3bf 100644
--- a/core/fs/pxe/tftp.c
+++ b/core/fs/pxe/tftp.c
@@ -205,6 +205,7 @@ void tftp_open(struct url_info *url, int flags, struct inode *inode,
     uint64_t opdata;
     uint16_t src_port;
     uint32_t src_ip;
+    uint16_t error_code;
 
     (void)redir;		/* TFTP does not redirect */
     (void)flags;
@@ -280,6 +281,16 @@ wait_pkt:
     switch (opcode) {
     case TFTP_ERROR:
         inode->size = 0;
+        error_code = *(uint16_t *)(reply_packet_buf + 2);
+        switch (ntohs(error_code)) {
+            case 1: /* File not found. */
+                errno = ENOENT;
+                break;
+
+            case 2: /* Access violation. */
+                errno = EACCES;
+                break;
+        }
 	goto done;        /* ERROR reply; don't try again */
 
     case TFTP_DATA:


More information about the Syslinux mailing list