mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/2] efivarfs: rework the filesystem to make it human readable
@ 2017-03-03 15:27 Jean-Christophe PLAGNIOL-VILLARD
  2017-03-03 15:31 ` [PATCH 1/2] ls: allow to list a symlink ending with '/' as a dir Jean-Christophe PLAGNIOL-VILLARD
  2017-03-09 14:38 ` [PATCH 0/2] " Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 2 replies; 7+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-03 15:27 UTC (permalink / raw)
  To: barebox

Hi,

efivarfs: rework the filesystem to make it human readable

today we use <varname>-<guid as %pUl>

such as Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c

now we will use a different approach where will represent first the vendor
as a directory and then inside the associates variable.

But also create symlink on the vendor with readable name.

so it will look like this:

barebox@barebox EFI payload:/ ls -l /efivars/
drwxrwxrwx             36 04b37fe8-f6ae-480b-bdd5-37d98c5e89aa
drwxrwxrwx             36 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
drwxrwxrwx             36 4c19049f-4137-4dd3-9c10-8b97a83ffdfa
drwxrwxrwx             36 5b446ed1-e30b-4faa-871a-3654eca36080
drwxrwxrwx             36 5b91f69c-8b88-4a2b-9269-5f1d802b5175
drwxrwxrwx             36 8be4df61-93ca-11d2-aa0d-00e098032b8c
lrwxrwxrwx              3 Efi -> 8be4df61-93ca-11d2-aa0d-00e098032b8c
lrwxrwxrwx              7 barebox -> 5b91f69c-8b88-4a2b-9269-5f1d802b5175
drwxrwxrwx             36 eb704011-1402-11d3-8e77-00a0c969723b
lrwxrwxrwx              7 systemd -> 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
barebox@barebox EFI payload:/ ls -l /efivars/Efi/
-rw-rw-rw-             62 Boot0000
-rw-rw-rw-             80 Boot0001
-rw-rw-rw-             84 Boot0002
-rw-rw-rw-            106 Boot0003
-rw-rw-rw-            108 Boot0004
-rw-rw-rw-            141 Boot0005
-rw-rw-rw-             88 Boot0006
-rw-rw-rw-              2 BootCurrent
-rw-rw-rw-              4 BootOptionSupport
-rw-rw-rw-             14 BootOrder
-rw-rw-rw-            107 ConIn
-rw-rw-rw-           1567 ConInDev
-rw-rw-rw-            103 ConOut
-rw-rw-rw-           1855 ConOutDev
-rw-rw-rw-             73 ErrOut
-rw-rw-rw-           1563 ErrOutDev
-rw-rw-rw-             14 Key0000
-rw-rw-rw-             14 Key0001
-rw-rw-rw-              4 Lang
-rw-rw-rw-             13 LangCodes
-rw-rw-rw-              8 OsIndicationsSupported
-rw-rw-rw-              3 PlatformLang
-rw-rw-rw-             18 PlatformLangCodes
-rw-rw-rw-            108 PlatformRecovery0000
-rw-rw-rw-              2 Timeout
barebox@barebox EFI payload:/ ls -l /efivars/barebox/
barebox@barebox EFI payload:/ ls -l /efivars/systemd/
-rw-rw-rw-             14 LoaderTimeInitUSec

please pull

The following changes since commit f14af7444ad9d8ce674382f222119f5fcd3f2576:

  efi: add veriable to report secure boot support and status (2017-02-28 23:05:31 +0800)

are available in the git repository at:

  git://git.jcrosoft.org/barebox.git delivery/efivarfs

for you to fetch changes up to a757520bfccf17064181ebc15646efdb83ee581b:

  efivarfs: rework the filesystem to make it human readable (2017-03-01 00:15:38 +0800)

----------------------------------------------------------------
Jean-Christophe PLAGNIOL-VILLARD (2):
      ls: allow to list a symlink ending with '/' as a dir
      efivarfs: rework the filesystem to make it human readable

 commands/ls.c     |  41 +++++++++++++++++----
 common/efi-guid.c |  17 +++++++--
 common/efi/efi.c  |   2 +-
 fs/efivarfs.c     | 379 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------
 include/efi.h     |   1 +
 5 files changed, 347 insertions(+), 93 deletions(-)

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] ls: allow to list a symlink ending with '/' as a dir
  2017-03-03 15:27 [PATCH 0/2] efivarfs: rework the filesystem to make it human readable Jean-Christophe PLAGNIOL-VILLARD
