summaryrefslogtreecommitdiffstats
path: root/common/environment.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/environment.c')
-rw-r--r--common/environment.c90
1 files changed, 80 insertions, 10 deletions
diff --git a/common/environment.c b/common/environment.c
index 0d31f5b4f7..39cad0c16a 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -26,8 +26,10 @@
#include <environment.h>
#include <globalvar.h>
#include <libfile.h>
+#include <block.h>
+#include <efi/partition.h>
+#include <bootsource.h>
#else
-# define errno_str(x) ("void")
#define EXPORT_SYMBOL(x)
#endif
@@ -49,15 +51,83 @@ struct action_data {
#define TMPDIR "/.defaultenv"
-static char *default_environment_path = "/dev/env0";
+static char *default_environment_path;
-void default_environment_path_set(char *path)
+void default_environment_path_set(const char *path)
{
- default_environment_path = path;
+ free(default_environment_path);
+
+ default_environment_path = xstrdup(path);
}
-char *default_environment_path_get(void)
+static guid_t partition_barebox_env_guid = PARTITION_BAREBOX_ENVIRONMENT_GUID;
+
+/*
+ * default_environment_path_search - look for environment partition
+ *
+ * This searches for a barebox environment partition on block devices. barebox
+ * environment partitions are recognized by the guid
+ * 6c3737f2-07f8-45d1-ad45-15d260aab24d. The device barebox itself has booted
+ * from is preferred over other devices.
+ *
+ * @return: The cdev providing the environment of found, NULL otherwise
+ */
+static struct cdev *default_environment_path_search(void)
{
+ struct cdev *part;
+ struct device_node *boot_node;
+ int max_score = 0;
+ struct cdev *env_cdev = NULL;
+ struct block_device *blk;
+
+ if (!IS_ENABLED(CONFIG_BLOCK))
+ return NULL;
+
+ boot_node = bootsource_of_node_get(NULL);
+
+ if (boot_node) {
+ struct device *dev;
+
+ dev = of_find_device_by_node(boot_node);
+ if (dev)
+ device_detect(dev);
+ }
+
+ for_each_block_device(blk) {
+ int score = 0;
+
+ part = cdev_find_child_by_gpt_typeuuid(&blk->cdev,
+ &partition_barebox_env_guid);
+ if (IS_ERR(part))
+ continue;
+
+ score++;
+
+ if (boot_node && boot_node == blk->cdev.device_node)
+ score++;
+
+ if (score > max_score) {
+ max_score = score;
+ env_cdev = part;
+ }
+ }
+
+ return env_cdev;
+}
+
+const char *default_environment_path_get(void)
+{
+ struct cdev *cdev;
+
+ if (default_environment_path)
+ return default_environment_path;
+
+ cdev = default_environment_path_search();
+ if (cdev)
+ default_environment_path = basprintf("/dev/%s", cdev->name);
+ else
+ default_environment_path = xstrdup("/dev/env0");
+
return default_environment_path;
}
@@ -297,7 +367,7 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags)
envfd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if (envfd < 0) {
- printf("could not open %s: %s\n", filename, errno_str());
+ printf("could not open %s: %m\n", filename);
ret = -errno;
goto out1;
}
@@ -306,7 +376,7 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags)
/* ENOSYS and EOPNOTSUPP aren't errors here, many devices don't need it */
if (ret && errno != ENOSYS && errno != EOPNOTSUPP) {
- printf("could not unprotect %s: %s\n", filename, errno_str());
+ printf("could not unprotect %s: %m\n", filename);
goto out;
}
@@ -314,7 +384,7 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags)
/* ENOSYS and EOPNOTSUPP aren't errors here, many devices don't need it */
if (ret && errno != ENOSYS && errno != EOPNOTSUPP) {
- printf("could not erase %s: %s\n", filename, errno_str());
+ printf("could not erase %s: %m\n", filename);
goto out;
}
@@ -337,7 +407,7 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags)
/* ENOSYS and EOPNOTSUPP aren't errors here, many devices don't need it */
if (ret && errno != ENOSYS && errno != EOPNOTSUPP) {
- printf("could not protect %s: %s\n", filename, errno_str());
+ printf("could not protect %s: %m\n", filename);
goto out;
}
@@ -385,7 +455,7 @@ int envfs_load(const char *filename, const char *dir, unsigned flags)
envfd = open(filename, O_RDONLY);
if (envfd < 0) {
- printf("environment load %s: %s\n", filename, errno_str());
+ printf("environment load %s: %m\n", filename);
if (errno == ENOENT)
printf("Maybe you have to create the partition.\n");
return -1;