tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

libkver enhancement (LIBKVER_MACHINE)



Hi,

many NetBSD users seem to use pkgtools/pkg_comp which eases building
packages in a chrooted environment (sandbox).  pkg_comp in turn uses
pkgtools/libkver in order to adjust the output of `uname -r' and `sysctl
kern.osrelease'---a very useful feature when building packages for an
older NetBSD release.

The attached patch enhances libkver and enables the user to additionally
manipulate the output of `uname -m' and `sysctl hw.machine'.  Given that
amd64/sparc64 kernels can run i386/sparc binaries, this feature makes
libkver more complete and avoids the risk of building unusable pkgsrc
packages because of overzealous third party configuration routines.

Here are some examples on a NetBSD 4.0 i386 system:

   # export LD_PRELOAD=/usr/pkg/lib/libkver.so
   uname -r: 4.0, uname -m: i386, kern.osrelease = 4.0, hw.machine = i386

   # export LD_PRELOAD=/usr/pkg/lib/libkver.so
   # export LIBKVER_OSRELEASE=3.0.1
   uname -r: 3.0.1, uname -m: i386, kern.osrelease = 3.0.1, hw.machine = i386

   # export LD_PRELOAD=/usr/pkg/lib/libkver.so
   # export LIBKVER_MACHINE=macppc
   uname -r: 4.0, uname -m: macppc, kern.osrelease = 4.0, hw.machine = macppc

   # export LD_PRELOAD=/usr/pkg/lib/libkver.so
   # export LIBKVER_OSRELEASE=3.0.1
   # export LIBKVER_MACHINE=macppc
   uname -r: 3.0.1, uname -m: macppc, kern.osrelease = 3.0.1, hw.machine = 
macppc

Of course you could also use /libkver_osrelease or /libkver_machine
symlinks instead of LIBKVER_OSRELEASE or LIBKVER_MACHINE.  See kver(3)
for more details.

Thanks,

                Petar Bogdanovic
Index: kver.c
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/libkver/files/lib/kver.c,v
retrieving revision 1.9
diff -u -r1.9 kver.c
--- kver.c      11 Aug 2006 14:44:29 -0000      1.9
+++ kver.c      15 May 2010 21:21:47 -0000
@@ -14,30 +14,100 @@
 
 #define KVER_VERSION_FMT "NetBSD %s (LIBKVER) #0: Tue Jan 19 00:00:00 UTC 2038 
root@localhost:/sys/arch/%s/compile/LIBKVER"
 
-#define KVER_NOT_INITIALIZED_OSRELEASE -2
-#define KVER_INVALID_OSRELEASE -1
+#define KVER_NOT_INITIALIZED_VAR       -2
+#define KVER_INVALID_VAR               -1
+
+#define KVER_MACHTYPE_MAXLEN   12
+#define KVER_MACHTYPE_LIST     \
+       "acorn26",              \
+       "acorn32",              \
+       "algor",                \
+       "alpha",                \
+       "amd64",                \
+       "amiga",                \
+       "amigappc",             \
+       "arc",                  \
+       "atari",                \
+       "bebox",                \
+       "cats",                 \
+       "cesfic",               \
+       "cobalt",               \
+       "dreamcast",            \
+       "evbarm",               \
+       "evbmips",              \
+       "evbppc",               \
+       "evbsh3",               \
+       "ews4800mips",          \
+       "hp300",                \
+       "hp700",                \
+       "hpcarm",               \
+       "hpcmips",              \
+       "hpcsh",                \
+       "i386",                 \
+       "ia64",                 \
+       "ibmnws",               \
+       "iyonix",               \
+       "landisk",              \
+       "luna68k",              \
+       "mac68k",               \
+       "macppc",               \
+       "mipsco",               \
+       "mmeye",                \
+       "mvme68k",              \
+       "mvmeppc",              \
+       "netwinder",            \
+       "news68k",              \
+       "newsmips",             \
+       "next68k",              \
+       "ofppc",                \
+       "pmax",                 \
+       "prep",                 \
+       "rs6000",               \
+       "sandpoint",            \
+       "sbmips",               \
+       "sgimips",              \
+       "shark",                \
+       "sparc",                \
+       "sparc64",              \
+       "sun2",                 \
+       "sun3",                 \
+       "vax",                  \
+       "x68k",                 \
+       "xen",                  \
+       "zaurus"
 
 #ifndef PATH_LIBKVER_OSRELEASE
 #define PATH_LIBKVER_OSRELEASE "/libkver_osrelease"
 #endif
+#ifndef PATH_LIBKVER_MACHINE
+#define PATH_LIBKVER_MACHINE "/libkver_machine"
+#endif
 #ifndef VAR_LIBKVER_OSRELEASE
 #define VAR_LIBKVER_OSRELEASE "LIBKVER_OSRELEASE"
 #endif