@ 2017-03-03 15:31 ` Jean-Christophe PLAGNIOL-VILLARD
  2017-03-03 15:31   ` [PATCH 2/2] efivarfs: rework the filesystem to make it human readable Jean-Christophe PLAGNIOL-VILLARD
  2017-03-09 14:38 ` [PATCH 0/2] " Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 1 reply; 7+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-03 15:31 UTC (permalink / raw)
  To: barebox

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 commands/ls.c | 41 +++++++++++++++++++++++++++++++++++------
 1 file changed, 35 insertions(+), 6 deletions(-)

diff --git a/commands/ls.c b/commands/ls.c
index 331a4d201..3bd5e3ff8 100644
--- a/commands/ls.c
+++ b/commands/ls.c
@@ -64,6 +64,16 @@ int ls(const char *path, ulong flags)
 	if (flags & LS_SHOWARG && s.st_mode & S_IFDIR)
 		printf("%s:\n", path);
 
+	if (S_ISLNK(s.st_mode)) {
+		int len = strlen(path);
+			
+		if (path[len - 1] != '/') {
+			ls_one(path, path, &s);
+			return 0;
+		}
+		s.st_mode |= S_IFDIR;
+	}
+
 	if (!(s.st_mode & S_IFDIR)) {
 		ls_one(path, path, &s);
 		return 0;
@@ -171,13 +181,25 @@ static int do_ls(int argc, char *argv[])
 			continue;
 		}
 
-		if (!(s.st_mode & S_IFDIR)) {
-			if (flags & LS_COLUMN)
-				string_list_add_sorted(&sl, argv[o]);
-			else
-				ls_one(argv[o], argv[o], &s);
+		if (s.st_mode & S_IFDIR) {
+			o++;
+			continue;
 		}
 
+		if (s.st_mode & S_IFLNK) {
+			int len = strlen(argv[o]);
+			
+			if (argv[o][len - 1] == '/') {
+			    o++;
+			    continue;
+			}
+		}
+
+		if (flags & LS_COLUMN)
+			string_list_add_sorted(&sl, argv[o]);
+		else
+			ls_one(argv[o], argv[o], &s);
+
 		o++;
 	}
 
@@ -197,7 +219,14 @@ static int do_ls(int argc, char *argv[])
 			continue;
 		}
 
-		if (s.st_mode & S_IFDIR) {
+		if (s.st_mode & S_IFDIR || s.st_mode & S_IFLNK) {
+			int len = strlen(argv[o]);
+			
+			if (s.st_mode & S_IFLNK && argv[o][len - 1] != '/') {
+				o++;
+				continue;
+			}
+
 			ret = ls(argv[o], flags);
 			if (ret) {
 				perror("ls");
-- 
2.11.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/2] efivarfs: rework the filesystem to make it human readable
  2017-03-03 15:31 ` [PATCH 1/2] ls: allow to list a symlink ending with '/' as a dir Jean-Christophe PLAGNIOL-VILLARD
@ 2017-03-03 15:31   ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 7+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-03 15:31 UTC (permalink / raw)
  To: barebox

today we use <varname>-<guid as %pUl>

such as Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c

now we will use a different approach where will represent first the vendor
as a directory and then inside the associates variable.

But also create symlink on the vendor with readable name.

so it will look like this:

barebox@barebox EFI payload:/ ls -l /efivars/
drwxrwxrwx             36 04b37fe8-f6ae-480b-bdd5-37d98c5e89aa
drwxrwxrwx             36 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
drwxrwxrwx             36 4c19049f-4137-4dd3-9c10-8b97a83ffdfa
drwxrwxrwx             36 5b446ed1-e30b-4faa-871a-3654eca36080
drwxrwxrwx             36 5b91f69c-8b88-4a2b-9269-5f1d802b5175
drwxrwxrwx             36 8be4df61-93ca-11d2-aa0d-00e098032b8c
lrwxrwxrwx              3 Efi -> 8be4df61-93ca-11d2-aa0d-00e098032b8c
lrwxrwxrwx              7 barebox -> 5b91f69c-8b88-4a2b-9269-5f1d802b5175
drwxrwxrwx             36 eb704011-1402-11d3-8e77-00a0c969723b
lrwxrwxrwx              7 systemd -> 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
barebox@barebox EFI payload:/ ls -l /efivars/Efi/
-rw-rw-rw-             62 Boot0000
-rw-rw-rw-             80 Boot0001
-rw-rw-rw-             84 Boot0002
-rw-rw-rw-            106 Boot0003
-rw-rw-rw-            108 Boot0004
-rw-rw-rw-            141 Boot0005
-rw-rw-rw-             88 Boot0006
-rw-rw-rw-              2 BootCurrent
-rw-rw-rw-              4 BootOptionSupport
-rw-rw-rw-             14 BootOrder
-rw-rw-rw-            107 ConIn
-rw-rw-rw-           1567 ConInDev
-rw-rw-rw-            103 ConOut
-rw-rw-rw-           1855 ConOutDev
-rw-rw-rw-             73 ErrOut
-rw-rw-rw-           1563 ErrOutDev
-rw-rw-rw-             14 Key0000
-rw-rw-rw-             14 Key0001
-rw-rw-rw-              4 Lang
-rw-rw-rw-             13 LangCodes
-rw-rw-rw-              8 OsIndicationsSupported
-rw-rw-rw-              3 PlatformLang
-rw-rw-rw-             18 PlatformLangCodes
-rw-rw-rw-            108 PlatformRecovery0000
-rw-rw-rw-              2 Timeout
barebox@barebox EFI payload:/ ls -l /efivars/barebox/
barebox@barebox EFI payload:/ ls -l /efivars/systemd/
-rw-rw-rw-             14 LoaderTimeInitUSec

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 common/efi-guid.c |  17 ++-
 common/efi/efi.c  |   2 +-
 fs/efivarfs.c     | 379 ++++++++++++++++++++++++++++++++++++++++++------------
 include/efi.h     |   1 +
 4 files changed, 312 insertions(+), 87 deletions(-)

