|
|
| version 1.9, 2025/04/15 16:49:36 | version 1.13, 2025/04/16 17:36:12 |
|---|---|
| Line 24 | Line 24 |
| * along with FreeM. If not, see <https://www.gnu.org/licenses/>. | * along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
| * | * |
| * $Log$ | * $Log$ |
| * Revision 1.13 2025/04/16 17:36:12 snw | |
| * Add FreeBSD shm cleanup script | |
| * | |
| * Revision 1.12 2025/04/15 21:57:10 snw | |
| * Fix SysV IPC bugs on FreeBSD | |
| * | |
| * Revision 1.11 2025/04/15 21:08:51 snw | |
| * Add some useful debug output | |
| * | |
| * Revision 1.10 2025/04/15 19:26:13 snw | |
| * Remove extra whitespace | |
| * | |
| * Revision 1.9 2025/04/15 16:49:36 snw | * Revision 1.9 2025/04/15 16:49:36 snw |
| * Make use of logprintf throughout codebase | * Make use of logprintf throughout codebase |
| * | * |
| Line 84 void shm_daemon_init(void); | Line 96 void shm_daemon_init(void); |
| shm_config_t *shm_config = (shm_config_t *) NULL; | shm_config_t *shm_config = (shm_config_t *) NULL; |
| #if defined(__FreeBSD__) | |
| # define FM_SHM_PERMS 0777 | |
| #else | |
| # define FM_SHM_PERMS 0770 | |
| #endif | |
| short shm_init(const size_t seg_size) | short shm_init(const size_t seg_size) |
| { | { |
| size_t alloc_map_size; | size_t alloc_map_size; |
| long pg_size; | long pg_size; |
| key_t shm_sk; | key_t shm_sk; |
| #if defined(__FreeBSD__) | |
| struct shmid_ds ctl; | |
| #endif | |
| shm_sk = ftok (config_file, 5); | shm_sk = ftok (config_file, 5); |
| pg_size = sysconf (_SC_PAGESIZE); | pg_size = sysconf (_SC_PAGESIZE); |
| Line 105 short shm_init(const size_t seg_size) | Line 127 short shm_init(const size_t seg_size) |
| shm_config->segsiz = seg_size + alloc_map_size + pg_size; | shm_config->segsiz = seg_size + alloc_map_size + pg_size; |
| shm_config->key = ftok (config_file, 1); | shm_config->key = ftok (config_file, 1); |
| shm_config->pgsiz = pg_size; | shm_config->pgsiz = pg_size; |
| shm_config->seg_id = shmget (shm_config->key, shm_config->segsiz, 0770 | IPC_CREAT); | shm_config->seg_id = shmget (shm_config->key, shm_config->segsiz, FM_SHM_PERMS | IPC_CREAT); |
| if (shm_config->seg_id == -1) { | if (shm_config->seg_id == -1) { |
| if (errno == 22) { | if (errno == 22) { |
| logprintf (FM_LOG_ERROR, "shm_init: cannot get shared memory segment of %ld bytes", (unsigned long) shm_config->segsiz); | logprintf (FM_LOG_ERROR, "shm_init: cannot get shared memory segment of %ld bytes", (unsigned long) shm_config->segsiz); |
| Line 122 short shm_init(const size_t seg_size) | Line 144 short shm_init(const size_t seg_size) |
| #endif | #endif |
| if (shm_config->dta == (void *) -1) { | if (shm_config->dta == (void *) -1) { |
| return SHMS_ATTACH_ERR; | logprintf (FM_LOG_FATAL, "shm_init: shmat() failed (error code %d [%s])", errno, strerror (errno)); |
| } | } |
| /* view the first sizeof (shm_hdr_t) bytes of the data area as an shm_hdr_t */ | /* view the first sizeof (shm_hdr_t) bytes of the data area as an shm_hdr_t */ |
| shm_config->hdr = (shm_hdr_t *) shm_config->dta; | shm_config->hdr = (shm_hdr_t *) shm_config->dta; |
| Line 169 short shm_init(const size_t seg_size) | Line 191 short shm_init(const size_t seg_size) |
| /* grab the pointers we need */ | /* grab the pointers we need */ |
| void *old_addr = shm_config->dta; | void *old_addr = shm_config->dta; |
| void *new_addr = shm_config->hdr->shmad; | void *new_addr = shm_config->hdr->shmad; |
| logprintf (FM_LOG_INFO, "shmmgr: remapping shared memory from virtual address %p to %p", old_addr, new_addr); | |
| /* detach and reattach */ | /* detach and reattach */ |
| if (shmdt (old_addr) == -1) { | if (shmdt (old_addr) == -1) { |
| logprintf (FM_LOG_FATAL, "shm_init: detach failed during detach/reattach [shmdt error %s]", strerror (errno)); | logprintf (FM_LOG_FATAL, "shm_init: detach failed during detach/reattach [shmdt error %s]", strerror (errno)); |
| } | } |
| #if defined(__FreeBSD__) | if ((shm_config->dta = shmat (shm_config->seg_id, new_addr, 0)) == -1) { |
| shm_config->dta = shmat (shm_config->seg_id, new_addr, SHM_REMAP); | switch (errno) { |
| #else | |
| shm_config->dta = shmat (shm_config->seg_id, new_addr, 0); | |
| #endif | |
| if (shm_config->dta == (void *) -1) { | case EINVAL: |
| logprintf (FM_LOG_FATAL, "shm_init: fatal error attaching shared memory segment [shmat error '%s']", strerror (errno)); | logprintf (FM_LOG_FATAL, "shm_init: shmat() failed; no matching shared memory segment exists or shared memory address invalid"); |
| break; | |
| case ENOMEM: | |
| logprintf (FM_LOG_ERROR, "shm_init: shmat() failed; specified address cannot be used for mapping"); | |
| exit (1); | |
| break; | |
| case EMFILE: | |
| logprintf (FM_LOG_FATAL, "shm_init: shmat() failed; per-process shared memory segment limit reached; check kernel tuning parameters"); | |
| break; | |
| default: | |
| logprintf (FM_LOG_FATAL, "shm_init: shmat() failed; error code %d [%s]", errno, strerror (errno)); | |
| break; | |
| } | |
| } | } |
| shm_config->hdr = (shm_hdr_t *) shm_config->dta; | shm_config->hdr = (shm_hdr_t *) shm_config->dta; |