Author Archives: netchild

About netchild

A FreeBSD committer.

Updating FreeBSD 8.2 (or 9.x) to 10 (beta4)

This is a little description how I remotely (no console, booted into multi-user during update, no external services like jails/httpd/… running) updated a FreeBSD 8.2 to 10 (beta4) from source. This should also work when updating from FreeBSD 9.x. Note, I had already switched to ATA_CAM on 8.2, so not instructions for the name change of the ata devices. No IPv6, WLAN or CARP is in use here, so changes which are needed in this area are not covered. Read UPDATING carefully, there are a lot of changes between major releases.

What I did:

  • update /usr/src
  • make buildworld
  • replace “make ” in /usr/src/Makefile.inc1 with ${MAKE} (two times, one for “VERSION”, one for “BRANCH”)
  • verify kernel config for changes needed (running “config MyKernel” in /usr/src/sys/YourArch/conf/ helps to identify syntax problems), sorry I didn’t take notes, but I diffed the old and the new GENERIC config and added/removed according to my interests
  • /usr/obj/…/src/usr.bin/bmake/make buildkernel KERNCONF=MyKernel
  • /usr/obj/…/src/usr.bin/bmake/make installkernel KERNCONF=MyKernel KODIR=/boot/kernel.10
  • mergemaster –p
  • /usr/obj/…/src/usr.bin/bmake/make installworld DESTDIR=/somewhere/test
  • mkdir /root/net10; cp /somewhere/test/rescue/ifconfig /somewhere/test/rescue/route /root/net10
  • create the file /etc/rc.10update with:
    case $(uname –r) in
    8.2*)
            MYIFCONFIG=/sbin/ifconfig
            MYROUTE=/sbin/route
            ;;
    10*)
            MYIFCONFIG=/root/net10/ifconfig
            MYROUTE=/root/net10/route
            ;;
    esac
    export MYIFCONFIG
    export MYROUTE
  • change the files (stupid approach: grep for “ifconfig” and “route” in /etc/rc.d to identify files which need to change, I skipped files which I identified as not needed in my case, if you use pf/IPv6/bridge/…, you may have to change some more files) /etc/rc.d/auto_linklocal /etc/rc.d/defaultroute /etc/rc.d/netif /etc/rc.d/netwait /etc/rc.d/routing: add “. /etc/rc.10update” at the end of the block with “. /etc/rc.subr”, change the “ifconfig”-command to ${MYIFCONFIG}, change the “route”-command to ${MYROUTE}
  • change /etc/network.subr: add “. /etc/rc.10update” before the first function, change the “ifconfig”-command to ${MYIFCONFIG}, change the “route”-command to ${MYROUTE}
  • make sure that the changes you made are 100% correct, rather triple-check than to not check at all (you will be locked out if they are not 100% OK)
  • stop any jails and make sure they do not restart at boot
  • deactivate the gmirror of the root-fs, if there is one (it is maybe easier to ask a remote hand to swap the boot order in case of problems)
  • here you could just a reboot of the server to come back to your current OS version, so make sure that the modifications in /etc did not cause any problems with the old version (in case you see problems with the v10 kernel), but if you do not have a remote console to single-user mode you have no chance to directly fix the problem (risk mitigation described above), no matter which version of the kernel you boot
  • nextboot –k kernel.10
  • shutdown –r now
  • login
  • check dmesg
  • optional: mv /boot/kernel /boot/kernel.8
  • make installkernel KERNCONF=MyKernel
    to have a v10 /boot/kernel
  • make installworld
  • mergemaster
  • make delete-old
  • rm –r /etc/rc.10update /root/net10
  • change rc.conf: add “inet” in ifconfig-aliases
  • review sysctl.conf for outdated entries
  • shutdown –r now
  • optional: rm –r /boot/kernel.10
  • enable jails again (or later… updating jails is not described here)
  • activate/resync mirror(s)
  • rebuild all ports (attention: new pkg system)
  • make delete-old-libs
  • reboot again to make sure everything is OK after the port-rebuild and removal of old libs (a console.log (syslog.conf) helps here

Share/Save

Which crypto card to use with FreeBSD (ssh/gpg)

The recent security incident triggered a discussion how to secure ssh/gpg keys.

One way I want to focus on here (because it is the way I want to use at home), is to store the keys on a crypto card. I did some research for suitable crypto cards and found one which is called Feitian PKI Smartcard, and one which is called OpenPGP card. The OpenPGP card also exists in a USB version (basically a small version of the card is already integrated into a small USB card reader).

The Feitian card is reported to be able to handle RSA keys upto 2048 bits. They do not seem to handle DSA (or ECDSA) keys. The smartcard quick starter guide they have  (the Tuning smartcard file system part) tells how to change the parameters of the card to store upto 9 keys on it.

The spec of the OpenPGP card tells that it supports RSA keys upto 3072 bits, but there are reports that it is able to handle RSA keys upto 4096 bits (you need to have at least GPG 2.0.18 to handle that big keys on the crypto card). It looks to me like the card is not handle DSA (or ECDSA) cards. There are only slots for upto 3 keys on it.

If I go this way, I would also need a card reader. It seems a class 3 one (hardware PIN pad and display) would be the most “future-proof” way to go ahead. I found a Reiner SCT cyberJack secoder card reader, which is believed to be supported by OpenSC and seems to be a good balance between cost and features of the Reiner SCT card readers.

If anyone reading this can suggest a better crypto card (keys upto 4096 bits, more than 3 slots, and/or DSA/ECDSA  support), or a better card reader, or has any practical experience with any of those components on FreeBSD, please add a comment.

Share/Save

Algorithm to detect repo-copies in CVS

FreeBSD is on its way to move from CVS to SVN  for the version control system for the Ports Collection. The decision was made to keep the complete history, so the complete CVS repository has to be converted to SVN.

As CVS has no way to record a copy or move of files inside the repository, we copied the CVS files inside the repository in case we wanted to copy or move a file (the so called “repocopy”). While this allows to see the full history of a file, the drawback is that you do not really know when a file was copied/moved if you are not strict at recording this info after doing a copy. Guess what, we where not.

Now with the move to SVN which has a build-in way for copies/moves, it would be nice if we could record this info. In an internal discussion someone told its not possible to detect a repocopy reliably.

Well, I thought otherwise and an hour later my mail went out how to detect one. The longest time was needed to write how to do it, not to come up with a solution. I do not know if someone picked up this algorithm and implemented something for the cvs2svn converter, but I decided to publish the algorithm here if someone needs a similar functionality somewhere else. Note, the following is tailored to the structure of the Ports Collection. This allows to speed up some things (no need to do all steps on all files). If you want to use this in a generic repository where the structure is not as regular as in our Ports Collection, you have to run this algorithm on all files.

It also detects commits where multiple files where committed at once in one commit (sweeping commits).

Preparation

  • check only category/name/Makefile
  • generate a hash of each commitlog+committer
  • if you are memory-limited use ha/sh/ed/dirs/cvs-rev and store pathname in the list cvs-rev (pathname = “category-name”) as storage
  • store the hash also in pathname/cvs-rev

If you have only one item in ha/sh/ed/dirs/cvs-rev in the end, there was no repocopy and no sweeping commit, you can delete this ha/sh/ed/dirs/cvs-rev.

If you have more than … let’s say … 10 (subject to tuning) pathnames in ha/sh/ed/dirs/cvs-rev you found a sweeping commit and you can delete the ha/sh/ed/dirs/cvs-rev.

The meat

The remaining ha/sh/ed/dirs/cvs-rev are probably repocopies. Take one ha/sh/ed/dirs/cvs-rev and for each pathname (there may be more than 2 pathnames) in there have a look at pathname/. Take the first cvs-rev of each and check if they have the same hash. Continue with the next rev-number for each until you found a cvs-rev which does not contain the same hash. If the number of cvs-revs since the beginning is >= … let’s say … 3 (subject to tuning), you have a candidate for a repocopy. If it is >=  … 10 (subject to tuning), you have a very good indicator for a repocopy. You have to proceed until you have only one pathname left.

You may detect multiple repocopies like A->B->C->D or A->B + A->D + A->C here.

Write out the repocopy candidate to a list and delete the ha/sh/ed/dirs/cvs-rev for each cvs-rev in a detected sequence.

This finds repocopy candidates for category/name/Makefile. To detect the correct repocopy-date (there are maybe cases where another file was changed after the Makefile but before the repocopy), you now have to look at all the files for a given repocopy-pair and check if there is a matching commit after the Makefile-commit-date. If you want to be 100% sure, you compare the complete commit-history of all files for a given repocopy-pair.

Share/Save

Alexander Leidinger

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

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

In case you have not noticed yet, KDTRACE_HOOKS is now in the GENERIC kernel in FreeBSD-current. This means you just need to load the DTrace modules and can use DTrace with the GENERIC kernel.

In case you do not know what you can do with DTrace, take the time to have a look at the DTrace blog. It is worth any minute you invest reading it.

Share

Alexander Leidinger

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

Alexander Leidinger

I just updated to a recent -current and tried the new nullfs. Sockets (e.g. the MySQL one) work now with nullfs. No need to have e.g. jails on the same FS and hardlink the socket to not need to use TCP in MySQL (or an IP at all for the jail).

Great work!

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

More drivers available in the FreeBSD-kernel doxygen docs

Yesterday I committed some more configs to generate doxygen documentation of FreeBSD-kernel drivers. I mechanically generated missing configs for subdirectories of src/sys/dev/. This means there is no dependency information included in the configs, and as such you will not get links e.g. to the PCI documentation, if a driver calls functions in the PCI driver (feel free to tell me about such dependencies).

If  you want to generate the HTML or PDF version of some subsystem, just go to src/tools/kerneldoc/subsys/ an run “make

How to fix FreeBSD for corporations (and user with smaller installations), the tools-viewpoint

There is a huge discussion going on on hackers@ about how FreeBSD is not suitable for large installations (anymore?). As of this writing, the discussion seems to get some discussion-clusters. We have some sub-topics which could lead to some good improvements.

One subtopic is the release engineering. Some changes like a more guided approach of what should be merged to which branch, the frequency of releases and maybe some kind of long-term-branch(es). There is some discussion to get maybe some joined-funding in some way from interested parties to pay someone to take care about long-term-branch(es).

Another subtopic is the way bugs are handled in our old bugtracking software and how patches go unnoticed there.

And both of them are connected (parts more, parts less) by what can be done in a volunteer project.

To me it looks like the proposals “just

Tuning guide in the wiki

In the light of the recent benchmark discussion, a volunteer imported the tuning man-page into the wiki. Some comments at some places for possible improvements are already made. Please go over there, have a look, and participate please (testing/verification/discussion/improvements/…).

As always, feel free to register with FirstnameLastname and tell a FreeBSD committer to add you to the contributors group for write access (you also get the benefit to be able to register for an email notification for specific pages).

Share

A phoronix benchmark creates a huge benchmarking discussion

The recent Phoronix benchmark which compared a release candidate of FreeBSD 9 with Oracle Linux Server 6.1 created a huge discussion in the FreeBSD mailinglists. The reason was that some people think the numbers presented there give a wrong picture of FreeBSD. Partly because not all benchmark numbers are presented in the most prominent page (as linked above), but only at a different place. This gives the impression that FreeBSD is inferior in this benchmark while it just puts the focus (for a reason, according to some people) on a different part of the benchmark (to be more specific, blogbench is doing disk reads and writes in parallel, FreeBSD gives higher priority to writes than to reads, FreeBSD 9 outperforms OLS 6.1 in the writes while OLS 6.1 shines with the reads, and only the reads are presented on the first page). Other complaints are that it is told that the default install was used (in this case UFS as the FS), when it was not (ZFS as the FS).

The author of the Phoronix article participated in parts of the discussion and asked for specific improvement suggestions. A FreeBSD committer seems to be already working to get some issues resolved. What I do not like personally, is that the article is not updated with a remark that some things presented do not reflect the reality and a retest is necessary.

As there was much talk in the thread but not much obvious activity from our side to resolve some issues, I started to improve the FreeBSD wiki page about benchmarking so that we are able to point to it in case someone wants to benchmark FreeBSD. Others already chimed in and improved some things too. It is far from perfect, some more eyes — and more importantly some more fingers which add content — are needed. Please go to the wiki page and try to help out (if you are afraid to write something in the wiki, please at least tell your suggestions on a FreeBSD mailinglist so that others can improve the wiki page).

What we need too, is a wiki page about FreeBSD tuning (a first step would be to take the man-page and convert it into a wiki page, then to improve it, and then to feed back the changes to the man-page while keeping the wiki page to be able to cross reference parts from the benchmarking page).

I already told about this in the thread about the Phoronix benchmark: everyone is welcome to improve the situation. Do not talk, write something. No matter if it is an improvement to the benchmarking page, tuning advise, or a tool which inspects the system and suggests some tuning. If you want to help in the wiki, create a FirstnameLastname account and ask a FreeBSD comitter for write access.

A while ago (IIRC we have to think in months or even years) there was some framework for automatic FreeBSD benchmarking. Unfortunately the author run out of time. The framework was able to install a FreeBSD system on a machine, run some specified benchmark (not much benchmarks where integrated), and then install another FreeBSD version to run the same benchmark, or to reinstall the same version to run another benchmark. IIRC there was also some DB behind which collected the results and maybe there was even some way to compare them. It would be nice if someone could get some time to talk with the author to get the framework and set it up somewhere, so that we have a controlled environment where we can do our own benchmarks in an automatic and repeatable fashion with several FreeBSD versions.

Share

(Free)BSD inside Android

Today I was looking into the OpenSource licenses which are displayed for Android (2.3.4). There are several files which come with a BSD license.

During looking at it, I noticed that the libm has the copyright of several FreeBSD people. I did not had an in-deep look if this is because they took the FreeBSD libm, or if this is because parts of the FreeBSD libm where adopted by other BSD projects.

What I noticed is, that some special characters are not displayed correctly. For example the name Dag-Erling Smørgrav looks mangled in the display of the license inside the phone (I hope it is displayed better in my blog). His name is not the only problem case, there are also other characters which are not rendered as expected.

This does not really look professional.

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