I have compiled nwipe open source utility in Centos. Once compiled it works absolutely fine on the machine where it was compiled. I have also copied the compiled package to another machine running Centos along with required libraries and it works fine.
I have tried to package this utility to work with Busybox RAMBOX embedded linux. The purpose of this utility is to PXEBoot the workstations via TFTP and auto wipe all the hard-drives.
In order to achieve this, I have used Linux kernel from Centos netboot CD and downloaded the busybox, copied nwipe utility that I compiled on another Centos development server.
I also copied all the required libraries. See below.
when I do ldd nwipe. It shows the dependencies for the libraries.
[root#localhost src]# ldd nwipe
linux-gate.so.1 => (0x00a78000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00650000)
libparted.so.2 => /usr/lib/libparted.so.2 (0x007fd000)
libpanel.so.5 => /usr/lib/libpanel.so.5 (0x00dd0000)
libncurses.so.5 => /lib/libncurses.so.5 (0x006db000)
libc.so.6 => /lib/libc.so.6 (0x004b0000)
libtinfo.so.5 => /lib/libtinfo.so.5 (0x007e2000)
/lib/ld-linux.so.2 (0x0048a000)
libuuid.so.1 => /lib/libuuid.so.1 (0x0025b000)
libdl.so.2 => /lib/libdl.so.2 (0x00649000)
libdevmapper.so.1.02 => /lib/libdevmapper.so.1.02 (0x0073c000)
libselinux.so.1 => /lib/libselinux.so.1 (0x006ba000)
libsepol.so.1 => /lib/libsepol.so.1 (0x00a2e000)
libudev.so.0 => /lib/libudev.so.0 (0x0066d000)
so I copied all these libraries dependencies to the busybox /lib /usr/lib folders.
Finally I compiled the busybox and used cpio and gzip to get the initrd.img file.
Then I use centos netboot kernel 2.6 and initrd.img to pxeboot the workstation. Everything works fine, I can use all the busybox basic linux commands. But when I execute ./nwipe it does not work. It simply shows the shell prompt again.
/# ./nwipe
/#
see below the content of my init file.
#!/bin/sh
#Mount things needed by this script
mount -t proc proc /proc
mount -t sysfs sysfs /sys
#Disable kernel messages from popping onto the screen
echo 0 > /proc/sys/kernel/printk
#Clear the screen
clear
#Create all the symlinks to /bin/busybox
busybox --install -s
#Create device nodes
mknod /dev/null c 1 3
mknod /dev/tty c 5 0
mdev -s
#Function for parsing command line options with "=" in them
# get_opt("init=/sbin/init") will return "/sbin/init"
get_opt() {
echo "$#" | cut -d "=" -f 2
}
#Defaults
init="/sbin/init"
root="/dev/hda1"
#Process command line options
for i in $(cat /proc/cmdline); do
case $i in
root\=*)
root=$(get_opt $i)
;;
init\=*)
init=$(get_opt $i)
;;
esac
done
#Mount the root device
mount "${root}" /newroot
#Check if $init exists and is executable
if [[ -x "/newroot/${init}" ]] ; then
#Unmount all other mounts so that the ram used by
#the initramfs can be cleared after switch_root
umount /sys /proc
#Switch to the new root and execute init
exec switch_root /newroot "${init}"
fi
#This will only be run if the exec above failed
echo "Failed to switch_root, dropping to a shell"
exec sh
Could someone please help me what I have to do to fix this?
How I can run my compiled software with busybox?
Thanks well in advance for reading this post.
I have managed to fix this by not using busybox. This time around I have used Centos minimal install and used dracut utility to create kernel and initramfs and mounted the root file system as NFS on the server. It works like a charm.
It works like a full blown Linux Centos and it is pretty fast.
Thank you for looking at this post :)
Related
Debugging my own kernel with qemu and gdb seems to be unnecessarily hard because pressing ctrl-c in gdb to break qemu does not break it, but makes it quit with the message
qemu-system-x86_64: terminating on signal 2
[Inferior 1 (Remote target) exited normally]
qemu command line:
qemu-system-x86_64 -s -no-shutdown -no-reboot -enable-kvm -m 1G -smp cores=1 -cpu qemu64 -drive if=pflash,format=raw,file=ovmf/OVMF.fd -drive file=fat:rw:hda,format=raw -net none -debugcon file:debug.log -global isa-debugcon.iobase=0x402 &
The behavior is the same without KVM. Could someone please help, how to solve this?
qemu-system-x86_64 v3.1.0
gdb v8.2.1
I would like not to build the latest versions of these from source as it seems to be a daunting task to do.
EDIT: Created a minimal environment where the issue can be reproduced. I may have tracked it down to running the whole thing from a shell script, but can't seem to progress further. Commenting out the gdb call in the script and starting it from a separate terminal, solves the issue (however i like things that work with as few keystrokes as possible).
You can download it here.
Just start the script called qd
(Is there a nicer way to provide files? I will delete this after a while.)
I tested with QEMU 5.0.0 and GDB 9.2, same issue, and same solution, that is commenting out the GDB call in the script and starting it from a separate terminal. You could probably just modify your script so that QEMU would be started in another
terminal. Starting QEMU using nohup is not working either.
I included the script I am usually using for building fresh versions of QEMU and GDB: latest versions are likely to have fixed bugs. The script is working on Ubuntu 20.04, and is probably still working on 16.04 and 18.04 - you may have to make small adjustments at the beginning of the script. Feel free to report issues, I would be willing to fix them.
build-qemu-gdb.sh:
#!/bin/bash
set -e
# Xenial/16.04
PERL_MODULES_VERSION=5.22
SPHINX=python-sphinx
# Bionic/18.04
PERL_MODULES_VERSION=5.26
SPHINX=python-sphinx
# Focal/20.04
PERL_MODULES_VERSION=5.30
SPHINX="sphinx-doc sphinx-common"
# Qemu
QEMU_VERSION=5.0.0
PREFIX=/opt/qemu-${QEMU_VERSION}
# GDB
GDB_VERSION=9.2
do_get_gdb()
{
if [ -f gdb-${GDB_VERSION}.tar.xz ]
then
echo "gdb-${GDB_VERSION}.tar.xz is present."
else
wget http://ftp.gnu.org/gnu/gdb/gdb-${GDB_VERSION}.tar.xz
fi
}
do_get_qemu()
{
if [ -f qemu-${QEMU_VERSION}.tar.xz ]
then
echo "qemu-${QEMU_VERSION}.tar.xz is present."
else
wget https://download.qemu.org/qemu-${QEMU_VERSION}.tar.xz
fi
}
do_install_prerequisites()
{
sudo apt-get install libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev libaio-dev libbluetooth-dev libbrlapi-dev libbz2-dev libcap-dev libcap-ng-dev libcurl4-gnutls-dev libgtk-3-dev libibverbs-dev \
libjpeg8-dev libncurses5-dev libnuma-dev librbd-dev librdmacm-dev libsasl2-dev libsdl2-dev libseccomp-dev libsnappy-dev libssh2-1-dev libvde-dev libvdeplug-dev libvte-2.91-dev libxen-dev liblzo2-dev \
valgrind xfslibs-dev liblzma-dev flex bison texinfo gettext perl perl-modules-${PERL_MODULES_VERSION} ${SPHINX}
}
do_configure()
{
local TARGET_LIST="x86_64-softmmu"
pushd qemu-${QEMU_VERSION}
./configure --target-list="${TARGET_LIST}" --prefix=${PREFIX} --extra-cflags="-I$(pwd)/packages/include" --extra-ldflags="-L$(pwd)/packages/lib"
popd
}
do_extract_qemu()
{
echo "extracting QEMU..."
rm -rf qemu-${QEMU_VERSION}
tar Jxf qemu-${QEMU_VERSION}.tar.xz
}
do_build_qemu()
{
echo "building..."
pushd qemu-${QEMU_VERSION}
make all
popd
}
do_install_qemu()
{
echo "installing..."
pushd qemu-${QEMU_VERSION}
sudo make install
popd
}
do_build_qemu()
{
do_extract_qemu
do_configure
do_build_qemu
do_install_qemu
}
do_extract_gdb()
{
echo "extracting GDB..."
rm -rf gdb-${GDB_VERSION}
tar Jxf gdb-${GDB_VERSION}.tar.xz
}
do_build_gdb()
{
do_extract_gdb
rm -rf gdb
mkdir gdb
pushd gdb
../gdb-${GDB_VERSION}/configure --enable-tui --prefix=/opt/gdb-${GDB_VERSION}-x86_64-none-elf --target=x86_64-none-elf --program-prefix=x86_64-none-elf-
make all install
popd
}
# main
do_install_prerequisites
do_get_qemu
do_build_qemu
do_get_gdb
do_build_gdb
The resulting new paths for QEMU and GDB after installation would be:
/opt/qemu-5.0.0/bin/qemu-system-x86_64
/opt/gdb-9.2-x86_64-none-elf/bin/x86_64-none-elf-gdb
I am trying to add a line and replace others with puppet file_line resource. I have a very strange behavior. Here is the code:
file_line { 'bashrc':
ensure => present,
path => '/user/.bashrc',
line => 'HISTCONTROL=ignoredups:ignorespace:erasedups',
match => '^HISTCONTROL\=',
}
file_line { 'sysctl_conf':
ensure => present,
path => '/etc/sysctl.conf',
line => 'net.ipv6.conf.all.disable_ipv6=1',
notify => Exec['/sbin/sysctl -p'],
}
I have this line: HISTCONTROL=ignoredups in the .bashrc file. When I run puppet agent -t it just appends this line HISTCONTROL=ignoredups:ignorespace:erasedups to the file and the original line HISTCONTROL=ignoredups is still there. More interesting is that the second file_line resource istn't executed at all.
But when I run puppet apply -e "include module", the line in .bashrc is replaced and the net.ipv6.conf.all.disable_ipv6=1 is appended to /etc/sysctl.conf.
System information:
root#puppet [Home]:~# puppet agent --version
5.5.8
root#puppet [Home]:~# puppet --version
5.5.8
root#puppet [Home]:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.5 LTS
Release: 16.04
Codename: xenial
root#puppet [Home]:~# puppet module list | grep stdlib
├── puppetlabs-stdlib (v5.1.0)
Can someone explain this please, or how to fix this?
Thanks
First of all please excuse my bad english, I'll try to get understandable.
I'm using a batch file (Windows, cmd.exe) to retrieve and silently install Adobe Flash on my computer.
The batch works well, but I have a problem when there is a major version change on Adobe servers.
Here is the command line batch:
#echo off
setlocal enableextensions
md c:\temp\flash
pushd c:\temp\flash
wget -nH --cut-dirs=5 -r --timestamping http://download.macromedia.com/get/flashplayer/current/licensing/win/install_flash_player_15_plugin.exe
wget -nH --cut-dirs=5 -r --timestamping http://download.macromedia.com/get/flashplayer/current/licensing/win/install_flash_player_15_active_x.exe
echo Closing browsers
pause
taskkill /f -im firefox.exe -im iexplore.exe
install_flash_player_15_plugin.exe -install -au 2
install_flash_player_15_active_x.exe -install -au 2
popd
setlocal disableextensions
pause
When Flash is upgraded to the next version, the filename changes from install_flash_player_15_active_x.exe
to
install_flash_player_16_active_x.exe
and the batch must be manually corrected or else it is stuck with an old version.
Is there any way to replace the version number with wildcards or some regular expression in order to have wget to retrieve the latest file when its name change ?
Or at least, is there any Windows compatible command line tool which parses the file names on a server, find the latest and passes it as a variable for wget (or cURL) ?
Thank you
You don't need Regular Expressions to get the current version of flash for IE and Firefox. Just change the URLs to
For Firefox: http://download.macromedia.com/pub/flashplayer/current/support/install_flash_player.exe
For IE: http://download.macromedia.com/pub/flashplayer/current/support/install_flash_player_ax.exe
wget -nH --cut-dirs=5 -r --timestamping http://download.macromedia.com/pub/flashplayer/current/support/install_flash_player.exe
wget -nH --cut-dirs=5 -r --timestamping http://download.macromedia.com/pub/flashplayer/current/support/install_flash_player_ax.exe
I have a (maybe) unusual situation. I need to run VMware CLI commands in a Windows box, but via the cygwin CLI inside a shell script. I can NOT change this for now, so any suggestions to "why not do this instead" may be futile, although appreciated. Here's a sample script.
#!/bin/bash
# Paths for vmware-cmd.pl file to run vmware commands from vsphere cli
_vcli_dir="/cygdrive/c/Program Files (x86)/VMware/VMware vSphere CLI"
_vcli_bin="$_vcli_dir/bin"
_vcli_perl="$_vcli_dir/Perl"
_vcli_perl_bin="$_vcli_perl/bin"
_vcli_perl_lib="$_vcli_perl/lib"
_vcli_perl_vlib="$_vcli_perl_lib/VMware"
_vcmd=vmware-cmd.pl
export _orig_path=$PATH
# Add above directories to path variable
export PATH=$PATH:$_vcli_dir:$_vcli_bin:$_vcli_perl:$_vcli_perl_bin:$_vcli_perl_lib:$_vcli_perl_vlib
echo $PATH
$_vcmd /?
export PATH=$_orig_path
echo $PATH
When I run the above script, I get
Can't locate VMware/VIRuntime.pm in #INC (#INC contains:
/usr/lib/perl5/site_perl/5.14/i686-cygwin-threads-64int
/usr/lib/perl5/site_perl/5.14
/usr/lib/perl5/vendor_perl/5.14/i686-cygwin-threads-64int
/usr/lib/perl5/vendor_perl/5.14
/usr/lib/perl5/5.14/i686-cygwin-threads-64int /usr/lib/perl5/5.14
/usr/lib/perl5/site_perl/5.10 /usr/lib/perl5/vendor_perl/5.10
/usr/lib/perl5/site_perl/5.8 .) at /cygdrive/c/Program Files
(x86)/VMware/VMware vSphere CLI/bin/vmware-cmd.pl line 8. BEGIN
failed--compilation aborted at /cygdrive/c/Program Files
(x86)/VMware/VMware vSphere CLI/bin/vmware-cmd.pl line 8.
I can run the same vmware-cmd.pl script from a DOS command prompt
c:> vmware-cm.pl
So I now my installation is correct.
Any clues please?
This post gave me the idea to fix it. But now I get a core dump.
How is Perl's #INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?)
The added line is the second export PERL5LIB line.
#!/bin/bash
# Path for vmware-cmd.pl file to run vmware commands from vsphere cli
_vcli_dir="/cygdrive/c/Program Files (x86)/VMware/VMware vSphere CLI"
_vcli_bin="$_vcli_dir/bin"
_vcli_perl="$_vcli_dir/Perl"
_vcli_perl_bin="$_vcli_perl/bin"
_vcli_perl_lib="$_vcli_perl/lib"
_vcli_perl_vlib="$_vcli_perl_lib/VMware"
_vcmd=vmware-cmd.pl
export _orig_path=$PATH
# Add above directories to path variable
export PATH=$PATH:$_vcli_dir:$_vcli_bin:$_vcli_perl:$_vcli_perl_bin:$_vcli_perl_lib:$_vcli_perl_vlib
export PERL5LIB=$_vcli_dir:$_vcli_bin:$_vcli_perl:$_vcli_perl_bin:$_vcli_perl_lib:$_vcli_perl_vlib
echo $PATH
$_vcmd /?
export PATH=$_orig_path
echo $PATH
I solved by going through my elbow to get to my a**, as the saying goes.
What I did was
- Install vmware cli on my Windows box to the default directory
- Added environment variables for the VMware main directory, the bin directory, the Perl directory and the Perl/bin directory
- Added these environment variables to my PATH variable.
Then I created a vmware-cli.bat file that takes parameters and concatenates them into a vmware-cli command with the correct values. For example, I call this to list the VMs in the server
cygwin:> ./vmware-cli.bat vmware-cmd.pl --server MyServer --username User --password PW -l
Inside the batch file I essentailly do
REM Get first parm as the command, and then concatenate the rest of the parms
set VCLI_CMD=%1
shift
:LOOP
if %1x==x goto :EXECUTE
set VCLI_CMD=%VCLI_CMD% %1
shift
goto LOOP:
:EXECUTE
%VCLI_CMD%
This is an alternative to the previous posted that will allow you to keep it in the same shell script
VIMCMD="/cygdrive/C/Program Files (x86)/VMware/VMware vSphere CLI/bin/vmware-cmd.pl"
VIMCMD_DOS=$(cygpath -d "$VIMCMD")
DOS_VIMCMD="cmd /c $VIMCMD_DOS"
Then you can run:
$ $DOS_VIMCMD --version
vSphere SDK for Perl version: 6.0.0
Script 'vmware-cmd.pl' version: 6.0.0
I have a Linux application that uses the libsctp.so library. When I run it as root, it runs fine.
But when I run it as an ordinary user, it gives the following error:
error while loading shared libraries: libsctp.so.1: cannot open shared object file: No such file or directory
But, when I do ldd as ordinary user, it is able to see the library:
[sanjeev#devtest6 src]$ ldd myapp
...
...
libsctp.so.1 => /usr/local/lib/libsctp.so.1 (0x00d17000)
[sanjeev#devtest6 src]$ ls -lL /usr/local/lib/libsctp.so.1
-rwxrwxrwx 1 root root 27430 2009-06-29 11:26 /usr/local/lib/libsctp.so.1
[sanjeev#devtest6 src]$
What could be wrong? How is the ldd is able to find libsctp.so, but when actually running the app, it is not able to find the same library?
EDIT: Just observed that this problem appears only if setuid bit is set for myapp.
I had the same exception on Ubuntu 18.04, after executing the following code:
SctpServerChannel s = SctpServerChannel.open();
The issue was solved after running:
sudo apt-get install libsctp1
Fixed the problem. I added a new file in /etc/ld.so.conf.d with the followng name:
libsctp.so.1.conf
The contents of libsctp.so.1.conf is as follows:
/usr/local/lib/
And then ran
/sbin/ldconfig
, after which my app ran successfully.
Explanation: Since the setuid bit was set, the program is executed as root, for whom LD_LIBRARY_PATH is not available. Hence it is not able to find libsctp.so. I was not aware of this because when I login as root, .bashrc gets executed and LD_LIBRARY_PATH becomes available.
It could be because of environment setting difference.
You may need to add /usr/local/lib/ to LIBRARY_PATH or kind of.
You can recieve that error if a shared library that libsctp.so itself depends on is not found (yes, it is a little confusing). Try ldd on the library itself:
ldd /usr/local/lib/libsctp.so.1
Are you setting LD_LIBRARY_PATH before switching to root user or after that? When you run ldd as root does it still find all dependent libraries?
dmitry#debian:~$ echo $LD_LIBRARY_PATH
dmitry#debian:~$ export LD_LIBRARY_PATH=/usr/local/lib
dmitry#debian:~$ echo $LD_LIBRARY_PATH
/usr/local/lib
dmitry#debian:~$ su
Password:
debian:/home/dmitry# echo $LD_LIBRARY_PATH
debian:/home/dmitry#