Search This Blog

Sunday, April 24, 2011

How to create a bootable USB thumb drive for Windows 7 64bit using Windows XP 32bit machine.

Problem:
We have the ISO of the Windows 7 64bit and want to install it using the USB Thumb drive installation method.
We have access only to our old Windows XP 32bit OS.

Solution:
Use the standard MS tool to format the USB Thumb drive [1].
It will failed at the 100% with an error message saying:


Status: Files copied successfully. However, we were unable to run bootsect to make the USB device
bootable. If you need assistance with bootsect ....#truncated#


Download and install the EasyBCD for your WinXP 32bit [2].
The installation will copy the bootsect.exe tool that can be used on winXP.

Run the bootsect.exe to make the USB Thumb drive bootable. The 'E:' is the driver letter assign by your XP!

C:\Program Files\NeoSmart Technologies\EasyBCD\bin>bootsect.exe /nt60 E:
Target volumes will be updated with BOOTMGR compatible bootcode.

E: (\\?\Volume{ba063d8e-7111-11e0-b640-aafb6b9edf9e})

    Successfully updated NTFS filesystem bootcode.

Bootcode was successfully updated on all targeted volumes.

As last, unmount the USB, reboot the system, change the BIOS and start the installation.

References:

[1] Windows 7 USB/DVD Download Tool

[2] EasyBCD

For troubleshooting purposes:
How To Boot And Install Windows 7 From USB Flash Drive

How to clone a partition to a remote NFS server

Problem description.
You formatted and re-partitioned your hard drive.
You have a partition of the size about 100GB that you dedicated to your OS.
The installation of your OS went fine as well as the installation of all your necessary drivers.

After all you would like to have a copy of your partition data that can quickly restore in a case something wrong happens.

Solution:
Download the SystemRescueCd ISO img file [1]
Create bootable USB thumb drive [2]
Boot the system using your USB thumb drive. Once it is fully loaded you will get bash command line access.

Mount your remote NFS site image repository:

# mkdir /tmp/nfs
# mount -t nfs -o nolock 192.168.0.X:/your/path /tmp/nfs

Copy and compress the partition while coping it out for backup purposes [3]. Copy the partition schema as well.

# For test purposes you can shortly run the partclone.dd with '-d' option
# it will create a log file in /var/log directory.
# But don't run it like that otherwise it will quickly fill your log partition

# partclone.dd -c -d -s /dev/sda1 -o - | bzip2 -1 -c > /tmp/nfs/sda1.winXP.32bit.img

# Once tested run without -d option
#
# partclone.dd -c -s /dev/sda1 -o - | bzip2 -1 -c > /tmp/nfs/sda1.winXP.32bit.img
# parted -l > /tmp/nfs/log.parted.l.txt
# parted -l -m > /tmp/nfs/log.parted.lm.txt
#
# to backup the partition table from the MBR sector (don't use it on GPT partitioned system)
# sfdisk -d > /tmp/nfs/log.sfdisk.d.txt
#
# umount /tmp/nfs

At the end unmount the NFS partition and we are ready to reboot the system.

Later on, as a security precaution create md5sums and some level of par2 recovery files if the image should have ever get corrupted.

# md5sum -b sda1.winXP.32bit.img > sda1.winXP.32bit.img.md5
# par2create -r3 sda1.winXP.32bit.img


References:

[1] SystemRescueCd

[2] Sysresccd-manual-en How to install SystemRescueCd on an USB-stick

[3] partclone.dd

man 5 nfs

par2 home page
man par2

Less tricks in linux on the bash command line

Some tricks that is worth to know when working on the linux bash cli that can save you a lot of time.

1. To tell less to normal print the raw control character of your stream you can use the '-r' or '-R' options.

