Re: [PATCH] fix for sysinfo(2) in 2.4.0-test1

From: Andries Brouwer (aeb@veritas.com)
Date: Sun Jun 04 2000 - 14:18:19 EST


On Sun, Jun 04, 2000 at 10:44:01AM -0600, Erik Andersen wrote:
: On Sun Jun 04, 2000 at 06:06:55PM +0200, Andi Kleen wrote:
:: Andries Brouwer <aeb@veritas.com> writes:
::
::: On Sun, Jun 04, 2000 at 01:35:51AM -0600, Erik Andersen wrote:
:::
:::: + val.totalram*=PAGE_SIZE;
:::: + val.freeram*=PAGE_SIZE;
:::: + val.sharedram*=PAGE_SIZE;
:::: + val.bufferram*=PAGE_SIZE;
:::: + val.totalswap*=PAGE_SIZE;
:::: + val.freeswap*=PAGE_SIZE;
:::: + val.totalhigh*=PAGE_SIZE;
:::: + val.freehigh*=PAGE_SIZE;
:::
::: You forgot setting mem_unit to 1.
::: Why can't your application multiply by mem_unit?
:
: Because someone broke a long standing interface and retrofitted it with new
: semantics. That is bad.
:
: Because my application needs to be able to be compiled under both 2.2 and 2.4,
: and needs to run correctly under both 2.2 and 2.4. In order to add in the
: multiply by mem_unit, I would need to copy the 2.2 and the 2.4 version of
: struct sysinfo into my own code (since mem_unit is not available under 2.2) and
: then check at runtime via uname which kernel is running to determine which
: struct to use and whether a multiply is needed. This take a simple long
: standing interface and turns it into a mess to use.

Yes, I agree that it was a very bad move to change this.
But now that someone did this, early in the 2.3.* series,
we can choose between a number of things.
One is to just back out the change and return to the old struct sysinfo
and old system call. That is a good idea.
One is to leave the change and solve compatibility in user space.
It means that binary compatibility (in semantics) has been lost,
and a recompile (of the very few utilities that use this) is required.
Asking for kernel version with uname is not a good idea - things were a bit messy
between 2.3.16 and 2.3.48. But code like

#include <stdio.h>

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 long 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-3*sizeof(long)]; /* Padding for libc5 */
};

extern int sysinfo (struct sysinfo *);

int
main() {
        struct sysinfo info;
        long long unit;

        info.mem_unit = 0;

        if (sysinfo(&info)) {
                perror("sysinfo");
                exit(1);
        }

        unit = (info.mem_unit ? info.mem_unit : 1);

        printf("total: %lld\nfree: %lld\nshared: %lld\nbuffer: %lld\n",
               info.totalram * unit, info.freeram * unit,
               info.sharedram * unit, info.bufferram * unit);

        return 0;
}

is good enough.

:: That shouldn't be changed binary incompatible though. Rather a
:: ``sysinfo64'' call needs to be added.
:
: I very much agree. ``sysinfo64'' is definitely needed.

Perhaps. This stuff is used very few places, and then almost always
for the load average. Somehow it seems a pity to add a new system call.
But it is true that that is the cleanest solution.

Andries

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Jun 07 2000 - 21:00:19 EST