From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: oss-tools@pengutronix.de
Subject: [OSS-Tools] [PATCH] barebox-state: add new --update option to avoid writes if possible
Date: Thu, 8 Oct 2020 17:48:40 +0200 [thread overview]
Message-ID: <20201008154840.21531-1-a.fatoum@pengutronix.de> (raw)
barebox-state --set always writes the state when successful. Users
seeking to conserve write cycles thus have to --get the variable in
question first to check whether to write it. Make life of such users
easier by having barebox-state support this out-of-the-box.
Use of the new --update option will only write a variable if its
new and old value compare unequal. This allows users to fire and
forget execute barebox-state.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
src/barebox-state.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/src/barebox-state.c b/src/barebox-state.c
index cd56ce7192c3..09e054e25f8b 100644
--- a/src/barebox-state.c
+++ b/src/barebox-state.c
@@ -51,6 +51,8 @@ static char *__state_mac_get(struct state_variable *var);
static int __state_string_set(struct state_variable *var, const char *val);
static char *__state_string_get(struct state_variable *var);
+enum state_action { STATE_ACTION_GET, STATE_ACTION_SET, STATE_ACTION_UPDATE };
+
struct variable_str_type {
enum state_variable_type type;
char *type_name;
@@ -279,7 +281,8 @@ char *state_get_var(struct state *state, const char *var)
return vtype->get(sv);
}
-static int state_set_var(struct state *state, const char *var, const char *val)
+static int state_set_var(struct state *state, const char *var, const char *val,
+ enum state_action action)
{
struct state_variable *sv;
struct variable_str_type *vtype;
@@ -296,6 +299,18 @@ static int state_set_var(struct state *state, const char *var, const char *val)
if (!vtype->set)
return -EPERM;
+ if (action == STATE_ACTION_UPDATE) {
+ char *oldval = vtype->get(sv);
+
+ if (!IS_ERR(oldval)) {
+ if (!strcmp(oldval, val)) {
+ free(oldval);
+ return 0;
+ }
+ free(oldval);
+ }
+ }
+
ret = vtype->set(sv, val);
if (ret)
return ret;
@@ -387,6 +402,7 @@ enum opt {
static struct option long_options[] = {
{"get", required_argument, 0, 'g' },
{"set", required_argument, 0, 's' },
+ {"update", required_argument, 0, 'u' },
{"name", required_argument, 0, 'n' },
{"input", required_argument, 0, 'i' },
{"dump", no_argument, 0, 'd' },
@@ -407,6 +423,7 @@ static void usage(char *name)
"\n"
"-g, --get <variable> get the value of a variable\n"
"-s, --set <variable>=<value> set the value of a variable\n"
+"-u, --update <variable>=<value> update the value of a variable only if it changed\n"
"-n, --name <name> specify the state to use (default=\"state\"). Multiple states are allowed.\n"
"-i, --input <name> load the devicetree from a file instead of using the system devicetree.\n"
"-d, --dump dump the state\n"
@@ -425,7 +442,7 @@ static void usage(char *name)
struct state_set_get {
char *arg;
- int get;
+ enum state_action action;
struct list_head list;
};
@@ -456,7 +473,7 @@ int main(int argc, char *argv[])
INIT_LIST_HEAD(&state_list.list);
while (1) {
- c = getopt_long(argc, argv, "hg:s:i:dvn:qf", long_options, &option_index);
+ c = getopt_long(argc, argv, "hg:u:s:i:dvn:qf", long_options, &option_index);
if (c < 0)
break;
switch (c) {
@@ -468,13 +485,14 @@ int main(int argc, char *argv[])
exit(0);
case 'g':
sg = xzalloc(sizeof(*sg));
- sg->get = 1;
+ sg->action = STATE_ACTION_GET;
sg->arg = optarg;
list_add_tail(&sg->list, &sg_list);
break;
+ case 'u':
case 's':
sg = xzalloc(sizeof(*sg));
- sg->get = 0;
+ sg->action = c == 's' ? STATE_ACTION_SET : STATE_ACTION_UPDATE;
sg->arg = optarg;
list_add_tail(&sg->list, &sg_list);
readonly = false;
@@ -627,7 +645,7 @@ int main(int argc, char *argv[])
if (state == &state_list) {
state = list_first_entry(&state_list.list, struct state_list, list);
}
- if (sg->get) {
+ if (sg->action == STATE_ACTION_GET) {
char *val = state_get_var(state->state, arg);
if (!val) {
pr_err("no such variable: %s\n", arg);
@@ -647,7 +665,7 @@ int main(int argc, char *argv[])
goto out_unlock;
}
*val++ = '\0';
- ret = state_set_var(state->state, var, val);
+ ret = state_set_var(state->state, var, val, sg->action);
if (ret) {
pr_err("Failed to set variable %s in state %s to %s: %s\n",
var, state->name, val,
--
2.28.0
_______________________________________________
OSS-Tools mailing list
OSS-Tools@pengutronix.de
reply other threads:[~2020-10-08 15:48 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201008154840.21531-1-a.fatoum@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=oss-tools@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox