1 9 files changed, 90 insertions(+), 33 deletions(-)
3 diff --git a/discover/kboot-parser.c b/discover/kboot-parser.c
4 index 23d48a4..7c7cb5d 100644
5 --- a/discover/kboot-parser.c
6 +++ b/discover/kboot-parser.c
7 @@ -133,7 +133,7 @@ static int kboot_parse(struct discover_context *dc)
8 conf = talloc_zero(dc, struct conf_context);
15 conf->global_options = kboot_global_options,
16 diff --git a/discover/parser.c b/discover/parser.c
17 index 2b4ddd2..8f2735c 100644
18 --- a/discover/parser.c
19 +++ b/discover/parser.c
20 @@ -13,16 +13,16 @@ extern struct parser __start_parsers[], __stop_parsers[];
21 void iterate_parsers(struct discover_context *ctx)
23 struct parser *parser;
24 + unsigned int count = 0;
26 pb_log("trying parsers for %s\n", ctx->device_path);
28 for (parser = __start_parsers; parser < __stop_parsers; parser++) {
29 pb_log("\ttrying parser '%s'\n", parser->name);
30 - /* just use a dummy device path for now */
31 - if (parser->parse(ctx))
33 + count += parser->parse(ctx);
35 - pb_log("\tno boot_options found\n");
37 + pb_log("\tno boot_options found\n");
40 static int compare_parsers(const void *a, const void *b)
41 diff --git a/discover/yaboot-parser.c b/discover/yaboot-parser.c
42 index 1000505..6101cd8 100644
43 --- a/discover/yaboot-parser.c
44 +++ b/discover/yaboot-parser.c
45 @@ -295,7 +295,7 @@ static int yaboot_parse(struct discover_context *dc)
46 conf = talloc_zero(dc, struct conf_context);
53 conf->global_options = yaboot_global_options,
54 diff --git a/lib/system/system.c b/lib/system/system.c
55 index 65bd6bf..7371445 100644
56 --- a/lib/system/system.c
57 +++ b/lib/system/system.c
58 @@ -20,6 +20,7 @@ const struct pb_system_apps pb_system_apps = {
60 .kexec = "/sbin/kexec",
61 .mount = "/bin/mount",
62 + .shutdown = "/sbin/shutdown",
63 .sftp = "/usr/bin/sftp",
64 .tftp = "/usr/bin/tftp",
65 .umount = "/bin/umount",
66 diff --git a/lib/system/system.h b/lib/system/system.h
67 index 47c7c02..1918309 100644
68 --- a/lib/system/system.h
69 +++ b/lib/system/system.h
70 @@ -5,6 +5,7 @@ struct pb_system_apps {
74 + const char *shutdown;
78 diff --git a/ui/common/discover-client.c b/ui/common/discover-client.c
79 index e8ce4dd..5b42b6c 100644
80 --- a/ui/common/discover-client.c
81 +++ b/ui/common/discover-client.c
82 @@ -46,7 +46,7 @@ struct discover_client* discover_client_init(
83 client->ops.cb_arg = cb_arg;
85 client->fd = socket(AF_UNIX, SOCK_STREAM, 0);
86 - if (!client->fd < 0) {
87 + if (client->fd < 0) {
88 pb_log("%s: socket: %s\n", __func__, strerror(errno));
91 diff --git a/ui/common/loader.c b/ui/common/loader.c
92 index 0fe62a0..5c69533 100644
93 --- a/ui/common/loader.c
94 +++ b/ui/common/loader.c
95 @@ -263,16 +263,22 @@ fail:
97 * pb_load_file - Loads a remote file and returns the local file path.
98 * @ctx: The talloc context to associate with the returned string.
99 + * @remote: The remote file URL.
100 + * @tempfile: An optional variable pointer to be set when a temporary local
103 * Returns the local file path in a talloc'ed character string on success,
107 -char *pb_load_file(void *ctx, const char *remote)
108 +char *pb_load_file(void *ctx, const char *remote, unsigned int *tempfile)
111 struct pb_url *url = pb_url_parse(NULL, remote);
119 @@ -280,19 +286,28 @@ char *pb_load_file(void *ctx, const char *remote)
122 local = pb_load_wget(ctx, url, 0);
123 + if (tempfile && local)
127 - local = pb_load_wget(ctx, url,
128 - wget_no_check_certificate);
129 + local = pb_load_wget(ctx, url, wget_no_check_certificate);
130 + if (tempfile && local)
134 local = pb_load_nfs(ctx, url);
135 + if (tempfile && local)
139 local = pb_load_sftp(ctx, url);
140 + if (tempfile && local)
144 local = pb_load_tftp(ctx, url);
145 + if (tempfile && local)
149 local = talloc_strdup(ctx, url->full);
150 diff --git a/ui/common/loader.h b/ui/common/loader.h
151 index b06bb43..42d4d4b 100644
152 --- a/ui/common/loader.h
153 +++ b/ui/common/loader.h
155 #if !defined(_PB_FILE_LOADER_H)
156 #define _PB_FILE_LOADER_H
158 -char *pb_load_file(void *ctx, const char *remote);
159 +char *pb_load_file(void *ctx, const char *remote, unsigned int *tempfile);
162 diff --git a/ui/common/ui-system.c b/ui/common/ui-system.c
163 index bd6dd31..0140f0e 100644
164 --- a/ui/common/ui-system.c
165 +++ b/ui/common/ui-system.c
167 #include "ui-system.h"
170 - * run_kexec_local - Final kexec helper.
171 + * kexec_load - kexec load helper.
172 * @l_image: The local image file for kexec to execute.
173 * @l_initrd: Optional local initrd file for kexec --initrd, can be NULL.
174 * @args: Optional command line args for kexec --append, can be NULL.
177 -static int run_kexec_local(const char *l_image, const char *l_initrd,
178 +static int kexec_load(const char *l_image, const char *l_initrd,
182 @@ -49,34 +49,64 @@ static int run_kexec_local(const char *l_image, const char *l_initrd,
186 - *p++ = pb_system_apps.kexec; /* 1 */
187 + *p++ = pb_system_apps.kexec; /* 1 */
188 + *p++ = "-l"; /* 2 */
191 s_initrd = talloc_asprintf(NULL, "--initrd=%s", l_initrd);
193 - *p++ = s_initrd; /* 2 */
194 + *p++ = s_initrd; /* 3 */
198 s_args = talloc_asprintf(NULL, "--append=%s", args);
200 - *p++ = s_args; /* 3 */
201 + *p++ = s_args; /* 4 */
204 - /* First try by telling kexec to run shutdown */
205 + *p++ = l_image; /* 5 */
206 + *p++ = NULL; /* 6 */
208 - *(p + 0) = l_image;
210 + result = pb_run_cmd(argv);
213 + pb_log("%s: failed: (%d)\n", __func__, result);
215 + talloc_free(s_initrd);
216 + talloc_free(s_args);
222 + * kexec_reboot - Helper to boot the new kernel.
224 + * Must only be called after a successful call to kexec_load().
227 +static int kexec_reboot(void)
230 + const char *argv[4];
233 + /* First try running shutdown. Init scripts should run 'exec -e' */
236 + *p++ = pb_system_apps.shutdown; /* 1 */
237 + *p++ = "-r"; /* 2 */
238 + *p++ = "now"; /* 3 */
239 + *p++ = NULL; /* 4 */
241 result = pb_run_cmd(argv);
243 - /* kexec will return zero on success */
244 - /* On error, force a kexec with the -f option */
245 + /* On error, force a kexec with the -e option */
248 - *(p + 0) = "-f"; /* 4 */
249 - *(p + 1) = l_image; /* 5 */
250 - *(p + 2) = NULL; /* 6 */
252 + *p++ = pb_system_apps.kexec; /* 1 */
253 + *p++ = "-e"; /* 2 */
254 + *p++ = NULL; /* 3 */
256 result = pb_run_cmd(argv);
258 @@ -84,9 +114,6 @@ static int run_kexec_local(const char *l_image, const char *l_initrd,
260 pb_log("%s: failed: (%d)\n", __func__, result);
262 - talloc_free(s_initrd);
263 - talloc_free(s_args);
268 @@ -99,31 +126,44 @@ int pb_run_kexec(const struct pb_kexec_data *kd)
270 char *l_image = NULL;
271 char *l_initrd = NULL;
272 + unsigned int clean_image = 0;
273 + unsigned int clean_initrd = 0;
275 pb_log("%s: image: '%s'\n", __func__, kd->image);
276 pb_log("%s: initrd: '%s'\n", __func__, kd->initrd);
277 pb_log("%s: args: '%s'\n", __func__, kd->args);
282 - l_image = pb_load_file(NULL, kd->image);
283 + l_image = pb_load_file(NULL, kd->image, &clean_image);
290 - l_initrd = pb_load_file(NULL, kd->initrd);
291 + l_initrd = pb_load_file(NULL, kd->initrd, &clean_initrd);
297 if (!l_image && !l_initrd)
301 + result = kexec_load(l_image, l_initrd, kd->args);
303 - result = run_kexec_local(l_image, l_initrd, kd->args);
310 talloc_free(l_image);
311 talloc_free(l_initrd);
314 + result = kexec_reboot();