+#ifndef VAR_LIBKVER_MACHINE
+#define VAR_LIBKVER_MACHINE "LIBKVER_MACHINE"
+#endif
 
 static struct kver {
        char osrelease[_SYS_NMLN];
-       int osrevision;
+       char machine[_SYS_NMLN];
        char version[_SYS_NMLN];
+       int osrelease_stat;
+       int machine_stat;
 }    kver = {
-       "", KVER_NOT_INITIALIZED_OSRELEASE, ""
+       "", "", "", KVER_NOT_INITIALIZED_VAR, KVER_NOT_INITIALIZED_VAR
 };
 
 static struct utsname real_utsname;
 
-#define KVER_NOT_INITIALIZED   \
-       (kver.osrevision == KVER_NOT_INITIALIZED_OSRELEASE)
-
-#define KVER_BADLY_INITIALIZED (kver.osrevision == KVER_INVALID_OSRELEASE)
+#define KVER_NOT_INITIALIZED                                           \
+       (kver.osrelease_stat == KVER_NOT_INITIALIZED_VAR) &&            \
+       (kver.machine_stat == KVER_NOT_INITIALIZED_VAR)
+
+#define KVER_BADLY_INITIALIZED                                         \
+       (kver.osrelease_stat == KVER_INVALID_VAR) &&                    \
+       (kver.machine_stat == KVER_INVALID_VAR)
 
 #define SYSCTL_STRING(oldp, oldlenp, str)                              \
        if (oldlenp) {                                                  \
@@ -60,24 +130,44 @@
 #define SYSCTL_CONST
 #endif
 
+static char *
+kver_getvar(char *var, char *path, char *buf, int bufsz)
+{
+       char *v;
+       int i;
+
+       v = getenv(var);
+       if (v == NULL) {
+               i = readlink(path, buf, bufsz - 1);
+               if (i <= 0) {
+                       v = NULL;
+               } else {
+                       buf[i] = '\0';
+                       v = buf;
+               }
+       }
+
+       return v;
+}
+
 static int
-str2osrevision(char *s)
+str2osrelease(char *s)
 {
        char c;
        int n, r = 0;
 
        if (s == NULL || *s == 0)
-               return KVER_INVALID_OSRELEASE;
+               return KVER_INVALID_VAR;
 
        if (!isdigit(*s))
-               return KVER_INVALID_OSRELEASE;
+               return KVER_INVALID_VAR;
 
        /* first digit: major */
        for (n = 0; isdigit(*s); s++) {
                n = (n * 10) + (*s - '0');
        }
        if (*s == 0 || *s != '.')
-               return KVER_INVALID_OSRELEASE;
+               return KVER_INVALID_VAR;
        r += (n * 100000000);
 
        /* second digit: minor */
@@ -114,48 +204,72 @@
                n += *s++ - '@';
        }
        if (n > 99)
-               return KVER_INVALID_OSRELEASE;
+               return KVER_INVALID_VAR;
        if (*s == 0)
                return r + (n * 10000);
 
        /* return on error if we end up here */
-       return KVER_INVALID_OSRELEASE;
+       return KVER_INVALID_VAR;
+}
+
+static int
+str2machine(char *s)
+{
+       int i, r;
+       char machtype[][KVER_MACHTYPE_MAXLEN] = {
+               KVER_MACHTYPE_LIST
+       };
+
+       for (i = 0; i < sizeof machtype / sizeof machtype[0]; i++)
+               if (!(r = strncmp(s, machtype[i], KVER_MACHTYPE_MAXLEN)))
+                       return r;
+
+       /* return on error if we end up here */
+       return KVER_INVALID_VAR;
 }
 
 static void
 kver_initialize(void)
 {
-       char *v;
+       char *v, buf[MAXPATHLEN];
        int i;
-       kver.osrevision = KVER_INVALID_OSRELEASE;       /* init done */
-       v = getenv(VAR_LIBKVER_OSRELEASE);
-       if (v == NULL) {
-               char b[MAXPATHLEN + 1];
-               i = readlink(PATH_LIBKVER_OSRELEASE, b, sizeof b - 1);
-               if (i <= 0) {
-                       v = NULL;
-               } else {
-                       b[i] = '\0';
-                       v = b;
-               }
-       }
-       if (v == NULL) {
-               warnx("libkver: not configured");
-               return;
-       }
+
+       kver.osrelease_stat = KVER_INVALID_VAR;         /* init done */
+       kver.machine_stat = KVER_INVALID_VAR;           /* init done */
+
        if (_uname(&real_utsname) != 0) {
                warn("libkver: uname");
                return;
        }
-       kver.osrevision = str2osrevision(v);
-       if (kver.osrevision == KVER_INVALID_OSRELEASE) {
-               warnx("libkver: invalid version: %s", v);
-               return;
+
+       (void) strncpy(kver.osrelease, real_utsname.release, _SYS_NMLN);
+       v = kver_getvar(VAR_LIBKVER_OSRELEASE, PATH_LIBKVER_OSRELEASE,
+           buf, sizeof buf);
+       if (v != NULL) {
+               kver.osrelease_stat = str2osrelease(v);
+               if (kver.osrelease_stat == KVER_INVALID_VAR) {
+                       warnx("libkver: invalid version: %s", v);
+               } else {
+                       (void) strncpy(kver.osrelease, v, _SYS_NMLN);
+               }
        }
-       (void) strncpy(kver.osrelease, v, _SYS_NMLN);
        kver.osrelease[_SYS_NMLN - 1] = '\0';
+
+       (void) strncpy(kver.machine, real_utsname.machine, _SYS_NMLN);
+       v = kver_getvar(VAR_LIBKVER_MACHINE, PATH_LIBKVER_MACHINE,
+           buf, sizeof buf);
+       if (v != NULL) {
+               kver.machine_stat = str2machine(v);
+               if (kver.machine_stat == KVER_INVALID_VAR) {
+                       warnx("libkver: invalid machine: %s", v);
+               } else {
+                       (void) strncpy(kver.machine, v, _SYS_NMLN);
+               }
+       }
+       kver.machine[_SYS_NMLN - 1] = '\0';
+
        (void) snprintf(kver.version, _SYS_NMLN, KVER_VERSION_FMT,
-           kver.osrelease, real_utsname.machine);
+           kver.osrelease, kver.machine);
        return;
 }
 
