Remove all files on the initramfs before switching root
The code from pjones's tree did not include the recursive remove code, so I readded it from the nash source code.master
parent
496d08bb19
commit
05469ee13e
|
@ -34,6 +34,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
#ifndef MS_MOVE
|
#ifndef MS_MOVE
|
||||||
#define MS_MOVE 8192
|
#define MS_MOVE 8192
|
||||||
|
@ -49,6 +50,73 @@ enum {
|
||||||
err_usage,
|
err_usage,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* remove all files/directories below dirName -- don't cross mountpoints */
|
||||||
|
static int
|
||||||
|
recursiveRemove(char * dirName)
|
||||||
|
{
|
||||||
|
struct stat sb,rb;
|
||||||
|
DIR * dir;
|
||||||
|
struct dirent * d;
|
||||||
|
char * strBuf = alloca(strlen(dirName) + 1024);
|
||||||
|
|
||||||
|
if (!(dir = opendir(dirName))) {
|
||||||
|
printf("error opening %s: %m\n", dirName);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fstat(dirfd(dir),&rb)) {
|
||||||
|
printf("unable to stat %s: %m\n", dirName);
|
||||||
|
closedir(dir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
while ((d = readdir(dir))) {
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) {
|
||||||
|
errno = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(strBuf, dirName);
|
||||||
|
strcat(strBuf, "/");
|
||||||
|
strcat(strBuf, d->d_name);
|
||||||
|
|
||||||
|
if (lstat(strBuf, &sb)) {
|
||||||
|
printf("failed to stat %s: %m\n", strBuf);
|
||||||
|
errno = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* only descend into subdirectories if device is same as dir */
|
||||||
|
if (S_ISDIR(sb.st_mode)) {
|
||||||
|
if (sb.st_dev == rb.st_dev) {
|
||||||
|
recursiveRemove(strBuf);
|
||||||
|
if (rmdir(strBuf))
|
||||||
|
printf("failed to rmdir %s: %m\n", strBuf);
|
||||||
|
}
|
||||||
|
errno = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (unlink(strBuf)) {
|
||||||
|
printf("failed to remove %s: %m\n", strBuf);
|
||||||
|
errno = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno) {
|
||||||
|
closedir(dir);
|
||||||
|
printf("error reading from %s: %m\n", dirName);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int switchroot(const char *newroot)
|
static int switchroot(const char *newroot)
|
||||||
{
|
{
|
||||||
/* Don't try to unmount the old "/", there's no way to do it. */
|
/* Don't try to unmount the old "/", there's no way to do it. */
|
||||||
|
@ -74,7 +142,7 @@ static int switchroot(const char *newroot)
|
||||||
errno=errnum;
|
errno=errnum;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
recursiveRemove("/");
|
||||||
if (mount(newroot, "/", NULL, MS_MOVE, NULL) < 0) {
|
if (mount(newroot, "/", NULL, MS_MOVE, NULL) < 0) {
|
||||||
errnum = errno;
|
errnum = errno;
|
||||||
fprintf(stderr, "switchroot: mount failed: %m\n");
|
fprintf(stderr, "switchroot: mount failed: %m\n");
|
||||||
|
|
Loading…
Reference in New Issue