I’ve been using ZFS since FreeBSD 8, but I must be missing something. I know it’s supposed to be wonderful and all that, but I was actually pretty happy with UFS.
So what’s the up-side to ZFS? Well you get more error checking and correction. And it’s more “auto” when it comes to allocating disk space. But call me old fashioned if you like; I don’t like “auto”.
Penguinistas might not “get” this next bit, but on a UNIX system you didn’t normally have One Big Disk. Instead you had several, and even if you only had one, you’d partition the slice it up so it looked like several. And then, of course, you’d mount disks or partitions on to the root filing system wherever you wanted them to appear.
For reliability, you could also create mirrors and striped RAIDs, put a FS on them and mount them wherever you wanted. And demount them, and mount them somewhere else, and so on.
ZFS does all this good stuff, but automatically, and often as One Big Disk. A good thing? Well… no.
First off, I like to know where and on which disk my data actually resides. I’m really uneasy with ZFS deciding for me. If ZFS loses it, I want to know where to find it. I also like having a FS on each drive or partition, so I can pull the drive out and mount it wherever I want to get data off – or move it from machine to machine. It’s my data, I’ll do what I want to with it, dammit!
Please generate and paste your ad code here. If left empty, the ad location will be highlighted on your blog pages with a reminder to enter your code.
Secondly, with UFS I get to decide what hardware is used for each kind of file. Parts of the FS that are rarely used can be put on slow, cheap, huge disks. The database goes on a velociraptor or better, and the swap partitions – well! Okay, you can use multiple zpools for difference performance situations but then you’re using it like UFS.
And then you get the management issues with One Big Disk. With the old way, when an FS on a drive fills up, it is full. You can’t create more files on it. You either have to delete unwanted stuff, or you can mount a bigger drive in its place. With One Big Disk, when it’s full, it’s also full. The difference is that you can’t write any data anywhere on the entire FS.
Take, for example, /var/log. Any UNIX admin with a bit of sense will have this in its own partition. If some script kiddie then did something that caused a lot of log file activity, eventually you’d run out of space in /var/log. But the rest of the system would still be alive. Yes, you can set a limit using ZFS dataset quotas, but who does? With UFS the default installation process created partitions with sensible sizes; ZFS systems install with no quotas whatsoever. Using the One Big Disk principle, ZFS satisfies the requests of any disk-eating process until there isn’t a single byte left anywhere, and then rolls over saying the zpool is full. Or it would say it if there was a monitor connected to the server in a data centre miles away, and there was someone there to look at it.
Okay, most of this has perfectly good solutions using ZFS. and I’ve yet to have a disaster with a ZFS system that’s required me to move drives around, so I don’t really know how possible it is when the chips are down. And ZFS has is a nice unified way of doing stuff, rather than fiddling around with geom and the FS separately. But after a couple of years with FreeBSD 10, where it became practical to boot from ZFS, shouldn’t I be feeling a bit more enthusiastic about it?
Having a ZFS pool attached as a data store rather than as a boot device is, of course, a different story. That’s when you see the benefits. But it does also eat resources, so I want the benefits to be worth it for the particular application.
It’s no secret that Linux users with good taste have viewed the FreeBSD kernel with envious eyes for many years. A while back Debian distributions started having the FreeBSD kernel as an option instead of the Linux one. (Yes, you read that correctly). But now things seem to have been turned up a notch with UbuntuBSD.
It seems a group of penguinistas regard the Ubuntu world’s adoption of systemd as a step too far, and forked. And rather than keeping with Linux, they’ve opted to dump the whole kernel and bolt the Ubuntu front-end on to FreeBSD instead, getting kernel technology like ZFS and jails but “…keeping the familiarity of Ubuntu”.
Where could this be going? We already have PC-BSD for a “shrink wrapped” graphical desktop environment. Is anyone actually using it? I’m not. I’m sure we’ve all downloaded it out of curiosity, but if I want a Windows PC I’ll have a Windows PC. With BSD I’m more than happy with a command line, thank you very much.
UbuntuBSD could be different. Linux users actually use the graphical desktop, and most can’t cope with a command line. If they were to switch to FreeBSD instead, UbuntuBSD would make a lot of sense.
Although it’s only been around a month, in early beta form, its Sourceforge page is showing a lot of downloads. If I wanted to run a graphical desktop on top of FreeBSD, UbuntuBSD would make a lot of sense over PC-BSD, because I get the vibes that Ubuntu has desktop applications more together.
There seems to be a bit of a problem with upgrades to FreeBSD 10.3-RELEASE. Basically, shutdown -r is hanging, requiring you to manually reset the machine (turn it off and on again). This is annoying unless the machine in question happens to be at a data centre on a different continent, in which “annoying” really doesn’t cut it.
Yesterday someone asked me how to allocate memory in a FreeBSD device driver. Although not quite as simple as a user-space malloc(), it’s relatively simple – but could I remember the name/parameter order? Not confidently, so I suggested RTFM.
A quick look at the manual doesn’t actually cover it very well. Basically there are special versions of malloc()/free() and they’re have exactly the same names, except the parameters are different. For example, malloc() has two extra parameters; one is the memory type (used for kernal statistics purposes), and one is a flags field, with options whether you’re prepared to wait, or is this a critical situation and using the reserve pool is okay.
For details, see “man 9 malloc”. The ‘9’ is important, as otherwise you’ll get the user-land version in libc. (Incidentally, a read through the libc code should put you off algorithms making wanton use dynamic memory allocation if you weren’t already).
Now what the FreeBSD documentation doesn’t tell you (and something for my to-do list) is how to actually make use of this in a device driver. I had to go back to code I’d written ten years ago to remind me, as I’m just as guilty of copying and tweaking my standard code many times over without really remembering what it does.
But before you go worrying about allocating dynamic memory in a device driver, consider that there’s no reason why you can’t just use static memory – just allocate in BSS in the normal way. Okay, this won’t suit every eventuality but on on most of my simple drivers, which have been to mess with custom hardware for a single process, it’s not actually a problem.
Okay, so you still want to use dynamic? Well to get the kernel versions instead of the the libc ones you need to include instead. As I mentioned above, for some reason using the same names must have seemed like a good idea at the time, but the parameters are different.
The other thing you should be aware of is when about allocating kernel memory you are talking about non-paged. Don’t go crazy.
There is also a memory allocation tracker and statistics dumper available in the libc version (see /etc/malloc.conf), which will help you out if you’ve messed up memory allocation. Don’t expect any such help with the kernel. However, if you compile the kernel with the INVARIANTS option set it will scrub freed memory with 0xdeadc0de, which is handy if you find yourself using unallocated or free kernel RAM. Actually, this is a pretty good idea if you’re writing KLDs anyway, as it stops and does a core dump at the first sign you’ve screwed up any kernel structures.
The documentation in “man 9 malloc” should be enough to cope with the extra parameters; basically the malloc_type. Note that the first parameter to the MALLOC_DEFINE macro is actually a name you make up! By convention it’s in the form M_XXXXX, in upper case.
Also note that when you’re freeing memory it’s not normally zeroed. Therefore someone else using kernel memory might be able to allocate it and read what your driver wrote. Okay, bug deal – if the bad guys are installing kernel modules it’s game anyway. But… consider the bad guys cause a kernel panic and get a core dump.
A bug has been found and fixed in the FreeBSD kernel that would allow someone with malicious intent to crash a running system. It’d be difficult to achieve unless the attacker had console access. However it’s been patched for all supported systems. See here for all the details (which I won’t repeat).
The sysarch() system call is used to get/set processor-specific stuff. You’re not supposed to call it directly; you’re supposed to call a processor-specific library if you want to do things like that, but you still can call it if you want to. On processors that support memory segments, such as i386, there is a Local Descriptor Table (LDT) to manage them if you want to mess with specific stuff like that. However, for security reasons, you can only modify the LDT using the sysarch() call, which checks what you’re trying to do and prevents applications from doing anything crazy.
Unfortunately the AMD64 implementation of the code gets the checking wrong. If you use a signed integer it’s always going to be less than another unsigned value, and when it compares the two parameters to make sure that one is less than the other it passes when it shouldn’t, and the rogue parameter causes it to go funky-deux and overwrite a shed load of stuff.
This is in all in:
in the function:
int amd64_set_ldt(td, uap, descs)
The FreeBSD advisory contains a patch for all “supported” versions; but what if you’re using an older one? Using the information from Core it’s easy enough to patch. But what else is affected?
To save you the trouble, I’ve looked back at earlier versions. The problem code definitely exists in the AMD64 versions for 8.x, but isn’t present in any 7.x, as far as I can tell. The system call simply doesn’t exist. On i386 versions, I can’t see any obvious problem with the code.
How worried should we be? If someone breaks in to a system with shell access, they will be able to crash it. However, I think it’s very unlikely that any service is written in such a way that malicious data could cause the necessary parameters to be sent to sysarch() call. In fact, on checking the ports collection, it’s not exactly used all over the place. You’re highly unlikely to be running any application that even makes the call.
UNIX permissions can send you around the twist sometimes. You can set them up to do anything, not. Here’s a good case in point…
Imagine you have Samba set up to provide users with a home directory. This is a useful feature; if you log in to the server with the name “fred” you (and only you) will see a network share called “fred”, which contains the files in your UNIX/Linux home directory. This is great for knowledgeable computer types, but is it such a great idea for normal lusers? If you’re running IMAP email it’s going to expose your mail directory, .forward and a load of other files that Windoze users might delete on a whim, and really screw things up.
Is there a Samba option to share home directories but to leave certain subdirectories alone? No. Can you just change the ownership and permissions of the critical files to root and deny write access? No! (Because mail systems require such files to be owned by their user for security reasons). Can you use permission bits or even an ACL? Possibly, but you’ll go insane trying.
A bit of lateral thinking is called for here. Let’s start with the standard section in smb.conf for creating automatic shares for home directories:
comment = Home Directories
browseable = no
writable = yes
The “homes” section is special – the name “homes” is reserved to make it so. Basically it auto-creates a share with a name matching the user when someone logs in, so that they can get to their home directory.
First off, you could make it non-writable (i.e. set writable = no). Not much use to use luser, but it does the job of stopping them deleting anything. If read-only access is good enough, it’s an option.
The next idea, if you want it to be useful, is to use the directive “hide dot files” in the definition. This basically returns files beginning in a ‘.’ as “hidden” to Windoze users, hiding the UNIX user configuration files and other stuff you don’t want deleted. Unfortunately the “mail” directory, containing all your loverly IMAP folders is still available for wonton destruction, but you can hide this too by renaming it .mail. All you then need to do is tell your mail server to use the new name. For example, in dovecot.conf, uncomment and edit the line thus:
mail_location = mbox:~/.mail/:INBOX=/var/mail/%u
(Note the ‘.’ added at the front of ~/mail/)
You then have to rename each of the user’s “mail” folders to “.mail”, restart dovecot and the job is done.
Except when you have lusers who have turned on the “Show Hidden Files” option in Windoze, of course. A surprising number seem to think this is a good idea. You could decide that hidden files allows advanced users control of their mail and configuration, and anyone messing with a hidden file can presumably be trusted to know what you’re doing. You could even mess with Windoze policies to stop them doing this (ha!). Or you may take the view that all lusers and dangerous and if there is a way to mess things up, they’ll find it and do it. In this case, here’s Plan B.
The trick is to know that the default path to shares in [homes] is ‘~’, but you can actually override this! For example:
path = /usr/data/flubnutz
This maps users’ home directories in a single directory called ‘flubnutz’. This is not that useful, and I haven’t even bothered to try it myself. When it becomes interesting is when you can add a macro to the path name. %S is a good one to use because it’s the name as the user who has logged in (the service name). %u, likewise. You can then do stuff like:
path = /usr/samba-files/%S
This stores the user’s home directory files in a completely different location, in a directory matching their name. If you prefer to keep the user’s account files together (like a sensible UNIX admin) you can use:
comment = Home Directories
path = /usr/home/%S/samba-files
browseable = no
writable = yes<
As you can imagine, this stores their Windows home directory files in a sub-directory to their home directory; one which they can’t escape from. You have to create “~/samba-files” and give them ownership of it for this to work. If you don’t want to use the explicit path, %h/samba-files should do instead.
I’ve written a few scripts to create directories and set permissions, which I might add to this if anyone expresses an interest.
A couple of year’s back I managed to compile and run FreeBSD/Apache/BIND on an ARM-based Raspberry Pi. It was fun, but I have to admit it’s been left on the shelf ever since. A solution waiting for a problem.
Since then the ARM has been a specific target for FreeBSD 11. Do you really need FreeBSD on your smartphone? However much I like BSD, the Linux-based Android does well enough. But wait…
ARM has a 64-bit turbo-nutter-bastard version waiting in the wings, for server use. The ARMv8 is scalable to at least 48 cores per socket and intended to go like the clappers in SMP applications. FreeBSD has long been considered to have the edge over the Linux kernel when it comes to SMP. This is getting interesting.
A team including Semihalf has now got FreeBSD 11 stable running on a twin-CPU monster using the Cavium ThunderX ARM chips, each of which has 48-cores. For details see their blog. With a lot of serious web applications running FreeBSD in preference to the freewheeling Linux, there could be a very ready market for this kind of box.
I would be in danger of being extremely jealous, as my budget for playing with ARM chips doesn’t stretch much past the Raspberry Pi. However, in the 1980’s Atari Research gave me an ATW transputer box with 128 discrete CPUs to help implement an OS on, so I’m still 32-cores ahead. There wasn’t much of a market for the ATW back then, but Cavium could be on to a winner with the approach nearly thirty years later.
Does anyone know what happened to the big transputer box prototype that was knocking around the Cambridge office? When the ATW/Abaq was released it was greatly scaled down with no more than 13 transputers, and lacked the glass case with all the flashing lights.
I’ve been playing about the Drupal 8 (still in Beta) and one of its features is that it needs the latest version of PHP (5.5.9 or later). I have a server I keep for testing the latest whatever, and this includes Apache 2.4. So how hard can it be to compile in PHP?
Actually, it’s not straightforward. Apache 2.4 is fine, but PHP is another matter. First off, installing lang/php55 does not include mod_php for Apache. It’s not that the option to compile it hasn’t been set – the option has gone. With a bit of digging around you can find it elsewhere – in www/mod_php55. Don’t be fooled in to thinking you need to just build and install that though…
You’ll probably end up with stuff like this in your httpd error log:
Call to undefined function session_name()
Call to undefined function hash()
Digging further you’ll find www/php55-session and security/php55-hash in there, and go off to build those too. Then wonder why it still isn’t working.
The clue can be found with this log file error:
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20121212-zts/session.so' - Cannot open "e;/usr/local/lib/php/20121212-zts/session.so"e; in Unknown on line 0
(NB. The "e appears in the log file itself!)
Basically, mod_php expects you to compile the ZTS (Zend Thread Safe) version of everything. And why wouldn’t you? Well it turns out that this important option is actually turned off by default so you need to configure the build to include it. Any extensions you’ve compiled up until now will not have been placed in a directory tagged with -zts, which is why it’s looking in the wrong place as shown by the error log.
If you’re reading this following a Google search, you’ve probably already fallen down the Pooh trap. You need to go back to lang/php55 and start again with the correct options. The best way to do this (in case you didn’t know) is:
When you run make config it’ll give you a chance to select ZTS, so do it.
Repeat this for compiling www/mod_php55 and then go back and compile www/php55-session, security/php55-hash and anything else you got wrong the first time, You don’t have the option to configured them, but they must be compiled again once the core of PHP has been compiled using ZTS.
Incidentally, if you haven’t had this pain before, you will probably need to switch to using the new pkg system if you haven’t already. Trying to build without it, it’ll put up a curt little note about it and go in to sulk mode until you do. Unfortunately, on an older FreeBSD, any attempt to compile this will result in an O_CLOEXEC symbol undefined error in pkg.c. This is actually a flag to the open() kernel function that was added to POSIX in 2008. What it means is that if your process subsequently makes exec call, the file handle will be automatically closed. It saves leaking fds if your execution path goes awry. But what’s the solution?
Well, if you’re using an older version of the kernel then it won’t support O_CLOEXEC anyway, so my fix is to delete it from the source and try again. It only appears once, and if the code is so sloppy that it doesn’t close the handle, it’s not the end of the world. The official answer is, of course, to upgrade your kernel.
If you are running Drupal 8, here’s a complete list of the ports you’ll need to compile:
lang/php55 (select ZTS option in the configuration dialogue)
www/mod_php55 (select ZTS option in the configuration dialogue)
devel/php55-tokenizer (for Drupal 8)
converters/php55-mbstring (not tested during setup)
All good fun! This relates to Drupal 8.0.0 RC1 – it may be different with the final release, of course.
Docker is available on FreeBSD. Yeah! Er. Hang on a minute – what’s the point.
People are talking about Docker a lot in the Linux world. It’s a system that allows a configured piece of software, together with all its ancillaries, to be in its own closed environment on any machine you choose. It’s not a VM – no emulation required. Well not much. It’s much more efficient that running multiple kernels on a hypervisor (as VirtualBox or VMWare).
But isn’t this one of the things Jails are for? Well, yes. It’s a kind of poor-man’s jail system for the poor deprived Linux users. Solaris and FreeBSD have been doing this kind of things for years with kernel support (i.e. out-of-the box and lot more efficiently).
So why should anyone be interested that FreeBSD also has Docker? Well, one of the things the Docker community has together is preconfigured applications you can just download and run. Given what a PITA it can be getting something running on a Linux box, which lacks a UNIX-like base system you can rely on, this does make sense. And running these pre-configured server applications on FreeBSD may be of interest, especially if you lack the in-house expertise to set them up yourself. But it won’t be all plain sailing. You need FreeBSD 11 (not yet released) to do it, together with the 64-bit Linux emulation library.
This does kind-of make sense. Stuff that’s currently Linux-only may be easier to deal with – I’m thinking Oracle here.