導航:首頁 > 操作系統 > linux內核讀寫文件

linux內核讀寫文件

發布時間:2023-10-11 14:09:02

linux內核操作的主要命令及作用

cp命令
該命令的功能是將給出的文件或目錄拷貝到另一文件或目錄中,同MSDOS下的命令一樣,功能十分強大

語法: cp [選項] 源文件或目錄 目標文件或目錄

說明:該命令把指定的源文件復制到目標文件或把多個源文件復制到目標目錄中

-r 若給出的源文件是一目錄文件,此時cp將遞歸復制該目錄下所有的子目錄和文件

mv命令
用戶可以使用mv命令來為文件或目錄改名或將文件由一個目錄移入另一個目錄中。該命令如同MSDOS下的ren和move的組合

語法:mv [選項] 源文件或目錄 目標文件或目錄

rm命令
該命令的功能為刪除一個目錄中的一個或多個文件或目錄,它也可以將某個目錄及其下的所有文件及子目錄均刪除

rm命令的一般形式為:

rm [選項] 文件…

如果沒有使用-r選項,則rm不會刪除目錄

該命令的各選項含義如下:

-f 忽略不存在的文件,從不給出提示

-r 指示rm將參數中列出的全部目錄和子目錄均遞歸地刪除

Vi命令
插入模式
按「i」切換進入插入模式「insert mode」,按「i」進入插入模式後是從游標當前位置開始輸入文件
按「a」進入插入模式後,是從目前游標所在位置的下一個位置開始輸入文字
按「o」進入插入模式後,是插入新的一行,從行首開始輸入文字
從插入模式切換為命令行模式
按「ESC」鍵
查找字元
「/關鍵字」:先按「/」鍵,再輸入您想尋找的字元,如果第一次找的關鍵字不是您想要的,可以一直按「n」會往後尋找到您要的關鍵字為止
「?關鍵字」:先按「?」鍵,再輸入您想尋找的字元,如果第一次找的關鍵字不是您想要的,可以一直按「n」會往前尋找到您要的關鍵字為止
離開vi
「q」:按「q」就是退出,如果無法離開vi,可以在「q」後跟一個「!」強制離開vi
「qw」:一般建議離開時,搭配「w」一起使用,這樣在退出的時候還可以保存文件

mkdir命令
功能:創建一個目錄(類似MSDOS下的md命令)

語法:mkdir [選項] dir-name

說明:該命令創建由dir-name命名的目錄。要求創建目錄的用戶在當前目錄中(dir-name的父目錄中)具有寫許可權,並且dirname不能是當前目錄中已有的目錄或 文件名稱。

命令中各選項的含義為:

-p 可以是一個路徑名稱。此時若路徑中的某些目錄尚不存在, 加上此選項後, 系統將自動建立好那些尚不存在的目錄,即一次可以建立多個目錄

cd 命令
功能:改變工作目錄

語法:cd [directory]

說明:該命令將當前目錄改變至directory所指定的目錄。若沒有指定directory, 則回到用戶的主目錄。為了改變到指定目錄,用戶必須擁有對指定目錄的執行和讀許可權

ls 命令
功能: 列出目錄的內容,該命令類似於DOS下的dir命令

語法:ls [選項] [目錄或是文件]

對於每個目錄,該命令將列出其中的所有子目錄與文件。對於每個文件,ls將輸出 其文件名以及所要求的其他信息。默認情況下,輸出條目按字母順序排序。當未給出目錄名或是文件名時,就顯示當前目錄的信息。

命令中各選項的含義如下:
-a 顯示指定目錄下所有子目錄與文件,包括隱藏文件
-c 按文件的修改時間排序
-t 顯示時按修改時間(最近優先)而不是按名字排序。若文件修改時間相同,則 按字典順序。修改時間取決於是否使用了c或u選頂。預設的時間標記是最後一次修改時間

tar命令
tar可以為文件和目錄創建檔案。利用tar,用戶可以為某一特定文件創建檔案(備份文件),也可以在檔案中改變文件,或者向檔案中加入新的文件。tar最初被用來在磁帶上創建檔案,現在,用戶可以在任何設備上創建檔案,如軟盤。利用tar命令,可以把一大堆的文件和目錄全部打包成一個文件,這對於備份文件或將幾個文件組合成為一個文件以便於網路傳輸是非常有用的。Linux上的tar是GNU版本的。

語法:tar [主選項+輔選項] 文件或者目錄

使用該命令時,主選項是必須要有的,它告訴tar要做什麼事情,輔選項是輔助使用的,可以選用。

主選項:

-c 創建新的檔案文件。如果用戶想備份一個目錄或是一些文件,就要選擇這個選項。

-x 從檔案文件中釋放文件。

-f 使用檔案文件或設備,這個選項通常是必選的。

-v 詳細報告tar處理的文件信息。如無此選項,tar不報告文件信息。

-z 用gzip來壓縮/解壓縮文件,加上該選項後可以將檔案文件進行壓縮,但還原時也一定要使用該選項進行解壓縮

文件或目錄的訪問許可權
Linux系統中的每個文件和目錄都有訪問許可許可權,用它來確定誰可以通過何種方式對文件和目錄進行訪問和操作
文件或目錄的訪問許可權分為只讀,只寫和可執行三種。以文件為例,只讀許可權表示只允許讀其內容,而禁止對其做任何的更改操作。可執行許可權表示允許將該文件作為一個程序執行。文件被創建時,文件所有者自動擁有對該文件的讀、寫和可執行許可權,以便於對文件的閱讀和修改。用戶也可根據需要把訪問許可權設置為需要的任何組合

有三種不同類型的用戶可對文件或目錄進行訪問:文件所有者,同組用戶、其他用戶。所有者一般是文件的創建者。所有者可以允許同組用戶有權訪問文件,還可以將文件的訪問許可權賦予系統中的其他用戶。在這種情況下,系統中每一位用戶都能訪問該用戶擁有的文件或目錄

每一文件或目錄的訪問許可權都有三組,每組用三位表示,分別為文件屬主的讀、寫和執行許可權;與屬主同組的用戶的讀、寫和執行許可權;系統中其他用戶的讀、寫和執行許可權。當用ls -l命令顯示文件或目錄的詳細信息時,最左邊的一列為文件的訪問許可權。

