Solved Fresh 11.1 install, ZFS not automounting

I just "upgraded" (i.e. reinstalled from scratch) to 11.1R on my server-of-all-work, and found that my ZFS pools and datasets won't automount, though I can mount them by hand. I have zfs_enable="YES" in my /etc/rc.conf. Is there something I forgot to do?
 
Does this happen when you boot the main system or when you boot using a rescue CD? Also: is the base system installed on ZFS or... ?

Look into the canmount property for your filesystems. For example: zfs get canmount zroot/var. If you used the installer then this property will most likely be set to off for at least the root file system. Normally this would only prevent it from auto mounting when you boot from a rescue CD and import the pool there. But I could imagine that this could also occur in other situations.

Apart from this make sure that the ZFS services are enabled, check: sysrc zfs_enable.
 
Does this happen when you boot the main system or when you boot using a rescue CD? Also: is the base system installed on ZFS or... ?

No, the base system is on UFS. After I installed yesterday, I called zpool import on the two pools, and then zfs mounted them. I brought the system down at the end of the day (I can't now remember why) and when I rebooted this morning, the zpools weren't mounted, which caused confusion til I discovered that. I don't have them listed in /etc/fstab, but they weren't listed before, either.

Apart from this make sure that the ZFS services are enabled, check: sysrc zfs_enable.

That might be the problem, because it returns "no" even though I do have zfs_enable="YES" in /etc/rc.conf (I just checked again).
 
Code:
# -- sysinstall generated deltas -- # Tue Oct 21 06:59:05 2008
# Created: Tue Oct 21 06:59:05 2008
# Enable network daemons for user convenience.
# Please make all changes to this file, not to /etc/defaults/rc.conf.
# This file now contains just the overrides from /etc/defaults/rc.conf.
hostname="momcat"
ifconfig_igb0="inet 192.168.0.96     netmask 255.255.255.0"
defaultrouter="192.168.0.98"
#
ntpd_enable="YES"
nfs_enable = "YES"
zfs_enable = "YES"
enable_ppp="YES"
samba_server_enable="YES"
# ---------------
lpd_enable="YES"
dbus_enable="YES"
hald_enable="YES"
moused_enable="YES"
# ---------------
#linux_enable="YES"
sshd_enable="YES"
usbd_enable="YES"
# ---------------
mysql_enable="YES"
mysql_dbdir="/MC/mysql_data"
apache24_enable="YES"
#apache24_http_accept_enable="YES"
# ---------------
ftp_enable="YES"
apm_enable="YES"
# -- cups
cupsd_enable="YES"
devfs_system_ruleset="system"
 
A stupid question: are the necessary kernel modules loaded (opensolaris.ko, zfs.ko) at boot time?
/boot/loader.conf contains zfs_load="YES"?
 
Yeah, and this is why I suggested that you'd use sysrc(8). I also always edit /etc/rc.conf by hand but sysrc can be an excellent tool to verify that everything is still in working order. In the example with the spaces above it would have clearly mentioned that the ZFS service isn't enabled.

But I guess this most likely solved the mystery :)
 
Nope, not /boot/loader.conf after all. I thought it must be, since I had indeed forgotten to put in the load command. But sysrc still returns "no" after fixing loader.conf and rebooting.
 
Remove the spaces in your rc.conf.
Or do you mean the ones around the "=" in those 2 lines? Is the interpreter really that fragile?

[after a quick edit and another reboot]

Yep. Really that fragile. I'm surprised that I never tripped over that bug--and it is a bug!-- before.

So much of Unix is just thrown-together that way, fragility galore.
 
In the example with the spaces above it would have clearly mentioned that the ZFS service isn't enabled.

It did just that:

That might be the problem, because it returns "no" even though I do have zfs_enable="YES" in /etc/rc.conf (I just checked again).