diff --git a/common/efi-guid.c b/common/efi-guid.c
index 71aa21ddd..6908012df 100644
--- a/common/efi-guid.c
+++ b/common/efi-guid.c
@@ -14,11 +14,21 @@ efi_guid_t efi_systemd_vendor_guid = EFI_SYSTEMD_VENDOR_GUID;
 
 #define EFI_GUID_STRING(guid, short, long) do {	\
 	if (!efi_guidcmp(guid, *g))		\
-		return long;			\
+		return is_long ? long : short;			\
 	} while(0)
 
+
 const char *efi_guid_string(efi_guid_t *g)
 {
+	const char *name;
+
+	name = efi_guid_string_type(g, 1);
+
+	return name ? name : "Unknown";
+}
+
+const char *efi_guid_string_type(efi_guid_t *g, int is_long)
+{
 	EFI_GUID_STRING(EFI_NULL_GUID, "NULL", "NULL GUID");
 	EFI_GUID_STRING(EFI_MPS_TABLE_GUID, "MPS Table", "MPS Table GUID in EFI System Table");
 	EFI_GUID_STRING(EFI_ACPI_TABLE_GUID, "ACPI Table", "ACPI 1.0 Table GUID in EFI System Table");
@@ -88,5 +98,8 @@ const char *efi_guid_string(efi_guid_t *g)
 	EFI_GUID_STRING(EFI_ISCSIDXE_INF_GUID, "IScsiDxe.inf", "EFI IScsiDxe.inf File GUID");
 	EFI_GUID_STRING(EFI_VLANCONFIGDXE_INF_GUID, "VlanConfigDxe.inf", "EFI VlanConfigDxe.inf File GUID");
 
-	return "unknown";
+	EFI_GUID_STRING(EFI_BAREBOX_VENDOR_GUID, "barebox", "Barebox Bootloader");
+	EFI_GUID_STRING(EFI_SYSTEMD_VENDOR_GUID, "systemd", "Linux systemd");
+
+	return NULL;
 }
diff --git a/common/efi/efi.c b/common/efi/efi.c
index 05c58250f..b4a5bb88e 100644
--- a/common/efi/efi.c
+++ b/common/efi/efi.c
@@ -299,7 +299,7 @@ static int efi_init(void)
 
 	defaultenv_append_directory(env_efi);
 
-	env = xasprintf("/efivars/barebox-env-%pUl", &efi_barebox_vendor_guid);
+	env = xasprintf("/efivars/%pUl/barebox-env", &efi_barebox_vendor_guid);
 	default_environment_path_set(env);
 
 	return 0;
diff --git a/fs/efivarfs.c b/fs/efivarfs.c
index bf7351e6d..90aa3cfcf 100644
--- a/fs/efivarfs.c
+++ b/fs/efivarfs.c
@@ -27,6 +27,7 @@
 #include <linux/stat.h>
 #include <xfuncs.h>
 #include <fcntl.h>
+#include <libgen.h>
 #include <efi.h>
 #include <wchar.h>
 #include <linux/err.h>
@@ -35,21 +36,99 @@
 #include <efi/efi-device.h>
 
 struct efivarfs_inode {
+	int is_dir;
+	int is_symlink;
 	s16 *name;
 	efi_guid_t vendor;
 	char *full_name; /* name including vendor namespacing */
+	struct efivarfs_inode *parent;
 	struct list_head node;
-};
-
-struct efivarfs_dir {
-	struct list_head *current;
-	DIR dir;
+	struct list_head childs;
 };
 
 struct efivarfs_priv {
 	struct list_head inodes;
 };
 
