Category Archives: Linuxulator

Alexander Leidinger » FreeBSD 2012-05-18 15:36:50

A while ago I committed the linuxulator D-Trace probes I talked about earlier. I waited a little bit for this announcement to make sure I have not broken anything. Nobody complained so far, so I assume nothing obviously bad crept in.

The >500 probes I committed do not cover the entire linuxulator, but are a good start. Adding new ones is straight forward, if someone is interested in a junior–kernel–hacker task, this would be one. Just ask me (or ask on emulation@), and I can guide you through it.

Share

Alexander Leidinger » FreeBSD 2012-05-18 15:30:06

Seems I forgot to announce that the linux_base-c6 is in the Ports Collection now. Well, it is not a replacement for the current default linux base, the linuxulator infrastructure ports are missing and we need to check if the kernel supports enough of 2.6.18 that nothing breaks.

TODO:

To my knowledge, nobody is working on anything of this. Anyone is welcome to have a look and provide patches.

Share

Alexander Leidinger » FreeBSD 2012-04-15 18:43:03

This weekend I made some progress in the linuxulator:

  • I MFCed the reporting of some linux-syscalls to 9-stable and 8-stable.
  • I updated my linuxulator-dtrace patch to a recent -current. I already compiled it on i386 and arundel@ has it compiled on amd64. I counted more than 500 new DTrace probes. Now that DTrace rescans for SDT probes when a kernel module is loaded, there is no kernel panic anymore when the linux module is loaded after the DTrace modules and you want to use DTrace. I try to commit this at a morning of a day where I can fix things during the day in case some problems show up which I did not notice during my testing.
  • I created a PR for portmgr@ to repocopy a new linux_base port.
  • I set the expiration date of linux_base-fc4 (only used by 7.x and upstream way past its EoL) and all dependent ports. It is set to the EoL of the last 7.x release, which can not use a later linux_base port. I also added a comment which explains that the date is the EoL of the last 7.x release.

Share

New CentOS linux_base for testing soonish

It seems my HOWTO create a new linux_base port was not too bad. There is now a PR for a CentOS 6 based linux_base port. I had a quick look at it and it seems that it is nearly usable to include into the Ports Collection (the SRPMs need to be added, but that can be done within some minutes).

When FreeBSD 8.3 is released and the Ports Collection open for sweeping commits again, I will ask portmgr to do a repo-copy for the new port and commit it. This is just the linux_base port, not the complete infrastructure which is needed to completely replace the current default linuxulator userland. This is just a start. The process of switching to a more recent linux_base port is a long process, and in this case depends upon enough support in the supported FreeBSD releases.

Attention: Anyone installing the port from the PR should be aware that using it is a highly experimental task. You need to change the linuxulator to impersonate himself as a linux 2.6.18 kernel (described in the pkg-message of the port), and the code in FreeBSD is far from supporting this. Anyone who wants to try it is welcome, but you have to run FreeBSD-current as of at least the last weekend, and watch out for kernel messages about unsupported syscalls. Reports to [email protected] please, not here on the webpage.

Share

New opportunities in the linuxulator

Last weekend I committed some dummy-syscalls to the linuxulator in FreeBSD-current. I also added some comments to syscalls.master which should give a hint which linux kernel had them for the first time (if the linux man–page I looked this up in is correct). So if someone wants to experiment with a higher compat.linux.osrelease than 2.6.16 (as it is needed for a CentOS based linux_base), he should now get some kernel messages about unimplemented syscalls instead of a silent failure.

There may be some low-hanging fruits in there, but I did not really verify this by checking what the dummy syscalls are supposed to do in linux and if we can easily map this to existing FreeBSD features. In case someone has a look, please send an email to emulation@FreeBSD.org.

Share

Static DTrace probes for the linuxulator updated

I got a little bit of time to update my 3 year old work of adding static DTrace probes to the linuxulator.

The changes are not in HEAD, but in my linuxulator-dtrace branch. The revision to have a look at is r230910. Included are some DTrace scripts:

  • script to check internal locks
  • script to trace futexes
  • script to generate stats for DTracified linuxulator parts
  • script to check for errors:
    • emulation errors (unsupported stuff, unknown stuff, …)
    • kernel errors (resource shortage, …)
    • programming errors (errors which can happen if someone made a mistake, but should not happen)

The programming-error checks give hints about userland programming errors respectively a hint about the reason of error return values due to resource shortage or maybe a wrong combination of parameters. An example error message for this case is “Application %s issued a sysctl which failed the length restrictions.nThe length passed is %d, the min length supported is 1 and the max length supported is %d.n�.

The stats-script (tailored specially to the linuxulator, but this can easily be extended to the rest of the kernel) can report about:

  • number of calls to a kernel function per executable binary (not per PID!): allows to see where an optimization would be beneficial for a given application
  • graph of CPU time spend in kernel functions per executable binary: together with the number of calls to this function this allows to determine if a kernel optimization would be beneficial / is possible for a given application
  • graph of longest running (CPU-time!) kernel function in total
  • timing statistics for the emul_lock
  • graph of longest held (CPU-time!) locks

