0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #include <stdlib.h>
0043 #include <stdio.h>
0044
0045
0046 #include <sys/mman.h>
0047 #include <sys/types.h>
0048 #include <sys/ipc.h>
0049 #include <sys/shm.h>
0050
0051 #include <unistd.h>
0052 #include <fcntl.h>
0053 #include <sys/stat.h>
0054
0055 #include <ndrstandard.h>
0056 #include <ndebug.h>
0057 #include <nstd_shm.h>
0058
0059 #include "sys_unix.h"
0060
0061
0062
0063
0064
0065
0066 typedef struct
0067 {
0068 char *suffix;
0069 int idx;
0070 } segmap_t;
0071
0072
0073
0074 exprivate segmap_t M_map[] = {
0075 {NDRX_SHM_SRVINFO_SFX, NDRX_SHM_SRVINFO_KEYOFSZ}
0076 ,{NDRX_SHM_SVCINFO_SFX, NDRX_SHM_SVCINFO_KEYOFSZ}
0077 ,{NDRX_SHM_BRINFO_SFX, NDRX_SHM_BRINFO_KEYOFSZ}
0078 ,{NDRX_SHM_P2S_SFX, NDRX_SHM_P2S_KEYOFSZ}
0079 ,{NDRX_SHM_S2P_SFX, NDRX_SHM_S2P_KEYOFSZ}
0080 ,{NDRX_SHM_CPM_SFX, NDRX_SHM_CPM_KEYOFSZ}
0081 ,{NDRX_SHM_LCF_SFX, NDRX_SHM_LCF_KEYOFSZ}
0082 ,{NDRX_SHM_ROUTCRIT_SFX, NDRX_SHM_ROUTCRIT_KEYOFSZ}
0083 ,{NDRX_SHM_ROUTSVC_SFX, NDRX_SHM_ROUTSVC_KEYOFSZ}
0084 ,{NULL}
0085 };
0086
0087
0088
0089
0090
0091
0092
0093 expublic unsigned int ndrx_hash_fn( void *k )
0094 {
0095 unsigned int hash = 5381;
0096 int c;
0097 char *str = (char *)k;
0098
0099 while ((c = *str++))
0100 hash = ((hash << 5) + hash) + c;
0101
0102 return hash;
0103 }
0104
0105
0106
0107
0108
0109
0110 expublic int ndrx_shm_is_attached(ndrx_shm_t *shm)
0111 {
0112 int ret=EXTRUE;
0113
0114 if (NULL==shm->mem || (void *)EXFAIL==shm->mem)
0115 {
0116 ret=EXFALSE;
0117 }
0118
0119 return ret;
0120 }
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 expublic int ndrx_shm_open(ndrx_shm_t *shm, int attach_on_exists)
0135 {
0136 int ret=EXSUCCEED;
0137
0138
0139 shm->fd = shmget(shm->key, shm->size, IPC_CREAT | IPC_EXCL| S_IRWXU | S_IRWXG);
0140
0141 if (shm->fd < 0)
0142 {
0143 int err = errno;
0144
0145
0146
0147 if (EEXIST==err && attach_on_exists)
0148 {
0149 NDRX_LOG_EARLY(log_info, "Shared memory exists [%s]/%x - attaching",
0150 shm->path, shm->key);
0151 return ndrx_shm_attach(shm);
0152 }
0153
0154 NDRX_LOG_EARLY(log_error, "Failed to create shm [%s]: %s",
0155 shm->path, strerror(err));
0156 EXFAIL_OUT(ret);
0157 }
0158
0159 shm->mem = (char *)shmat(shm->fd, 0, 0);
0160
0161 if ((void *)EXFAIL==shm->mem)
0162 {
0163 NDRX_LOG_EARLY(log_error, "Failed to shmat memory for [%s] fd %d/%x bytes %d: %s",
0164 shm->path, shm->fd, shm->key, shm->size, strerror(errno));
0165 EXFAIL_OUT(ret);
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 NDRX_LOG_EARLY(log_info, "Shm: [%s] %d/%x created size: %d mem: %p",
0179 shm->path, shm->fd, shm->key, shm->size, shm->mem);
0180
0181 out:
0182
0183
0184
0185 if (EXSUCCEED!=ret && EXFAIL!=shm->fd)
0186 {
0187 ndrx_shm_remove(shm);
0188 }
0189
0190 NDRX_LOG_EARLY(log_debug, "return %d", ret);
0191
0192 return ret;
0193 }
0194
0195
0196
0197
0198
0199
0200 expublic int ndrx_shm_attach(ndrx_shm_t *shm)
0201 {
0202 int ret=EXSUCCEED;
0203
0204 if (ndrx_shm_is_attached(shm))
0205 {
0206 NDRX_LOG_EARLY(log_debug, "shm [%s] %d/%x size: %d already attached", shm->path,
0207 shm->fd, shm->key, shm->size);
0208 goto out;
0209 }
0210
0211
0212 shm->fd = shmget(shm->key, shm->size, S_IRWXU | S_IRWXG);
0213
0214 if (shm->fd < 0)
0215 {
0216 NDRX_LOG_EARLY(log_error, "Failed to shmget/attach shm key=%x [%s]: %s",
0217 shm->key, shm->path, strerror(errno));
0218 EXFAIL_OUT(ret);
0219 }
0220
0221 shm->mem = (char *)shmat(shm->fd, 0, 0);
0222
0223 if (MAP_FAILED==shm->mem)
0224 {
0225 NDRX_LOG_EARLY(log_error, "Failed to shmat memory for [%s] fd %d/%x bytes %d: %s",
0226 shm->path, shm->fd, shm->key, shm->size, strerror(errno));
0227 EXFAIL_OUT(ret);
0228 }
0229
0230 NDRX_LOG_EARLY(log_debug, "Shm: [%s] %d/%x attach size: %d mem: %p",
0231 shm->path, shm->fd, shm->key, shm->size, shm->mem);
0232
0233 out:
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 NDRX_LOG_EARLY(log_debug, "return %d", ret);
0244
0245 return ret;
0246 }
0247
0248
0249
0250
0251
0252 expublic int ndrx_shm_close(ndrx_shm_t *shm)
0253 {
0254 int ret=EXSUCCEED;
0255
0256 if ((void *)EXFAIL==shm->mem || NULL==shm->mem)
0257 {
0258 NDRX_LOG_EARLY(log_debug, "[%s] %x already closed", shm->path, shm->key);
0259 }
0260 else
0261 {
0262 ret = shmdt(shm->mem);
0263
0264 if (EXSUCCEED!=ret)
0265 {
0266 NDRX_LOG_EARLY(log_error, "Failed to detach shm [%s] %d/%x addr [%p]: %d - %s",
0267 shm->path, shm->fd, shm->key, shm->mem, errno, strerror(errno));
0268 }
0269 else
0270 {
0271 shm->mem = NULL;
0272 }
0273 }
0274
0275 out:
0276 return ret;
0277 }
0278
0279
0280
0281
0282
0283 expublic int ndrx_shm_remove(ndrx_shm_t *shm)
0284 {
0285 int ret=EXSUCCEED;
0286 int fd;
0287
0288
0289 if (EXFAIL!=(fd = shmget(shm->key, 0, S_IRWXU | S_IRWXG)))
0290 {
0291 if (EXSUCCEED!=shmctl(fd, IPC_RMID, NULL))
0292 {
0293 NDRX_LOG_EARLY(log_error, "Failed to IPC_RMID %d/%x: [%s]: %s",
0294 fd, shm->key, shm->path, strerror(errno));
0295 ret = EXFAIL;
0296 }
0297
0298 shm->fd = EXFAIL;
0299 shm->mem = NULL;
0300 }
0301 else
0302 {
0303 NDRX_LOG_EARLY(log_warn, "Failed to remove: [%s] %x", shm->path, shm->key);
0304 }
0305
0306 return ret;
0307 }
0308
0309
0310
0311
0312
0313
0314 exprivate key_t keygetshm(char *path, key_t ipckey)
0315 {
0316 char *p;
0317 key_t ret;
0318 segmap_t *pp;
0319
0320 if (NULL==(p = strchr(path, NDRX_FMT_SEP)))
0321 {
0322 NDRX_LOG(log_error, "Failed to get suffix for memory segment [%s]",
0323 path);
0324 EXFAIL_OUT(ret);
0325 }
0326
0327
0328 p++;
0329
0330 pp = M_map;
0331
0332 while (NULL!=pp->suffix)
0333 {
0334 if (0==strcmp(pp->suffix, p))
0335 {
0336 break;
0337 }
0338 pp++;
0339 }
0340
0341 if (NULL==pp->suffix)
0342 {
0343 NDRX_LOG(log_error, "Failed to map shared memory segment [%s] to system v key",
0344 p);
0345 EXFAIL_OUT(ret);
0346 }
0347
0348 ret = ipckey + pp->idx;
0349
0350 NDRX_LOG(log_info, "[%s] segment mapped to ipc key %x", path, ret);
0351
0352 out:
0353
0354 return ret;
0355 }
0356
0357
0358
0359
0360
0361
0362 expublic int ndrx_shm_remove_name(char *path, key_t ipckey)
0363 {
0364 int ret = EXSUCCEED;
0365 key_t key = keygetshm(path, ipckey);
0366 int fd;
0367
0368 if (EXFAIL!=key)
0369 {
0370
0371 if (EXFAIL!=(fd = shmget(key, 0, S_IRWXU | S_IRWXG)))
0372 {
0373 if (EXSUCCEED!=shmctl(fd, IPC_RMID, NULL))
0374 {
0375 NDRX_LOG_EARLY(log_error, "Failed to IPC_RMID %d/%x: [%s]: %s",
0376 fd, key, path, strerror(errno));
0377 ret = EXFAIL;
0378 }
0379 }
0380 }
0381
0382 out:
0383 return ret;
0384 }
0385
0386
0387
0388
0389
0390
0391 expublic string_list_t * ndrx_shm_shms_list(key_t ipckey)
0392 {
0393 string_list_t *ret = NULL;
0394 char segment[NDRX_MAX_Q_SIZE*2];
0395 int i;
0396 key_t key;
0397 int fd;
0398
0399 for (i=0; NULL!=M_map[i].suffix; i++)
0400 {
0401 key = ipckey + M_map[i].idx;
0402
0403 if (EXFAIL!=(fd = shmget(key, 0, S_IRWXU | S_IRWXG)))
0404 {
0405 snprintf(segment, sizeof(segment), "%x:%d:%s",
0406 (unsigned int)key, fd, M_map[i].suffix);
0407 if (EXSUCCEED!=ndrx_string_list_add(&ret, segment))
0408 {
0409 NDRX_LOG(log_error, "Failed to add shm segment to list");
0410 if (NULL!=ret)
0411 {
0412 ndrx_string_list_free(ret);
0413 ret = NULL;
0414 }
0415 goto out;
0416 }
0417 }
0418 }
0419 out:
0420 return ret;
0421 }
0422
0423