+static struct efivarfs_inode *efivarfs_get_by_name(
+	struct list_head *inodes, const char *full_name)
+{
+	struct efivarfs_inode *inode, *tmp;
+
+	list_for_each_entry_safe(inode, tmp, inodes, node) {
+		if (!strcmp(inode->full_name, full_name))
+			return inode;
+	}
+
+	return NULL;
+}
+
+static struct efivarfs_inode *efivarfs_get_by_vendor(
+	struct efivarfs_priv *priv, efi_guid_t *guid)
+{
+	struct efivarfs_inode *inode, *tmp;
+
+	list_for_each_entry_safe(inode, tmp, &priv->inodes, node) {
+		if (!efi_guidcmp(inode->vendor, *guid))
+			return inode;
+	}
+
+	return NULL;
+}
+
+static struct efivarfs_inode *efivarfs_add_vendor(
+	struct efivarfs_priv *priv, efi_guid_t *guid)
+{
+	struct efivarfs_inode *vendor;
+	struct efivarfs_inode *symlink;
+	const char *name;
+
+	vendor = efivarfs_get_by_vendor(priv, guid);
+
+	if (vendor)
+		return vendor;
+
+	vendor = xzalloc(sizeof(*vendor));
+	vendor->is_dir = 1;
+	vendor->full_name = basprintf("%pUl", guid);
+	vendor->vendor = *guid;
+
+	list_add_tail(&vendor->node, &priv->inodes);
+	INIT_LIST_HEAD(&vendor->childs);
+
+	name = efi_guid_string_type(guid, 0);
+	if (!name)
+		goto out;
+
+	/* add symlink if we can resolv it */
+	symlink = xzalloc(sizeof(*symlink));
+	symlink->is_symlink = 1;
+	symlink->full_name = xstrdup(name);
+	symlink->vendor = *guid;
+	symlink->parent = vendor;
+	list_add_tail(&symlink->node, &priv->inodes);
+
+out:
+	return vendor;
+}
+
+static struct efivarfs_inode *efivarfs_add_var(
+	struct efivarfs_inode *v_inode, s16 *name)
+{	
+	struct efivarfs_inode *inode;
+
+	inode = xzalloc(sizeof(*inode));
+	inode->name = xstrdup_wchar(name);
+
+	inode->vendor = v_inode->vendor;
+
+	inode->full_name = xstrdup_wchar_to_char(inode->name);
+
+	list_add_tail(&inode->node, &v_inode->childs);
+
+	return inode;
+}
+
 static int char_to_nibble(char c)
 {
 	int ret = tolower(c);
@@ -93,47 +172,74 @@ int efi_guid_parse(const char *str, efi_guid_t *guid)
 	return 0;
 }
 