例如:
$ ls -l sobsrc. tgz
-rw-r–r– 1 root root 483997 Ju1 l5 17:3l sobsrc. tgz
橫線代表空許可。r代表只讀,w代表寫,x代表可執行。注意這里共有10個位置。第一個字元指定了文件類型。在通常意義上,一個目錄也是一個文件。如果第一個字元是橫線,表示是一個非目錄的文件。如果是d,表示是一個目錄

例如:
- rw- r– r–
普通文件 文件主 組用戶 其他用戶
是文件sobsrc.tgz 的訪問許可權,表示sobsrc.tgz是一個普通文件;sobsrc.tgz的屬主有讀寫許可權;與sobsrc.tgz屬主同組的用戶只有讀許可權;其他用戶也只有讀許可權。

chmod 命令
chmod命令是非常重要的,用於改變文件或目錄的訪問許可權。用戶用它控制文件或目錄的訪問許可權。
該命令有兩種用法。一種是包含字母和操作符表達式的文字設定法;另一種是包含數字的數字設定法。

文字設定法

chmod [who] [+ | - | =] [mode] 文件名

命令中各選項的含義為:

操作對象who可是下述字母中的任一個或者它們的組合:
u 表示「用戶(user)」,即文件或目錄的所有者。
g 表示「同組(group)用戶」,即與文件屬主有相同組ID的所有用戶。
o 表示「其他(others)用戶」
a 表示「所有(all)用戶」。它是系統默認值。

操作符號可以是:
+ 添加某個許可權。
- 取消某個許可權。
= 賦予給定許可權並取消其他所有許可權(如果有的話)

設置mode所表示的許可權可用下述字母的任意組合:
r 可讀
w 可寫
x 可執行

X 只有目標文件對某些用戶是可執行的或該目標文件是目錄時才追加x 屬性。

s 在文件執行時把進程的屬主或組ID置為該文件的文件屬主。方式「u+s」設置文件的用戶ID位,「g+s」設置組ID位。

t 保存程序的文本到交換設備上。

u 與文件屬主擁有一樣的許可權。

g 與和文件屬主同組的用戶擁有一樣的許可權。

o 與其他用戶擁有一樣的許可權。

文件名:以空格分開的要改變許可權的文件列表,支持通配符
在一個命令行中可給出多個許可權方式,其間用逗號隔開。

例如:chmod g+r,o+r example
使同組和其他用戶對文件example 有讀許可權

chgrp命令
功能:改變文件或目錄所屬的組。

語法:chgrp [選項] group filename

該命令改變指定指定文件所屬的用戶組。其中group可以是用戶組ID,也可以是/etc/group文件中用戶組的組名。文件名是以空格分開的要改變屬組的文件列表,支持通配符。如果用戶不是該文件的屬主或超級用戶,則不能改變該文件的組。

該命令的各選項含義為:
-R 遞歸式地改變指定目錄及其下的所有子目錄和文件的屬組

chown 命令
功能:更改某個文件或目錄的屬主和屬組。這個命令也很常用。例如root用戶把自己的一個文件拷貝給用戶xu,為了讓用戶xu能夠存取這個文件,root用戶應該把這個文件的屬主設為xu,否則,用戶xu無法存取這個文件。

語法:chown [選項] 用戶或組 文件

說明:chown將指定文件的擁有者改為指定的用戶或組。用戶可以是用戶名或用戶ID。組可以是組名或組ID。文件是以空格分開的要改變許可權的文件列表,支持通配符。

該命令的各選項含義如下:
-R 遞歸式地改變指定目錄及其下的所有子目錄和文件的擁有者
-v 顯示chown命令所做的工作

passwd命令
出於系統安全考慮,Linux系統中的每一個用戶除了有其用戶名外,還有其對應的用戶口令。因此使用useradd命令增加時,還需使用passwd命令為每一位新增加的用戶設置口令;用戶以後還可以隨時用passwd命令改變自己的口令

該命令的一般格式為: passwd [用戶名] 其中用戶名為需要修改口令的用戶名。只有超級用戶可以使用「passwd 用戶名」修改其他用戶的口令,普通用戶只能用不帶參數的passwd命令修改自己的口令

該命令的使用方法如下:
輸入passwd< Enter>;
在new password:提示下輸入新的口令(在屏幕上看不到這個口令):
系統提示再次輸入這個新口令

su命令
它可以讓一個普通用戶擁有超級用戶或其他用戶的許可權,也可以讓超級用戶以普通用戶的身份做一些事情。普通用戶使用這個命令時必須有超級用戶或其他用戶的口令。如要離開當前用戶的身份,可以打exit

該命令的一般形式為: su [選項] [使用者帳號]

說明:若沒有指定使用者帳號,則系統預設值為超級用戶root。 該命令中各選項的含義分別為:
-c 執行一個命令後就結束
- 加了這個減號的目的是使環境變數和欲轉換的用戶相同
-m 保留環境變數不變

shutdown命令
shutdown 命令可以安全地關閉或重啟Linux系統,它在系統關閉之前給系統上的所有登錄用戶提示一條警告信息。該命令還允許用戶指定一個時間參數,可以是一個精確的時間,也可以是從現在開始的一個時間段。精確時間的格式是hh:mm,表示小時和分鍾;時間段由「+」和分鍾數表示。系統執行該命令後,會自動進行數據同步的工作

該命令的一般格式為: shutdown [選項] [時間] [警告信息] 命令中各選項的含義為:

-k 並不真正關機,而只是發出警告信息給所有用戶。

-r 關機後立即重新啟動。

-h 關機後不重新啟動。

-f 快速關機,重啟動時跳過fsck。

-n 快速關機,不經過init程序。

-c 取消一個已經運行的shutdown

需要特別說明的是,該命令只能由超級用戶使用

free命令
free命令的功能是查看當前系統內存的使用情況,它顯示系統中剩餘及已用的物理內存和交換內存,以及共享內存和被核心使用的緩沖區。

該命令的一般格式為: free [-b | -k | -m] 命令中各選項的含義如下:

-b 以位元組為單位顯示。

-k 以K位元組為單位顯示。

-m 以兆位元組為單位顯示

df命令
功能:檢查文件系統的磁碟空間佔用情況。可以利用該命令來獲取硬碟被佔用了多少空間,目前還剩下多少空間等信息

語法:df [選項]

