| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
31 | 1 | 2 | 3 | 4 | 5 | 6 | |||
7 | 8 | 9 | 10 | 11 | 12 | 13 | |||
14 | 15 | 16 | 17 | 18 | 19 | 20 | |||
21 | 22 | 23 | 24 | 25 | 26 | 27 | |||
28 | 29 | 30 | 31 | 1 | 2 | 3 | |||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
private volatile long mask = 0xF; @Override public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) { if (!isStarted()) { return FilterReply.NEUTRAL; } // for performance reasons, skip change detection (MASK-1) times out of MASK. // Only once every MASK calls is change detection code executed // Note that MASK is a variable itself. if (((invocationCounter++) & mask) != mask) { return FilterReply.NEUTRAL; } long now = System.currentTimeMillis(); synchronized (configurationWatchList) { updateMaskIfNecessary(now); if (changeDetected(now)) { // Even though reconfiguration involves resetting the loggerContext, // which clears the list of turbo filters including this instance, it is // still possible for this instance to be subsequently invoked by another // thread if it was already executing when the context was reset. disableSubsequentReconfiguration(); detachReconfigurationToNewThread(); } } return FilterReply.NEUTRAL; }
這行 if (((invocationCounter++) & mask) != mask) {
mask = 0xf,其實要每循環 0xf 次,也就是 15 次,才會去 check 一次是否要更新,也就是說,不管過了多久,如果沒到這 15 次,也不會去檢查是否更新配置。
也就是說,我多打幾次 log,配置文件就生效了。
spring security(下簡寫為 ss)控制的安全主要有兩方面,Web 和 Method Call,這兩個方面的權限控制有比較多的相通的設計,也有一些特別的功能。比如 Method Call 可以做 After Invocation 控制,而 Web 可以做 Ip 地址控制。
這里面有兩個最基本的概念:authentication manager 和 access decision manager,前者控制認證,后都控制鑒權。
1. 在 ss 的認證系統中,默認的實現幫助我們提供了三個概念,用戶(user),角色(authority,一般存 role)和組(group),三者的關系是,組、角色與用戶都是多對多關系,組和角色間沒關系,默認是不啟用組的。后續,在 Acl 權限管理中,可以看到角色之間,是可以有包含(樹形?)關系的。
2. 在 ss 的鑒權系統中,明顯會比認證復雜得多。有 AccessDecisionManager, AccessDecisionVoter(前置), AfterInvocationProvider(后置), RoleHierarchy, SidRetrievalStrategy, LookupStrategy, PermissionGrantingStrategy, SecurityExpressionHandler, AclService, MutableAclService, AclCache 概念過多了,要一個一個解釋
a) 中心是 AccessDecisionManager,主要負責 AccessDecisionVoter 的管理,默認提供了3種實現:1. AffirmativeBased 如果有任何一個投票器允許訪問,請求將被立刻允許,而不管之前可能有的拒絕決定。2. ConsensusBased 多數票(允許或拒絕)決定了結果,平局的投票 和空票(全是棄權的)的結果是可配置的。3. UnanimousBased 所有的投票器必須全是允許的,否則訪問將 被拒絕。
AccessDecisionManager 在用于 Web 和 Method Call 兩種情況下,可能是不一致的,因為功能也不一致。
b) Method Call 除了使用 AccessDecisionManager 進行權限判斷外,還可以增加 AfterInvocationProvider 來進行出口數據的判斷,默認提供了 3 種。
1) PostInvocationAdviceProvider: 需要提供一個 PostInvocationAuthorizationAdvice,默認實現只有一個,就是 ExpressionBasedPostInvocationAdvice,可以通過 spel 來進行權限判斷。注意 ExpressionBasedPostInvocationAdvice 中需要提供一個 MethodSecurityExpressionHandler,能夠創建出一個 MethodSecurityExpressionOperations,放到 spel context 中,供 spel function 調用,這樣的方式,在后續很常見。
2) AclEntryAfterInvocationProvider 和 AclEntryAfterInvocationCollectionFilteringProvider : 這兩種都差不多,主要依賴 AclService, ObjectIdentityRetrievalStrategy, SidRetrievalStrategy 來配合,檢查返回值的權限。Collection 版本的,可以把無權限的數據去掉,只留下有權限的數據。
c) RoleHierarchy 提供了角色之間的關系,提供了兩個實現,一個是沒關系的,直接把 user 的 role 返回,另外一個是有繼承關系的。繼承關系實現挺有意思的,能夠處理多級的 include 關系,比較好用。
RoleHierarchy 的使用比較復雜,會被 AccessDecisionVoter, SidRetrievalStrategy, SecurityExpressionHandler 用到,SecurityExpressionHandler 又會被 AccessDecisionVoter 用到,所以還是有點兒混亂。
具體的說 SecurityExpressionHandler 會用到 PermissionEvaluator 和 RoleHierarchy,PermissionEvaluator 的一個實現 AclPermissionEvaluator 會用到 SidRetrievalStrategy。
d) SidRetrievalStrategy 和 RoleHierarchy 的功能比較接近,比 RoleHierarchy 高一個抽象層次,功能上也有所區別,是從一個 authentication 拿到所有相關的 Sid(包括 Role(GrantedAuthoritySid) 和 User(PrincipalSid)),而 RoleHierarchy 只包括了 Role(GrantedAuthoritySid)的繼承關系。
e) LookupStrategy 通過 ObjectIdentity 和 Sid 把相關的 Acl 查詢出來??梢栽?LookupStrategy 擴展 Acl 和 Ace 的功能,比如在 Ace 上面加上時間的條件限制,就需要自己定義 LookupStrategy,把時間條件從數據庫查詢出來,并放到自定義的 Ace 當中。
但這件事情非常麻煩,因為默認實現的 BasicLookupStrategy 是個 Final 的類,所以只能自己直接實現接口,無法使用現有的功能。
LookupStrategy 會生成 Acl,而最終的權限驗證是由 Acl 完成的,如果想驗證帶時間條件的 Ace,需要給 Acl 設置自定義的帶有檢查時間功能的 PermissionGrantingStrategy,實際上,這個 PermissionGrantingStrategy 會首先設置給 LookupStrategy,LookupStrategy 在創建 Acl 的時候,再放到 Acl 中去。
f) SecurityExpressionHandler 能夠執行 spel,得到是否可以訪問的結果,它的子類都是繼承自 AbstractSecurityExpressionHandler 的,有一個非常重要的方法是 SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, T invocation),創建一個 SecurityExpressionOperations 放到 EvaluationContext 中去,提供 spel 中執行的方法實現。比如 SecurityExpressionOperations 的一個抽象實現 SecurityExpressionRoot 中,就包含了大量的權限驗證方法,如 hasRole, hasPermission 等常用的功能。
g) AclService, MutableAclService, AclCache 概念比較簡單,AclService 是通過 LookupStrategy 查詢 Acl,自已可以查詢 ObjectIdentity 的父子關聯關系,MutableAclService 提供了修改的能力,AclCache 為 AclService 提供緩存,默認的實現了一個 EhCacheBasedAclCache。
3. ss 的鑒權模型 Sid, ObjectIdentity, Acl, Ace, Permission
a) Sid: 是中心,所有的授權會關聯在 Sid 上面,Sid 和之前的 Role Base Permission 會有些相同的地方,但也明顯不同,Sid 默認實現情況下,分為 GrantedAuthoritySid 和 PrincipalSid,其實就是 Role 和 User,通過 SidRetrievalStrategy 拿到一個 Authentication 的 Sid。
b) ObjectIdentity: 可以理解成 Resource,就是可訪問的目標資源,有 id 和 type 兩個字段,默認實現的 ObjectIdentityImpl 會直接調用目標 domainObject 的 getClass 和 getId 方法拿到兩個參數。在 PermissionEvaluator, AfterInvocationProvider 中,會用到 ObjectIdentityRetrievalStrategy 和 ObjectIdentityGenerator,ObjectIdentityRetrievalStrategy 會根據 domainObject 拿到 ObjectIdentity,然后使用 Acl 進行鑒權,ObjectIdentityGenerator 會在系統提供的不是 domainObject,而是 type, id 的時候,拿到 ObjectIdentity,然后進行 Acl 鑒權,這兩個接口有一個共同的實現 ObjectIdentityRetrievalStrategyImpl,如果需要在 ObjectIdentity 進行新的抽象,需要用新的實現,到得不同的 ObjectIdentity,比如將業務對象分類鑒權這樣的需求。
c) Acl, 每個 ObjectIdentity 最多對應一條 Acl,Acl 中包含了很多,包括 parental,說明 Acl 是有繼承關系的?其實不是,呵呵,是 ObjectIdentity 有繼承關系而已。有一個 ObjectIdentity,有很多 Sid,還有一個叫做 Owner 的 Sid,有從 LookupStrategy 傳過來的 PermissionGrantingStrategy,進行實際的鑒權,還有 AclAuthorizationStrategy 檢查有沒有權限進行 Acl security check。實現時間條件檢查,就擴展 PermissionGrantingStrategy。
為什么沒有 RoleHierarchy 或是 SidRetrievalStrategy 存在呢?是因為調用 Acl 進行權限檢查之前,已經把相關的 Sid 得到了,再給 Acl 的。
d) Ace, Permission: Ace 存儲 Sid, Permission,提供給 Acl 鑒權用。增加時間條件的話,最基本的,就是要在 Ace 中,增加時間條件字段。Permission 是用二進制存儲的,但默認實現的數據庫存儲并不是,是一個一條,存在數據庫里面的。
好吧,概念還是非常多的,不過鑒于權限控制本身就是個復雜的話題,ss 這些設計的我覺得已經非常好,也基本夠用了。
@import url(http://www.aygfsteel.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); Security.setProperty("ssl.SocketFactory.provider", "com.datayes.cloud.util.TrustAllSSLSocketFactory");主要完成了下面4個工作
1. 創建一個本地的目錄結構,以存放 rpm 包
2. 啟動一個 apache,使這些文件能夠遠程訪問
3. 寫一個 spec,并且用 rpmbuild 做成一個安裝包,用來在機器上安裝新的 repository 位置
4. 使用 yum downloadonly plugin 將需要的 rpm 包放到本地目錄下,然后使用 createrepo 命令創建 metadata
本來是希望能有一個類似于 nexus 這樣的 proxy host server 將遠程的 package cache 下來,找來找去,也找到了一個 nexus yum plugin,但這個 plugin 只支持手工的 deploy rpm package 到 nexus 上面,不能做 proxy 方式的。
寫寫步驟和遇到的問題吧。
[haha] name=haha baseurl=http://192.168.157.131/yum/centos/$releasever/$basearch/ enabled=1 gpgcheck=0
Summary: haha Name: haha Version: 0.1 Release: 1 Source0: haha Group: Applications/Internet License: GPLv2+ URL: http://192.168.157.131/yum/ #BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildArch: noarch
%description The haha yum repo #%prep #%setup -q %install mkdir -p $RPM_BUILD_ROOT/etc/yum.repos.d install -m 0644 -p %{SOURCE0} $RPM_BUILD_ROOT/etc/yum.repos.d
%clean rm -rf ${RPM_BUILD_ROOT} %files /etc/yum.repos.d/haha.repo
參考了
1. 自建yum源與制作RPM安裝包yum源
2. yum只下載rpm包不自動安裝方法
3. Installing Chef Server 0.10 in RHEL 6
ResultSet
By default, ResultSets are completely retrieved and stored in memory. In most cases this is the most efficient way to operate, and due to the design of the MySQL network protocol is easier to implement. If you are working with ResultSets that have a large number of rows or large values, and cannot allocate heap space in your JVM for the memory required, you can tell the driver to stream the results back one row at a time.
To enable this functionality, create a Statement
instance in the following manner:
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE);
The combination of a forward-only, read-only result set, with a fetch size of Integer.MIN_VALUE
serves as a signal to the driver to stream result sets row-by-row. After this, any result sets created with the statement will be retrieved row-by-row.
There are some caveats with this approach. You must read all of the rows in the result set (or close it) before you can issue any other queries on the connection, or an exception will be thrown.
The earliest the locks these statements hold can be released (whether they be MyISAM
table-level locks or row-level locks in some other storage engine such as InnoDB
) is when the statement completes.
If the statement is within scope of a transaction, then locks are released when the transaction completes (which implies that the statement needs to complete first). As with most other databases, statements are not complete until all the results pending on the statement are read or the active result set for the statement is closed.
Therefore, if using streaming results, process them as quickly as possible if you want to maintain concurrent access to the tables referenced by the statement producing the result set.
在 Eclipse 中執行下面代碼。
byte[] bytes = new byte[]{-16, -97, -116, -70};
String s = new String(bytes, "UTF-8");
System.out.println(s);
結果打印出了一朵花,呵呵,實在是太有意思了。
@import url(http://www.aygfsteel.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); Picasa 像冊真的很給力,2048 像素以下(包含)的照片不計算空間,據說 15 分鐘以內的也不算空間,除了這些,有1G的空間可以使用。SELinux全稱是Security Enhanced Linux,由美國國家安全部(National Security Agency)領導開發的GPL項目,它擁有一個靈活而強制性的訪問控制結構,旨在提高Linux系統的安全性,提供強健的安全保證,可防御未知攻擊,據稱相當于B1級的軍事安全性能。比MS NT所謂的C2等高得多。
應用SELinux后,可以減輕惡意攻擊或惡意軟件帶來的災難,并提供對機密性和完整性有很高要求的信息很高的安全保障。 SELinux vs Linux 普通Linux安全和傳統Unix系統一樣,基于自主存取控制方法,即DAC,只要符合規定的權限,如規定的所有者和文件屬性等,就可存取資源。在傳統的安全機制下,一些通過setuid/setgid的程序就產生了嚴重安全隱患,甚至一些錯誤的配置就可引發巨大的漏洞,被輕易攻擊。
而SELinux則基于強制存取控制方法,即MAC,透過強制性的安全策略,應用程序或用戶必須同時符合DAC及對應SELinux的MAC才能進行正常操作,否則都將遭到拒絕或失敗,而這些問題將不會影響其他正常運作的程序和應用,并保持它們的安全系統結構。
SELinux的配置相關文件都在/etc/selinux下,其中/etc/selinux/targeted目錄里就包含了策略的詳細配置和context定義,以下是主要文件及功用:
/etc/selinux/targeted/contexts/*_context 默認的context設置
/etc/selinux/targeted/contexts/files/* 精確的context類型劃分
/etc/selinux/targeted/policy/* 策略文件
Apache under SELinux - 讓Apache跑得順起來!
對于剛使用Redhat Enterprise Linux 4 或Fedora Core 2以上/CentOS 4的用戶,一定會為Apache經常無法正常運轉,報以"Permission denied"等錯誤而大為不解,甚至大為惱火。
其實這是因為這些系統里激活了SELinux,而用戶的apache配置與SELinux的配置策略有抵觸產生的,只有通過適當調整,使apache的配置和訪問符合策略才能正常使用。
現在下面來分析一下SELinux中有關httpd(apache)的context定義(略有刪節)
/home/[^/]+/((www)|(web)|(public_html))(/.+)? system_u:object_r:httpd_user_content_t
/var/www(/.*)? system_u:object_r:httpd_sys_content_t
/var/www/cgi-bin(/.*)? system_u:object_r:httpd_sys_script_exec_t
/usr/lib/cgi-bin(/.*)? system_u:object_r:httpd_sys_script_exec_t
/var/www/perl(/.*)? system_u:object_r:httpd_sys_script_exec_t
/var/www/icons(/.*)? system_u:object_r:httpd_sys_content_t
/var/cache/httpd(/.*)? system_u:object_r:httpd_cache_t
/etc/vhosts -- system_u:object_r:httpd_config_t
/usr/sbin/httpd -- system_u:object_r:httpd_exec_t
/usr/sbin/apache(2)? -- system_u:object_r:httpd_exec_t
/usr/sbin/suexec -- system_u:object_r:httpd_suexec_exec_t
/var/log/httpd(/.*)? system_u:object_r:httpd_log_t
/var/log/apache(2)?(/.*)? system_u:object_r:httpd_log_t
/var/log/cgiwrap\.log.* -- system_u:object_r:httpd_log_t
/var/cache/ssl.*\.sem -- system_u:object_r:httpd_cache_t
/var/cache/mod_ssl(/.*)? system_u:object_r:httpd_cache_t
/var/run/apache(2)?\.pid.* -- system_u:object_r:httpd_var_run_t
/var/lib/httpd(/.*)? system_u:object_r:httpd_var_lib_t
/var/lib/php/session(/.*)? system_u:object_r:httpd_var_run_t
/etc/apache-ssl(2)?(/.*)? system_u:object_r:httpd_config_t
/usr/lib/apache-ssl(/.*)? -- system_u:object_r:httpd_exec_t
/usr/sbin/apache-ssl(2)? -- system_u:object_r:httpd_exec_t
/var/log/apache-ssl(2)?(/.*)? system_u:object_r:httpd_log_t
/var/run/apache-ssl(2)?\.pid.* -- system_u:object_r:httpd_var_run_t
/var/run/gcache_port -s system_u:object_r:httpd_var_run_t
/var/lib/squirrelmail/prefs(/.*)? system_u:object_r:httpd_squirrelmail_t
/usr/bin/htsslpass -- system_u:object_r:httpd_helper_exec_t
/usr/share/htdig(/.*)? system_u:object_r:httpd_sys_content_t
/var/lib/htdig(/.*)? system_u:object_r:httpd_sys_content_t
針對上述的內容,可以對如下的幾個常見問題進行簡單處理:
1.phpmyadmin在非默認/var/www/html目錄下無法運轉
通常類似的情況都是在配置了虛擬主機時,訪問/phpmyadmin等提示403訪問拒絕,日志里也提示Permission denied,這是因為phpmyadmin防止的目錄及文件本身屬性不符合context要求。
假設phpmyadmin放在/web目錄下,那么執行:
chcon -R -t httpd_user_content_t /web
則會令/web及其下所有子目錄/文件,包括phpmyadmin文件都獲得了httpd_user_content_t的屬性,如果其傳統的Unix屬性對httpd來說是可讀的話,再重新訪問一下就應該可以了。
2./home目錄下的虛擬主機無法運轉
與問題1也是類似的,不過根據上文中context的定義,/home目錄下必須是用戶的$HOME/www或public_html或web目錄才是 httpd_user_content_t類型,因此建議將要作為web頁面的內容放置在用戶的$HOME/www或web或public_html里,并確保其屬性是httpd_user_content_t,使用如下命令查看:
ls -Z /home/abc/
drwxr-xr-x abc abc user_u:object_r:user_home_dir_t tmp
drwxrwxr-x abc abc user_u:object_r:httpd_user_content www
如不是,則可通過chcon來逐級目錄及文件更改,直至最后能訪問:
chcon -R -t httpd_user_content_t /home/abc/web
chcon -t user_home_dir_t /home/abc
3.CGI程序無法運行
如果cgi程序放在/var/www/cgi-bin/里也無法執行,遇到403或500錯誤的話,可以檢查cgi程序的屬性,按SELinux contexts文件里定義的,/var/www/cgi-bin/里必須是httpd_sys_script_exec_t 屬性。通過ls -Z查看,如果不是則通過如下命令更改:
chcon -t httpd_sys_script_exec_t /var/www/cgi-bin/*.cgi
如果是虛擬主機里的cgi,則參考問題2使之能正常使用普通的功能后,再通過chcon設置cgi文件的context為httpd_sys_script_exec_t即可。
4.Setuid/gid 程序無法運行
例如早期的SqWebMail及qmailadmin等,需要setuid/gid的支持,但在SELinux下這將受到嚴格限制。第一種方法是比較徹底的辦法,能保留系統的安全性,通過:
audit2allow -l -i /var/log/messages
將SELinux拒絕的信息轉換為相應的policy allow指令,將這些指令添加到SELinux policy 的src里相應的配置文件,重新生成policy并加載。但這樣做相對比較麻煩。
另一個方法最簡單,但將使apache得不到保護。首先確定SELinux 類型是targeted的:
cat /etc/selinux/config|grep SELINUXTYPE
然后,使apache脫離SELinux保護:
setsebool -P httpd_disable_trans 1
然后重啟動apache:
/etc/init.d/httpd restart
這樣所有apache強制的檢查都失效,需要setuid/gid的程序可以正常使用。但這樣帶來了增加漏洞的危險,對于迫切需要運行而又很急的情況,本方法是一個最大限度減少系統安全缺失的最后辦法。對于取消SELinux 未必是一個好方法。
一.
ps -Z
ls -Z
id -Z
例:
[root@ljj cgi-bin]# ls -Z
-rwxrwxrwx root root root:object_r:httpd_sys_script_exec_t a.cgi
-rw-r--r-- root root root:object_r:httpd_sys_script_exec_t a.txt
二. chcon
修改文件的屬性 fild1:fild2:fild3
chcon -u fild1 file
chcon -l fild2 file
chcon -t fild3 file
例:
chcon -u root file1
三.getsebool
獲取se相關的bool值
例:
[root@ljj cgi-bin]# getsebool -a | grep httpd
httpd_builtin_scripting --> inactive
httpd_disable_trans --> active
httpd_enable_cgi --> active
httpd_enable_homedirs --> active
httpd_ssi_exec --> active
httpd_tty_comm --> inactive
httpd_unified --> inactive
得到了一些與httpd相關的bool值,配置httpd.conf中的user_dir時,要保證這里的httpd_enable_homedirs是 active的,還要保證:
chcon -R -t httpd_sys_content_t ~user/public_html;
四. togglesebool
給se的相關bool值取反
例:
togglesebool httpd_enable_homedirs
本次操作環境:
Ubuntu Server 10.10
SCSI Harddisk:/dev/sda 500GB
U盤:/dev/sdb 8GB(模擬成USB Harddisk,安裝OS)
介紹2種分區表:
MBR分區表:(MBR含義:主引導記錄)
所支持的最大卷:2T (T; terabytes,1TB=1024GB)
對分區的設限:最多4個主分區或3個主分區加一個擴展分區。
GPT分區表:(GPT含義:GUID分區表)
支持最大卷:18EB,(E:exabytes,1EB=1024TB)
每個磁盤最多支持128個分區
所以如果要大于2TB的卷或分區就必須得用GPT分區表。
Linux下fdisk工具不支持GPT,得使用另一個GNU發布的強大分區工具parted。
fdisk工具用的話,會有下面的警告信息:
WARNING: GPT (GUID Partition Table) detected on '/dev/sda'! The util fdisk doesn't support GPT. Use GNU Parted.
下面是用parted工具對/dev/sda做GPT分區的過程:
root@node01:/mnt# parted /dev/sda
GNU Parted 2.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel gpt
Warning: The existing disk label on /dev/sda will be destroyed and all data on this disk
will be lost. Do you want to continue?
Yes/No? yes
(parted) print
Model: DELL PERC 6/i Adapter (scsi)
Disk /dev/sda: 500GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
(parted)mkpart primary 0KB 500GB
Warning: You requested a partition from 0.00B to 500GB.
The closest location we can manage is 17.4kB to 500GB.
Is this still acceptable to you?
Yes/No? yes
Warning: The resulting partition is not properly aligned for best performance.
Ignore/Cancel? Ignore
(parted) print
Model: DELL PERC 6/i Adapter (scsi)
Disk /dev/sda: 500GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
1 17.4kB 500GB 500GB primary
(parted)quit
Information: You may need to update /etc/fstab.
root@node01:/#fdisk -l
WARNING: GPT (GUID Partition Table) detected on '/dev/sda'! The util fdisk doesn't support GPT. Use GNU Parted.
Disk /dev/sda: 499.6 GB, 499558383616 bytes
255 heads, 63 sectors/track, 60734 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sda1 1 60735 487849983+ ee GPT
root@node01:/#mkfs.ext4 /dev/sda1
mke2fs 1.41.12 (17-May-2010)
文件系統標簽=
操作系統:Linux
塊大小=4096 (log=2)
分塊大小=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
30490624 inodes, 121962487 blocks
6098124 blocks (5.00%) reserved for the super user
第一個數據塊=0
Maximum filesystem blocks=4294967296
3722 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000
正在寫入inode表: 完成
Creating journal (32768 blocks): 完成
Writing superblocks and filesystem accounting information: 完成
This filesystem will be automatically checked every 24 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
root@node01:/#mount /dev/sda1 /export/glusterfs01/
root@node01:/# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/node01-root
6.8G 987M 5.5G 16% /
none 7.9G 208K 7.9G 1% /dev
none 7.9G 0 7.9G 0% /dev/shm
none 7.9G 32K 7.9G 1% /var/run
none 7.9G 0 7.9G 0% /var/lock
/dev/sdb1 228M 21M 196M 10% /boot
/dev/sda1 458G 198M 435G 1% /export/glusterfs01
root@node01:/#vi /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid -o value -s UUID' to print the universally unique identifier
# for a device; this may be used with UUID= as a more robust way to name
# devices that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc nodev,noexec,nosuid 0 0
/dev/mapper/node01-root / ext4 errors=remount-ro 0 1
# /boot was on /dev/sdb1 during installation
UUID=c21707ff-ba0f-43ee-819a-8e72fa0f8500 /boot ext2 defaults 0 2
/dev/mapper/node01-swap_1 none swap sw 0 0
/dev/sda1 /export/glusterfs01 ext4 defaults 0 2
重啟就可以自動掛載了!至此完成。
@import url(http://www.aygfsteel.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); 1. cross join 就是笛卡爾積
private void queryGroupSorted(int columnCount, ResultTarget result) {
int rowNumber = 0;
setCurrentRowNumber(0);
Value[] previousKeyValues = null;
while (topTableFilter.next()) {
setCurrentRowNumber(rowNumber + 1);
if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) {
rowNumber++;
Value[] keyValues = new Value[groupIndex.length];
// update group
for (int i = 0; i < groupIndex.length; i++) {
int idx = groupIndex[i];
Expression expr = expressions.get(idx);
keyValues[i] = expr.getValue(session);
}
if (previousKeyValues == null) {
previousKeyValues = keyValues;
currentGroup = New.hashMap();
} else if (!Arrays.equals(previousKeyValues, keyValues)) {
addGroupSortedRow(previousKeyValues, columnCount, result);
previousKeyValues = keyValues;
currentGroup = New.hashMap();
}
currentGroupRowId++;
for (int i = 0; i < columnCount; i++) {
if (groupByExpression == null || !groupByExpression[i]) {
Expression expr = expressions.get(i);
expr.updateAggregate(session);
}
}
}
}
if (previousKeyValues != null) {
addGroupSortedRow(previousKeyValues, columnCount, result);
}
}
http://en.wikipedia.org/wiki/Category:Unix_signals 1.SIGHUP信號 UNIX中進程組織結構為 session (會話)包含一個前臺進程組及一個或多個后臺進程組,一個進程組包含多個進程。一個session可能會有一個session首進程,而一個session首進程可能會有一個控制終端。一個進程組可能會有一個進程組首進程。進程組首進程的進程ID與該進程組ID相等。這兒是可能會有,在一定情況之下是沒有的。與終端交互的進程是前臺進程,否則便是后臺進程。
SIGHUP會在以下3種情況下被發送給相應的進程:
1、終端關閉時,該信號被發送到session首進程以及作為job提交的進程(即用 & 符號提交的進程)
2、session首進程退出時,該信號被發送到該session中的前臺進程組中的每一個進程
3、若父進程退出導致進程組成為孤兒進程組,且該進程組中有進程處于停止狀態(收到SIGSTOP或SIGTSTP信號),該信號會被發送到該進程組中的每一個進程。
系統對SIGHUP信號的默認處理是終止收到該信號的進程。所以若程序中沒有捕捉該信號,當收到該信號時,進程就會退出。
下面觀察幾種因終端關閉導致進程退出的情況,在這兒進程退出是因為收到了SIGHUP信號。login shell是session首進程。
首先寫一個測試程序,代碼如下:
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 程序中捕捉SIGHUP信號后打印一條信息,pause()使程序暫停。
編譯后的執行文件為sigtest。
1、命 令:sigtest front > tt.txt
操 作:關閉終端
結 果:tt.txt文件的內容為front : sighup received
原 因: sigtest是前臺進程,終端關閉后,根據上面提到的第1種情況,login shell作為session首進程,會收到SIGHUP信號然后退出。根據第2種情況,sigtest作為前臺進程,會收到login shell發出的SIGHUP信號。
2、命 令:sigtest back > tt.txt &
操 作:關閉終端
結 果:tt.txt文件的內容為 back : sighup received
原 因: sigtest是提交的job,根據上面提到的第1種情況,sigtest會收到SIGHUP信號。
3、命 令:寫一個shell,內容為[sigtest &],然后執行該shell
操 作:關閉終端
結 果:ps -ef | grep sigtest 會看到該進程還在,tt文件為空
原 因: 執行該shell時,sigtest作為job提交,然后該shell退出,致使sigtest變成了孤兒進程,不再是當前session的job了,因此sigtest即不是session首進程也不是job,不會收到SIGHUP。同時孤兒進程屬于后臺進程,因此login shell退出后不會發送SIGHUP給sigtest,因為它只將該信號發送給前臺進程。第3條說過若進程組變成孤兒進程組的時候,若有進程處于停止狀態,也會收到SIGHUP信號,但sigtest沒有處于停止狀態,所以不會收到SIGHUP信號。
4、命 令:nohup sigtest > tt
操 作:關閉終端
結 果:tt文件為空
原 因: nohup可以防止進程收到SIGHUP信號
至此,我們就清楚了何種情況下終端關閉后進程會退出,何種情況下不會退出。
要想終端關閉后進程不退出有以下幾種方法,均為通過shell的方式:
1、編寫shell,內容如下
trap "" SIGHUP #該句的作用是屏蔽SIGHUP信號,trap可以屏蔽很多信號
sigtest
2、nohup sigtest 可以直接在命令行執行,
若想做完該操作后繼續別的操作,可以 nohup sigtest &
3、編寫shell,內容如下
sigtest &
其實任何將進程變為孤兒進程的方式都可以,包括fork后父進程馬上退出。
2.SIGCHLD信號 子進程死后,會發送SIGCHLD信號給父進程。 一個進程在調用exit命令結束自己的生命的時候,其實它并沒有真正的被銷毀,而是留下一個稱為僵尸進程(Zombie)的數據結構(系統調用exit,它的作用是使進程退出,但也僅僅限于將一個正常的進程變成一個僵尸進程,并不能將其完全銷毀)。在Linux進程的狀態中,僵尸進程 是非常特殊的一種,它已經放棄了幾乎所有內存空間,沒有任何可執行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態等信息供其他進程收集,除此之外,僵尸進程不再占有任何內存空間。它需要它的父進程來為它收尸,如果他的父進程沒安裝SIGCHLD信號處理函數調用wait或waitpid()等待子進程結束,又沒有顯式忽略該信號,那么它就一直保持僵尸狀態,如果這時父進程結束了,那么init進程自動會接手這個子進程,為它收尸,它還是能被清除的。但是如果如果父進程是一個循環,不會結束,那么子進程就會一直保持僵尸狀態,這就是為什么系統中有時會有很多的僵尸進程。 2.SIGTERM信號 kill() 可以發 SIGTERM 過去;kill 命令默認也使用 SIGTERM 信號。 |
$ kill -l 列表中,編號為1 ~ 31的信號為傳統UNIX支持的信號,是不可靠信號(非實時的),編號為32 ~ 63的信號是后來擴充的,稱做可靠信號(實時信號)。不可靠信號和可靠信號的區別在于前者不支持排隊,可能會造成信號丟失,而后者不會。 下面我們對編號小于SIGRTMIN的信號進行討論。 1) SIGHUP 登錄Linux時,系統會分配給登錄用戶一個終端(Session)。在這個終端運行的所有程序,包括前臺進程組和后臺進程組,一般都屬于這個 Session。當用戶退出Linux登錄時,前臺進程組和后臺有對終端輸出的進程將會收到SIGHUP信號。這個信號的默認操作為終止進程,因此前臺進 程組和后臺有終端輸出的進程就會中止。不過可以捕獲這個信號,比如wget能捕獲SIGHUP信號,并忽略它,這樣就算退出了Linux登錄,wget也 能繼續下載。 此外,對于與終端脫離關系的守護進程,這個信號用于通知它重新讀取配置文件。 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 如果父進程沒有處理這個信號,也沒有等待(wait)子進程,子進程雖然終止,但是還會在內核進程表中占有表項,這時的子進程稱為僵尸進程。這種情 況我們應該避免(父進程或者忽略SIGCHILD信號,或者捕捉它,或者wait它派生的子進程,或者父進程先終止,這時子進程的終止自動由init進程來接管)。 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 在以上列出的信號中,程序不可捕獲、阻塞或忽略的信號有:SIGKILL,SIGSTOP 此外,SIGIO在SVR4是退出,在4.3BSD中是忽略;SIGCONT在進程掛起時是繼續,否則是忽略,不能被阻塞。 |