Unfortunately this can not be committed to HEAD as-is. The DTrace SDT provider can not handle probes which are added to the kernel after the SDT provider is already loaded. This means that you either have to compile the linuxulator statically into the kernel, or you have to load the SDT kernel module after the linuxulator module is loaded. If you do not respect this, you get a kernel panic on first access of one of the providers in the linuxulator (AFAIR this includes listing the probes available in the kernel).

Share

Linuxulator explained (for developers): adding ioctls directly to the kernel

After giving an overview of the in-kernel basics of the Linuxulator, I want now to describe how to add support for new ioctls to the Linuxulator.

Where are the files to modify?

The platform independent code for the ioctls is in SRC/sys/compat/linux/linux_ioctl.c. The defines to have names for the ioctl values are in SRC/sys/compat/linux/linux_ioctl.h.

How to modify them?

First of all create a new header which will contain all the structures, named values and macros for those new ioctls. As written above, the ioctl values (e.g. #define LINUX_VIDIOC_ENCODER_CMD 0x564d /* 0xc028564d */) do not belong there, they shall be added to linux_ioctl.h. During the course of adding support for ioctls, you will need this new header. Add it in the SRC/sys/compat/linux/ directory, and prefix the name with a linux_. It would be good to decide on a common tag here (referenced as yourtag in the following), and stay with it. Use it wherever you need to have some specific name for the ioctl-set you want to add. In this case it would result in linux_yourtag.h (or even linux_ioctl_yourtag.h, depending if this is used for something very specific to the ioctls, or some generic linux feature) as the name of the header file. This was not done in the past, so do not expect that the names inside the linux_ioctl.c file will be consistent to this naming scheme, but it is never too late to correct mistakes of the past (at least in Open Source software development).

Now add this header to linux_ioctl.c (you need to include compat/linux/linux_yourtag.h). After that add the ioctl values to linux_ioctl.h. As can be seen above, the defines should be named the same as on linux, but with a LINUX_ prefix (make sure they where not defined before somewhere else). The ioctl values need to be the same hex values as in Linux, off course. Sort them according to their hex value. When you added all, you need to add two more defines. The LINUX_IOCTL_yourtag_MIN and LINUX_IOCTL_yourtag_MAX ones. The MIN-one needs to be an alias for the first (sorted according to the hex value) ioctl you added, and MAX needs to be an alias for the last (again, sorted according to the hex value) ioctl you added.

The next step is to let the Linuxulator know that it is able to handle the ioctls in the LINUX_IOCTL_yourtag_MIN to LINUX_IOCTL_yourtag_MAX range. Search the static linux_ioctl_function_t section of linux_ioctl.c and add such a variable for your ioctl set. The name of the variable should be something like linux_ioctl_yourtag.

Similar for the handler-definition for this. Search the static struct linux_ioctl_handler section and add a yourtag_handler. Set it to { linux_ioctl_yourtag, LINUX_IOCTL_yourtag_MIN, LINUX_IOCTL_yourtag_MAX }. To make this handler known to the Linuxulator, you need to add it to the DATA_SET section. Add DATA_SET(linux_ioctl_handler_set, yourtag_handler) there.

Now the meat, the function which handles the ioctls. You already defined it as linux_ioctl_function_t, but now you need to write it. The outline of it looks like this:

static int
linux_ioctl_yourtag(struct thread *td, struct linux_ioctl_args *args)
{
        struct file *fp;
        int error;
        switch (args->cmd & 0xffff) {
        case LINUX_an_easy_ioctl:
                break;
        case LINUX_a_not_so_easy_ioctl:
                /* your handling of the ioctl */
                fdrop(fp, td);
                return (error);
        /* some more handling of your ioctls */
        default:
       return (ENOIOCTL);
        }
        error = ioctl(td, (struct ioctl_args *)args);
        return (error);
}

An easy ioctl in the switch above is an ioctl where you do not have to do something but can pass the ioctl through to FreeBSD itself. The not so easy ioctl case is an ioctl where you need to do e.g. a fget(td, args->fd, &fp). This is just an example, there are also other possibilities where you need to do additional stuff before the return, or where you do not pass the ioctl to FreeBSD. A typical example of what needs to be done here is to copy values from linux structures to FreeBSD structures (and the other way too), or to translate between 64bit and 32bit. Linux programs on amd64 are 32bit executables and 32bit structures/pointers. To make this work on amd64, you need to find a way to map between the two. There are examples in the kernel where this is already the case. The more prominent examples in the 64bit<->32bit regard are the v4l and v4l2 ioctls.

The tedious part is to research if a translation has to be done and if yes what needs to be translated how. When this is done, most of the work is not so hard. The linux_yourtag.h should contain the structures you need for this translation work.

It is also possible to add ioctls in a kernel module, but this is not subject to this description (I will update this posting with a link to it when I get time to write about it).

Share

HOWTO add linux-infrastructure ports for a new linux_base port

In my last blog-post I described how to create a new linux_base port. This blog-post is about the other Linux–ports which make up the Linux–infrastructure in the FreeBSD Ports Collection for a given Linux-release.

What are linux-infrastructure ports?

A linux_base port contains as much as possible and at the same time as little as possible to make up a useful Linux-compatibility-experience in FreeBSD. I know, this is not a descriptive explanation. And it is not on purpose. There are no fixed rules what has to be inside or what not. It “matured� into the current shape. A practical example is, that there is no GUI-stuff in the linux_base. While you need the GUI parts like GTK or QT for software like Skype and acroread, you do not need them for headless game servers. While you may need various libraries for game servers, you may not need those for Skype or acroread. As such some standard parts are in separate ports which are named linux–LINUX_DIST_SUFFIX-NAME. For GTK and the Fedora 10 release this results in linux-f10-gtk2. Such generic ports which depend upon a specific Linux-release make up the Linux-infrastructure in the FreeBSD Ports Collection. Those ports are referenced in port-Makefiles via the USE_LINUX_APPS variable, e.g. USE_LINUX_APPS=gtk2.

If you created a new linux_base port, you need most standard infrastructure ports in a version for the Linux-release used in the linux_base port, to have the Linux-application ports in the FreeBSD Ports Collection working (if you are unlucky, some ports do not play well with the Linux-release you have chosen, but this is out of the scope of this HOWTO).

Updating Mk/bsd.linux-apps.mk

 First we need to set the LINUX_DIST_SUFFIX variable to a value suitable to the new Linux-release. This is done in the conditional which checks the OVERRIDE_LINUX_NONBASE_PORTS variable for valid values. Add an appropriate conditional, and do not forget to add the new valid value to the IGNORE line in the last else branch of the conditional.

The next step is to check the _LINUX_APPS_ALL and _LINUX_26_APPS variables. If there are some infrastructure ports which are not available for the new Linux-release, the conditional which checks the availability of a given infrastructure port for a given Linux-release needs to be modified. If at a later step you notice that there are some additional infrastructure ports necessary for the new Linux-release, _LINUX_APPS_ALL and the check-logic needs to be modified too (e.g. add a new variable for your Linux-release, add the content of the variable to _LINUX_APPS_ALL, and change the check to do the right thing).

After that two tedious parts need to be done.

For each infrastructure port there is a set of variables. The name_PORT variable contains the location of the port in the Ports Collection. Typically you do not have to change it (if you really want to change it, do not do it, fix the naming of the infrastructure port instead), because we use a naming convention here which includes the LINUX_DIST_SUFFIX. The name_DETECT variable is an internal variable, do not change it (if you create a new infrastructure port, copy it from somewhere else and make sure the name in value of the variable matches the port name in the name of the variable). Then there are several name_suffix_FILE variables. Leave the existing ones alone, and add a new one with the correct suffix for your new Linux-release. The value of the variable needs to be an important file which is installed by the infrastructure port in question. FYI: The content of the name_suffix_FILE variables are used to set the name_DETECT variables, depending on the Linux-relase the name_DETECT variables are used to check if the port is already installed. Ideally the name_suffix_FILE variable points to a library in the port. The name_DEPENDS variable lists dependencies of this infrastructure port. If the dependencies changed in your Linux-release, you need to add a conditional to change the dependency if LINUX_DIST_SUFFIX is set to your Linux-release.

Normally this is all what needs to be done in PORTSDIR/Mk/bsd.linux-apps.mk, the rest of the file is code to check dependencies and some correctness checks.

The second tedious part is to actually create all those infrastructure ports. Normally you can copy an existing infrastructure port, rename it, adjust the PORTNAME, PORTVERSION, PORTREVISION, MASTER_SITES, PKGNAMEPREFIX, DISTFILES, CONFLICTS (also in all other Linux-release versions of this infrastructure port), LINUX_DIST_VER, RPMVERSION (if set/neccesary) and SRC_DISTFILE variables, generate the distfile checksums (make makesum), and fix the plist. I suggest to script parts of this work (as of this writing Freshports counts 68 ports where the portname starts with linux-f10-).

Adding new infrastructure ports, or removing infrastructure ports for a given Linux-release

If your Linux-release does not come with a package for an existing infrastructure port, just do not create a corresponding name_suffix_FILE line. You still need to do the right thing regarding dependencies of ports which depend upon this non-existing infrastructure port (if your Linux-release comes with packages for them).

To add a new infrastructure port, copy an existing block, rename the variables, set them correctly, add a new variable for your Linux-release in the first _LINUX_APPS_ALL section, add the content of this variable to _LINUX_APPS_ALL, and change the check-logic as described above.

Final words

If you have something which installs and deinstalls correctly, feel free to provide it on [email protected] for review/testing. If you have questions during the porting, feel also free to send a mail there.

Share

HOWTO create a new linux_base port

FreeBSD is in need of a new linux_base port. It is on my TODO list since a long time, but I do not get the time to create one. I still do not have the time to work on a new one, but when you read this, I managed to get the time to create a HOWTO which describes what needs to be done to create a new linux_base port.

I will not describe how to create a new linux_base port from scratch, I will just describe how you can copy the last one and update it to something newer based upon the existing infrastructure for RPM packages.

Specific questions which come up during porting a new Linux release should be asked on [email protected],  there are more people which can answer questions than here in my blog. I will add useful information to this HOWTO if necessary.

In the easy case most of the work is searching the right RPMs and their dependencies to use, and to create the plist.

Why do we need a new linux_base port?

The current linux_base port is based upon Fedora 10, which is end of life since December 2009. Even Fedora 13 is already end of life. Fedora 16 is supposed to be released this year. From a support point of view, Fedora 15 or maybe even Fedora 16 would be a good target for the next linux_base port. Other alternatives would be to use an extended lifetime release of another RPM based distribution, like for example CentOS 6 (which seems to be based upon Fedora 12 with backports from Fedora 13 and 14). Using a Linux release which is told to be supported for at least 10 years, sounds nice from a FreeBSD point of view (only minor changes to the linux ports in such a case, instead of creating a complete new linux_base each N+2 releases like with Fedora), but it also means additional work if you want to create the first linux_base port for it.

The mysteries you have to conquer if you want to create a new linux_base port

What we do not know is, if Fedora 15/16, CentOS 6, or any other Linux release will work in a supported FreeBSD release. There are two ways to find this out.

The first one is to take an existing Linux system, chroot into it (either via NFS or after making a copy into a directory of a FreeBSD system), and to run a lot of programs (acroread, skype, shells, scripts, …). The LTP testsuite is not that much useful here, as it will test mostly kernel features, but we do not know which kernel features are mandatory for a given userland of a Linux release.

The second way of testing if a given Linux release works on FreeBSD is to actually create a new linux_base port for it and test it without chrooting.

The first way is faster, if you are only interested in testing if something works. The second way provides an easy to setup testbed for FreeBSD kernel developers to fix the Linuxulator so that it works with the new linux_base port. Both ways have their merits, but it is up to the person doing the work to decide which way to go.

The meat: HOWTO create a new linux_base port

First off, you need a system (or a jail) without any linux_base port installed. After that you can create a new linux_base port (= lbN), by just making a copy of the latest one (= lbO). In lbN you need to add lbO as a CONFLICT, and in all other existing linux_base ports, you need to add lbN as a conflict.

Change the PORTNAME, PORTVERSION, reset the PORTREVISION in lbN, and set LINUX_DIST_VER  to the new Linux-release version in the lbN Makefile (this is used in PORTSDIR/Mk/bsd.linux-rpm.mk and PORTSDIR/Mk/bsd.linux-apps.mk).

If you do not stay with Fedora, there is some more work to do before you can have a look at chosing RPMs for installation. You need to have a look at PORTSDIR/Mk/bsd.linux-rpm.mk and add some cases for the new LINUX_DIST you want to use. Do not forget to set LINUX_DIST in the lbN Makefile to the name of the distribution you use. You also need to augment the LINUX_DIST_VER check in PORTSDIR/Mk/bsd.linux-rpm.mk with some LINUX_DIST conditionals. If you are lucky, the directory structure for downloads is similar to the Fedora structure, and there is not a lot to do here.

When this is done, you can have a look at the BIN_DISTFILES variable in the lbN Makefile. Try to find similar RPMs for the new Linux release you want to port. Some may not be available, and it may also be the case that different ones are needed instead. I suggest to first work with the ones which are available (make makesum, test install and create plist). After that you need to find out what the replacement RPMs for non-existing ones are. You are on your own here. Search around the net, and/or have a look at the dependencies in the RPMs of lbO to determine if something was added as a dependency of something else or not (if not, forget about it ATM). When you managed to find replacement RPMs, you can now have a look at the dependencies of the RPMs in lbN. Do not add blindly all dependencies, not all are needed in FreeBSD (the linux_base ports are not supposed to create an environment which you can chroot into, they are supposed to augment the FreeBSD system to be able to run Linux programs in ports like they where FreeBSD native programs). What you need in the linux_base ports are libraries, config and data files which do not exist in FreeBSD or have a different syntax than in FreeBSD (those config or data files which are just in a different place, can be symlinked), and basic shell commands (which commands are needed or not… well… good question, in the past we made decisions what to include based upon problem reports from users). Now for the things which are not available and where not added as a dependency. Those are things which are either used during install, or where useful to have in the past. Find out by what it was replaced and have a look if this replacement can easily be used instead. If it can be used, add it. If not, well… bad luck, we (the FreeBSD community) will see how to handle this somehow.

If you think that you have all you need in BIN_DISTFILES, please update SRC_DISTFILES accordingly and generate the distfile via  make –DPACKAGE_BUILDING makesum to have the checksums of the sources (for legal reasons we need them on our mirrors).

The next step is to have a look at REMOVE_DIRS, REMOVE_FILES and ADD_DIRS if something needs to be modified. Most of them are there to fall back to the corresponding FreeBSD directories/files, or because they are not needed at all (REMOVE_*). Do not remove directories from ADD_DIRS, they are created here to fix some edge conditions (I do not remember exactly why we had to add them, and I do not take the time ATM to search in the CVS history).

If you are lucky, this is all (make sure the plist is correct). If you are not lucky and you need to make some modifications to files, have a look at the do-build target in the Makefile, this is the place where some changes are done to create a nice user experience.

If you arrive here while creating a new linux_base port, lean back and feel a bit proud. You managed to create a new linux_base port. It is not very well tested at this moment, and it is far from everything which needs to be done to have the complete Linux infrastructure for a given Linux release, but the most important part is done. Please notify [email protected] and call for testers.

What is missing?

The full Linuxulator infrastructure for the FreeBSD Ports Collection has some more ports around a linux_base port. Most of the infrastructure for this is handled in Mk/bsd.linux-apps.mk.

UPDATE: I got some time to write how to update the Linux-infrastructure ports.

Share

v4l2 support in the linuxulator now in 8-stable

I MFCed the v4l2 support in the linuxulator to 8–stable. This allows now to use v4l2–webcams in skype/flash on 8-stable too.

Share

Video4Linux2 sup­port in FreeBSD (linuxulator)

I com­mit­ted the v4l2 sup­port into the lin­ux­u­la­tor (in 9-current). Part of this was the import of the v4l2 header from linux. We have the per­mis­sion to use it (like the v4l one), it is not licensed via GPL. This means we can use it in FreeBSD native dri­vers, and they are even allowed to be com­piled into GENERIC (but I doubt we have a dri­ver which could pro­vide the v4l2 inter­face in GENERIC).

The code I com­mit­ted is “just� the glue-code which allows to use FreeBSD native devices which pro­vide a v4l2 inter­face (e.g. multimedia/pwcbsd or multimedia/webcamd) from linux programs.

Thanks to nox@ for writing the glue code.

Share

DTrace probes for the Linuxulator updated

If someone had a look at the earlier post about DTrace probes for the Linuxulator: I updated the patch at the same place. The difference between the previous one is that some D-scripts are fixed now to do what I meant, specially the ones which provide statistics output.

Share

New DTrace probes for the linuxulator

I forward ported my DTrace probes for the FreeBSD linuxulator from a 2008-current to a recent –current. I have not the complete FreeBSD linuxulator covered, but a big part is already done. I can check the major locks in the linuxulator, trace futexes, and I have a D-script which yells at a lot of errors which could happen but should not.

Some of my D-scripts need some changes, as real-world testing showed that they are not really working as expected. They can get overwhelmed by the amount of speculation and dynamic variables (error message: dynamic variable drops with non-empty dirty list). For the dynamic variables problem I found a discussion on the net with some suggestions. For the speculation part I expect similar tuning-possibilities.

Unfortunately the D-script which checks the internal locks fails to compile. Seems there is a little misunderstanding on my side how the D-language is supposed to work.

I try to get some time later to have a look at those problems.

During my development I stumbled over some generic DTrace problems with the SDT provider I use for my probes:

  • If you load the Linux module after the SDT module, your system will panic as soon as you want to access some probes, e.g. “dtrace –lâ€? will panic the system. Loading the Linux module before the SDT module prevents the panic.
  • Unloading the SDT module while the Linux module with the SDT probes is still loaded panics the system too. Do not unload the Linux module if you run with my patch.

According to avg@ those are known problems, but I think nobody is working on this. This is bad, because this means I can not commit my current patchset.

If someone wants to try the new DTrace probes for the linuxulator, feel free to go to http://www.Leidinger.net/FreeBSD/current-patches/ and download linuxulator-dtrace.diff. I do not offer a working hyperlink here on purpose, the SDT bugs can hurt if you are not careful, and I want to make the use of this patch a strong opt-in because of this. If the patch hurts you, it is your fault, you have been warned.

Share

Non-default linux base ports deprecated

Yesterday I deprecated the non-default Fedora based Linux base ports. This means fc6, f7, f8 and f9 will vanish soon (I decided for one month of expiry time). This is because all of them are End of Life upstream since a long time (= no security updates).

The fc4 and f10 ones are still available — even if they are End of Life too — because FreeBSD 7.x can not use something newer than the fc4 one, and we have not tested yet a more recent Linux distribution.

Probably the most easy way to update the Linux base ports to something newer is to stay with Fedora (we have a lot of ports-infrastructure for it already). Unfortunately it is not known if something newer works without problems (missing epoll/inotify support could be a roadblock here in case it is extensively used in a more recent version).

I want to get some time to have a look if a more recent Fedora version is suitable for the use as a Linux base in FreeBSD 8.x+, but I do not have an estimate when I can start and how long it may take. In case someone already tested a more recent Fedora version feel free to share your experience.

Share

HOWTO: creating your own updated linux RPM for the FreeBSD linuxulator

Background info

The FreeBSD linux compatibility environment currently uses RPMs from Fedora 10. Unfortunately Fedora 10 is end of life since a while. For one of the RPMs (the pango one) we where aware of a security vulnerability. As we do not know if it is feasible to update the linuxulator ports to something more recent, I decided to setup a VM with Fedora 10 and generate a new RPM for the linux-f10-pango port. Thanks to Luchesar V. ILIEV for explaining me how to do this.

Setup of the VM

I used VirtualBox 4.0.4 on a Solaris 10 x86 machine. I configured a fixed size disk of 16 GB and kept the default network setup (after installing the guest tools / kernel modules I switched to virtio, as I was not able to do anything useful besides a ping) and RAM size. The CD/DVD drive was configured to use the image of the full Fedora 10 DVD for i386 systems.

Setup of Fedora 10

Booting the VM from the DVD leads to the graphical Fedora 10 install software (after chosing to install a new system on the console). There I accepted all the defaults, except for the software to install. I deselected the Office and Productivity group and selected the Software Development group. When I was asked if I want to install some additional RPMs I had a look at the complete list and installed some I thought are necessary. I do not remember anymore which ones I chose, but everything which looks related to RPM building is a good candidate.

After a while the install will be finished and you can boot into the new system (eject the DVD from the drive before reboot). After reboot chose to install the Guest Additions in the menu of the VM. This should mount the ISO image in the VM. As root execute the file for Linux. This will build some kernel modules for better integration (e.g. seamless integration of the mouse between your desktop and the VM). At this point I rebooted and configured virtio as the NIC. I also had to configure the network settings by hand, as the GUI tool did not safe all the settings correctly.

Update and install of required RPMs

After the VM was up and the network configured, I updated the entire system (chose System Update in the menu). To update the pango port, I had to install the libthai-devel RPM. I had the RPM for it (and all the files I need to build a new pango RPM) already downloaded, so I did a “yum install /path/to/rpm�. At this point I was ready to create the RPM build environment.

The RPM build environment

As a normal user I executed the command rpmdev-setuptree which creates the directory rpmbuild and populates it with some directories. Now you just need to find a suitable .spec file and put it into rpmbuild/SPECS, put the sources (and maybe patches referenced in the .spec file) into rpmbuild/SOURCES, and you are ready to go (I patched pango.spec for a more recent pango version, basically just changing the version numbers). If you want to have a custom packager and vendor attribute in the RPM, you can add a line for each to ~/.rpmmacros, e.g. %packager yournamehere and %vendor whateverisappropriate. I used my @FreeBSD.org EMail address as the packager, and FreeBSD as the vendor.

Building a RPM

I used rpmbuild –ba –target i386-redhat-linux-gnu –clean rpmbuild/SPECS/pango.spec to build the new pango RPM. If everything is OK, the resulting RPMs (a source RPM, a devel RPM, a debuginfo RPM and the RPM for the binaries) are in rpmbuild/RPMS and rpmbuild/SRPMS. For a FreeBSD port we just need the source RPM (to comply to the (L)GPL) and the RPM for the binaries.

Additional info

The i386-redhat-linux-gnu string which is used for the –target option of the rpmbuild command is what seems to be used to build the Fedora 10 RPMs. After building pango, the RPM has i686-pc-linux-gnu in some filenames instead (the default value for this setup). The binaries seem to be compiled for i386, so there should be no problem even for old systems.

Share

A new linux-f10-pango port is ready

In the last days I took (and even had) the time to install a VM with Fedora 10, updated all the packages after installation, and created a new linux-f10-pango port (v 1.28.3). I did this because the port has a security vulnerability according to our VuXML DB and there where more and more reports in the last months from users which had a problem with this.

During the update of the port I noticed that the port does not contain a FORBIDDEN entry, just portaudit complains about it because there is an entry in the VuXML. That is not nice. I was told that the ports slush will be lifted soon (I need to bump some PORTREVISIONs), this means that I can commit the update probably tomorrow, just in time when the new RPM should hit the FreeBSD distribution infrastructure (MASTER_SITE_LOCAL is updated once a day from a specific folder in our home directories).

Thanks to Luchesar V. ILIEV for the nice writeup of what to install in Fedora 10 to be able to build RPMs, and the description of how to build your own RPM.

Share

The FreeBSD-linuxulator explained (for developers): basics

The last post about the Linuxulator where I explained the Linuxulator from an user point of view got some good amount of attention. Triggered by a recent explanation of the Linuxulator errno stuff to a fellow FreeBSD developer I decided so see if more developers are interested in some more info too…

The syscall vector

In sys/linux/linux_sysvec.c is all the basic setup to handle Linux “system stuff� in FreeBSD. The “system stuff� is about translating FreeBSD errnos to Linux errnos, about translating FreeBSD signals to Linux signales, about handling Linux traps, and about setting up the FreeBSD system vector (the kernel structure which contains all the data to identify when a Linux program is called and to be able to lookup the right kernel functions for e.g. syscalls and ioctls).

There is not only one syscall vector, there is one for a.out (struct sysentvec linux_sysvec) and one for ELF (struct sysentvec elf_linux_sysvec) binaries (at least on i386, for other architectures it may not make sense to have the a.out stuff, as they maybe never seen any a.out Linux binary).

The ELF AUX args

When an ELF image is executed, the Linuxulator adds some runtime information (like pagesize, uid, guid, …) so that the userland can query this information which is not static at build-time easily. This is handled in the elf_linux_fixup function(). If you see some error messages about missing ELF notes from e.g. glibc, this is the place to add this information to. It would not be bad from time to time to have a look what Linux is providing and missing pieces there. FreeBSD does not has an automated way of doing this, and I am not aware of someone who regularly checks this. There is a little bit more info about ELF notes available in a message to one of the FreeBSD mailing lists, it also has an example how to read out this data.

Traps

Linux and FreeBSD do not share the same point of view how a trap shall be handled (SIGBUS or SIGSEGV), the corresponding decision making is handled in translate_traps() and a translation table is available as _bsd_to_linux_trapcode.

Signals

The values for the signal names are not the same in FreeBSD and Linux. The translation tables are called linux_to_bsd_signal and bsd_to_linux_signal. The translation is a feature of the syscall vector (= automatic).

Errnos

The values for the errno names are not the same in FreeBSD and Linux. The translation table is called bsd_to_linux_errno. Returning an errno in one of the Linux syscalls will trigger an automatic translation from the FreeBSD errno value to the Linux errno value. This means that FreeBSD errnos have to be returned (e.g. FreeBSD ENOSYS=78) and the Linux program will receive the Linux value (e.g. Linux ENOSYS=38, and as the Linux kernel returns negative errnos, the linux program will get –38).

If you see somewhere an “-ESOMETHING� in the Linuxulator code, this is either a bug, or some clever/tricky/dangerous use of the sign-bit to encode some info (e.g. in the futex code there is a function which returns –ENOSYS, but the sign-bit is used as an error indicator and the calling code is responsible to translate negative errnos into positive ones).

Syscalls

The Linux syscalls are defined similar to the FreeBSD ones. There is a mapping table (sys/linux/syscalls.master) between syscall numbers and the corresponding functions. This table is used to generate code (“make sysent� in sys//linux/) which does what is necessary.

Share

The FreeBSD-linuxulator explained (for users)

After another mail where I explained a little bit of the linuxulator behavior, it is time to try to make an easy text which I can reference in future answers. If someone wants to add parts of this explanation to the FreeBSD handbook, go ahead.

Linux emulation? No, “native� execution (sort of)!

First, the linuxulator is not an emulation. It is “just� a binary interface which is a little bit different from the FreeBSD-“native�-one. This means that the binary files in FreeBSD and Linux are both files which comply to the ELF specification.

When the FreeBSD kernel loads an ELF file, it looks if it is a FreeBSD ELF file or a Linux ELF file (or some other flavor it knows about). Based upon this it looks up appropriate actions in a table for this binary (it can also differentiate between 64-bit and 32-bit, and probably other things too).

The FreeBSD-table is always compiled in (for a better big picture: at least on an AMD/Intel 64-bit platform there is also the possibility to include a 32-bit version of this table additionally, to be able to execute 32-bit programs on 64-bit systems), and other ones like the Linux one can be loaded additionally into the kernel (or build statically in the kernel, if desired).

Those tables contain some parameters and pointers which allow to execute the binary. If a program is making a system call, the kernel will look up the correct function inside this table. It will do this for FreeBSD binaries, and for Linux binaries. This means that there is no emulation/simulation (overhead) going on… at least ideally. Some behavior is a little bit differently between Linux and FreeBSD, so that a little bit of translation/house-keeping has to go on for some Linux system calls for the underlying FreeBSD kernel functions.

This means that a lot of Linux stuff in FreeBSD is handled at the same speed as if this Linux program would be a FreeBSD program.

Linux file/directory tricks

When the kernel detects a Linux program, it is also playing some tricks with files and directories (also a property of the above mentioned table in the kernel, so theoretically the kernel could play tricks for FreeBSD programs too).

If you look up for a file or directory /A, the kernel will first look for /compat/linux/A, and if it does not find it, it will look for /A. This is important! For example if you have an empty /compat/linux/home, any application which wants to display the contents of /home will show /compat/linux/home. As it is empty, you see nothing. If this application does not allow you to enter a directory manually via the keyboard, you have lost (ok, you can remove /compat/linux/home or fill it with what you want to have). If you can enter a directory via the keyboard, you could enter /home/yourlogin, this would first let the kernel look for /compat/linux/home/yourlogin, and as it can not find it then have a look for /home/yourlogin (which we assume is there), and as such would display the contents of your home directory.

This implies several things:

  • you can hide FreeBSD directory contents from Linux programs while still being able to access the content
  • “badlyâ€? programmed Linux applications (more correctly: Linux programs which make assumptions which do not hold in FreeBSD) can prevent you from accessing FreeBSD files, or files which are the same in Linux and FreeBSD (like /etc/group which is not available in /compat/linux in the linux_base ports, so that the FreeBSD one is read)
  • you can have different files for Linux than for FreeBSD

The Linux userland

The linux_base port in FreeBSD is coming from a plain installation of Linux packages. The difference is that some files are deleted, either because we can not use them in the linuxulator, or because they exist already in the FreeBSD tree at the same place and we want that the Linux programs use the FreeBSD file (/etc/group and /etc/passwd come to mind). The installation also marks binary programs as Linux programs, so that the kernel knows which kernel-table to consult for system calls and such (this is not really necessary for all binary programs, but it is harder to script the correct detection logic, than to just “brand� all binary programs).

Additionally some configurations are made to (hopefully) make it do the right thing out of the box. The complete setup of the linux_base ports is done to let Linux programs integrate into FreeBSD. This means if you start acroread or skype, you do not want to have to have to configure some things in /compat/linux/etc/ first to have your fonts look the same and your user IDs resolved to names (this does not work if you use LDAP or kerberos or other directory services for the user/group ID management, you need to configure this yourself). All this should just work and the application windows shall just pop up on your screen so that you can do what you want to do. Some linux_base ports also do not work on all FreeBSD releases. This can be because some kernel features which this linux_base ports depends upon is not available (yet) in FreeBSD. Because of this you should not choice a linux_base port yourself. Just go and install the program from the Ports Collection and let it install the correct linux_base port automatically (a different FreeBSD release may have a different default linux_base port).

A note of caution, there are instructions out there which tell how to install more recent linux_base ports into FreeBSD releases which do not have them as default. You do this on your own risk, it may or may not work. It depends upon which programs you use and at which version those programs are (or more technically, which kernel features they depend upon). If it does not work for you, you just have two possibilities: revert back and forget about it, or update your FreeBSD version to a more recent one (but it could be the case, that even the most recent development version of FreeBSD does not have support for what you need).

Linux libraries and “ELF file OS ABI invalid�-error messages

Due to the above explained fact about file/directory tricks by the kernel, you have to be careful with (additional) Linux libraries. When a Linux program needs some libraries, several directories (specified in /compat/linux/etc/ld.so.conf) are searched. Let us assume that the /compat/linux/etc/ld.so.conf specifies to search in /A, /B and /C. This means the FreeBSD kernel first gets a request to open /A/libXYZ. Because of this he first tries /compat/linux/A/libXYZ, and if it does not exist he tries /A/libXYZ. When this fails too, the Linux runtime linker tries the next directory in the config, so that the kernel looks now for /compat/linux/B/libXYZ and if it does not exist for /B/libXYZ.

Now assume that libXYZ is in /compat/linux/C/ as a Linux library, and in /B as a FreeBSD library. This means that the kernel will first find the FreeBSD library /B/libXYZ. The Linux binary which needs it can not do anything with this FreeBSD library (which depends upon the FreeBSD syscall table and FreeBSD symbols from e.g. libc), and the Linux runtime linker will bail out because of this (actually he sees that the lin is not of the required type by reading the ELF header of it). Unfortunately the Linux runtime linker will not continue to search for another library with the same name in another directory (at least this was the case last time I checked and modified the order in which the Linux runtime linker searches for libraries… this has been a while, so he may be smarter now) and you will see the above error message (if you started the linux program in a terminal).

The bottom line of all this is: the error message about ELF file OS ABI invalid just means that the Linux program was not able to find the correct Linux library and got a FreeBSD library instead. Go, install the corresponding Linux library, and make sure the Linux program can find it instead of the FreeBSD library (do not forget to run “/compat/linux/sbin/ldconfig –r /compat/linux� if you make changes by hand instead of using a port, else your changes may not be taken into account).

Constraints regarding chroot into /compat/linux

The linux_base ports are designed to have a nice install-and-start experience. The drawback of this is, that there is not a full Linux system in /compat/linux, so doing a chroot into /compat/linux will cause trouble (depending on what you want to do). If you want to chroot into the linux system on your FreeBSD machine, you better install a linux_dist port. A linux_dist port can be installed in parallel to a linux_base port. Both of them are independent and as such you need to redo/copy configuration changes you want to have in both environments.

Share

v4l support in the linuxulator MFCed to 8-stable

I merged the v4l translation layer into the linuxulator of 8-stable. As in –current, this just means that linux apps (like Skype) can now use FreeBSD native devices which conform to the v4l ABI. The port multimedia/webcamd provides access to some webcams (or DVB hardware) via the v4l ABI.

People which want to test the linuxulator part should first make sure a native FreeBSD application has no problem accessing the device.

Share

Video4Linux support in FreeBSD

Yesterday I committed the v4l support into the linuxulator (in 9-current). Part of this was the import of the v4l header from linux. We have the permission to use it, it is not licensed via GPL. This means we can use it in FreeBSD native drivers, and they are even allowed to be compiled into GENERIC (but I doubt we have a driver which could provide the v4l interface in GENERIC).

The code I committed is “just” the glue-code which allows to use FreeBSD native devices which provide a v4l interface (e.g. multimedia/pwcbsd) from linux programs.

If someone is willing to write the glue-code for the v4l2 interface please contact me. We have the permission to use the v4l2 header too, we just need someone doing the coding.

In a similar way, if someone is willing to add v4l2 interface support to FreeBSD native drivers (I do not know any FreeBSD driver which provides a v4l2 interface) , just tell me and I import the v4l2 header into FreeBSD.

And if someone wants to add v4l support to FreeBSD native drivers but does not know where to start, feel free to contact me too.

Regarding the code which is in FreeBSD ATM: it is not completely finished yet (some clipping related stuff is being worked on), but the not finished part can not even be tested, as we do not know about a FreeBSD device which provides this functionality.

There is no MFC planned yet, but the more success stories and test scenarios are being told about on the emulation or multimedia mailinglists, the more likely I will do a MFC sooner than later.

Share/Bookmark