@@ -174,7 +288,7 @@
        if (KVER_BADLY_INITIALIZED || namelen != 2)
                goto real;
 
-       if (name[0] == CTL_KERN) {
+       if (name[0] == CTL_KERN || name[0] == CTL_HW) {
                size_t len;
                int r = 0;
                switch (name[1]) {
@@ -189,13 +303,16 @@
                                        if (*oldlenp < sizeof(int))
                                                return (ENOMEM);
                                        *oldlenp = sizeof(int);
-                                       *((int *) oldp) = kver.osrevision;
+                                       *((int *) oldp) = kver.osrelease_stat;
                                }
                        }
                        return (r);
                case KERN_VERSION:
                        SYSCTL_STRING(oldp, oldlenp, kver.version);
                        return (r);
+               case HW_MACHINE:
+                       SYSCTL_STRING(oldp, oldlenp, kver.machine);
+                       return (r);
                }
        }
 real:  return (_sysctl(name, namelen, oldp, oldlenp, newp, newlen));
@@ -214,6 +331,6 @@
        (void) strncpy(n->nodename, real_utsname.nodename, _SYS_NMLN);
        (void) strncpy(n->release, kver.osrelease, _SYS_NMLN);
        (void) strncpy(n->version, kver.version, _SYS_NMLN);
-       (void) strncpy(n->machine, real_utsname.machine, _SYS_NMLN);
+       (void) strncpy(n->machine, kver.machine, _SYS_NMLN);
        return 0;
 }
Index: kver.3
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/libkver/files/lib/kver.3,v
retrieving revision 1.2
diff -u -r1.2 kver.3
--- kver.3      24 Apr 2004 10:53:03 -0000      1.2
+++ kver.3      15 May 2010 21:21:47 -0000
@@ -22,23 +22,40 @@
 This is useful for, among other things, building packages in a
 sandbox/chrooted environment for a different
 .Nx
-release then the system hosting the sandbox.
+release or machine architecture then the system hosting the sandbox.
 .Pp
-The library must be configured for reporting a specific
-.Nx
-release or else it emits a warning message on the standard error output.
-The value of the environment variable
+The values of the environment variables
 .Ev LIBKVER_OSRELEASE
-or the ``name'' of the file referenced by the symbolic link named
+and
+.Ev LIBKVER_MACHINE
+or the ``names'' of the files referenced by the symbolic links named
 .Pa /libkver_osrelease
+and
+.Pa /libkver_machine
 are checked in that order for the
 .Nx
-release number the library should reports information for.
+release number or the machine architecture the library should report
+information for.
 .Sh EXAMPLES
-.Dl env LD_PRELOAD=/lib/libkver.so LIBKVER_OSRELEASE=1.5 uname -r
+.Dl export LD_PRELOAD=/lib/libkver.so
+.Dl export LIBKVER_OSRELEASE=1.5
+.Dl uname -r
+.Dl sysctl kern.osrelease
+.Pp
+.Dl export LD_PRELOAD=/lib/libkver.so
+.Dl export LIBKVER_MACHINE=i386
+.Dl uname -m
+.Dl sysctl hw.machine
+.Pp
+.Dl export LD_PRELOAD=/lib/libkver.so
+.Dl ln -s 4.0.1 /libkver_osrelease
+.Dl uname -r
+.Dl sysctl kern.osrelease
 .Pp
-.Dl ln -s 1.6.2 /libkver_osrelease
-.Dl env LD_PRELOAD=/lib/libkver.so uname -r
+.Dl export LD_PRELOAD=/lib/libkver.so
+.Dl ln -s i386 /libkver_machine
+.Dl uname -m
+.Dl sysctl hw.machine
 .Sh SEE ALSO
 .Xr ld.so 1 ,
 .Xr sysctl 3 ,


Home | Main Index | Thread Index | Old Index