說明:df命令可顯示所有文件系統對i節點和磁碟塊的使用情況。

該命令各個選項的含義如下:

-a 顯示所有文件系統的磁碟使用情況,包括0塊(block)的文件系統,如/proc文件系統。

-k 以k位元組為單位顯示。

-i 顯示i節點信息,而不是磁碟塊。

-t 顯示各指定類型的文件系統的磁碟空間使用情況。

命令
的英文原義為「disk usage」,含義為顯示磁碟空間的使用情況。

功能:統計目錄(或文件)所佔磁碟空間的大小。

語法: [選項] [Names…]

說明:該命令逐級進入指定目錄的每一個子目錄並顯示該目錄佔用文件系統數據塊(1024位元組)的情況。若沒有給出Names,則對當前目錄進行統計。

該命令的各個選項含義如下:

-s 對每個Names參數只給出佔用的數據塊總數。

date命令
date命令的功能是顯示和設置系統日期和時間。

該命令的一般格式為: date [選項] 顯示時間格式(以+開頭,後面接格式)

date 設置時間格式

命令中各選項的含義分別為:

-s datestr, –set datestr 設置datestr 描述的日期

注意:只有超級用戶才有許可權使用date命令設置時間,一般用戶只能使用date命令顯示時間。

ifconfig
作用
ifconfig用於查看和更改網路介面的地址和參數,包括IP地址、網路掩碼、廣播地址,使用許可權是超級用戶
格式
ifconfig -interface [options] address
主要參數
-interface:指定的網路介面名,如eth0和eth1
up:激活指定的網路介面卡
down:關閉指定的網路介面
address:設置指定介面設備的IP地址
netmask address:設置介面的子網掩碼
應用說明
ifconfig是用來設置和配置網卡的命令行工具。為了手工配置網路,這是一個必須掌握的命令。使用該命令的好處是無須重新啟動機器。

要賦給eth0介面IP地址207.164.186.2,並且馬上激活它,使用下面命令:

#fconfig eth0 210.34.6.89 netmask 255.255.255.128
該命令的作用是設置網卡eth0的IP地址、網路掩碼和網路的本地廣播地址。若運行不帶任何參數的ifconfig命令,這個命令將顯示機器所有激活介面的信息。帶有「-a」參數的命令則顯示所有介面的信息,包括沒有激活的介面。注意,用ifconfig命令配置的網路設備參數,機器重新啟動以後將會丟失

如果要暫停某個網路介面的工作,可以使用down參數:
#ifconfig eth0 down

netstat
作用
檢查整個Linux網路狀態
格式
netstat [-acCeFghilMnNoprstuvVwx][-A][–ip]
主要參數
-a–all:顯示所有連線中的Socket
-l–listening:顯示監控中的伺服器的Socket
-n–numeric:直接使用IP地址,而不通過域名伺服器
-p–programs:顯示正在使用Socket的程序識別碼和程序名稱
-t–tcp:顯示TCP傳輸協議的連線狀況
-u–udp:顯示UDP傳輸協議的連線狀況
-apn 查看開啟的埠
應用實例
netstat主要用於Linux察看自身的網路狀況,如開啟的埠、在為哪些用戶服務,以及服務的狀態等。此外,它還顯示系統路由表、網路介面狀態等。可以說,它是一個綜合性的網路狀態的察看工具。在默認情況下,netstat只顯示已建立連接的埠。如果要顯示處於監聽狀態的所有埠,使用-a參數即可:
#netstat -a

lsof
作用
顯示系統打開的文件
格式
lsof 〔options〕 filename
主要參數
lsof -a: 表示兩個參數都必須滿足時才顯示結果
lsof -c string: 顯示COMMAND列中包含指定字元的進程所有打開的文件
lsof -u username: 顯示所屬user進程打開的文件
lsof -g gid: 顯示歸屬gid的進程情況
lsof +d /DIR/: 顯示目錄下被進程打開的文件
lsof +D /DIR/: 同上,但是會搜索目錄下的所有目錄,時間相對較長
lsof -d FD: 顯示指定文件描述符的進程
lsof -n: 不將IP轉換為hostname,預設是不加上-n參數
lsof -i: 用以顯示符合條件的進程情況
lsof -i:port: 查看埠運行的程序。
例如:查看22埠所運行的程序 #lsof -i:22

telnet
作用
telnet表示開啟終端機階段作業,並登入遠端主機。telnet是一個Linux命令,同時也是一個協議(遠程登陸協議)
格式
telnet [-8acdEfFKLrx][-b][-e][-k][-l][-n][-S][-X][主機名稱IP地址<通信埠>]

ftp
作用
ftp命令進行遠程文件傳輸。FTP是ARPANet的標准文件傳輸協議,該網路就是現今Internet的前身,所以ftp既是協議又是一個命令。
格式
ftp [-dignv][主機名稱IP地址]
應用說明
ftp命令是標準的文件傳輸協議的用戶介面,是在TCP/IP網路計算機之間傳輸文件簡單有效的方法,它允許用戶傳輸ASCⅡ文件和二進制文件。為了使用ftp 來傳輸文件,用戶必須知道遠程計算機上的合法用戶名和口令。這個用戶名/口令的組合用來確認ftp會話,並用來確定用戶對要傳輸的文件進行什麼樣的訪問。另外,用戶需要知道對其進行ftp會話的計算機名字的IP地址
用戶可以通過使用ftp客戶程序,連接到另一台計算機上;可以在目錄中上下移動、列出目錄內容;可以把文件從遠程計算機機拷貝到本地機上;還可以把文件從本地機傳輸到遠程系統中。ftp內部命令有72個,下面列出主要幾個內部命令:
ls:列出遠程機的當前目錄
cd:在遠程機上改變工作目錄
lcd:在本地機上改變工作目錄
close:終止當前的ftp會話
get(mget):從遠程機傳送指定文件到本地機
put(mput):從本地機傳送指定文件到遠程機
quit:斷開與遠程機的連接,並退出ftp

