2

Context: an AIX lpar with very low memory (no forking possible, so only shell's builtins (cd, echo, kill) will work). I can have a (hmc) console to it, but I need a better way to start freing memory in AIX, when memory is too low to even allow you to do a "ps -ef". (I have a way, but it is a way to randomly kill existing pids. I need to have more info on the PID I can kill, so I can choose an unimportant PID)

I want to know :

  • How could I see the content of files using only ksh' builtins
  • and the ultimate goal: what file's content could I look at, using only builtins, to choose the pids to kill, so that I only kill "mundane" process, (when I killed enough PIDs, I will then be able to "ps -ef" "netstat -rn" etc, and "ps" should still show the "important" processes)

What I already know:

  • I can log in the console (ssh hscroot@hmc, vtmenu, choose the lpar with OutOfMemory problems, log as root, and, after a while (2-5 minutes) and several complaints that ksh can't fork commandes in /etc/profile, I get to a (ksh) prompt.

  • Now I can simulate "ls" to see what /proc/PID# directory exists: cd /proc ; echo * will get me the list of still running PIDs. (usually I'll see 0, 1(init), which are not to be killed, and also a whole bunch of other PIDs, with little indication of what process they run (ksh? syncd? ls? java?).

  • I can also : kill some pids here to free memory enough (kill is a builtin in ksh (or bash!), so no need to fork to use it) and when I killed enough PIDs, I am then able to then do a ps -ef netstat -rn etc, allowing me to get the state of the server before I shutdown -rF to reboot it from the lpar itself (This will sync, close filesystems, etc. Note that the alternative, a reboot from the HMC, is usually not possible (as it probably tries to fork some commands), unless you add "--immed", which is like powering off directly and is not advisable as it can cause filesystem problems, causing sometimes very lengthy fsck when restarting the lpar).

  • killing some PIDs and runnign the shutdown: allow me to get some "ps -ef" ideas of what was running and needs to restart, get the routes (in case the static routes don't match), and shutdown "more gracefully", preserving the filesystem and avoiding lengthy fsck when it starts-up.)

But I need your help to also:

  • See the content of some files! (for ex: to be able to see the pid of some of the pid files in /var/run/*.pid, I'd do : cd /var/run and then echo *pid to get the list of pid files, but then, with only builtins of ksh (remember: no forking!) how can I get the content of one of those files?). The same trick could also help to get some infos underneath /proc/PID#/ ..., maybe allowing me to also choose the right PID to kill)

  • choose PIDs "wisely" using the above (or whatever trick you can have)

Precision: Bonus points if your trick works with this version ksh builtins:

prompt# strings /usr/bin/ksh | grep '\..*\.' | grep builtin
0@(#)27  1.57.14.5  src/bos/usr/bin/ksh/builtin.c, cmdksh, bos61Z, z2013_29A2 7/5/13 00:10:52
2

Please Try this:

Of a list of included builtins in ksh:

$ ksh -c 'builtin' 

This are the only builtins useful to answer your question:

echo kill print printf read

So, it seems that the only way to "read a file" is to use read.
Lets define a couple of functions (copy and paste in the CLI):

function Usage {
    echo "fileread: filename [from line] [to line]"
    exit 1
}

function fileread {
    [ "$#" -lt 1 ] && echo "please supply the name of a file" && Usage
    linestart=${2:-1}
    lineend=${3:-0}
    i=0
    while IFS=$'\n' read line; do
        i=$((i+1))
        [[ "$i" -lt "$linestart" ]] && continue
        [[ "$lineend" != 0 && "$i" -gt "$lineend" ]] && continue
        echo "$i $line"
    done <"$1"
}

And then, call the function (as an example):

$ cd /var/run
$ fileread sshd.pid 10 20
  • read! I forgot to use read (which I use daily in several scripts and one liners)... thanks for the reminder! – Olivier Dulac Oct 20 '16 at 18:14
  • 1
    @OlivierDulac Another way to cat a file without forking, despite appearances, is echo "$(<FILENAME)". It might not work with your version of ksh, I don't know which versions have it. – Gilles Oct 20 '16 at 21:31
  • 1
    fileread() looks like the standalone shcat() function in one of the /etc/rc*.sh files in any solaris derived OS - see src.illumos.org/source/xref/illumos-gate/usr/src/cmd/svc/shell/… – Henk Langeveld Oct 21 '16 at 20:10
  • 1
    @HenkLangeveld I did not use, nor had I any idea of any previous implementation of such a function. Any code I posted is my own independent creation including any and all mistakes. – sorontar Oct 21 '16 at 20:21
  • @sorontar - as I guess there will be many more independent solutions, thanks for your contribution. I guess shcat() is probably one of the earliest ever exposed to the public. Don't know if it was already used in SunOS 3 or 4. – Henk Langeveld Oct 23 '16 at 11:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.