What does geeko#buildhost signify in linux version? - linux

On a linux server when checking the Linux version I see the following "geeko#buildhost"
Version: Linux version 4.12.14-95.54-default (geeko#buildhost) (gcc version 4.8.5 (SUSE Linux) ) #1 SMP Thu Jun 4 12:49:28 UTC 2020 (892ef1f)
What does this signify? does it have something to do with who built the os packages?

It is simply an identifier showing the user and host names where the kernel is compiled. The former is the result of executing whoami and the latter is the result of running uname -n. You can see how it is put together in init/version.c:
const char linux_banner[] =
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "#"
LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
The variables are set by scripts/mkcompile_h:
if test -z "$KBUILD_BUILD_USER"; then
LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/')
else
LINUX_COMPILE_BY=$KBUILD_BUILD_USER
fi
if test -z "$KBUILD_BUILD_HOST"; then
LINUX_COMPILE_HOST=`uname -n`
else
LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST
fi

Related

Check cuda version in bash scripts

Basically, I want to achieve a version control on CUDA, similar to this:
if python3 -c 'import sys; assert sys.version_info == (3,8)' > /dev/null
then
exit;
fi
In my case, the CUDA version shown by ncvv -V must be >=11.3
according to this answer we could get cuda version via:
CUDA_VERSION=$(nvcc --version | sed -n 's/^.*release \([0-9]\+\.[0-9]\+\).*$/\1/p')
from the output of nvcc -V, in which the version is given after the key word "release":
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Sun_Mar_21_19:15:46_PDT_2021
Cuda compilation tools, release 11.3, V11.3.58
Build cuda_11.3.r11.3/compiler.29745058_0
But I am having trouble on further comparing the version with 11.3
I figured out a solution via python:
import os,re
b = os.popen('nvcc -V').readlines()
>>> b
['nvcc: NVIDIA (R) Cuda compiler driver\n', 'Copyright (c) 2005-2021 NVIDIA Corporation\n', 'Built on Sun_Mar_21_19:15:46_PDT_2021\n', 'Cuda compilation tools, release 11.3, V11.3.58\n', 'Build cuda_11.3.r11.3/compiler.29745058_0\n']
b = str(b)
c = re.findall(r"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}",b)
>>> c[0]
'11.3.58'
cc = c[0].split(".")
>>> cc
['11', '3', '58']
>>> [int(x) for x in cc] >[11,3,0]
True
>>> [int(x) for x in cc] >[11,4,0]
False
>>> [int(x) for x in cc] >[8,4,0]
True
>>> [int(x) for x in cc] >[8,314,0]
True
to sum up:
#!/usr/bin/env bash
if python3 -c 'import os,re; assert [int(x) for x in re.findall(r"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}", str(os.popen("nvcc -V").readlines()))[0].split(".")] >[11,3,0]'> /dev/null
then
echo '11'
else
echo '22'
fi
Awk will allow you to deal with the decimal places:
nvcc --version | awk '/V([0-9]+.){2}.[0-9]+$/ { sub("V","",$NF);if ($NF>11.3) { exit 0 } else { exit 1 } }'
Run the output of the nvcc command into awk and then process lines with V followed by any number of digits, a full stop (2 times) and then any number of digits followed by an end of line (this regular expression may need amending for your use case)
Processing the resulting line, we take the last field and remove the "V" using awk's sub function. We then compare the new field to see whether it is greater than 11.3. If it is exit with 0, otherwise exit with 1.
Finally, within your script, you can utilise the command result with:
if $(nvcc --version | awk '/V([0-9]+.){2}.[0-9]+$/ { sub("V","",$NF);if ($NF>11.3) { exit 0 } else { exit 1 } }')
then
exit
fi
nvcc --version | mawk 'NF*=/ release /' OFS='\f' FS='^.+[Vv]|[.]'
11
3
58
and this solution is very adaptable to other version number scenarios too - say i wanna extract out the xnu version (i.e. very-core-macos) out :
# this is one single line, re-formatted for readability
Darwin 21.6.0 Darwin Kernel Version 21.6.0: Sat Jun 18 17:07:22 PDT 2022;
root:xnu-8020.140.41~1/RELEASE_ARM64_T6000 arm64 arm
uname -mprsv |
mawk 'NF*=/[:]xnu[-]/' OFS='\f' FS='^.+[:]xnu[-]|[.~]|[/].+$'
8020
140
41
1

How to upgrade rpm package using bash script?

I want to install the specific rpm packages using bash script. But I am getting error.
I am using the below code :
#!/bin/bash
systemctl stop edb-as-10.service
server_status=$(systemctl status edb-as-10.service|awk '{print $1,$2,$3}'|grep Active|cut -d ":" -f2|cut -d " " -f2|tr -d " ")
echo "$server_status"
if [ "$server_status" == inactive ]; then
echo "You can proceed with upgrading the Potgresql server"
rpm –Uvh --nodeps edb-as10-server-pltcl-10.9.17-1.rhel7.x86_64.rpm
systemctl start edb-as-10.service else
echo " Failed to do Upgrading"
fi
I'm getting this error :
RPM version 4.11.3 Copyright (C) 1998-2002 - Red Hat, Inc. This
program may be freely redistributed under the terms of the GNU GPL
Usage: rpm [-aKfgpqVcdLilsiv?] [-a|--all] [-f|--file] [-g|--group]
[-p|--package] [--pkgid] [--hdrid] [--triggeredby] [--whatrequires]
[--whatprovides]
[--nomanifest] [-c|--configfiles] [-d|--docfiles] [-L|--licensefiles] [--dump] [-l|--list] [--queryformat=QUERYFORMAT]
[-s|--state] [--nofiledigest]
[--nofiles] [--nodeps] [--noscript] [--allfiles] [--allmatches] [--badreloc] [-e|--erase +] [--excludedocs]
[--excludepath=] [--force]
[-F|--freshen +] [-h|--hash] [--ignorearch] [--ignoreos] [--ignoresize] [-i|--install] [--justdb] [--nodeps]
[--nofiledigest]
[--nocontexts] [--noorder] [--noscripts] [--notriggers] [--nocollections] [--oldpackage] [--percent] [--prefix=]
[--relocate==]
[--replacefiles] [--replacepkgs] [--test] [-U|--upgrade +] [--reinstall=+] [-D|--define 'MACRO
EXPR'] [--undefine=MACRO]
[-E|--eval 'EXPR'] [--macros=] [--noplugins] [--nodigest] [--nosignature] [--rcfile=] [-r|--root ROOT]
[--dbpath=DIRECTORY]
[--querytags] [--showrc] [--quiet] [-v|--verbose] [--version] [-?|--help] [--usage] [--scripts] [--setperms] [--setugids]
[--conflicts] [--obsoletes]
[--provides] [--requires] [--info] [--changelog] [--xml] [--triggers] [--last] [--dupes] [--filesbypkg] [--fileclass]
[--filecolor] [--fscontext]
[--fileprovide] [--filerequire] [--filecaps]
But when I run the command
rpm –Uvh --nodeps edb-as10-server-pltcl-10.9.17-1.rhel7.x86_64.rpm
on terminal its working but when it placed in script its not working.

Why does system call fails?

I try to compile simple utility (kernel 3.4.67), which
all it does is trying to use system call very simply as following:
int main(void)
{
int rc;
printf("hello 1\n");
rc = system("echo hello again");
printf("system returned %d\n",rc);
rc = system("ls -l");
printf("system returned %d\n",rc);
return 0;
}
Yet, system call fails as you can see in the following log:
root#w812a_kk:/ # /sdcard/test
hello 1
system returned 32512
system returned 32512
I compile it as following:
arm-linux-gnueabihf-gcc -s -static -Wall -Wstrict-prototypes test.c -o test
That's really wierd becuase I used system in past in different linux and never had any issue with it.
I even tried another cross cpompiler but I get the same failure.
Version of kernel & cross compiler:
# busybox uname -a
Linux localhost 3.4.67 #1 SMP PREEMPT Wed Sep 28 18:18:33 CST 2016 armv7l GNU/Linux
arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (crosstool-NG linaro-1.13.1-4.7-2013.03-20130313 - Linaro GCC 2013.03) 4.7.3 20130226 (prerelease)
EDIT:
root#w812a_kk:/ # echo hello again && echo $? && echo $0
hello again
0
tmp-mksh
root#w812a_kk:/ #
But I did find something interesting:
On calling test_expander() withing the main, it works OK. so I suspect that maybe system call try to find a binary which is not founded ?
int test_expander(void)
{
pid_t pid;
char *const parmList[] = {"/system/bin/busybox", "echo", "hello", NULL};
if ((pid = fork()) == -1)
perror("fork error");
else if (pid == 0) {
execv("/system/bin/busybox", parmList);
printf("Return not expected. Must be an execv error.n");
}
return 0;
}
Thank you for any idea.
Ran
The return value of system(), 32512 decimal, is 7F00 in hex.
This value is strangely similar to 0x7F, which is the result of system() if /bin/sh can not be executed. It seems there is some problem with byte ordering (big/little endian). Very strange.
Update: while writing the answer, you edited the question and pulled in something about /system/bin/busybox.
Probably you simply don't have /bin/sh.
I think I understand what happens
From system man page:
The system() library function uses fork(2) to create a child process
that executes the shell command specified in command using execl(3)
as follows:
execl("/bin/sh", "sh", "-c", command, (char *) 0);
But in my filesystem sh is founded only /system/bin , not in /bin
So I better just use execv instead. (I can't do static link becuase it's read-only filesystem)
Thanks,
Ran

how to remove vendor name from crosstool-ng toolchain name

How do I configure crosstool-ng to drop the vendor name from the generated toolchain name.
For example to create an arm cross toolchain without specifying a vendor part would result in the following naming output
arm-unknown-linux-gnueabihf-g++
If I had supplied a vendor for instance "linaro" then I would have an output such as
arm-linaro-linux-gnueabihf-g++
What I want is to make the crosstool-ng to output the name as follows
arm-linux-gnueabihf-g++
I am aware that you can use the "Tuple's sed transform" and the "Tuple's alias" these facilities from menuconfig but these only create symbolic links to the arm-unknown-gnueabihf-g++ etc.
I have a toolchain that came with a board I am playing with and these toolchain have the vendor's part omitted. So my question "How do they do that?"
Even if the documentation states that:
CT_TARGET_VENDOR: [...] It can be set to empty, to remove the vendor string from the target tuple.
(see http://crosstool-ng.github.io/docs/configuration/ )
The current behavior is to fall back to 'unknown' if no value for CT_TARGET_VENDOR is given.
This situation was discussed within the crosstool-ng mailing list back in 2011 and there was a patch provided with a solution which may help you.
The idea of the patch was to:
[...] supplies a fake vendor and
then strips it out afterwards.
within scripts/functions of the crosstool-ng source.
See: https://sourceware.org/ml/crossgcc/2011-10/msg00047.html
diff -r a31d097e28cd -r 5b1330e7264a scripts/functions
--- a/scripts/functions Wed Oct 19 15:27:32 2011 +1300
+++ b/scripts/functions Wed Oct 19 16:23:36 2011 +1300
## -944,6 +944,20 ##
fi
}
+# Computes the target tuple from the configuration and the supplied
+# vendor string
+CT_BuildOneTargetTuple() {
+ local vendor="${1}"
+ local target
+
+ target="${CT_TARGET_ARCH}"
+ target="${target}${vendor:+-${vendor}}"
+ target="${target}${CT_TARGET_KERNEL:+-${CT_TARGET_KERNEL}}"
+ target="${target}${CT_TARGET_SYS:+-${CT_TARGET_SYS}}"
+
+ echo "${target}"
+}
+
# Compute the target tuple from what is provided by the user
# Usage: CT_DoBuildTargetTuple
# In fact this function takes the environment variables to build the target
## -994,10 +1008,7 ##
CT_DoKernelTupleValues
# Finish the target tuple construction
- CT_TARGET="${CT_TARGET_ARCH}"
- CT_TARGET="${CT_TARGET}${CT_TARGET_VENDOR:+-${CT_TARGET_VENDOR}}"
- CT_TARGET="${CT_TARGET}${CT_TARGET_KERNEL:+-${CT_TARGET_KERNEL}}"
- CT_TARGET="${CT_TARGET}${CT_TARGET_SYS:+-${CT_TARGET_SYS}}"
+ CT_TARGET=$(CT_BuildOneTargetTuple "${CT_TARGET_VENDOR}")
# Sanity checks
__sed_alias=""
## -1012,7 +1023,14 ##
esac
# Canonicalise it
- CT_TARGET=$(CT_DoConfigSub "${CT_TARGET}")
+ if [ -n "${CT_TARGET_VENDOR}" ]; then
+ CT_TARGET=$(CT_DoConfigSub "${CT_TARGET}")
+ else
+ # Canonicalise with a fake vendor string then strip it out
+ local target=$(CT_BuildOneTargetTuple "CT_INVALID")
+ CT_TARGET=$(CT_DoConfigSub "${target}" |sed -r -s s:CT_INVALID-::)
+ fi
+
# Prepare the target CFLAGS
CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ENDIAN_CFLAG}"
CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ARCH_CFLAG}"