route
作用
route表示手工產生、修改和查看路由表
格式
#route [-add][-net|-host] targetaddress [-netmask Nm][dev]If]
#route [-delete][-net|-host] targetaddress [gw Gw] [-netmask Nm] [dev]If]
主要參數
-add:增加路由
-delete:刪除路由
-net:路由到達的是一個網路,而不是一台主機
-host:路由到達的是一台主機
-netmask Nm:指定路由的子網掩碼
gw:指定路由的網關
[dev]If:強迫路由鏈指定介面。
應用實例
route命令是用來查看和設置Linux系統的路由信息,以實現與其它網路的通信。要實現兩個不同的子網之間的通信,需要一台連接兩個網路的路由器,或者同時位於兩個網路的網關來實現
在Linux系統中,設置路由通常是為了解決以下問題:該Linux系統在一個區域網中,區域網中有一個網關,能夠讓機器訪問Internet,那麼就需要將這台機器的IP地址設置為Linux機器的默認路由。使用下面命令可以增加一個默認路由:
route add 0.0.0.0 192.168.1.1

top
作用
top命令用來顯示執行中的程序進程,使用許可權是所有用戶。
格式
top [-] [d delay] [q] [c] [S] [s] [i] [n]
主要參數
d:指定更新的間隔,以秒計算
q:沒有任何延遲的更新。如果使用者有超級用戶,則top命令將會以最高的優先序執行
c:顯示進程完整的路徑與名稱
i:不顯示任何閑置(Idle)或無用(Zombie)的行程
n:顯示更新的次數,完成後將會退出top。
說明
top命令是Linux系統管理的一個主要命令,通過它可以獲得許多信息。這里我們結合圖1來說明它給出的信息
下面列出了詳細解釋
PID(Process ID):進程標示號
USER:進程所有者的用戶名
PR:進程的優先順序別
NI:進程的優先順序別數值
VIRT:進程佔用的虛擬內存值
RES:進程佔用的物理內存值
SHR:進程使用的共享內存值
S:進程的狀態,其中S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值是負數
%CPU:該進程佔用的CPU使用率
%MEM:該進程佔用的物理內存和總內存的百分比
TIME+:該進程啟動後佔用的總的CPU時間
Command:進程啟動的啟動命令名稱,如果這一行顯示不下,進程會有一個完整的命令行。

❷ Linux系統I/O操作與零拷貝

Linux中傳統的I/O操作是一種緩存I/O,I/O過程中產生的數據傳輸通常需要在緩沖區中進行多次拷貝。當應用程序需要訪問某個數據(read()操作)時,操作系統會先判斷這塊數據是否在內核緩沖區中,如果在內核緩沖區中找不到這塊數據,內核會先將這塊數據從磁碟中讀出來放到內核緩沖區中,應用程序再從緩沖區中讀取。當應用程序需要將數據輸出(write())時,同樣需要先將數據拷貝到輸出堆棧相關的內核緩沖區,再從內核緩沖區拷貝到輸出設備中。

以一次網路請求為例,如下圖。對於一次數據讀取,用戶應用程序只需要調用read()及write()兩個系統調用就可以完成一次數據傳輸,但這個過程中數據經過了四次拷貝,且數據拷貝需要由CPU來調控。在某些情況下,這些數據拷貝會極大地降低系統數據傳輸的性能,比如文件伺服器中,一個文件從磁碟讀取後不加修改地回傳給調用方,那麼這佔用CPU時間去處理這四次數據拷貝的性價比是極低的。

一次處理網路調用的系統I/O的流程:

以上可以發現,傳統的Linux系統I/O 操作要進行4次內核空間與應用程序空間的上下文切換,以及4次數據拷貝。

直接內存訪問(Direct Memory Access,DMA)是計算機科學中的一種內存訪問技術,允許某些電腦內部的硬體子系統獨立地讀取系統內存,而不需要中央處理器(CPU)的介入。在同等程度的處理器負擔下,DMA是一種快速的數據傳送方式。這類子系統包括硬碟控制器、顯卡、網卡和音效卡。

在Linux系統中,當應用程序需要讀取文件中的數據時,操作系統先分配一些內存,將數據從存儲設備讀入到這些內存中,然後再將數據傳遞應用進程;當需要往文件中寫數據時,操作系統先分配內存接收用戶數據,然後再將數據從內存寫入磁碟。文件cache管理就是對這些由操作系統分配並用開存儲文件數據的內存的管理。

在Linux系統中,文件cache分為兩個層面,page cache 與 Buffer cache,每個page cache包含若干個buffer cache。操作系統中,磁碟文件都是由一系列的數據塊(Block)組成,buffer cache也叫塊緩存,是對磁碟一個數據塊的緩存,目的是為了在程序多次訪問同一個磁碟塊時減少訪問時間;而文件系統對數據的組織形式為頁,page cache為頁緩存,是由多個塊緩存構成,其對應的緩存數據塊在磁碟上不一定是連續的。也就是說buffer cache緩存文件的具體內容--物理磁碟上的磁碟塊,加速對磁碟的訪問,而page cache緩存文件的邏輯內容,加速對文件內容的訪問。

buffer cache的大小一般為1k,page cache在32位系統上一般為4k,在64位系統上一般為8k。磁碟數據塊、buffer cache、page cache及文件的關系如下圖:

文件cache的目的是加快對數據文件的訪問,同時會有一個預讀過程。對於每個文件的第一次讀請求,系統會讀入所請求的頁面並讀入緊隨其後的幾個頁面;對於第二次讀請求,如果所讀頁面在cache中,則會直接返回,同時又一個非同步預讀的過程(將讀取頁面的下幾頁讀入cache中),如果不在cache中,說明讀請求不是順序讀,則會從磁碟中讀取文件內容並刷新cache。因此在順序讀取情況下,讀取數據的性能近乎內存讀取。

DMA允許硬體子系統直接將數據從磁碟讀取到內核緩沖區,那麼在一次數據傳輸中,磁碟與內核緩沖區,輸出設備與內核緩沖區之間的兩次數據拷貝就不需要CPU進行調度,CPU只需要進行緩沖區管理、以及創建和處理DMA。而Page Cache/Buffer Cache的預讀取機制則加快了數據的訪問效率。如下圖所示,還是以文件伺服器請求為例,此時CPU負責的數據拷貝次數減少了兩次,數據傳輸性能有了較大的提高。

使用DMA的系統I/O操作要進行4次內核空間與應用程序空間的上下文切換,2次CPU數據拷貝及2次DMA數據拷貝。

