2018年1月25日 星期四

檔案與目錄的管理

每個檔案的參用係透過一個inode(資訊節點);inode即是一個實際的物件,
也是一個概念係實體(由Linux核心裡的一個資料結構來表示)inode可用來儲存與某個檔案有關的中介資料(metadata),例如檔案的存取權限、上一次的存取時間戳記、擁有者、群組、長度
以及檔案之資料的擺放位置但不包含檔案的名稱,
檔案名稱是存放在目錄項目(directory entry)

$ ls -i
       -i, --inode
              print the index number of each file
-------------------------------------------------------
stat, fstat, lstat - get file status
       int stat(const char *path, struct stat *buf);
       int fstat(int fd, struct stat *buf);
       int lstat(const char *path, struct stat *buf);

struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for filesystem I/O */ blkcnt_t st_blocks; /* number of 512B blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last status change */ };


Linux系統並未保存建立的時間
-------------------------------------------------------
chmod, fchmod - change permissions of a file

       int chmod(const char *path, mode_t mode);

       int fchmod(int fd, mode_t mode);

-------------------------------------------------------
chown, fchown, lchown - change ownership of a file
       int chown(const char *path, uid_t owner, gid_t group);
       int fchown(int fd, uid_t owner, gid_t group);
       int lchown(const char *path, uid_t owner, gid_t group);
-------------------------------------------------------
xattr - Extended attributes
提供一個機制可用於把鍵/值對(key/value pair)關聯到檔案
延伸屬性讓現有的檔案系統得以支援原始設計中未提供的功能
Think: 是否可以透過xattr來記檔案建立的時間!?
fatal error: attr/xattr.h: No such file or directory
apt-get install libattr1-dev
-------------------------------------------------------
目錄Directory包含了一串檔案名稱,每個檔案名稱會被對映到一個inode編號
每個名稱又稱為一個目錄項目(directory entry)
而且每個名稱至inode的映射稱為一個連結(link)
每個目錄包含兩個特殊目錄: 
.」dot(點)目錄用於參照目錄本身
..」dot-dot(點點)目錄則用於參照目錄的父目錄

getcwd, get_current_dir_name - get current working directory

       char *getcwd(char *buf, size_t size);

       char *get_current_dir_name(void);
如果buf為NULL,Linux的C函式庫會分配一個長度size個位元組的緩衝區,
而且會把當前工作目錄儲存在該處。如果size為0
C函式庫會分配一個足以儲存當前目錄的緩衝區
然後應用程式的責任是在它完成工作後,經由free()釋出緩衝區
雷同get_current_dir_name()

chdir, fchdir - change working directory
mkdir / rmdir - create / delete a directory

       int chdir(const char *path);

       int fchdir(int fd);

       int mkdir(const char *pathname, mode_t mode);

       int rmdir(const char *pathname);



opendir / readdir / closedir - open / read / close a directory

       DIR *opendir(const char *name);

       struct dirent *readdir(DIR *dirp);

       int closedir(DIR *dirp);



      //dirent結構代表一個目錄項目(directory entry)

           struct dirent
               ino_t                 d_ino;               /* inode number */
               off_t                  d_off;                /* not an offset; see NOTES */
               unsigned short d_reclen;          /* length of this record */
               unsigned char  d_type;             /* type of file; not supported
                                                                    by all filesystem types */
               char                 d_name[256];  /* filename */
           };

-------------------------------------------------------

硬連結(Hard Link)
可以把Hard Link當成源文件的副本,它顯示跟源文件一樣的大小但事實上卻不占任何空間。
並沒有另外建立一個inode,不可跨檔案系統
$ ln orig_file hardlink_file

符號連結(Symbolic Link)
可以把Symbolic Link當成快捷跨檔案系統
$ ln -s orig_file softlink_file
$ ls -i

2430961 -rw-rw-r-- 2 bh0322 bh0322    237 Jan 24 09:25 hardlink_file

2430951 lrwxrwxrwx 1 bh0322 bh0322   13 Jan 25 02:08 softlink_file -> orig_file

2430961 -rw-rw-r-- 2 bh0322 bh0322    237 Jan 24 09:25 orig_file

如果orig_file被刪除掉,softlink_file會找不到orig_file,hardlink_file不會受影響

link - make a new name for a file
symlink - make a new name for a file
unlink - delete a name and possibly the file it refers to
       int link(const char *oldpath, const char *newpath);
       int symlink(const char *oldpath, const char *newpath);
       int unlink(const char *pathname);
為了避免肆意破壞任何類型的檔案,C語言提供了remove()函式:
remove - remove a file or directory
       int remove(const char *pathname);