sh has never allowed spaces around = assignments. Perhaps sysrc could output a warning if it detects ‘^[^#]+( +=|= +)’. Or a /etc/rc.d/sanity could be added that yells if it finds one in one of the sh-based .conf files.
 
Or do you mean the ones around the "=" in those 2 lines? Is the interpreter really that fragile?

[after a quick edit and another reboot]

Yep. Really that fragile. I'm surprised that I never tripped over that bug--and it is a bug!-- before.

So much of Unix is just thrown-together that way, fragility galore.

It’s not a bug. sh, like all languages, has a syntax that is expected to be followed, so this was a syntax error.

It would be nice if we detected and warned on the error rather than (apprently) silently ignoring it, but you have to draw a line somewhere for what you will proactively check for. This might be a nice one to check for; it’s a fairly simple check, and could be done only once during boot, or if sysrc is run. It’s also an easy one to overlook, as this thread shows.

Edit: and if I recall, sysrc was created to help prevent just these sorts of simple-but-frustrating bugs from hand-editing rc.conf.
 
It’s not a bug. sh, like all languages, has a syntax that is expected to be followed, so this was a syntax error.

I think you'll have to agree, though, that it's a needless syntax error, like so many. In the majority of modern languages, including human ones, extra whitespace is not syntactically significant, And it would be so very easy to fix the problem in sh, if that's who's doing the interpretation--no existing files would have to be changed, but extra whitespace would no longer prevent interpretation.

(I'm a psychologist by training, and trying to prevent bad human-factors decisions like the one that produced this problem consumed most of my professional time in the computer industry)
 
I think you'll have to agree, though, that it's a needless syntax error, like so many. In the majority of modern languages, including human ones, extra whitespace is not syntactically significant, And it would be so very easy to fix the problem in sh, if that's who's doing the interpretation--no existing files would have to be changed, but extra whitespace would no longer prevent interpretation.

(I'm a psychologist by training, and trying to prevent bad human-factors decisions like the one that produced this problem consumed most of my professional time in the computer industry)
It's not the number of whitespaces that matters (when you type commands, i.e. to list the contents of a directory,
Code:
ls -l ~
or
Code:
ls    -l  ~
it's the same) but the presence of the whitespace itself that throws the error. While this could seem fragile, sticking to this conventions prevent to much unneeded complications in the code (at least this is valid for sh, for more complex programs could be unacceptable).
 
It's not the number of whitespaces that matters (when you type commands, i.e. to list the contents of a directory,
Code:
ls -l ~
or
Code:
ls    -l  ~
it's the same) but the presence of the whitespace itself that throws the error. While this could seem fragile, sticking to this conventions prevent to much unneeded complications in the code (at least this is valid for sh, for more complex programs could be unacceptable).

But what unneeded complications? It seems to me that using whitespace as a break wouldn't be any harder when reading a file like /etc/rc.conf than it is when that same interpreter reads the command line--it's the same code that does the parsing, or would be.

(One space is extra, when the parser expects no spaces, no?)
 
The problem is that /etc/rc.conf is not a config file, but a shell script, and shell isn't really a programming language so has quite a few caveats.

Code:
# echo $TEST

# TEST = 123
sh: TEST: not found
# TEST=123
# echo $TEST
123

How can it tell the first assignment above (with the spaces), is not an attempt to run the command called TEST, with a couple of arguments (one of which is the = sign)? It can't really, and so to set a variable you have make it clear you are doing an assignment. It's just one of the limitations of trying to write a script using a shell interpreter.

Ideally of course, rc.conf should be read by a proper parser so it can have a real, more forgiving, "config file" format, but it's much easier and more lightweight for the rc scripts to just treat it as a script.
 
But what unneeded complications?
The context. The shell should distinguish between the whitespace(s) used, i.e. in setting a variable, and when parsing commands. Unless you quote or escape the equal sign, the interpreter will consider foo=1 as a variable assignement (and declaration, of course), but if you use whitespaces (foo = 1), will not; it'll threat them (foo, the =, and 1) as separate things. :)

EDIT: Didn't notice your comment usdmatt, sorry :oops:. Thank you for your clear explanation. :)
 
The problem is that /etc/rc.conf is not a config file, but a shell script, and shell isn't really a programming language so has quite a few caveats.

Code:
# echo $TEST

# TEST = 123
sh: TEST: not found
# TEST=123
# echo $TEST
123

How can it tell the first assignment above (with the spaces), is not an attempt to run the command called TEST, with a couple of arguments (one of which is the = sign)? It can't really, and so to set a variable you have make it clear you are doing an assignment. It's just one of the limitations of trying to write a script using a shell interpreter.

Ideally of course, rc.conf should be read by a proper parser so it can have a real, more forgiving, "config file" format, but it's much easier and more lightweight for the rc scripts to just treat it as a script.

It's a fairly bad idea from a human standpoint to try to allow completely ambiguous statements and then when that doesn't work, constrain the wrong thing! Either use parens for argument lists just like nearly every other language, or disallow operators as arguments, or demand that they be passed as strings and decoded internally.

In this response, I'm presuming that one can't pass an operator without somehow taking the curse off it.

I would parse TEST = 123 the usual way:
while not finished,
read the line
capture the first token (TEST). At this point I don't know what it is, but it must be either a var or a call,
discard whitespace
find and capture the next token (=). Now I know it's an assignment, not a call
discard whitespace
find and capture the next token (123) Now I know what to assign to TEST and I do that, and then go on to look for a statement separator or an EOL
discard whitespace
find and capture the next token or EOL. In this case, it's the EOL
read the next line and jump to while
 
The context. The shell should distinguish between the whitespace(s) used, i.e. in setting a variable, and when parsing commands. Unless you quote or escape the equal sign, the interpreter will consider foo=1 as a variable assignement (and declaration, of course), but if you use whitespaces (foo = 1), will not; it'll threat them (foo, the =, and 1) as separate things. :)

EDIT: Didn't notice your comment usdmatt, sorry :oops:. Thank you for your clear explanation. :)

See my reply to usdmatt
 
There's a human-factors principle I call "conservation of obnoxiousness". It states that obnoxiousness will be conserved until consumed.

So if the designer (in this case of the sh language) doesn't have good design skills, or doesn't pay attention, or doesn't care, then the obnoxiousness will affect those who use his work forever. So it's always better for the designer to consume the obnoxiousness before it's generated rather than afflicting everyone after him.

(The late Maurice Wilkes gave a talk one day, and the auditorium was packed solid with engineers. I thought the roof was going to come off the place when he slyly remarked that the really nice thing about being the creator of a standard is that everyone who follows after us will have to make the same mistakes we did. Gales of laughter and thunderous applause, it was at least a full minute before the poor man could continue)
 
I would parse TEST = 123 the usual way:
while not finished,
read the line
capture the first token (TEST). At this point I don't know what it is, but it must be either a var or a call,
discard whitespace
find and capture the next token (=). Now I know it's an assignment, not a call

Yeah this is a shell interpreter, designed for running commands, not a programming language. It is just going to assume you want to run the program called TEST and pass = as the first argument, which is entirely something a user "might" want to do at the command prompt. Other shell interpreter scripts like batch files have just as many limitations. It's far more important for it to be able to accept a command from a user with arguments (regardless of what they are), in the universally standard command arg1 arg2 format, than to suddenly switch to assignment if an argument happens to be =; A shell doing something different because the first argument to a command is = would be considered a bug by most people. Choosing name=value for assignment is a perfectly reasonable solution for adding variable assignment - without creating any side effects for normal command execution (apart from the fact you can't have an executable called my=program of course).

Unfortunately you just have to follow the syntax rules, like you would with any other language. Yes it's not great that spaces break assignment in rc.conf, but that comes from the fact that sh's primary purpose is to run commands. As I said it would be nice if it had a proper config format and parser but rc.d has been around a long time and back then being able to just "run" the config file to process it without any additional code or a parser was desirable; And FreeBSD haven't decided it's worth replacing it yet.
 
Back
Top