Fórumok
Hello,
adott egy 32 bites virtuozzo-val virtualizált gép, amelyen a
int ret = shmget(0xXXXXXXXX, YYYYYYYY, IPC_CREAT|IPC_EXCL|0660);
parancs ENOSPC-vel elszáll. A sysctl-ben beállítottam a
kernel.shmmax = 4294967295
kernel.shmall = 268435456
paramétereket, és ulimit sincs.
100MB memóriát szeretnék lefoglalni, van szabadon 1.5 GIGA. Swap nincs a géphez.
Virtuozzo specifikus dolog lehet? Találkozott már valaki ilyennel?
Ui: 0 shm segment és 0 szemafor van használva, biztos nem az fogyott el
Hozzászólások
Virtuozzo/OpenVZ specifikus - nezd meg user beancounters (/proc/user_beancounters) tartalmat, valoszinuleg tullepted a vm limitjet. vzctl set $VEID --shmpages X segitsegevel beallithatod mennyi shm legyen elerheto a vm-en belul.
http://wiki.openvz.org/Resource_shortage
http://wiki.openvz.org/Shmpages#shmpages
Helló, itt a kimenet:
uid resource held maxheld barrier limit failcnt
shmpages 5940 16042 19567 19567 3
Ezek szerint 20 ezer page, azaz kemény 80 mega SHM van engedélyezve. Sajnos a szolgáltató nem fogja miattam átállítani, nincs valami módszer a kliens oldalról a memória rovására az shm növelésére?
Nem tudom, hogy hogyan működik ez a virtualizáló izé, de elképzelhető, hogy az shm memóriaterület globális erőforrás (azaz az összes virtuális gép ugyanabból a keretből dolgozik), ezért kénytelenek korlátozni a használatot, hogy mindenkinek jusson.
subscribe
Virtualizációtól függetlenül javaslom az alábbit. Feltételezem, hogy a memóriát szülő-gyerek viszonyban osztod meg (*).
shmget() helyett használj mmap()-et. A lényeg az, hogy ne anonim mapping-et használj (mint az shmget), hanem regular file backed mapping-et. A különbség nagyjából csak annyi, hogy nem a swap lesz a backing store, hanem egy reguláris file. Ezt ajánlom:
-- A nullás mód nem tévedés.
-- felkerekítve lapméretre. Bár alaposabban nézegetve az mmap() speckóját, ez valószínűleg nem is kell.
Attól, hogy a címtartomány alatt egy reguláris file van, nem a swap, még semmivel sem valószínűbb a diszkre írogatás. (Ha tudod, milyen minta szerint fogják a processzek elérni a tartományt, akkor adhatsz tippet az OS-nek, lásd
.)
A fenti hatására a file nagyon rövid ideig lesz látható a filerendszerben (és idegen uid-ok számára azalatt is megnyithatatlan lesz, és azonos euid számára is tipp lesz a nullás mód), onnantól kezdve csak mapping referenciák lesznek a file-ra. Ha az összes hivatkozó processz leáll (rendesen, vagy kilövik), a file területe automatikusan fel fog szabadulni, ráadásul az OS-nek még csak nem is szükséges kiírnia a diszkre a tartomány tartalmát (az _exit()-ben automatikusan bennefoglalt munmap() hatására ezt meg kellene tennie egyébként, úgy gondolom). Az mmap()-ra tehát most nem úgy kell tekinteni, hogy byte-tömb-ként akarunk használni egy file-t, hanem úgy, hogy odateszünk egy ideiglenes "swap file"-t egy osztott memóriatartomány mögé.
(*) Ha a memóriát nem ilyen viszonyban lévő processzek között osztod meg, akkor ugye az shmget()-et is úgy használod valószínűleg, hogy az összes processzben ftok()-kal eljutsz ugyanahhoz a kulcshoz ugyanabból a file-ból, majd shmget()-tel eljutsz az azonosítóhoz, majd shmat()-tal rácsatlakozol. (Feltéve, hogy az egész előtt egy dedikált processz létrehozta a szegmenst.) Ugyanezt megteheted mmap()-pel is: (a) a backing store-t adó file-t nem törlöd le, hanem tartósan megőrzöd, vagy (b) a backing store-t adó file-t letörlöd ugyan, de egy dedikált daemon processzben egyetlen fd referenciát nyitva tartasz rá. Ehhez a daemon-hoz hozzácsatlakoznak a többiek egy unix domain socket-en, amin keresztül a daemon SCM_RIGHTS-szal átküldi az fd-t ("interprocess dup()"). Ezután minden processz maga végrehajthatja az mmap()-et és a close()-t. Remélhetőleg azért a megosztásra nem így van szükséged, hanem szülő-gyerek viszonyban.