On 08/22/2017 06:15 PM, [ext] Reichel Andreas wrote:
From: Andreas Reichel <[email protected]>
From: Reichel Andreas <[email protected]>
* Change API to use one state function
Provide one function to set and one to get the global update state
instead of six different.
* env: Remove BGENVTYPE from code
Since different storage backends come with different .c files, there
is no need for switch cases.
* move some functions to simplify API dependencies
Signed-off-by: Andreas Reichel <[email protected]>
---
env/env_api_fat.c | 297 ++++++++++++++++++++++++++++---------
include/env_api.h | 30 ++--
swupdate-adapter/ebgenv.c | 367 ++++++----------------------------------------
swupdate-adapter/ebgenv.h | 43 ++----
tools/bg_setenv.c | 14 +-
tools/tests/Makefile | 2 +-
tools/tests/test_api.c | 79 +++++-----
7 files changed, 354 insertions(+), 478 deletions(-)
diff --git a/env/env_api_fat.c b/env/env_api_fat.c
index de82b8c..ec97b14 100644
--- a/env/env_api_fat.c
+++ b/env/env_api_fat.c
@@ -17,6 +17,27 @@ const char *tmp_mnt_dir = "/tmp/mnt-XXXXXX";
static bool verbosity = false;
+static EBGENVKEY bgenv_str2enum(char *key)
+{
+ if (strncmp(key, "kernelfile", strlen("kernelfile") + 1) == 0) {
+ return EBGENV_KERNELFILE;
+ }
+ if (strncmp(key, "kernelparams", strlen("kernelparams") + 1) == 0) {
+ return EBGENV_KERNELPARAMS;
+ }
+ if (strncmp(key, "watchdog_timeout_sec",
+ strlen("watchdog_timeout_sec") + 1) == 0) {
+ return EBGENV_WATCHDOG_TIMEOUT_SEC;
+ }
+ if (strncmp(key, "revision", strlen("revision") + 1) == 0) {
+ return EBGENV_REVISION;
+ }
+ if (strncmp(key, "ustate", strlen("ustate") + 1) == 0) {
+ return EBGENV_USTATE;
+ }
+ return EBGENV_UNKNOWN;
+}
+
void be_verbose(bool v)
{
verbosity = v;
@@ -347,89 +368,72 @@ bool write_env(CONFIG_PART *part, BG_ENVDATA *env)
return result;
}
-CONFIG_PART config_parts[ENV_NUM_CONFIG_PARTS];
-BG_ENVDATA oldenvs[ENV_NUM_CONFIG_PARTS];
+static CONFIG_PART config_parts[ENV_NUM_CONFIG_PARTS];
+static BG_ENVDATA oldenvs[ENV_NUM_CONFIG_PARTS];
-bool bgenv_init(BGENVTYPE type)
+bool bgenv_init()
{
- switch (type) {
- case BGENVTYPE_FAT:
- memset((void *)&config_parts, 0,
- sizeof(CONFIG_PART) * ENV_NUM_CONFIG_PARTS);
- /* enumerate all config partitions */
- if (!probe_config_partitions(config_parts)) {
- VERBOSE(stderr, "Error finding config partitions.\n");
- return false;
- }
- for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
- read_env(&config_parts[i], &oldenvs[i]);
- uint32_t sum = crc32(0, (Bytef *)&oldenvs[i],
- sizeof(BG_ENVDATA) - sizeof(oldenvs[i].crc32));
- if (oldenvs[i].crc32 != sum) {
- VERBOSE(stderr, "Invalid CRC32!\n");
- continue;
- }
+ memset((void *)&config_parts, 0,
+ sizeof(CONFIG_PART) * ENV_NUM_CONFIG_PARTS);
+ /* enumerate all config partitions */
+ if (!probe_config_partitions(config_parts)) {
+ VERBOSE(stderr, "Error finding config partitions.\n");
+ return false;
+ }
+ for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
+ read_env(&config_parts[i], &oldenvs[i]);
+ uint32_t sum = crc32(0, (Bytef *)&oldenvs[i],
+ sizeof(BG_ENVDATA) - sizeof(oldenvs[i].crc32));
+ if (oldenvs[i].crc32 != sum) {
+ VERBOSE(stderr, "Invalid CRC32!\n");
A point for the TODO or TODISCUSS list: I would be in favor of informing
the user of broken environments per default. I would classify this
message as a 'WARNING'. Everything over and including the 'NOTICE' log
priority should be printed without the 'verbose' option IMO. Maybe use a
logging framework.
Just had a quick search. This might be a nice framework:
https://github.com/dhess/c-logging those are 2 files under the CC0
license and compatible to syslog. Should be easy to include into this
project.
+ continue;
}
- return true;
}
- return false;
+ return true;
}
-BGENV *bgenv_get_by_index(BGENVTYPE type, uint32_t index)
+BGENV *bgenv_open_by_index(uint32_t index)
{
BGENV *handle;
- switch (type) {
- case BGENVTYPE_FAT:
- /* get config partition by index and allocate handle */
- if (index >= ENV_NUM_CONFIG_PARTS) {
- return NULL;
- }
- if (!(handle = calloc(1, sizeof(BGENV)))) {
- return NULL;
- }
- handle->desc = (void *)&config_parts[index];
- handle->data = &oldenvs[index];
- handle->type = type;
- return handle;
+ /* get config partition by index and allocate handle */
+ if (index >= ENV_NUM_CONFIG_PARTS) {
+ return NULL;
}
- return NULL;
+ if (!(handle = calloc(1, sizeof(BGENV)))) {
+ return NULL;
+ }
+ handle->desc = (void *)&config_parts[index];
+ handle->data = &oldenvs[index];
+ return handle;
}
-BGENV *bgenv_get_oldest(BGENVTYPE type)
+BGENV *bgenv_open_oldest()
{
uint32_t minrev = 0xFFFFFFFF;
uint32_t min_idx = 0;
- switch (type) {
- case BGENVTYPE_FAT:
- for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
- if (oldenvs[i].revision < minrev) {
- minrev = oldenvs[i].revision;
- min_idx = i;
- }
+ for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
+ if (oldenvs[i].revision < minrev) {
+ minrev = oldenvs[i].revision;
+ min_idx = i;
}
- return bgenv_get_by_index(type, min_idx);
}
- return NULL;
+ return bgenv_open_by_index(min_idx);
}
-BGENV *bgenv_get_latest(BGENVTYPE type)
+BGENV *bgenv_open_latest()
{
uint32_t maxrev = 0;
uint32_t max_idx = 0;
- switch (type) {
- case BGENVTYPE_FAT:
- for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
- if (oldenvs[i].revision > maxrev) {
- maxrev = oldenvs[i].revision;
- max_idx = i;
- }
+ for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
+ if (oldenvs[i].revision > maxrev) {
+ maxrev = oldenvs[i].revision;
+ max_idx = i;
}
- return bgenv_get_by_index(type, max_idx);
}
- return NULL;
+ return bgenv_open_by_index(max_idx);
}
bool bgenv_write(BGENV *env)
@@ -439,23 +443,19 @@ bool bgenv_write(BGENV *env)
if (!env) {
return false;
}
- switch (env->type) {
- case BGENVTYPE_FAT:
- part = (CONFIG_PART *)env->desc;
- if (!part) {
- VERBOSE(
- stderr,
- "Invalid config partition to store environment.\n");
- return false;
- }
- if (!write_env(part, env->data)) {
- VERBOSE(stderr, "Could not write to %s\n",
- part->devpath);
- return false;
- }
- return true;
+ part = (CONFIG_PART *)env->desc;
+ if (!part) {
+ VERBOSE(
+ stderr,
+ "Invalid config partition to store environment.\n");
+ return false;
}
- return false;
+ if (!write_env(part, env->data)) {
+ VERBOSE(stderr, "Could not write to %s\n",
+ part->devpath);
+ return false;
+ }
+ return true;
}
BG_ENVDATA *bgenv_read(BGENV *env)
@@ -474,3 +474,154 @@ bool bgenv_close(BGENV *env)
}
return false;
}
+
+int bgenv_get(BGENV *env, char *key, char **type, void *data, size_t maxlen)
+{
+ EBGENVKEY e;
+
+ if (!key || !data || maxlen == 0) {
+ return EINVAL;
+ }
+ e = bgenv_str2enum(key);
+ if (e == EBGENV_UNKNOWN) {
+ return EINVAL;
+ }
+ if (!env) {
+ return EPERM;
+ }
+ switch (e) {
+ case EBGENV_KERNELFILE:
+ str16to8(data, env->data->kernelfile);
+ if (type) {
+ sprintf(*type, "char*");
+ }
+ break;
+ case EBGENV_KERNELPARAMS:
+ str16to8(data, env->data->kernelparams);
+ if (type) {
+ sprintf(*type, "char*");
+ }
+ break;
+ case EBGENV_WATCHDOG_TIMEOUT_SEC:
+ sprintf(data, "%lu", env->data->watchdog_timeout_sec);
+ if (type) {
+ sprintf(*type, "uint16_t");
+ }
+ break;
+ case EBGENV_REVISION:
+ sprintf(data, "%lu", env->data->revision);
+ if (type) {
+ sprintf(*type, "uint32_t");
+ }
+ break;
+ case EBGENV_USTATE:
+ sprintf(data, "%u", env->data->ustate);
+ if (type) {
+ sprintf(*type, "uint16_t");
+ }
+ break;
+ default:
+ return EINVAL;
+ }
+ return 0;
+}
+
+int bgenv_set(BGENV *env, char *key, char *type, void *data, size_t datalen)
+{
+ EBGENVKEY e;
+ int val;
+ char *p;
+ char *value = (char *)data;
+
+ if (!key || !data || datalen == 0) {
+ return EINVAL;
+ }
+
+ e = bgenv_str2enum(key);
+ if (e == EBGENV_UNKNOWN) {
+ return EINVAL;
+ }
+ if (!env) {
+ return EPERM;
+ }
+ switch (e) {
+ case EBGENV_REVISION:
+ errno = 0;
Setting errno to zero not needed here, I assume.
+ val = strtol(value, &p, 10);
+ if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) ||
+ (errno != 0 && val == 0)) {
+ return errno;
+ }
+ if (p == value) {
+ return EINVAL;
+ }
+ env->data->revision = val;
+ break;
+ case EBGENV_KERNELFILE:
+ str8to16(env->data->kernelfile, value);
+ break;
+ case EBGENV_KERNELPARAMS:
+ str8to16(env->data->kernelparams, value);
+ break;
+ case EBGENV_WATCHDOG_TIMEOUT_SEC:
+ errno = 0;
+ val = strtol(value, &p, 10);
+ if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) ||
+ (errno != 0 && val == 0)) {
+ return errno;
+ }
+ if (p == value) {
+ return EINVAL;
+ }
+ env->data->watchdog_timeout_sec = val;
+ break;
+ case EBGENV_USTATE:
+ errno = 0;
+ val = strtol(value, &p, 10);
Maybe allow "NORMAL", "TESTING", "FAILED" here as well. Makes it much
more readable.
+ if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) ||
+ (errno != 0 && val == 0)) {
+ return errno;
+ }
+ if (p == value) {
+ return EINVAL;
+ }
+ env->data->ustate = val;
+ break;
+ default:
+ return EINVAL;
+ }
+ return 0;
+}
+
+BGENV *bgenv_create_new()
+{
+ BGENV *env_latest;
+ BGENV *env_new;
+
+ env_latest = bgenv_open_latest();
+ if (!env_latest)
+ goto create_new_io_error;
+
+ int new_rev = env_latest->data->revision + 1;
+
+ if (!bgenv_close(env_latest))
+ goto create_new_io_error;
+
+ env_new = bgenv_open_oldest();
+ if (!env_new)
+ goto create_new_io_error;
+
+ /* zero fields */
+ memset(env_new->data, 0, sizeof(BG_ENVDATA));
+ /* update revision field and testing mode */
+ env_new->data->revision = new_rev;
+ env_new->data->ustate = 1;
+ /* set default watchdog timeout */
+ env_new->data->watchdog_timeout_sec = 30;
+
+ return env_new;
+
+create_new_io_error:
+ errno = EIO;
+ return NULL;
+}
diff --git a/include/env_api.h b/include/env_api.h
index 3e78ed3..b9bc15d 100644
--- a/include/env_api.h
+++ b/include/env_api.h
@@ -10,8 +10,8 @@
* the COPYING file in the top-level directory.
*/
-#ifndef __BG_UTILS_H__
-#define __BG_UTILS_H__
+#ifndef __ENV_API_H__
+#define __ENV_API_H__
#include <stddef.h>
#include <stdint.h>
@@ -47,7 +47,14 @@
if (verbosity) \
fprintf(o, __VA_ARGS__)
-typedef enum { BGENVTYPE_FAT } BGENVTYPE;
+typedef enum {
+ EBGENV_KERNELFILE,
+ EBGENV_KERNELPARAMS,
+ EBGENV_WATCHDOG_TIMEOUT_SEC,
+ EBGENV_REVISION,
+ EBGENV_USTATE,
+ EBGENV_UNKNOWN
+} EBGENVKEY;
typedef struct {
char *devpath;
@@ -56,7 +63,6 @@ typedef struct {
} CONFIG_PART;
typedef struct {
- BGENVTYPE type;
void *desc;
BG_ENVDATA *data;
} BGENV;
@@ -66,12 +72,18 @@ extern void be_verbose(bool v);
extern char *str16to8(char *buffer, wchar_t *src);
extern wchar_t *str8to16(wchar_t *buffer, char *src);
-extern bool bgenv_init(BGENVTYPE type);
-extern BGENV *bgenv_get_by_index(BGENVTYPE type, uint32_t index);
-extern BGENV *bgenv_get_oldest(BGENVTYPE type);
-extern BGENV *bgenv_get_latest(BGENVTYPE type);
+extern bool bgenv_init(void);
+extern BGENV *bgenv_open_by_index(uint32_t index);
+extern BGENV *bgenv_open_oldest(void);
+extern BGENV *bgenv_open_latest(void);
extern bool bgenv_write(BGENV *env);
extern BG_ENVDATA *bgenv_read(BGENV *env);
extern bool bgenv_close(BGENV *env);
-#endif // __BG_UTILS_H__
+extern BGENV *bgenv_create_new(void);
+extern int bgenv_get(BGENV *env, char *key, char **type, void *data,
+ size_t maxlen);
+extern int bgenv_set(BGENV *env, char *key, char *type, void *data,
+ size_t datalen);
+
+#endif // __ENV_API_H__
diff --git a/swupdate-adapter/ebgenv.c b/swupdate-adapter/ebgenv.c
index 951bdc7..2c3d52c 100644
--- a/swupdate-adapter/ebgenv.c
+++ b/swupdate-adapter/ebgenv.c
@@ -14,81 +14,10 @@
#include "ebgdefs.h"
#include "ebgenv.h"
-typedef enum {
- EBGENV_KERNELFILE,
- EBGENV_KERNELPARAMS,
- EBGENV_WATCHDOG_TIMEOUT_SEC,
- EBGENV_REVISION,
- EBGENV_USTATE,
- EBGENV_UNKNOWN
-} EBGENVKEY;
-
static BGENV *env_current = NULL;
-typedef struct _PCOLLECTOR {
- void *p;
- struct _PCOLLECTOR *next;
-} PCOLLECTOR;
-
-static PCOLLECTOR ebg_gc;
-
static bool ebg_new_env_created = false;
-static bool ebg_gc_addpointer(void *pnew)
-{
- PCOLLECTOR *pc = &ebg_gc;
-
- while (pc->next) {
- pc = pc->next;
- }
- pc->next = calloc(sizeof(PCOLLECTOR), 1);
- if (!pc->next) {
- return false;
- }
- pc = pc->next;
- pc->p = pnew;
- return true;
-}
-
-static void ebg_gc_cleanup()
-{
- PCOLLECTOR *pc = &ebg_gc;
-
- while (pc) {
- if (pc->p) {
- free(pc->p);
- }
- PCOLLECTOR *tmp = pc;
- pc = pc->next;
- if (tmp != &ebg_gc) {
- free(tmp);
- }
- }
- ebg_gc.p = NULL;
- ebg_gc.next = NULL;
-}
-
-static EBGENVKEY ebg_env_str2enum(char *key)
-{
- if (strncmp(key, "kernelfile", strlen("kernelfile") + 1) == 0) {
- return EBGENV_KERNELFILE;
- }
- if (strncmp(key, "kernelparams", strlen("kernelparams") + 1) == 0) {
- return EBGENV_KERNELPARAMS;
- }
- if (strncmp(key, "watchdog_timeout_sec",
- strlen("watchdog_timeout_sec") + 1) == 0) {
- return EBGENV_WATCHDOG_TIMEOUT_SEC;
- }
- if (strncmp(key, "revision", strlen("revision") + 1) == 0) {
- return EBGENV_REVISION;
- }
- if (strncmp(key, "ustate", strlen("ustate") + 1) == 0) {
- return EBGENV_USTATE;
- }
- return EBGENV_UNKNOWN;
-}
-
void ebg_beverbose(bool v)
{
be_verbose(v);
@@ -96,313 +25,113 @@ void ebg_beverbose(bool v)
int ebg_env_create_new(void)
{
- /* initialize garbage collector */
- ebg_gc.p = NULL;
- ebg_gc.next = NULL;
-
- if (!bgenv_init(BGENVTYPE_FAT)) {
+ if (!bgenv_init()) {
return EIO;
}
- env_current = bgenv_get_latest(BGENVTYPE_FAT);
-
- if (ebg_new_env_created)
- return env_current == NULL ? EIO : 0;
-
- if (!env_current) {
- return EIO;
+ if (!ebg_new_env_created) {
+ env_current = bgenv_create_new();
}
- /* first time env is opened, a new one is created for update
- * purpose */
- int new_rev = env_current->data->revision + 1;
- if (!bgenv_close(env_current)) {
- return EIO;
- }
- env_current = bgenv_get_oldest(BGENVTYPE_FAT);
- if (!env_current) {
- return EIO;
- }
- /* zero fields */
- memset(env_current->data, 0, sizeof(BG_ENVDATA));
- /* update revision field and testing mode */
- env_current->data->revision = new_rev;
- env_current->data->ustate = 1;
- /* set default watchdog timeout */
- env_current->data->watchdog_timeout_sec = 30;
- ebg_new_env_created = true;
+ ebg_new_env_created = env_current != NULL;
- return env_current == NULL ? EIO : 0;
+ return env_current == NULL ? errno : 0;
}
int ebg_env_open_current(void)
{
- /* initialize garbage collector */
- ebg_gc.p = NULL;
- ebg_gc.next = NULL;
-
- if (!bgenv_init(BGENVTYPE_FAT)) {
+ if (!bgenv_init()) {
return EIO;
}
- env_current = bgenv_get_latest(BGENVTYPE_FAT);
+ env_current = bgenv_open_latest();
return env_current == NULL ? EIO : 0;
}
-char *ebg_env_get(char *key)
+int ebg_env_get(char *key, char *buffer)
{
- EBGENVKEY e;
- char *buffer;
-
- if (!key) {
- errno = EINVAL;
- return NULL;
- }
- e = ebg_env_str2enum(key);
- if (e == EBGENV_UNKNOWN) {
- errno = EINVAL;
- return NULL;
- }
- if (!env_current) {
- errno = EPERM;
- return NULL;
- }
- switch (e) {
- case EBGENV_KERNELFILE:
- buffer = (char *)malloc(ENV_STRING_LENGTH);
- if (!buffer) {
- errno = ENOMEM;
- return NULL;
- }
- if (!ebg_gc_addpointer(buffer)) {
- errno = ENOMEM;
- return NULL;
- };
- str16to8(buffer, env_current->data->kernelfile);
- return buffer;
- case EBGENV_KERNELPARAMS:
- buffer = (char *)malloc(ENV_STRING_LENGTH);
- if (!buffer) {
- errno = ENOMEM;
- return NULL;
- }
- if (!ebg_gc_addpointer(buffer)) {
- errno = ENOMEM;
- return NULL;
- }
- str16to8(buffer, env_current->data->kernelparams);
- return buffer;
- case EBGENV_WATCHDOG_TIMEOUT_SEC:
- if (asprintf(&buffer, "%lu",
- env_current->data->watchdog_timeout_sec) < 0) {
- errno = ENOMEM;
- return NULL;
- }
- if (!ebg_gc_addpointer(buffer)) {
- errno = ENOMEM;
- return NULL;
- }
- return buffer;
- case EBGENV_REVISION:
- if (asprintf(&buffer, "%lu", env_current->data->revision) < 0) {
- errno = ENOMEM;
- return NULL;
- }
- if (!ebg_gc_addpointer(buffer)) {
- errno = ENOMEM;
- return NULL;
- }
- return buffer;
- case EBGENV_USTATE:
- if (asprintf(&buffer, "%u", env_current->data->ustate) < 0) {
- errno = ENOMEM;
- return NULL;
- }
- if (!ebg_gc_addpointer(buffer)) {
- errno = ENOMEM;
- return NULL;
- }
- return buffer;
- default:
- errno = EINVAL;
- return NULL;
- }
- errno = EINVAL;
- return NULL;
+ return bgenv_get(env_current, key, NULL, buffer, ENV_STRING_LENGTH);
}
int ebg_env_set(char *key, char *value)
{
- EBGENVKEY e;
- int val;
- char *p;
-
- if (!key || !value) {
- return EINVAL;
- }
- e = ebg_env_str2enum(key);
- if (e == EBGENV_UNKNOWN) {
- return EINVAL;
- }
- if (!env_current) {
- return EPERM;
- }
- switch (e) {
- case EBGENV_REVISION:
- errno = 0;
- val = strtol(value, &p, 10);
- if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) ||
- (errno != 0 && val == 0)) {
- return errno;
- }
- if (p == value) {
- return EINVAL;
- }
- env_current->data->revision = val;
- break;
- case EBGENV_KERNELFILE:
- str8to16(env_current->data->kernelfile, value);
- break;
- case EBGENV_KERNELPARAMS:
- str8to16(env_current->data->kernelparams, value);
- break;
- case EBGENV_WATCHDOG_TIMEOUT_SEC:
- errno = 0;
- val = strtol(value, &p, 10);
- if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) ||
- (errno != 0 && val == 0)) {
- return errno;
- }
- if (p == value) {
- return EINVAL;
- }
- env_current->data->watchdog_timeout_sec = val;
- break;
- case EBGENV_USTATE:
- errno = 0;
- val = strtol(value, &p, 10);
- if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) ||
- (errno != 0 && val == 0)) {
- return errno;
- }
- if (p == value) {
- return EINVAL;
- }
- env_current->data->ustate = val;
- break;
- default:
- return EINVAL;
- }
- return 0;
+ return bgenv_set(env_current, key, "String", value, strlen(value));
}
-bool ebg_env_isupdatesuccessful(void)
+uint16_t ebg_env_getglobalstate()
{
+ BGENV *env;
+ int res = 4;
I would like an enum here and/or some documentation or at least a better
variable name than 'res'. Magic number
+
/* find all environments with revision 0 */
for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
- BGENV *env = bgenv_get_by_index(BGENVTYPE_FAT, i);
+ BGENV *env = bgenv_open_by_index(i);
if (!env) {
continue;
}
/* update was unsuccessful if there is a revision 0 config,
- * with
- * testing and boot_once set */
+ * with ustate == 3 */
Since you have some defines for the ustate, why not use them in the
documentation as well.
if (env->data->revision == REVISION_FAILED &&
env->data->ustate == 3) {
and in the code. (But I have made this point in a previous patch already.)
Claudius
(void)bgenv_close(env);
- return false;
+ res = 3;
}
(void)bgenv_close(env);
- }
- return true;
-}
-
-int ebg_env_clearerrorstate(void)
-{
- for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
- BGENV *env = bgenv_get_by_index(BGENVTYPE_FAT, i);
-
- if (!env) {
- continue;
- }
- if (env->data->revision == REVISION_FAILED &&
- env->data->ustate == 3) {
- env->data->ustate = 0;
- if (!bgenv_write(env)) {
- (void)bgenv_close(env);
- return EIO;
- }
- }
- if (!bgenv_close(env)) {
- return EIO;
+ if (res == 3) {
+ return res;
}
}
- return 0;
-}
-int ebg_env_confirmupdate(void)
-{
- return ebg_env_set("ustate", "0");
-}
-
-bool ebg_env_isokay(void)
-{
- BGENV *env;
- bool res = false;
-
- env = bgenv_get_latest(BGENVTYPE_FAT);
+ env = bgenv_open_latest();
if (!env) {
errno = EIO;
return res;
}
- if (env->data->ustate == 0) {
- res = true;
- }
+
+ res = env->data->ustate;
bgenv_close(env);
+
return res;
}
-bool ebg_env_isinstalled(void)
+int ebg_env_setglobalstate(uint16_t ustate)
{
- BGENV *env;
- bool res = false;
+ char buffer[2];
+ int res;
- env = bgenv_get_latest(BGENVTYPE_FAT);
- if (!env) {
- errno = EIO;
- return res;
- }
- if (env->data->ustate == 1) {
- res = true;
+ if (ustate > 3) {
+ return EINVAL;
}
- bgenv_close(env);
- return res;
-}
-
-bool ebg_env_istesting(void)
-{
- BGENV *env;
- bool res = false;
+ snprintf(buffer, sizeof(buffer), "%d", ustate);
+ res =
+ bgenv_set(env_current, "ustate", "String", buffer, strlen(buffer));
- env = bgenv_get_latest(BGENVTYPE_FAT);
- if (!env) {
- errno = EIO;
+ if (ustate != 0) {
return res;
}
- if (env->data->ustate == 2) {
- res = true;
+
+ for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
+ BGENV *env = bgenv_open_by_index(i);
+
+ if (!env) {
+ continue;
+ }
+ env->data->ustate = ustate;
+ if (!bgenv_write(env)) {
+ (void)bgenv_close(env);
+ return EIO;
+ }
+ if (!bgenv_close(env)) {
+ return EIO;
+ }
}
- bgenv_close(env);
- return res;
+ return 0;
}
int ebg_env_close(void)
{
- /* free all allocated memory */
- ebg_gc_cleanup();
-
/* if no environment is open, just return EIO */
if (!env_current) {
return EIO;
diff --git a/swupdate-adapter/ebgenv.h b/swupdate-adapter/ebgenv.h
index 97c23db..db20dda 100644
--- a/swupdate-adapter/ebgenv.h
+++ b/swupdate-adapter/ebgenv.h
@@ -36,12 +36,10 @@ int ebg_env_open_current(void);
/** @brief Retrieve variable content
* @param key an enum constant to specify the variable
- * @return a pointer to the buffer with the variable content on success,
- * NULL on failure. The returned pointer must not be freed and is freed
- * automatically on closing the environment. If NULL is returned, errno is
- * set.
+ * @buffer pointer to buffer containing requested value
+ * @return 0 on success, errno on failure
*/
-char *ebg_env_get(char *key);
+int ebg_env_get(char *key, char* buffer);
/** @brief Store new content into variable
* @param key name of the environment variable to set
@@ -50,36 +48,17 @@ char *ebg_env_get(char *key);
*/
int ebg_env_set(char *key, char *value);
-/** @brief Check if last update was successful
- * @return true if successful, false if not
- */
-bool ebg_env_isupdatesuccessful(void);
-
-/** @brief Reset all stored failure states
- * @return 0 if successful, errno on failure
- */
-int ebg_env_clearerrorstate(void);
-
-/** @brief Check if active env is clean
- * @return true if yes, errno set on failure
- */
-bool ebg_env_isokay(void);
-
-/** @brief Check if active env has state 'installed'
- * @return true if yes, errno set on failure
- */
-bool ebg_env_isinstalled(void);
-
-/** @brief Check if active env is in testing state
- * @return true if yes, errno set on failure
+/** @brief Get global ustate value, accounting for all environments
+ * @return ustate value
*/
-bool ebg_env_istesting(void);
+uint16_t ebg_env_getglobalstate(void);
-/** @brief Confirm environment after update - sets testing and boot_once
- * both to 0
- * @return 0 if successful, errno on failure
+/** @brief Set global ustate value, accounting for all environments
+ * if state is set to zero and updating only current environment
+ * if state is set to a non-zero value.
+ * @return errno on error, 0 if okay.
*/
-int ebg_env_confirmupdate(void);
+int ebg_env_setglobalstate(uint16_t ustate);
/** @brief Closes environment and finalize library. Changes are written
* before closing.
diff --git a/tools/bg_setenv.c b/tools/bg_setenv.c
index ad11138..7efd759 100644
--- a/tools/bg_setenv.c
+++ b/tools/bg_setenv.c
@@ -244,7 +244,7 @@ int main(int argc, char **argv)
}
int result = 0;
if (!arguments.output_to_file) {
- if (!bgenv_init(BGENVTYPE_FAT)) {
+ if (!bgenv_init()) {
fprintf(stderr,
"Error initializing FAT environment.\n");
return 1;
@@ -254,7 +254,7 @@ int main(int argc, char **argv)
printf("\n----------------------------\n");
printf(" Config Partition #%d ", i);
}
- BGENV *env = bgenv_get_by_index(BGENVTYPE_FAT, i);
+ BGENV *env = bgenv_open_by_index(i);
if (env) {
if (verbosity) {
dump_env(env->data);
@@ -272,7 +272,7 @@ int main(int argc, char **argv)
BGENV *env_current;
if (auto_update) {
/* search latest and oldest revision */
- env_current = bgenv_get_latest(BGENVTYPE_FAT);
+ env_current = bgenv_open_latest();
if (!env_current) {
fprintf(stderr, "Failed to retrieve "
"latest "
@@ -282,7 +282,7 @@ int main(int argc, char **argv)
arguments.tmpdata.revision =
env_current->data->revision + 1;
- env_new = bgenv_get_oldest(BGENVTYPE_FAT);
+ env_new = bgenv_open_oldest();
if (!env_new) {
fprintf(stderr, "Failed to retrieve "
"oldest "
@@ -316,12 +316,10 @@ int main(int argc, char **argv)
}
} else {
if (part_specified) {
- env_new = bgenv_get_by_index(
- BGENVTYPE_FAT,
+ env_new = bgenv_open_by_index(
arguments.which_part);
} else {
- env_new =
- bgenv_get_latest(BGENVTYPE_FAT);
+ env_new = bgenv_open_latest();
}
if (!env_new) {
fprintf(stderr, "Failed to retrieve "
diff --git a/tools/tests/Makefile b/tools/tests/Makefile
index 9c0af09..5c4b334 100644
--- a/tools/tests/Makefile
+++ b/tools/tests/Makefile
@@ -67,7 +67,7 @@ MOCKOBJS_test_api = $(ENV_API)
MOCKOBJS_SYMBOLS_$(ENV_API)-test_partitions = probe_config_file
MOCKOBJS_SYMBOLS_$(ENV_API)-test_environment = oldenvs configparts fopen
fclose fread fwrite feof mount_partition
-MOCKOBJS_SYMBOLS_$(ENV_API)-test_api = bgenv_init bgenv_write bgenv_close
bgenv_get_latest bgenv_get_by_index bgenv_get_oldest
+MOCKOBJS_SYMBOLS_$(ENV_API)-test_api = bgenv_init bgenv_write bgenv_close
bgenv_open_latest bgenv_open_by_index bgenv_open_oldest
MOCKOBJS_SYMBOLS_ebgpart-test_partitions = ped_device_probe_all
ped_device_get_next ped_disk_next_partition
TEST_TARGETS = test_partitions.target test_environment.target test_api.target
diff --git a/tools/tests/test_api.c b/tools/tests/test_api.c
index 53e573d..dfabdac 100644
--- a/tools/tests/test_api.c
+++ b/tools/tests/test_api.c
@@ -30,11 +30,8 @@ static BG_ENVDATA dataupdate = {0};
static int test_env_revision = 42;
static char *test_env_revision_str = "42";
-bool bgenv_init(BGENVTYPE type)
+bool bgenv_init()
{
- if (type != BGENVTYPE_FAT) {
- return false;
- }
return true;
}
@@ -48,17 +45,20 @@ bool bgenv_close(BGENV *env_current)
return true;
}
-BGENV *bgenv_get_by_index(BGENVTYPE type, uint32_t index)
+BGENV *bgenv_open_by_index(uint32_t index)
{
- return &envupdate;
+ if (index == 1) {
+ return &envupdate;
+ }
+ return &env;
}
-BGENV *bgenv_get_latest(BGENVTYPE type)
+BGENV *bgenv_open_latest()
{
return mock_ptr_type(BGENV *);
}
-BGENV *bgenv_get_oldest(BGENVTYPE type)
+BGENV *bgenv_open_oldest()
{
return mock_ptr_type(BGENV *);
}
@@ -67,21 +67,21 @@ static void test_api_openclose(void **state)
{
int ret;
- will_return(bgenv_get_latest, &env);
+ will_return(bgenv_open_latest, &env);
ret = ebg_env_open_current();
assert_int_equal(ret, 0);
will_return(bgenv_write, true);
ret = ebg_env_close();
assert_int_equal(ret, 0);
- will_return(bgenv_get_latest, &env);
+ will_return(bgenv_open_latest, &env);
ret = ebg_env_open_current();
assert_int_equal(ret, 0);
will_return(bgenv_write, false);
ret = ebg_env_close();
assert_int_equal(ret, EIO);
- will_return(bgenv_get_latest, NULL);
+ will_return(bgenv_open_latest, NULL);
ret = ebg_env_open_current();
assert_int_equal(ret, EIO);
ret = ebg_env_close();
@@ -93,8 +93,9 @@ static void test_api_openclose(void **state)
static void test_api_accesscurrent(void **state)
{
int ret;
+ char buffer[4096];
- will_return(bgenv_get_latest, &env);
+ will_return(bgenv_open_latest, &env);
ret = ebg_env_open_current();
assert_int_equal(ret, 0);
will_return(bgenv_write, true);
@@ -107,7 +108,7 @@ static void test_api_accesscurrent(void **state)
ret = ebg_env_set("kernelfile", "vmlinuz");
assert_int_equal(ret, EPERM);
- will_return(bgenv_get_latest, &env);
+ will_return(bgenv_open_latest, &env);
ret = ebg_env_open_current();
assert_int_equal(ret, 0);
@@ -121,20 +122,23 @@ static void test_api_accesscurrent(void **state)
ret = ebg_env_close();
assert_int_equal(ret, 0);
- char *value;
- value = ebg_env_get("kernelfile");
- assert_null(value);
- assert_int_equal(errno, EPERM);
+ ret = ebg_env_get("kernelfile", buffer);
+ assert_int_equal(ret, EPERM);
- will_return(bgenv_get_latest, &env);
+ will_return(bgenv_open_latest, &env);
ret = ebg_env_open_current();
assert_int_equal(ret, 0);
- assert_string_equal(ebg_env_get("kernelfile"), "vmlinuz");
- assert_string_equal(ebg_env_get("kernelparams"), "root=/dev/sda");
- assert_string_equal(ebg_env_get("watchdog_timeout_sec"), "13");
- assert_string_equal(ebg_env_get("ustate"), "1");
- assert_string_equal(ebg_env_get("revision"), test_env_revision_str);
+ assert_int_equal(ebg_env_get("kernelfile", buffer), 0);
+ assert_string_equal(buffer, "vmlinuz");
+ assert_int_equal(ebg_env_get("kernelparams", buffer), 0);
+ assert_string_equal(buffer, "root=/dev/sda");
+ assert_int_equal(ebg_env_get("watchdog_timeout_sec", buffer), 0);
+ assert_string_equal(buffer, "13");
+ assert_int_equal(ebg_env_get("ustate", buffer), 0);
+ assert_string_equal(buffer, "1");
+ assert_int_equal(ebg_env_get("revision", buffer), 0);
+ assert_string_equal(buffer, test_env_revision_str);
will_return(bgenv_write, true);
ret = ebg_env_close();
@@ -145,8 +149,8 @@ static void test_api_accesscurrent(void **state)
static void test_api_update(void **state)
{
- will_return(bgenv_get_latest, &env);
- will_return(bgenv_get_oldest, &envupdate);
+ will_return(bgenv_open_latest, &env);
+ will_return(bgenv_open_oldest, &envupdate);
assert_int_equal(ebg_env_create_new(), 0);
assert_int_equal(envupdate.data->revision, test_env_revision + 1);
@@ -155,21 +159,24 @@ static void test_api_update(void **state)
assert_int_equal(envupdate.data->ustate, 1);
assert_int_equal(ebg_env_set("ustate", "2"), 0);
- assert_int_equal(ebg_env_confirmupdate(), 0);
+ for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
+ will_return(bgenv_write, true);
+ }
+ assert_int_equal(ebg_env_setglobalstate(0), 0);
+ if (ENV_NUM_CONFIG_PARTS == 1) {
+ will_return(bgenv_open_latest, &envupdate);
+ }
assert_int_equal(ebg_env_set("revision", "0"), 0);
assert_int_equal(ebg_env_set("ustate", "3"), 0);
- assert_false(ebg_env_isupdatesuccessful());
+ assert_int_equal(ebg_env_getglobalstate(), 3);
- assert_int_equal(ebg_env_set("revision", "0"), 0);
- assert_int_equal(ebg_env_set("ustate", "0"), 0);
- assert_true(ebg_env_isupdatesuccessful());
-
- assert_int_equal(ebg_env_set("revision", "0"), 0);
- assert_int_equal(ebg_env_set("ustate", "3"), 0);
- will_return(bgenv_write, true);
- assert_int_equal(ebg_env_clearerrorstate(), 0);
- assert_true(ebg_env_isupdatesuccessful());
+ will_return(bgenv_open_latest, &env);
+ for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
+ will_return(bgenv_write, true);
+ }
+ assert_int_equal(ebg_env_setglobalstate(0), 0);
+ assert_int_equal(ebg_env_getglobalstate(), 0);
will_return(bgenv_write, true);
assert_int_equal(ebg_env_close(), 0);
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-54 Fax: (+49)-8142-66989-80 Email: [email protected]
--
You received this message because you are subscribed to the Google Groups "EFI Boot
Guard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/efibootguard-dev/2536adb3-8bb6-1ba7-0329-ca6289b21ca7%40siemens.com.
For more options, visit https://groups.google.com/d/optout.