summaryrefslogtreecommitdiffstats
path: root/discover/paths.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2013-09-25 14:23:39 +0800
committerJeremy Kerr <jk@ozlabs.org>2013-09-26 14:30:17 +0800
commitca5a62c1d04a3eea1d1c307d4fa4f0b1559140d2 (patch)
tree022367e0be0f9207dd4b7c4c87a3b85ea4717602 /discover/paths.c
parent7889b6f4bf81a1d2742c6f7d6fb9f6f603dd251e (diff)
downloadtalos-petitboot-ca5a62c1d04a3eea1d1c307d4fa4f0b1559140d2.tar.gz
talos-petitboot-ca5a62c1d04a3eea1d1c307d4fa4f0b1559140d2.zip
discover: Don't depend on tftp failure for type detection
Rather than always trying both TFTP client types, do a runtime detection on first invocation. This can be fixed at build-time with --with-tftp=TYPE. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'discover/paths.c')
-rw-r--r--discover/paths.c109
1 files changed, 69 insertions, 40 deletions
diff --git a/discover/paths.c b/discover/paths.c
index dbdf16e..82a82b1 100644
--- a/discover/paths.c
+++ b/discover/paths.c
@@ -186,6 +186,41 @@ fail:
return NULL;
}
+static enum tftp_type check_tftp_type(void *ctx)
+{
+ const char *argv[] = { pb_system_apps.tftp, "-V", NULL };
+ struct process *process;
+ enum tftp_type type;
+
+ process = process_create(ctx);
+ process->path = pb_system_apps.tftp;
+ process->argv = argv;
+ process->keep_stdout = true;
+ process_run_sync(process);
+
+ if (!process->stdout_buf || process->stdout_len == 0) {
+ pb_log("Can't check TFTP client type!\n");
+ type = TFTP_TYPE_BROKEN;
+
+ } else if (memmem(process->stdout_buf, process->stdout_len,
+ "tftp-hpa", strlen("tftp-hpa"))) {
+ pb_debug("Found TFTP client type: tftp-hpa\n");
+ type = TFTP_TYPE_HPA;
+
+ } else if (memmem(process->stdout_buf, process->stdout_len,
+ "BusyBox", strlen("BusyBox"))) {
+ pb_debug("Found TFTP client type: BusyBox tftp\n");
+ type = TFTP_TYPE_BUSYBOX;
+
+ } else {
+ pb_log("Unknown TFTP client type!\n");
+ type = TFTP_TYPE_BROKEN;
+ }
+
+ process_release(process);
+ return type;
+}
+
/**
* pb_load_tftp - Loads a remote file via tftp and returns the local file path.
*
@@ -202,24 +237,44 @@ static char *load_tftp(void *ctx, struct pb_url *url,
char *local;
struct process *process;
- local = local_name(ctx);
+ if (tftp_type == TFTP_TYPE_UNKNOWN)
+ tftp_type = check_tftp_type(ctx);
- if (!local)
+ if (tftp_type == TFTP_TYPE_BROKEN)
return NULL;
- /* first try busybox tftp args */
+ local = local_name(ctx);
+ if (!local)
+ return NULL;
- p = argv;
- *p++ = pb_system_apps.tftp; /* 1 */
- *p++ = "-g"; /* 2 */
- *p++ = "-l"; /* 3 */
- *p++ = local; /* 4 */
- *p++ = "-r"; /* 5 */
- *p++ = url->path; /* 6 */
- *p++ = url->host; /* 7 */
- if (url->port)
- *p++ = url->port; /* 8 */
- *p++ = NULL; /* 9 */
+ if (tftp_type == TFTP_TYPE_BUSYBOX) {
+ /* first try busybox tftp args */
+
+ p = argv;
+ *p++ = pb_system_apps.tftp; /* 1 */
+ *p++ = "-g"; /* 2 */
+ *p++ = "-l"; /* 3 */
+ *p++ = local; /* 4 */
+ *p++ = "-r"; /* 5 */
+ *p++ = url->path; /* 6 */
+ *p++ = url->host; /* 7 */
+ if (url->port)
+ *p++ = url->port; /* 8 */
+ *p++ = NULL; /* 9 */
+ } else {
+ p = argv;
+ *p++ = pb_system_apps.tftp; /* 1 */
+ *p++ = "-m"; /* 2 */
+ *p++ = "binary"; /* 3 */
+ *p++ = url->host; /* 4 */
+ if (url->port)
+ *p++ = url->port; /* 5 */
+ *p++ = "-c"; /* 6 */
+ *p++ = "get"; /* 7 */
+ *p++ = url->path; /* 8 */
+ *p++ = local; /* 9 */
+ *p++ = NULL; /* 10 */
+ }
if (url_data) {
process = process_create(ctx);
@@ -237,32 +292,6 @@ static char *load_tftp(void *ctx, struct pb_url *url,
if (!result)
return local;
- /* next try tftp-hpa args */
- p = argv;
- *p++ = pb_system_apps.tftp; /* 1 */
- *p++ = "-m"; /* 2 */
- *p++ = "binary"; /* 3 */
- *p++ = url->host; /* 4 */
- if (url->port)
- *p++ = url->port; /* 5 */
- *p++ = "-c"; /* 6 */
- *p++ = "get"; /* 7 */
- *p++ = url->path; /* 8 */
- *p++ = local; /* 9 */
- *p++ = NULL; /* 10 */
-
- if (url_data) {
- process->argv = argv;
- result = process_run_async(process);
- if (result)
- process_release(process);
- } else {
- result = process_run_simple_argv(ctx, argv);
- }
-
- if (!result)
- return local;
-
talloc_free(local);
return NULL;
}
OpenPOWER on IntegriCloud