table of contents
- bookworm-backports 1:4.24.0-2~bpo12+1
- testing 1:4.24.0-2
- unstable 1:4.24.0-2
shmctl(2) | System Calls Manual | shmctl(2) |
NAZWA¶
shmctl - steruje segmentami pamięci dzielonej Systemu V
BIBLIOTEKA¶
Standardowa biblioteka C (libc, -lc)
SKŁADNIA¶
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
OPIS¶
shmctl() wykonuje operację określoną przez parametr cmd na segmencie pamięci dzielonej Systemu V o identyfikatorze shmid.
Parametr buf jest wskaźnikiem do struktury shmid_ds, zdefiniowanej następująco w <sys/shm.h>:
struct shmid_ds {
struct ipc_perm shm_perm; /* Prawa dostępu */
size_t shm_segsz; /* Rozmiar segmentu (w bajtach) */
time_t shm_atime; /* Czas ostatniego dołączenia */
time_t shm_dtime; /* Czas ostatniego odłączenia */
time_t shm_ctime; /* Czas utworzenia/ostatniej mody-
fikacji za pomocą shmctl() */
pid_t shm_cpid; /* PID twórcy segmentu */
pid_t shm_lpid; /* PID ostatniego shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* Liczba dołączeń */
... };
Pola struktury shmid_ds są następujące:
- shm_perm
- Jest to struktura ipc_perm (zob. niżej), która określa prawa dostępu do segmentu pamięci wspólnej.
- shm_segsz
- Rozmiar segmentu pamięci wspólnej w bajtach.
- shm_atime
- Czas ostatniego wykonania wywołania systemowego shmat(2), dołączającego ten segment.
- shm_dtime
- Czas ostatniego wykonania wywołania systemowego shmdt(2), odłączającego ten segment.
- shm_ctime
- Czas utworzenia segmentu lub czas ostatniej operacji IPC_SET shmctl().
- shm_cpid
- Identyfikator procesu, który utworzył ten segment pamięci wspólnej.
- shm_lpid
- Identyfikator procesu, który ostatni wykonał wywołanie systemowe shmat(2) lub shmdt(2).
- shm_nattch
- Liczba procesów, które dołączyły ten segment.
Struktura ipc_perm jest zdefiniowana następująco (wyróżnione pola można ustawić za pomocą IPC_SET):
struct ipc_perm {
key_t __key; /* Klucz podany w msgget() */
uid_t uid; /* Efektywny UID właściciela */
gid_t gid; /* Efektywny GID właściciela */
uid_t cuid; /* Efektywny UID twórcy */
gid_t cgid; /* Efektywny GID twórcy */
unsigned short mode; /* Uprawnienia + znaczniki */
SHM_DEST i SHM_LOCKED */
unsigned short __seq; /* Numer sekwencji */ };
Najmniej znaczące 9 bitów pola mode struktury ipc_perm definiuje uprawnienia dostępu do segmentu pamięci dzielonej. Istnieją następujące bity uprawnień:
0400 | Odczyt przez użytkownika |
0200 | Zapis przez użytkownika |
0040 | Odczyt przez grupę |
0020 | Zapis przez grupę |
0004 | Odczyt przez pozostałych |
0002 | Zapis przez pozostałych |
Bity 0100, 0010 i 0001 (bity praw do uruchamiania) nie są przez system wykorzystywane (nie jest konieczne posiadanie uprawnienia do wykonywania, aby przeprowadzić wywołanie shmat(2) ze znacznikiem SHM_EXEC).
Poprawne wartości parametru cmd to:
- IPC_STAT
- Kopiuje informacje ze struktury kontrolnej jądra skojarzonej z shmid do struktury wskazywanej przez buf. Wywołujący musi mieć uprawnienie odczytu segmentu pamięci dzielonej.
- IPC_SET
- Zapisuje wartości niektórych pól struktury shmid_ds wskazywanej przez parametr buf do struktury kontrolnej związanej z tym segmentem pamięci dzielonej wraz z aktualizacją jego shm_ctime.
- Aktualizowane są następujące pola: shm_perm.uid, shm_perm.gid i (9 najmniej znaczących bitów z) shm_perm.mode.
- Efektywny identyfikator użytkownika procesu wywołującego musi odpowiadać właścicielowi (shm_permuid) lub twórcy (shm_perm.cuid) segmentu pamięci dzielonej albo wywołujący musi być uprzywilejowany.
- IPC_RMID
- Zaznacza segment do usunięcia. Zostanie on naprawdę usunięty jedynie w momencie, w którym ostatni używający go proces się od niego odłączy (tj. gdy pole shm_nattch struktury shmid_ds opisującej segment osiągnie wartość zero). Użytkownik musi być właścicielem segmentu, jego twórcą lub użytkownikiem uprzywilejowanym. Argument buf jest ignorowany.
- Jeśli segment został zaznaczony do usunięcia, to zostanie ustawiony (niestandardowy) znacznik SHM_DEST pola shm_perm.mode struktury danych zwracanej przez IPC_STAT.
- Wywołujący musi zapewnić, że segment po użyciu zostanie na pewno usunięty. W przeciwnym przypadku pamięć lub obszar wymiany zajmowane przez segment nie zostaną zwolnione.
- Proszę zapoznać się również z opisem z /proc/sys/kernel/shm_rmid_forced w proc(5).
- IPC_INFO (specyficzne dla Linuksa)
- Zwraca w strukturze, na którą wskazuje buf, informacje o systemowych ograniczeniach i parametrach pamięci dzielonej. Struktura jest typu shminfo (dlatego wymagane jest rzutowanie) i jest zdefiniowana w <sys/shm.h>, pod warunkiem, że zdefiniowano również makro _GNU_SOURCE:
-
struct shminfo {
unsigned long shmmax; /* Maksymalny rozmiar segmentu */
unsigned long shmmin; /* Minimalny rozmiar segmentu;
zawsze 1 */
unsigned long shmmni; /* Maksymalna liczba segmentów */
unsigned long shmseg; /* Maksymalna liczba segmentów,
które proces może podłączyć;
nieużywane przez jądro */
unsigned long shmall; /* Maksymalna liczba stron
pamięci dzielonej, globalna
dla systemu */ };
- Ustawienia shmmni, shmmax oraz shmall można zmienić za pomocą plików /proc o nazwach takich samych, jak nazwy tych ustawień; szczegóły można znaleźć w podręczniku proc(5).
- SHM_INFO (specyficzne dla Linuksa)
- Zwraca strukturę shm_info, której pola zawierają informacje o zasobach systemowych używanych przez pamięć dzieloną. Struktura jest zdefiniowana w <sys/shm.h>, pod warunkiem, że zdefiniowano również makro _GNU_SOURCE:
-
struct shm_info {
int used_ids; /* Liczba istniejących
obecnie segmentów */
unsigned long shm_tot; /* Całkowita liczba stron
pamięci dzielonej */
unsigned long shm_rss; /* Liczba stron pamięci dzielonej
w fizycznej pamięci */
unsigned long shm_swp; /* Liczba stron pamięci dzielonej
w przestrzeni wymiany */
unsigned long swap_attempts;
/* Nieużywane od Linuksa 2.4 */
unsigned long swap_successes;
/* Nieużywane od Linuksa 2.4 */ };
- SHM_STAT (specyficzne dla Linuksa)
- Zwraca strukturę shmid_ds, taką jak dla IPC_STAT. Jednakże parametr shmid nie jest identyfikatorem segmentu, ale indeksem wewnętrznej tablicy jądra przechowującej informacje o wszystkich segmentach pamięci dzielonej w systemie.
- SHM_STAT_ANY (specyficzne dla Linuksa, od Linuksa 4.17)
- Zwraca strukturę shmid_ds, jak dla SHM_STAT. Jednak sem_perm.mode nie jest sprawdzany pod kątem uprawnień odczytu do shmid co oznacza, że każdy użytkownik może wykonać tę operację (podobnie jak każdy użytkownik może odczytać /proc/sysvipc/shm, pozyskując te same informacje).
Proces wywołujący może zabronić lub zezwolić na wymianę obszarów pamięci zajmowanych przez segment, używając następujących wartości cmd:
- SHM_LOCK (specyficzne dla Linuksa)
- Zapobiega umieszczaniu segmentu pamięci dzielonej w przestrzeni wymiany. Wywołujący musi zawieść we wszystkich stronach, których obecność jest konieczna po włączeniu blokowania. Jeśli segment jest zablokowany, to zostanie ustawiony (niestandardowy) znacznik SHM_LOCKED pola shm_perm.mode struktury danych zwracanej przez IPC_STAT.
- SHM_UNLOCK (specyficzne dla Linuksa)
- Odblokowuje segment, zezwalając na umieszczenie go w przestrzeni wymiany.
Przed Linuksem 2.6.10 tylko proces uprzywilejowany mógł stosować SHM_LOCK i SHM_UNLOCK. Od Linuksa 2.6.10 nieuprzywilejowany proces może wywołać te operacje, pod warunkiem że efektywny identyfikator użytkownika odpowiada identyfikatorowi twórcy lub właściciela segmentu oraz (w przypadku SHM_LOCK) ilość pamięci do zablokowania mieści się w ograniczeniu zasobów RLIMIT_MEMLOCK (patrz setrlimit(2)).
WARTOŚĆ ZWRACANA¶
Pomyślnie zakończone operacje IPC_INFO i SHM_INFO zwracają indeks najwyższego używanego wpisu w wewnętrznej tablicy jądra przechowującej informacje o wszystkich segmentach pamięci dzielonej. (Informacji tej można użyć w operacjach SHM_STAT lub SHM_STAT_ANY, aby otrzymać informacje o wszystkich segmentach pamięci dzielonej w systemie). Pomyślnie zakończona operacja SHM_STAT zwraca identyfikator segmentu pamięci dzielonej o indeksie przekazanym w shmid. Pozostałe operacje zwracają 0, jeżeli tylko się powiodą.
W razie wystąpienia błędu zwracane jest -1 i ustawiane errno wskazując błąd.
BŁĘDY¶
- EACCES
- Wydano polecenie IPC_STAT lub SHM_STAT, a prawa dostępu określone w shm_perm.modes nie pozwalają na odczyt segmentu shmid i proces wywołujący nie ma przywileju CAP_IPC_OWNER (ang. capability) w przestrzeni nazw użytkownika, która zarządza jego przestrzenią IPC.
- EFAULT
- Parametr cmd ma wartość IPC_SET lub IPC_STAT, ale adres wskazany przez buf jest niedostępny.
- EIDRM
- shmid wskazuje na usunięty identyfikator.
- EINVAL
- shmid nie jest poprawnym identyfikatorem lub cmd nie jest poprawnym poleceniem. Albo: w przypadku operacji SHM_STAT lub SHM_STAT_ANY wartość indeksu podana w parametrze shmid odwoływała się do obecnie nieużywanego elementu tablicy.
- ENOMEM
- (Od Linuksa 2.6.9) Podano SHM_LOCK, a rozmiar segmentu do zablokowania oznaczałby przekroczenie ograniczenia na całkowitą liczbę bajtów w pamięci dzielonej przypadającą na rzeczywisty identyfikator użytkownika procesu wywołującego. Ograniczenie to jest opisywane przez miękki limit zasobu RLIMIT_MEMLOCK (patrz setrlimit(2)).
- EOVERFLOW
- Próbowano wywołać polecenie IPC_STAT, a wartość GID lub UID jest za duża, aby ją umieścić w strukturze wskazywanej przez buf.
- EPERM
- Próbowano wywołać polecenie IPC_SET lub IPC_RMID, ale efektywny UID właściciela wywołującego procesu nie odpowiada twórcy segmentu (określonemu w shm_perm.cuid), właścicielowi segmentu (określonemu w shm_perm.uid), a proces nie jest uprzywilejowany (Linux: nie ma przywileju CAP_SYS_ADMIN).
- Lub (przed Linuksem 2.6.9) podano SHM_LOCK lub SHM_UNLOCK, ale proces nie był uprzywilejowany (Linux: nie miał ustawionego przywileju CAP_IPC_LOCK; od wersji Linuksa 2.6.9 ten błąd może wystąpić również gdy RLIMIT_MEMLOCK jest równy 0 i proces wywołujący nie jest uprzywilejowany).
STANDARDY¶
POSIX.1-2001, POSIX.1-2008, SVr4.
UWAGI¶
Operacje IPC_INFO, SHM_STAT oraz SHM_INFO są używane przez program ipcs(1) w celu dostarczenia informacji o zajmowanych zasobach. W przyszłości operacje te mogą zostać zmodyfikowane lub przeniesione do interfejsu systemu plików /proc.
Linux pozwala na dołączenie (shmat(2)) segmentu pamięci dzielonej, który już został zaznaczony do usunięcia za pomocą shmctl(IPC_RMID). Ta właściwość nie jest dostępna w innych implementacjach Uniksa; przenośne aplikacje nie powinny od niej zależeć.
Niektóre pola struktury struct shmid_ds były w Linuksie 2.2 typu short, ale stały się typu long w Linuksie 2.4. Aby to wykorzystać, powinna wystarczyć rekompilacja pod glibc-2.1.91 lub nowszą. (Jądro rozróżnia stare wywołania od nowych za pomocą znacznika IPC_64 w cmd).
ZOBACZ TAKŻE¶
mlock(2), setrlimit(2), shmget(2), shmop(2), capabilities(7), sysvipc(7)
TŁUMACZENIE¶
Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Rafał Lewczuk <R.Lewczuk@elka.pw.edu.p>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl>, Robert Luberda <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.
15 grudnia 2022 r. | Linux man-pages 6.03 |