Hello community,
here is the log from the commit of package lilo
checked in at Wed Sep 24 17:10:24 CEST 2008.
--------
--- arch/i386/lilo/lilo.changes 2008-09-05 14:01:31.000000000 +0200
+++ /mounts/work_src_done/STABLE/lilo/lilo.changes 2008-09-19 16:16:08.000000000 +0200
@@ -1,0 +2,5 @@
+Fri Sep 19 16:14:58 CEST 2008 - olh@suse.de
+
+- rewrite /chosen/bootpath parser to support IPv6 TFTP (bnc#417538)
+
+-------------------------------------------------------------------
Old:
----
yaboot-22.8-r1099.tar.bz2
New:
----
yaboot-22.8-r1119.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ lilo.spec ++++++
--- /var/tmp/diff_new_pack.y25764/_old 2008-09-24 17:10:15.000000000 +0200
+++ /var/tmp/diff_new_pack.y25764/_new 2008-09-24 17:10:15.000000000 +0200
@@ -21,7 +21,7 @@
Name: lilo
ExclusiveArch: ppc ppc64 %ix86 x86_64
-%define yaboot_vers 22.8-r1099
+%define yaboot_vers 22.8-r1119
Group: System/Boot
License: BSD 3-Clause
Summary: The Linux Loader, a Boot Menu
@@ -50,7 +50,7 @@
BuildRequires: gcc-32bit glibc-devel-32bit libgcc42-32bit libmudflap42-32bit
%endif
Version: 22.8
-Release: 17
+Release: 23
Source0: lilo-ppc-%{version}.tar.bz2
Source1: http://penguinppc.org/projects/yaboot/yaboot-%{yaboot_vers}.tar.bz2
Source86: lilo-%{version}.src.tar.bz2
@@ -212,6 +212,8 @@
%endif
%doc %{_mandir}/*/*
%changelog
+* Fri Sep 19 2008 olh@suse.de
+- rewrite /chosen/bootpath parser to support IPv6 TFTP (bnc#417538)
* Fri Sep 05 2008 olh@suse.de
- let yaboot boot SLES9 zImage files by allocating runtime memory at 4MB
* Fri Aug 29 2008 olh@suse.de
++++++ lilo-ppc-22.8.tar.bz2 ++++++
++++++ yaboot-22.8-r1099.tar.bz2 -> yaboot-22.8-r1119.tar.bz2 ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yaboot-22.8-r1099/Changelog.SuSE new/yaboot-22.8-r1119/Changelog.SuSE
--- old/yaboot-22.8-r1099/Changelog.SuSE 2008-09-05 14:01:48.000000000 +0200
+++ new/yaboot-22.8-r1119/Changelog.SuSE 2008-09-19 16:40:56.000000000 +0200
@@ -1,4 +1,149 @@
------------------------------------------------------------------------
+r1119 | olh | 2008-09-19 14:33:32 +0000 (Fri, 19 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/second/parse_device_path.c
+
+assign correct variable to filename if there is no directory in bootpath
+------------------------------------------------------------------------
+r1118 | olh | 2008-09-19 14:16:08 +0000 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/lilo.changes
+ M /trunk/yaboot/include/file.h
+ M /trunk/yaboot/second/file.c
+ M /trunk/yaboot/second/fs_of.c
+ M /trunk/yaboot/second/parse_device_path.c
+
++- rewrite /chosen/bootpath parser to support IPv6 TFTP (bnc#417538)
+
+------------------------------------------------------------------------
+r1117 | olh | 2008-09-19 13:30:34 +0000 (Fri, 19 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/include/file.h
+ M /trunk/yaboot/second/file.c
+ M /trunk/yaboot/second/parse_device_path.c
+
+use path_part to access path_description->part
+------------------------------------------------------------------------
+r1116 | olh | 2008-09-19 11:58:10 +0000 (Fri, 19 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/include/file.h
+ M /trunk/yaboot/second/file.c
+ M /trunk/yaboot/second/parse_device_path.c
+
+use path_directory to access path_description->directory
+------------------------------------------------------------------------
+r1115 | olh | 2008-09-19 11:30:34 +0000 (Fri, 19 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/include/file.h
+ M /trunk/yaboot/second/parse_device_path.c
+
+use path_partition to access path_description->partition
+------------------------------------------------------------------------
+r1114 | olh | 2008-09-19 11:12:51 +0000 (Fri, 19 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/include/debug.h
+ M /trunk/yaboot/include/file.h
+ M /trunk/yaboot/second/file.c
+ M /trunk/yaboot/second/fs_of.c
+ M /trunk/yaboot/second/parse_device_path.c
+
+use path_device to access path_description->device
+------------------------------------------------------------------------
+r1113 | olh | 2008-09-18 14:17:36 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/second/parse_device_path.c
+
+force TYPE_UNSET for default_device
+------------------------------------------------------------------------
+r1112 | olh | 2008-09-18 14:07:24 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/include/file.h
+ M /trunk/yaboot/second/parse_device_path.c
+ M /trunk/yaboot/second/yaboot.c
+
+make parse_device_path static
+------------------------------------------------------------------------
+r1111 | olh | 2008-09-18 09:26:05 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/include/file.h
+
+add path_description->flags
+------------------------------------------------------------------------
+r1110 | olh | 2008-09-18 09:22:31 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/include/file.h
+
+Lindent include/file.h
+------------------------------------------------------------------------
+r1109 | olh | 2008-09-18 09:18:47 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/second/parse_device_path.c
+
+Lindent second/parse_device_path.c
+------------------------------------------------------------------------
+r1108 | olh | 2008-09-18 09:11:29 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/include/file.h
+ M /trunk/yaboot/second/fs_of.c
+ M /trunk/yaboot/second/parse_device_path.c
+
+use path_net_after to access path_description->u.n.ip_after_filename
+------------------------------------------------------------------------
+r1107 | olh | 2008-09-18 09:06:43 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/include/file.h
+ M /trunk/yaboot/second/fs_of.c
+ M /trunk/yaboot/second/parse_device_path.c
+
+use path_net_before to access path_description->u.n.ip_before_filename
+------------------------------------------------------------------------
+r1106 | olh | 2008-09-18 08:50:08 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/include/debug.h
+ M /trunk/yaboot/include/file.h
+ M /trunk/yaboot/second/file.c
+ M /trunk/yaboot/second/fs_of.c
+ M /trunk/yaboot/second/parse_device_path.c
+ M /trunk/yaboot/second/yaboot.c
+
+use path_filename to access path_description->filename
+------------------------------------------------------------------------
+r1105 | olh | 2008-09-18 08:45:14 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/second/parse_device_path.c
+
+use local variable for ->filename for upcoming changes
+------------------------------------------------------------------------
+r1104 | olh | 2008-09-18 08:40:43 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/second/yaboot.c
+
+use pointers for kernel and ramdisk for upcoming changes
+------------------------------------------------------------------------
+r1103 | olh | 2008-09-15 12:03:44 +0000 (Mon, 15 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/util/split_of_path.c
+
+remove double colons
+------------------------------------------------------------------------
+r1102 | olh | 2008-09-15 12:03:21 +0000 (Mon, 15 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/util/split_of_path.c
+
+add :0.0.0.0, to possible network paths
+------------------------------------------------------------------------
+r1101 | olh | 2008-09-15 12:01:07 +0000 (Mon, 15 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/util/split_of_path.c
+
+add :bootp,0.0.0.0,,0.0.0.0 to possible network paths
+------------------------------------------------------------------------
+r1100 | olh | 2008-09-15 11:56:52 +0000 (Mon, 15 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/yaboot/second/yaboot.c
+
+add missing newline in debug printf
+------------------------------------------------------------------------
r1099 | olh | 2008-09-05 12:01:31 +0000 (Fri, 05 Sep 2008) | 2 lines
Changed paths:
M /trunk/lilo.changes
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yaboot-22.8-r1099/include/debug.h new/yaboot-22.8-r1119/include/debug.h
--- old/yaboot-22.8-r1099/include/debug.h 2006-08-18 14:31:50.000000000 +0200
+++ new/yaboot-22.8-r1119/include/debug.h 2008-09-19 13:12:51.000000000 +0200
@@ -36,7 +36,7 @@
file_name)
# define DEBUG_OPEN_NEW do { const struct path_description *s = spec; \
DEBUG_F("dev='%s', s1='%s', s2='%s', filename='%s'\n",\
- s->device, s->u.d.s1, s->u.d.s2, s->filename); \
+ path_device(s), s->u.d.s1, s->u.d.s2, path_filename(s)); \
} while (0)
# define DEBUG_SLEEP prom_sleep(3)
#else
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yaboot-22.8-r1099/include/file.h new/yaboot-22.8-r1119/include/file.h
--- old/yaboot-22.8-r1099/include/file.h 2008-07-04 16:24:50.000000000 +0200
+++ new/yaboot-22.8-r1119/include/file.h 2008-09-19 16:16:08.000000000 +0200
@@ -3,8 +3,6 @@
*
* Copyright (C) 2001 Ethan Benson
*
- * parse_device_path()
- *
* Copyright (C) 2001 Colin Walters
*
* Copyright (C) 1999 Benjamin Herrenschmidt
@@ -44,34 +42,54 @@
int part;
};
+enum flags {
+ may_have_equal_sign,
+ needs_equal_sign,
+ got_COMMAND,
+ got_QUALIFIER,
+ got_FILENAME,
+ do_ISCSI,
+ do_IPV6,
+ do_something,
+};
+
+#define FLAG_MAYBE_EQUALSIGN (1 << may_have_equal_sign)
+#define FLAG_NEEDS_EQUALSIGN (1 << needs_equal_sign)
+#define FLAG_COMMAND (1 << got_COMMAND)
+#define FLAG_QUALIFIER (1 << got_QUALIFIER)
+#define FLAG_FILENAME (1 << got_FILENAME)
+#define FLAG_ISCSI (1 << do_ISCSI)
+#define FLAG_IPV6 (1 << do_IPV6)
+#define FLAG_SOMETHING (1 << do_something)
+
/* describes individual parts of a firmware path
* block: <device>:<partition>,<directory/><filename>
* network: <device>:,<filename>,
*/
struct path_description {
- int part; /* Partition number or -1 */
+#define path_part(x) (x)->part
+ int part; /* Partition number or -1 */
enum device_type type;
+#define path_flags(x) (x)->flags
+ unsigned int flags;
+#define path_device(x) (x)->device
char *device;
union {
struct {
+#define path_partition(x) (x)->u.b.partition
char *partition;
+#define path_directory(x) (x)->u.b.directory
char *directory;
} b;
struct {
+#define path_net_before(x) (x)->u.n.ip_before_filename
char *ip_before_filename;
+#define path_net_after(x) (x)->u.n.ip_after_filename
char *ip_after_filename;
unsigned char mac[6];
- char *dev_options;
- u32 client_ip;
- u32 server_ip;
- u32 gateway_ip;
- u32 netmask;
- u32 bootp_retry;
- u32 tftp_retry;
- u32 tftp_blocksize;
} n;
struct {
char *s1;
@@ -79,38 +97,37 @@
} d;
} u;
+#define path_filename(x) (x)->filename
char *filename;
};
struct boot_file_t {
/* File access methods */
- const struct fs_t *fs;
+ const struct fs_t *fs;
/* Filesystem private (to be broken once we have a
* better malloc'ator)
*/
enum device_type dev_type;
- ihandle of_device;
- u32 inode;
- u64 pos;
- unsigned char* buffer;
- u64 len;
-// unsigned int dev_blk_size;
-// unsigned int part_start;
-// unsigned int part_count;
+ ihandle of_device;
+ u32 inode;
+ u64 pos;
+ unsigned char *buffer;
+ u64 len;
+// unsigned int dev_blk_size;
+// unsigned int part_start;
+// unsigned int part_count;
};
-extern int
-open_file(const struct path_description* spec,
- struct boot_file_t* file);
+extern int open_file(const struct path_description *spec, struct boot_file_t *file);
char *path_description_to_string(const struct path_description *input);
int imagepath_to_path_description(const char *imagepath, struct path_description *result, const struct path_description *default_device);
-int parse_device_path(const char *imagepath, struct path_description *result);
void set_default_device(const char *dev, const char *partition, struct path_description *default_device);
+extern int yaboot_set_bootpath(const char *imagepath, struct path_description *default_device);
#define dump_path_description(p) do { __dump_path_description(__FUNCTION__,__LINE__,p); } while(0)
-void __dump_path_description (const char *fn, int l, const struct path_description *p);
+void __dump_path_description(const char *fn, int l, const struct path_description *p);
#endif
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yaboot-22.8-r1099/Makefile new/yaboot-22.8-r1119/Makefile
--- old/yaboot-22.8-r1099/Makefile 2008-09-05 14:01:48.000000000 +0200
+++ new/yaboot-22.8-r1119/Makefile 2008-09-19 16:40:56.000000000 +0200
@@ -6,7 +6,7 @@
include Config
-VERSION = 22.8-r1099
+VERSION = 22.8-r1119
# Debug mode (spam/verbose)
DEBUG = 0
# make install vars
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yaboot-22.8-r1099/second/file.c new/yaboot-22.8-r1119/second/file.c
--- old/yaboot-22.8-r1099/second/file.c 2007-03-20 12:44:46.000000000 +0100
+++ new/yaboot-22.8-r1119/second/file.c 2008-09-19 16:16:08.000000000 +0200
@@ -79,10 +79,10 @@
struct partition_t *p;
char f[1024];
int fserrorno;
- int partition = spec->part;
+ int partition = path_part(spec);
- parts = partitions_lookup(spec->device);
- sprintf(f, "%s%s", spec->u.b.directory, spec->filename);
+ parts = partitions_lookup(path_device(spec));
+ sprintf(f, "%s%s", path_directory(spec) ? path_directory(spec) : "" , path_filename(spec));
DEBUG_F("filename '%s'\n", f);
fserrorno = FILE_ERR_BADDEV;
if (parts) {
@@ -92,7 +92,7 @@
for (p = parts; p; p = p->next) {
DEBUG_F("#%02d, start: %08lx, length: %08lx\n", p->part_number, p->part_start, p->part_size);
if (partition == -1 || partition == p->part_number) {
- if (fs_open(file, spec->device, p, f)) {
+ if (fs_open(file, path_device(spec), p, f)) {
fserrorno = FILE_ERR_OK;
break;
}
@@ -103,7 +103,7 @@
#ifdef DEBUG
prom_printf("no partitions found.\n");
#endif
- fserrorno = of_filesystem.open(file, spec->device, NULL, f);
+ fserrorno = of_filesystem.open(file, path_device(spec), NULL, f);
if (fserrorno == FILE_ERR_OK)
file->fs = &of_filesystem;
}
@@ -145,7 +145,7 @@
{
memset(file, 0, sizeof(struct boot_file_t));
file->fs = &fs_default;
- file->dev_type = prom_get_devtype(spec->device);
+ file->dev_type = prom_get_devtype(path_device(spec));
switch (file->dev_type) {
case TYPE_ISCSI:
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yaboot-22.8-r1099/second/fs_of.c new/yaboot-22.8-r1119/second/fs_of.c
--- old/yaboot-22.8-r1099/second/fs_of.c 2008-07-22 13:29:51.000000000 +0200
+++ new/yaboot-22.8-r1119/second/fs_of.c 2008-09-19 16:16:08.000000000 +0200
@@ -151,17 +151,17 @@
DEBUG_ENTER;
DEBUG_OPEN_NEW;
- sprintf(buffer, "%s:%s,", spec->device, spec->u.n.ip_before_filename);
+ sprintf(buffer, "%s:%s%s", path_device(spec), path_net_before(spec), path_flags(spec) & FLAG_IPV6 ? "" : ",");
p = p + strlen(buffer);
- strcat(buffer, spec->filename);
+ strcat(buffer, path_filename(spec));
while (*p) {
if (*p == '/')
*p = '\\';
p++;
}
- if (spec->u.n.ip_after_filename && strlen(spec->u.n.ip_after_filename)) {
+ if (path_net_after(spec)) {
strcat(buffer, ",");
- strcat(buffer, spec->u.n.ip_after_filename);
+ strcat(buffer, path_net_after(spec));
}
DEBUG_F("Opening: \"%s\"\n", buffer);
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yaboot-22.8-r1099/second/parse_device_path.c new/yaboot-22.8-r1119/second/parse_device_path.c
--- old/yaboot-22.8-r1099/second/parse_device_path.c 2008-07-22 15:17:16.000000000 +0200
+++ new/yaboot-22.8-r1119/second/parse_device_path.c 2008-09-19 16:33:32.000000000 +0200
@@ -1,4 +1,4 @@
-/* $Id: parse_device_path.c 1092 2008-07-22 13:17:16Z olh $ */
+/* $Id: parse_device_path.c 1119 2008-09-19 14:33:32Z olh $ */
#ifndef DEVPATH_TEST
#include
#include
@@ -9,8 +9,48 @@
#include
#include
+struct option {
+ const char *name;
+ unsigned int flag;
+};
+
+/* Device Support Extensions */
+static struct option interface_options[] = {
+ {.name = "duplex",.flag = FLAG_MAYBE_EQUALSIGN},
+ {.name = "speed",.flag = FLAG_MAYBE_EQUALSIGN},
+ {.name = "promiscuous"},
+ {}
+};
+
+/* do TFTP unless one command is given */
+static struct option command_keywords[] = {
+ {.name = "iscsi",.flag = FLAG_COMMAND | FLAG_ISCSI},
+ {}
+};
+
+static struct option qualifier_options[] = {
+ {.name = "rawio",.flag = FLAG_QUALIFIER},
+ {.name = "ipv6",.flag = FLAG_QUALIFIER | FLAG_IPV6},
+ {.name = "bootp",.flag = FLAG_QUALIFIER},
+ {.name = "dhcpv6",.flag = FLAG_QUALIFIER | FLAG_MAYBE_EQUALSIGN},
+ {.name = "isns",.flag = FLAG_QUALIFIER | FLAG_MAYBE_EQUALSIGN},
+ {.name = "slp",.flag = FLAG_QUALIFIER | FLAG_MAYBE_EQUALSIGN},
+ {}
+};
+
+static struct option tftp_ipv6_boostrap_options[] = {
+ {.name = "dhcpv6",.flag = FLAG_MAYBE_EQUALSIGN},
+ {.name = "ciaddr",.flag = FLAG_NEEDS_EQUALSIGN},
+ {.name = "giaddr",.flag = FLAG_NEEDS_EQUALSIGN},
+ {.name = "siaddr",.flag = FLAG_NEEDS_EQUALSIGN},
+ {.name = "filename",.flag = FLAG_NEEDS_EQUALSIGN | FLAG_FILENAME},
+ {.name = "tftp-retries",.flag = FLAG_NEEDS_EQUALSIGN},
+ {.name = "blksize",.flag = FLAG_NEEDS_EQUALSIGN},
+ {}
+};
+
#define DHCP_UDP_OVERHEAD (20 + /* IP header */ \
- 8) /* UDP header */
+ 8) /* UDP header */
#define DHCP_SNAME_LEN 64
#define DHCP_FILE_LEN 128
#define DHCP_FIXED_NON_UDP 236
@@ -23,28 +63,27 @@
#define DHCP_MIN_LEN 548
struct dhcp_packet {
- u8 op; /* 0: Message opcode/type */
- u8 htype; /* 1: Hardware addr type (net/if_types.h) */
- u8 hlen; /* 2: Hardware addr length */
- u8 hops; /* 3: Number of relay agent hops from client */
- u32 xid; /* 4: Transaction ID */
- u16 secs; /* 8: Seconds since client started looking */
- u16 flags; /* 10: Flag bits */
- u32 ciaddr; /* 12: Client IP address (if already in use) */
- u32 yiaddr; /* 16: Client IP address */
- u32 siaddr; /* 18: IP address of next server to talk to */
- u32 giaddr; /* 20: DHCP relay agent IP address */
- unsigned char chaddr [16]; /* 24: Client hardware address */
- char sname [DHCP_SNAME_LEN]; /* 40: Server name */
- char file [DHCP_FILE_LEN]; /* 104: Boot filename */
- unsigned char options [DHCP_OPTION_LEN];
+ u8 op; /* 0: Message opcode/type */
+ u8 htype; /* 1: Hardware addr type (net/if_types.h) */
+ u8 hlen; /* 2: Hardware addr length */
+ u8 hops; /* 3: Number of relay agent hops from client */
+ u32 xid; /* 4: Transaction ID */
+ u16 secs; /* 8: Seconds since client started looking */
+ u16 flags; /* 10: Flag bits */
+ u32 ciaddr; /* 12: Client IP address (if already in use) */
+ u32 yiaddr; /* 16: Client IP address */
+ u32 siaddr; /* 18: IP address of next server to talk to */
+ u32 giaddr; /* 20: DHCP relay agent IP address */
+ unsigned char chaddr[16]; /* 24: Client hardware address */
+ char sname[DHCP_SNAME_LEN]; /* 40: Server name */
+ char file[DHCP_FILE_LEN]; /* 104: Boot filename */
+ unsigned char options[DHCP_OPTION_LEN];
/* 212: Optional parameters
- (actual length dependent on MTU). */
+ (actual length dependent on MTU). */
};
/* DHCP options */
-enum dhcp_options
-{
+enum dhcp_options {
DHCP_PAD = 0,
DHCP_NETMASK = 1,
DHCP_ROUTERS = 3,
@@ -69,107 +108,216 @@
#undef S
#undef I
-static void parse_block_device(struct path_description *result)
+static void parse_block_device(struct path_description *result, const char *blockdev_options)
{
- char *ip;
-#if 0
- prom_printf("%s\n", __FUNCTION__);
-#endif
- if (!result->u.b.partition)
- return;
+ const char *pd, *pf;
+ char *p;
+ int part;
+ size_t len;
- result->part = strtol(result->u.b.partition, &ip, 10);
- DEBUG_F("part '%d', partition '%s', ip '%s'\n", result->part, result->u.b.partition, ip);
- if (result->part)
- *ip++ = '\0';
- else {
- result->part = -1;
- result->u.b.partition = "";
- }
- if (',' == ip[0])
- ip++;
- result->u.b.directory = ip;
- result->filename = strrchr(result->u.b.directory, '/');
- if (!result->filename)
- result->filename = strrchr(result->u.b.directory, '\\');
- if (result->filename) {
- memmove(result->filename + 2, result->filename + 1, strlen(result->filename + 1) + 1);
- result->filename++;
- result->filename[0] = '\0';
- result->filename++;
- } else {
- result->filename = result->u.b.directory;
- result->u.b.directory = "";
- }
+ DEBUG_F("options '%s'\n", blockdev_options);
+ part = strtol(blockdev_options, &p, 10);
+ /* if there is no partition number, ignore it */
+ if (part <= 0)
+ part = -1;
+ path_part(result) = part;
+ /* find the comma after the partition number */
+ pd = strchr(blockdev_options, ',');
+ /* there is a comma, hopefully its not part of a filesystem path */
+ if (pd)
+ pd++; /* skip it */
+ else
+ pd = blockdev_options; /* path may begin with a directory */
+ /* find the last filesystem delimiter, can be either /, or \ for firmware pathnames */
+ pf = strrchr(pd, '/');
+ if (!pf)
+ pf = strrchr(pd, '\\');
+ if (pf) {
+ len = pf - pd;
+ /* the delimiter itself is also required */
+ len++;
+ p = malloc(len + 1);
+ if (p) {
+ memcpy(p, pd, len);
+ p[len] = '\0';
+ path_directory(result) = p;
+ }
+ /* skip the filesystem delimiter */
+ pf++;
+ } else
+ pf = pd; /* path contains only the filename */
+ path_filename(result) = strdup(pf);
}
-/**
- * reset_device_to_iscsi
- * When the bootpath is on an "iscsi" device,
- * the firmware needs to be passed the contents of the
- * "nas-bootdevice" property.
+/*
+ * search options listed in *opt
+ * set flags in path for all options found
+ * stop at first unknown string, or if stopflag is found
+ * return the len of found options at offset
+ * FIXME: len still includes the trailing comma
*/
-static void reset_device_to_iscsi(struct path_description *result)
+size_t parse_options(const char *string, size_t offset, struct path_description *path, struct option *opt, unsigned int stopflag)
{
- int size = prom_getproplen_chosen("nas-bootdevice");
+ struct option *opt_save;
+ char b[64], *eq;
+ const char *pos;
+ int match;
+ size_t ol, sl, new_offset;
+
+ if (!string || !*string)
+ return 0;
- if (size > 0) {
- result->device = malloc(size + 2);
- if (result->device) {
- prom_get_chosen("nas-bootdevice", result->device, size);
- DEBUG_F("nas-bootdevice: <%s>\n", result->device);
+ ol = sl = 0;
+ new_offset = offset;
+
+ opt_save = opt;
+ do {
+ match = 0;
+
+ /* check how long the current option is */
+ pos = strchr(string + new_offset, ',');
+ if (pos)
+ sl = pos - (string + new_offset);
+ else
+ sl = strlen(string + new_offset);
+
+ /* its too long or there is nothing up to the next comma */
+ if (!sl || sl > (sizeof(b) - 1))
+ continue;
+
+ memcpy(b, string + new_offset, sl);
+ b[sl] = '\0';
+ eq = strchr(b, '=');
+
+ while (opt->name) {
+ ol = strlen(opt->name);
+ /* option must be at least as long as the string */
+ if (sl >= ol) {
+ /* truncate at the equal sign to simplify matching */
+ if (eq)
+ *eq = '\0';
+ match = strcmp(opt->name, b) == 0;
+ if (eq)
+ *eq = '=';
+ if (match) {
+ /* skip if option needs an equalsign */
+ if (!(!eq && opt->flag & FLAG_NEEDS_EQUALSIGN)) {
+ path_flags(path) |= opt->flag;
+ if (opt->flag & stopflag) {
+ /* forward offset up to the = */
+ new_offset += ol + 1;
+ /* get out of the loop */
+ match = 0;
+ } else {
+ if (pos) {
+ new_offset += sl; /* up to the end of the option */
+ new_offset++; /* skip the comma after current match */
+ }
+ }
+ break;
+ }
+ }
+ }
+ opt++;
}
- }
+ opt = opt_save;
+ } while (match && pos); /* one or more match, or no more data */
+ /* return the difference */
+ return new_offset - offset;
}
/*
- * options for a "network" device, according to "4.3.2 iSCSI Bootstrap"
- *
- * iscsi,[dev=block],[ipv6,][dhcp[=diaddr],][bootp,][slp[=SLPserver],][isns=iSNSserver,][itname=initname,]
- * [ichapid=initchapid,][ichappw=initchappw,]ciaddr=initaddr,[giaddr=gatewayaddr,][subnetmask=netmask,]
- * siaddr=targetserver,[iport=targetport,]iname=targetname,[ilun=targetlun,][chapid=targetchapid,][chappw=targetchappw,]disklabel args
- *
- * There will be no disk-label args because the firmware is unable to load the bootfile from a specified partition.
- * Only the first 0x41 PReP Boot is considered, /chosen/bootpath will not contain partition, directory and filename
- * Clear partition and directory string, invalidate partition numer
+ * When the bootpath is on an "iscsi" device,
+ * the firmware needs to be passed the contents of the * "nas-bootdevice" property.
+ * It points to a block device with options.
+ * keep this path+options as the full devicepath to a block device
*/
-static void parse_iscsi_device(struct path_description *result)
+static const char nas[] = "nas-bootdevice";
+static void get_iscsi_options(struct path_description *path, const char *netdev_options, size_t offset)
{
- result->part = -1;
- result->u.b.directory = result->u.b.partition = "";
- reset_device_to_iscsi(result);
- return;
+ char *p;
+ int size;
+ prom_printf(" \n"
+ " *** This is the yaboot iSCSI codepath. *** \n"
+ " \n"
+ " *** How exactly did you get that far?! *** \n"
+ " \n");
+ path->type = TYPE_ISCSI;
+ size = prom_getproplen_chosen(nas);
+ if (size <= 0) {
+ prom_printf("'%s' property missing for iSCSI boot\n", nas);
+ return;
+ }
+ p = malloc(size + 2); /* FIXME: fix the additional 2 */
+ if (p) {
+ prom_get_chosen(nas, p, size);
+ DEBUG_F("%s: <%s>\n", nas, p);
+ } else
+ p = "";
+ path_device(path) = p;
}
-/*
- * pmac and older chrp (up to power5) can request any file from the tfp server
- * Newer IBM firmware requires a boot path with static ip addresses and the
- * desired filename. If /chosen/bootpath is reused, the bootfile (yaboot) itself
- * is loaded again and again.
- * pmac uses dhcp-response
- * chrp uses bootpreply-packet
- * power6 CAS firmware use bootp-response
- * build a static IP data from the bootp server response
- * format is <device>:tftpserver,filename,client,gateway,bootp-retry,tftp-retry,netmask,tftp-blocksize
- */
+
+static void get_tftp_ipv6_options(struct path_description *path, const char *netdev_options, size_t offset)
+{
+ char *p, *pf;
+ size_t len;
+
+ /* stop parsing at filename= */
+ len = parse_options(netdev_options, offset, path, &tftp_ipv6_boostrap_options[0], FLAG_FILENAME);
+ /*
+ * need SOME data to let firmware download from IPv6 TFTP server
+ * relies on parser to return the len of filename= itself
+ */
+ if (!len)
+ return;
+
+ /* forward offset to include all options including filename= */
+ offset += len;
+ p = malloc(offset + 1);
+ if (p) {
+ memcpy(p, netdev_options, offset);
+ p[offset] = '\0';
+ path_net_before(path) = p;
+ }
+ /* find len of filename value */
+ p = strchr(netdev_options + offset, ',');
+ if (!p) {
+ /* no more options, use filename value */
+ pf = malloc(strlen(netdev_options + offset) + 1);
+ if (pf) {
+ strcpy(pf, netdev_options + offset);
+ path_filename(path) = pf;
+ }
+ } else {
+ len = p - (netdev_options + offset);
+ pf = malloc(len + 1);
+ if (pf) {
+ memcpy(pf, netdev_options + offset, len);
+ pf[len] = '\0';
+ path_filename(path) = pf;
+ }
+ /* skip the comma */
+ p++;
+ /* use all whats left */
+ path_net_after(path) = strdup(p);
+ }
+}
+
static void ipv4_to_ascii(char *buf, u32 ip)
{
if (buf)
- sprintf(buf,"%u.%u.%u.%u",
- (ip & 0xff000000) >> 24,
- (ip & 0x00ff0000) >> 16,
- (ip & 0x0000ff00) >> 8,
- (ip & 0x000000ff));
+ sprintf(buf, "%u.%u.%u.%u", (ip & 0xff000000) >> 24, (ip & 0x00ff0000) >> 16, (ip & 0x0000ff00) >> 8, (ip & 0x000000ff));
}
-static void get_dhcp_options(const struct dhcp_packet *dp, int size, u32 *netmask, u32 *gateway)
+static void get_dhcp_ipv4_options(const struct dhcp_packet *dp, int size, u32 * netmask, u32 * gateway)
{
unsigned char *p, value, len;
u32 i;
-
/* add 4 byte cookie offset */
- i =offsetof(struct dhcp_packet, options) + 4;
+ i = offsetof(struct dhcp_packet, options) + 4;
+ *netmask = *gateway = 0;
if (size >= i) {
- p = (unsigned char*)dp;
+ p = (unsigned char *)dp;
p += i;
size -= i;
while (size > 0) {
@@ -195,217 +343,282 @@
}
}
-static void hack_boot_path_for_CAS(struct path_description *result)
+/*
+ * pmac and older chrp (up to power5) can request any file from the tfp server
+ * Newer IBM firmware requires a boot path with static ip addresses and the
+ * desired filename. If /chosen/bootpath is reused, the bootfile (yaboot) itself
+ * is loaded again and again.
+ * pmac uses dhcp-response
+ * chrp uses bootpreply-packet
+ * power6 CAS firmware use bootp-response
+ * build a static IP data from the bootp server response
+ * format is <device>:tftpserver,filename,client,gateway,bootp-retry,tftp-retry,netmask,tftp-blocksize
+ */
+
+/*
+ * If booted via bootp/dhcp, all IPv4 addresses may be zero
+ * The new IBM CAS firmware expects that we construct a new bootpath based on the bootp response packet
+ * Assume all data was supplied manually if the property does not exist
+ */
+static int get_tftp_ipv4_ibm_CAS(struct path_description *path, const char *netdev_options, size_t offset)
{
- char *p, buf[sizeof("000.000.000.000")];
- char *clientip, *gatewayip, *bootp_retry, *tftp_retry, *netmask, *tftp_blocksize;
+ const char *p;
+ char *p1, *pf, buf[sizeof("000.000.000.000")];
+ int bootp_retry, tftp_retry, tftp_blocksize;
struct dhcp_packet *dp;
- int size, s;
+ u32 netmask_ipv4, gateway_ipv4;
+ int size, i;
size = prom_getproplen_chosen("bootp-response");
if (size <= 0)
- return;
-
+ return 0;
+ /* IPv4 data via DHCP */
dp = malloc(size);
if (!dp)
- return;
- clientip = gatewayip = bootp_retry = tftp_retry = netmask = tftp_blocksize = NULL;
+ return 0;
prom_get_chosen("bootp-response", dp, size);
- p = strrchr(result->u.n.ip_before_filename, ',');
+ bootp_retry = tftp_retry = 5;
+ tftp_blocksize = 512;
+
+ p = netdev_options + offset;
+ /* find comma after server IPv4 */
+ p = strchr(p, ',');
if (p) {
- *p = '\0';
- result->u.n.dev_options = result->u.n.ip_before_filename;
+ p++;
+ /* find comma after filename */
+ p1 = strchr(p, ',');
+ if (p1) {
+ i = p1 - p;
+ pf = malloc(i + 1);
+ if (pf) {
+ memcpy(pf, p, i);
+ pf[i] = '\0';
+ path_filename(path) = pf;
+ }
+ p1++; /* skip comma */
+ p = p1;
+ /* skip client IPv4 and gateway IPv4, move forward after comma */
+ for (i = 0; i < 2; i++) {
+ p = strchr(p, ',');
+ if (!p)
+ break;
+ p++;
+ }
+ }
}
-
- result->u.n.server_ip = dp->siaddr;
- result->u.n.client_ip = dp->yiaddr;
- result->u.n.gateway_ip = dp->giaddr;
- get_dhcp_options(dp, size, &result->u.n.netmask, &result->u.n.gateway_ip);
-
- ipv4_to_ascii(buf, dp->siaddr);
- s = 0;
- if (result->u.n.dev_options)
- s += strlen(result->u.n.dev_options) + 1;
- s += strlen(buf) + 1;
- p = malloc(s);
if (p) {
- result->u.n.ip_before_filename = p;
- if (result->u.n.dev_options) {
- sprintf(p,"%s,", result->u.n.dev_options);
- p += strlen(p);
+ bootp_retry = strtol(p, &p1, 10);
+ if (bootp_retry == 0 && (p == p1))
+ bootp_retry = 5;
+ if (p1)
+ p = p1;
+ /* find comma after bootp-retry */
+ p = strchr(p, ',');
+ if (p) {
+ p++;
+ tftp_retry = strtol(p, &p1, 10);
+ if (tftp_retry == 0 && (p == p1))
+ tftp_retry = 5;
+ if (p1)
+ p = p1;
+ /* find comma after tftp-retry */
+ p = strchr(p, ',');
+ if (p) {
+ p++;
+ /* find comma after netmask */
+ p = strchr(p, ',');
+ if (p) {
+ p++;
+ tftp_blocksize = strtol(p, &p1, 10);
+ if (tftp_blocksize == 0 && (p == p1))
+ tftp_blocksize = 512;
+
+ }
+ }
}
- sprintf(p,"%s", buf);
}
+ get_dhcp_ipv4_options(dp, size, &netmask_ipv4, &gateway_ipv4);
+ ipv4_to_ascii(buf, dp->siaddr);
+ i = offset + 1 + strlen(buf) + 1; /* options + comma + server IPv4 + null */
+ p1 = malloc(i);
+ if (p1) {
+ memcpy(p1, netdev_options, offset); /* FIXME: this includes trailing comma */
+ memcpy(p1 + offset, buf, strlen(buf) + 1); /* this includes trailing NUL */
+ path_net_before(path) = p1;
+ }
+ i = 3 * sizeof(buf) + 3 * sizeof(buf) + 5 + 1; /* 3 * IPv4 + 3 * int + 5 comma + null */
+ p1 = malloc(i);
+ if (p1) {
+ ipv4_to_ascii(buf, dp->yiaddr);
+ i = strlen(buf);
+ memcpy(p1, buf, i);
+ p1[i] = ',';
+ i++;
+
+ ipv4_to_ascii(buf, gateway_ipv4);
+ memcpy(p1 + i, buf, strlen(buf));
+ i += strlen(buf);
+ p1[i] = ',';
+ i++;
- clientip = result->u.n.ip_after_filename;
+ ipv4_to_ascii(buf, netmask_ipv4);
- p = strchr(clientip, ',');
- if (!p)
- goto end_parse;
- *p = '\0';
- p++;
- gatewayip = p;
+ sprintf(p1 + i, "%d,%d,%s,%d", bootp_retry, tftp_retry, buf, tftp_blocksize);
- p = strchr(p, ',');
- if (!p)
- goto end_parse;
- *p = '\0';
- p++;
- bootp_retry = p;
+ path_net_after(path) = p1;
+ }
+ return 1;
+}
- p = strchr(p, ',');
- if (!p)
- goto end_parse;
- *p = '\0';
- p++;
- tftp_retry = p;
+static void get_tftp_ipv4_options(struct path_description *path, const char *netdev_options, size_t offset)
+{
+ char *p, *pf;
+ size_t i;
- p = strchr(p, ',');
- if (!p)
- goto end_parse;
- *p = '\0';
- p++;
- netmask = p;
-
- p = strchr(p, ',');
- if (!p)
- goto end_parse;
- *p = '\0';
- p++;
- tftp_blocksize = p;
-
-end_parse:
- s = sizeof(buf) + 1 + sizeof(buf) + 1 + strlen(bootp_retry) + 1 + strlen(tftp_retry) + 1 + sizeof(buf) + 1 + strlen(tftp_blocksize) + 1;
- p = malloc(s);
- if (p) {
- result->u.n.ip_after_filename = p;
- ipv4_to_ascii(buf, result->u.n.client_ip);
- sprintf(p, "%s,", buf);
- p += strlen(p);
- ipv4_to_ascii(buf, result->u.n.gateway_ip);
- sprintf(p, "%s,", buf);
- p += strlen(p);
- sprintf(p, "%s,", bootp_retry ? bootp_retry : "5");
- p += strlen(p);
- sprintf(p, "%s,", tftp_retry ? tftp_retry : "5");
- p += strlen(p);
- ipv4_to_ascii(buf, result->u.n.netmask);
- sprintf(p, "%s,%s", buf, tftp_blocksize ? tftp_blocksize : "512");
+ if (netdev_options[offset]) {
+ if (get_tftp_ipv4_ibm_CAS(path, netdev_options, offset) == 0) {
+ /* find comma after server IPv4 */
+ p = strchr(netdev_options + offset, ',');
+ DEBUG_F("comma after server IPv4 '%s' -> '%s'\n", netdev_options + offset, p);
+ if (p) {
+ offset = p - netdev_options;
+ p = malloc(offset + 1);
+ if (p) {
+ /* keep everything up to the filename */
+ memcpy(p, netdev_options, offset);
+ p[offset] = '\0';
+ path_net_before(path) = p;
+ }
+ offset++; /* skip the comma before the filename */
+ p = strchr(netdev_options + offset, ','); /* comma after the filename */
+ DEBUG_F("comma after filename '%s'\n", p);
+ if (p) {
+ i = p - (netdev_options + offset);
+ pf = malloc(i + 1);
+ if (pf) {
+ memcpy(pf, netdev_options + offset, i);
+ pf[i] = '\0';
+ path_filename(path) = pf;
+ }
+ offset = p - netdev_options;
+ offset++; /* skip the comma after the filename */
+ i = strlen(netdev_options + offset);
+ p = malloc(i + 1);
+ if (p) {
+ strcpy(p, netdev_options + offset);
+ path_net_after(path) = p;
+ }
+ } else {
+ /* nothing after filename */
+ path_filename(path) = strdup(netdev_options + offset);
+ }
+ } else {
+ /* no filename was provided */
+ i = strlen(netdev_options + offset);
+ p = malloc(i + 1);
+ if (p) {
+ strcpy(p, netdev_options + offset);
+ path_net_before(path) = p;
+ }
+ }
+ }
+ } else {
+ /* maybe pmac, booted without any options */
+ p = malloc(offset + 1);
+ if (p) {
+ strcpy(p, netdev_options);
+ path_net_before(path) = p;
+ }
}
- return;
}
-static void parse_net_device(struct path_description *result)
+static void get_tftp_options(struct path_description *path, const char *netdev_options, size_t offset)
{
- char *p;
-#if 0
- prom_printf("%s\n", __FUNCTION__);
-#endif
- if (!result->u.n.ip_before_filename)
- goto out;
+ DEBUG_F("ipv%d tftp: netdev_options '%s' offset '%s'\n", path_flags(path) & FLAG_IPV6 ? 6 : 4, netdev_options, netdev_options + offset);
+ if (path_flags(path) & FLAG_IPV6)
+ get_tftp_ipv6_options(path, netdev_options, offset);
+ else
+ get_tftp_ipv4_options(path, netdev_options, offset);
+}
+
+static void parse_net_device(struct path_description *path, const char *netdev_options)
+{
+ size_t offset, newlen;
- p = result->u.n.ip_before_filename;
+ offset = 0;
+ newlen = parse_options(netdev_options, offset, path, &interface_options[0], 0);
+ if (newlen)
+ offset += newlen;
- if (strncmp("bootp", p, 5) == 0) {
- p = strchr(p, ',');
- if (!p) {
- result->u.n.ip_before_filename[5] = ',';
- result->u.n.ip_before_filename[6] = '\0';
- goto out;
- }
- p++;
- }
- if (strncmp("promiscuous", p, 11) == 0) {
- p = strchr(p, ',');
- if (!p)
- goto out;
- p++;
- }
- if (strncmp("speed=", p, 6) == 0) {
- p = strchr(p, ',');
- if (!p)
- goto out;
- p++;
- }
- if (strncmp("duplex=", p, 7) == 0) {
- p = strchr(p, ',');
- if (!p)
- goto out;
- p++;
- }
- p = strchr(p, ',');
- if (!p)
- goto out;
- *p = '\0';
- p++;
- result->filename = p;
- p = strchr(p, ',');
- if (p) {
- *p = '\0';
- p++;
- result->u.n.ip_after_filename = p;
- }
- out:
- hack_boot_path_for_CAS(result);
- return;
+ newlen = parse_options(netdev_options, offset, path, &command_keywords[0], 0);
+ if (newlen)
+ offset += newlen;
+
+ newlen = parse_options(netdev_options, offset, path, &qualifier_options[0], 0);
+ if (newlen)
+ offset += newlen;
+
+ if (path_flags(path) & FLAG_ISCSI)
+ get_iscsi_options(path, netdev_options, offset);
+ else
+ get_tftp_options(path, netdev_options, offset);
}
static void get_mac_address(struct path_description *result)
{
- phandle dev = prom_finddevice(result->device);
+ phandle dev = prom_finddevice(path_device(result));
if (dev != PROM_INVALID_HANDLE) {
if (prom_getprop(dev, "mac-address", &result->u.n.mac, 6) == -1)
prom_getprop(dev, "local-mac-address", &result->u.n.mac, 6);
- prom_printf("MAC for %s: %02x:%02x:%02x:%02x:%02x:%02x\n",
- result->device,
- result->u.n.mac[0], result->u.n.mac[1],
- result->u.n.mac[2], result->u.n.mac[3],
- result->u.n.mac[4], result->u.n.mac[5]
- );
+ prom_printf("MAC for %s: %02x:%02x:%02x:%02x:%02x:%02x\n", path_device(result),
+ result->u.n.mac[0], result->u.n.mac[1], result->u.n.mac[2], result->u.n.mac[3], result->u.n.mac[4], result->u.n.mac[5]);
}
}
-int parse_device_path(const char *imagepath, struct path_description *result)
+/*
+ * split the full image path into device and options part
+ * parse options depending on the device type
+ */
+static int parse_device_path(const char *imagepath, struct path_description *result)
{
- char *colon;
+ char *colon, *p;
+ size_t offset;
DEBUG_F("imagepath '%s'\n", imagepath);
if (!imagepath)
return 0;
- result->device = malloc(strlen(imagepath) + 2);
- if (!result->device)
- return 0;
- strcpy(result->device, imagepath);
- result->u.d.s1 = strchr(result->device, ':');
- if (result->u.d.s1) {
- colon = result->u.d.s1;
- *result->u.d.s1 = '\0';
- result->u.d.s1++;
- } else
- colon = NULL;
+ offset = 0;
+ if (result->type == TYPE_UNSET) {
+ colon = strchr(imagepath, ':');
+ if (colon)
+ offset = colon - imagepath;
+ else
+ offset = strlen(imagepath);
+ p = malloc(offset + 1);
+ if (!p)
+ return 0;
+ memcpy(p, imagepath, offset);
+ p[offset] = '\0';
+ if (colon)
+ offset++; /* skip the colon */
+ path_device(result) = p;
- result->type = prom_get_devtype(result->device);
+ result->type = prom_get_devtype(path_device(result));
+ }
switch (result->type) {
case TYPE_BLOCK:
- parse_block_device(result);
+ parse_block_device(result, imagepath + offset);
break;
case TYPE_NET:
- if (strncmp("iscsi,", result->u.d.s1, 6) == 0) {
- result->type = TYPE_ISCSI;
- *colon = ':';
- result->u.d.s1 = NULL;
- parse_iscsi_device(result);
- } else {
- parse_net_device(result);
- get_mac_address(result);
- }
+ get_mac_address(result);
+ parse_net_device(result, imagepath + offset);
break;
case TYPE_INVALID:
- prom_printf("firmware said the path '%s' is invalid\n", result->device);
+ prom_printf("firmware said the path '%s' is invalid\n", path_device(result));
return 0;
default:
- prom_printf("type %d of '%s' not handled\n", result->type, result->device);
+ prom_printf("type %d of '%s' not handled\n", result->type, path_device(result));
return 0;
}
dump_path_description(result);
@@ -421,36 +634,36 @@
return NULL;
dump_path_description(input);
path = NULL;
- len = strlen(input->device);
- len += strlen(input->filename);
+ len = strlen(path_device(input));
+ len += strlen(path_filename(input));
len += 1 + 1 + 1; /* : , \0 */
switch (input->type) {
case TYPE_ISCSI:
case TYPE_BLOCK:
- if (input->part > 0)
- sprintf(part, "%d,", input->part);
+ if (path_part(input) > 0)
+ sprintf(part, "%d,", path_part(input));
else {
part[0] = ',';
part[1] = '\0';
}
len += strlen(part);
- len += strlen(input->u.b.directory);
+ len += strlen(path_directory(input));
path = malloc(len);
if (path)
- sprintf(path, "%s:%s%s%s", input->device, part, input->u.b.directory, input->filename);
+ sprintf(path, "%s:%s%s%s", path_device(input), part, path_directory(input), path_filename(input));
break;
case TYPE_NET:
- len += strlen(input->u.n.ip_before_filename);
- if (input->u.n.ip_after_filename) {
+ len += strlen(path_net_before(input));
+ if (path_net_after(input)) {
len++;
- len += strlen(input->u.n.ip_after_filename);
+ len += strlen(path_net_after(input));
}
path = malloc(len);
if (path)
- sprintf(path, "%s:%s,%s%s%s", input->device,
- input->u.n.ip_before_filename, input->filename,
- input->u.n.ip_after_filename ? "," : "",
- input->u.n.ip_after_filename ? input->u.n.ip_after_filename : "");
+ sprintf(path, "%s:%s%s%s%s%s", path_device(input),
+ path_net_before(input),
+ path_flags(input) & FLAG_IPV6 ? "" : ",",
+ path_filename(input), path_net_after(input) ? "," : "", path_net_after(input) ? path_net_after(input) : "");
break;
default:
break;
@@ -458,8 +671,13 @@
return path;
}
-int imagepath_to_path_description(const char *imagepath, struct path_description *result,
- const struct path_description *default_device)
+/*
+ * Take the full or relative imagepath and build a full path
+ * If its a relative path, use the device yaboot was loaded from as a base
+ * Handle special string '&device;' as device yaboot was loaded from
+ * returns 0 if something cant be parsed
+ */
+int imagepath_to_path_description(const char *imagepath, struct path_description *result, const struct path_description *default_device)
{
char *past_device, *comma, *dir, *pathname;
char part[42];
@@ -484,21 +702,17 @@
pathname = NULL;
switch (default_device->type) {
case TYPE_ISCSI:
- result->part = default_device->part;
- pathname = malloc(strlen(default_device->device) + 1);
- if (!pathname)
+ path_part(result) = path_part(default_device);
+ path_device(result) = strdup(path_device(default_device));
+ if (!path_device(result))
return 0;
- strcpy(pathname, default_device->device);
- result->device = pathname;
- pathname = malloc(strlen(imagepath) + 1);
- if (!pathname) {
- free(result->device);
+ path_filename(result) = strdup(imagepath);
+ if (!path_filename(result)) {
+ free(path_device(result));
return 0;
}
- strcpy(pathname, imagepath);
- result->filename = pathname;
#if defined(DEBUG) || defined(DEVPATH_TEST)
- prom_printf("hardcoded iscsi path '%s' '%d' '%s'\n", result->device, result->part, result->filename);
+ prom_printf("hardcoded iscsi path '%s' '%d' '%s'\n", path_device(result), path_part(result), path_filename(result));
#endif
/* do not call parse_device_path */
return 1;
@@ -506,45 +720,44 @@
part[0] = '\0';
/* parse_device_path will look for a partition number */
if (past_device)
- len = strlen(default_device->device) + 1 + strlen(past_device);
+ len = strlen(path_device(default_device)) + 1 + strlen(past_device);
else {
- if (default_device->part > 0)
- sprintf(part, "%d", default_device->part);
+ if (path_part(default_device) > 0)
+ sprintf(part, "%d", path_part(default_device));
comma = ",";
- if (imagepath[0] != '/' && imagepath[0] != '\\' && default_device->u.b.directory)
- dir = default_device->u.b.directory;
- len = strlen(default_device->device) + 1 + strlen(part) + 1 + strlen(dir) + strlen(imagepath);
+ if (imagepath[0] != '/' && imagepath[0] != '\\' && path_directory(default_device))
+ dir = path_directory(default_device);
+ len = strlen(path_device(default_device)) + 1 + strlen(part) + 1 + strlen(dir) + strlen(imagepath);
}
len += 2;
pathname = malloc(len);
if (pathname)
- sprintf(pathname, "%s:%s%s%s%s", default_device->device, part, comma, dir,
- past_device ? past_device : imagepath);
+ sprintf(pathname, "%s:%s%s%s%s", path_device(default_device), part, comma, dir, past_device ? past_device : imagepath);
#if defined(DEBUG) || defined(DEVPATH_TEST)
prom_printf("parsing block path '%s'\n", pathname);
#endif
break;
case TYPE_NET:
if (past_device)
- len = strlen(default_device->device) + 1 + strlen(past_device);
+ len = strlen(path_device(default_device)) + 1 + strlen(past_device);
else {
- len = strlen(default_device->device) + 1;
- if (default_device->u.n.ip_before_filename)
- len += strlen(default_device->u.n.ip_before_filename);
+ len = strlen(path_device(default_device)) + 1;
+ if (path_net_before(default_device))
+ len += strlen(path_net_before(default_device));
len++;
len += strlen(imagepath);
- if (default_device->u.n.ip_after_filename) {
- len += 1 + strlen(default_device->u.n.ip_after_filename);
+ if (path_net_after(default_device)) {
+ len += 1 + strlen(path_net_after(default_device));
comma = ",";
}
}
len += 2;
pathname = malloc(len);
if (pathname)
- sprintf(pathname, "%s:%s,%s%s%s", default_device->device,
- default_device->u.n.ip_before_filename ? default_device->u.n.ip_before_filename : "",
- past_device ? past_device : imagepath, comma,
- default_device->u.n.ip_after_filename ? default_device->u.n.ip_after_filename : "");
+ sprintf(pathname, "%s:%s%s%s%s%s", path_device(default_device),
+ path_net_before(default_device) ? path_net_before(default_device) : "",
+ path_flags(default_device) & FLAG_IPV6 ? "" : ",",
+ past_device ? past_device : imagepath, comma, path_net_after(default_device) ? path_net_after(default_device) : "");
#if defined(DEBUG) || defined(DEVPATH_TEST)
prom_printf("parsing net path '%s'\n", pathname);
#endif
@@ -569,11 +782,11 @@
endp = strdup(dev);
if (!endp)
return;
- default_device->device = endp;
- endp = strchr(default_device->device, ':');
+ path_device(default_device) = endp;
+ endp = strchr(path_device(default_device), ':');
if (endp)
endp[0] = '\0';
- default_device->type = prom_get_devtype(default_device->device);
+ default_device->type = prom_get_devtype(path_device(default_device));
}
if (partition) {
@@ -581,7 +794,12 @@
if (endp != partition && *endp == 0) {
if (TYPE_UNSET == default_device->type)
default_device->type = TYPE_BLOCK;
- default_device->part = n;
+ path_part(default_device) = n;
}
}
}
+int yaboot_set_bootpath(const char *imagepath, struct path_description *result)
+{
+ result->type = TYPE_UNSET;
+ return parse_device_path(imagepath, result);
+}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yaboot-22.8-r1099/second/yaboot.c new/yaboot-22.8-r1119/second/yaboot.c
--- old/yaboot-22.8-r1099/second/yaboot.c 2008-09-05 14:01:31.000000000 +0200
+++ new/yaboot-22.8-r1119/second/yaboot.c 2008-09-18 16:07:24.000000000 +0200
@@ -999,6 +999,7 @@
int result;
enum get_params_result gpr;
struct boot_param_t params;
+ struct path_description *kernel, *rd;
void *claim_base;
void *initrd_base;
unsigned long initrd_size;
@@ -1009,6 +1010,8 @@
char fw_nbr_reboots[4];
char *msg;
+ kernel = ¶ms.kernel;
+ rd = ¶ms.rd;
make_params_buffer = malloc(2048);
if (!make_params_buffer)
return;
@@ -1034,8 +1037,8 @@
prom_printf("Please wait, loading kernel...\n");
- msg = path_description_to_string(¶ms.kernel);
- result = open_file(¶ms.kernel, &file);
+ msg = path_description_to_string(kernel);
+ result = open_file(kernel, &file);
if (result != FILE_ERR_OK) {
if (msg) {
prom_perror(result, msg);
@@ -1070,7 +1073,7 @@
}
prom_printf(" Elf64 kernel loaded...\n");
} else {
- prom_printf("%s: Not a valid ELF image\n", params.kernel.filename);
+ prom_printf("%s: Not a valid ELF image\n", path_filename(kernel));
file.fs->close(&file);
gpr = GET_PARAMS_STOP;
continue;
@@ -1085,10 +1088,10 @@
* can't tell the size it will be so we claim an arbitrary amount
* of 4Mb.
*/
- if (params.rd.filename) {
+ if (path_filename(rd)) {
prom_printf("Loading ramdisk...\n");
- msg = path_description_to_string(¶ms.rd);
- result = open_file(¶ms.rd, &file);
+ msg = path_description_to_string(rd);
+ result = open_file(rd, &file);
if (result != FILE_ERR_OK) {
if (msg) {
prom_perror(result, msg);
@@ -1197,7 +1200,7 @@
return;
}
- if (!parse_device_path(bootpath, &default_device)) {
+ if (!yaboot_set_bootpath(bootpath, &default_device)) {
prom_printf("%s: Unable to parse\n", bootpath);
return;
}
@@ -1274,7 +1277,7 @@
sles9_base = prom_claim((void *)SLES9_ZIMAGE_BASE, SLES9_ZIMAGE_SIZE, 0);
if (sles9_base == (void*) - 1)
sles9_base = NULL;
- DEBUG_F("Allocated %08x bytes @ %p for SLES8/9 install file", SLES9_ZIMAGE_SIZE, sles9_base);
+ DEBUG_F("Allocated %08x bytes @ %p for SLES8/9 install file\n", SLES9_ZIMAGE_SIZE, sles9_base);
if (sles9_base)
addr = SLES9_ZIMAGE_BASE + SLES9_ZIMAGE_SIZE;
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yaboot-22.8-r1099/util/split_of_path.c new/yaboot-22.8-r1119/util/split_of_path.c
--- old/yaboot-22.8-r1099/util/split_of_path.c 2008-07-04 13:55:17.000000000 +0200
+++ new/yaboot-22.8-r1119/util/split_of_path.c 2008-09-15 14:03:44.000000000 +0200
@@ -1,4 +1,4 @@
-/* $Id: split_of_path.c 1084 2008-07-04 11:55:17Z olh $ */
+/* $Id: split_of_path.c 1103 2008-09-15 12:03:44Z olh $ */
#include
#include
@@ -96,6 +96,8 @@
"network:000.000.000.000,,000.000.000.000,000.000.000.000,00",
"network:speed=auto,duplex=auto,0.0.0.0,,0.0.0.0,0.0.0.0"
"network:speed=auto,duplex=auto,000.000.000.000,,000.000.000.000,000.000.000.000,5,5,255.255.255.000,512"
+ "network:bootp,0.0.0.0,,0.0.0.0"
+ "network:0.0.0.0,"
NULL,
};
static const char *file_paths[] = {
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
---------------------------------------------------------------------
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org