Re: [Patch] sysinfo compatibility

From: Erik Andersen (andersen@codepoet.org)
Date: Tue Aug 21 2001 - 12:46:41 EST


On Tue Aug 21, 2001 at 07:30:04PM +0200, Christoph Rohland wrote:
> And I have somewhat harder feelings since we get a lot of bug reports
> that our installer only detects 0M RAM when running on a 2.4 machine
> while it works with the 2.2 kernel. We are talking about an ABI which
> is directly imported into user space programs.

Its your lucky day. Put something like this in your installer,
and your problems will go away:

/* Include our own copy of struct sysinfo to avoid binary compatibility
 * 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 short pad; /* Padding needed for m68k */
    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);

/* How much memory does this machine have?
   Units are kBytes to avoid overflow on 4GB machines */
static int check_free_memory()
{
    struct sysinfo info;
    unsigned int result, u, s=10;

    if (sysinfo(&info) != 0) {
        fprintf(stderr,"Error checking free memory");
        return -1;
    }

    /* Kernels 2.0.x and 2.2.x return info.mem_unit==0 with values in bytes.
     * Kernels 2.4.0 return info.mem_unit in bytes. */
    u = info.mem_unit;
    if (u==0) u=1;
    while ( (u&1) == 0 && s > 0 ) { u>>=1; s--; }
    result = (info.totalram>>s) + (info.totalswap>>s);
    result = result*u;
    if (result < 0) result = INT_MAX;
    return result;
}

 -Erik

--
Erik B. Andersen   email:  andersee@debian.org, andersen@lineo.com
--This message was written using 73% post-consumer electrons--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Aug 23 2001 - 21:00:44 EST