@@ -33,6 +33,7 @@
#include "pctl.h"
#include "generated/autoconf.h"
#include "state.h"
+#include "swupdate_vars.h"
#ifdef CONFIG_SYSTEMD
#include <systemd/sd-daemon.h>
@@ -451,6 +452,7 @@ void *network_thread (void *data)
struct subprocess_msg_elem *subprocess_msg;
bool should_close_socket;
struct swupdate_cfg *cfg;
+ char *varvalue;
if (!instp) {
TRACE("Fatal error: Network thread aborting...");
@@ -690,6 +692,21 @@ void *network_thread (void *data)
msg.data.msg[0] = get_state();
msg.type = ACK;
break;
+ case SET_SWUPDATE_VARS:
+ msg.type = swupdate_vars_set(msg.data.vars.varname,
+ msg.data.vars.varvalue,
+ msg.data.vars.varnamespace) == 0 ? ACK : NACK;
+ break;
+ case GET_SWUPDATE_VARS:
+ varvalue = swupdate_vars_get(msg.data.vars.varname,
+ msg.data.vars.varnamespace);
+ memset(msg.data.vars.varvalue, 0, sizeof(msg.data.vars.varvalue));
+ if (varvalue) {
+ strlcpy(msg.data.vars.varvalue, varvalue, sizeof(msg.data.vars.varvalue));
+ msg.type = ACK;
+ } else
+ msg.type = NACK;
+ break;
default:
msg.type = NACK;
}
@@ -17,11 +17,13 @@
#include <dirent.h>
#include "generated/autoconf.h"
#include "util.h"
-#include "dlfcn.h"
-#include "bootloader.h"
+#include "pctl.h"
+#include <network_ipc.h>
#include "swupdate_vars.h"
+char *namespace_default = NULL;
+
static inline void libuboot_cleanup(struct uboot_ctx *ctx)
{
libuboot_close(ctx);
@@ -32,8 +34,11 @@ int swupdate_vars_initialize(struct uboot_ctx **ctx, const char *namespace)
{
int ret;
- if (!namespace)
- return -EINVAL;
+ if (!namespace || !strlen(namespace)) {
+ if(!namespace_default)
+ return -EINVAL;
+ namespace = namespace_default;
+ }
ret = libuboot_read_config_ext(ctx, get_fwenv_config());
if (ret) {
@@ -50,7 +55,7 @@ int swupdate_vars_initialize(struct uboot_ctx **ctx, const char *namespace)
return 0;
}
-char *swupdate_vars_get(const char *name, const char *namespace)
+static char *__swupdate_vars_get(const char *name, const char *namespace)
{
int ret;
struct uboot_ctx *ctx = NULL;
@@ -65,7 +70,32 @@ char *swupdate_vars_get(const char *name, const char *namespace)
return value;
}
-int swupdate_vars_set(const char *name, const char *value, const char *namespace)
+char *swupdate_vars_get(const char *name, const char *namespace)
+{
+ if (!name)
+ return NULL;
+
+ if (pid == getpid())
+ {
+ ipc_message msg;
+ memset(&msg, 0, sizeof(msg));
+
+ msg.type = GET_SWUPDATE_VARS;
+ if (namespace)
+ strlcpy(msg.data.vars.varnamespace, namespace, sizeof(msg.data.vars.varnamespace));
+ strlcpy(msg.data.vars.varname, name, sizeof(msg.data.vars.varname));
+
+ if (ipc_send_cmd(&msg) || msg.type == NACK) {
+ ERROR("Failed to get variable %s", name);
+ return NULL;
+ }
+ return strdup (msg.data.vars.varvalue);
+ }
+
+ return __swupdate_vars_get(name, namespace);
+}
+
+static int __swupdate_vars_set(const char *name, const char *value, const char *namespace)
{
int ret;
struct uboot_ctx *ctx = NULL;
@@ -81,6 +111,28 @@ int swupdate_vars_set(const char *name, const char *value, const char *namespace
return ret;
}
+int swupdate_vars_set(const char *name, const char *value, const char *namespace)
+{
+ ipc_message msg;
+
+ if (!name)
+ return -EINVAL;
+
+ if (pid == getpid()) {
+ memset(&msg, 0, sizeof(msg));
+ msg.magic = IPC_MAGIC;
+ msg.type = SET_SWUPDATE_VARS;
+ if (namespace)
+ strlcpy(msg.data.vars.varnamespace, namespace, sizeof(msg.data.vars.varnamespace));
+ strlcpy(msg.data.vars.varname, name, sizeof(msg.data.vars.varname));
+ if (value)
+ strlcpy(msg.data.vars.varvalue, value, sizeof(msg.data.vars.varvalue));
+ return !(ipc_send_cmd(&msg) == 0 && msg.type == ACK);
+ }
+
+ return __swupdate_vars_set(name, value, namespace);
+}
+
int swupdate_vars_unset(const char *name, const char *namespace)
{
return swupdate_vars_set(name, NULL, namespace);
@@ -91,6 +143,10 @@ int swupdate_vars_apply_list(const char *filename, const char *namespace)
int ret;
struct uboot_ctx *ctx = NULL;
+ if (pid == getpid()) {
+ ERROR("This function can be called only by core !");
+ return -EINVAL;
+ }
ret = swupdate_vars_initialize(&ctx, namespace);
if (!ret) {
libuboot_load_file(ctx, filename);
@@ -8,9 +8,11 @@
#pragma once
#include <libuboot.h>
+#include <stdbool.h>
int swupdate_vars_initialize(struct uboot_ctx **ctx, const char *namespace);
int swupdate_vars_apply_list(const char *filename, const char *namespace);
char *swupdate_vars_get(const char *name, const char *namespace);
int swupdate_vars_set(const char *name, const char *value, const char *namespace);
int swupdate_vars_unset(const char *name, const char *namespace);
+bool swupdate_set_default_namespace(const char *namespace);
Access to SWUPdate's vars (namespace) is guaranteed for the core, but other processes could need to store some values to store a state between runs. This is not possible from subprocess because rights are not guaranteed for the namespace's storage. Add an IPC as done for bootloader environment to let subprocesses to store persistently variables. Signed-off-by: Stefano Babic <stefano.babic@swupdate.org> --- core/network_thread.c | 17 +++++++++++ core/swupdate_vars.c | 68 +++++++++++++++++++++++++++++++++++++---- include/swupdate_vars.h | 2 ++ 3 files changed, 81 insertions(+), 6 deletions(-)