Saturday, May 31, 2008

Django|django crash problem - Size does matter — tomster.org

Size does matter — tomster.org

Size does matter

Filed Under:

From the obscure-obscenity-Department

Today, the Zope instance hosting this site experienced frequent crashes (as in "every couple of minutes) in the form of coredumps of the zope process. Stumped, bewildered, frustrated and near tears I did what I always do in such cases: pour my little heart out on #plone ;-)

Sure enough, help was at hand. And today's tip of the hat goes to... drumroll... lurker, who alerted me to the fact, that python needs explicit 'huge stack' suppport on FreeBSD. A bit of googling supported this view and so I reinstalled python from the ports, but first ran make config and then enabled HUGE_STACK_SIZE:


After that I ran a few stresstests with ab and the instance easily withheld several thousand requests for the front page. Why this option isn't enabled by default is beyond me. So keep that in mind, kids, when you install python on your BSD boxen: size does matter ;-) (As if the term 'huge stack size' wasn't already obscene enough without such a foot-in-mouth reference...)


Could this be a stack size problem?

On FreeBSD, the default stack size is configured smaller than in most other distributions. This already bites on a regular basis with Zope installations. (e.g. things like http://tomster.org/blog/archive/2006/09/27/size-does-matter)

From a current FreeBSD port /usr/ports/lang/python24/Makefile:

.if defined(WITHOUT_HUGE_STACK_SIZE)
CFLAGS+= -DTHREAD_STACK_SIZE=0x20000
.else
CFLAGS+= -DTHREAD_STACK_SIZE=0x100000
.endif # defined(WITHOUT_HUGE_STACK_SIZE)



Wyatt Baldwin wrote:

On 6/15/06, Philip Jenvey <pjen@groovie.org> wrote:

On Jun 15, 2006, at 6:56 PM, uuellbee wrote:

One known cause of core dumps on FreeBSD is when a python app needs a large stack size (this can be avoided by enabling the python port's HUGE_STACK_SIZE option), but since you're loading a simple app this can't be the problem.

I found some info on this and one suggestion was to #define THREAD_STACK_SIZE in thread_pthread.h. [See http://www.pythomnic.org/step_by_step.html.] I tried this instead of setting HUGE_STACK_SIZE because I'm compiling Python from source.

Here is the line I added:

#define THREAD_STACK_SIZE (0x100000)

Now when I visit the test site, it just keeps Loading... apparently forever. (It's been going in a another tab for a while now).

You might try switching the threading library via libmap.conf incase there's something strange related to threads.

I can't find libmap.conf on my system.

I tried compiling without threads, but something complained about not finding threads when I started the server. I also tried using the --with-pth option (GNU pth threading libraries), but that didn't change anything.

Otherwise to get some kind on information on why the core dump occurred you'll need to recompile python with debugging symbols. You can do this by putting the following line in /etc/make.conf prior to building the port:

CFLAGS=-g

Then you can run 'gdb python.core' and issue the 'bt' command to gdb to see a backtrace.

I'll recompile with the THREAD_STACK_SIZE hack removed and try this......

Here's what I get from running 'gdb ~/bin/python python.core': [Copyright, etc] This GDB was configured as "i386-marcel-freebsd"... Core was generated by `python'. Program terminated with signal 10, Bus error. [Bunch of lines of reading/loading symbols] #0 0x2825a31b in pthread_testcancel () from /usr/lib/libpthread.so.1

Here is the output of bt: #0 0x2825a31b in pthread_testcancel () from /usr/lib/libpthread.so.1 #1 0x28252902 in pthread_mutexattr_init () from /usr/lib/libpthread.so.1 #2 0x00000000 in ?? ()

This sounds pretty similar to this issue:

http://mail.python.org/pipermail/python-list/2005-April/276728.html

What's strange is he wasn't able to immediately reproduce the core dump while running python through GDB (mentioned here: http:// mail.python.org/pipermail/python-list/2005-February/265137.html ). You might want to also try what he did -- running python through gdb with the symbols enabled. Enabling the debugging symbols will hopefully provide a more thorough back trace and possibly explain why the larger thread stack size changed the behavior (I suspect there's a bigger problem that blows out the stack and the larger one simply postpones the problem).

Before doing that I would play with libmap.conf. There isn't an /etc/ defaults/libmap.conf, but there should be a man page for it on your system (libmap.conf(5)). You're currently using the libpthread threading library: what you want is to switch to the libthr library via libmap.conf (and hope the problem doesn't occur there).

I am currently doing this on a 7.0-CURRENT machine, and my libmap.conf looks like this:

libpthread.so.2 libthr.so.2 libpthread.so libthr.so

The version numbers are going to be different for FreeBSD 5.4. Check the man page aHUGE_STACK_SIZEnd google for more info/examples.

I'll take a deeper look into libmap. One thing that might be interesting is I installed Myghty by itself and had no problems, which would perhaps imply that the problem is somewhere in Paste (not that I really know what I'm talking about).

~wyatt

I never got around to messing around with gdb or libmap. I just set HUGE_STACK_SIZE in the FreeBSD Python port and everything works fine.

~wyatt

Thursday, May 29, 2008

Cygwin|Set SSH daemon in Cygwin on a Windows 2003 server

HOWTO setup the Cygwin SSH daemon on a Windows 2003 server

Installing the Cygwin SSH daemon

How to setup the secure shell daemon on a Windows 2003 server

Note : This set of instructions has worked for me at our institution. You should read /usr/share/doc/Cygwin/openssh.README after installing cygwin and check the cygwin mailing list if you encounter problems.

Installing and Testing cygwin

  • Create the destination folder (C:\cygwin or D:\cygwin as appropriate). Default permissions will be for administrators and SYSTEM only. Add SERVER\Users with modify control to the list. These permissions will be inherited to the rest of the folder as it is populated.
  • Create a directory to locally store the cygwin packages e.g. C:\temp\cygwinarchive. Open a browser window to the following URL http://www.cygwin.com/setup.exe and save the installation file setup.exe to the archive directory just created (C:\temp\cygwinarchive in this example)
  • Double click on the downloaded cygwin setup program. The current version is 2.510.2.2 (February 3rd, 2006). Click 'Next' and answer the prompts :
    • Leave default "install from internet"
    • Install to root directory c:\cygwin
    • leave default "install for all users"
    • leave default text file type "unix / binary"
    • Set local package directory to c:\temp\cygwinarchive (the directory created in the previous step). This should be the default.
    • Leave the default "direct connection"
    • Select a mirror (any of the ones with starting with http://mirror in the name). The package list will be downloaded.
    • The 'Select Packages' window can be stretched. Click on the plus sign to expand the categories. Install at least the following list of packages.
      • From Admin, select all packages.
      • From Archive, select unzip and zip packages.
      • From Base, leave the default, select all packages.
      • From Doc, leave the default, man and 'cygwin doc' packages.
      • From Editors, select vim package.
      • From Net, select openssh (openssl will get checked automatically), rsync and tcp_wrappers packages.
    • When you've selected these packages, click 'Next'. The installation tells you which packages it is installing as it progresses.
    • Uncheck 'Create desktop icon'. Leave default 'Add to start menu'. Click 'Finish'.
    • A post install script runs a few final commands. Then you should see a message saying 'Installation complete'. Click 'OK'.
  • Edit C:\cygwin\cygwin.bat. Make sure it contains these lines - you will need to add the line setting the CYGWIN environment variable.
    @echo off set CYGWIN=binmode tty ntsec C: chdir \cygwin\bin  bash --login -i 
  • Test cygwin to make sure it works. Start, Programs, Cygnus Solutions, Cygwin Bash Shell - should get a command window with a prompt saying 'Administrator@servername'. This is a bash shell and you can use unix or DOS / NT type commands e.g.
    • 'ls /bin' to see the cygwin bin directory
    • 'dir c:' to see the contents of the C: directory
    Type "control d" or "logout" to exit the shell.

  • If you get a message saying 'cannot create /home/userid', run this command from the cygwin window "mkpasswd -l >/etc/passwd".

  • While you're in the cygwin shell window, run this command to change the mount prefix from "/cygdrive" to "/". You should logout and back in again after running this command in order to reset your PATH environment variable properly.
    mount -s --change-cygdrive-prefix / 
  • Also, create a home directory where you can place user startup files. The default location is the "Documents and Settings" folder. Creating a /home directory and using the -p switch to assign the home directory when adding a new user keeps all the cygwin files under the c:\cygwin directory.
    mkdir -p /home 

Installing the SSH daemon service

  • From a cygwin prompt (Start, All Programs, Cygwin ?), run ssh-host-config to create the service, set up the ssh host keys and create the sshd_config file in /etc/. Note that 2 local users are created, one called sshd to handle privilege separation and one that is required on Windows 2003 called sshd_server that runs the service in order to use public key authentication. You should see output like this:
    $ ssh-host-config Generating /etc/ssh_host_key Generating /etc/ssh_host_rsa_key Generating /etc/ssh_host_dsa_key Overwrite existing /etc/ssh_config file? (yes/no) yes Generating /etc/ssh_config file Overwrite existing /etc/sshd_config file? (yes/no) yes Privilege separation is set to yes by default since OpenSSH 3.3. However, this requires a non-privileged account called 'sshd'. For more info on privilege separation read /usr/share/doc/openssh/README.privsep.  Should privilege separation be used? (yes/no) yes Warning: The following function requires administrator privileges! Should this script create a local user 'sshd' on this machine? (yes/no) yes Generating /etc/sshd_config file Added ssh to C:\WINDOWS\system32\drivers\etc\services   Warning: The following functions require administrator privileges!  Do you want to install sshd as service? (Say "no" if it's already installed as service) (yes/no) yes  You appear to be running Windows 2003 Server or later.  On 2003 and later systems, it's not possible to use the LocalSystem account if sshd should allow passwordless logon (e. g. public key authentication). If you want to enable that functionality, it's required to create a new account 'sshd_server' with special privileges, which is then used to run the sshd service under.  Should this script create a new local account 'sshd_server' which has the required privileges? (yes/no) yes  Please enter a password for new user 'sshd_server'.  Please be sure that this password matches the password rules given on your system. Entering no password will exit the configuration.  PASSWORD=xxxxxxx  User 'sshd_server' has been created with password 'xxxxxxxx'. If you change the password, please keep in mind to change the password for the sshd service, too.  Also keep in mind that the user sshd_server needs read permissions on all users' .ssh/authorized_keys file to allow public key authentication for these users!.  (Re-)running ssh-user-config for each user will set the required permissions correctly.   Which value should the environment variable CYGWIN have when sshd starts? It's recommended to set at least "ntsec" to be able to change user context without password. Default is "ntsec".  CYGWIN=binmode ntsec tty  The service has been installed under sshd_server account. To start the service, call net start sshd' or cygrunsrv -S sshd'.  Host configuration finished. Have fun! 
  • You can start the service from the services MMC panel, or using either of the commands listed above ("net start sshd" or "cygrunsrv -S sshd").

Generating public/private SSH keys for a user

  • If you need to generate ssh public and private keys for a user on this machine who will be uploading data or logging in to a remote machine, you will need to carry out this step. Sign on as the user who needs the keys created. They will automatically be in their home directory. Run ssh-user-config to setup the ssh keys. Create only an SSH2 RSA identity (use a null passphrase - just press return). Output should be similar to this :
       cygwinadmin@HICKORY ~    $ ssh-user-config    Shall I create an SSH1 RSA identity file for you? (yes/no) no    Shall I create an SSH2 RSA identity file for you? (yes/no)  (yes/no) yes    Generating /home/pswander/.ssh/id_rsa    Enter passphrase (empty for no passphrase):Press ENTER    Enter same passphrase again:Press ENTER    Do you want to use this identity to login to this machine? (yes/no) yes    Shall I create an SSH2 DSA identity file for you? (yes/no)  (yes/no) no     Configuration finished. Have fun! 
  • Update the file /home/userid/.ssh/authorized_keys with any public keys from other users who you wish to be able to connect to this user's account. Refer to this document for more information. Make sure each entry you add is all on one line.
  • Make sure the service is running (state 4 = running)
    $ sc query sshd  SERVICE_NAME: sshd          TYPE               : 10  WIN32_OWN_PROCESS           STATE              : 4  RUNNING                                  (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN))         WIN32_EXIT_CODE    : 0  (0x0)         SERVICE_EXIT_CODE  : 0  (0x0)         CHECKPOINT         : 0x0         WAIT_HINT          : 0x0 
  • Test the service from the cygwin prompt using "ssh -v localhost". You will get challenged with the new host key and will have to enter your password as you connect. You should see output like this:
    The authenticity of host 'localhost (127.0.0.1)' can't be established. RSA key fingerprint is 75:8a:67:20:0d:75:dd:06:64:04:d0:ac:23:c7:74:ba. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'localhost' (RSA) to the list of known hosts.  The last line is: You are successfully logged in to this server!!!  
  • Test the service from a remote host. You can now update the authorized_keys file with the public key file from the user and host you want to connect from. Then test your connection from that host by issuing the command "ssh userid@servername dir c:\"

Adding and removing users from the passwd file

  • You can add domain or local users using the mkpasswd command. Test what would be added for a domain user with this command:
    mkpasswd -d domain_name -u joeuser 
  • You can add an ads domain user to the passwd file and give him a home directory in /home with this command:
    mkpasswd -d ads -p /home -u kscully >>/etc/passwd 
  • You can add local users using the -l switch instead of the -d switch. Be careful not to use the -d domain_name switch without specifying a user or you will get entries for ALL doamin users in the passwd file.
  • Users can be removed and both users and groups can be updated by starting a cygwin shell and using vi to edit the /etc/passwd and /etc/group files.

Restricting SSH access to specific servers

Working on a netsh script to restrict access to specific servers.

cygrunsrv --install sshd --path '/usr/sbin/sshd' --env 'PATH=/bin;/sbin' --env 'CYGWIN=ntsec tty' -a -D

Switching the user who runs the service

In a normal installation, the ssh-host-config script creates a local user called sshd_server under whose credentials the ssh daemon runs. This is fine for local shell access to the server and secure file transfers to and from the server, but it is not possible to access any network resources while the service is running under the local user account.

The solution is to run the service under a domain user account - one that has access to the shares or servers remote from the server running sshd. In order to switch the service to run under a different user, these steps must be carried out :

  • Open "Computer Management", open the Services tab, right click on the "Cygwin sshd" service and stop the service.
  • Right click on the "Cygwin sshd" service again and select properties. Under the 'Log On' tab, switch the name of the account the service is running from ".\sshd_server" to domain\userid, where domain and userid correspond to a userid with access to the resources you require in the domain. You will be prompted for this user's password.
  • Open Control Panel -> Administratice Tools -> Local Security Settings -> Local Policies. Then click on 'User Rights Assignment'. Make sure the domain user you specified in step one is in the list for these 4 rights :
    1. Adjust memory quotas for a process
    2. Create a token object
    3. Log on as a service (already granted if you completed step 1)
    4. Replace a process level token
  • Add the domain user to the local password file
        mkpasswd -d domain -u userid >> /etc/passwd     
  • Change to ownership of the files required by the sshd service owner. Open a cygwin bash session and run these commands for your userid
        $ chown userid /var/log/sshd.log     $ chown -R userid /var/empty     $ chown userid /etc/ssh*     
  • In the services tab again, right click on the 'Cygwin sshd' service and select 'start'. Check the event log for a successful start, or for errors in case the service does not start successfully.

Wednesday, May 28, 2008

Proxy|Python code accross proxy

Python code accross proxy
=====================================
#!/usr/bin/env python
"""
Test read a htm from internet and across intranet proxy

"""

import sys
import getopt
import urllib2

def startTask():
proxy={
'user':'Stephen',
'pass':'pass',
'host':'proxy.com',
'port':8080
}

proxy_support = urllib2.ProxyHandler({"http":"http://%(user)s:%(pass)s@%(host)s:%(port)d" % proxy})
#proxy_support = urllib2.ProxyHandler({"http":"http://username:password@proxy.com:8080"})


opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler)

# install it
urllib2.install_opener(opener)

sock = urllib2.urlopen('http://www.python.org/')
print sock.headers
print sock.read()

if __name__ == "__main__":
startTask()

Friday, May 16, 2008

Raid|Raid 0+1 好還是 1+0 呢?

Raid 0+1 好還是 1+0 呢? at Hsiaoi Collection

Raid 0+1 好還是 1+0 呢?

Published at 2007, 八月 3日 in 科技.

Raid是什麼東西? 0+1 & 1+0 有什麼不同?
所謂的「RAID」,是「Redundant Array of Independent Disks 」的縮寫,也就是「獨立磁碟備援陣列」的意思。也有人將它說成「Redundant Array of Inexpensive Drives」﹙低價硬碟備援陣列﹚,當初RAID技術發表時用的是這個全名,不過現在則是前者的說法較多人採用。

其中「Redundant」是「過多、多餘」的意思,要組成一部磁碟機通常只需一顆硬碟,甚至一顆硬碟還能分割成許多磁碟區。但是在組RAID磁碟機時,要用上的硬碟比一顆還要「多」,也就是要用上2顆以上的硬碟。

因此RAID在實體上是多顆硬碟,在系統中被當作一顆硬碟使用,而在作業系統底下,也還是可以將它分割為單一或多個分割區。因此建立好的RAID, 使用起來跟單一硬碟是完全相同的,只是依組成方式的不同,RAID可以提供更大的容量、更高的讀寫效能,或是額外的「安全性」。﹙這裡所說的「安全性」, 是指硬碟損毀之後資料重建、回復的能力,與加密防駭等功能無關﹚

而且RAID的「容量、速度、安全性」加成之後的CP值,能夠遠遠高於相同效能表現的超高階硬碟,這才是許多玩家樂於採用的主因。RAID的組成方式很多,在進入我們的測試之前,先帶大家看看RAID的各種類別。

0+1 跟 1+0 差異?

RAID 0+1 是先 RAID 0(stripe)再 RAID 1(mirror), 如下圖:
01.jpg

RAID 1+0 是先 RAID 1(mirror)再 RAID 0(stripe), 如下圖:
10.jpg

這兩種 RAID 技術主要的差異在於 performance 及 reliability 的差別. 以下分幾種 disk failure 的 case 來討論. 每一[]表示一顆硬碟.

Case 1. 任何一顆硬碟損壞
RAID 0+1 : 另一個 stripe 可繼續運作, 但本身成為 SPOF.
RAID 1+0 : 兩個 segments 均可繼續運作, 所以無 SPOF 的 concern. (勝)

Case 2. 兩個 stripe/segment 各損壞一顆硬碟
RAID 0+1 : 兩個 stripes 都無法繼續運作.
RAID 1+0 : 兩個 segments 均可繼續運作, 所以無 SPOF 的 concern. (勝)

Case 3. 同一個 stripe/segment 損壞兩顆硬碟
RAID 0+1 : 另一個 stripe 可繼續運作, 但本身成為 SPOF.
RAID 1+0 : 若損壞的兩顆,屬於同一 mirror set, 則無法繼續運作(敗);若屬於不同 mirror set, 則兩個 segments 均可繼續運作, 所以無 SPOF 的 concern. (勝)

綜合以上分析, RAID 1+0 不是在所有的情況下, 它的 reliability 都優於 RAID 0+1, 但是在大部分的情況, RAID 1+0 的 reliability 是優於 RAID 0+1 的. 所以 RAID 0+1 適用於對 performance 的需求高於 reliability 的環境;RAID 1+0 則相反.

另外在 recovery 的情況, RAID 0+1 要重新 mirror 整個 stripe; 而 RAID 1+0 只要重新 mirror 一顆硬碟即可.

除了 performance 和 reliability 上的差異, 兩者在 poor scalability 和 high cost 的特性均相同.

JBOD (Just Bunch of Disks)

這種組成方式嚴格來說不算RAID,因為它的功能就跟它的全名一樣,「只是將多顆磁碟湊在一起」, 當作一顆超大硬碟來用。假設是4顆250GB的大硬碟,在JBOD模式下就成了一顆1TB﹙=1000GB﹚的超高容量硬碟,但是除了容量提升之外,它的 速度還是跟單一硬碟相同,也沒有額外的安全性。

RAID 0 (Striped)

這是最簡單也最猛的一種磁碟陣列,它的功能是在資料寫入時,將資料分割成幾個小區塊,分別存到各顆硬碟裡,因此可以提升寫入速度。當需要讀取時,再分別由所有硬碟裡將小區塊抓出來,所以也有較高的讀取速度。

但它的缺點是只要其中一顆硬碟壞掉,或只是小小的出點問題,都可能因為一小部分資料的不完整,就造成整個磁碟陣列無法正常讀取,全部的資料就這樣毀 於一旦,完全沒有安全性可言。儘管如此,RAID 0存取效能隨著組成硬碟數目增加而提升的特性,對於「效能至上」的玩家們還是有不小的吸引力。

RAID 1 (Mirrored)

這種磁碟陣列是將單一磁碟作「鏡射」(Mirror)的動作,也就是資料寫入時將相同的資料同時丟進兩顆硬碟,確保所有的資料都隨時存在另一個備 份。因為對單一硬碟寫入的資料量不變,所以寫入速度跟非RAID磁碟機沒有差別,不過在讀取時能同時由兩顆硬碟抓取資料,所以速度還是有所提升。

RAID 10 / 01 (Striped & Mirrored)

這是將RAID 0與RAID 1的架構作結合用的磁碟陣列,10與01的差別僅是先鏡射再分割資料,或是先分割再將資料鏡射到兩組硬碟,但功能是相同的,而且都需由4顆硬碟組成。這種 組法同時具備效能提升與資料備份的優點,只要不是「同組鏡射」的兩顆硬碟同時毀損,資料都可以救得回來。

RAID 2.3.4

這幾種RAID一直都沒有成為主流,也很少有硬體支援這幾種組法。它們都是由RAID 0改良而來,RAID 2是以位元為單位將資料分割寫入,並加入位元檢查用的錯誤修正碼(ECC),並以「漢明碼」來作資料編碼,單一磁碟毀損時可以藉此將故障硬碟的所有資料還原回來。

RAID 3則是改用的方式作資料編碼,並獨立使用一顆硬碟來存放同位檢查用的資料。而RAID 4同樣是以「同位元檢查」編碼、獨立硬碟存放檢查碼,但是資料的分割改回用資料區塊為單位。這兩種方式都至少需要3顆硬碟。

RAID 5 (Parity RAID)

RAID 5是由RAID 2.3.4改良而來,終於成為比較普及的一種架構。 它先將原始資料與同位檢查位元作組合,再以位元為單位分散存放在所有硬碟中,因此不需多用一部硬碟來存放檢查碼。但RAID 5實際上仍需一顆硬碟的容量來存放同位檢查碼,所以RAID整體的可用容量會等於總容量減去單顆硬碟容量,只是這個浪費的空間是分散在各顆硬碟中。RAID 5因為是分散的存取架構,因此效能提升明顯,而且任何一顆硬碟毀損,都還可以救得回來。 雖有浪費一顆硬碟容量的缺點,但是跟RAID 10 / 01一半的容量浪費相比,RAID 5單顆容量換得的安全性可說是相當划算。

各種RAID架構比較表

RAID方案

硬碟數

可用容量

效能

安全性

主要應用

JBOD

大於2

全部

不變

幾乎等於0

容量至上

RAID 0

大於2

全部

最高

危險

追求效能的狂熱玩家

RAID 1

2

總容量的50%

稍有提升

最高

完全不能出錯的資料備份

RAID 0+1

4以上的偶數

總容量的50%

極高

同時需要備份和效能,且預算無上限

RAID 5

3以上

N-1顆

讀快寫慢

同RAID 0+1但預算限制

原文參考: Sata Raid 完全攻略 )