<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body><div>On Fri, 2018-05-04 at 22:29 +0800, Ge Song wrote:</div><div><snip></div><div><br></div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><blockquote type="cite" cite="mid:27fbdbe910bf6c2b1970caeb1e6fbc6fc976fb1b.camel@mendozajonas.com" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><pre>+</pre><pre>+int main(void)</pre><pre>+{</pre><pre>+ void *ctx = NULL;</pre><pre>+ int rc, errno_value;</pre><pre>+ size_t size;</pre><pre>+ uint8_t *data = NULL;</pre><pre>+ uint32_t attr = DEF_ATTR;</pre><pre>+</pre><pre>+ if(!probe())</pre><pre>+ return EXIT_SUCCESS;</pre><pre>+</pre><pre>+ talloc_new(ctx);</pre><pre>+ size = strlen(test_data) + 1;</pre><pre>+ rc = efi_set_variable(ctx, test_efivar_guid, test_varname,</pre><pre>+ (uint8_t *)test_data, size, attr);</pre><pre>+</pre><pre>+ rc = efi_get_variable(ctx, test_efivar_guid, test_varname,</pre><pre>+ &data, &size, &attr);</pre><pre>+</pre><pre>+ rc = strcmp((char *)data, test_data);</pre><pre><br></pre>
</blockquote>
<pre>This still segfaults:</pre><pre><br></pre><pre> (gdb) frame 1</pre><pre> #1 0x0000555555554f94 in main () at ../test/lib/test-efivar.c:80</pre><pre> 80 rc = strcmp((char *)data, test_data);</pre><pre><br></pre><pre>Most likely because efi_get_variable() is returning an error, likely since</pre><pre>efi_set_variable() is failing because /sys/firmware/efi/efivars is only</pre><pre>writable by root on my machine.</pre><pre>I could just run the test as root and it would probably pass, but I don't want</pre><pre>to be writing random efi variables to my (or anyone elses) laptops as part of a</pre><pre>Petitboot test :)</pre><pre><br></pre>
</blockquote>
<font face="Times New Roman, Times, serif">Yes, operations under that
folder require root permission. I forgot to mention that since
usually<br>
petitboot will be executed with the root permission , so sorry for
it.<br>
<br>
In fact, the temporary variable set in NVRAM will be deleted in
the end of the function, when<br>
it returns normally, the variable won't be found in efivarfs
anymore.<br>
<br>
To be precise, the delete operation causes one bit in variable's
attribute field(in NVRAM) transition<br>
from 0(valid) to 1(invalid), when this happens, both firmware and
OS will ignore this variable and<br>
no side effect will be introduced. <br>
<br>
The shortcoming is a little space is occupied by this temporary
variable, although it has been deleted.<br>
Don't worry about it, when the variable storage is full, a reclaim
action will be taken by firmware.<br>
</font>
<blockquote type="cite" cite="mid:27fbdbe910bf6c2b1970caeb1e6fbc6fc976fb1b.camel@mendozajonas.com" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<pre>What would be better would be to have a 'fake' efivar directory that we set up</pre><pre>as part of the test, and write and read changes to that. Then we're just</pre><pre>testing that our writing and parsing of the efivarfs format works, not testing</pre><pre>the efivarfs implementation of whatever machine we're on.</pre><pre><br></pre><pre>For example we could have a test/lib/efivarfs directory with some dummy files</pre><pre>in there in the efivarfs format. Then if we change the efivarfs path Petitboot</pre><pre>uses the test can write to that without affecting the system. What do you think?</pre><pre><br></pre>
</blockquote>
<font face="Times New Roman, Times, serif">Sounds like writing a
simple userspace filesystem? I agree with you, that's really a
good solution,<br>
and it's a interesting work, maybe more time is needed, I have to
study how to accomplish it first:) </font></blockquote><div><br></div><div>That would be interesting but I won't ask you to put in that much work for this series! An easier approach would just be</div><div>to have get_efivarfs_path() return a path to the test directory, eg. "./test/lib/efivarfs_data/" and within that write a few</div><div>files in the efivarfs format. We don't need to write to the real efivarfs for a test since we're just testing our parsing of it.</div><div>Besides a lot of testing runs on machines without access to efivarfs (on a Jenkins box for instance), so we don't want to</div><div>have to guarantee that it exists.</div><div><br></div><div>Have a look at test/parser/data/ for example - it's just a collection of "example" files we can test ourselves against, I</div><div>imagine we could do something very similar for lib/efi as well.</div><div><br></div></body></html>