$ ls -la --color | less -X 
total 3284
drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 ESC[0mESC[01;34m.ESC[0m
drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ESC[01;34m..ESC[0m
drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 ESC[01;34m.adobeESC[0m
drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 ESC[01;34m.ankiESC[0m

$ ls -la --color | less -X -r
total 3284
drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 .
drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ..
drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 .adobe
drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 .anki

2. To list only #n lines from the input with or without the raw characters being interpreted.

$ ls -la --color | cat -t | head -10
total 3284
drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 ^[[0m^[[01;34m.^[[0m
drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ^[[01;34m..^[[0m
drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 ^[[01;34m.adobe^[[0m
drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 ^[[01;34m.anki^[[0m

$ ls -la --color | head -10
total 3284
drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 .
drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ..
drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 .adobe
drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 .anki

3. To list files with line numbers.

$ less -N -X /etc/init.d/networking 
      1 #!/bin/sh -e
      2 ### BEGIN INIT INFO
      3 # Provides:          networking
      4 # Required-Start:    

$ ls -la --color | cat -n -t | head -5
     1 total 3284
     2 drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 ^[[0m^[[01;34m.^[[0m
     3 drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ^[[01;34m..^[[0m
     4 drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 ^[[01;34m.adobe^[[0m
     5 drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 ^[[01;34m.anki^[[0m

$ ls -la --color | cat -n | head -5
     1 total 3284
     2 drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 .
     3 drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ..
     4 drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 .adobe
     5 drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 .anki

Reference:

Monday, April 11, 2011

What does my bash ulimit function use to set/report the limitation of resources

Everyone knows the output from the 'ulimit' bash, builtin function. But what functionality actually this function uses to mange all of this.

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 20
file size               (blocks, -f) unlimited
pending signals                 (-i) 16382
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Let's find out if the 'strace' program come in handy for this job.

# let's create auxilary file we will use later
$ cat mylimits.sh
ulimit -a

$ strace bash mylimits.sh 1>/dev/null 2>/tmp/strace.out
$ tail -20 /tmp/strace.out 
getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0
write(1, "open files                      "..., 42) = 42
write(1, "pipe size            (512 bytes,"..., 39) = 39
getrlimit(RLIMIT_MSGQUEUE, {rlim_cur=800*1024, rlim_max=800*1024}) = 0
write(1, "POSIX message queues     (bytes,"..., 44) = 44
getrlimit(RLIMIT_RTPRIO, {rlim_cur=0, rlim_max=0}) = 0
write(1, "real-time priority              "..., 39) = 39
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
write(1, "stack size              (kbytes,"..., 42) = 42
getrlimit(RLIMIT_CPU, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
write(1, "cpu time               (seconds,"..., 47) = 47
getrlimit(RLIMIT_NPROC, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
write(1, "max user processes              "..., 47) = 47
getrlimit(RLIMIT_AS, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
write(1, "virtual memory          (kbytes,"..., 47) = 47
getrlimit(RLIMIT_LOCKS, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
write(1, "file locks                      "..., 47) = 47
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(255, "", 10)                       = 0
exit_group(0)                           = ?

So as we can see the limitations are managed by the 'getrlimit' function and enforced on the kernel level.

For more info about this take a look at man 2 setrlimit

For these who are not afraid of glibc library a quick look at they wrappers may help as well: glibc "Resource Usage And Limitation"

An obsolete kernel function man 3 ulimit

Sunday, April 10, 2011

How to filter and dump in clear text http requests and responses from the network dump using the cli program tshark

There are many programs that allow us to save network traffic into a file for later analyze. Once you have the file(s) we could like to quickly investigate the data inside and verify what we sent and what we revived.

If we are interested, let's say only in the HTTP traffic than the command line 'tshark' has only limited capabilities in a way to present us the data for review and investigation.

We can still play with the various options: '-Tfields' and multiple '-e' but still don't get the complete headers output.

The complete list that can be used with '-e' can be found here .
Alternatively we can experiment with the '-Tpdml' that will create alike XML file. But even with all this flexibility we still can't print a custom name header like in this curl request bellow:

curl -H "Rado: my_value" -v -o /tmp/page.html http://rtomaszewski.blogspot.com/2011/04/tshark-in-network-troubleshooting.html

To solve this little problem we have created a small program written in python. It takes the output from 'tshark -S -V' and parses it to present the data in a way we want.

Example how to use it:
# tshark -r /tmp/net.pcap -R http -V | parse.py -d
# tshark -r /tmp/net.pcap -R http -V | parse.py 
# tshark -nn -s0 -i any -w /tmp/net.pcap  -f tcp -R http -l -S -V | parse.py
# tshark -nn -s0 -i any -w /tmp/net.pcap  -f tcp -R http -l -S -V | parse.py -d

An example output from the 'parse.py' when running on the command line:

$ curl -H "Rado: my_value" -v -o /tmp/page.html http://rtomaszewski.blogspot.com/2011/04/tshark-in-network-troubleshooting.html 
* About to connect() to rtomaszewski.blogspot.com port 80 (#0)
*   Trying 209.85.229.132... connected
* Connected to rtomaszewski.blogspot.com (209.85.229.132) port 80 (#0)
> GET /2011/04/tshark-in-network-troubleshooting.html HTTP/1.1
> User-Agent: curl/7.19.7 (i486-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: rtomaszewski.blogspot.com
> Accept: */*
> Rado: my_value
> 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< ETag: "b6d5837e-31bb-4473-95af-da3c1d466295"
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Server: GSE
< Age: 1202
< Date: Sun, 10 Apr 2011 19:14:00 GMT
< Expires: Sun, 10 Apr 2011 19:14:00 GMT
< Last-Modified: Sun, 10 Apr 2011 19:03:05 GMT
< Cache-Control: public, must-revalidate, proxy-revalidate, max-age=0
< Transfer-Encoding: chunked
< 
{ [data not shown]
100 49993    0 49993    0     0  28925      0 --:--:--  0:00:01 --:--:-- 57529* Connection #0 to host rtomaszewski.blogspot.com left intact

* Closing connection #0
# tshark -nn -s0 -i wlan0 -w /tmp/net.pcap -R http -f tcp -S -V | ./parse.py  
Running as user "root" and group "root". This could be dangerous.
Capturing on wlan0
Internet Protocol, Src: 192.168.43.111 (192.168.43.111), Dst: 209.85.229.132 (209.85.229.132)
Transmission Control Protocol, Src Port: 38391 (38391), Dst Port: 80 (80), Seq: 1, Ack: 1, Len: 226
    [Stream index: 1]
    GET /2011/04/tshark-in-network-troubleshooting.html HTTP/1.1\r\n
    User-Agent: curl/7.19.7 (i486-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n
    Host: rtomaszewski.blogspot.com\r\n
    Accept: */*\r\n
    Rado: my_value\r\n

Internet Protocol, Src: 209.85.229.132 (209.85.229.132), Dst: 192.168.43.111 (192.168.43.111)
Transmission Control Protocol, Src Port: 80 (80), Dst Port: 38391 (38391), Seq: 49070, Ack: 227, Len: 1375
    [Stream index: 1]
    HTTP/1.1 200 OK\r\n
    Content-Type: text/html; charset=UTF-8\r\n
    ETag: "b6d5837e-31bb-4473-95af-da3c1d466295"\r\n
    X-Content-Type-Options: nosniff\r\n
    X-XSS-Protection: 1; mode=block\r\n
    Server: GSE\r\n
    Age: 1202\r\n
    Date: Sun, 10 Apr 2011 19:14:00 GMT\r\n
    Expires: Sun, 10 Apr 2011 19:14:00 GMT\r\n
    Last-Modified: Sun, 10 Apr 2011 19:03:05 GMT\r\n
    Cache-Control: public, must-revalidate, proxy-revalidate, max-age=0\r\n
    Transfer-Encoding: chunked\r\n

2 packets captured
The program can be downloaded form here: parse.py Additionally the source code of this short tool can be seen here:
#!/usr/bin/python 
#
## tested on python 2.6.5
#
# author : radoslaw tomaszewski

import sys
import re
import inspect


class ParseTsharkOut:
  no=0
  debugYes=0 
    
  ipRe=None
  tcpRe=None
  protRe=None
  
  ipInfo=[]
  tcpInfo=[]
  protInfo=[]
  
  auxStart=0
  tcpAuxStart=0

  protAux=1
  
  def __init__(self):
    self.ipRe="Internet Protocol,(.*)$"
    self.tcpRe=["Transmission Control Protocol,(.*)$", "    (\[Stream index:.*)$"]
    self.protRe=["Hypertext Transfer Protocol", "    ([^\[ ].*)$", "^$| *(\\\\r|\\\\n)"]
    
  def debug(self, s):
    if self.debugYes : 
      parent=inspect.stack()[1][3]
      #parent=inspect.stack()
      print("debug:[" + str(parent) + "] " +  s.rstrip())
  
  def usage(self):
    print("todo")   
  
  def ipParse(self,s):
    self.debug(s)

    tmp=re.match(self.ipRe, s)
#    tmp=re.match("..", s)
    if tmp is None :
       return 0
    else:
       self.ipInfo.append(tmp.group(0))
       return 1
       
  def tcpParse(self,s):
    self.debug(s)
    ret=0

    tmp=re.match(self.tcpRe[self.tcpAuxStart], s)
    if tmp is None :
       return 0
    else:
       self.tcpInfo.append(tmp.group(0))
       
       ret=self.tcpAuxStart
       self.tcpAuxStart=(self.tcpAuxStart + 1 ) % 2
       
       return ret
  
  def protParse(self,s):
    self.debug(s)

    if ( self.protAux ) :
       if re.match(self.protRe[0], s):
         self.protAux=0
         return 0
         
    else :
       if re.match(self.protRe[2], s):
         self.protAux=1
         self.show()
         return 1

       tmp=re.match(self.protRe[1], s)
       if tmp is None :
         return 0
       else:
         self.protInfo.append(tmp.group(0))
         return 0
    
  def parse(self, s):
    funcs=[self.ipParse, self.tcpParse, self.protParse]
    
    if funcs[self.auxStart](s):
      self.auxStart= ( self.auxStart + 1 ) % 3 
  
  def show(self):
    self.debug("start")
    
    for i in self.ipInfo:
      print(i)
      
    for i in self.tcpInfo:
      print(i)

    for i in self.protInfo:
      print(i)  
      
    print("")
      
    self.ipInfo=[]
    self.tcpInfo=[]
    self.protInfo=[]      
  
  def main(self):
    try:
      if sys.argv[1] == '-d':
        self.debugYes=1
        self.debug("debuging is turn on")
    except (IndexError):
      None 
      
    self.debug("main start")

    for l in sys.stdin:
      self.parse(l)  
      
    return 0  
      
  

if __name__ == "__main__":
        sys.exit(ParseTsharkOut().main())


aaa

tshark in network troubleshooting

As described in another of my posts, there is not good and elegant way of printing on stdout and to a file the data captured on the wire when using 'tcpdump'.

In help the 'tshark' that comes with the 'wireshark' packet sniffer comes handy to do the job in a simple and elegant way.

To capture all network packets and to write them to a file you would use a syntax similar to this one:

# tshark -nn -i any -w /tmp/net.pcap
Running as user "root" and group "root". This could be dangerous.
Capturing on Pseudo-device that captures on all interfaces
24

If you don't like the packet counter constantly being updated when tshark runs use the '-q' options like that:

# tshark -nn -i any -w /tmp/net.pcap.pcap -q

And finally when you want to observe the packet in live and in the same time have a raw copy of the network dump on your disk use the '-S' option like that:

# tshark -nn -i any -w /tmp/net.pcap.pcap -S
Running as user "root" and group "root". This could be dangerous.
Capturing on Pseudo-device that captures on all interfaces
  0.000000    127.0.0.1 -> 127.0.0.1    ICMP Echo (ping) request
  0.028908    127.0.0.1 -> 127.0.0.1    ICMP Echo (ping) request
  0.297138 192.168.122.1 -> 192.168.122.255 UDP Source port: 17500  Destination port: 17500
  1.036921    127.0.0.1 -> 127.0.0.1    ICMP Echo (ping) request
  2.045086    127.0.0.1 -> 127.0.0.1    ICMP Echo (ping) request
5 packets captured

After all, when you are done with the troubleshooting and need to convenience someone you can sent him the saved file /tmp/net.pcap for review.

More info
man tshark

Tuesday, April 5, 2011

How to understand Apache MPM processes during the starting phase

One of the great flexibility that comes with Apache HTTP server is its incredible modularity. But sometimes it take a little time and experimenting before you understand how your favourite MPM model works.

So let's take a look how many processes there are going to be created when we start Apache after not customized installation?

All descriptions and examples are based on the default configuration in the Ubuntu:

# cat /etc/lsb-release

DISTRIB_ID=Ubuntu

DISTRIB_RELEASE=10.04

DISTRIB_CODENAME=lucid

DISTRIB_DESCRIPTION="Ubuntu 10.04.1 LTS"

The installation itself is as simple as:

# aptitude install apache2

By default when you start Apache with its default config it will look like this:

# ps -AHl | egrep 'apach|httpd'
1 S     0 25528     1  0  80   0 -  1348 poll_s ?        00:00:00   apache2
5 S    33 25530 25528  0  80   0 -  1291 skb_re ?        00:00:00     apache2
5 S    33 25532 25528  0  80   0 - 56702 pipe_w ?        00:00:00     apache2
5 S    33 25533 25528  0  80   0 - 56702 pipe_w ?        00:00:00     apache2

A closer look at the configuration in /etc/apache2/apache2.conf reveals more then one section that could be in control of your http server. So which one is our?

# grep -B7 'IfModule mpm_prefork_module'  apache2.conf 

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves


# grep -A8 'IfModule mpm_'  apache2.conf 

    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0


# worker MPM
--

    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75 
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          150
    MaxRequestsPerChild   0

--

    StartServers          2
    MaxClients          150
    MinSpareThreads      25
    MaxSpareThreads      75 
    ThreadLimit          64
    ThreadsPerChild      25
    MaxRequestsPerChild   0



Well, if you paid attention when installing the server then you know what MPM you installed. If you don't remember than we can find this by running:

# apache2ctl -l
Compiled in modules:
  core.c
  mod_log_config.c
  mod_logio.c
  worker.c  < - - - this is the one we can customize
  http_core.c
  mod_so.c
From the doc Apache MPM worker we know what the above options should mean as well.

    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75 
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          150
    MaxRequestsPerChild   0

Base on line # 2 (StartServers) we should see 2 processes. But when you scroll up we can see 4! So what is going on there? To understand the situation we need to look at the processes and threads statistics together.
# ps -lFmC apache2
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN    RSS PSR STIME TTY          TIME CMD
1 - root     25528     1  0   -   - -  1348 -       2580   - Apr04 ?        00:00:00 /usr/sbin/apache2 -k start
1 S root         -     -  0  80   0 -     - poll_s     -   0 Apr04 -        00:00:00 -
5 - www-data 25530 25528  0   -   - -  1291 -       1784   - Apr04 ?        00:00:00 /usr/sbin/apache2 -k start
5 S www-data     -     -  0  80   0 -     - skb_re     -   0 Apr04 -        00:00:00 -
5 - www-data 25532 25528  0   -   - - 56736 -       2776   - Apr04 ?        00:00:00 /usr/sbin/apache2 -k start
5 S www-data     -     -  0  80   0 -     - pipe_w     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - inet_c     -   1 Apr04 -        00:00:00 -
5 - www-data 25533 25528  0   -   - - 56736 -       2768   - Apr04 ?        00:00:00 /usr/sbin/apache2 -k start
5 S www-data     -     -  0  80   0 -     - pipe_w     -   0 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - futex_     -   1 Apr04 -        00:00:00 -
1 S www-data     -     -  0  80   0 -     - inet_c     -   1 Apr04 -        00:00:00 -

At the end everything is as it suppose to be. From all the 4 Apache processes the first 2 are for management and communication and then the last 2 are actually the one we defined in our config file to process the client's requests. All lines with the 'futex' show as well that there is 25 worker threads in the last to processes so this is controlled by the parameter ThreadsPerChild and is correct as well.