<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>