Duplicating Non-Reentrant Functions

Illustration

As I was playing with PIC16454 using USB, I kept getting these warnings: Microchip/usb_device.c:277:: advisory: (1510) non-reentrant function "_USBDeviceInit" appears in multiple call graphs and has been duplicated by the compiler

This was due to function being called from both main function and from interrupt handler. Since function could be interrupted at any point in time, this was definitely a problem and compiler did find a valid solution. However, this was a bit suboptimal for my case.

Since I had issue with only a few functions, I decided to make use of Hybrid option is XC8 compiler stack options. With this option warnings were gone. Surprisingly, this also made my code smaller. Hybrid stack compiled into 7181 words while standard Compiled stack was 7398.

If you have reentrancy happening in just a few functions, Hybrid option might be good for you.*


* Some restrictions apply. Please contact your fellow developers if your compile lasts longer than 4 hours.

Case-insensitive ZFS

Don’t.

Well, this was a short one. :)

From the very start of its existence, ZFS supported case-insensitive datasets. In theory, if you share disk with Windows machine, this is what you should use. But reality is a bit more complicated. It’s not that setting doesn’t work. It’s more a case of working too well.

Realistically you are going to be running ZFS on some *nix machine and access it from Windows, it’ll be via Samba. As *nix API generally expects case-sensitivity, Samba will dynamically convert what it shares from the case-sensitive world into the case-insensitive one. If file system is case-insensitive, Samba will get confused and you will suddenly have issues renaming files that differ only in case.

For example, you won’t be able to rename test.txt into Test.txt. Before doing rename Samba will if the new file already exists (step needed if underlying system is case-insensitive) in order to avoid overwriting unrelated file. This second check will fail on case-insensitive dataset as ZFS will report Test.txt exists. Because of this check (that would be necessary on case-sensitive file system) Samba will incorrectly think that destination already exists and not allow the rename. Yep, any rename differing only in case will fail.

Now, this could be fixable. If Samba would recognize the file system is case-insensitive, it could skip that check. But what if you have case-sensitive file system mounted within case-insensitive dataset? Or vice-versa? Should Samba check on every access or cache results? For something that doesn’t happen on *nix often, this would be either flaky implementation or a big performance hit.

Therefore, Samba assumes that file system is case-sensitive. In 99% of cases, this is true. Unless you want to chase ghosts, just give it what it wants.

Using Null in the Face of CS0121

Sometime you might want to use null as a parameter but you get the annoying CS0121.

The call is ambiguous between the following methods or properties…

One could just adjust constructor but that would be an easy way out.

Proper way would be to use default operator. For example, if you want to use null string, you can use something like default(string):

var dummy = new Dummy(default(string));

If we’re using nullable reference types, just add question mark:

var dummy = new Dummy(default(string?));

And this simple trick selects the correct constructor every time.

Changing ZFS Key Location

Back when I was creating my original pool, I decided to use password prompt as my encryption key unlocking method. And it was good. But then I wanted to automate this a bit. I wanted my key to be read of USB drive.

To do that one can simply prepare a new key and point the pool toward it.

dd if=/dev/urandom of=^^/usb/key.dat^^ bs=32 count=1
zfs change-key -o keylocation=file://^^/usb/key.dat^^ -o keyformat=raw Pool

Of course, it’s easy to return it back to password prompt too:

zfs change-key -o keylocation=prompt -o keyformat=passphrase Pool

Simple enough.

Configuring HTTP/2 for WordPress on Ubuntu

Last year I wrote this exact article only to find out it’s no longer current. So, as I rebuilt my web server on a new VM, I decided to bring it a bit of update for PHP 7.4

The first step, of course, is enabling HTTP/2 module:

a2enmod http2

Second step is adding HTTP/2 protocol definition to /etc/apache2/apache2.conf:

Protocols h2 h2c http/1.1
H2Direct on
H2ModernTLSOnly on

Followed by Apache’s restart:

systemctl restart apache2

In ideal world this would be it. But, despite Apache starting without error, a check via Developer Tools will show HTTP 1.1 is still in use. So we need an additional PHP with FastCGI support:

apt-get install php7.4-fpm

Furthermore, we need some modules enabled and disabled:

a2dismod php7.4
a2dismod mpm_prefork
a2enmod mpm_event
a2enmod proxy_fcgi
a2enconf php7.4-fpm

Of course, addition to /etc/apache2/apache2.conf is needed too:

<Files "*.php">
   SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost/"
</Files>

If you configured prefork before, you also need to remove it’s configuration. In my case StartServers, MinSpareServers, MaxSpareServers, MaxClients, and MaxRequestsPerChild settings had to go.

Of course, another Apache restart is upon us:

systemctl restart apache2

Congratulations! HTTP/2 should be working now.