[ENBD] diskless enbd-client/enbd on initrd

Rudolph Bott rb at megabit.net
Thu Feb 23 08:15:56 MST 2006


Peter T. Breuer wrote:
> "Also sprach Rudolph Bott:"
> 
>>Peter T. Breuer wrote:
>>
>>>"Also sprach Rudolph Bott:"
>>>
>>>>does anyone have experience with enbd-client on an initrd?
>>>
>>>Never ... I suppose it would be possible, but difficult, since a bit of
>>>userspace needs to be set up ... how do you chroot while the client is
>>>still running on the old root?
>>>
>>
>>Well what do you mean by "a bit"?
> 
> 
> I'm not sure, never having done it.  But as you said, you need the
> client daemon running, and you need to mount the device, and you might
> want a bit of space in /var to handle the connection state repository
> (optional).  Can't think of anything else, but I'm sure there is more
> (chroot, sh, blah, blah).
> 
> 
>>btw, I forgot to mention that I'm using enbd-2.4.33pre.tar.gz
> 
> 
> OK.
> 
> 
>>As I mentioned before, the whole thing was working with nbd (v 2.6.0).
> 
> 
> Yes, but my question about how you chroot or umount the original root
> while the clients are running on it stands.
> 
> 
>>Do you have any hints what files/directorys/devices enbd-client might 
>>require to exist in the initrd-tree?
> 
> 
> None.  The error you showed didn't seem to me to be to do with it, but
> with the question I put a couple of times now!  How can you chroot while
> the client daemons are running on the original root?  At the very least
> they have the /dev/nda* entries open, no? That's what the error seemed
> to indicate.
> 
> I'll take a look at your script, but it wouldbe easier if you put a set
> -x in it and thus got info about where the "busy" error occurs. I
> assume it is at or near a chroot or umount!
> 
> Peter
> 
> 

Below you can see how the work is done in the nbd-environment (you can 
find the nbd_root package here: http://borderworlds.dk/projects/)

What it basically does is to read/parse the kernel boot param "nbdroot", 
which contains the host "host:port" information
then (after the fork() call) it runs nbd-client with the extracted 
parameters (assuming that nbd is built into the kernel so that no module 
loading is required).
Then it triggers the mount() call to mount the nb-device under /mnt/ of 
the initrd. There is no chroot or whatsoever; its a simple call to 
pivot_root(), which swaps the "roots" (initrd and rootfs on nbd). The 
nbd-client (and the ramdisk) still reside in memory and everything works 
fine.

Now to the enbd-version...i've already posted the source code in my last 
mail so i'll leave that out for now. The error messages you see are 
generated by the function perror(), which seems to display the last 
error returned by a given function (or probably class of functions, e.g. 
mount, exec etc.).
And since the mount fails (because there is nothing "behind" /dev/nda), 
pivot_root fails, too.

I Hope that clarified some things ;)



-- begin linuxrc.c (which the kernel runs as init process)

#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <linux/unistd.h>
#include <nbdroot_version.h>

int main () {
   struct stat statbuf;
   char *root, *host, *port;
   int pid, i, j;

   fprintf(stderr, "nbd_root version %s\n", NBDROOT_VERSION);
   pid = getpid();
   if (pid != 1) {
     fprintf(stderr, "My pid is %d but should be 1, please make sure 
that linuxrc gets executed as init.\n", pid);
     return 1;
   }

   if ((root = getenv("nbdroot")) != NULL) {
     fprintf(stderr, "root: %s\n", root);
     j = -1;
     for (i = 0; i < strlen(root); ++i) {
       if (root[i] == ':') {
         j = i;
       }
     }
     if (j == -1) {
       fprintf(stderr, "\"nbdroot\" must be on the form <host>:<port>.\n");
       return 1;
     }
     host = (char *)malloc(strlen(root) + 1);
     strncpy(host, root, j);
     host[j] = 0;
     port = root + j + 1;
   } else {
     fprintf(stderr, "No root specified via the \"nbdroot\" parameter.\n");
     return 1;
   }

   if ((pid = fork())) {
     waitpid(pid,NULL,0);
   } else {
     execl("bin/nbd-client", "nbd-client", host, port, "/dev/nb0", NULL);
     perror("exec");
   }

   if (mount("/dev/nb0", "/mnt", "ext3", MS_RDONLY, "")) {
     perror("mount");
   }
   if (stat("/mnt/initrd", &statbuf)) {
     fprintf(stderr, "The directory /initrd does not exist on the root 
filesystem.\nPlease create it and try again.\n");
     return 1;
   }
   if (pivot_root("/mnt","/mnt/initrd")) {
     perror("pivot_root");
   }
   chdir("/");
   execl("/sbin/init", "init", NULL);
   fprintf(stderr, "Failed to start init :(\n");

   return 1;
}

--end linuxrc.c

-- 
Mit freundlichen Gruessen / with kind regards
  Rudolph Bott

-------------------------------------------------------------------
Megabit Informationstechnik GmbH  Karstr.25  41068 Moenchengladbach
Tel: 02161/308980   mailto:info at megabit.net       ftp://megabit.net
Fax: 02161/3089818  mailto:support at megabit.net   http://megabit.net
-------------------------------------------------------------------


More information about the ENBD mailing list