374 lines
12 KiB
Markdown
374 lines
12 KiB
Markdown
# Solutions
|
|
## Table of Contents
|
|
- [Solutions](#solutions)
|
|
- [Table of Contents](#table-of-contents)
|
|
- [Summary Display of `top`](#summary-display-of-top)
|
|
- [Processes `PID` `1` and `2`](#processes-pid-1-and-2)
|
|
- [Own Shell Process](#own-shell-process)
|
|
- [Showing off my Variables](#showing-off-my-variables)
|
|
- [Monitoring](#monitoring)
|
|
- [Job Control](#job-control)
|
|
- [What changed?](#what-changed)
|
|
- [Process Creation](#process-creation)
|
|
|
|
## Summary Display of `top`
|
|
Memory used, CPU used
|
|
|
|
## Processes `PID` `1` and `2`
|
|
|
|
| `PID` | Command | Owner |
|
|
| ----- | ---------- | ----- |
|
|
| 1 | `systemd` | root |
|
|
| 2 | `kthreadd` | root |
|
|
|
|
## Own Shell Process
|
|
|
|
| `PID` | Command | Owner |
|
|
| ----- | ------- | ------ |
|
|
| 8096 | `bash` | ubuntu |
|
|
|
|
## Showing off my Variables
|
|
|
|
```bash
|
|
printenv
|
|
```
|
|
|
|
```env
|
|
SHELL=/bin/bash
|
|
SESSION_MANAGER=local/ManuSurface:@/tmp/.ICE-unix/4052,unix/ManuSurface:/tmp/.ICE-unix/4052
|
|
QT_ACCESSIBILITY=1
|
|
COLORTERM=truecolor
|
|
PYENV_SHELL=bash
|
|
XDG_CONFIG_DIRS=/etc/xdg/xdg-pop:/etc/xdg
|
|
SSH_AGENT_LAUNCHER=gnome-keyring
|
|
XDG_MENU_PREFIX=gnome-
|
|
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
|
|
GTK_IM_MODULE=ibus
|
|
POSH_PID=8096
|
|
GNOME_SHELL_SESSION_MODE=pop
|
|
DOTNET_ROOT=/usr/lib/dotnet
|
|
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
|
|
GRADLE_HOME=/home/manuel/.sdkman/candidates/gradle/current
|
|
NVS_OS=linux
|
|
NVS_USE_XZ=1
|
|
SDKMAN_CANDIDATES_DIR=/home/manuel/.sdkman/candidates
|
|
XMODIFIERS=@im=ibus
|
|
DESKTOP_SESSION=pop
|
|
GTK_MODULES=gail:atk-bridge
|
|
PWD=/home/manuel
|
|
PYENV_VIRTUALENV_INIT=1
|
|
LOGNAME=manuel
|
|
XDG_SESSION_DESKTOP=pop
|
|
XDG_SESSION_TYPE=x11
|
|
GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1
|
|
SYSTEMD_EXEC_PID=4075
|
|
XAUTHORITY=/run/user/1000/gdm/Xauthority
|
|
WINDOWPATH=2
|
|
HOME=/home/manuel
|
|
USERNAME=manuel
|
|
LANG=en_US.UTF-8
|
|
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
|
|
XDG_CURRENT_DESKTOP=pop:GNOME
|
|
VTE_VERSION=6800
|
|
SDKMAN_VERSION=5.16.0
|
|
CONDA_PROMPT_MODIFIER=false
|
|
GNOME_TERMINAL_SCREEN=/org/gnome/Terminal/screen/41f216e0_74b7_4540_876a_34b9260733e4
|
|
DOTNET_BUNDLE_EXTRACT_BASE_DIR=/home/manuel/.cache/dotnet_bundle_extract
|
|
LESSCLOSE=/usr/bin/lesspipe %s %s
|
|
XDG_SESSION_CLASS=user
|
|
NVS_ROOT=/home/manuel/.nvs
|
|
TERM=xterm-256color
|
|
LESSOPEN=| /usr/bin/lesspipe %s
|
|
LIBVIRT_DEFAULT_URI=qemu:///system
|
|
USER=manuel
|
|
GNOME_TERMINAL_SERVICE=:1.225
|
|
NVS_HOME=/home/manuel/.nvs
|
|
SDKMAN_DIR=/home/manuel/.sdkman
|
|
DISPLAY=:1
|
|
SHLVL=1
|
|
QT_IM_MODULE=ibus
|
|
SDKMAN_CANDIDATES_API=https://api.sdkman.io/2
|
|
POSH_THEME=/home/manuel/.omp/manuel.omp.json
|
|
XDG_RUNTIME_DIR=/run/user/1000
|
|
GODOT4=godot
|
|
PYENV_ROOT=/home/manuel/.pyenv
|
|
XDG_DATA_DIRS=/usr/share/pop:/usr/share/gnome:/home/manuel/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop
|
|
PATH=/home/manuel/.pyenv/plugins/pyenv-virtualenv/shims:/home/manuel/.pyenv/shims:/home/manuel/.pyenv/plugins/pyenv-virtualenv/shims:/home/manuel/.sdkman/candidates/gradle/current/bin:/home/manuel/.pyenv/plugins/pyenv-virtualenv/shims:/home/manuel/.pyenv/bin:/home/manuel/.nvs/default/bin:/home/manuel/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/manuel/.dotnet/tools
|
|
GDMSESSION=pop
|
|
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
|
|
SDKMAN_PLATFORM=linuxx64
|
|
POWERLINE_COMMAND=oh-my-posh
|
|
BASH_FUNC_nvs%%=() { if [ -z "${NVS_HOME}" ]; then
|
|
export NVS_HOME="${NVS_ROOT}";
|
|
fi;
|
|
export NVS_POSTSCRIPT="${NVS_HOME}/nvs_tmp_$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -f1 -d" ").sh";
|
|
local NODE_EXE="node";
|
|
if [ "${NVS_OS}" = "win" ]; then
|
|
NODE_EXE="node.exe";
|
|
fi;
|
|
local NODE_PATH="${NVS_HOME}/cache/${NODE_EXE}";
|
|
if [ ! -f "${NODE_PATH}" ]; then
|
|
local NODE_VERSION="$(grep '"bootstrap" *:' "${NVS_ROOT}/defaults.json" | sed -e 's/.*: *"//' -e 's/"[^\n]*//' -e 's/.*\///')";
|
|
local NODE_REMOTE="$(grep '"bootstrap" *:' "${NVS_ROOT}/defaults.json" | sed -e 's/.*: *"//' -e 's/"[^\n]*//' -e 's/\/.*//')";
|
|
local NODE_BASE_URI="$(grep "\"${NODE_REMOTE}\" *:" "${NVS_ROOT}/defaults.json" | sed -e 's/.*: *"//' -e 's/"[^\n]*//')";
|
|
local NODE_ARCHIVE_EXT=".tar.gz";
|
|
local TAR_FLAGS="-zxvf";
|
|
if [ "${NVS_OS}" = "win" ]; then
|
|
NODE_ARCHIVE_EXT=".7z";
|
|
else
|
|
if [ "${NVS_USE_XZ}" = "1" ]; then
|
|
NODE_ARCHIVE_EXT=".tar.xz";
|
|
TAR_FLAGS="-Jxvf";
|
|
fi;
|
|
fi;
|
|
local NODE_ARCH="$(uname -m | sed -e 's/x86_64/x64/;s/i86pc/x64/;s/i686/x86/;s/aarch64/arm64/')";
|
|
if [ "${NVS_OS}" = "aix" ]; then
|
|
NODE_ARCH="ppc64";
|
|
fi;
|
|
local NODE_FULLNAME="node-v${NODE_VERSION}-${NVS_OS}-${NODE_ARCH}";
|
|
local NODE_URI="${NODE_BASE_URI}v${NODE_VERSION}/${NODE_FULLNAME}${NODE_ARCHIVE_EXT}";
|
|
local NODE_ARCHIVE="${NVS_HOME}/cache/${NODE_FULLNAME}${NODE_ARCHIVE_EXT}";
|
|
if [ ! -d "${NVS_HOME}/cache" ]; then
|
|
command mkdir -p "${NVS_HOME}/cache";
|
|
fi;
|
|
echo "Downloading bootstrap node from ${NODE_URI}";
|
|
if type noglob > /dev/null 2>&1; then
|
|
noglob curl -L -# "${NODE_URI}" -o "${NODE_ARCHIVE}";
|
|
else
|
|
curl -L -# "${NODE_URI}" -o "${NODE_ARCHIVE}";
|
|
fi;
|
|
if [ ! -f "${NODE_ARCHIVE}" ] && [ "${NODE_ARCHIVE_EXT}" = ".tar.xz" ]; then
|
|
NODE_ARCHIVE_EXT=".tar.gz";
|
|
TAR_FLAGS="-zxvf";
|
|
NODE_ARCHIVE="${NVS_HOME}/cache/${NODE_FULLNAME}${NODE_ARCHIVE_EXT}";
|
|
echo "Retry download bootstrap node from ${NODE_URI} in gz format";
|
|
if type noglob > /dev/null 2>&1; then
|
|
noglob curl -L -# "${NODE_URI}" -o "${NODE_ARCHIVE}";
|
|
else
|
|
curl -L -# "${NODE_URI}" -o "${NODE_ARCHIVE}";
|
|
fi;
|
|
fi;
|
|
if [ ! -f "${NODE_ARCHIVE}" ]; then
|
|
echo "Failed to download node binary.";
|
|
return 1;
|
|
fi;
|
|
if [ "${NVS_OS}" = "win" ]; then
|
|
"${NVS_ROOT}/tools/7-Zip/7zr.exe" e "-o${NVS_HOME}/cache" -y "${NODE_ARCHIVE}" "${NODE_FULLNAME}/${NODE_EXE}" > /dev/null 2>&1;
|
|
else
|
|
if [ "${NVS_OS}" = "aix" ]; then
|
|
gunzip "${NODE_ARCHIVE}" | tar -xvC "${NVS_HOME}/cache" "${NODE_FULLNAME}/bin/${NODE_EXE}" > /dev/null 2>&1;
|
|
else
|
|
tar $TAR_FLAGS "${NODE_ARCHIVE}" -C "${NVS_HOME}/cache" "${NODE_FULLNAME}/bin/${NODE_EXE}" > /dev/null 2>&1;
|
|
fi;
|
|
mv "${NVS_HOME}/cache/${NODE_FULLNAME}/bin/${NODE_EXE}" "${NVS_HOME}/cache/${NODE_EXE}" > /dev/null 2>&1;
|
|
rm -r "${NVS_HOME}/cache/${NODE_FULLNAME}" > /dev/null 2>&1;
|
|
fi;
|
|
if [ ! -f "${NODE_PATH}" ]; then
|
|
echo "Failed to setup node binary.";
|
|
return 1;
|
|
fi;
|
|
echo "";
|
|
fi;
|
|
local EXIT_CODE=0;
|
|
case "$@" in
|
|
"cd")
|
|
local DIR=$PWD;
|
|
while [ "$DIR" != "" -a ! \( -e "$DIR/.node-version" -o -e "$DIR/.nvmrc" \) ]; do
|
|
if [ "$DIR" = "/" ]; then
|
|
DIR=;
|
|
else
|
|
DIR=$(dirname "$DIR");
|
|
fi;
|
|
done;
|
|
if [ "$DIR" != "$NVS_AUTO_DIRECTORY" ]; then
|
|
command "${NODE_PATH}" "${NVS_ROOT}/lib/index.js" auto;
|
|
EXIT_CODE=$?;
|
|
fi;
|
|
export NVS_AUTO_DIRECTORY=$DIR
|
|
;;
|
|
*)
|
|
command "${NODE_PATH}" "${NVS_ROOT}/lib/index.js" "$@";
|
|
EXIT_CODE=$?
|
|
;;
|
|
esac;
|
|
if [ ${EXIT_CODE} = 2 ]; then
|
|
rm "${NODE_PATH}";
|
|
nvs $@;
|
|
fi;
|
|
if [ -f "${NVS_POSTSCRIPT}" ]; then
|
|
. "${NVS_POSTSCRIPT}";
|
|
command rm "${NVS_POSTSCRIPT}";
|
|
unset NVS_POSTSCRIPT;
|
|
fi;
|
|
return $EXIT_CODE
|
|
}
|
|
BASH_FUNC_nvsudo%%=() { local NVS_CURRENT=`nvs which`;
|
|
if [ -n "${NVS_CURRENT}" ]; then
|
|
NVS_CURRENT=`dirname "${NVS_CURRENT}"`;
|
|
fi;
|
|
sudo "NVS_CURRENT=${NVS_CURRENT}" "${NVS_ROOT}/nvs" $*
|
|
}
|
|
_=/usr/bin/printenv
|
|
```
|
|
|
|
```bash
|
|
export Name="Manuel"
|
|
```
|
|
|
|
## Monitoring
|
|
```bash
|
|
tail --follow /var/log/syslog
|
|
```
|
|
|
|
- A message is logged stating that a new session has been started
|
|
- It is nested in a few `sshd` processes and a `bash` process
|
|
- The PID is `1375`, the state is "Sleeping"
|
|
|
|
***Hierarchy:***
|
|
|
|
```log
|
|
├─sshd───sshd───sshd───bash───screen───screen─┬─bash───tail
|
|
```
|
|
|
|
- The SSH session is terminated because the terminal running in it has been closed
|
|
|
|
## Job Control
|
|
Each syslog message is printed 3 times because 3 observers are running at the same time.
|
|
|
|
### What changed?
|
|
- Job 2 is now the previous job (flagged with a `+`)
|
|
- Job 2 is stopped
|
|
- Job 2's command doesn't have an ampersand `&` at the end of it (probably because it is not running (in background))
|
|
|
|
## Process Creation
|
|
|
|
```bash
|
|
size a.out
|
|
```
|
|
|
|
```
|
|
text data bss dec hex filename
|
|
1565 600 8 2173 87d a.out
|
|
```
|
|
|
|
```bash
|
|
objdump -h a.out
|
|
```
|
|
|
|
```bash
|
|
objdump -dj .text a.out
|
|
```
|
|
|
|
```c
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
|
|
int main()
|
|
{
|
|
fork();
|
|
sleep(30);
|
|
printf("My PID is: %d\n", getpid());
|
|
return 0;
|
|
}
|
|
```
|
|
|
|
The virtual memory is identical, but their reserved memory is different.
|
|
|
|
```c
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <unistd.h>
|
|
|
|
int main()
|
|
{
|
|
int pid = fork();
|
|
if (pid == 0)
|
|
{
|
|
sleep(1);
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
int status = 0;
|
|
sleep(10);
|
|
waitpid(pid, &status, 0);
|
|
sleep(10);
|
|
return 0;
|
|
}
|
|
}
|
|
```
|
|
|
|
Der Prozess verweilt im Zustand `Z` (Zombie) bis `waitpid()` ausgeführt wird.
|
|
|
|
```c
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <unistd.h>
|
|
|
|
int main()
|
|
{
|
|
int pid = fork();
|
|
if (pid == 0)
|
|
{
|
|
sleep(10);
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
```
|
|
|
|
Der Child-Prozess wird dem Prozess 1 (init) untergeordnet. Er wechselt nicht in den Zustand `Z`.
|
|
|
|
```c
|
|
#define _GNU_SOURCE
|
|
#include <sched.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <unistd.h>
|
|
#define STACK_SIZE (1024 * 1024) /* Stack size for cloned child */
|
|
|
|
static int childFunc(void *arg)
|
|
{
|
|
//do something
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
char *stack;
|
|
char *stackTop;
|
|
pid_t pid;
|
|
|
|
if (argc < 2)
|
|
{
|
|
fprintf(stderr, "Usage: %s <child-hostname>\n", argv[0]); // 1. Show help text if wrong amount of args
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/* Create shared memory at address `stack` which is readable and writeable */
|
|
stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
|
|
|
|
stackTop = stack + STACK_SIZE; // Store address to top of stack
|
|
|
|
/* Run `childFunc` in a new process with a new UTS that exits with exit code `SIGCHLD` */
|
|
pid = clone(childFunc, stackTop, CLONE_NEWUTS | SIGCHLD, argv[1]);
|
|
|
|
if (waitpid(pid, NULL, 0) == -1)
|
|
{
|
|
exit(EXIT_FAILURE); // Exit with non-zero exit code if child exits abnormally
|
|
}
|
|
|
|
printf("child has terminated\n");
|
|
exit(EXIT_SUCCESS); // Exit with zero exit code otherwise
|
|
}
|
|
```
|