Zamykání souborů je mechanismus, který umožňuje přístup k souboru v kteroukoli konkrétní dobu pouze jednomu procesu. Pomocí mechanismu zamykání souborů může mnoho procesů číst/zapisovat jeden soubor bezpečnějším způsobem.
V tomto článku prozkoumáme různé typy zamykání souborů v systému Linux a pomocí příkladu programu pochopíme jejich rozdíly.
Použijeme následující příklad, abychom pochopili, proč je zamykání souborů vyžadováno.
- Proces „A“ otevře a přečte soubor, který obsahuje informace související s účtem.
- Proces „B“ také otevře soubor a přečte informace v něm.
- Nyní proces „A“ změní zůstatek účtu záznamu v jeho kopii a zapíše jej zpět do souboru.
- Proces „B“, který nemá žádný způsob, jak zjistit, že se soubor od posledního čtení změnil, má zastaralou původní hodnotu. Poté změní zůstatek účtu stejného záznamu a zapíše zpět do souboru.
- Nyní bude mít soubor pouze změny provedené procesem „B“.
Aby se předešlo těmto problémům, používá se zamykání k zajištění „serializace“.
Níže jsou uvedeny dva typy zamykání souborů Linux:
- Upozornění zamykání
- Povinné zamykání
1. Poradenské zamykání
Poradenské uzamčení vyžaduje spolupráci zúčastněných procesů. Předpokládejme, že proces „A“ získá zámek WRITE a začal zapisovat do souboru a proces „B“, aniž by se pokusil získat zámek, může soubor otevřít a zapisovat do něj. Proces „B“ je zde nespolupracující proces. Pokud se proces „B“ pokusí získat zámek, znamená to, že tento proces spolupracuje na zajištění „serializace“.
Poradenské zamykání bude fungovat pouze v případě, že zúčastněné procesy spolupracují. Poradenské zamykání někdy také nazývané jako „nevynucené“ zamykání.
2. Povinné zamykání
Povinné zamykání nevyžaduje spolupráci zúčastněných procesů. Povinné zamykání způsobuje, že jádro kontroluje každé otevření, čtení a zápis, aby ověřilo, že volající proces neporušuje zámek daného souboru. Více informací o povinném zamykání lze nalézt na kernal.org
Chcete-li povolit povinné zamykání v Linuxu, musíte jej povolit na úrovni souborového systému a také na jednotlivých souborech. Postup je následující:
- Připojte systém souborů pomocí možnosti „-o mand“
- Pro soubor lock_file zapněte bit set-group-ID a vypněte bit group-execute, abyste povolili povinné zamykání daného konkrétního souboru. (Tento způsob byl zvolen, protože když vypnete bit group-execute, set-group-ID pro něj nemá žádný skutečný význam)
Příklady zamykání souborů Linux
Abyste pochopili, jak to funguje, vytvořte si následující program file_lock.c:
#include <stdio.h> #include <fcntl.h> int main(int argc, char **argv) { if (argc > 1) { int fd = open(argv[1], O_WRONLY); if(fd == -1) { printf("Unable to open the file\n"); exit(1); } static struct flock lock; lock.l_type = F_WRLCK; lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = 0; lock.l_pid = getpid(); int ret = fcntl(fd, F_SETLKW, &lock); printf("Return value of fcntl:%d\n",ret); if(ret==0) { while (1) { scanf("%c", NULL); } } } }
Zkompilujte program pomocí gcc.
# cc -o file_lock file_lock.c
Znovu připojte kořenový souborový systém s volbou „mand“ pomocí příkazu mount, jak je ukázáno níže. To umožní povinné zamykání na úrovni systému souborů.
Poznámka:Abyste mohli provést níže uvedený příkaz, musíte být root.
# mount -oremount,mand /
Vytvořte 2 soubory s názvem „advisory.txt“ a „mandatory.txt“ v adresáři, kde je umístěn spustitelný soubor (zámek_souboru). Povolte Set-Group-ID a deaktivujte Group-Execute-Bit pro „mandatory.txt“ následovně
# touch advisory.txt # touch mandatory.txt # chmod g+s,g-x mandatory.txt
Uzamykání testovacího upozornění: Nyní spusťte ukázkový program s argumentem ‚advisory.txt‘.
# ./file_lock advisory.txt
Program bude čekat na vstup od uživatele. Z jiného terminálu nebo konzole vyzkoušejte následující
# ls >>advisory.txt
Ve výše uvedeném příkladu příkaz ls zapíše svůj výstup do souboru consulty.txt. I když získáme zámek zápisu, stále může do souboru zapisovat nějaký jiný proces ( Nespolupracující ). Toto se nazývá „poradní“ zamykání.
Test povinného zamykání: Znovu spusťte ukázkový program s argumentem ‘mandatory.txt’.
# ./file_lock mandatory.txt
Z jiného terminálu nebo konzole vyzkoušejte následující:
# ls >>mandatory.txt
Ve výše uvedeném příkladu bude příkaz ls čekat na odstranění zámku, než zapíše svůj výstup do souboru povinné.txt. Stále se jedná o nespolupracující proces, ale uzamčení je dosaženo pomocí povinného zamykání.