diff options
Diffstat (limited to 'common/environment.c')
-rw-r--r-- | common/environment.c | 90 |
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; |