Updates to handle Linux 2.4.0 kernels (kludged around the "none" entries in

/proc/mounts, added a hack to make sysinfo work with both old and new kernels).
 -Erik
This commit is contained in:
Eric Andersen 2000-06-26 10:45:52 +00:00
parent 8a24a6783a
commit 10dc9d4d17
14 changed files with 159 additions and 47 deletions

View File

@ -1,3 +1,13 @@
0.46
* Updates to handle Linux 2.4.0 kernels (kludged around the
"none" entries in /proc/mounts, added a hack to make sysinfo
work with both old and new kernels).
* Fixed a nasty bug in tar when could mess up saved symlinks.
-Erik Andersen
0.45 0.45
* Now compiles vs libc5 (which can save lots of space for * Now compiles vs libc5 (which can save lots of space for
embedded systems). embedded systems).

23
TODO
View File

@ -39,31 +39,14 @@ list discussion):
Linux 2.4.x kernels Linux 2.4.x kernels
BusyBox 0.45 currently will not work with the Linux 2.4.x kernels. BusyBox 0.46 currently will not work with the Linux 2.4.x kernels.
I know of the following problems: I know of the following problems:
1) The sysinfo syscall has changed what it does (binary incompatable), breaking 1) BusyBox NFS support is broken with 2.4.x (needs to be adjusted for NFSv3 and
init and free.
2) BusyBox NFS support is broken with 2.4.x (needs to be adjusted for NFSv3 and
kernel header changes). kernel header changes).
3) mount,umount,and df are all broken by the "none" entries for fake filesystems
such as the shared mem one. Al Viro claims these will be disappearing soon...
I made a kernel patch that reverts the sysinfo changes
http://kernelnotes.org/lnxlists/linux-kernel/lk_0006_01/msg00619.html
and I have been fighting with Alan Cox to get these changes fixed in a binary
compatable way, but Alan has so far not been very receptive. I am planning on
appealing to Linus (when he gets back from vacation) and then going with
whatever he decides...
So my thought is, 2.4.x just isn't ready for BusyBox to target it, and even if
it was, BusyBox isn't ready yet either. Seems to me like this will not be
ready for a while, and we should just not worry about it yet.
As long as I have BB_FEATURE_NFSMOUNT turned off, everything compiles cleanly As long as I have BB_FEATURE_NFSMOUNT turned off, everything compiles cleanly
for me with linux2.4.0test1-ac22-riel (i.e. I don't see the freeramdisk.c for me with linux2.4.0test2. I use Debian potato (gcc 2.95.2, GNU libc 2.1.3).
problem you reported). I use Debian potato (gcc 2.95.2, GNU libc 2.1.3).
Of course, as noted above, compiling != working. Of course, as noted above, compiling != working.
----------- -----------

View File

@ -103,6 +103,9 @@ extern int df_main(int argc, char **argv)
} }
while ((mountEntry = getmntent(mountTable))) { while ((mountEntry = getmntent(mountTable))) {
if (strcmp(mountEntry->mnt_fsname, "none") == 0) {
continue;
}
df(mountEntry->mnt_fsname, mountEntry->mnt_dir); df(mountEntry->mnt_fsname, mountEntry->mnt_dir);
} }
endmntent(mountTable); endmntent(mountTable);

3
df.c
View File

@ -103,6 +103,9 @@ extern int df_main(int argc, char **argv)
} }
while ((mountEntry = getmntent(mountTable))) { while ((mountEntry = getmntent(mountTable))) {
if (strcmp(mountEntry->mnt_fsname, "none") == 0) {
continue;
}
df(mountEntry->mnt_fsname, mountEntry->mnt_dir); df(mountEntry->mnt_fsname, mountEntry->mnt_dir);
} }
endmntent(mountTable); endmntent(mountTable);

36
free.c
View File

