1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Mon, 27 Jul 2015 13:39:45 +0200
Subject: [PATCH] bootstate: set kernel option to name of boot target
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
common/bootstate.c | 60 ++++++++++++++++++++++++++++++++----------------------
1 file changed, 36 insertions(+), 24 deletions(-)
diff --git a/common/bootstate.c b/common/bootstate.c
index fde278262fa3..2dcc47cfa257 100644
--- a/common/bootstate.c
+++ b/common/bootstate.c
@@ -631,20 +631,8 @@ void _pr_flags(struct bootstate *bootstate, unsigned flags)
(verbose) ? _pr_flags(bootstate, flags) : 0; \
})
-/*
- * bootstate_get_target - create a new state instance from a device_node
- *
- * @bootstate the bootstate instance to work in
- * @flags supported flags:
- * BOOTCHOOSER_FLAG_VERBOSE
- * BOOTCHOOSER_FLAG_ATTEMPTS_KEEP
- * BOOTCHOOSER_FLAG_ATTEMPTS_DEC
- * BOOTCHOOSER_FLAG_ATTEMPTS_RESET
- * BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS
- * @target_out a string to the choosen boot target is returned via
- * this paramater
- */
-int bootstate_get_target(struct bootstate *bootstate, unsigned flags, char **target_out)
+static struct bootstate_target *bootstate_target_get(struct bootstate *bootstate,
+ unsigned flags)
{
struct bootstate_target *target;
int ret;
@@ -655,7 +643,7 @@ int bootstate_get_target(struct bootstate *bootstate, unsigned flags, char **tar
ret = bootstate_load(bootstate);
if (ret)
- return ret;
+ return ERR_PTR(ret);
if (flags & BOOTCHOOSER_FLAG_ATTEMPTS_RESET) {
list_for_each_entry(target, &bootstate->targets, list) {
@@ -710,7 +698,6 @@ int bootstate_get_target(struct bootstate *bootstate, unsigned flags, char **tar
}
found = true;
- *target_out = strdup(target->boot);
pr_debug("%s: selected target '%s', boot '%s'\n",
__func__, target->name, target->boot);
if (!v)
@@ -723,7 +710,33 @@ int bootstate_get_target(struct bootstate *bootstate, unsigned flags, char **tar
bootstate_save(bootstate);
if (!found)
- return -ENOENT;
+ return ERR_PTR(-ENOENT);
+
+ return target;
+}
+
+/*
+ * bootstate_get_target - create a new state instance from a device_node
+ *
+ * @bootstate the bootstate instance to work in
+ * @flags supported flags:
+ * BOOTCHOOSER_FLAG_VERBOSE
+ * BOOTCHOOSER_FLAG_ATTEMPTS_KEEP
+ * BOOTCHOOSER_FLAG_ATTEMPTS_DEC
+ * BOOTCHOOSER_FLAG_ATTEMPTS_RESET
+ * BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS
+ * @target_out a string to the choosen boot target is returned via
+ * this paramater
+ */
+int bootstate_get_target(struct bootstate *bootstate, unsigned flags, char **target_out)
+{
+ struct bootstate_target *target;
+
+ target = bootstate_target_get(bootstate, flags);
+ if (IS_ERR(target))
+ return PTR_ERR(target);
+
+ *target_out = strdup(target->boot);
return 0;
}
@@ -732,7 +745,7 @@ int bootstate_bootchooser(char *name, unsigned flags, unsigned timeout)
{
struct bootstate *bootstate;
bool v = flags & BOOTCHOOSER_FLAG_VERBOSE;
- char *target;
+ struct bootstate_target *target;
int ret;
if (!name)
@@ -765,16 +778,15 @@ int bootstate_bootchooser(char *name, unsigned flags, unsigned timeout)
while (true) {
char *cmd, *system;
- ret = bootstate_get_target(bootstate, flags, &target);
- if (ret)
- return ret;
+ target = bootstate_target_get(bootstate, flags);
+ if (IS_ERR(target))
+ return PTR_ERR(target);
- system = asprintf("bootstate.active=%s", target);
+ system = asprintf("bootstate.active=%s", target->name);
globalvar_add_simple("linux.bootargs.bootchooser", system);
free(system);
- cmd = asprintf("boot %s", target);
- free(target);
+ cmd = asprintf("boot %s", target->boot);
pr_info("%srunning: %s...\n",
flags & BOOTCHOOSER_FLAG_DRYRUN ? "not " : "", cmd);
if (!(flags & BOOTCHOOSER_FLAG_DRYRUN))
|