Mmap內存映射與標准I/O操作的區別在於當應用程序需要訪問數據時,不需要進行內核緩沖區到應用程序緩沖區之間的數據拷貝。Mmap使得應用程序和操作系統共享內核緩沖區,應用程序直接對內核緩沖區進行讀寫操作,不需要進行數據拷貝。Linux系統中通過調用mmap()替代read()操作。

同樣以文件伺服器獲取文件(不加修改)為例,通過mmap操作的一次系統I/O過程如下:

通過以上流程可以看到,數據拷貝從原來的4次變為3次,2次DMA拷貝1次內核空間數據拷貝,CPU只需要調控1次內核空間之間的數據拷貝,CPU花費在數據拷貝上的時間進一步減少(4次上下文切換沒有改變)。對於大容量文件讀寫,採用mmap的方式其讀寫效率和性能都比較高。(數據頁較多,需要多次拷貝)

註:mmap()是讓應用程序空間與內核空間共享DMA從磁碟中讀取的文件緩沖,也就是應用程序能直接讀寫這部分PageCache,至於上圖中從頁緩存到socket緩沖區的數據拷貝只是文件伺服器的處理,根據應用程序的不同會有不同的處理,應用程序也可以讀取數據後進行修改。重點是虛擬內存映射,內核緩存共享。

djk中nio包下的MappedByteBuffer,官方注釋為 A direct byte buffer whose content is a memory-mapped region of a file,即直接位元組緩沖區,其內容是文件的內存映射區域。 FileChannel是是nio操作文件的類,其map()方法在在實現類中調用native map0()本地方法,該方法通過mmap()實現,因此是將文件從磁碟讀取到內核緩沖區,用戶應用程序空間直接操作內核空間共享的緩沖區,Java程序通過MappedByteBuffer的get()方法獲取內存數據。

MappedByteBuffer允許Java程序直接從內存訪問文件,可以將整個文件或文件的一部分映射到內存中,由操作系統進行相關的請求並將內存中的修改寫入到磁碟中。

FileChannel map有三種模式

MappedByteBuffer的應用,以rocketMQ為例(簡單介紹)。

procer端發送消息最終會被寫入到commitLog文件中,consumer端消費時先從訂閱的consumeQueue中讀取持久化消息的commitLogOffset、size等內容,隨後再根據offset、size從commitLog中讀取消息的真正實體內容。其中,commitLog是混合部署的,所有topic下的消息隊列共用一個commitLog日誌數據文件,consumeQueue類似於索引,同時區分開不同topic下不同MessageQueue的消息。

rocketMQ利用MappedByteBuffer及PageCache加速對持久化文件的讀寫操作。rocketMQ通過MappedByteBuffer將日誌數據文件映射到OS的虛擬內存中(PageCache),寫消息時首先寫入PageCache,通過刷盤方式(非同步或同步)將消息批量持久化到磁碟;consumer消費消息時,讀取consumeQueue是順序讀取的,雖然有多個消費者操作不同的consumeQueue,對混合部署的commitLog的訪問時隨機的,但整體上是從舊到新的有序讀,加上PageCache的預讀機制,大部分情況下消息還是從PageCache中讀取,不會產生太多的缺頁中斷(要讀取的消息不在pageCache中)而從磁碟中讀取。

rocketMQ利用mmap()使程序與內核空間共享內核緩沖區,直接對PageCache中的文件進行讀寫操作,加速對消息的讀寫請求,這是其高吞吐量的重要手段。

使用mmap能減少CPU數據拷貝的次數,但也存在一些問題。

從Linux2.1開始,Linux引入sendfile()簡化操作。取消read()/write(),mmap()/write()。

調用sendfile的流程如下:

通過sendfile()的I/O進行了2次應用程序空間與內核空間的上下文切換,以及3次數據拷貝,其中2次是DMA拷貝,1次是CPU拷貝。sendfile相比起mmap,數據信息沒有進入到應用程序空間,所以能減少2次上下文切換的開銷,而數據拷貝次數是一樣的。

上述流程也可以看出,sendfile()適合對文件不加修改的I/O操作。

sendfile()只是減少應用程序空間與內核空間的上下文切換,並沒有減少CPU數據拷貝的次數,還存在一次內核空間的兩個緩沖區的數據拷貝。要實現CPU零數據拷貝,需要引入一些硬體上的支持。在上一小節的sendfile流程中,數據需要從內核緩沖區拷貝到內核空間socket緩沖區,數據都是在內核空間,如果socket緩沖區到網卡的這次DMA數據傳輸操作能直接讀取到內核緩沖區中的數據,那麼這一次的CPU數據拷貝也就能避免。要達到這個目的,DMA需要知道存有文件位置和長度信息的緩沖區描述符,即socket緩沖區需要從內核緩沖區接收這部分信息,DMA需要支持數據收集功能。

sendfile()調用後,數據從磁碟文件拷貝到內核緩沖區中,然後將文件位置和長度信息的緩沖區描述符傳遞到socket緩沖區,此時數據並沒有被拷貝。之後網卡子系統根據socket緩沖區中的文件信息利用DMA技術收集拷貝數據。整個過程進行了2次內核空間和應用程序空間的上下文切換,及2次DMA數據拷貝,CPU不需要參與數據拷貝工作,從而實現零拷貝。當然DMA收集拷貝功能需要硬體和驅動程序的支持。

在操作系統中,硬體和軟體之間的數據傳輸可以通過DMA來進行,DMA進行數據傳輸的過程幾乎不需要CPU參與,但是在內核緩沖區(頁緩存)與應用程序緩沖區之間的數據拷貝並沒有類似於DMA之類的工具可以使用,mmap、sendfile都是為了減少數據在內核空間與應用程序空間傳輸時的數據拷貝和上下文切換次數,有效地改善數據在兩者之間傳遞的效率。

linux操作系統的零拷貝技術並不單指某一種方式,現有的零拷貝技術種類非常多,在不同的Linux內核版本上有不同的支持。常見的,如果應用程序需要修改數據,則使用mmap(),如果只進行文件數據傳輸,則可選擇sendfile()。

另外,關於零拷貝技術適用於什麼場景?在上述的描述中,數據在傳遞過程中,除了mmap外,應用程序和操作系統幾乎是沒有改變數據的,mmap的內存映射也是沒有改變數據的,也就是說在靜態資源的讀取場景下,零拷貝更能發揮作用。正如其名,拷貝是在不改變數據的情況下,零是利用手段去減少CPU參與數據拷貝的次數,以釋放CPU去進行其他系統調用與計算。