@ -23,20 +23,36 @@
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <sys/sysinfo.h> #include <errno.h>
#define DIVISOR 1024
extern int free_main(int argc, char **argv) extern int free_main(int argc, char **argv)
{ {
struct sysinfo info; struct sysinfo info;
sysinfo(&info); sysinfo(&info);
info.totalram/=DIVISOR; /* Kernels prior to 2.4.x will return info.mem_unit==0. Kernels after
info.freeram/=DIVISOR; * 2.4.x actually fill this value in */
info.totalswap/=DIVISOR; if (info.mem_unit==0) {
info.freeswap/=DIVISOR; /* Looks like we have a kernel prior to Linux 2.4.x */
info.sharedram/=DIVISOR; info.mem_unit=1024;
info.bufferram/=DIVISOR; info.totalram/=info.mem_unit;
info.freeram/=info.mem_unit;
info.totalswap/=info.mem_unit;
info.freeswap/=info.mem_unit;
info.sharedram/=info.mem_unit;
info.bufferram/=info.mem_unit;
} else {
/* Bah. Linux 2.4.x completely changed sysinfo. This can in theory
overflow a 32 bit unsigned long, but who puts more then 4GiB ram+swap
on an embedded system? */
info.mem_unit/=1024;
info.totalram*=info.mem_unit;
info.freeram*=info.mem_unit;
info.totalswap*=info.mem_unit;
info.freeswap*=info.mem_unit;
info.sharedram*=info.mem_unit;
info.bufferram*=info.mem_unit;
}
if (argc > 1 && **(argv + 1) == '-') { if (argc > 1 && **(argv + 1) == '-') {
usage("free\n" usage("free\n"
#ifndef BB_FEATURE_TRIVIAL_HELP #ifndef BB_FEATURE_TRIVIAL_HELP
@ -61,3 +77,5 @@ extern int free_main(int argc, char **argv)
info.freeram+info.freeswap); info.freeram+info.freeswap);
return(TRUE); return(TRUE);
} }

20
init.c
View File

@ -42,7 +42,6 @@
#include <linux/version.h> #include <linux/version.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <sys/sysinfo.h> /* For check_free_memory() */
#include <sys/fcntl.h> #include <sys/fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/mount.h> #include <sys/mount.h>
@ -270,13 +269,28 @@ static int check_free_memory()
{ {
struct sysinfo info; struct sysinfo info;
/* Pre initialize mem_unit in case this kernel is something prior to
* the linux 2.4 kernel (which will actually fill in mem_unit... */
sysinfo(&info); sysinfo(&info);
if (sysinfo(&info) != 0) { if (sysinfo(&info) != 0) {
message(LOG, "Error checking free memory: %s\n", strerror(errno)); printf("Error checking free memory: %s\n", strerror(errno));
return -1; return -1;
} }
if (info.mem_unit==0) {
/* Looks like we have a kernel prior to Linux 2.4.x */
info.mem_unit=1024;
info.totalram/=info.mem_unit;
info.totalswap/=info.mem_unit;
} else {
/* Bah. Linux 2.4.x completely changed sysinfo. This can in theory
overflow a 32 bit unsigned long, but who puts more then 4GiB ram+swap
on an embedded system? */
info.mem_unit/=1024;
info.totalram*=info.mem_unit;
info.totalswap*=info.mem_unit;
}
return((info.totalram+info.totalswap)/1024); return(info.totalram+info.totalswap);
} }
static void console_init() static void console_init()

View File

@ -42,7 +42,6 @@
#include <linux/version.h> #include <linux/version.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <sys/sysinfo.h> /* For check_free_memory() */
#include <sys/fcntl.h> #include <sys/fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/mount.h> #include <sys/mount.h>
@ -270,13 +269,28 @@ static int check_free_memory()
{ {
struct sysinfo info; struct sysinfo info;
/* Pre initialize mem_unit in case this kernel is something prior to
* the linux 2.4 kernel (which will actually fill in mem_unit... */
sysinfo(&info); sysinfo(&info);
if (sysinfo(&info) != 0) { if (sysinfo(&info) != 0) {
message(LOG, "Error checking free memory: %s\n", strerror(errno)); printf("Error checking free memory: %s\n", strerror(errno));
return -1; return -1;
} }
if (info.mem_unit==0) {
/* Looks like we have a kernel prior to Linux 2.4.x */
info.mem_unit=1024;
info.totalram/=info.mem_unit;
info.totalswap/=info.mem_unit;
} else {
/* Bah. Linux 2.4.x completely changed sysinfo. This can in theory
overflow a 32 bit unsigned long, but who puts more then 4GiB ram+swap
on an embedded system? */
info.mem_unit/=1024;
info.totalram*=info.mem_unit;
info.totalswap*=info.mem_unit;
}
return((info.totalram+info.totalswap)/1024); return(info.totalram+info.totalswap);
} }
static void console_init() static void console_init()

View File

@ -30,6 +30,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/param.h> #include <sys/param.h>
#include <mntent.h> #include <mntent.h>
@ -296,9 +297,27 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
#define RB_POWER_OFF 0x4321fedc #define RB_POWER_OFF 0x4321fedc
#endif #endif
/* Include our own copy of struct sysinfo to avoid binary compatability
* problems with Linux 2.4, which changed things. Grumble, grumble. */
struct sysinfo {
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* Number of current processes */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* Memory unit size in bytes */
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
};
extern int sysinfo (struct sysinfo* info);
#ifndef setbit
/* Bit map related macros -- libc5 doens't provide these... sigh. */ /* Bit map related macros -- libc5 doens't provide these... sigh. */
#ifndef setbit
#define NBBY CHAR_BIT #define NBBY CHAR_BIT
#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) #define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) #define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))

View File

@ -358,6 +358,10 @@ extern int mount_main(int argc, char **argv)
fatalError( "\nDEVMTAB_GET_MOUNTS: %s\n", strerror (errno)); fatalError( "\nDEVMTAB_GET_MOUNTS: %s\n", strerror (errno));
for( i = 0 ; i < numfilesystems ; i++) { for( i = 0 ; i < numfilesystems ; i++) {
/* klude around Linux 2.4.x stupidity */
if (strcmp(mntentlist[i].mnt_fsname, "none") == 0) {
continue;
}
fprintf( stdout, "%s %s %s %s %d %d\n", mntentlist[i].mnt_fsname, fprintf( stdout, "%s %s %s %s %d %d\n", mntentlist[i].mnt_fsname,
mntentlist[i].mnt_dir, mntentlist[i].mnt_type, mntentlist[i].mnt_dir, mntentlist[i].mnt_type,
mntentlist[i].mnt_opts, mntentlist[i].mnt_freq, mntentlist[i].mnt_opts, mntentlist[i].mnt_freq,
@ -380,6 +384,10 @@ extern int mount_main(int argc, char **argv)
while ((m = getmntent(mountTable)) != 0) { while ((m = getmntent(mountTable)) != 0) {
char *blockDevice = m->mnt_fsname; char *blockDevice = m->mnt_fsname;
/* klude around Linux 2.4.x stupidity */
if (strcmp(blockDevice, "none") == 0) {
continue;
}
if (strcmp(blockDevice, "/dev/root") == 0) { if (strcmp(blockDevice, "/dev/root") == 0) {
find_real_root_device_name( blockDevice); find_real_root_device_name( blockDevice);
} }

View File

@ -23,20 +23,36 @@
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <sys/sysinfo.h> #include <errno.h>
#define DIVISOR 1024
extern int free_main(int argc, char **argv) extern int free_main(int argc, char **argv)
{ {
struct sysinfo info; struct sysinfo info;
sysinfo(&info); sysinfo(&info);
info.totalram/=DIVISOR; /* Kernels prior to 2.4.x will return info.mem_unit==0. Kernels after
info.freeram/=DIVISOR; * 2.4.x actually fill this value in */
info.totalswap/=DIVISOR; if (info.mem_unit==0) {
info.freeswap/=DIVISOR; /* Looks like we have a kernel prior to Linux 2.4.x */
info.sharedram/=DIVISOR; info.mem_unit=1024;
info.bufferram/=DIVISOR; info.totalram/=info.mem_unit;
info.freeram/=info.mem_unit;
info.totalswap/=info.mem_unit;
info.freeswap/=info.mem_unit;
info.sharedram/=info.mem_unit;
info.bufferram/=info.mem_unit;
} else {
/* Bah. Linux 2.4.x completely changed sysinfo. This can in theory
overflow a 32 bit unsigned long, but who puts more then 4GiB ram+swap
on an embedded system? */
info.mem_unit/=1024;
info.totalram*=info.mem_unit;
info.freeram*=info.mem_unit;
info.totalswap*=info.mem_unit;
info.freeswap*=info.mem_unit;
info.sharedram*=info.mem_unit;
info.bufferram*=info.mem_unit;
}
if (argc > 1 && **(argv + 1) == '-') { if (argc > 1 && **(argv + 1) == '-') {
usage("free\n" usage("free\n"
#ifndef BB_FEATURE_TRIVIAL_HELP #ifndef BB_FEATURE_TRIVIAL_HELP
@ -61,3 +77,5 @@ extern int free_main(int argc, char **argv)
info.freeram+info.freeswap); info.freeram+info.freeswap);
return(TRUE); return(TRUE);
} }

View File

@ -31,13 +31,14 @@
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include <sys/sysinfo.h> #include <errno.h>
#define FSHIFT 16 /* nr of bits of precision */ #define FSHIFT 16 /* nr of bits of precision */
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */ #define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_INT(x) ((x) >> FSHIFT) #define LOAD_INT(x) ((x) >> FSHIFT)
#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
extern int uptime_main(int argc, char **argv) extern int uptime_main(int argc, char **argv)
{ {
int updays, uphours, upminutes; int updays, uphours, upminutes;

View File

@ -31,13 +31,14 @@
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include <sys/sysinfo.h> #include <errno.h>
#define FSHIFT 16 /* nr of bits of precision */ #define FSHIFT 16 /* nr of bits of precision */
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */ #define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_INT(x) ((x) >> FSHIFT) #define LOAD_INT(x) ((x) >> FSHIFT)
#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
extern int uptime_main(int argc, char **argv) extern int uptime_main(int argc, char **argv)
{ {
int updays, uphours, upminutes; int updays, uphours, upminutes;

View File

@ -358,6 +358,10 @@ extern int mount_main(int argc, char **argv)
fatalError( "\nDEVMTAB_GET_MOUNTS: %s\n", strerror (errno)); fatalError( "\nDEVMTAB_GET_MOUNTS: %s\n", strerror (errno));
for( i = 0 ; i < numfilesystems ; i++) { for( i = 0 ; i < numfilesystems ; i++) {
/* klude around Linux 2.4.x stupidity */
if (strcmp(mntentlist[i].mnt_fsname, "none") == 0) {
continue;
}
fprintf( stdout, "%s %s %s %s %d %d\n", mntentlist[i].mnt_fsname, fprintf( stdout, "%s %s %s %s %d %d\n", mntentlist[i].mnt_fsname,
mntentlist[i].mnt_dir, mntentlist[i].mnt_type, mntentlist[i].mnt_dir, mntentlist[i].mnt_type,
mntentlist[i].mnt_opts, mntentlist[i].mnt_freq, mntentlist[i].mnt_opts, mntentlist[i].mnt_freq,
@ -380,6 +384,10 @@ extern int mount_main(int argc, char **argv)
while ((m = getmntent(mountTable)) != 0) { while ((m = getmntent(mountTable)) != 0) {
char *blockDevice = m->mnt_fsname; char *blockDevice = m->mnt_fsname;
/* klude around Linux 2.4.x stupidity */
if (strcmp(blockDevice, "none") == 0) {
continue;
}
if (strcmp(blockDevice, "/dev/root") == 0) { if (strcmp(blockDevice, "/dev/root") == 0) {
find_real_root_device_name( blockDevice); find_real_root_device_name( blockDevice);
} }

View File

@ -131,6 +131,15 @@ extern int get_kernel_revision(void)
} }
#endif /* BB_INIT */ #endif /* BB_INIT */
#if defined BB_FREE || defined BB_INIT || defined BB_UNAME || defined BB_UPTIME
#include <sys/syscall.h>
_syscall1(int, sysinfo, struct sysinfo *, info);
#endif /* BB_INIT */
#if defined (BB_CP_MV) || defined (BB_DU) #if defined (BB_CP_MV) || defined (BB_DU)
#define HASH_SIZE 311 /* Should be prime */ #define HASH_SIZE 311 /* Should be prime */
@ -1189,6 +1198,9 @@ extern struct mntent *findMountPoint(const char *name, const char *table)
return 0; return 0;
while ((mountEntry = getmntent(mountTable)) != 0) { while ((mountEntry = getmntent(mountTable)) != 0) {
if (strcmp(mountEntry->mnt_fsname, "none") == 0) {
continue;
}
if (strcmp(name, mountEntry->mnt_dir) == 0 if (strcmp(name, mountEntry->mnt_dir) == 0
|| strcmp(name, mountEntry->mnt_fsname) == 0) /* String match. */ || strcmp(name, mountEntry->mnt_fsname) == 0) /* String match. */
break; break;