diff -ruN mkinitrd-4.2.1.10.reiserfs/nash/nash.8 mkinitrd-4.2.1.10/nash/nash.8 --- mkinitrd-4.2.1.10.reiserfs/nash/nash.8 2004-08-03 02:28:09.000000000 +0400 +++ mkinitrd-4.2.1.10/nash/nash.8 2007-06-13 23:06:32.000000000 +0400 @@ -38,7 +38,7 @@ .TP \fBfind \fIdir\fR -name \fIname\fR -Display the path to files named \fIname\fR in or below directory \fIdir\FR. +Display the path to files named \fIname\fR in or below directory \fIdir\fR. This is a \fBvery\fR limited implementation of find(1). .TP @@ -47,6 +47,10 @@ system. If none is available, no output is displayed. .TP +\fBinsmod\fR \fImodule\fR [ \fImodule options\fR ... ] +Inserts a module into the kernel. + +.TP \fBlosetup \fI/dev/loopdev\fR \fIfile\fR Binds \fIfile\fR to the loopback device \fI/dev/loopdev\fR. See \fBlosetup(8)\fR for information on loopback devices. @@ -84,10 +88,10 @@ the device number. .TP -\fBmount \fI[--ro]\fR -o \fIopts\fR -t \fItype\fR \fIdevice\fR \fImntpoint\fR +\fBmount\fR [ --ro ] -o \fIopts\fR -t \fItype\fR \fIdevice\fR \fImntpoint\fR Mounts a filesystem. It does not support NFS, and it must be used in the form given above (arguments must go first). If \fIdevice\fR is of the form -\fBLABEL=\fIfoo\fR the devices listed in /fB/proc/partitions\fR will +\fBLABEL=\fIfoo\fR the devices listed in \fB/proc/partitions\fR will be searched, and the first device with a volume label of \fIfoo\fR will be mounted. Normal \fBmount\fR(2) options are supported, and \fB--ro\fR will mount the filesystem read only for compatibility with older versions of nash. @@ -99,13 +103,23 @@ and mounts the current root filesystem as \fIoldrootpath\fR. .TP +\fBraidautorun \fImddevice\fR +Runs raid autodetection on all raid-typed partitions. \fImddevice\fR must +be a raid device (any will do). + +.TP \fBreadlink \fIpath\fR Displays the value of the symbolic link \fIpath\fR. .TP -\fBraidautorun \fImddevice\fR -Runs raid autodetection on all raid-typed partitions. \fImddevice\fR must -be a raid device (any will do). +\fBrm\fR [ -r | -n ] \fIpath\fR [ [ -r | -n ] \fIpath2\fR [ ... ] ] +Removes file(s) or directory(s) \fIpath1\fR, \fIpath2\fR... +If specified \fI-r\fR key then rm enters to subdirectories +recursively. \fI-n\fR key disables recursion. + +.TP +\fBrmdir \fIpath1\fR [ \fIpath2\fR [ ... ] ] +Removes empty directory(s) \fIpath1\fR, \fIpath2\fR... .TP \fBsetquiet\fR @@ -120,15 +134,22 @@ Sleep for \fInum\fR seconds .TP +\fBstabilized\fR [ --iterations \fIN\fR ] [ --interval \fIMSECS\fR ] \fIfile\fR + +.TP \fBswitchroot \fInewrootpath\fR -Makes the filesystem mounted at \fInewrootpath\fR the new root -filesystem by moving the mountpoint. This will only work in 2.6 or -later kernels. +Unmounts \fI/dev\fR, \fI/proc\fR and \fI/sys\fR, removes them and makes the filesystem +mounted at \fInewrootpath\fR the new root filesystem by moving the mountpoint. +This will only work in 2.6 or later kernels. .TP \fBumount \fIpath\fR Unmounts the filesystem mounted at \fIpath\fR. +.TP +\fBunlink \fIfile\fR [ \fIfile2\fR [ ... ] ]\fR +Removes file(s) \fIfile\fR, \fIfile2\fR... + .SH RETURN VALUE Returns 0 is the last command succeeded or 1 if it failed. diff -ruN mkinitrd-4.2.1.10.reiserfs/nash/nash.c mkinitrd-4.2.1.10/nash/nash.c --- mkinitrd-4.2.1.10.reiserfs/nash/nash.c 2007-06-13 22:58:12.000000000 +0400 +++ mkinitrd-4.2.1.10/nash/nash.c 2007-06-13 23:10:26.000000000 +0400 @@ -771,6 +771,8 @@ return 0; } +int doRm(const char *path, int recursive); + #define MAX_INIT_ARGS 32 /* 2.6 magic not-pivot-root but kind of similar stuff. * This is based on code from klibc/utils/run_init.c @@ -807,6 +809,12 @@ if (init == NULL) cmdline = getKernelCmdLine(); + doRm("/dev", 1); + umount("/proc"); + rmdir("/proc"); + umount("/sys"); + rmdir("/sys"); + if (mount(".", "/", NULL, MS_MOVE, NULL)) { printf("switchroot: mount failed: %d\n", errno); return 1; @@ -1556,6 +1564,134 @@ return 0; } +int doRm(const char *path, int recursive) { + struct stat st; + int result = 0; + stat(path, &st); + if ( S_ISDIR(st.st_mode) ) { + if (recursive) { + DIR *dir = opendir(path); + if (dir) { + size_t np_size = 0; + char * new_path = NULL; + struct dirent *de; + while( (de = readdir(dir)) ) { + if ( strcmp(de->d_name, "..") && strcmp(de->d_name, ".") ) { // do not delete ".." and "." entries + const size_t new_size = strlen(de->d_name) + strlen(path) + 2; + if (new_size > np_size) { + np_size = new_size; + new_path = (char*)realloc(new_path, np_size); + } + strncpy(new_path, path, np_size); + strcat(new_path, "/"); + strcat(new_path, de->d_name); + doRm(new_path, recursive); + } + } + free(new_path); + closedir(dir); + } + } + result = rmdir(path); + } else + result = unlink(path); + + if (result != 0) + printf("rm: unable to remove \"%s\": %d\n", path, errno); + return result; +} + +int rmCommand(char * cmd, char * end) { + int recursive = 0; + char *arg; + while( (cmd = getArg(cmd, end, &arg)) ) { + if ( !strcmp("-r", arg) ) + recursive = 1; + else if ( !strcmp("-n", arg) ) + recursive = 0; + else + doRm(arg, recursive); + } + return 0; +} + +int rmdirCommand(char * cmd, char * end) { + char *path; + int result = -1; + while( (cmd = getArg(cmd, end, &path)) ) { + if (result < 0) + result = 1; + if ( rmdir(path) ) + printf("rmdir: unable to delete \"%s\": %d\n", path, errno); + else + result = 0; + } + return result; +} + +int unlinkCommand(char * cmd, char * end) { + char *path; + int result = -1; + while( (cmd = getArg(cmd, end, &path)) ) { + if (result < 0) + result = 1; + if ( unlink(path) ) + printf("unlink: unable to delete \"%s\": %d\n", path, errno); + else + result = 0; + } + return result; +} + +extern long init_module(void*, unsigned long, const char *); + +int insmodCommand(char * cmd, char * end) { + char *modname; + int fd; + int result = 1; + if ( !(cmd = getArg(cmd, end, &modname)) ) { + printf("insmod: path expected\n"); + return 1; + } + if ( (fd = open(modname, O_RDONLY) ) < 0) { + printf("insmod: unable to open \"%s\": %d\n", modname, errno); + return 1; + } + do { + void *buffer; + off_t modsize = lseek(fd, 0, SEEK_END); + if (modsize == (off_t)-1) { + printf("insmod: unable to determine module \"%s\" size: %d\n", modname, errno); + break; + } + + buffer = malloc(modsize); + if (buffer == NULL) { + printf("insmod: unable to allocate memory for \"%s\": %d\n", modname, errno); + break; + } + + lseek(fd, 0, SEEK_SET); + if ( read(fd, buffer, modsize) != modsize) { + printf("insmod: unable to read \"%s\": %d\n", modname, errno); + free(buffer); + break; + } + + *end = '\0'; + if (init_module(buffer, modsize, (cmd < end) ? cmd : "") ) { + printf("insmod: unable to insert module \"%s %s\": %d\n", modname, cmd, errno); + free(buffer); + break; + } + + result = 0; + } while(0); + + close(fd); + return result; +} + int runStartup(int fd) { char contents[32768]; int i; @@ -1645,6 +1781,14 @@ rc = readlinkCommand(chptr, end); else if (!strncmp(start, "setquiet", MAX(8, chptr-start))) rc = setQuietCommand(chptr, end); + else if (!strncmp(start, "rm", MAX(2, chptr-start))) + rc = rmCommand(chptr, end); + else if (!strncmp(start, "insmod", MAX(6, chptr - start))) + rc = insmodCommand(chptr, end); + else if (!strncmp(start, "unlink", MAX(6, chptr - start))) + rc = unlinkCommand(chptr, end); + else if (!strncmp(start, "rmdir", MAX(5, chptr - start))) + rc = rmdirCommand(chptr, end); #ifdef DEBUG else if (!strncmp(start, "cat", MAX(3, chptr-start))) rc = catCommand(chptr, end); diff -ruN mkinitrd-4.2.1.10.orig/mkinitrd mkinitrd-4.2.1.10/mkinitrd --- mkinitrd-4.2.1.10.orig/mkinitrd 2007-01-31 23:45:09.000000000 +0300 +++ mkinitrd-4.2.1.10/mkinitrd 2007-06-13 23:18:06.000000000 +0400 @@ -518,6 +518,17 @@ rootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $3; exit }}' $fstab) rootopts=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $4; exit }}' $fstab) +# in case the root filesystem in fstab set to `auto' +if [ "$rootfs" == "auto" ]; then + echo "Warning: root filesystem type in fstab is 'auto'." >&2 + while read MNT_LINE; do + if [ "`echo $MNT_LINE | cut --delimiter=' ' --field=2`" == "/" ]; then + rootfs="`echo $MNT_LINE | cut --delimiter=' ' --field=3`" + test "$rootfs" != "rootfs" && break + fi + done < /proc/mounts +fi + # in case the root filesystem is modular findmodule -${rootfs} @@ -601,10 +612,11 @@ ln -s bin $MNTIMAGE/sbin inst /sbin/nash "$MNTIMAGE/bin/nash" -inst /sbin/insmod.static "$MNTIMAGE/bin/insmod" +strip --strip-all "$MNTIMAGE/bin/nash" ln -s /sbin/nash $MNTIMAGE/sbin/modprobe if [ -n "$USE_UDEV" ]; then + inst /sbin/insmod.static "$MNTIMAGE/bin/insmod" inst /sbin/udev.static $MNTIMAGE/sbin/udev ln -s udev $MNTIMAGE/sbin/udevstart mkdir -p $MNTIMAGE/etc/udev @@ -788,6 +800,10 @@ [ -n "$UDEV_KEEP_DEV" ] && echo "mount -t tmpfs --bind /dev /sysroot/dev" >> $RCFILE + echo "echo Removing temporary files" >> $RCFILE + echo "rm -r /bin /etc /init /lib /loopfs" >> $RCFILE + echo "unlink /sbin" >> $RCFILE + echo "echo Switching to new root" >> $RCFILE echo "switchroot /sysroot" >> $RCFILE else