❸ linux 文件描述符最大是多少

人們常說linux最大有65536個文件描述符,是由於常用linux內核的默認值決定的,實際上是可以通過修改內核突破的。
了解下文件描述符,內核(kernel)利用文件描述符(file descriptor)來訪問文件。文件描述符是非負整數。打開現存文件或新建文件時,內核會返回一個文件描述符。讀寫文件也需要使用文件描述符來指定待讀寫的文件。
文件描述符的有效范圍是 0 到 OPEN_MAX。一般來說,每個進程最多可以打開 64 個文件(0 — 63)。對於 FreeBSD 5.2.1、Mac OS X 10.3 和 Solaris 9 來說,每個進程最多可以打開文件的多少取決於系統內存的大小,int 的大小,以及系統管理員設定的限制。Linux 2.4.22 強制規定最多不能超過 1,048,576 。

❹ Linux中編寫了內核模塊的C源程序之後怎麼編寫makefile文件的內容

linux內核的源代碼都在

的/pub/linux目錄下

軟體的源代碼在該一般項目主頁或發行版的「源」,或其他開源軟體的網站

❺ linux內核態,在LSM框架中的文件操作hook介面中如何獲取一個正在被操作的文件的內容(linux4.4版本)

LSM是Linux Secrity Mole的簡稱,即linux安全模塊。其是一種輕量級通用訪
問控制框架,適合於多種訪問控制模型在它上面以內核可載入模塊的形實現。用
戶可以根據自己的需求選擇合適的安全模塊載入到內核上實現。

LSM設計思想:
LSM的設計思想:在最少改變內核代碼的情況下,提供一個能夠成功實現強制訪
問控制模塊需要的結構或者介面。LSM避免了利用如在systrace系統調用中的出
現過的系統調用干預,因為它不能擴展到多處理器內核,並且它受制於參數替換
攻擊。還有LSM在設計時做了兩點考慮:對不使用的人來說盡量少引入麻煩,對
使用的人來說要帶來效率。以Linus Torvalds為代表的內核開發人員對Linux安

全模塊(LSM)提出了三點要求:
1、真正的通用,當使用一個不同的安全模型的時候,只需要載入一個不同的內
核模塊。
2、概念上簡單,對Linux內核影響最小,高效,並且。
3、能夠支持現存的POSIX.1e capabilities邏輯,作為一個可選的安全模塊。
還有,針對linux上提出的各種不同的Linux安全增強系統對Linux安全模塊(LSM
)提出的要求是:能夠允許他們以可載入內核模塊的形式重新實現其安全功能,

並且不會在安全性方面帶來明顯的損失,也不會帶來額外的系統開銷。
LSM框架結構:
LSM框架主要由五部分構成:
1、在特定的內核數據結構中加入安全域。
2、在內核源代碼中不同的關鍵點插入對安全鉤子函數的調用。
3、加入一個通用的安全系統調用。
4、提供了函數允許內核模塊注冊為安全模塊或者注銷。
5、5、將capabilities邏輯的大部分移植為一個可選的安全模塊。
安全域是一個void*類型的指針,它使得安全模塊把安全信息和內核內部對象聯
系起來。下面列出被修改加入了安全域的內核數據結構,以及各自所代表的內核

內部對象:
task_struct結構:代表任務(進程)
linux_binprm結構:代表程序
super_block結構:代表文件系統
inode結構:代表管道,文件,或者Socket套接字
file結構:代表打開的文件
sk_buff結構:代表網路緩沖區(包)
net_device結構:代表網路設備
kern_ipc_perm結構:代表Semaphore信號,共享內存段,或者消息隊列
msg_msg:代表單個的消息

Linux安全模塊(LSM)提供了兩類對安全鉤子函數的調用:一類管理內核對象的
安全域,另一類仲裁對這些內核對象的訪問。對安全鉤子函數的調用通過鉤子來
實現,鉤子是全局表security_ops中的函數指針,這個全局表的類型是
security_operations結構,這個結構定義在include/linux/security.h這個頭
文件中。
LSM介面的核心是security_ops,當系統啟動時,他們被初始化為傳統的DAC策略
。傳統DAC訪問控制是指控制系統中的主體(如進程)對系統中的客體(如文件
目錄、文件)的訪問(讀、寫和執行等)。自主訪問控制DAC 是指主體(進程,
用戶)對客體(文件、目錄、特殊設備文件、IPC等)的訪問許可權是由客體的屬
主或超級用戶決定的,而且此許可權一旦確定,將作為以後判斷主體對客體是否有

訪問許可權的依據。
在載入安全模塊時,我們必需先對模塊進行注冊,我們可以使用
register_security()函數向LSM注冊一個安全模塊。在我們的模塊被載入成
功後,就可以進行訪問控制操作。如果此時還有一個安全模塊要使用
register_security()函數進行載入,則會出現錯誤,直到使用
unregister_security()函數向框架注銷後,下一個模塊才可以載入。當然LS
M還提供了mod_reg_security()函數和mod_unreg_security()函數,可以連續注
冊多個安全模塊。如果有其他後來的模塊需要載入,可以通過mod_reg_security
()向第一個模塊注冊,形成支持不同策略的模塊棧。
註:以上出現的函數均基於2.6.22以前的版本,對於後續的版本,出現了
register_security()函數未被導出或者取消掉了unregister_security()函數。
LSM執行過程:
根據下圖的執行步驟:用戶在執行系統調用時,先通過原有的內核介面依次執行
功能性的錯誤檢查,接著進行傳統的DAC檢查,並在即將訪問內核的內部對象之
前,通過LSM鉤子函數調用LSM。LSM再調用具體的訪問控制策略來決定訪問的合
法性。圖三顯示了LSM鉤子的調用:

圖三:基於LSM的內核對象訪問過程

Lilinux安全模塊(LSM)主要支持"限制型"的訪問控制決策:當Linux內核授予
文件或目錄訪問許可權時,Linux安全模塊(LSM)可能會拒絕,而當 Linux內核拒
絕訪問時,可以跳過LSM。

========

使用LSM實現自己的訪問控制