What is the maximum size of a Linux environment variable value?

Is there a limit to the amount of data that can be stored in an environment variable on Linux, and if so: what is it?
For Windows, I've found following KB article which summarizes to:
Windows XP or later: 8191 characters
Windows 2000/NT 4.0: 2047 characters
I don't think there is a per-environment variable limit on Linux. The total size of all the environment variables put together is limited at execve() time. See "Limits on size of arguments and environment" here for more information.
A process may use setenv() or putenv() to grow the environment beyond the initial space allocated by exec.
Here's a quick and dirty program that creates a 256 MB environment variable.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
size_t size = 1 << 28; /* 256 MB */
char *var;
var = malloc(size);
if (var == NULL) {
perror("malloc");
return 1;
}
memset(var, 'X', size);
var[size - 1] = '\0';
var[0] = 'A';
var[1] = '=';
if (putenv(var) != 0) {
perror("putenv");
return 1;
}
/* Demonstrate E2BIG failure explained by paxdiablo */
execl("/bin/true", "true", (char *)NULL);
perror("execl");
printf("A=%s\n", getenv("A"));
return 0;
}
Well, it's at least 4M on my box. At that point, I got bored and wandered off. Hopefully the terminal output will be finished before I'm back at work on Monday :-)
export b1=A
export b2=$b1$b1
export b4=$b2$b2
export b8=$b4$b4
export b16=$b8$b8
export b32=$b16$b16
export b64=$b32$b32
export b128=$b64$b64
export b256=$b128$b128
export b512=$b256$b256
export b1k=$b512$b512
export b2k=$b1k$b1k
export b4k=$b2k$b2k
export b8k=$b4k$b4k
export b16k=$b8k$b8k
export b32k=$b16k$b16k
export b64k=$b32k$b32k
export b128k=$b64k$b64k
export b256k=$b128k$b128k
export b512k=$b256k$b256k
export b1m=$b512k$b512k
export b2m=$b1m$b1m
export b4m=$b2m$b2m
echo $b4m
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
: : : : : : : : : : : :
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
If you're worried that 4M may not be enough for your environment variable, you may want to rethink how you're doing things.
Perhaps it would be a better idea to put the information into a file and then use an environment variable to reference that file. I've seen cases where, if the variable is of the form #/path/to/any/fspec, it gets the actual information from the file path/to/any/fspec. If it doesn't begin with #, it uses the value of the environment variable itself.
Interestingly enough, with all those variables set, every single command starts complaining that the argument list is too long so, even though it lets you set them, it may not be able to start programs after you've done it (since it has to pass the environment to those programs).
Here are two helpful commands:
getconf -a | grep ARG_MAX
true | xargs --show-limits
I did a quick test on my Linux box with the following snippet:
a="1"
while true
do
a=$a$a
echo "$(date) $(numfmt --to=iec-i --suffix=B --padding=7 ${#a})"
done
On my box (Gentoo 3.17.8-gentoo-r1) this results in (last lines of output):
Wed Jan 3 12:16:10 CET 2018 16MiB
Wed Jan 3 12:16:11 CET 2018 32MiB
Wed Jan 3 12:16:12 CET 2018 64MiB
Wed Jan 3 12:16:15 CET 2018 128MiB
Wed Jan 3 12:16:21 CET 2018 256MiB
Wed Jan 3 12:16:33 CET 2018 512MiB
xrealloc: cannot allocate 18446744071562068096 bytes
So: the limit is quite high!
Don't know exactly but a quick experiment shows that no error occurs e.g. with 64kB of value:
% perl -e 'print "#include <stdlib.h>\nint main() { return setenv(\"FOO\", \"", "x"x65536, "\", 1); }\n";'\
| gcc -x c -o envtest - && ./envtest && echo $?
0
I used this very quick and dirty php code (below), modifying it for different values, and found that it works for variable lengths up to 128k. After that, for whatever reason, it doesn't work; no exception is raised, no error is reported, but the value does not show up in the subshell.
Maybe this is a php-specific limit? Maybe there are php.ini settings that might affect it? Or maybe there's a limit on the size of vars that a subshell will inherit? Maybe there are relevant kernel or shell config settings..
Anyway, by default, in CentOS, the limit for setting a var in the environment via putenv in php seems to be about 128k.
<?php
$s = 'abcdefghijklmnop';
$s2 = "";
for ($i = 0; $i < 8100; $i++) $s2 .= $s;
$result = putenv('FOO='.$s2);
print shell_exec('echo \'FOO: \'${FOO}');
print "length of s2: ".strlen($s2)."\n";
print "result = $result\n";
?>
Version info -
[root#localhost scratch]# php --version
PHP 5.2.6 (cli) (built: Dec 2 2008 16:32:08)
<..snip..>
[root#localhost scratch]# uname -a
Linux localhost.localdomain 2.6.18-128.2.1.el5 #1 SMP Tue Jul 14 06:36:37 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
[root#localhost scratch]# cat /etc/redhat-release
CentOS release 5.3 (Final)
The command line (with all argument) plus the environment variable should be less then 128k.
In my case it was due to buffer was limited when accepting a variable input value with read command. Solution was to add -e
Before read accessToken
After read -e accessToken
Docs: http://linuxcommand.org/lc3_man_pages/readh.html

Resources