FreeBSD 13 and /etc/motd: it’s gone!

A few days ago I was running a system-wide upgrade of a FreeBSD 12 system of mines, and while executing the great freebsd-update something caught my attention:

The following file will be removed, as it no longer exists in
FreeBSD 13.0-RELEASE: /etc/motd
Does this look reasonable (y/n)?


Uhm, as far as I know /etc/motd has been there since the epoch, and quite frankly I’m an happy administrator that loves to use /etc/motd to customize machine login messages.
But it was only after the very last step of freebsd-update that the file was gone, and the login message appeared as… well, it disappeared at all!
Digging around did not show any particular result, except for a this thread, that however I looked at only after having read the manual. In particular, the man page for motd(5) reports the following:

MOTD(5)                   FreeBSD File Formats Manual                  MOTD(5)

NAME
     motd – file containing message(s) of the day

DESCRIPTION
     The file /var/run/motd is normally displayed by login(1) after a user has
     logged in but before the shell is run.  It is generally used for
     important system-wide announcements.  During system startup, a line
     containing the kernel version string is prepended to /etc/motd.template
     and the contents are written to /var/run/motd.

     /var/run/motd can be updated without a system reboot by manually
     restarting the motd service after updating /etc/motd.template:
           service motd restart

...
HISTORY
     Prior to FreeBSD 13.0, motd lived in /etc.



and after the upgrade a line that reads as update_motd="NO" appeared in my /etc/rc.conf service configuration file.
So what is happening?
I don’t have a rationale for all this stuff, but essentially:
  • /etc/motd has gone, and the system is going to display /var/run/motd instead;
  • the latter, /var/run/motd is going to be regenerated by a motd daemon;
  • at system boot, the kernel information and the content of a template file, /etc/motd.template are appended into /var/run/motd and the latter is shown.


In other words, it works like this pseudo-code:

# @boot

if [ "$update_motd" = "YES" ]; then
   uname -a > /var/run/motd
   cat /etc/motd.template >> /var/run/motd
fi


# @login
cat /var/run/motd


While this could seem a little too complicated for the service itself, that is displaying a system wide message, it does have a few advantages:
  • the file that could change is no more in the almost static directory /etc, rather the /var/run directory clearly indicates that the file in there is subject to a change while the system is running;
  • the system is going to display the kernel information at every boot, no need to worry about updating the content of the message of the day after an upgrade;
  • the static part of the message of the day is going to stay static into /etc;
  • the system can apply a new motd without needing for a full reboot (and this was possible even before, but now it is simpler to manage it).

There is one main drawback I can see, at least in this version: it is not possible to avoid the kernel information string to appear in the message of the day. While having the kernel information string is useful to system administrators and developers, it could not be the same for normal users. In fact, digging into /etc/rc.d/motd, the implementation of the service itself, the following piece of code is not conditionated by any particular rc variable:

% cat /etc/rc.d/motd
...
   T=`mktemp -t motd`
   uname -v | sed -e 's,^\([^#]*\) #\(.* [1-2][0-9][0-9][0-9]\).*/\([^\]*\) $,\1 (\3) #\2,' > ${T}
   cat "${TEMPLATE}" >> ${T}
...


and therefore the uname result will always appear on top of the message of the day, no matter how you configure it.

How to force the update of the message of the day

There is however a little trick to take into account: the update of the message of the day happens if and only if update_motd is correctly set on /etc/rc.conf. In other words, the message of the day is now managed as a system wide service, and therefore it must be instrumented via rc variables.
So far there is only one: update_motd. If that is set to YES (in any case combination), the system will automatically update the message of the day on startup and whenever the service motd is (re)started:

% sudo service motd restart
Updating motd:.


Manipulating the message of the day manually

The file /var/run/motd is a text file, and therefore it can be manipulated as you used to do (if you did!) with the classical /etc/motd:

# date > /var/run/motd
# df -h >> /var/run/motd


and at the very next login the system will show the new content you crafted into /var/run/motd.
Unless and until you run the motd service (re)start!

I want my /etc/motd back again

Well, you can, but as backward compatibility file. In other words, if you create the /etc/motd file and do not have /etc/motd.template, the system will automatically link /etc/motd to the result of /var/run/motd creating also a /etc/motd.template default file with the content of /etc/motd.
In other words:
  • if you have an old (compatibilty) /etc/motd and don’t have a /etc/motd.template file;
  • the /etc/motd will be placed as /etc/motd.template;
  • /var/run/motd will be updated based on the previous template content and the rules explained above;
  • /etc/motd will be linked to /var/run/motd.

In this way, the /etc/motd file, if present, will always display the exact content of the runtime message of the day (i.e., /var/run/motd), and the template will be created for you with your old content of /etc/motd. This is a kind of upgrade of the message of the day system.
It is interesting to note that, in such case, any line containing FreeBSD and a version number will be stripped of into the template so that uname will do the job without any incoherent repetition.

Conclusions

On FreeBSD 13 the message of the day is now managed as a service, and this enables the system to automatically update the content of the message of the day in the case it has changed. You can always place your own manually crafted message of the day, but in such case you must take into account the fact that the update_motd variable has to be set to NO, or at reboot (or system restart) the file content will be overwritten.
One drawback, in my opinion, of this schema is that the kernel information cannot be removed from the top of the message of the day. On the other hand, this means you don’t need to manually update such information.
Last, the presence of the /etc/motd file will be used as a starting template for ugprading the system to the new service layout, and in the end it will be linked to the real message of the day, so that all your scripts that are based on /etc/motd will continue to work.

The article FreeBSD 13 and /etc/motd: it's gone! has been posted by Luca Ferrari on May 6, 2021

Tags: freebsd