首先對LSM 進行簡單介紹。雖然linux下的各位基本都知道一些,但是還要羅嗦
一下。
LSM中文全稱是linux安全模塊。英文全稱:linux security mole.
LSM是一種輕量級、通用的訪問控制框架,適合多種訪問控制模型以內核模塊的
形式實現。其特點是通用、簡單、高效、支持POSIX。1e能力機制。
LSM的架構圖如下:

通過系統調用進入內核之後,系統首先進行傳統的許可權檢查(傳統許可權檢查主要
是基於用戶的,用戶通過驗證之後就可以訪問資源),通過之後才會進行強制訪
問控制。(強制訪問控制是不允許主體干涉的一種訪問控制,其採用安全標識、
信息分級等信息敏感性進行訪問控制。並且通過比較主體的級別和資源的敏感性
來確定是否允許訪問。比如說系統設置A用戶不允許訪問文件B,即便A是文件B的
所有者,訪問也是受限制的。)從圖上看來,LSM實現訪問控制主要通過安全模
塊的鉤子函數實現。

LSM框架主要由五部分組成:這個網上資料很多。
在關鍵的特定內核數據結構中加入了安全域;
在內核源碼中不同的關鍵點處插入對安全鉤子函數的調用;
提供了一個通用的安全系統調用;
提供了注冊和注銷函數,使得訪問控制策略可以以內核模塊方式實現;
將capabilities邏輯的大部分功能移植為一個可選的安全模塊。

我們這里重點結合源碼對LSM框架進行解釋。我使用的源碼是3.5.4
首先介紹安全域欄位,它是一個空類型的指針,在內核中的很多內核結構中都存
在,比如inode、superblock、dentry、file等等。類型欄位為void *
security;
那麼安全域怎麼和安全模塊中的信息關聯起來?
當安全模塊載入之後,安全域中的指針便指向安全模塊中的安全信息。這里以
selinux為例進行介紹。
內核裡面security/selinux/include/objsec.h中定義了不同對象的安全信息,
格式為XXX_security_strut.

上面的文件的安全信息裡麵包含打開文件描述符時的安全ID、文件所有者的安全
ID等等。
要聯系安全模塊中安全信息和安全域需要幾個控制鉤子函數。這些鉤子函數實現
了對內核關鍵信息的設置和管理。這里主要介紹alloc_security、
free_security。
selinux裡面通過實現安全信息空間分配實現關聯。比如以文件安全信息為例
這里分配空間成功之後,通過file->f_security = fsec實現了關聯。
撤銷關聯是在安全模塊卸載之後調用file_free_security.

這里具體通過設置file->f_secrity為NULL,然後釋放安全信息結構實現。
現在來看看內核如何實現selinux的訪問控制。這里主要就是實現LSM裡面的鉤子
函數了。LSM裡面給出了結構體security_operations,裡面給出了很多鉤子函數
,實現了相關鉤子函數就可以實現訪問控制了。

上面的函數就實現了file_permission鉤子函數。可以看下inode結構體的獲得,
感受內核是通過文件->目錄項->inode。該函數主要實現自己的訪問控制策略就
OK 了。
哪selinux來說,在獲得文件安全ID之後,主要對掩碼和文件打開時相關的安全
信息進行檢測,符合就通過訪問控制。
selinux基本實現了LSM裡面的所有鉤子函數,待鉤子函數實現後,對LSM裡面鉤
子域進行填充就OK了。

做完以上這些還需要注冊安全模塊到LSM,這里注冊和注銷使用了
register_security和unregister_security。
比如selinux在注冊時使用語句register_security(&selinux_ops)實現。

接下來通過上面的分析我們可以實現簡單的基於LSM的訪問控制。
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mole.h>
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <linux/fcntl.h>
#include <linux/uaccess.h>
#include <linux/file.h>
#include <linux/namei.h>

static int lsm_test_file_permission(struct file *file,int mask)
{
int path=0;
struct file *filp;
struct nameidata nd;

path = path_lookup(FILENAME,LOOKUP_FOLLOW,&nd);

if(!mask)
return 0;

if(path)
{
printk("lookup file failed!\n");
return -1;
}

filp = filp_open("/home/yuyunchao/code/sb.c",O_RDONLY,0);
{
printk("open failed!\n");
}
return 0;
}

static struct security_operations lsm_test_security_ops = {
.file_permission = lsm_test_file_permission,
};

static int __init lsm_file_init(void)
{
if(register_security(&lsm_test_security_ops)){
printk("register error ..........\n");
return -1;
}

printk("lsm_file init..\n ");
return 0;
}

static void __exit lsm_file_exit(void)
{
if(unregister_security(&lsm_test_security_ops)){
printk("unregister error................\n");
return ;
}

printk("mole exit.......\n");
}

MODULE_LICENSE("GPL");
mole_init(lsm_file_init);
mole_exit(lsm_file_exit);
========

LSM(Linux Security Mole)應用方法(簡單例子)

LSM在內核中很多地方已經插入了hook函數,並且在security.c函數中聲明了
security_ops結構,要實現你自己的安全模塊,只需要定義你自己的struct
security_operations,並且用register_security注冊即可,下面舉個簡單例子

test.c代碼如下:
/*
* Test Linux Security Mole
*
* Author: penghuan <[email protected]>
*
* Copyright (C) 2010 UbuntuKylin, Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
*/

#include <linux/security.h>
#include <linux/sysctl.h>
#include <linux/ptrace.h>
#include <linux/prctl.h>
#include <linux/ratelimit.h>
#include <linux/workqueue.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/dcache.h>
#include <linux/path.h>

int test_file_permission(struct file *file, int mask)
{
char *name = file->f_path.dentry->d_name.name;
if(!strcmp(name, "test.txt"))
{
file->f_flags |= O_RDONLY;
printk("you can have your control code here!\n");
}
return 0;
}

static struct security_operations test_security_ops = {
.name = "test",

.file_permission = test_file_permission,
};

static __init int test_init(void)
{
printk("enter test init!\n");

printk(KERN_INFO "Test: becoming......\n")

if (register_security(&test_security_ops))
panic("Test: kernel registration failed.\n");

return 0;
}

security_initcall(test_init);

將該文件以模塊的形式放到security/下編譯進內核,啟用新的內核後,當你操
作文件test.txt時,通過dmesg命令就能再終端看到」you can have your
control code here!「輸出
所以一般的做法是:定義你自己的struct security_operations,實現你自己的
hook函數,具體有哪些hook函數可以查詢include/linux/security.h文件,然後
調用register_security來用你的test_security_ops初始化全局的security_ops
指針

