diff options
author | Patrick Mooney <patrick.f.mooney@gmail.com> | 2015-07-30 14:57:08 +0000 |
---|---|---|
committer | Patrick Mooney <patrick.f.mooney@gmail.com> | 2015-07-30 18:00:58 +0000 |
commit | 36afd076aca463269fb43107a134e0cc417e044c (patch) | |
tree | 4020817e98d5fc993748339d9d2914e71c28324a | |
parent | 6f2b4ac2461254029e30e71d710eff1b5ee7799d (diff) | |
download | illumos-joyent-36afd076aca463269fb43107a134e0cc417e044c.tar.gz |
OS-4571 lxbrand allow manipulation of uname release and version
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/lx_brand.c | 26 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/misc.c | 21 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h | 2 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_support/lx_support.c | 52 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/io/lx_netlink.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_brand.c | 143 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_syscall.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/procfs/lx_prvnops.c | 20 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_brand.h | 24 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_syscalls.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_types.h | 10 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_uname.c | 76 | ||||
-rw-r--r-- | usr/src/uts/intel/Makefile.files | 1 |
13 files changed, 253 insertions, 129 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c index 2f9d7930b3..cdc556459e 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c +++ b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c @@ -87,7 +87,7 @@ * function should return -errno back to the Linux caller. */ -char lx_release[LX_VERS_MAX]; +char lx_release[LX_KERN_RELEASE_MAX]; char lx_cmd_name[MAXNAMLEN]; /* @@ -545,7 +545,7 @@ lx_start(uintptr_t sp, uintptr_t entry) int lx_init(int argc, char *argv[], char *envp[]) { - char *r; + char *rele, *vers; auxv_t *ap; long *p; int err; @@ -572,17 +572,23 @@ lx_init(int argc, char *argv[], char *envp[]) lx_debug_init(); - r = getenv("LX_RELEASE"); - if (r == NULL) { - if (zone_getattr(getzoneid(), LX_KERN_VERSION_NUM, lx_release, - sizeof (lx_release)) != sizeof (lx_release)) - (void) strlcpy(lx_release, "2.4.21", LX_VERS_MAX); + rele = getenv("LX_RELEASE"); + vers = getenv("LX_VERSION"); + if (rele == NULL) { + if (zone_getattr(getzoneid(), LX_ATTR_KERN_RELEASE, + lx_release, sizeof (lx_release)) <= 0) + (void) strlcpy(lx_release, "2.4.21", + LX_KERN_RELEASE_MAX); } else { - (void) strlcpy(lx_release, r, 128); + (void) strlcpy(lx_release, rele, LX_KERN_RELEASE_MAX); } + if (syscall(SYS_brand, B_OVERRIDE_KERN_VER, rele, vers) != 0) { + lx_debug("failed to override kernel release/version"); + } lx_debug("lx_release: %s\n", lx_release); + /* * Should we kill an application that attempts an unimplemented * system call? @@ -977,7 +983,7 @@ static lx_syscall_handler_t lx_handlers[] = { lx_exit, /* 60: exit */ NULL, /* 61: wait4 */ NULL, /* 62: kill */ - lx_uname, /* 63: uname */ + NULL, /* 63: uname */ lx_semget, /* 64: semget */ lx_semop, /* 65: semop */ lx_semctl, /* 66: semctl */ @@ -1367,7 +1373,7 @@ static lx_syscall_handler_t lx_handlers[] = { lx_sigreturn, /* 119: sigreturn */ lx_clone, /* 120: clone */ lx_setdomainname, /* 121: setdomainname */ - lx_uname, /* 122: uname */ + NULL, /* 122: uname */ NULL, /* 123: modify_ldt */ lx_adjtimex, /* 124: adjtimex */ lx_mprotect, /* 125: mprotect */ diff --git a/usr/src/lib/brand/lx/lx_brand/common/misc.c b/usr/src/lib/brand/lx/lx_brand/common/misc.c index f56b9e8905..03a6df70dd 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/misc.c +++ b/usr/src/lib/brand/lx/lx_brand/common/misc.c @@ -229,27 +229,6 @@ lx_getcwd(uintptr_t p1, uintptr_t p2) return (len + 1); } -long -lx_uname(uintptr_t p1) -{ - struct lx_utsname *un = (struct lx_utsname *)p1; - char buf[LX_SYS_UTS_LN + 1]; - - if (gethostname(un->nodename, sizeof (un->nodename)) == -1) - return (-errno); - - (void) strlcpy(un->sysname, LX_UNAME_SYSNAME, LX_SYS_UTS_LN); - (void) strlcpy(un->release, lx_release, LX_SYS_UTS_LN); - (void) strlcpy(un->version, LX_UNAME_VERSION, LX_SYS_UTS_LN); - (void) strlcpy(un->machine, LX_UNAME_MACHINE, LX_SYS_UTS_LN); - if ((sysinfo(SI_SRPC_DOMAIN, buf, LX_SYS_UTS_LN) < 0)) - un->domainname[0] = '\0'; - else - (void) strlcpy(un->domainname, buf, LX_SYS_UTS_LN); - - return (0); -} - /* * {get,set}groups16() - Handle the conversion between 16-bit Linux gids and * 32-bit illumos gids. diff --git a/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h b/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h index 6f1b772228..05a38a0788 100644 --- a/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h +++ b/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h @@ -47,7 +47,7 @@ extern "C" { #endif -extern char lx_release[LX_VERS_MAX]; +extern char lx_release[LX_KERN_RELEASE_MAX]; extern char lx_cmd_name[MAXNAMLEN]; extern pid_t zoneinit_pid; diff --git a/usr/src/lib/brand/lx/lx_support/lx_support.c b/usr/src/lib/brand/lx/lx_support/lx_support.c index d1f96defb5..f4e1a23da0 100644 --- a/usr/src/lib/brand/lx/lx_support/lx_support.c +++ b/usr/src/lib/brand/lx/lx_support/lx_support.c @@ -60,8 +60,6 @@ static void usage(void) __NORETURN; #define CP_CMD "/usr/bin/cp" #define MOUNT_CMD "/sbin/mount" -#define KVSTRLEN 10 - static char *bname = NULL; static char *zonename = NULL; static char *zoneroot = NULL; @@ -175,7 +173,7 @@ lxs_remove_autofsck() * Extract any lx-supported attributes from the zone configuration file. */ static void -lxs_getattrs(zone_dochandle_t zdh, char **kvers) +lxs_getattrs(zone_dochandle_t zdh, char **krelease) { struct zone_attrtab attrtab; int err; @@ -186,22 +184,22 @@ lxs_getattrs(zone_dochandle_t zdh, char **kvers) lxs_err(gettext("error accessing zone configuration")); } - *kvers = (char *)malloc(KVSTRLEN); - if (*kvers == NULL) + *krelease = (char *)malloc(LX_KERN_RELEASE_MAX); + if (*krelease == NULL) lxs_err(gettext("out of memory")); - bzero(*kvers, KVSTRLEN); + bzero(*krelease, LX_KERN_RELEASE_MAX); while ((err = zonecfg_getattrent(zdh, &attrtab)) == Z_OK) { if ((strcmp(attrtab.zone_attr_name, "kernel-version") == 0) && - (zonecfg_get_attr_string(&attrtab, *kvers, - KVSTRLEN) != Z_OK)) + (zonecfg_get_attr_string(&attrtab, *krelease, + LX_KERN_RELEASE_MAX) != Z_OK)) lxs_err(gettext("invalid type for zone attribute: %s"), attrtab.zone_attr_name); } - if (strlen(*kvers) == 0) { - free(*kvers); - *kvers = NULL; + if (strlen(*krelease) == 0) { + free(*krelease); + *krelease = NULL; } /* some kind of error while looking up attributes */ @@ -214,7 +212,7 @@ lxs_boot() { zoneid_t zoneid; zone_dochandle_t zdh; - char *kvers; + char *krelease; lxs_make_initctl(); lxs_remove_autofsck(); @@ -228,7 +226,7 @@ lxs_boot() } /* Extract any relevant attributes from the config file. */ - lxs_getattrs(zdh, &kvers); + lxs_getattrs(zdh, &krelease); zonecfg_fini_handle(zdh); /* @@ -238,16 +236,16 @@ lxs_boot() if ((zoneid = getzoneidbyname(zonename)) < 0) lxs_err(gettext("unable to get zoneid")); - if (kvers != NULL) { + if (krelease != NULL) { /* Backward compatability with incomplete version attr */ - if (strcmp(kvers, "2.4") == 0) { - kvers = "2.4.21"; - } else if (strcmp(kvers, "2.6") == 0) { - kvers = "2.6.18"; + if (strcmp(krelease, "2.4") == 0) { + krelease = "2.4.21"; + } else if (strcmp(krelease, "2.6") == 0) { + krelease = "2.6.18"; } - if (zone_setattr(zoneid, LX_KERN_VERSION_NUM, kvers, - strlen(kvers)) < 0) + if (zone_setattr(zoneid, LX_ATTR_KERN_RELEASE, krelease, + strlen(krelease)) < 0) lxs_err(gettext("unable to set kernel version")); } @@ -264,7 +262,7 @@ static int lxs_verify(char *xmlfile) { zone_dochandle_t handle; - char *kvers; + char *krelease; char hostidp[HW_HOSTID_LEN]; zone_iptype_t iptype; @@ -294,14 +292,14 @@ lxs_verify(char *xmlfile) } /* Extract any relevant attributes from the config file. */ - lxs_getattrs(handle, &kvers); + lxs_getattrs(handle, &krelease); zonecfg_fini_handle(handle); - if (kvers) { - if (strlen(kvers) > (LX_VERS_MAX - 1) || - (strncmp(kvers, "2.4", 3) != 0 && - strncmp(kvers, "2.6", 3) != 0 && - strncmp(kvers, "3.", 2) != 0)) + if (krelease) { + if (strlen(krelease) >= LX_KERN_RELEASE_MAX || + (strncmp(krelease, "2.4", 3) != 0 && + strncmp(krelease, "2.6", 3) != 0 && + strncmp(krelease, "3.", 2) != 0)) lxs_err(gettext("invalid value for zone attribute: %s"), "kernel-version"); } diff --git a/usr/src/uts/common/brand/lx/io/lx_netlink.c b/usr/src/uts/common/brand/lx/io/lx_netlink.c index 2e80e1bf11..36b0cf9b2b 100644 --- a/usr/src/uts/common/brand/lx/io/lx_netlink.c +++ b/usr/src/uts/common/brand/lx/io/lx_netlink.c @@ -1239,7 +1239,7 @@ lx_netlink_getroute(lx_netlink_sock_t *lxsock, lx_netlink_hdr_t *hdr, * truncate our input to prevent later confusion. */ if (curproc->p_zone->zone_brand == &lx_brand && - lx_kern_version_cmp(curproc->p_zone, "2.6.32") <= 0 && + lx_kern_release_cmp(curproc->p_zone, "2.6.32") <= 0 && rtmsgp->rtm_dst_len == 0) { rtmsg_size = sizeof (rtmsg.rtm_family); } diff --git a/usr/src/uts/common/brand/lx/os/lx_brand.c b/usr/src/uts/common/brand/lx/os/lx_brand.c index 44acdff3b1..5dc026a21e 100644 --- a/usr/src/uts/common/brand/lx/os/lx_brand.c +++ b/usr/src/uts/common/brand/lx/os/lx_brand.c @@ -364,36 +364,77 @@ lx_setbrand(proc_t *p) /* ARGSUSED */ int -lx_setattr(zone_t *zone, int attr, void *buf, size_t bufsize) +lx_setattr(zone_t *zone, int attr, void *ubuf, size_t ubufsz) { - char vers[LX_VERS_MAX]; + lx_zone_data_t *lxzd = (lx_zone_data_t *)zone->zone_brand_data; - if (attr == LX_KERN_VERSION_NUM) { - if (bufsize > (LX_VERS_MAX - 1)) + switch (attr) { + case LX_ATTR_KERN_RELEASE: { + char buf[LX_KERN_RELEASE_MAX]; + bzero(buf, LX_KERN_RELEASE_MAX); + if (ubufsz >= LX_KERN_RELEASE_MAX) { return (ERANGE); - bzero(vers, LX_VERS_MAX); - if (copyin(buf, &vers, bufsize) != 0) + } + if (copyin(ubuf, buf, ubufsz) != 0) { return (EFAULT); - lx_set_kern_version(zone, vers); + } + (void) strlcpy(lxzd->lxzd_kernel_release, buf, + LX_KERN_RELEASE_MAX); return (0); } - return (EINVAL); + case LX_ATTR_KERN_VERSION: { + char buf[LX_KERN_VERSION_MAX]; + bzero(buf, LX_KERN_VERSION_MAX); + if (ubufsz >= LX_KERN_VERSION_MAX) { + return (ERANGE); + } + if (copyin(ubuf, buf, ubufsz) != 0) { + return (EFAULT); + } + (void) strlcpy(lxzd->lxzd_kernel_version, buf, + LX_KERN_VERSION_MAX); + return (0); + } + default: + return (EINVAL); + } } /* ARGSUSED */ int -lx_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize) +lx_getattr(zone_t *zone, int attr, void *ubuf, size_t *ubufsz) { - if (attr == LX_KERN_VERSION_NUM) { - if (*bufsize < LX_VERS_MAX) + lx_zone_data_t *lxzd = (lx_zone_data_t *)zone->zone_brand_data; + int len; + + switch (attr) { + case LX_ATTR_KERN_RELEASE: { + len = strnlen(lxzd->lxzd_kernel_release, LX_KERN_RELEASE_MAX); + len++; + if (*ubufsz < len) { return (ERANGE); - if (copyout(lx_get_zone_kern_version(curzone), buf, - LX_VERS_MAX) != 0) + } + if (copyout(lxzd->lxzd_kernel_release, ubuf, len) != 0) { return (EFAULT); - *bufsize = LX_VERS_MAX; + } + *ubufsz = len; return (0); } - return (-EINVAL); + case LX_ATTR_KERN_VERSION: { + len = strnlen(lxzd->lxzd_kernel_version, LX_KERN_VERSION_MAX); + len++; + if (*ubufsz < len) { + return (ERANGE); + } + if (copyout(lxzd->lxzd_kernel_version, ubuf, len) != 0) { + return (EFAULT); + } + *ubufsz = len; + return (0); + } + default: + return (EINVAL); + } } uint32_t @@ -725,7 +766,10 @@ lx_init_brand_data(zone_t *zone) * Set the default lxzd_kernel_version to 2.4. * This can be changed by a call to setattr() during zone boot. */ - (void) strlcpy(data->lxzd_kernel_version, "2.4.21", LX_VERS_MAX); + (void) strlcpy(data->lxzd_kernel_release, "2.4.21", + LX_KERN_RELEASE_MAX); + (void) strlcpy(data->lxzd_kernel_version, "BrandZ virtual linux", + LX_KERN_VERSION_MAX); /* * Linux is not at all picky about address family when it comes to @@ -1369,32 +1413,43 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, exit(code, sig); /* NOTREACHED */ break; - } - return (EINVAL); -} + case B_OVERRIDE_KERN_VER: { + void *urel = (void *)arg1; + void *uver = (void *)arg2; + size_t len; -char * -lx_get_zone_kern_version(zone_t *zone) -{ - return (((lx_zone_data_t *)zone->zone_brand_data)->lxzd_kernel_version); -} + pd = ptolxproc(p); + if (urel != NULL) { + if (copyinstr(urel, pd->l_uname_release, + LX_KERN_RELEASE_MAX, &len) != 0) { + return (EFAULT); + } + pd->l_uname_release[LX_KERN_RELEASE_MAX - 1] = '\0'; + } + if (uver != NULL) { + if (copyinstr(uver, pd->l_uname_version, + LX_KERN_VERSION_MAX, &len) != 0) { + return (EFAULT); + } + pd->l_uname_version[LX_KERN_VERSION_MAX - 1] = '\0'; + } -void -lx_set_kern_version(zone_t *zone, char *vers) -{ - lx_zone_data_t *lxzd = (lx_zone_data_t *)zone->zone_brand_data; + return (0); + } - (void) strlcpy(lxzd->lxzd_kernel_version, vers, LX_VERS_MAX); + } + + return (EINVAL); } /* * Compare linux kernel version to the one set for the zone. * Returns greater than 0 if zone version is higher, less than 0 if the zone - * version is lower, and 0 if the version are equal. + * version is lower, and 0 if the versions are equal. */ int -lx_kern_version_cmp(zone_t *zone, const char *vers) +lx_kern_release_cmp(zone_t *zone, const char *vers) { int zvers[3] = {0, 0, 0}; int cvers[3] = {0, 0, 0}; @@ -1402,7 +1457,7 @@ lx_kern_version_cmp(zone_t *zone, const char *vers) VERIFY(zone->zone_brand == &lx_brand); - (void) sscanf(ztolxzd(zone)->lxzd_kernel_version, "%d.%d.%d", &zvers[0], + (void) sscanf(ztolxzd(zone)->lxzd_kernel_release, "%d.%d.%d", &zvers[0], &zvers[1], &zvers[2]); (void) sscanf(vers, "%d.%d.%d", &cvers[0], &cvers[1], &cvers[2]); @@ -1444,17 +1499,25 @@ lx_setid_clear(vattr_t *vap, cred_t *cr) * Copy the per-process brand data from a parent proc to a child. */ void -lx_copy_procdata(proc_t *child, proc_t *parent) +lx_copy_procdata(proc_t *cp, proc_t *pp) { - lx_proc_data_t *cpd = child->p_brand_data; - lx_proc_data_t *ppd = parent->p_brand_data; + lx_proc_data_t *cpd, *ppd; + char buf_version[LX_SYS_UTS_LN]; + + /* + * Since b_copy_procdata is called during getproc(), while the child + * process is still being initialized, acquiring cp->p_lock should not + * be required. + */ + VERIFY(cp->p_brand == &lx_brand); + VERIFY(cpd = cp->p_brand_data); - VERIFY(parent->p_brand == &lx_brand); - VERIFY(child->p_brand == &lx_brand); - VERIFY(ppd != NULL); - VERIFY(cpd != NULL); + mutex_enter(&pp->p_lock); + VERIFY(pp->p_brand == &lx_brand); + VERIFY(ppd = pp->p_brand_data); - *cpd = *ppd; + bcopy(ppd, cpd, sizeof (lx_proc_data_t)); + mutex_exit(&pp->p_lock); cpd->l_fake_limits[LX_RLFAKE_LOCKS].rlim_cur = LX_RLIM64_INFINITY; cpd->l_fake_limits[LX_RLFAKE_LOCKS].rlim_max = LX_RLIM64_INFINITY; diff --git a/usr/src/uts/common/brand/lx/os/lx_syscall.c b/usr/src/uts/common/brand/lx/os/lx_syscall.c index 0598a7d997..ad52900dba 100644 --- a/usr/src/uts/common/brand/lx/os/lx_syscall.c +++ b/usr/src/uts/common/brand/lx/os/lx_syscall.c @@ -645,7 +645,7 @@ lx_sysent_t lx_sysent32[] = { {"sigreturn", NULL, 0, 1}, /* 119 */ {"clone", NULL, 0, 5}, /* 120 */ {"setdomainname", NULL, 0, 2}, /* 121 */ - {"uname", NULL, 0, 1}, /* 122 */ + {"uname", lx_uname, 0, 1}, /* 122 */ {"modify_ldt", lx_modify_ldt, 0, 3}, /* 123 */ {"adjtimex", NULL, 0, 1}, /* 124 */ {"mprotect", NULL, 0, 3}, /* 125 */ @@ -957,7 +957,7 @@ lx_sysent_t lx_sysent64[] = { {"exit", NULL, 0, 1}, /* 60 */ {"wait4", lx_wait4, 0, 4}, /* 61 */ {"kill", lx_kill, 0, 2}, /* 62 */ - {"uname", NULL, 0, 1}, /* 63 */ + {"uname", lx_uname, 0, 1}, /* 63 */ {"semget", NULL, 0, 3}, /* 64 */ {"semop", NULL, 0, 3}, /* 65 */ {"semctl", NULL, 0, 4}, /* 66 */ diff --git a/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c b/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c index 1cc74357ce..cde72b42bb 100644 --- a/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c +++ b/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c @@ -3408,14 +3408,12 @@ lxpr_read_diskstats(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf) static void lxpr_read_version(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf) { - char *vers; - - vers = lx_get_zone_kern_version(LXPTOZ(lxpnp)); + lx_zone_data_t *lxzd = ztolxzd(LXPTOZ(lxpnp)); lxpr_uiobuf_printf(uiobuf, "%s version %s (%s version %d.%d.%d) " "#%s SMP %s\n", - LX_UNAME_SYSNAME, vers, + LX_UNAME_SYSNAME, lxzd->lxzd_kernel_release, #if defined(__GNUC__) "gcc", __GNUC__, @@ -3427,7 +3425,7 @@ lxpr_read_version(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf) (__SUNPRO_C & 0xff) / 0x10, __SUNPRO_C & 0xf, #endif - LX_UNAME_VERSION, + lxzd->lxzd_kernel_version, "00:00:00 00/00/00"); } @@ -3456,7 +3454,8 @@ lxpr_read_stat(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf) ulong_t pswitch_cum = 0; ulong_t forks_cum = 0; hrtime_t msnsecs[NCMSTATES]; - char *lx_kern_version = lx_get_zone_kern_version(LXPTOZ(lxpnp)); + /* is the emulated release > 2.4 */ + boolean_t newer_than24 = lx_kern_release_cmp(LXPTOZ(lxpnp), "2.4") > 0; /* temporary variable since scalehrtime modifies data in place */ hrtime_t tmptime; @@ -3489,7 +3488,8 @@ lxpr_read_stat(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf) pgswapin_cum += CPU_STATS(cp, vm.pgswapin); pgswapout_cum += CPU_STATS(cp, vm.pgswapout); - if (strncmp(lx_kern_version, "2.4", 3) != 0) { + + if (newer_than24) { cpu_nrunnable_cum += cp->cpu_disp->disp_nrunnable; w_io_cum += CPU_STATS(cp, sys.iowait); for (i = 0; i < NCMSTATES; i++) { @@ -3512,7 +3512,7 @@ lxpr_read_stat(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf) cp = cp->cpu_next; } while (cp != cpstart); - if (strncmp(lx_kern_version, "2.4", 3) != 0) { + if (newer_than24) { lxpr_uiobuf_printf(uiobuf, "cpu %lu %lu %lu %lu %lu %lu %lu\n", user_cum, 0L, sys_cum, idle_cum, 0L, irq_cum, 0L); @@ -3551,7 +3551,7 @@ lxpr_read_stat(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf) irq_ticks += NSEC_TO_TICK(tmptime); } - if (strncmp(lx_kern_version, "2.4", 3) != 0) { + if (newer_than24) { lxpr_uiobuf_printf(uiobuf, "cpu%d %lu %lu %lu %lu %lu %lu %lu\n", cp->cpu_id, user_ticks, 0L, sys_ticks, idle_ticks, @@ -3571,7 +3571,7 @@ lxpr_read_stat(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf) mutex_exit(&cpu_lock); - if (strncmp(lx_kern_version, "2.4", 3) != 0) { + if (newer_than24) { lxpr_uiobuf_printf(uiobuf, "page %lu %lu\n" "swap %lu %lu\n" diff --git a/usr/src/uts/common/brand/lx/sys/lx_brand.h b/usr/src/uts/common/brand/lx/sys/lx_brand.h index 895ea44db5..7198bea59c 100644 --- a/usr/src/uts/common/brand/lx/sys/lx_brand.h +++ b/usr/src/uts/common/brand/lx/sys/lx_brand.h @@ -97,6 +97,7 @@ extern "C" { #define B_HELPER_TGSIGQUEUE 146 #define B_SET_NATIVE_STACK 147 #define B_SIGEV_THREAD_ID 148 +#define B_OVERRIDE_KERN_VER 149 #ifndef _ASM /* @@ -143,7 +144,8 @@ typedef enum lx_ptrace_options { #define LX_VERSION_1 1 #define LX_VERSION LX_VERSION_1 -#define LX_KERN_VERSION_NUM ZONE_ATTR_BRAND_ATTRS +#define LX_ATTR_KERN_RELEASE ZONE_ATTR_BRAND_ATTRS +#define LX_ATTR_KERN_VERSION (ZONE_ATTR_BRAND_ATTRS + 1) /* * Aux vector containing phdr of Linux executable and ehdr of interpreter @@ -382,6 +384,13 @@ typedef enum lx_proc_flags { #define LX_PROC_ALL (LX_PROC_INSTALL_MODE | LX_PROC_STRICT_MODE) +/* Maximum length for fields of LX uname */ +#define LX_SYS_UTS_LN 65 + +/* Max. length of kernel release string */ +#define LX_KERN_RELEASE_MAX LX_SYS_UTS_LN +#define LX_KERN_VERSION_MAX LX_SYS_UTS_LN + #ifdef _KERNEL /* @@ -418,6 +427,10 @@ typedef struct lx_proc_data { lx_proc_flags_t l_flags; lx_rlimit64_t l_fake_limits[LX_RLFAKE_NLIMITS]; + + /* Override zone-wide settings for uname release and version */ + char l_uname_release[LX_KERN_RELEASE_MAX]; + char l_uname_version[LX_KERN_VERSION_MAX]; } lx_proc_data_t; #endif /* _KERNEL */ @@ -431,9 +444,6 @@ typedef struct lx_proc_data { #define LX_AFF_ULONGS (LX_NCPU / (8 * sizeof (ulong_t))) typedef ulong_t lx_affmask_t[LX_AFF_ULONGS]; -/* Max. length of kernel version string */ -#define LX_VERS_MAX 16 - /* Length of proc boot_id string */ #define LX_BOOTID_LEN 37 @@ -649,7 +659,8 @@ struct lx_lwp_data { * enhanced to support different mounts with different subsystem controllers. */ typedef struct lx_zone_data { - char lxzd_kernel_version[LX_VERS_MAX]; + char lxzd_kernel_release[LX_KERN_RELEASE_MAX]; + char lxzd_kernel_version[LX_KERN_VERSION_MAX]; ksocket_t lxzd_ioctl_sock; char lxzd_bootid[LX_BOOTID_LEN]; /* procfs boot_id */ vfs_t *lxzd_cgroup; /* cgroup for this zone */ @@ -684,8 +695,7 @@ typedef struct lx_zone_data { #define LX_MAX_SYSCALL(lwp) lx_nsysent32 #endif -extern char *lx_get_zone_kern_version(zone_t *); -extern int lx_kern_version_cmp(zone_t *, const char *); +extern int lx_kern_release_cmp(zone_t *, const char *); extern void lx_lwp_set_native_stack_current(lx_lwp_data_t *, uintptr_t); extern void lx_divert(klwp_t *, uintptr_t); diff --git a/usr/src/uts/common/brand/lx/sys/lx_syscalls.h b/usr/src/uts/common/brand/lx/sys/lx_syscalls.h index c4a2307592..3202bb5455 100644 --- a/usr/src/uts/common/brand/lx/sys/lx_syscalls.h +++ b/usr/src/uts/common/brand/lx/sys/lx_syscalls.h @@ -108,6 +108,7 @@ extern long lx_sysinfo64(); extern long lx_tgkill(); extern long lx_time(); extern long lx_tkill(); +extern long lx_uname(); extern long lx_wait4(); extern long lx_waitid(); extern long lx_waitpid(); diff --git a/usr/src/uts/common/brand/lx/sys/lx_types.h b/usr/src/uts/common/brand/lx/sys/lx_types.h index e91484c16b..9293d00ae1 100644 --- a/usr/src/uts/common/brand/lx/sys/lx_types.h +++ b/usr/src/uts/common/brand/lx/sys/lx_types.h @@ -54,16 +54,6 @@ extern "C" { #endif /* !_KERNEL */ -#define LX_SYS_UTS_LN 65 - -struct lx_utsname { - char sysname[LX_SYS_UTS_LN]; - char nodename[LX_SYS_UTS_LN]; - char release[LX_SYS_UTS_LN]; - char version[LX_SYS_UTS_LN]; - char machine[LX_SYS_UTS_LN]; - char domainname[LX_SYS_UTS_LN]; -}; typedef uint64_t lx_dev_t; typedef uint16_t lx_dev16_t; diff --git a/usr/src/uts/common/brand/lx/syscall/lx_uname.c b/usr/src/uts/common/brand/lx/syscall/lx_uname.c new file mode 100644 index 0000000000..1b9f6b31c1 --- /dev/null +++ b/usr/src/uts/common/brand/lx/syscall/lx_uname.c @@ -0,0 +1,76 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Joyent, Inc. + */ + +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/thread.h> +#include <sys/proc.h> +#include <sys/zone.h> +#include <sys/brand.h> +#include <sys/lx_brand.h> +#include <sys/lx_types.h> + +struct lx_utsname { + char lxu_sysname[LX_SYS_UTS_LN]; + char lxu_nodename[LX_SYS_UTS_LN]; + char lxu_release[LX_SYS_UTS_LN]; + char lxu_version[LX_SYS_UTS_LN]; + char lxu_machine[LX_SYS_UTS_LN]; + char lxu_domainname[LX_SYS_UTS_LN]; +}; + +long +lx_uname(void *uptr) +{ + proc_t *p = curproc; + lx_proc_data_t *lxpd = ptolxproc(p); + lx_zone_data_t *lxzd = ztolxzd(p->p_zone); + struct lx_utsname un; + + bzero(&un, sizeof (un)); + + (void) strlcpy(un.lxu_sysname, LX_UNAME_SYSNAME, LX_SYS_UTS_LN); + (void) strlcpy(un.lxu_nodename, p->p_zone->zone_nodename, + LX_SYS_UTS_LN); + if (lxpd->l_uname_release[0] != '\0') { + (void) strlcpy(un.lxu_release, lxpd->l_uname_release, + LX_SYS_UTS_LN); + } else { + (void) strlcpy(un.lxu_release, lxzd->lxzd_kernel_release, + LX_SYS_UTS_LN); + } + if (lxpd->l_uname_version[0] != '\0') { + (void) strlcpy(un.lxu_version, lxpd->l_uname_version, + LX_SYS_UTS_LN); + } else { + (void) strlcpy(un.lxu_version, lxzd->lxzd_kernel_version, + LX_SYS_UTS_LN); + } + if (get_udatamodel() == DATAMODEL_LP64) { + (void) strlcpy(un.lxu_machine, LX_UNAME_MACHINE64, + LX_SYS_UTS_LN); + } else { + (void) strlcpy(un.lxu_machine, LX_UNAME_MACHINE32, + LX_SYS_UTS_LN); + } + (void) strlcpy(un.lxu_domainname, p->p_zone->zone_domain, + LX_SYS_UTS_LN); + + if (copyout(&un, uptr, sizeof (un)) != 0) { + return (set_errno(EFAULT)); + } + + return (0); +} diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files index 236e824127..78c9de19f2 100644 --- a/usr/src/uts/intel/Makefile.files +++ b/usr/src/uts/intel/Makefile.files @@ -321,6 +321,7 @@ LX_BRAND_OBJS = \ lx_sysinfo.o \ lx_thread_area.o \ lx_timer.o \ + lx_uname.o \ lx_wait.o \ lx_xattr.o |