Peri­od­ic scrub­bing of ZFS pools

I noticed that we do not have some auto­mat­ic way of scrub­bing a ZFS pool peri­od­i­cal­ly. A quick poll on fs@ revealed, that there is inter­est in some­thing like this. So I took a lit­tle bit of time to write a peri­od­ic dai­ly script which checks if the last scrub is X days ago and scrubs a pool accord­ing­ly. The script has options to scrub all pools, or just a spe­cif­ic sub­set. It also allows to spec­i­fy a time-interval between scrubs for each pool with dif­fer­ent lev­els of fall-back (if no pool-specific inter­val is set, the default inter­val is used, which is set to 30 days if no oth­er default inter­val is specified).

The dis­cus­sion about this is hap­pen­ing over at fs@, so go there and have a look for the CFT (with a link to the WIP of the script) and the dis­cus­sion if you are interested.

So far there are some minor details to sort out (and a lit­tle bit of doc­u­men­ta­tion to write) before I can com­mit it… prob­a­bly next week.

Mono build prob­lems on FreeBSD-current

I try to build mono on FreeBSD-current (it is a depen­den­cy of some GNOME pro­gram). Unfor­tu­nate­ly this does not work correctly.

What I see are hangs of the build. If I stop the build when it hangs and restart it, it will con­tin­ue and suc­ceed to process the build steps a lit­tle bit fur­ther, but then it hangs again.

If I ktrace the hang­ing process, I see that there is a call to wait return­ing with the error mes­sage that the child does not exist. Then there is a call to nanosleep.

It looks to me like this process missed some SIGCLD (or is wait­ing for some­thing which did not exist at all), and a loop is wait­ing for a child to exit. This loop prob­a­bly has no prop­er con­di­tion for the fact that there is no such child (any­more). As such it will stay for­ev­er in this loop.

So I grepped a litte bit around in mono and found the fol­low­ing code in <mono-src-dir>/mcs/class/Mono.Posix/Mono.Unix/UnixProcess.cs:

public void WaitForExit ()
{
    int status;
    int r;
    do {
        r = Native.Syscall.waitpid (pid, out status, (Native.WaitOptions) 0);
    } while (UnixMarshal.ShouldRetrySyscall (r));
    UnixMarshal.ThrowExceptionForLastErrorIf (r);
}

This does look a lit­tle bit as it could be relat­ed to the prob­lem I see, but Shoul­dRetrySyscall only returns true if the errno is EINTR. So this looks correct. 🙁

I looked a lit­tle bit more at this file and it looks like either I do not under­stand the seman­tic of this lan­guage, or Get­ProcessSta­tus does return the return­val­ue of the wait­pid call instead of the sta­tus (which is not what it shall return to my under­stand­ing). If I am cor­rect, it can not real­ly detect the sta­tus of a process. It would be very bad if such a fun­da­men­tal thing went unno­ticed in mono…  which does not put a good light on the unit-tests (if any) or the gen­er­al test­ing of mono. For this rea­son I hope I am wrong.

I did not stop there, as this part does not look like it is the prob­lem. I found the fol­low­ing in mono/io-layer/processes.c:

static gboolean waitfor_pid (gpointer test, gpointer user_data)
{
...
    do {
        ret = waitpid (process->id, &status, WNOHANG);
    } while (errno == EINTR);

    if (ret <= 0) {
        /* Process not ready for wait */
#ifdef DEBUG
        g_message ("%s: Process %d not ready for waiting for: %s",
                   __func__, process->id, g_strerror (errno));
#endif

        return (FALSE);
    }

#ifdef DEBUG
    g_message ("%s: Process %d finished", __func__, ret);
#endif

    process->waited = TRUE;
...
}

And here we have the prob­lem, I think. I changed the (ret <= 0) to  (ret == 0 || (ret < 0 && errno != ECHILD)). This will not real­ly give the cor­rect sta­tus, but at least it should not block any­more and I should be able to see the dif­fer­ence dur­ing the build.

And now after test­ing, I see a dif­fer­ence, but the prob­lem is still there. The wait with ECHILD is gone in the loop, but there is still some loop with a sem­a­phore operation:

62960 mono     CALL  clock_gettime(0xd,0xbf9feef8)
62960 mono     RET   clock_gettime 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   semop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   semop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   semop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   semop 0
62960 mono     CALL  nanosleep(0xbf9fef84,0)
62960 mono     RET   nanosleep 0
62960 mono     CALL  clock_gettime(0xd,0xbf9feef8)
62960 mono     RET   clock_gettime 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   semop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   semop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   semop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   semop 0
62960 mono     CALL  nanosleep(0xbf9fef84,0)

OK, there is more going on. I think some­one with more knowl­edge about mono should have a look at this (do not only look at this semop thing, but also look why it los­es a child).

I do not like being ill

Unfor­tu­nate­ly you can not chose…

So, I am now on the sofa, cov­ered a lot (a flu, I even have no voice any­more; before I left work a female cowork­er told that her hus­band would prob­a­bly be hap­py if this would hap­pen to her…  😀 ) and med­ica­tion and water are not far away on the table.

The good thing with the cur­rent tech­nol­o­gy is, that you can still be a lit­tle bit pro­duc­tive (depend­ing on the illness).

As you can read this, it means I have my net­book with me, so that I can take care about some sim­ple things.

Video for lin­ux (v4l) emu­la­tion com­ing to the linuxulator

I am in the process of prepar­ing the import of code which makes v4l devices usable in the lin­ux­u­la­tor. Basi­cal­ly this means you can use your web­cam in skype (test­ed by the sub­mit­ter of the patch on amd64).

This is not a “apply patch and com­mit” thing, because the orig­i­nal videodev.h (with some mod­i­fi­ca­tions) is used. I was seek­ing the OK from core@ for this. As there is no license in the head­er, and the orig­i­nal author (Alan Cox, the lin­ux one, not our FreeB­SD one) gave per­mis­sions to use it, core@ is OK with the import.

I intent to do a ven­dor import of the lin­ux head­er (pre­pared today, togeth­er with some readme which explains where it comes from and some stuff to show that we are on the safe side regard­ing legal stuff), and then I want to copy this over to the lin­ux­u­la­tor as linux_videodev.h and com­mit the patch (prob­a­bly a lit­tle bit mod­i­fied in a few places). My plan is to com­mit it this week. Peo­ple which already want to play around with it now can have a look at the emu­la­tion mail­inglist, a link to the patch is post­ed there.

With the head­er being in a ven­dor branch, inter­est­ed peo­ple could then start to sub­mit new BSD licensed dri­vers or mod­i­fy exist­ing dri­vers which make use of the v4l inter­face, but I let the import of the head­er into the FreeB­SD include direc­to­ry up to the per­son which wants to com­mit the first native FreeBSD-v4l support.

When such native FreeBSD-v4l sup­port is com­mit­ted, the lin­ux­u­la­tor code needs to be revised.