樓主,我剛開始研究LSM,但網上資料太少,您這個代碼,我編譯成ko文件老是
有警告,並且insmod時,說Unknown symbol register_security。我最近看了看
內核模塊變成,沒有對內核進行太深入的了解。不知能否把LSM的實驗步驟給出
的再詳細點,謝謝。

你需要把代碼編進內核

是需要把那段源碼拷到內核目錄下,然後重新編譯內核?。。沒有不編譯內核的
方法嗎?。。直接按照模塊進行編譯。另外那個test.txt放在哪個文件夾里?。

是需要把那段源碼拷到內核目錄下,然後重新編譯內核?。。沒有不編譯內核的
方法嗎?。。直接按照模塊進行 ...

是的,你去網上找下怎麼把模塊編進內核,lsm模塊不能以模塊方式載入,涉及
安全;test.txt是測試文件,當你把代碼編進內核後,用新內核啟動,然後操作
test.txt文件,就會有輸出,test.txt隨便放哪裡

樓主,您好,我剛開始學習lsm模塊,把您的模塊編譯進內核,新的內核載入後
,register_security總是失敗,請問下可能是什麼原因導致的。我的內核版本
是3.13.11。

register_security的返回值是-11

========

LSM在Linux中的實現方式
LSM(Linux Secure Model)一種輕量級訪問控制機制.
其實現方式有如在系統調用中加入一個後門....
方式如下:
static struct file *__dentry_open(struct dentry *dentry, struct

vfsmount *mnt,
struct file *f,
int (*open)(struct inode *, struct file *),
const struct cred *cred)
{
struct inode *inode;
int error;
...............................................................
error = security_dentry_open(f, cred); //LSM機制實現方式,在此加入了

一個LSM函數.

//security_dentry_open的實現如下,相當於一個介面,對一個函數指針再

//封裝一下.

//只返回是與否,這樣的控制信息.
if (error)
goto cleanup_all;
................................................................
return f;
cleanup_all:
.................................................................
return ERR_PTR(error);
}
//========簡單封裝一個指針結構體===========================
int security_dentry_open(struct file *file, const struct cred *cred)
{
int ret;
ret = security_ops->dentry_open(file, cred);
if (ret)
return ret;
return fsnotify_perm(file, MAY_OPEN);
}

========

利用LSM實現更安全的linux

LSM的全稱是Linux Security Moles,它是linux內核中用來支持更靈活的

安全策略的一個底層框架,雖然聽起來比較復雜,但是可以就把它理解成一組安

插在linux內核的鉤子函數和一些預留的被稱為安全域的數據結構,下面先說說

這個框架的由來吧。

linux本身的機制就保證了linux擁有更好的安全機制,但是在這個機制下面

,還是隱藏了許多的問題:

1、許可權粒度太大。用過linux的人應該對0644這樣的訪問許可權設置不陌生,

它對能夠操作這個文件的用戶做了限制,但是這個只是限制到了組,而沒有更進

一步的細分,當然,如果LSM只是用來限制這個的話,那麼也就太沒意思了,因

為實現文件更細的控制粒度,ACL就能夠很出色的完成,順便提一下,ACL有一個

分配的限制,如果哪位朋友需要用ACL進行粒度更細的訪問許可權控制的話,可能

需要注意一下這方面的東西。

2、root用戶的許可權太大。在linux中,root用戶就是至高無上的,他擁有對

機器的完全控制許可權,可以做他想做的一切事情。但是很多時候,我們可能並不

希望有root有這么大的許可權,比如在現在比較流行的雲存儲中,用戶肯定不希望

服務提供商能夠隨意訪問我們的文件,那麼這個時候,就需要對root用戶進行一

定的設置了。

由於這些問題的存在,所以出現了像SE Linux(Securiy Enhanced Linux )

這樣的增強補丁。但是每個系統對於具體安全細節的控制不盡相同, 所以Linus

Tovalds 提出應該要有一個 Linux 內核所能接受的安全框架來支持這些安全策

略,這個安全框架應該提供包含內核數據結構中的透明安全域以及用來控制、維

護安全域操作的安全鉤子,於是就有了LSM。

LSM在內核中的位置,可以用下圖來表示:

當用戶態程序調用某些操作系統提供的函數的時候,比如read()函數,其會

對應於內核中的一個系統調用,然後該首先會進行一些常規的錯誤檢測,接著進

行DAC(Discretionary Access Control)檢測,再接著它會進行LSM檢測。從上

圖中能夠看出來,LSM其實是一個非常底層的安全策略框架,利用LSM,可以接管

所有的系統調用,這樣,我們就能對包括root在內的所有用戶的許可權進行控制,

並且實現粒度更細的訪問許可權控制。

當系統初始化的時候,LSM就是一個空的框架,它不提供任何的檢測,其所

做的全部工作幾乎就是返回0,當然,有些不帶返回值的函數除外。而我們則可

以針對自己特定的需求來編寫LSM,然後將我們編寫的LSM鉤子函數,通過其數據

結構struct security_operations注冊到系統中去,這樣,我們的LSM檢測就開

始起作用了。
更多信息可參考《Linux就該這么學》

閱讀全文

與linux內核讀寫文件相關的資料

熱點內容
pdf轉換成word免費版在線轉換 瀏覽:462
荒廢了三年還能做程序員嗎 瀏覽:656
阿里雲內網vpn伺服器 瀏覽:101
l命令第一個點對第二個點對不上 瀏覽:829
oracle導出表命令 瀏覽:909
怎麼寫域名加密 瀏覽:1003
手機文件壓縮出錯 瀏覽:522
如何登錄毒app 瀏覽:836
汽車中控台加密 瀏覽:862
海南農村信用社app如何開通簡訊 瀏覽:809
phpdns緩存 瀏覽:415
ipad騰訊視頻app如何播放本地視頻 瀏覽:990
蝦米伺服器關閉如何找到以前的歌 瀏覽:18
php自動建站 瀏覽:475
命令與征服3游俠網 瀏覽:970
騰訊雲買哪個地區伺服器 瀏覽:249
香港哪裡有app賣內地零食 瀏覽:684
編譯內核找不到工具鏈 瀏覽:453
java常見模式 瀏覽:504
典欣空調壓縮機 瀏覽:426