/* * Initialize the Interprocess Communication system and its associated shared * memory structure. It first creates a temporary file using the mkstemp() * function. It than sets the file large enough to hold the filebench_shm and an * additional megabyte. (Additional megabyte is required to make sure that all * sizeof(filebench_shm) bytes plus page alignment bytes will fit in the file.) * The file is then memory mapped. Once the shared memory region is created, * ipc_init initializes various locks, pointers, and variables in the shared * memory. It also uses ftok() to get a shared memory semaphore key for later * use in allocating shared semaphores. */ void ipc_init(char *fsplug) { int shmfd; char tmpbuf[MB] = {0}; key_t key; #ifdef HAVE_SEM_RMID int sys_semid; #endif char *shmdir; shmdir = getenv("FB_SHM_DIR"); if (shmdir == NULL) shmdir = "/tmp"; if (asprintf(&shmpath, "%s/filebench-shm-XXXXXX", shmdir) < 0) { filebench_log(LOG_FATAL, "Could not name shared memory file"); exit(1); } shmfd = mkstemp(shmpath); if (shmfd < 0) { filebench_log(LOG_FATAL, "Could not create shared memory " "file %s: %s", shmpath, strerror(errno)); exit(1); } (void)lseek(shmfd, sizeof(filebench_shm_t), SEEK_SET); if (write(shmfd, tmpbuf, MB) != MB) { filebench_log(LOG_FATAL, "Could not write to the shared memory " "file: %s", strerror(errno)); exit(1); } if ((filebench_shm = (filebench_shm_t *)mmap(NULL, sizeof(filebench_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0)) == MAP_FAILED) { filebench_log(LOG_FATAL, "Could not mmap the shared " "memory file: %s", strerror(errno)); exit(1); } (void) memset(filebench_shm, 0, (char *)&filebench_shm->shm_marker - (char *)filebench_shm); /* * Pass the name of the target filesystem, if not the local driver */ if (fsplug) fb_strlcpy(filebench_shm->shm_filesys_path,fsplug, sizeof(filebench_shm->shm_filesys_path)); /* * First, initialize all the structures needed for the filebench_log() * function to work correctly with the log levels other than LOG_FATAL */ filebench_shm->shm_epoch = gethrtime(); filebench_shm->shm_debug_level = LOG_INFO; /* Setup mutexes for object lists */ ipc_mutexattr_init(IPC_MUTEX_NORMAL); ipc_mutexattr_init(IPC_MUTEX_PRIORITY); ipc_mutexattr_init(IPC_MUTEX_ROBUST); ipc_mutexattr_init(IPC_MUTEX_PRI_ROB); (void) pthread_mutex_init(&filebench_shm->shm_msg_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); filebench_log(LOG_INFO, "Allocated %lldMB of shared memory", (sizeof(filebench_shm_t) + MB) / MB); filebench_shm->shm_rmode = FILEBENCH_MODE_TIMEOUT; filebench_shm->shm_string_ptr = &filebench_shm->shm_strings[0]; filebench_shm->shm_ptr = (char *)filebench_shm->shm_addr; filebench_shm->shm_path_ptr = &filebench_shm->shm_filesetpaths[0]; (void) pthread_mutex_init(&filebench_shm->shm_fileset_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_procflow_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_procs_running_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_threadflow_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_flowop_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_eventgen_lock, ipc_mutexattr(IPC_MUTEX_PRI_ROB)); (void) pthread_mutex_init(&filebench_shm->shm_malloc_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_ism_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) ipc_mutex_lock(&filebench_shm->shm_ism_lock); (void) pthread_cond_init(&filebench_shm->shm_eventgen_cv, ipc_condattr()); (void) pthread_rwlock_init(&filebench_shm->shm_flowop_find_lock, ipc_rwlockattr()); (void) pthread_rwlock_init(&filebench_shm->shm_run_lock, ipc_rwlockattr()); /* Create semaphore */ if ((key = ftok(shmpath, 1)) < 0) { filebench_log(LOG_ERROR, "cannot create sem: %s", strerror(errno)); exit(1); } #ifdef HAVE_SEM_RMID if ((sys_semid = semget(key, 0, 0)) != -1) (void) semctl(sys_semid, 0, IPC_RMID); #endif filebench_shm->shm_semkey = key; filebench_shm->shm_sys_semid = -1; filebench_shm->shm_dump_fd = -1; filebench_shm->shm_eventgen_hz = 0; filebench_shm->shm_id = -1; }
/* * Initialize the Interprocess Communication system and its * associated shared memory structure. It first creates a * temporary file using either the mkstemp() function or the * tempnam() and open() functions. If the process model is in * use,it than sets the file large enough to hold the * filebench_shm and an additional Megabyte. The file is then * memory mapped. If the process model is not in use, it simply * mallocs a region of sizeof (filebench_shm_t). * * Once the shared memory region / file is created, ipc_init * initializes various locks pointers, and variables in the * shared memory. It also uses ftok() to get a shared memory * semaphore key for later use in allocating shared semaphores. */ void ipc_init(void) { filebench_shm_t *buf = malloc(MB); key_t key; caddr_t c1; caddr_t c2; #ifdef HAVE_SEM_RMID int semid; #endif #ifdef HAVE_MKSTEMP shmpath = (char *)malloc(128); (void) strcpy(shmpath, "/var/tmp/fbenchXXXXXX"); shmfd = mkstemp(shmpath); #else shmfd = open(shmpath, O_CREAT | O_RDWR | O_TRUNC, 0666); shmpath = tempnam("/var/tmp", "fbench"); #endif /* HAVE_MKSTEMP */ #ifdef USE_PROCESS_MODEL if (shmfd < 0) { filebench_log(LOG_FATAL, "Cannot open shm %s: %s", shmpath, strerror(errno)); exit(1); } (void) lseek(shmfd, sizeof (filebench_shm_t), SEEK_SET); if (write(shmfd, buf, MB) != MB) { filebench_log(LOG_FATAL, "Cannot allocate shm: %s", strerror(errno)); exit(1); } /* LINTED E_BAD_PTR_CAST_ALIGN */ if ((filebench_shm = (filebench_shm_t *)mmap((caddr_t)0, sizeof (filebench_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0)) == NULL) { filebench_log(LOG_FATAL, "Cannot mmap shm"); exit(1); } #else if ((filebench_shm = (filebench_shm_t *)malloc(sizeof (filebench_shm_t))) == NULL) { filebench_log(LOG_FATAL, "Cannot malloc shm"); exit(1); } #endif /* USE_PROCESS_MODEL */ c1 = (caddr_t)filebench_shm; c2 = (caddr_t)&filebench_shm->marker; (void) memset(filebench_shm, 0, c2 - c1); filebench_shm->epoch = gethrtime(); filebench_shm->debug_level = LOG_VERBOSE; filebench_shm->shm_rmode = FILEBENCH_MODE_TIMEOUT; filebench_shm->string_ptr = &filebench_shm->strings[0]; filebench_shm->shm_ptr = (char *)filebench_shm->shm_addr; filebench_shm->path_ptr = &filebench_shm->filesetpaths[0]; /* Setup mutexes for object lists */ (void) pthread_mutex_init(&filebench_shm->fileset_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->procflow_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->threadflow_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->flowop_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->msg_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->eventgen_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->malloc_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->ism_lock, ipc_mutexattr()); (void) pthread_cond_init(&filebench_shm->eventgen_cv, ipc_condattr()); (void) pthread_rwlock_init(&filebench_shm->flowop_find_lock, ipc_rwlockattr()); (void) pthread_rwlock_init(&filebench_shm->run_lock, ipc_rwlockattr()); (void) pthread_rwlock_rdlock(&filebench_shm->run_lock); (void) ipc_mutex_lock(&filebench_shm->ism_lock); /* Create semaphore */ if ((key = ftok(shmpath, 1)) < 0) { filebench_log(LOG_ERROR, "cannot create sem: %s", strerror(errno)); exit(1); } #ifdef HAVE_SEM_RMID if ((semid = semget(key, 0, 0)) != -1) (void) semctl(semid, 0, IPC_RMID); #endif filebench_shm->semkey = key; filebench_shm->log_fd = -1; filebench_shm->dump_fd = -1; filebench_shm->eventgen_hz = 0; filebench_shm->shm_id = -1; free(buf); }