blob: 6d81d83578a8cf49b81c81d8f566c7cbf49e42a1 [file] [log] [blame]
Patrick Williamsb48b7b42016-08-17 15:04:38 -05001From de9a6284df8add6ec03e1d9981d0b6d0595bbc69 Mon Sep 17 00:00:00 2001
2From: Andrea Adami <andrea.adami@gmail.com>
3Date: Mon, 10 Nov 2014 23:37:23 +0100
4Subject: [PATCH 4/4] kexecboot.c: workaround for absolute kernel and initrd
5 symlinks
6
7Add MOUNTPOINT prefix if the kernel/initrd symlinks start with '/'.
8Do nothing if the path is a relative symbolic link or not a symlink.
9
10Fix following situation:
11
12root@mizar:/var/tmp# ls -al boot/
13total 2076
14drwxr-xr-x 2 root root 4096 lug 5 01:38 .
15drwxrwxrwt 4 root root 4096 lug 5 12:26 ..
16-rw-r--r-- 1 root root 831 lug 5 01:24 boot.cfg
17-rw-r--r-- 1 root root 1322 lug 5 01:24 icon.xpm
18lrwxrwxrwx 1 root root 34 lug 5 12:26 zImage ->
19/boot/zImage-3.14.5-yocto-standard
20-rw-r--r-- 1 root root 2106832 lug 5 01:20 zImage-3.14.5-yocto-standard
21
22Cannot open `/mnt/boot/zImage': No such file or directory
23Nothing has been loaded!
24
25Signed-off-by: Andrea Adami <andrea.adami@gmail.com>
26---
27 kexecboot.c | 53 ++++++++++++++++++++++++++++++++++++++++++++---------
28 1 file changed, 44 insertions(+), 9 deletions(-)
29
30diff --git a/kexecboot.c b/kexecboot.c
31index 7268d6b..8a7a7d2 100644
32--- a/kexecboot.c
33+++ b/kexecboot.c
34@@ -208,11 +208,16 @@ void start_kernel(struct params_t *params, int choice)
35 const char *load_argv[] = { NULL, "-l", NULL, NULL, NULL, NULL };
36 const char *exec_argv[] = { NULL, "-e", NULL, NULL};
37
38- char *cmdline_arg = NULL, *initrd_arg = NULL;
39+ char *cmdline_arg = NULL, *initrd_arg = NULL, *kernel_arg = NULL;
40 int n, idx, u;
41 struct stat sinfo;
42 struct boot_item_t *item;
43
44+ /* buffer for readlink (could be truncated) */
45+ char buf[512];
46+ int len;
47+
48+
49 item = params->bootcfg->list[choice];
50
51 exec_argv[0] = kexec_path;
52@@ -306,10 +311,17 @@ void start_kernel(struct params_t *params, int choice)
53 }
54 }
55
56+ /* Mount boot device */
57+ if ( -1 == mount(mount_dev, mount_point, mount_fstype,
58+ MS_RDONLY, NULL) ) {
59+ perror("Can't mount boot device");
60+ exit(-1);
61+ }
62+
63 /* fill '--initrd' option */
64 if (item->initrd) {
65 /* allocate space */
66- n = sizeof(str_initrd_start) + strlen(item->initrd);
67+ n = sizeof(str_initrd_start) + strlen(item->initrd) + 1 + sizeof(mount_point) + sizeof(buf);
68
69 initrd_arg = (char *)malloc(n);
70 if (NULL == initrd_arg) {
71@@ -317,24 +329,46 @@ void start_kernel(struct params_t *params, int choice)
72 } else {
73 strcpy(initrd_arg, str_initrd_start); /* --initrd= */
74 strcat(initrd_arg, item->initrd);
75+
76+ if ((len = readlink(item->initrd, buf, sizeof(buf)-1)) != -1) {
77+ buf[len] = '\0';
78+ /* Fix absolute symlinks: prepend MOUNTPOINT */
79+ if (buf[0] == '/') {
80+ strcpy(initrd_arg, str_initrd_start); /* --initrd= */
81+ strcat(initrd_arg, mount_point);
82+ strcat(initrd_arg, buf);
83+ }
84+ }
85 load_argv[idx] = initrd_arg;
86 ++idx;
87 }
88 }
89
90 /* Append kernelpath as last arg of kexec */
91- load_argv[idx] = item->kernelpath;
92+ /* allocate space */
93+ n = strlen(item->kernelpath) + 1 + sizeof(mount_point) + sizeof(buf);
94+
95+ kernel_arg = (char *)malloc(n);
96+ if (NULL == kernel_arg) {
97+ perror("Can't allocate memory for kernel_arg");
98+ } else {
99+ strcpy(kernel_arg, item->kernelpath);
100+
101+ if ((len = readlink(item->kernelpath, buf, sizeof(buf)-1)) != -1) {
102+ buf[len] = '\0';
103+ /* Fix absolute symlinks: prepend MOUNTPOINT */
104+ if (buf[0] == '/') {
105+ strcpy(kernel_arg, mount_point);
106+ strcat(kernel_arg, buf);
107+ }
108+ }
109+ load_argv[idx] = kernel_arg;
110+ }
111
112 DPRINTF("load_argv: %s, %s, %s, %s, %s", load_argv[0],
113 load_argv[1], load_argv[2],
114 load_argv[3], load_argv[4]);
115
116- /* Mount boot device */
117- if ( -1 == mount(mount_dev, mount_point, mount_fstype,
118- MS_RDONLY, NULL) ) {
119- perror("Can't mount boot device");
120- exit(-1);
121- }
122
123 /* Load kernel */
124 n = fexecw(kexec_path, (char *const *)load_argv, envp);
125@@ -347,6 +381,7 @@ void start_kernel(struct params_t *params, int choice)
126
127 dispose(cmdline_arg);
128 dispose(initrd_arg);
129+ dispose(kernel_arg);
130
131 /* Check /proc/sys/net presence */
132 if ( -1 == stat("/proc/sys/net", &sinfo) ) {
133--
1341.9.1
135