remove() deletes a name from the filesystem.  It calls unlink(2) for files, and rmdir(2) for directories.
-------------------------------------------------------
device node是存取硬體的標準機制
每個裝置節點會被指定兩個數值,稱為主要編號(major number)及次要編號(minor number)
這些主要和次要編號會映射至被載入核心的特定裝置驅動程式
特殊裝置節點:
1. crw-rw-rw- 1 root root 1, 3 Aug 28 02:23 /dev/null
核心會靜靜丟棄針對該裝置檔的所有寫入要求。(黑洞) 例如把 fd 0 1 2都導入黑洞
針對該裝置檔的所有的讀取要求,核心會傳回end-of-file (EOF)
(1) 重新導向
$ cat file 2>/dev/null
$ find / -name XXX 2>/dev/null
(2) 清空文件內容
$ cat /dev/null > file

2. crw-rw-rw- 1 root root 1, 5 Aug 28 02:23 /dev/zero
核心會靜靜丟棄針對該裝置檔的所有寫入要求。(dummy files or swap)
針對該裝置檔的所有的讀取要求,核心會傳回null位元組的無窮串流
(1) 產生一個特定大小的空白文件
$ dd if=/dev/zero of=test.txt bs=1k count=1 1+0 records in 1+0 records out 1024 bytes (1.0 kB) copied, 0.000159227 s, 6.4 MB/s

$ dd if=/dev/null of=test.txt bs=1k count=1 0+0 records in 0+0 records out 0 bytes (0 B) copied, 0.00011535 s, 0.0 kB/s
Difference between /dev/null and /dev/zero

3. crw-rw-rw- 1 root root 1, 7 Aug 28 02:23 /dev/full

亂數產生器
核心的亂數產生器會從裝置驅動程式以及其他源頭收集noise(雜亂的資料),
而且核心會把收集到的noise連結在一起,並且對它進行單向雜湊運算
所得到的結果然後會被存入一個熵集區(entropy pool)
核心會不斷估算集區中熵的位元數目
4. crw-rw-rw- 1 root root 1, 8 Aug 28 02:23 /dev/random
5. crw-rw-rw- 1 root root 1, 9 Aug 28 02:23 /dev/urandom 「unblocked」


$ dd if=/dev/random of=random.dat bs=1024b count=1
0+1 records in
0+1 records out
28 bytes (28 B) copied, 0.000360786 s, 77.6 kB/s


$ dd if=/dev/urandom of=urandom.dat bs=1024b count=1
1+0 records in
1+0 records out
524288 bytes (524 kB) copied, 0.0499055 s, 10.5 MB/s


-rw-rw-r-- 1 bh0322 bh0322      28 Jan 25 06:39 random.dat

-rw-rw-r-- 1 bh0322 bh0322 524288 Jan 25 06:40 urandom.dat
可以看到使用/dev/random產生隨機數的速度很慢,而且產生的量很有限,
當然,/dev/urandom的隨機效果則好很多。

(1) 產生亂數的IP位置
od -vAn -N4 -tu4 /dev/urandom

(2) 隨機MAC位置
dd if=/dev/urandom bs=1 count=6 2> /dev/null | od -t x1 | sed '2d;s/^0\+ //;s/ /:/g'


/proc/sys/kernel/random/ ├── boot_id ├── entropy_avail ├── poolsize ├── read_wakeup_threshold ├── urandom_min_reseed_secs ├── uuid └── write_wakeup_threshold

rand, rand_r, srand - pseudo-random number generator
C 裡面使用 rand() 可以產生變數。但是每次傳回的解果都是一樣的。
所以我們可以加上 srand(time(0)),藉由時間來取得亂數總子。
但這樣的亂數種子每秒變動一次。所以如果需要在一秒之內取得多個亂數則會有問題

int main()
{
   FILE *fp;
   int randno;

   if ((fp = fopen("/dev/urandom", "r")) == NULL) {
   fprintf(stderr, "Error! Could not open /dev/urandom for read\n");
    return -1;
   }

   randno = fgetc(fp);
   fclose(fp);

   return 0;
}

random, srandom, initstate, setstate - random number generator
getrandom - obtain a series of random bytes

getrandom() was introduced in version 3.17 of the Linux kernel. Support was added to glibc in version 2.25.
/*
* Add device- or boot-specific data to the input and nonblocking
* pools to help initialize them to unique values.
*
* None of this adds any entropy, it is meant to avoid the
* problem of the nonblocking pool having similar initial state
* across largely identical devices.
*/

void add_device_randomness(const void *buf, unsigned int size)

Bash內建變數
$ echo $RANDOM
-------------------------------------------------------
監控檔案事件
inotify可用於監控檔案-監視檔案何時被移動、讀取、寫入或刪除

沒有留言:

張貼留言