-static int efivarfs_parse_filename(const char *filename, efi_guid_t *vendor, s16 **name)
+static struct efivarfs_inode *efivarfs_parse_path(struct efivarfs_priv *priv,
+		const char *filename, s16 **name, char **full_name)
 {
-	int len, ret;
-	const char *guidstr;
-	s16 *varname;
-	int i;
+	char *dir, *file;
+	char *tmp = xstrdup(filename);
+	char *tmp2 = xstrdup(filename);
+	const char *vendor_str;
+	s16 *varname = NULL;
+	int len;
+	void *ret = ERR_PTR(-EINVAL);
+	struct efivarfs_inode *inode;
+
+	dir = dirname(tmp);
+	file = basename(tmp2);
 
-	if (*filename == '/')
+	if (filename[0] == '/')
 		filename++;
 
-	len = strlen(filename);
+	if (dir[0] == '/')
+		dir++;
 
-	if (len < sizeof("-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"))
-		return -EINVAL;
+	if (!strlen(dir)) {
+		vendor_str = filename;
+		*name = NULL;
+		*full_name = NULL;
+	} else {
+		int i;
 
-	guidstr = filename + len - sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
-	if (*guidstr != '-')
-		return -EINVAL;
+		vendor_str = dir;
+		if (name) {
+			len = strlen(file);
+
+			varname = xzalloc((len + 1) * sizeof(s16));
+
+			for (i = 0; i < len; i++)
+				varname[i] = file[i];
 
-	guidstr++;
+			*name = varname;
+		}
 
-	ret = efi_guid_parse(guidstr, vendor);
+		if (full_name)
+			*full_name = xstrdup(file);
+	}
 
-	varname = xzalloc((guidstr - filename) * sizeof(s16));
+	inode = efivarfs_get_by_name(&priv->inodes, vendor_str);
+	if (!inode)
+		goto err;
 
-	for (i = 0; i < guidstr - filename - 1; i++)
-		varname[i] = filename[i];
+	ret = inode;
+	goto out;
 
-	*name = varname;
+err:
+	free(varname);
+	*name = NULL;
+out:
+	free(tmp);
+	free(tmp2);
 
-	return 0;
+	return ret;
 }
 
 static int efivars_create(struct device_d *dev, const char *pathname, mode_t mode)
 {
 	struct efivarfs_priv *priv = dev->priv;
 	struct efivarfs_inode *inode;
-	efi_guid_t vendor;
+	struct efivarfs_inode *vendor;
 	efi_status_t efiret;
 	u8 dummydata;
-	char *name8;
 	s16 *name;
 	int ret;
 
@@ -141,58 +247,73 @@ static int efivars_create(struct device_d *dev, const char *pathname, mode_t mod
 		pathname++;
 
 	/* deny creating files with other vendor GUID than our own */
-	ret = efivarfs_parse_filename(pathname, &vendor, &name);
-	if (ret)
+	vendor = efivarfs_parse_path(priv, pathname, &name, NULL);
+	if (IS_ERR(vendor))
 		return -ENOENT;
 
-	if (memcmp(&vendor, &EFI_BAREBOX_VENDOR_GUID, sizeof(efi_guid_t)))
-		return -EPERM;
-
-	inode = xzalloc(sizeof(*inode));
-	inode->name = name;
-	inode->vendor = vendor;
-
-
-	name8 = xstrdup_wchar_to_char(inode->name);
-	inode->full_name = basprintf("%s-%pUl", name8, &inode->vendor);
-	free(name8);
+	if (memcmp(&vendor->vendor, &EFI_BAREBOX_VENDOR_GUID, sizeof(efi_guid_t))) {
+		ret =  -EPERM;
+		goto out;
+	}
 
-	efiret = RT->set_variable(inode->name, &inode->vendor,
+	efiret = RT->set_variable(name, &vendor->vendor,
 				  EFI_VARIABLE_NON_VOLATILE |
 				  EFI_VARIABLE_BOOTSERVICE_ACCESS |
 				  EFI_VARIABLE_RUNTIME_ACCESS,
 				  1, &dummydata);
 	if (EFI_ERROR(efiret)) {
-		free(inode);
-		return -efi_errno(efiret);
+		ret = -efi_errno(efiret);
+		goto out;
 	}
 
-	list_add_tail(&inode->node, &priv->inodes);
+	inode = efivarfs_add_var(vendor, name);
+	ret = 0;
 
-	return 0;
+out:
+	free(name);
+
+	return ret;
 }
 
 static int efivars_unlink(struct device_d *dev, const char *pathname)
 {
 	struct efivarfs_priv *priv = dev->priv;
-	struct efivarfs_inode *inode, *tmp;
+	struct efivarfs_inode *vendor, *inode;
 	efi_status_t efiret;
+	s16 *name;
+	char *full_name;
+	int ret;
 
 	if (pathname[0] == '/')
 		pathname++;
 
-	list_for_each_entry_safe(inode, tmp, &priv->inodes, node) {
-		if (!strcmp(inode->full_name, pathname)) {
-			efiret = RT->set_variable(inode->name, &inode->vendor,
-						  0, 0, NULL);
-			if (EFI_ERROR(efiret))
-				return -efi_errno(efiret);
-			list_del(&inode->node);
-			free(inode);
-		}
+	vendor = efivarfs_parse_path(priv, pathname, &name, &full_name);
+	if (IS_ERR(vendor)) {
+		ret = PTR_ERR(vendor);
+		goto out;
 	}
 
-	return 0;
+	inode = efivarfs_get_by_name(&vendor->childs, full_name);
+	if (IS_ERR(inode)) {
+		ret = PTR_ERR(inode);
+		goto out;
+	}
+
+	efiret = RT->set_variable(inode->name, &inode->vendor,  0, 0, NULL);
+	if (EFI_ERROR(efiret)) {
+		ret = -efi_errno(efiret);
+		goto out;
+	}
+
+	list_del(&inode->node);
+	free(inode);
+	ret = 0;
+
+out:
+	free(full_name);
+	free(name);
+
+	return ret;
 }
 
 struct efivars_file {
@@ -206,14 +327,20 @@ struct efivars_file {
 static int efivarfs_open(struct device_d *dev, FILE *f, const char *filename)
 {
 	struct efivars_file *efile;
+	struct efivarfs_priv *priv = dev->priv;
+	struct efivarfs_inode *vendor;
 	efi_status_t efiret;
 	int ret;
 
 	efile = xzalloc(sizeof(*efile));
 
-	ret = efivarfs_parse_filename(filename, &efile->vendor, &efile->name);
-	if (ret)
-		return -ENOENT;
+	vendor = efivarfs_parse_path(priv, filename, &efile->name, NULL);
+	if (IS_ERR(vendor)) {
+		ret = PTR_ERR(vendor);
+		goto out;
+	}
+
+	efile->vendor = vendor->vendor;
 
 	efiret = RT->get_variable(efile->name, &efile->vendor,
 				  NULL, &efile->size, NULL);
@@ -243,6 +370,7 @@ static int efivarfs_open(struct device_d *dev, FILE *f, const char *filename)
 
 out:
 	free(efile->buf);
+	free(efile->name);
 	free(efile);
 
 	return ret;
@@ -253,6 +381,7 @@ static int efivarfs_close(struct device_d *dev, FILE *f)
 	struct efivars_file *efile = f->priv;
 
 	free(efile->buf);
+	free(efile->name);
 	free(efile);
 
 	return 0;
@@ -314,31 +443,75 @@ static loff_t efivarfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
 	return f->pos;
 }
 
+struct efivarfs_dir {
+	struct efivarfs_inode *vendor;
+	struct efivarfs_inode *var;
+	int empty;
+	DIR dir;
+};
+
 static DIR *efivarfs_opendir(struct device_d *dev, const char *pathname)
 {
 	struct efivarfs_priv *priv = dev->priv;
 	struct efivarfs_dir *edir;
+	DIR *dir;
 
 	edir = xzalloc(sizeof(*edir));
-	edir->current = priv->inodes.next;
+	dir = &edir->dir;
+	dir->priv = edir;
+
+	if (pathname[0] == '/')
+		pathname++;
+
+	if (!strlen(pathname)) {
+		if (list_empty(&priv->inodes))
+			return dir;
 
-	return &edir->dir;
+		edir->vendor = list_first_entry(&priv->inodes,
+					struct efivarfs_inode, node);
+	} else {
+		struct efivarfs_inode *inode;
+
+		inode = efivarfs_get_by_name(&priv->inodes, pathname);
+		edir->vendor = inode->is_symlink ? inode->parent : inode;
+		if (!edir->vendor)
+			return dir;
+
+		if (list_empty(&edir->vendor->childs)) {
+			edir->empty = 1;
+			return dir;
+		}
+
+		edir->var = list_first_entry(&edir->vendor->childs,
+					struct efivarfs_inode, node);
+	}
+
+	return dir;
 }
 
 static struct dirent *efivarfs_readdir(struct device_d *dev, DIR *dir)
 {
 	struct efivarfs_priv *priv = dev->priv;
 	struct efivarfs_dir *edir = container_of(dir, struct efivarfs_dir, dir);
-	struct efivarfs_inode *inode;
+	struct efivarfs_inode *vendor = edir->vendor;
+	struct efivarfs_inode *var = edir->var;
 
-	if (edir->current == &priv->inodes)
+	if (!vendor)
 		return NULL;
 
-	inode = list_entry(edir->current, struct efivarfs_inode, node);
+	if (!var) {
+		if (edir->empty || &vendor->node == &priv->inodes)
+			return NULL;
 
-	strcpy(dir->d.d_name, inode->full_name);
+		strcpy(dir->d.d_name, vendor->full_name);
+		edir->vendor = list_entry(vendor->node.next, struct efivarfs_inode, node);
+	} else {
+		if (&var->node == &vendor->childs)
+			return NULL;
 
-	edir->current = edir->current->next;
+		strcpy(dir->d.d_name, var->full_name);
+		edir->var = list_entry(var->node.next, struct efivarfs_inode, node);
+	}
 
 	return &dir->d;
 }
@@ -354,26 +527,69 @@ static int efivarfs_closedir(struct device_d *dev, DIR *dir)
 
 static int efivarfs_stat(struct device_d *dev, const char *filename, struct stat *s)
 {
-	efi_guid_t vendor;
+	struct efivarfs_priv *priv = dev->priv;
+	struct efivarfs_inode *vendor;
 	s16 *name;
 	efi_status_t efiret;
 	unsigned long size = 0;
-	int ret;
+	int ret = -EINVAL;
 
-	ret = efivarfs_parse_filename(filename, &vendor, &name);
-	if (ret)
-		return -ENOENT;
+	vendor = efivarfs_parse_path(priv, filename, &name, NULL);
+	if (IS_ERR(vendor))
+		return PTR_ERR(vendor);
+
+	if (filename[0] == '/')
+		filename++;
+
+	if (!name) {
+		s->st_size = strlen(filename);
+		if (vendor->is_dir)
+			s->st_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO;
+		else
+			s->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
+
+		ret = 0;
+
+		goto out;
+	}
 
-	efiret = RT->get_variable(name, &vendor, NULL, &size, NULL);
+	efiret = RT->get_variable(name, &vendor->vendor, NULL, &size, NULL);
 
 	free(name);
 
-	if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL)
-		return -efi_errno(efiret);
+	if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL) {
+		ret = -efi_errno(efiret);
+		goto out;
+	}
 
 	s->st_mode = 00666 | S_IFREG;
 	s->st_size = size;
 
+	ret = 0;
+
+out:
+	return ret;
+}
+
+static int efivarfs_readlink(struct device_d *dev, const char *pathname,
+			char *buf, size_t bufsiz)
+{
+	struct efivarfs_priv *priv = dev->priv;
+	struct efivarfs_inode *node;
+	int len;
+
+	if (pathname[0] == '/')
+		pathname++;
+
+	node = efivarfs_get_by_name(&priv->inodes, pathname);
+
+	if (!node || !node->parent)
+		return -ENOENT;
+
+	len = min(bufsiz, strlen(node->parent->full_name));
+
+	memcpy(buf, node->parent->full_name, len);
+
 	return 0;
 }
 
@@ -382,7 +598,6 @@ static int efivarfs_probe(struct device_d *dev)
 	efi_status_t efiret;
 	efi_guid_t vendor;
 	s16 name[1024];
-	char *name8;
 	unsigned long size;
 	struct efivarfs_priv *priv;
 
@@ -391,24 +606,19 @@ static int efivarfs_probe(struct device_d *dev)
 	priv = xzalloc(sizeof(*priv));
 	INIT_LIST_HEAD(&priv->inodes);
 
+	efivarfs_add_vendor(priv, &efi_barebox_vendor_guid);
+
 	while (1) {
 		struct efivarfs_inode *inode;
+		struct efivarfs_inode *v_inode;
 
 		size = sizeof(name);
 		efiret = RT->get_next_variable(&size, name, &vendor);
 		if (EFI_ERROR(efiret))
 			break;
 
-		inode = xzalloc(sizeof(*inode));
-		inode->name = xstrdup_wchar(name);
-
-		inode->vendor = vendor;
-
-		name8 = xstrdup_wchar_to_char(inode->name);
-		inode->full_name = basprintf("%s-%pUl", name8, &vendor);
-		free(name8);
-
-		list_add_tail(&inode->node, &priv->inodes);
+		v_inode = efivarfs_add_vendor(priv, &vendor);
+		inode = efivarfs_add_var(v_inode, name);
 	}
 
 	dev->priv = priv;
@@ -442,6 +652,7 @@ static struct fs_driver_d efivarfs_driver = {
 	.readdir   = efivarfs_readdir,
 	.closedir  = efivarfs_closedir,
 	.stat      = efivarfs_stat,
+	.readlink  = efivarfs_readlink,
 	.drv = {
 		.probe  = efivarfs_probe,
 		.remove = efivarfs_remove,
diff --git a/include/efi.h b/include/efi.h
index e1fc134ee..afad26314 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -668,6 +668,7 @@ char *device_path_to_str(struct efi_device_path *dev_path);
 u8 device_path_to_type(struct efi_device_path *dev_path);
 char *device_path_to_partuuid(struct efi_device_path *dev_path);
 
+const char *efi_guid_string_type(efi_guid_t *g, int is_long);
 const char *efi_guid_string(efi_guid_t *g);
 
 #endif /* _LINUX_EFI_H */
-- 
2.11.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2] efivarfs: rework the filesystem to make it human readable
  2017-03-03 15:27 [PATCH 0/2] efivarfs: rework the filesystem to make it human readable Jean-Christophe PLAGNIOL-VILLARD
  2017-03-03 15:31 ` [PATCH 1/2] ls: allow to list a symlink ending with '/' as a dir Jean-Christophe PLAGNIOL-VILLARD
@ 2017-03-09 14:38 ` Jean-Christophe PLAGNIOL-VILLARD
  2017-03-13  7:24   ` Sascha Hauer
  1 sibling, 1 reply; 7+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-09 14:38 UTC (permalink / raw)
  To: barebox

Hi,

	Sascha is this one ok?

Best Regards,
J.
On 16:27 Fri 03 Mar     , Jean-Christophe PLAGNIOL-VILLARD wrote:
> Hi,
> 
> efivarfs: rework the filesystem to make it human readable
> 
> today we use <varname>-<guid as %pUl>
> 
> such as Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c
> 
> now we will use a different approach where will represent first the vendor
> as a directory and then inside the associates variable.
> 
> But also create symlink on the vendor with readable name.
> 
> so it will look like this:
> 
> barebox@barebox EFI payload:/ ls -l /efivars/
> drwxrwxrwx             36 04b37fe8-f6ae-480b-bdd5-37d98c5e89aa
> drwxrwxrwx             36 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
> drwxrwxrwx             36 4c19049f-4137-4dd3-9c10-8b97a83ffdfa
> drwxrwxrwx             36 5b446ed1-e30b-4faa-871a-3654eca36080
> drwxrwxrwx             36 5b91f69c-8b88-4a2b-9269-5f1d802b5175
> drwxrwxrwx             36 8be4df61-93ca-11d2-aa0d-00e098032b8c
> lrwxrwxrwx              3 Efi -> 8be4df61-93ca-11d2-aa0d-00e098032b8c
> lrwxrwxrwx              7 barebox -> 5b91f69c-8b88-4a2b-9269-5f1d802b5175
> drwxrwxrwx             36 eb704011-1402-11d3-8e77-00a0c969723b
> lrwxrwxrwx              7 systemd -> 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
> barebox@barebox EFI payload:/ ls -l /efivars/Efi/
> -rw-rw-rw-             62 Boot0000
> -rw-rw-rw-             80 Boot0001
> -rw-rw-rw-             84 Boot0002
> -rw-rw-rw-            106 Boot0003
> -rw-rw-rw-            108 Boot0004
> -rw-rw-rw-            141 Boot0005
> -rw-rw-rw-             88 Boot0006
> -rw-rw-rw-              2 BootCurrent
> -rw-rw-rw-              4 BootOptionSupport
> -rw-rw-rw-             14 BootOrder
> -rw-rw-rw-            107 ConIn
> -rw-rw-rw-           1567 ConInDev
> -rw-rw-rw-            103 ConOut
> -rw-rw-rw-           1855 ConOutDev
> -rw-rw-rw-             73 ErrOut
> -rw-rw-rw-           1563 ErrOutDev
> -rw-rw-rw-             14 Key0000
> -rw-rw-rw-             14 Key0001
> -rw-rw-rw-              4 Lang
> -rw-rw-rw-             13 LangCodes
> -rw-rw-rw-              8 OsIndicationsSupported
> -rw-rw-rw-              3 PlatformLang
> -rw-rw-rw-             18 PlatformLangCodes
> -rw-rw-rw-            108 PlatformRecovery0000
> -rw-rw-rw-              2 Timeout
> barebox@barebox EFI payload:/ ls -l /efivars/barebox/
> barebox@barebox EFI payload:/ ls -l /efivars/systemd/
> -rw-rw-rw-             14 LoaderTimeInitUSec
> 
> please pull
> 
> The following changes since commit f14af7444ad9d8ce674382f222119f5fcd3f2576:
> 
>   efi: add veriable to report secure boot support and status (2017-02-28 23:05:31 +0800)
> 
> are available in the git repository at:
> 
>   git://git.jcrosoft.org/barebox.git delivery/efivarfs
> 
> for you to fetch changes up to a757520bfccf17064181ebc15646efdb83ee581b:
> 
>   efivarfs: rework the filesystem to make it human readable (2017-03-01 00:15:38 +0800)
> 
> ----------------------------------------------------------------
> Jean-Christophe PLAGNIOL-VILLARD (2):
>       ls: allow to list a symlink ending with '/' as a dir
>       efivarfs: rework the filesystem to make it human readable
> 
>  commands/ls.c     |  41 +++++++++++++++++----
>  common/efi-guid.c |  17 +++++++--
>  common/efi/efi.c  |   2 +-
>  fs/efivarfs.c     | 379 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------
>  include/efi.h     |   1 +
>  5 files changed, 347 insertions(+), 93 deletions(-)
> 
> Best Regards,
> J.
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2] efivarfs: rework the filesystem to make it human readable
  2017-03-09 14:38 ` [PATCH 0/2] " Jean-Christophe PLAGNIOL-VILLARD
@ 2017-03-13  7:24   ` Sascha Hauer
  2017-03-13  8:20     ` Michael Olbrich
  0 siblings, 1 reply; 7+ messages in thread
From: Sascha Hauer @ 2017-03-13  7:24 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox, m.olbrich

On Thu, Mar 09, 2017 at 03:38:40PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> Hi,
> 
> 	Sascha is this one ok?

I asked Michael to have a look at this series, so far he didn't find
time.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2] efivarfs: rework the filesystem to make it human readable
  2017-03-13  7:24   ` Sascha Hauer
@ 2017-03-13  8:20     ` Michael Olbrich
  2017-03-13 10:19       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Olbrich @ 2017-03-13  8:20 UTC (permalink / raw)
  To: barebox

Hi,

On Mon, Mar 13, 2017 at 08:24:42AM +0100, Sascha Hauer wrote:
> On Thu, Mar 09, 2017 at 03:38:40PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > 	Sascha is this one ok?
> 
> I asked Michael to have a look at this series, so far he didn't find
> time.

I'm not sure I like it this way. The old way matches what the Linux kernel
does so it's familiar. And the mix of guids and 'names' is rather
cluttered because they are not grouped separately.
Maybe keep the old version and add something like the by-name etc. symlinks
used in udev:

<guid-for-foo>-bar
<something>
  EFI
    [...]
  foo
    bar -> ../../<guid-for-foo>-bar


Michael

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2] efivarfs: rework the filesystem to make it human readable
  2017-03-13  8:20     ` Michael Olbrich
@ 2017-03-13 10:19       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 7+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-13 10:19 UTC (permalink / raw)
  To: Michael Olbrich; +Cc: barebox


> On 13 Mar 2017, at 4:20 PM, Michael Olbrich <m.olbrich@pengutronix.de> wrote:
> 
> Hi,
> 
> On Mon, Mar 13, 2017 at 08:24:42AM +0100, Sascha Hauer wrote:
>> On Thu, Mar 09, 2017 at 03:38:40PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>> 	Sascha is this one ok?
>> 
>> I asked Michael to have a look at this series, so far he didn't find
>> time.
> 
> I'm not sure I like it this way. The old way matches what the Linux kernel
> does so it's familiar. And the mix of guids and 'names' is rather
> cluttered because they are not grouped separately.
we can split them in sub dirs

/efivars/by-guid/<guid>/var

and keep the known one in

/efivars/Efi/…
/efivars/barebox/…
/efivars/systemd/…

as we will use known guid for most of the time

as does linux too most of the time

> Maybe keep the old version and add something like the by-name etc. symlinks
> used in udev:
> 
> <guid-for-foo>-bar
> <something>
>  EFI
>    [...]
>  foo
>    bar -> ../../<guid-for-foo>-bar

<guid-for-foo>-bar is un readable 

and we need to parse a filename which is a prone to error even when creating new variable
and today we only allow to create var for barebox guid in the "user space”
So this is easier to handle

and when you ls it at the end is hard to read

The efivarfs is for user not C Code 

That’s why I prefer to have a design that is easy to read

Best Regards,
J.
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-03-13 10:20 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-03 15:27 [PATCH 0/2] efivarfs: rework the filesystem to make it human readable Jean-Christophe PLAGNIOL-VILLARD
2017-03-03 15:31 ` [PATCH 1/2] ls: allow to list a symlink ending with '/' as a dir Jean-Christophe PLAGNIOL-VILLARD
2017-03-03 15:31   ` [PATCH 2/2] efivarfs: rework the filesystem to make it human readable Jean-Christophe PLAGNIOL-VILLARD
2017-03-09 14:38 ` [PATCH 0/2] " Jean-Christophe PLAGNIOL-VILLARD
2017-03-13  7:24   ` Sascha Hauer
2017-03-13  8:20     ` Michael Olbrich
2017-03-13 10:19       ` Jean-Christophe PLAGNIOL-VILLARD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox