/** * _9p_dispatcher_thread: thread used for RPC dispatching. * * This function is the main loop for the 9p dispatcher. * It never returns because it is an infinite loop. * * @param Arg (unused) * * @return Pointer to the result (but this function will mostly loop forever). * */ void *_9p_dispatcher_thread(void *Arg) { int _9p_socket; int rc = 0; long int newsock = -1; pthread_attr_t attr_thr; pthread_t tcp_thrid; SetNameFunction("_9p_disp"); /* Calling dispatcher main loop */ LogInfo(COMPONENT_9P_DISPATCH, "Entering nfs/rpc dispatcher"); LogDebug(COMPONENT_9P_DISPATCH, "My pthread id is %p", (caddr_t) pthread_self()); /* Set up the _9p_socket (trying V6 first, will fall back to V4 * if V6 fails). */ _9p_socket = _9p_create_socket_V6(); if (_9p_socket == -1) { LogFatal(COMPONENT_9P_DISPATCH, "Can't get socket for 9p dispatcher"); } /* Init for thread parameter (mostly for scheduling) */ if (pthread_attr_init(&attr_thr) != 0) LogDebug(COMPONENT_9P_DISPATCH, "can't init pthread's attributes"); if (pthread_attr_setscope(&attr_thr, PTHREAD_SCOPE_SYSTEM) != 0) LogDebug(COMPONENT_9P_DISPATCH, "can't set pthread's scope"); if (pthread_attr_setdetachstate(&attr_thr, PTHREAD_CREATE_DETACHED) != 0) LogDebug(COMPONENT_9P_DISPATCH, "can't set pthread's join state"); LogEvent(COMPONENT_9P_DISPATCH, "9P dispatcher started"); while (true) { newsock = accept(_9p_socket, NULL, NULL); if (newsock < 0) { LogCrit(COMPONENT_9P_DISPATCH, "accept failed: %d", errno); continue; } /* Starting the thread dedicated to signal handling */ rc = pthread_create(&tcp_thrid, &attr_thr, _9p_socket_thread, (void *)newsock); if (rc != 0) { LogFatal(COMPONENT_THREAD, "Could not create 9p socket manager thread, error = %d (%s)", errno, strerror(errno)); } } /* while */ close(_9p_socket); return NULL; } /* _9p_dispatcher_thread */
/* Equivalent du _9p_socket_thread( */ void * _9p_rdma_thread( void * Arg ) { msk_trans_t * trans = Arg ; _9p_rdma_priv * priv = NULL ; _9p_conn_t * p_9p_conn = NULL ; uint8_t * rdmabuf = NULL ; struct ibv_mr * mr = NULL ; msk_data_t * rdata = NULL ; _9p_datalock_t * datalock = NULL ; unsigned int i = 0 ; int rc = 0 ; if( ( priv = gsh_malloc( sizeof(*priv) ) ) == NULL ) { LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not malloc private structure" ) ; goto error ; } memset(priv, 0, sizeof(*priv)); trans->private_data = priv; if( ( p_9p_conn = gsh_malloc( sizeof(*p_9p_conn) ) ) == NULL ) { LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not malloc _9p_conn" ) ; goto error ; } memset(p_9p_conn, 0, sizeof(*p_9p_conn)); priv->pconn = p_9p_conn; for (i = 0; i < FLUSH_BUCKETS; i++) { pthread_mutex_init(&p_9p_conn->flush_buckets[i].lock, NULL); glist_init(&p_9p_conn->flush_buckets[i].list); } p_9p_conn->sequence = 0 ; atomic_store_uint32_t(&p_9p_conn->refcount, 0) ; p_9p_conn->trans_type = _9P_RDMA ; p_9p_conn->trans_data.rdma_trans = trans ; memcpy(&p_9p_conn->addrpeer, msk_get_dst_addr(trans), sizeof(p_9p_conn->addrpeer)); /* Init the fids pointers array */ memset( &p_9p_conn->fids, 0, _9P_FID_PER_CONN* sizeof( _9p_fid_t * ) ) ; /* Set initial msize. Client may request a lower value during TVERSION */ p_9p_conn->msize = nfs_param._9p_param._9p_rdma_msize ; if( gettimeofday( &p_9p_conn->birth, NULL ) == -1 ) LogMajor( COMPONENT_9P, "Cannot get connection's time of birth" ) ; /* Alloc rdmabuf */ if( ( rdmabuf = gsh_malloc( (_9P_RDMA_BUFF_NUM)*_9P_RDMA_CHUNK_SIZE)) == NULL ) { LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not malloc rdmabuf" ) ; goto error ; } memset( rdmabuf, 0, (_9P_RDMA_BUFF_NUM)*_9P_RDMA_CHUNK_SIZE); priv->rdmabuf = rdmabuf; /* Register rdmabuf */ if( ( mr = msk_reg_mr( trans, rdmabuf, (_9P_RDMA_BUFF_NUM)*_9P_RDMA_CHUNK_SIZE, IBV_ACCESS_LOCAL_WRITE)) == NULL ) { LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not register rdmabuf" ) ; goto error ; } /* Get prepared to recv data */ if( ( rdata = gsh_malloc( _9P_RDMA_BUFF_NUM * sizeof(*rdata) ) ) == NULL ) { LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not malloc rdata" ) ; goto error ; } memset( rdata, 0, (_9P_RDMA_BUFF_NUM * sizeof(*rdata)) ) ; priv->rdata = rdata; if( (datalock = gsh_malloc(_9P_RDMA_BUFF_NUM*sizeof(*datalock))) == NULL ) { LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not malloc datalock" ) ; goto error ; } memset( datalock, 0, (_9P_RDMA_BUFF_NUM * sizeof(*datalock)) ) ; priv->datalock = datalock; for( i=0; i < _9P_RDMA_BUFF_NUM; i++) { rdata[i].data=rdmabuf+i*_9P_RDMA_CHUNK_SIZE ; rdata[i].max_size=_9P_RDMA_CHUNK_SIZE ; rdata[i].mr = mr; datalock[i].data = &rdata[i]; pthread_mutex_init(&datalock[i].lock, NULL); if( i < _9P_RDMA_OUT ) datalock[i].sender = &datalock[i+_9P_RDMA_OUT] ; else datalock[i].sender = NULL ; } /* for (unsigned int i=0; i < _9P_RDMA_BUFF_NUM; i++) */ for( i=0; i < _9P_RDMA_OUT; i++) { if( ( rc = msk_post_recv( trans, &rdata[i], _9p_rdma_callback_recv, _9p_rdma_callback_recv_err, &(datalock[i]) ) ) != 0 ) { LogEvent( COMPONENT_9P, "9P/RDMA: trans handler could recv first byte of datalock[%u], rc=%u", i, rc ) ; goto error ; } } /* Finalize accept */ if( ( rc = msk_finalize_accept( trans ) ) != 0 ) { LogMajor( COMPONENT_9P, "9P/RDMA: trans handler could not finalize accept, rc=%u", rc ) ; goto error ; } pthread_exit( NULL ) ; error: _9p_rdma_cleanup_conn_thread( trans ) ; pthread_exit( NULL ) ; } /* _9p_rdma_handle_trans */
void *LUSTREFSAL_UP_Thread(void *Arg) { const struct fsal_up_vector *event_func; struct lustre_filesystem *lustre_fs = Arg; struct lcap_cl_ctx *ctx = NULL; struct changelog_rec *rec; struct changelog_ext_jobid *jid; struct changelog_ext_rename *rnm; int flags = LCAP_CL_DIRECT|LCAP_CL_JOBID; int rc; long long last_idx = 0LL; long long managed_idx = 0LL; unsigned int req_count = 0; /* For wanting of a llapi call to get this information */ /* @todo: use information form fsal_filesystem here */ const char mdtname[] = "lustre-MDT0000"; const char chlg_reader[] = "cl1"; char my_jobid[JOBID_LEN]; /* Compute my jobid */ snprintf(my_jobid, JOBID_LEN, "%s.%d", exec_name, getuid()); /* get the FSAL_UP vector */ event_func = lustre_fs->up_ops; if (event_func == NULL) { LogFatal(COMPONENT_FSAL_UP, "FSAL up vector does not exist. Can not continue."); gsh_free(Arg); return NULL; } LogFullDebug(COMPONENT_FSAL_UP, "Initializing callback thread for %s MDT=%s my_jobid=%s", lustre_fs->fsname, mdtname, my_jobid); /* Wait for 2 seconds, until the rest of the server starts */ sleep(2); /* Main loop */ last_idx = 0LL; managed_idx = 0LL; while (true) { /* open changelog reading channel in lcap */ rc = lcap_changelog_start(&ctx, flags, mdtname, last_idx); if (rc) { LogFatal(COMPONENT_FSAL_UP, "could not read changelog, " "lcap_changelog_start:(%d,%s)", rc, strerror(-rc)); return NULL; } while ((rc = lcap_changelog_recv(ctx, &rec)) == 0) { if (rec->cr_flags & CLF_JOBID) jid = changelog_rec_jobid(rec); else break; if (rec->cr_index > managed_idx) { managed_idx = rec->cr_index; last_idx = rec->cr_index; req_count += 1; /* If jobid is an empty string, skip it */ if (jid->cr_jid[0] == '\0') { rc = lcap_changelog_free(ctx, &rec); if (rc) LogFatal(COMPONENT_FSAL_UP, "lcap_changelog_free: " "%d,%s\n", rc, strerror(-rc)); continue; } /* Do not care for records generated * by Ganesha's activity */ if (!strcmp(jid->cr_jobid, my_jobid)) { rc = lcap_changelog_free(ctx, &rec); if (rc) LogFatal(COMPONENT_FSAL_UP, "lcap_changelog_free: " "%d,%s\n", rc, strerror(-rc)); continue; } rc = lustre_changelog_upcall(lustre_fs, event_func, rec); if (rc) LogMajor(COMPONENT_FSAL, "error occured when dealing" " with a changelog record"); rc = lcap_changelog_free(ctx, &rec); if (rc) LogFatal(COMPONENT_FSAL_UP, "lcap_changelog_free: %d,%s\n", rc, strerror(-rc)); } } if (req_count > FLUSH_REQ_COUNT) { rc = lcap_changelog_clear(ctx, mdtname, chlg_reader, last_idx); if (rc) LogDebug(COMPONENT_FSAL_UP, "lcap_changelog_clear() exited" " with status %d, %s", rc, strerror(-rc)); else LogDebug(COMPONENT_FSAL_UP, "changelog records cleared"); req_count = 0; } /* clear si req_count > 0 et eof sans avoir vu de records */ if (rc < 0) LogDebug(COMPONENT_FSAL_UP, "lcap_changelog_recv() loop exited" " with status %d, %s", rc, strerror(-rc)); /* Close changelog file */ rc = lcap_changelog_fini(ctx); if (rc) LogFatal(COMPONENT_FSAL_UP, "lcap_changelog_fini: %d,%s\n", rc, strerror(-rc)); last_idx = 0LL; /* Sleep for one second to avoid too aggressive polling * on LUSTRE changelogs */ sleep(1); } return NULL; }
void InputDeviceSingleton::BeginJoystickCalibration() { int msgColor = makecol(255, 255, 255); int bgColor = makecol(0, 0, 255); // for each joystick, run a calibration sequence for (int index = 0; index < num_joysticks; index++) { // clear the screen clear_to_color(screen, bgColor); // while the jostick needs to be calibrated while (joy[index].flags & JOYFLAG_CALIBRATE) { // get the calibration message const char* message = calibrate_joystick_name(index); // show the message on the screen textprintf_centre_ex(screen, font, SCREEN_W / 2, SCREEN_H / 2, msgColor, -1, "%s, and press a key.", message); // read a key readkey(); // try to calibrate the joystick if (0 != calibrate_joystick(index)) { // show a message that we failed textprintf_centre_ex(screen, font, SCREEN_W / 2, 64 + (SCREEN_H / 2), msgColor, -1, "Could not calibrate the Joystick!"); // read a key readkey(); // and bail with a fatal error LogFatal("Could not calibrate the joystick!"); } } } // try to save the calibration data to a file if (0 != save_joystick_data("joysettings.dat")) { // clear the screen to red clear_to_color(screen, makecol(255, 0, 0)); // show a message on the screen textprintf_centre_ex(screen, font, SCREEN_W / 2, SCREEN_H / 2, makecol(255, 255, 0), -1, "Joystick Calibration data file could not be saved! Press a key to exit the program."); // read a key readkey(); LogFatal("Joystick Calibration data file could not be saved! Program will now exit!"); } // clear the screen clear_to_color(screen, bgColor); // show a message on the screen textprintf_centre_ex(screen, font, SCREEN_W / 2, SCREEN_H / 2, msgColor, -1, "Joysticks have been calibrated. Press a key to exit the program."); // read a key readkey(); // log a message that the joysticks were calibrated LogMessage("Joysticks calibrated! Program Exiting..."); exit(1); }
bool C4Application::PreInit() { // startup dialog: Only use if no next mission has been provided bool fUseStartupDialog = !Game.HasScenario(); // Load graphics early, before we draw anything, since we need shaders // loaded to draw. Game.SetInitProgress(0.0f); Log(LoadResStr("IDS_PRC_GFXRES")); if (!GraphicsResource.Init()) return false; Game.SetInitProgress(fUseStartupDialog ? 10.0f : 1.0f); // Startup message board if (!isEditor) if (Config.Graphics.ShowStartupMessages || Game.NetworkActive) { C4Facet cgo; cgo.Set(FullScreen.pSurface,0,0,C4GUI::GetScreenWdt(), C4GUI::GetScreenHgt()); GraphicsSystem.MessageBoard->Init(cgo,true); } // init loader: Black screen for first start if a video is to be shown; otherwise default spec if (fUseStartupDialog && !isEditor) { if (!::GraphicsSystem.InitLoaderScreen(C4CFN_StartupBackgroundMain)) { LogFatal(LoadResStr("IDS_PRC_ERRLOADER")); return false; } } Game.SetInitProgress(fUseStartupDialog ? 20.0f : 2.0f); if (!Game.PreInit()) return false; // Music if (!MusicSystem.Init("frontend")) Log(LoadResStr("IDS_PRC_NOMUSIC")); Game.SetInitProgress(fUseStartupDialog ? 34.0f : 2.0f); // Sound if (!SoundSystem.Init()) Log(LoadResStr("IDS_PRC_NOSND")); // Play some music! - after sound init because sound system might be needed by music system if (fUseStartupDialog && !isEditor && Config.Sound.FEMusic) MusicSystem.Play(); Game.SetInitProgress(fUseStartupDialog ? 35.0f : 3.0f); if (fUseStartupDialog) { AppState = C4AS_Startup; // default record? Game.Record = Game.Record || Config.General.DefRec; // if no scenario or direct join has been specified, get game startup parameters by startup dialog if (!isEditor) C4Startup::InitStartup(); } // directly launch scenario / network game else { AppState = C4AS_StartGame; } return true; }
static void initialize_remote_filesystem(char **argv, int hasLocalFilesystem) { #ifdef OMIT_NFS_SUPPORT printf ("***** Initializing TFTP *****\n"); #if __RTEMS_MAJOR__>4 || \ (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \ (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) mount_and_make_target_path(NULL, "/TFTP", RTEMS_FILESYSTEM_TYPE_TFTPFS, RTEMS_FILESYSTEM_READ_WRITE, NULL); #else rtems_bsdnet_initialize_tftp_filesystem (); #endif if (!hasLocalFilesystem) { char *path; int pathsize = 200; int l; path = mustMalloc(pathsize, "Command path name "); strcpy (path, "/TFTP/BOOTP_HOST/epics/"); l = strlen (path); if (gethostname (&path[l], pathsize - l - 10) || (path[l] == '\0')) { LogFatal ("Can't get host name"); } strcat (path, "/st.cmd"); argv[1] = path; } #else char *server_name; char *server_path; char *mount_point; char *cp; int l = 0; printf ("***** Initializing NFS *****\n"); NFS_INIT if (env_nfsServer && env_nfsPath && env_nfsMountPoint) { server_name = env_nfsServer; server_path = env_nfsPath; mount_point = env_nfsMountPoint; cp = mount_point; while ((cp = strchr(cp+1, '/')) != NULL) { *cp = '\0'; if ((mkdir (mount_point, 0755) != 0) && (errno != EEXIST)) LogFatal("Can't create directory \"%s\": %s.\n", mount_point, strerror(errno)); *cp = '/'; } argv[1] = rtems_bsdnet_bootp_cmdline; } else if (hasLocalFilesystem) { return; } else { /* * Use first component of nvram/bootp command line pathname * to set up initial NFS mount. A "/tftpboot/" is prepended * if the pathname does not begin with a '/'. This allows * NFS and TFTP to have a similar view of the remote system. */ if (rtems_bsdnet_bootp_cmdline[0] == '/') cp = rtems_bsdnet_bootp_cmdline + 1; else cp = rtems_bsdnet_bootp_cmdline; cp = strchr(cp, '/'); if ((cp == NULL) || ((l = cp - rtems_bsdnet_bootp_cmdline) == 0)) LogFatal("\"%s\" is not a valid command pathname.\n", rtems_bsdnet_bootp_cmdline); cp = mustMalloc(l + 20, "NFS mount paths"); server_path = cp; server_name = rtems_bsdnet_bootp_server_name; if (rtems_bsdnet_bootp_cmdline[0] == '/') { mount_point = server_path; strncpy(mount_point, rtems_bsdnet_bootp_cmdline, l); mount_point[l] = '\0'; argv[1] = rtems_bsdnet_bootp_cmdline; /* * Its probably common to embed the mount point in the server * name so, when this is occurring, dont clobber the mount point * by appending the first node from the command path. This allows * the mount point to be a different path then the server's mount * path. * * This allows for example a line similar to as follows the DHCP * configuration file. * * server-name "[email protected]:/vol/vol0/bootRTEMS"; */ if ( server_name ) { const size_t allocSize = strlen ( server_name ) + 2; char * const pServerName = mustMalloc( allocSize, "NFS mount paths"); char * const pServerPath = mustMalloc ( allocSize, "NFS mount paths"); const int scanfStatus = sscanf ( server_name, "%[^:] : / %s", pServerName, pServerPath + 1u ); if ( scanfStatus == 2 ) { pServerPath[0u]= '/'; server_name = pServerName; server_path = pServerPath; } else { free ( pServerName ); free ( pServerPath ); } } } else { char *abspath = mustMalloc(strlen(rtems_bsdnet_bootp_cmdline)+2,"Absolute command path"); strcpy(server_path, "/tftpboot/"); mount_point = server_path + strlen(server_path); strncpy(mount_point, rtems_bsdnet_bootp_cmdline, l); mount_point[l] = '\0'; mount_point--; strcpy(abspath, "/"); strcat(abspath, rtems_bsdnet_bootp_cmdline); argv[1] = abspath; } } nfsMount(server_name, server_path, mount_point); #endif }
static fsal_status_t makesymlink(struct fsal_obj_handle *dir_hdl, const struct req_op_context *opctx, const char *name, const char *link_path, struct attrlist *attrib, struct fsal_obj_handle **handle) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct stat sb; struct glfs_object *glhandle = NULL; unsigned char globjhdl[GLAPI_HANDLE_LENGTH]; struct glusterfs_handle *objhandle = NULL; struct glusterfs_export *glfs_export = container_of(dir_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *parenthandle = container_of(dir_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif rc = setglustercreds(glfs_export, &opctx->creds->caller_uid, &opctx->creds->caller_gid, opctx->creds->caller_glen, opctx->creds->caller_garray); if (rc != 0) { status = gluster2fsal_error(EPERM); LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials"); goto out; } /* FIXME: what else from attrib should we use? */ glhandle = glfs_h_symlink(glfs_export->gl_fs, parenthandle->glhandle, name, link_path, &sb); rc = setglustercreds(glfs_export, NULL, NULL, 0, NULL); if (rc != 0) { status = gluster2fsal_error(EPERM); LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials"); goto out; } if (glhandle == NULL) { status = gluster2fsal_error(errno); goto out; } rc = glfs_h_extract_handle(glhandle, globjhdl, GLAPI_HANDLE_LENGTH); if (rc < 0) { status = gluster2fsal_error(errno); goto out; } rc = construct_handle(glfs_export, &sb, glhandle, globjhdl, GLAPI_HANDLE_LENGTH, &objhandle); if (rc != 0) { status = gluster2fsal_error(rc); goto out; } *handle = &objhandle->handle; *attrib = objhandle->handle.attributes; out: if (status.major != ERR_FSAL_NO_ERROR) { gluster_cleanup_vars(glhandle); } #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_makesymlink); #endif return status; }
void *_9p_socket_thread(void *Arg) { long int tcp_sock = (long int)Arg; int rc = -1; struct pollfd fds[1]; int fdcount = 1; static char my_name[MAXNAMLEN + 1]; socklen_t addrpeerlen = 0; struct sockaddr_storage addrpeer; char strcaller[INET6_ADDRSTRLEN]; request_data_t *req = NULL; int tag; unsigned long sequence = 0; unsigned int i = 0; char *_9pmsg = NULL; uint32_t msglen; struct _9p_conn _9p_conn; int readlen = 0; int total_readlen = 0; snprintf(my_name, MAXNAMLEN, "9p_sock_mgr#fd=%ld", tcp_sock); SetNameFunction(my_name); /* Init the struct _9p_conn structure */ memset(&_9p_conn, 0, sizeof(_9p_conn)); pthread_mutex_init(&_9p_conn.sock_lock, NULL); _9p_conn.trans_type = _9P_TCP; _9p_conn.trans_data.sockfd = tcp_sock; for (i = 0; i < FLUSH_BUCKETS; i++) { pthread_mutex_init(&_9p_conn.flush_buckets[i].lock, NULL); glist_init(&_9p_conn.flush_buckets[i].list); } atomic_store_uint32_t(&_9p_conn.refcount, 0); /* Init the fids pointers array */ memset(&_9p_conn.fids, 0, _9P_FID_PER_CONN * sizeof(struct _9p_fid *)); /* Set initial msize. * Client may request a lower value during TVERSION */ _9p_conn.msize = _9p_param._9p_tcp_msize; if (gettimeofday(&_9p_conn.birth, NULL) == -1) LogFatal(COMPONENT_9P, "Cannot get connection's time of birth"); addrpeerlen = sizeof(addrpeer); rc = getpeername(tcp_sock, (struct sockaddr *)&addrpeer, &addrpeerlen); if (rc == -1) { LogMajor(COMPONENT_9P, "Cannot get peername to tcp socket for 9p, error %d (%s)", errno, strerror(errno)); /* XXX */ strncpy(strcaller, "(unresolved)", INET6_ADDRSTRLEN); strcaller[12] = '\0'; } else { switch (addrpeer.ss_family) { case AF_INET: inet_ntop(addrpeer.ss_family, &((struct sockaddr_in *)&addrpeer)-> sin_addr, strcaller, INET6_ADDRSTRLEN); break; case AF_INET6: inet_ntop(addrpeer.ss_family, &((struct sockaddr_in6 *)&addrpeer)-> sin6_addr, strcaller, INET6_ADDRSTRLEN); break; default: snprintf(strcaller, INET6_ADDRSTRLEN, "BAD ADDRESS"); break; } LogEvent(COMPONENT_9P, "9p socket #%ld is connected to %s", tcp_sock, strcaller); printf("9p socket #%ld is connected to %s\n", tcp_sock, strcaller); } _9p_conn.client = get_gsh_client(&addrpeer, false); /* Set up the structure used by poll */ memset((char *)fds, 0, sizeof(struct pollfd)); fds[0].fd = tcp_sock; fds[0].events = POLLIN | POLLPRI | POLLRDBAND | POLLRDNORM | POLLRDHUP | POLLHUP | POLLERR | POLLNVAL; for (;;) { total_readlen = 0; /* new message */ rc = poll(fds, fdcount, -1); if (rc == -1) { /* timeout = -1 => Wait indefinitely for events */ /* Interruption if not an issue */ if (errno == EINTR) continue; LogCrit(COMPONENT_9P, "Got error %u (%s) on fd %ld connect to %s while polling on socket", errno, strerror(errno), tcp_sock, strcaller); } if (fds[0].revents & POLLNVAL) { LogEvent(COMPONENT_9P, "Client %s on socket %lu produced POLLNVAL", strcaller, tcp_sock); goto end; } if (fds[0].revents & (POLLERR | POLLHUP | POLLRDHUP)) { LogEvent(COMPONENT_9P, "Client %s on socket %lu has shut down and closed", strcaller, tcp_sock); goto end; } if (!(fds[0].revents & (POLLIN | POLLRDNORM))) continue; /* Prepare to read the message */ _9pmsg = gsh_malloc(_9p_conn.msize); if (_9pmsg == NULL) { LogCrit(COMPONENT_9P, "Could not allocate 9pmsg buffer for client %s on socket %lu", strcaller, tcp_sock); goto end; } /* An incoming 9P request: the msg has a 4 bytes header showing the size of the msg including the header */ readlen = recv(fds[0].fd, _9pmsg, _9P_HDR_SIZE, MSG_WAITALL); if (readlen != _9P_HDR_SIZE) goto badmsg; msglen = *(uint32_t *) _9pmsg; if (msglen > _9p_conn.msize) { LogCrit(COMPONENT_9P, "Message size too big! got %u, max = %u", msglen, _9p_conn.msize); goto end; } LogFullDebug(COMPONENT_9P, "Received 9P/TCP message of size %u from client %s on socket %lu", msglen, strcaller, tcp_sock); total_readlen += readlen; while (total_readlen < msglen) { readlen = recv(fds[0].fd, _9pmsg + total_readlen, msglen - total_readlen, 0); if (readlen > 0) { total_readlen += readlen; continue; } if (readlen == 0 || (readlen < 0 && errno != EINTR)) goto badmsg; } /* while */ server_stats_transport_done(_9p_conn.client, total_readlen, 1, 0, 0, 0, 0); /* Message is good. */ req = pool_alloc(request_pool, NULL); req->rtype = _9P_REQUEST; req->r_u._9p._9pmsg = _9pmsg; req->r_u._9p.pconn = &_9p_conn; /* Add this request to the request list, * should it be flushed later. */ tag = *(u16 *) (_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE); _9p_AddFlushHook(&req->r_u._9p, tag, sequence++); LogFullDebug(COMPONENT_9P, "Request tag is %d\n", tag); /* Message was OK push it */ DispatchWork9P(req); /* Not our buffer anymore */ _9pmsg = NULL; continue; badmsg: if (readlen == 0) LogEvent(COMPONENT_9P, "Premature end for Client %s on socket %lu, total read = %u", strcaller, tcp_sock, total_readlen); else if (readlen < 0) { LogEvent(COMPONENT_9P, "Read error client %s on socket %lu errno=%d, total read = %u", strcaller, tcp_sock, errno, total_readlen); } else LogEvent(COMPONENT_9P, "Header too small! for client %s on socket %lu: readlen=%u expected=%u", strcaller, tcp_sock, readlen, _9P_HDR_SIZE); /* Either way, we close the connection. * It is not possible to survive * once we get out of sync in the TCP stream * with the client */ break; /* bail out */ } /* for( ;; ) */ end: LogEvent(COMPONENT_9P, "Closing connection on socket %lu", tcp_sock); close(tcp_sock); /* Free buffer if we encountered an error * before we could give it to a worker */ if (_9pmsg) gsh_free(_9pmsg); while (atomic_fetch_uint32_t(&_9p_conn.refcount)) { LogEvent(COMPONENT_9P, "Waiting for workers to release pconn"); sleep(1); } _9p_cleanup_fids(&_9p_conn); if (_9p_conn.client != NULL) put_gsh_client(_9p_conn.client); pthread_exit(NULL); } /* _9p_socket_thread */
/** * _9p_create_socket: create the accept socket for 9P * * This function create the accept socket for the 9p dispatcher thread. * * @return socket fd or -1 if failed. * */ int _9p_create_socket(void) { int sock = -1; int one = 1; int centvingt = 120; int neuf = 9; struct sockaddr_in6 sinaddr_tcp6; struct netbuf netbuf_tcp6; struct t_bind bindaddr_tcp6; struct __rpc_sockinfo si_tcp6; sock = socket(P_FAMILY, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) goto bad_socket; if ((setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) || (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) == -1) || (setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, ¢vingt, sizeof(centvingt)) == -1) || (setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, ¢vingt, sizeof(centvingt)) == -1) || (setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &neuf, sizeof(neuf)) == -1)) goto bad_socket; socket_setoptions(sock); memset(&sinaddr_tcp6, 0, sizeof(sinaddr_tcp6)); sinaddr_tcp6.sin6_family = AF_INET6; /* All the interfaces on the machine are used */ sinaddr_tcp6.sin6_addr = in6addr_any; sinaddr_tcp6.sin6_port = htons(_9p_param._9p_tcp_port); netbuf_tcp6.maxlen = sizeof(sinaddr_tcp6); netbuf_tcp6.len = sizeof(sinaddr_tcp6); netbuf_tcp6.buf = &sinaddr_tcp6; bindaddr_tcp6.qlen = SOMAXCONN; bindaddr_tcp6.addr = netbuf_tcp6; if (!__rpc_fd2sockinfo(sock, &si_tcp6)) { LogFatal(COMPONENT_DISPATCH, "Cannot get 9p socket info for tcp6 socket errno=%d (%s)", errno, strerror(errno)); return -1; } if (bind(sock, (struct sockaddr *)bindaddr_tcp6.addr.buf, (socklen_t) si_tcp6.si_alen) == -1) { LogFatal(COMPONENT_DISPATCH, "Cannot bind 9p tcp6 socket, error %d (%s)", errno, strerror(errno)); return -1; } if (listen(sock, 20) == -1) { LogFatal(COMPONENT_DISPATCH, "Cannot bind 9p tcp6 socket, error %d (%s)", errno, strerror(errno)); return -1; } return sock; bad_socket: LogFatal(COMPONENT_9P_DISPATCH, "Bad socket option 9p, error %d (%s)", errno, strerror(errno)); return -1; } /* _9p_create_socket */
/* Partition table parser */ int VfsParsePartitionTable(DevId_t DiskId, uint64_t SectorBase, uint64_t SectorCount, uint32_t SectorSize) { /* Allocate structures */ void *TmpBuffer = (void*)kmalloc(SectorSize); MCoreModule_t *Module = NULL; MCoreMasterBootRecord_t *Mbr = NULL; MCoreDeviceRequest_t Request; int PartitionCount = 0; int i; /* Read sector */ Request.Type = RequestRead; Request.DeviceId = DiskId; Request.SectorLBA = SectorBase; Request.Buffer = (uint8_t*)TmpBuffer; Request.Length = SectorSize; /* Create & Wait */ DmCreateRequest(&Request); DmWaitRequest(&Request); /* Sanity */ if (Request.Status != RequestOk) { /* Error */ LogFatal("VFSM", "REGISTERDISK: Error reading from disk - 0x%x\n", Request.Status); kfree(TmpBuffer); return 0; } _CRT_UNUSED(SectorCount); /* Cast */ Mbr = (MCoreMasterBootRecord_t*)TmpBuffer; /* Valid partition table? */ for (i = 0; i < 4; i++) { /* Is it an active partition? */ if (Mbr->Partitions[i].Status == PARTITION_ACTIVE) { /* Inc */ PartitionCount++; /* Allocate a filesystem structure */ MCoreFileSystem_t *Fs = (MCoreFileSystem_t*)kmalloc(sizeof(MCoreFileSystem_t)); Fs->State = VfsStateInit; Fs->DiskId = DiskId; Fs->FsData = NULL; Fs->SectorStart = SectorBase + Mbr->Partitions[i].LbaSector; Fs->SectorCount = Mbr->Partitions[i].LbaSize; Fs->Id = GlbFileSystemId; Fs->SectorSize = SectorSize; /* Check extended partitions first */ if (Mbr->Partitions[i].Type == 0x05) { /* Extended - CHS */ } else if (Mbr->Partitions[i].Type == 0x0F || Mbr->Partitions[i].Type == 0xCF) { /* Extended - LBA */ PartitionCount += VfsParsePartitionTable(DiskId, SectorBase + Mbr->Partitions[i].LbaSector, Mbr->Partitions[i].LbaSize, SectorSize); } else if (Mbr->Partitions[i].Type == 0xEE) { /* GPT Formatted */ } /* Check MFS */ else if (Mbr->Partitions[i].Type == 0x61) { /* MFS 1 */ Module = ModuleFind(MODULE_FILESYSTEM, FILESYSTEM_MFS); /* Load */ if (Module != NULL) ModuleLoad(Module, Fs); } /* Check FAT */ else if (Mbr->Partitions[i].Type == 0x1 || Mbr->Partitions[i].Type == 0x6 || Mbr->Partitions[i].Type == 0x8 /* Might be FAT16 */ || Mbr->Partitions[i].Type == 0x11 /* Might be FAT16 */ || Mbr->Partitions[i].Type == 0x14 /* Might be FAT16 */ || Mbr->Partitions[i].Type == 0x24 /* Might be FAT16 */ || Mbr->Partitions[i].Type == 0x56 /* Might be FAT16 */ || Mbr->Partitions[i].Type == 0x8D || Mbr->Partitions[i].Type == 0xAA || Mbr->Partitions[i].Type == 0xC1 || Mbr->Partitions[i].Type == 0xD1 || Mbr->Partitions[i].Type == 0xE1 || Mbr->Partitions[i].Type == 0xE5 || Mbr->Partitions[i].Type == 0xEF || Mbr->Partitions[i].Type == 0xF2) { /* Fat-12 */ } else if (Mbr->Partitions[i].Type == 0x4 || Mbr->Partitions[i].Type == 0x6 || Mbr->Partitions[i].Type == 0xE || Mbr->Partitions[i].Type == 0x16 || Mbr->Partitions[i].Type == 0x1E || Mbr->Partitions[i].Type == 0x90 || Mbr->Partitions[i].Type == 0x92 || Mbr->Partitions[i].Type == 0x9A || Mbr->Partitions[i].Type == 0xC4 || Mbr->Partitions[i].Type == 0xC6 || Mbr->Partitions[i].Type == 0xCE || Mbr->Partitions[i].Type == 0xD4 || Mbr->Partitions[i].Type == 0xD6) { /* Fat16 */ } else if (Mbr->Partitions[i].Type == 0x0B /* CHS */ || Mbr->Partitions[i].Type == 0x0C /* LBA */ || Mbr->Partitions[i].Type == 0x27 || Mbr->Partitions[i].Type == 0xCB || Mbr->Partitions[i].Type == 0xCC) { /* Fat32 */ } /* Lastly */ if (Fs->State == VfsStateActive) VfsInstallFileSystem(Fs); else kfree(Fs); } } /* Done */ kfree(TmpBuffer); return PartitionCount; }
void *stats_thread(void *addr) { FILE *stats_file = NULL; struct stat statref; struct stat stattest; time_t current_time; struct tm current_time_struct; struct tm boot_time_struct; char strdate[1024]; char strbootdate[1024]; unsigned int i = 0; unsigned int j = 0; int reopen_stats = FALSE; nfs_worker_data_t *workers_data = addr; cache_inode_stat_t global_cache_inode_stat; nfs_worker_stat_t global_worker_stat; hash_stat_t hstat; hash_stat_t hstat_reverse; unsigned long long total_fsal_calls; fsal_statistics_t global_fsal_stat; unsigned int min_pending_request; unsigned int max_pending_request; unsigned int total_pending_request; unsigned int average_pending_request; unsigned int len_pending_request = 0; unsigned int avg_latency; #ifndef _NO_BUDDY_SYSTEM int rc = 0; buddy_stats_t global_buddy_stat; #endif SetNameFunction("stat_thr"); #ifndef _NO_BUDDY_SYSTEM if((rc = BuddyInit(NULL)) != BUDDY_SUCCESS) { /* Failed init */ LogFatal(COMPONENT_MAIN, "NFS STATS : Memory manager could not be initialized"); } LogInfo(COMPONENT_MAIN, "NFS STATS : Memory manager successfully initialized"); #endif /* Open the stats file, in append mode */ if((stats_file = fopen(nfs_param.core_param.stats_file_path, "a")) == NULL) { LogCrit(COMPONENT_MAIN, "NFS STATS : Could not open stats file %s, no stats will be made...", nfs_param.core_param.stats_file_path); return NULL; } if(stat(nfs_param.core_param.stats_file_path, &statref) != 0) { LogCrit(COMPONENT_MAIN, "NFS STATS : Could not get inode for %s, no stats will be made...", nfs_param.core_param.stats_file_path); fclose(stats_file); return NULL; } #ifdef _SNMP_ADM_ACTIVE /* start snmp library */ if(stats_snmp(workers_data) == 0) LogInfo(COMPONENT_MAIN, "NFS STATS: SNMP stats service was started successfully"); else LogCrit(COMPONENT_MAIN, "NFS STATS: ERROR starting SNMP stats export thread"); #endif /*_SNMP_ADM_ACTIVE*/ while(1) { /* Initial wait */ sleep(nfs_param.core_param.stats_update_delay); /* Debug trace */ LogInfo(COMPONENT_MAIN, "NFS STATS : now dumping stats"); /* Stats main loop */ if(stat(nfs_param.core_param.stats_file_path, &stattest) == 0) { if(stattest.st_ino != statref.st_ino) reopen_stats = TRUE; } else { if(errno == ENOENT) reopen_stats = TRUE; } /* Check is file has changed (the inode number will be different) */ if(reopen_stats == TRUE) { /* Stats file has changed */ LogEvent(COMPONENT_MAIN, "NFS STATS : stats file has changed or was removed, I close and reopen it"); fflush(stats_file); fclose(stats_file); if((stats_file = fopen(nfs_param.core_param.stats_file_path, "a")) == NULL) { LogCrit(COMPONENT_MAIN, "NFS STATS : Could not open stats file %s, no further stats will be made...", nfs_param.core_param.stats_file_path); return NULL; } statref = stattest; reopen_stats = FALSE; } /* Get the current epoch time */ current_time = time(NULL); memcpy(¤t_time_struct, localtime(¤t_time), sizeof(current_time_struct)); snprintf(strdate, 1024, "%u, %.2d/%.2d/%.4d %.2d:%.2d:%.2d ", (unsigned int)current_time, current_time_struct.tm_mday, current_time_struct.tm_mon + 1, 1900 + current_time_struct.tm_year, current_time_struct.tm_hour, current_time_struct.tm_min, current_time_struct.tm_sec); /* Printing the general Stats */ memcpy(&boot_time_struct, localtime(&ServerBootTime), sizeof(boot_time_struct)); snprintf(strbootdate, 1024, "%u, %.2d/%.2d/%.4d %.2d:%.2d:%.2d ", (unsigned int)ServerBootTime, boot_time_struct.tm_mday, boot_time_struct.tm_mon + 1, 1900 + boot_time_struct.tm_year, boot_time_struct.tm_hour, boot_time_struct.tm_min, boot_time_struct.tm_sec); fprintf(stats_file, "NFS_SERVER_GENERAL,%s;%s\n", strdate, strbootdate); /* Zeroing the cache_stats */ global_cache_inode_stat.nb_gc_lru_active = 0; global_cache_inode_stat.nb_gc_lru_total = 0; global_cache_inode_stat.nb_call_total = 0; memset(global_cache_inode_stat.func_stats.nb_err_unrecover, 0, sizeof(unsigned int) * CACHE_INODE_NB_COMMAND); /* Merging the cache inode stats for every thread */ for(i = 0; i < nfs_param.core_param.nb_worker; i++) { global_cache_inode_stat.nb_gc_lru_active += workers_data[i].cache_inode_client.stat.nb_gc_lru_active; global_cache_inode_stat.nb_gc_lru_total += workers_data[i].cache_inode_client.stat.nb_gc_lru_total; global_cache_inode_stat.nb_call_total += workers_data[i].cache_inode_client.stat.nb_call_total; for(j = 0; j < CACHE_INODE_NB_COMMAND; j++) { if(i == 0) { global_cache_inode_stat.func_stats.nb_success[j] = workers_data[i].cache_inode_client.stat.func_stats.nb_success[j]; global_cache_inode_stat.func_stats.nb_call[j] = workers_data[i].cache_inode_client.stat.func_stats.nb_call[j]; global_cache_inode_stat.func_stats.nb_err_retryable[j] = workers_data[i].cache_inode_client.stat.func_stats. nb_err_retryable[j]; global_cache_inode_stat.func_stats.nb_err_unrecover[j] = workers_data[i].cache_inode_client.stat.func_stats. nb_err_unrecover[j]; } else { global_cache_inode_stat.func_stats.nb_success[j] += workers_data[i].cache_inode_client.stat.func_stats.nb_success[j]; global_cache_inode_stat.func_stats.nb_call[j] += workers_data[i].cache_inode_client.stat.func_stats.nb_call[j]; global_cache_inode_stat.func_stats.nb_err_retryable[j] += workers_data[i].cache_inode_client.stat.func_stats. nb_err_retryable[j]; global_cache_inode_stat.func_stats.nb_err_unrecover[j] += workers_data[i].cache_inode_client.stat.func_stats. nb_err_unrecover[j]; } } } /* Printing the cache_inode stat */ fprintf(stats_file, "CACHE_INODE_CALLS,%s;%u,%u,%u", strdate, global_cache_inode_stat.nb_call_total, global_cache_inode_stat.nb_gc_lru_total, global_cache_inode_stat.nb_gc_lru_active); for(j = 0; j < CACHE_INODE_NB_COMMAND; j++) fprintf(stats_file, "|%u,%u,%u,%u", global_cache_inode_stat.func_stats.nb_call[j], global_cache_inode_stat.func_stats.nb_success[j], global_cache_inode_stat.func_stats.nb_err_retryable[j], global_cache_inode_stat.func_stats.nb_err_unrecover[j]); fprintf(stats_file, "\n"); /* Pinting the cache inode hash stat */ /* This is done only on worker[0]: the hashtable is shared and worker 0 always exists */ HashTable_GetStats(workers_data[0].ht, &hstat); fprintf(stats_file, "CACHE_INODE_HASH,%s;%u,%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u\n", strdate, hstat.dynamic.nb_entries, hstat.computed.min_rbt_num_node, hstat.computed.max_rbt_num_node, hstat.computed.average_rbt_num_node, hstat.dynamic.ok.nb_set, hstat.dynamic.notfound.nb_set, hstat.dynamic.err.nb_set, hstat.dynamic.ok.nb_test, hstat.dynamic.notfound.nb_test, hstat.dynamic.err.nb_test, hstat.dynamic.ok.nb_get, hstat.dynamic.notfound.nb_get, hstat.dynamic.err.nb_get, hstat.dynamic.ok.nb_del, hstat.dynamic.notfound.nb_del, hstat.dynamic.err.nb_del); /* Merging the NFS protocols stats together */ global_worker_stat.nb_total_req = 0; global_worker_stat.nb_udp_req = 0; global_worker_stat.nb_tcp_req = 0; global_worker_stat.stat_req.nb_mnt1_req = 0; global_worker_stat.stat_req.nb_mnt3_req = 0; global_worker_stat.stat_req.nb_nfs2_req = 0; global_worker_stat.stat_req.nb_nfs3_req = 0; global_worker_stat.stat_req.nb_nfs4_req = 0; global_worker_stat.stat_req.nb_nlm4_req = 0; global_worker_stat.stat_req.nb_nfs40_op = 0; global_worker_stat.stat_req.nb_nfs41_op = 0; global_worker_stat.stat_req.nb_rquota1_req = 0; global_worker_stat.stat_req.nb_rquota2_req = 0; /* prepare for computing pending request stats */ min_pending_request = 10000000; max_pending_request = 0; total_pending_request = 0; average_pending_request = 0; len_pending_request = 0; for(i = 0; i < nfs_param.core_param.nb_worker; i++) { global_worker_stat.nb_total_req += workers_data[i].stats.nb_total_req; global_worker_stat.nb_udp_req += workers_data[i].stats.nb_udp_req; global_worker_stat.nb_tcp_req += workers_data[i].stats.nb_tcp_req; global_worker_stat.stat_req.nb_mnt1_req += workers_data[i].stats.stat_req.nb_mnt1_req; global_worker_stat.stat_req.nb_mnt3_req += workers_data[i].stats.stat_req.nb_mnt3_req; global_worker_stat.stat_req.nb_nfs2_req += workers_data[i].stats.stat_req.nb_nfs2_req; global_worker_stat.stat_req.nb_nfs3_req += workers_data[i].stats.stat_req.nb_nfs3_req; global_worker_stat.stat_req.nb_nfs4_req += workers_data[i].stats.stat_req.nb_nfs4_req; global_worker_stat.stat_req.nb_nfs40_op += workers_data[i].stats.stat_req.nb_nfs40_op; global_worker_stat.stat_req.nb_nfs41_op += workers_data[i].stats.stat_req.nb_nfs41_op; global_worker_stat.stat_req.nb_nlm4_req += workers_data[i].stats.stat_req.nb_nlm4_req; global_worker_stat.stat_req.nb_rquota1_req += workers_data[i].stats.stat_req.nb_nlm4_req; global_worker_stat.stat_req.nb_rquota2_req += workers_data[i].stats.stat_req.nb_nlm4_req; for(j = 0; j < MNT_V1_NB_COMMAND; j++) { if(i == 0) { global_worker_stat.stat_req.stat_req_mnt1[j].total = workers_data[i].stats.stat_req.stat_req_mnt1[j].total; global_worker_stat.stat_req.stat_req_mnt1[j].success = workers_data[i].stats.stat_req.stat_req_mnt1[j].success; global_worker_stat.stat_req.stat_req_mnt1[j].dropped = workers_data[i].stats.stat_req.stat_req_mnt1[j].dropped; } else { global_worker_stat.stat_req.stat_req_mnt1[j].total += workers_data[i].stats.stat_req.stat_req_mnt1[j].total; global_worker_stat.stat_req.stat_req_mnt1[j].success += workers_data[i].stats.stat_req.stat_req_mnt1[j].success; global_worker_stat.stat_req.stat_req_mnt1[j].dropped += workers_data[i].stats.stat_req.stat_req_mnt1[j].dropped; } } for(j = 0; j < MNT_V3_NB_COMMAND; j++) { if(i == 0) { global_worker_stat.stat_req.stat_req_mnt3[j].total = workers_data[i].stats.stat_req.stat_req_mnt3[j].total; global_worker_stat.stat_req.stat_req_mnt3[j].success = workers_data[i].stats.stat_req.stat_req_mnt3[j].success; global_worker_stat.stat_req.stat_req_mnt3[j].dropped = workers_data[i].stats.stat_req.stat_req_mnt3[j].dropped; } else { global_worker_stat.stat_req.stat_req_mnt3[j].total += workers_data[i].stats.stat_req.stat_req_mnt3[j].total; global_worker_stat.stat_req.stat_req_mnt3[j].success += workers_data[i].stats.stat_req.stat_req_mnt3[j].success; global_worker_stat.stat_req.stat_req_mnt3[j].dropped += workers_data[i].stats.stat_req.stat_req_mnt3[j].dropped; } } for(j = 0; j < NFS_V2_NB_COMMAND; j++) { if(i == 0) { global_worker_stat.stat_req.stat_req_nfs2[j].total = workers_data[i].stats.stat_req.stat_req_nfs2[j].total; global_worker_stat.stat_req.stat_req_nfs2[j].success = workers_data[i].stats.stat_req.stat_req_nfs2[j].success; global_worker_stat.stat_req.stat_req_nfs2[j].dropped = workers_data[i].stats.stat_req.stat_req_nfs2[j].dropped; } else { global_worker_stat.stat_req.stat_req_nfs2[j].total += workers_data[i].stats.stat_req.stat_req_nfs2[j].total; global_worker_stat.stat_req.stat_req_nfs2[j].success += workers_data[i].stats.stat_req.stat_req_nfs2[j].success; global_worker_stat.stat_req.stat_req_nfs2[j].dropped += workers_data[i].stats.stat_req.stat_req_nfs2[j].dropped; } } for(j = 0; j < NFS_V3_NB_COMMAND; j++) { if(i == 0) { global_worker_stat.stat_req.stat_req_nfs3[j].total = workers_data[i].stats.stat_req.stat_req_nfs3[j].total; global_worker_stat.stat_req.stat_req_nfs3[j].success = workers_data[i].stats.stat_req.stat_req_nfs3[j].success; global_worker_stat.stat_req.stat_req_nfs3[j].dropped = workers_data[i].stats.stat_req.stat_req_nfs3[j].dropped; global_worker_stat.stat_req.stat_req_nfs3[j].tot_latency = workers_data[i].stats.stat_req.stat_req_nfs3[j].tot_latency; global_worker_stat.stat_req.stat_req_nfs3[j].min_latency = workers_data[i].stats.stat_req.stat_req_nfs3[j].min_latency; global_worker_stat.stat_req.stat_req_nfs3[j].max_latency = workers_data[i].stats.stat_req.stat_req_nfs3[j].max_latency; } else { global_worker_stat.stat_req.stat_req_nfs3[j].total += workers_data[i].stats.stat_req.stat_req_nfs3[j].total; global_worker_stat.stat_req.stat_req_nfs3[j].success += workers_data[i].stats.stat_req.stat_req_nfs3[j].success; global_worker_stat.stat_req.stat_req_nfs3[j].dropped += workers_data[i].stats.stat_req.stat_req_nfs3[j].dropped; global_worker_stat.stat_req.stat_req_nfs3[j].tot_latency += workers_data[i].stats.stat_req.stat_req_nfs3[j].tot_latency; set_min_latency(&(global_worker_stat.stat_req.stat_req_nfs3[j]), workers_data[i].stats.stat_req.stat_req_nfs3[j].min_latency); set_max_latency(&(global_worker_stat.stat_req.stat_req_nfs3[j]), workers_data[i].stats.stat_req.stat_req_nfs3[j].max_latency); } } for(j = 0; j < NFS_V4_NB_COMMAND; j++) { if(i == 0) { global_worker_stat.stat_req.stat_req_nfs4[j].total = workers_data[i].stats.stat_req.stat_req_nfs4[j].total; global_worker_stat.stat_req.stat_req_nfs4[j].success = workers_data[i].stats.stat_req.stat_req_nfs4[j].success; global_worker_stat.stat_req.stat_req_nfs4[j].dropped = workers_data[i].stats.stat_req.stat_req_nfs4[j].dropped; } else { global_worker_stat.stat_req.stat_req_nfs4[j].total += workers_data[i].stats.stat_req.stat_req_nfs4[j].total; global_worker_stat.stat_req.stat_req_nfs4[j].success += workers_data[i].stats.stat_req.stat_req_nfs4[j].success; global_worker_stat.stat_req.stat_req_nfs4[j].dropped += workers_data[i].stats.stat_req.stat_req_nfs4[j].dropped; } } for(j = 0; j < NFS_V40_NB_OPERATION; j++) { if(i == 0) { global_worker_stat.stat_req.stat_op_nfs40[j].total = workers_data[i].stats.stat_req.stat_op_nfs40[j].total; global_worker_stat.stat_req.stat_op_nfs40[j].success = workers_data[i].stats.stat_req.stat_op_nfs40[j].success; global_worker_stat.stat_req.stat_op_nfs40[j].failed = workers_data[i].stats.stat_req.stat_op_nfs40[j].failed; } else { global_worker_stat.stat_req.stat_op_nfs40[j].total += workers_data[i].stats.stat_req.stat_op_nfs40[j].total; global_worker_stat.stat_req.stat_op_nfs40[j].success += workers_data[i].stats.stat_req.stat_op_nfs40[j].success; global_worker_stat.stat_req.stat_op_nfs40[j].failed += workers_data[i].stats.stat_req.stat_op_nfs40[j].failed; } } for(j = 0; j < NFS_V41_NB_OPERATION; j++) { if(i == 0) { global_worker_stat.stat_req.stat_op_nfs41[j].total = workers_data[i].stats.stat_req.stat_op_nfs41[j].total; global_worker_stat.stat_req.stat_op_nfs41[j].success = workers_data[i].stats.stat_req.stat_op_nfs41[j].success; global_worker_stat.stat_req.stat_op_nfs41[j].failed = workers_data[i].stats.stat_req.stat_op_nfs41[j].failed; } else { global_worker_stat.stat_req.stat_op_nfs41[j].total += workers_data[i].stats.stat_req.stat_op_nfs41[j].total; global_worker_stat.stat_req.stat_op_nfs41[j].success += workers_data[i].stats.stat_req.stat_op_nfs41[j].success; global_worker_stat.stat_req.stat_op_nfs41[j].failed += workers_data[i].stats.stat_req.stat_op_nfs41[j].failed; } } for(j = 0; j < NLM_V4_NB_OPERATION; j++) { if(i == 0) { global_worker_stat.stat_req.stat_req_nlm4[j].total = workers_data[i].stats.stat_req.stat_req_nlm4[j].total; global_worker_stat.stat_req.stat_req_nlm4[j].success = workers_data[i].stats.stat_req.stat_req_nlm4[j].success; global_worker_stat.stat_req.stat_req_nlm4[j].dropped = workers_data[i].stats.stat_req.stat_req_nlm4[j].dropped; } else { global_worker_stat.stat_req.stat_req_nlm4[j].total += workers_data[i].stats.stat_req.stat_req_nlm4[j].total; global_worker_stat.stat_req.stat_req_nlm4[j].success += workers_data[i].stats.stat_req.stat_req_nlm4[j].success; global_worker_stat.stat_req.stat_req_nlm4[j].dropped += workers_data[i].stats.stat_req.stat_req_nlm4[j].dropped; } } for(j = 0; j < RQUOTA_NB_COMMAND; j++) { if(i == 0) { global_worker_stat.stat_req.stat_req_rquota1[j].total = workers_data[i].stats.stat_req.stat_req_rquota1[j].total; global_worker_stat.stat_req.stat_req_rquota1[j].success = workers_data[i].stats.stat_req.stat_req_rquota1[j].success; global_worker_stat.stat_req.stat_req_rquota1[j].dropped = workers_data[i].stats.stat_req.stat_req_rquota1[j].dropped; global_worker_stat.stat_req.stat_req_rquota2[j].total = workers_data[i].stats.stat_req.stat_req_rquota2[j].total; global_worker_stat.stat_req.stat_req_rquota2[j].success = workers_data[i].stats.stat_req.stat_req_rquota2[j].success; global_worker_stat.stat_req.stat_req_rquota2[j].dropped = workers_data[i].stats.stat_req.stat_req_rquota2[j].dropped; } else { global_worker_stat.stat_req.stat_req_rquota1[j].total += workers_data[i].stats.stat_req.stat_req_rquota1[j].total; global_worker_stat.stat_req.stat_req_rquota1[j].success += workers_data[i].stats.stat_req.stat_req_rquota1[j].success; global_worker_stat.stat_req.stat_req_rquota1[j].dropped += workers_data[i].stats.stat_req.stat_req_rquota1[j].dropped; global_worker_stat.stat_req.stat_req_rquota2[j].total += workers_data[i].stats.stat_req.stat_req_rquota2[j].total; global_worker_stat.stat_req.stat_req_rquota2[j].success += workers_data[i].stats.stat_req.stat_req_rquota2[j].success; global_worker_stat.stat_req.stat_req_rquota2[j].dropped += workers_data[i].stats.stat_req.stat_req_rquota2[j].dropped; } } /* Computing the pending request stats */ len_pending_request = workers_data[i].pending_request->nb_entry - workers_data[i].pending_request->nb_invalid; if(len_pending_request < min_pending_request) min_pending_request = len_pending_request; if(len_pending_request > max_pending_request) max_pending_request = len_pending_request; total_pending_request += len_pending_request; } /* for( i = 0 ; i < nfs_param.core_param.nb_worker ; i++ ) */ /* Compute average pending request */ average_pending_request = total_pending_request / nfs_param.core_param.nb_worker; fprintf(stats_file, "NFS/MOUNT STATISTICS,%s;%u,%u,%u|%u,%u,%u,%u,%u|%u,%u,%u,%u\n", strdate, global_worker_stat.nb_total_req, global_worker_stat.nb_udp_req, global_worker_stat.nb_tcp_req, global_worker_stat.stat_req.nb_mnt1_req, global_worker_stat.stat_req.nb_mnt3_req, global_worker_stat.stat_req.nb_nfs2_req, global_worker_stat.stat_req.nb_nfs3_req, global_worker_stat.stat_req.nb_nfs4_req, total_pending_request, min_pending_request, max_pending_request, average_pending_request); fprintf(stats_file, "MNT V1 REQUEST,%s;%u", strdate, global_worker_stat.stat_req.nb_mnt1_req); for(j = 0; j < MNT_V1_NB_COMMAND; j++) fprintf(stats_file, "|%u,%u,%u", global_worker_stat.stat_req.stat_req_mnt1[j].total, global_worker_stat.stat_req.stat_req_mnt1[j].success, global_worker_stat.stat_req.stat_req_mnt1[j].dropped); fprintf(stats_file, "\n"); fprintf(stats_file, "MNT V3 REQUEST,%s;%u", strdate, global_worker_stat.stat_req.nb_mnt3_req); for(j = 0; j < MNT_V3_NB_COMMAND; j++) fprintf(stats_file, "|%u,%u,%u", global_worker_stat.stat_req.stat_req_mnt3[j].total, global_worker_stat.stat_req.stat_req_mnt3[j].success, global_worker_stat.stat_req.stat_req_mnt3[j].dropped); fprintf(stats_file, "\n"); fprintf(stats_file, "NFS V2 REQUEST,%s;%u", strdate, global_worker_stat.stat_req.nb_nfs2_req); for(j = 0; j < NFS_V2_NB_COMMAND; j++) fprintf(stats_file, "|%u,%u,%u", global_worker_stat.stat_req.stat_req_nfs2[j].total, global_worker_stat.stat_req.stat_req_nfs2[j].success, global_worker_stat.stat_req.stat_req_nfs2[j].dropped); fprintf(stats_file, "\n"); fprintf(stats_file, "NFS V3 REQUEST,%s;%u", strdate, global_worker_stat.stat_req.nb_nfs3_req); for(j = 0; j < NFS_V3_NB_COMMAND; j++) { if(global_worker_stat.stat_req.stat_req_nfs3[j].total > 0) { avg_latency = (global_worker_stat.stat_req.stat_req_nfs3[j].tot_latency / global_worker_stat.stat_req.stat_req_nfs3[j].total); } else { avg_latency = 0; } fprintf(stats_file, "|%u,%u,%u,%u,%u,%u,%u", global_worker_stat.stat_req.stat_req_nfs3[j].total, global_worker_stat.stat_req.stat_req_nfs3[j].success, global_worker_stat.stat_req.stat_req_nfs3[j].dropped, global_worker_stat.stat_req.stat_req_nfs3[j].tot_latency, avg_latency, global_worker_stat.stat_req.stat_req_nfs3[j].min_latency, global_worker_stat.stat_req.stat_req_nfs3[j].max_latency); } fprintf(stats_file, "\n"); fprintf(stats_file, "NFS V4 REQUEST,%s;%u", strdate, global_worker_stat.stat_req.nb_nfs4_req); for(j = 0; j < NFS_V4_NB_COMMAND; j++) fprintf(stats_file, "|%u,%u,%u", global_worker_stat.stat_req.stat_req_nfs4[j].total, global_worker_stat.stat_req.stat_req_nfs4[j].success, global_worker_stat.stat_req.stat_req_nfs4[j].dropped); fprintf(stats_file, "\n"); fprintf(stats_file, "NFS V4.0 OPERATIONS,%s;%u", strdate, global_worker_stat.stat_req.nb_nfs40_op); for(j = 0; j < NFS_V40_NB_OPERATION; j++) fprintf(stats_file, "|%u,%u,%u", global_worker_stat.stat_req.stat_op_nfs40[j].total, global_worker_stat.stat_req.stat_op_nfs40[j].success, global_worker_stat.stat_req.stat_op_nfs40[j].failed); fprintf(stats_file, "\n"); fprintf(stats_file, "NFS V4.1 OPERATIONS,%s;%u", strdate, global_worker_stat.stat_req.nb_nfs41_op); for(j = 0; j < NFS_V41_NB_OPERATION; j++) fprintf(stats_file, "|%u,%u,%u", global_worker_stat.stat_req.stat_op_nfs41[j].total, global_worker_stat.stat_req.stat_op_nfs41[j].success, global_worker_stat.stat_req.stat_op_nfs41[j].failed); fprintf(stats_file, "\n"); fprintf(stats_file, "NLM V4 REQUEST,%s;%u", strdate, global_worker_stat.stat_req.nb_nlm4_req); for(j = 0; j < NLM_V4_NB_OPERATION; j++) fprintf(stats_file, "|%u,%u,%u", global_worker_stat.stat_req.stat_req_nlm4[j].total, global_worker_stat.stat_req.stat_req_nlm4[j].success, global_worker_stat.stat_req.stat_req_nlm4[j].dropped); fprintf(stats_file, "\n"); fprintf(stats_file, "RQUOTA V1 REQUEST,%s;%u", strdate, global_worker_stat.stat_req.nb_rquota1_req); for(j = 0; j < RQUOTA_NB_COMMAND; j++) fprintf(stats_file, "|%u,%u,%u", global_worker_stat.stat_req.stat_req_rquota1[j].total, global_worker_stat.stat_req.stat_req_rquota1[j].success, global_worker_stat.stat_req.stat_req_rquota1[j].dropped); fprintf(stats_file, "\n"); fprintf(stats_file, "RQUOTA V2 REQUEST,%s;%u", strdate, global_worker_stat.stat_req.nb_rquota2_req); for(j = 0; j < RQUOTA_NB_COMMAND; j++) fprintf(stats_file, "|%u,%u,%u", global_worker_stat.stat_req.stat_req_rquota2[j].total, global_worker_stat.stat_req.stat_req_rquota2[j].success, global_worker_stat.stat_req.stat_req_rquota2[j].dropped); fprintf(stats_file, "\n"); /* Printing the cache inode hash stat */ nfs_dupreq_get_stats(&hstat); fprintf(stats_file, "DUP_REQ_HASH,%s;%u,%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u\n", strdate, hstat.dynamic.nb_entries, hstat.computed.min_rbt_num_node, hstat.computed.max_rbt_num_node, hstat.computed.average_rbt_num_node, hstat.dynamic.ok.nb_set, hstat.dynamic.notfound.nb_set, hstat.dynamic.err.nb_set, hstat.dynamic.ok.nb_test, hstat.dynamic.notfound.nb_test, hstat.dynamic.err.nb_test, hstat.dynamic.ok.nb_get, hstat.dynamic.notfound.nb_get, hstat.dynamic.err.nb_get, hstat.dynamic.ok.nb_del, hstat.dynamic.notfound.nb_del, hstat.dynamic.err.nb_del); /* Printing the UIDMAP_TYPE hash table stats */ idmap_get_stats(UIDMAP_TYPE, &hstat, &hstat_reverse); fprintf(stats_file, "UIDMAP_HASH,%s;%u,%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u\n", strdate, hstat.dynamic.nb_entries, hstat.computed.min_rbt_num_node, hstat.computed.max_rbt_num_node, hstat.computed.average_rbt_num_node, hstat.dynamic.ok.nb_set, hstat.dynamic.notfound.nb_set, hstat.dynamic.err.nb_set, hstat.dynamic.ok.nb_test, hstat.dynamic.notfound.nb_test, hstat.dynamic.err.nb_test, hstat.dynamic.ok.nb_get, hstat.dynamic.notfound.nb_get, hstat.dynamic.err.nb_get, hstat.dynamic.ok.nb_del, hstat.dynamic.notfound.nb_del, hstat.dynamic.err.nb_del); fprintf(stats_file, "UNAMEMAP_HASH,%s;%u,%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u\n", strdate, hstat_reverse.dynamic.nb_entries, hstat_reverse.computed.min_rbt_num_node, hstat_reverse.computed.max_rbt_num_node, hstat_reverse.computed.average_rbt_num_node, hstat_reverse.dynamic.ok.nb_set, hstat_reverse.dynamic.notfound.nb_set, hstat_reverse.dynamic.err.nb_set, hstat_reverse.dynamic.ok.nb_test, hstat_reverse.dynamic.notfound.nb_test, hstat_reverse.dynamic.err.nb_test, hstat_reverse.dynamic.ok.nb_get, hstat_reverse.dynamic.notfound.nb_get, hstat_reverse.dynamic.err.nb_get, hstat_reverse.dynamic.ok.nb_del, hstat_reverse.dynamic.notfound.nb_del, hstat_reverse.dynamic.err.nb_del); /* Printing the GIDMAP_TYPE hash table stats */ idmap_get_stats(GIDMAP_TYPE, &hstat, &hstat_reverse); fprintf(stats_file, "GIDMAP_HASH,%s;%u,%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u\n", strdate, hstat.dynamic.nb_entries, hstat.computed.min_rbt_num_node, hstat.computed.max_rbt_num_node, hstat.computed.average_rbt_num_node, hstat.dynamic.ok.nb_set, hstat.dynamic.notfound.nb_set, hstat.dynamic.err.nb_set, hstat.dynamic.ok.nb_test, hstat.dynamic.notfound.nb_test, hstat.dynamic.err.nb_test, hstat.dynamic.ok.nb_get, hstat.dynamic.notfound.nb_get, hstat.dynamic.err.nb_get, hstat.dynamic.ok.nb_del, hstat.dynamic.notfound.nb_del, hstat.dynamic.err.nb_del); fprintf(stats_file, "GNAMEMAP_HASH,%s;%u,%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u\n", strdate, hstat_reverse.dynamic.nb_entries, hstat_reverse.computed.min_rbt_num_node, hstat_reverse.computed.max_rbt_num_node, hstat_reverse.computed.average_rbt_num_node, hstat_reverse.dynamic.ok.nb_set, hstat_reverse.dynamic.notfound.nb_set, hstat_reverse.dynamic.err.nb_set, hstat_reverse.dynamic.ok.nb_test, hstat_reverse.dynamic.notfound.nb_test, hstat_reverse.dynamic.err.nb_test, hstat_reverse.dynamic.ok.nb_get, hstat_reverse.dynamic.notfound.nb_get, hstat_reverse.dynamic.err.nb_get, hstat_reverse.dynamic.ok.nb_del, hstat_reverse.dynamic.notfound.nb_del, hstat_reverse.dynamic.err.nb_del); /* Stats for the IP/Name hashtable */ nfs_ip_name_get_stats(&hstat); fprintf(stats_file, "IP_NAME_HASH,%s;%u,%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u|%u,%u,%u\n", strdate, hstat_reverse.dynamic.nb_entries, hstat_reverse.computed.min_rbt_num_node, hstat_reverse.computed.max_rbt_num_node, hstat_reverse.computed.average_rbt_num_node, hstat_reverse.dynamic.ok.nb_set, hstat_reverse.dynamic.notfound.nb_set, hstat_reverse.dynamic.err.nb_set, hstat_reverse.dynamic.ok.nb_test, hstat_reverse.dynamic.notfound.nb_test, hstat_reverse.dynamic.err.nb_test, hstat_reverse.dynamic.ok.nb_get, hstat_reverse.dynamic.notfound.nb_get, hstat_reverse.dynamic.err.nb_get, hstat_reverse.dynamic.ok.nb_del, hstat_reverse.dynamic.notfound.nb_del, hstat_reverse.dynamic.err.nb_del); /* fsal statistics */ memset(&global_fsal_stat, 0, sizeof(fsal_statistics_t)); total_fsal_calls = 0; for(i = 0; i < nfs_param.core_param.nb_worker; i++) { for(j = 0; j < FSAL_NB_FUNC; j++) { total_fsal_calls += workers_data[i].stats.fsal_stats.func_stats.nb_call[j]; global_fsal_stat.func_stats.nb_call[j] += workers_data[i].stats.fsal_stats.func_stats.nb_call[j]; global_fsal_stat.func_stats.nb_success[j] += workers_data[i].stats.fsal_stats.func_stats.nb_success[j]; global_fsal_stat.func_stats.nb_err_retryable[j] += workers_data[i].stats.fsal_stats.func_stats.nb_err_retryable[j]; global_fsal_stat.func_stats.nb_err_unrecover[j] += workers_data[i].stats.fsal_stats.func_stats.nb_err_unrecover[j]; } } fprintf(stats_file, "FSAL_CALLS,%s;%llu", strdate, total_fsal_calls); for(j = 0; j < FSAL_NB_FUNC; j++) fprintf(stats_file, "|%u,%u,%u,%u", global_fsal_stat.func_stats.nb_call[j], global_fsal_stat.func_stats.nb_success[j], global_fsal_stat.func_stats.nb_err_retryable[j], global_fsal_stat.func_stats.nb_err_unrecover[j]); fprintf(stats_file, "\n"); #ifndef _NO_BUDDY_SYSTEM /* buddy memory */ memset(&global_buddy_stat, 0, sizeof(buddy_stats_t)); for(i = 0; i < nfs_param.core_param.nb_worker; i++) { global_buddy_stat.TotalMemSpace += workers_data[i].stats.buddy_stats.TotalMemSpace; global_buddy_stat.ExtraMemSpace += workers_data[i].stats.buddy_stats.ExtraMemSpace; global_buddy_stat.StdMemSpace += workers_data[i].stats.buddy_stats.StdMemSpace; global_buddy_stat.StdUsedSpace += workers_data[i].stats.buddy_stats.StdUsedSpace; if(workers_data[i].stats.buddy_stats.StdUsedSpace > global_buddy_stat.WM_StdUsedSpace) global_buddy_stat.WM_StdUsedSpace = workers_data[i].stats.buddy_stats.StdUsedSpace; global_buddy_stat.NbStdPages += workers_data[i].stats.buddy_stats.NbStdPages; global_buddy_stat.NbStdUsed += workers_data[i].stats.buddy_stats.NbStdUsed; if(workers_data[i].stats.buddy_stats.NbStdUsed > global_buddy_stat.WM_NbStdUsed) global_buddy_stat.WM_NbStdUsed = workers_data[i].stats.buddy_stats.NbStdUsed; } /* total memory space preallocated, total space preallocated for pages, total space that overflows pages */ /* total memory, used memory, avg used memory/worker, max used memory/worker */ /* total pages, used pages, avg used pages/worker, max used pages/worker */ fprintf(stats_file, "BUDDY_MEMORY,%s;%lu,%lu,%lu|%lu,%lu,%lu|%u,%u,%u,%u\n", strdate, (unsigned long)global_buddy_stat.TotalMemSpace, (unsigned long)global_buddy_stat.StdMemSpace, (unsigned long)global_buddy_stat.ExtraMemSpace, (unsigned long)global_buddy_stat.StdUsedSpace, (unsigned long)(global_buddy_stat.StdUsedSpace / nfs_param.core_param.nb_worker), (unsigned long)global_buddy_stat.WM_StdUsedSpace, global_buddy_stat.NbStdPages, global_buddy_stat.NbStdUsed, global_buddy_stat.NbStdUsed / nfs_param.core_param.nb_worker, global_buddy_stat.WM_NbStdUsed); #endif /* Flush the data written */ fprintf(stats_file, "END, ----- NO MORE STATS FOR THIS PASS ----\n"); fflush(stats_file); /* Now managed IP stats dump */ nfs_ip_stats_dump(ht_ip_stats, nfs_param.core_param.nb_worker, nfs_param.core_param.stats_per_client_directory); } /* while ( 1 ) */ return NULL; } /* stats_thread */
void *reaper_thread(void *unused) { hash_table_t *ht = ht_client_id; struct rbt_head *head_rbt; hash_data_t *pdata = NULL; int i, v4; struct rbt_node *pn; nfs_client_id_t *clientp; #ifndef _NO_BUDDY_SYSTEM if((i = BuddyInit(&nfs_param.buddy_param_admin)) != BUDDY_SUCCESS) { /* Failed init */ LogFatal(COMPONENT_MAIN, "Memory manager could not be initialized"); } LogInfo(COMPONENT_MAIN, "Memory manager successfully initialized"); #endif SetNameFunction("reaper_thr"); while(1) { /* Initial wait */ /* TODO: should this be configurable? */ /* sleep(nfs_param.core_param.reaper_delay); */ sleep(reaper_delay); LogFullDebug(COMPONENT_MAIN, "NFS reaper : now checking clients"); /* For each bucket of the hashtable */ for(i = 0; i < ht->parameter.index_size; i++) { head_rbt = &(ht->array_rbt[i]); restart: /* acquire mutex */ P_w(&(ht->array_lock[i])); /* go through all entries in the red-black-tree*/ RBT_LOOP(head_rbt, pn) { pdata = RBT_OPAQ(pn); clientp = (nfs_client_id_t *)pdata->buffval.pdata; /* * little hack: only want to reap v4 clients * 4.1 initializess this field to '1' */ v4 = (clientp->create_session_sequence == 0); if (clientp->confirmed != EXPIRED_CLIENT_ID && nfs4_is_lease_expired(clientp) && v4) { V_w(&(ht->array_lock[i])); LogDebug(COMPONENT_MAIN, "NFS reaper: expire client %s", clientp->client_name); nfs_client_id_expire(clientp); goto restart; } if (clientp->confirmed == EXPIRED_CLIENT_ID) { LogDebug(COMPONENT_MAIN, "reaper: client %s already expired", clientp->client_name); } RBT_INCREMENT(pn); } V_w(&(ht->array_lock[i])); } } /* while ( 1 ) */
int main(int argc, char *argv[]) { char *tempo_exec_name = NULL; char localmachine[MAXHOSTNAMELEN + 1]; int c; int dsc; int rc; int pidfile; char *log_path = NULL; char *exec_name = "nfs-ganesha"; int debug_level = -1; int detach_flag = true; bool dump_trace = false; #ifndef HAVE_DAEMON int dev_null_fd = 0; pid_t son_pid; #endif sigset_t signals_to_block; struct config_error_type err_type; /* Set the server's boot time and epoch */ now(&nfs_ServerBootTime); nfs_ServerEpoch = (time_t) nfs_ServerBootTime.tv_sec; srand(nfs_ServerEpoch); tempo_exec_name = strrchr(argv[0], '/'); if (tempo_exec_name != NULL) exec_name = main_strdup("exec_name", tempo_exec_name + 1); if (*exec_name == '\0') exec_name = argv[0]; /* get host name */ if (gethostname(localmachine, sizeof(localmachine)) != 0) { fprintf(stderr, "Could not get local host name, exiting...\n"); exit(1); } else { nfs_host_name = main_strdup("host_name", localmachine); } /* now parsing options with getopt */ while ((c = getopt(argc, argv, options)) != EOF) { switch (c) { case 'v': case '@': printf("NFS-Ganesha Release = V%s\n", GANESHA_VERSION); #if !GANESHA_BUILD_RELEASE /* A little backdoor to keep track of binary versions */ printf("%s compiled on %s at %s\n", exec_name, __DATE__, __TIME__); printf("Release comment = %s\n", VERSION_COMMENT); printf("Git HEAD = %s\n", _GIT_HEAD_COMMIT); printf("Git Describe = %s\n", _GIT_DESCRIBE); #endif exit(0); break; case 'L': /* Default Log */ log_path = main_strdup("log_path", optarg); break; case 'N': /* debug level */ debug_level = ReturnLevelAscii(optarg); if (debug_level == -1) { fprintf(stderr, "Invalid value for option 'N': NIV_NULL, NIV_MAJ, NIV_CRIT, NIV_EVENT, NIV_DEBUG, NIV_MID_DEBUG or NIV_FULL_DEBUG expected.\n"); exit(1); } break; case 'f': /* config file */ nfs_config_path = main_strdup("config_path", optarg); break; case 'p': /* PID file */ nfs_pidfile_path = main_strdup("pidfile_path", optarg); break; case 'F': /* Don't detach, foreground mode */ detach_flag = false; break; case 'R': /* Shall we manage RPCSEC_GSS ? */ fprintf(stderr, "\n\nThe -R flag is deprecated, use this syntax in the configuration file instead:\n\n"); fprintf(stderr, "NFS_KRB5\n"); fprintf(stderr, "{\n"); fprintf(stderr, "\tPrincipalName = nfs@<your_host> ;\n"); fprintf(stderr, "\tKeytabPath = /etc/krb5.keytab ;\n"); fprintf(stderr, "\tActive_krb5 = true ;\n"); fprintf(stderr, "}\n\n\n"); exit(1); break; case 'T': /* Dump the default configuration on stdout */ my_nfs_start_info.dump_default_config = true; break; case 'C': dump_trace = true; break; case 'E': nfs_ServerEpoch = (time_t) atoll(optarg); break; case 'h': fprintf(stderr, usage, exec_name); exit(0); default: /* '?' */ fprintf(stderr, "Try '%s -h' for usage\n", exec_name); exit(1); } } /* initialize memory and logging */ nfs_prereq_init(exec_name, nfs_host_name, debug_level, log_path, dump_trace); #if GANESHA_BUILD_RELEASE LogEvent(COMPONENT_MAIN, "%s Starting: Ganesha Version %s", exec_name, GANESHA_VERSION); #else LogEvent(COMPONENT_MAIN, "%s Starting: %s", exec_name, "Ganesha Version " _GIT_DESCRIBE ", built at " __DATE__ " " __TIME__ " on " BUILD_HOST); #endif /* initialize nfs_init */ nfs_init_init(); nfs_check_malloc(); /* Start in background, if wanted */ if (detach_flag) { #ifdef HAVE_DAEMON /* daemonize the process (fork, close xterm fds, * detach from parent process) */ if (daemon(0, 0)) LogFatal(COMPONENT_MAIN, "Error detaching process from parent: %s", strerror(errno)); /* In the child process, change the log header * if not, the header will contain the parent's pid */ set_const_log_str(); #else /* Step 1: forking a service process */ switch (son_pid = fork()) { case -1: /* Fork failed */ LogFatal(COMPONENT_MAIN, "Could not start nfs daemon (fork error %d (%s)", errno, strerror(errno)); break; case 0: /* This code is within the son (that will actually work) * Let's make it the leader of its group of process */ if (setsid() == -1) { LogFatal(COMPONENT_MAIN, "Could not start nfs daemon (setsid error %d (%s)", errno, strerror(errno)); } /* stdin, stdout and stderr should not refer to a tty * I close 0, 1 & 2 and redirect them to /dev/null */ dev_null_fd = open("/dev/null", O_RDWR); if (dev_null_fd < 0) LogFatal(COMPONENT_MAIN, "Could not open /dev/null: %d (%s)", errno, strerror(errno)); if (close(STDIN_FILENO) == -1) LogEvent(COMPONENT_MAIN, "Error while closing stdin: %d (%s)", errno, strerror(errno)); else { LogEvent(COMPONENT_MAIN, "stdin closed"); dup(dev_null_fd); } if (close(STDOUT_FILENO) == -1) LogEvent(COMPONENT_MAIN, "Error while closing stdout: %d (%s)", errno, strerror(errno)); else { LogEvent(COMPONENT_MAIN, "stdout closed"); dup(dev_null_fd); } if (close(STDERR_FILENO) == -1) LogEvent(COMPONENT_MAIN, "Error while closing stderr: %d (%s)", errno, strerror(errno)); else { LogEvent(COMPONENT_MAIN, "stderr closed"); dup(dev_null_fd); } if (close(dev_null_fd) == -1) LogFatal(COMPONENT_MAIN, "Could not close tmp fd to /dev/null: %d (%s)", errno, strerror(errno)); /* In the child process, change the log header * if not, the header will contain the parent's pid */ set_const_log_str(); break; default: /* This code is within the parent process, * it is useless, it must die */ LogFullDebug(COMPONENT_MAIN, "Starting a child of pid %d", son_pid); exit(0); break; } #endif } /* Make sure Linux file i/o will return with error * if file size is exceeded. */ #ifdef _LINUX signal(SIGXFSZ, SIG_IGN); #endif /* Echo PID into pidfile */ pidfile = open(nfs_pidfile_path, O_CREAT | O_RDWR, 0644); if (pidfile == -1) { LogFatal(COMPONENT_MAIN, "Can't open pid file %s for writing", nfs_pidfile_path); } else { char linebuf[1024]; struct flock lk; /* Try to obtain a lock on the file */ lk.l_type = F_WRLCK; lk.l_whence = SEEK_SET; lk.l_start = (off_t) 0; lk.l_len = (off_t) 0; if (fcntl(pidfile, F_SETLK, &lk) == -1) LogFatal(COMPONENT_MAIN, "Ganesha already started"); /* Put pid into file, then close it */ (void)snprintf(linebuf, sizeof(linebuf), "%u\n", getpid()); if (write(pidfile, linebuf, strlen(linebuf)) == -1) LogCrit(COMPONENT_MAIN, "Couldn't write pid to file %s", nfs_pidfile_path); } /* Set up for the signal handler. * Blocks the signals the signal handler will handle. */ sigemptyset(&signals_to_block); sigaddset(&signals_to_block, SIGTERM); sigaddset(&signals_to_block, SIGHUP); sigaddset(&signals_to_block, SIGPIPE); if (pthread_sigmask(SIG_BLOCK, &signals_to_block, NULL) != 0) LogFatal(COMPONENT_MAIN, "Could not start nfs daemon, pthread_sigmask failed"); /* init URL package */ config_url_init(); /* Create a memstream for parser+processing error messages */ if (!init_error_type(&err_type)) goto fatal_die; /* Parse the configuration file so we all know what is going on. */ if (nfs_config_path == NULL || nfs_config_path[0] == '\0') { LogWarn(COMPONENT_INIT, "No configuration file named."); nfs_config_struct = NULL; } else nfs_config_struct = config_ParseFile(nfs_config_path, &err_type); if (!config_error_no_error(&err_type)) { char *errstr = err_type_str(&err_type); if (!config_error_is_harmless(&err_type)) { LogCrit(COMPONENT_INIT, "Error %s while parsing (%s)", errstr != NULL ? errstr : "unknown", nfs_config_path); if (errstr != NULL) gsh_free(errstr); goto fatal_die; } else LogWarn(COMPONENT_INIT, "Error %s while parsing (%s)", errstr != NULL ? errstr : "unknown", nfs_config_path); if (errstr != NULL) gsh_free(errstr); } if (read_log_config(nfs_config_struct, &err_type) < 0) { LogCrit(COMPONENT_INIT, "Error while parsing log configuration"); goto fatal_die; } /* We need all the fsal modules loaded so we can have * the list available at exports parsing time. */ start_fsals(); /* parse configuration file */ if (nfs_set_param_from_conf(nfs_config_struct, &my_nfs_start_info, &err_type)) { LogCrit(COMPONENT_INIT, "Error setting parameters from configuration file."); goto fatal_die; } /* initialize core subsystems and data structures */ if (init_server_pkgs() != 0) { LogCrit(COMPONENT_INIT, "Failed to initialize server packages"); goto fatal_die; } /* Load Data Server entries from parsed file * returns the number of DS entries. */ dsc = ReadDataServers(nfs_config_struct, &err_type); if (dsc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing DS entries"); goto fatal_die; } /* Create stable storage directory, this needs to be done before * starting the recovery thread. */ rc = nfs4_recovery_init(); if (rc) { LogCrit(COMPONENT_INIT, "Recovery backend initialization failed!"); goto fatal_die; } /* Start grace period */ nfs_start_grace(NULL); /* Wait for enforcement to begin */ nfs_wait_for_grace_enforcement(); /* Load export entries from parsed file * returns the number of export entries. */ rc = ReadExports(nfs_config_struct, &err_type); if (rc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing export entries"); goto fatal_die; } if (rc == 0 && dsc == 0) LogWarn(COMPONENT_INIT, "No export entries found in configuration file !!!"); report_config_errors(&err_type, NULL, config_errs_to_log); /* freeing syntax tree : */ config_Free(nfs_config_struct); /* Everything seems to be OK! We can now start service threads */ nfs_start(&my_nfs_start_info); return 0; fatal_die: report_config_errors(&err_type, NULL, config_errs_to_log); LogFatal(COMPONENT_INIT, "Fatal errors. Server exiting..."); /* NOT REACHED */ return 2; }
bool C4FontLoader::InitFont(CStdFont &rFont, const char *szFontName, FontType eType, int32_t iSize, C4GroupSet *pGfxGroups, bool fDoShadow) { // safety if (!szFontName || !*szFontName) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // get font to load // pFontDefs may be NULL if no fonts are loaded; but then iFontDefCount is zero as well // the function must not be aborted, because a standard windows font may be loaded std::vector<C4FontDef>::iterator pFontDefC = FontDefs.begin(), pFontDef = FontDefs.end(); while (pFontDefC != FontDefs.end()) { // check font if (pFontDefC->Name == szFontName) { int32_t iSizeDiff = Abs(pFontDefC->iSize - iSize); // better match than last font? if (pFontDef == FontDefs.end() || Abs(pFontDef->iSize - iSize) >= iSizeDiff) pFontDef = pFontDefC; } // check next one ++pFontDefC; } // if def has not been found, use the def as font name // determine font def string const char *szFontString = szFontName; // special: Fonts without shadow are always newly rendered if (!fDoShadow) { pFontDef=FontDefs.end(); } if (pFontDef!=FontDefs.end()) switch (eType) { case C4FT_Log: szFontString = pFontDef->LogFont.getData(); break; case C4FT_MainSmall:szFontString = pFontDef->SmallFont.getData(); break; case C4FT_Main: szFontString = pFontDef->Font.getData(); break; case C4FT_Caption: szFontString = pFontDef->CaptionFont.getData(); break; case C4FT_Title: szFontString = pFontDef->TitleFont.getData(); break; default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call } // font not assigned? if (!*szFontString) { // invalid call or spec LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // get font name char FontFaceName[C4MaxName+1], FontParam[C4MaxName+1]; SCopyUntil(szFontString, FontFaceName, ',', C4MaxName); // is it an image file? const char *szExt = GetExtension(FontFaceName); if (SEqualNoCase(szExt, "png") || SEqualNoCase(szExt, "bmp")) { // image file name: load bitmap font from image file // if no graphics group is given, do not load yet if (!pGfxGroups) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // indent given? int32_t iIndent = 0; if (SCopySegment(szFontString, 1, FontParam, ',', C4MaxName)) sscanf(FontParam, "%i", &iIndent); // load font face from gfx group int32_t iGrpId; C4Group *pGrp = pGfxGroups->FindEntry(FontFaceName, NULL, &iGrpId); if (!pGrp) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // check if it's already loaded from that group with that parameters if (!rFont.IsSameAsID(FontFaceName, iGrpId, iIndent)) { // it's not; so (re-)load it now! if (rFont.IsInitialized()) { // reloading rFont.Clear(); LogF(LoadResStr("IDS_PRC_UPDATEFONT"), FontFaceName, iIndent, 0); } C4Surface sfc; if (!sfc.Load(*pGrp, FontFaceName)) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // init font from face try { rFont.Init(GetFilenameOnly(FontFaceName), &sfc, iIndent); } catch (std::runtime_error & e) { LogFatal(e.what()); LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } rFont.id = iGrpId; } } else { int32_t iDefFontSize; DWORD dwDefWeight=FW_NORMAL; #if defined(_WIN32) && !defined(HAVE_FREETYPE) switch (eType) { case C4FT_Log: iDefFontSize = 8; break; case C4FT_MainSmall:iDefFontSize = iSize+1; break; case C4FT_Main: iDefFontSize = iSize+4; break; case C4FT_Caption: iDefFontSize = iSize+6; dwDefWeight = FW_BOLD; break; case C4FT_Title: iDefFontSize = iSize*3; break; default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call } #else switch (eType) { case C4FT_Log: iDefFontSize = iSize*12/14; break; case C4FT_MainSmall:iDefFontSize = iSize*13/14; break; case C4FT_Main: iDefFontSize = iSize; break; case C4FT_Caption: iDefFontSize = iSize*16/14; /*dwDefWeight = FW_MEDIUM;*/ break; case C4FT_Title: iDefFontSize = iSize*22/14; /*dwDefWeight = FW_MEDIUM;*/ break; default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call } #endif // regular font name: let WinGDI or Freetype draw a font with the given parameters // font size given? if (SCopySegment(szFontString, 1, FontParam, ',', C4MaxName)) sscanf(FontParam, "%i", &iDefFontSize); // font weight given? if (SCopySegment(szFontString, 2, FontParam, ',', C4MaxName)) sscanf(FontParam, "%i", &dwDefWeight); // check if it's already loaded from that group with that parameters if (!rFont.IsSameAs(FontFaceName, iDefFontSize, dwDefWeight)) { // it's not; so (re-)load it now! if (rFont.IsInitialized()) { // reloading rFont.Clear(); LogF(LoadResStr("IDS_PRC_UPDATEFONT"), FontFaceName, iDefFontSize, dwDefWeight); } // init with given font name try { // check if one of the internally listed fonts should be used C4VectorFont * pFont = pVectorFonts; while (pFont) { if (SEqual(pFont->Name.getData(), FontFaceName)) { if (InitFont(rFont, pFont, iDefFontSize, dwDefWeight, fDoShadow)) break; } pFont = pFont->pNext; } // no internal font matching? Then create one using the given face/filename (using a system font) if (!pFont) { pFont = new C4VectorFont(); if (pFont->Init(FontFaceName, iDefFontSize, dwDefWeight, Config.General.LanguageCharset)) { AddVectorFont(pFont); if (!InitFont(rFont, pFont, iDefFontSize, dwDefWeight, fDoShadow)) throw std::runtime_error(FormatString("Error initializing font %s", FontFaceName).getData()); } else { delete pFont; // no match for font face found throw std::runtime_error(FormatString("Font face %s undefined", FontFaceName).getData()); } } } catch (std::runtime_error & e) { LogFatal(e.what()); LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } rFont.id = 0; } } // done, success return true; }
static void nfs_Start_threads(void) { int rc = 0; pthread_attr_t attr_thr; LogDebug(COMPONENT_THREAD, "Starting threads"); /* Init for thread parameter (mostly for scheduling) */ if (pthread_attr_init(&attr_thr) != 0) LogDebug(COMPONENT_THREAD, "can't init pthread's attributes"); if (pthread_attr_setscope(&attr_thr, PTHREAD_SCOPE_SYSTEM) != 0) LogDebug(COMPONENT_THREAD, "can't set pthread's scope"); if (pthread_attr_setdetachstate(&attr_thr, PTHREAD_CREATE_JOINABLE) != 0) LogDebug(COMPONENT_THREAD, "can't set pthread's join state"); LogEvent(COMPONENT_THREAD, "Starting delayed executor."); delayed_start(); /* Starting the thread dedicated to signal handling */ rc = pthread_create(&sigmgr_thrid, &attr_thr, sigmgr_thread, NULL); if (rc != 0) { LogFatal(COMPONENT_THREAD, "Could not create sigmgr_thread, error = %d (%s)", errno, strerror(errno)); } LogDebug(COMPONENT_THREAD, "sigmgr thread started"); rc = worker_init(); if (rc != 0) { LogFatal(COMPONENT_THREAD, "Could not start worker threads: %d", errno); } /* Start event channel service threads */ nfs_rpc_dispatch_threads(&attr_thr); #ifdef _USE_9P /* Starting the 9P/TCP dispatcher thread */ rc = pthread_create(&_9p_dispatcher_thrid, &attr_thr, _9p_dispatcher_thread, NULL); if (rc != 0) { LogFatal(COMPONENT_THREAD, "Could not create 9P/TCP dispatcher, error = %d (%s)", errno, strerror(errno)); } LogEvent(COMPONENT_THREAD, "9P/TCP dispatcher thread was started successfully"); #endif #ifdef _USE_9P_RDMA /* Starting the 9P/RDMA dispatcher thread */ rc = pthread_create(&_9p_rdma_dispatcher_thrid, &attr_thr, _9p_rdma_dispatcher_thread, NULL); if (rc != 0) { LogFatal(COMPONENT_THREAD, "Could not create 9P/RDMA dispatcher, error = %d (%s)", errno, strerror(errno)); } LogEvent(COMPONENT_THREAD, "9P/RDMA dispatcher thread was started successfully"); #endif #ifdef USE_DBUS /* DBUS event thread */ rc = pthread_create(&gsh_dbus_thrid, &attr_thr, gsh_dbus_thread, NULL); if (rc != 0) { LogFatal(COMPONENT_THREAD, "Could not create gsh_dbus_thread, error = %d (%s)", errno, strerror(errno)); } LogEvent(COMPONENT_THREAD, "gsh_dbusthread was started successfully"); #endif /* Starting the admin thread */ rc = pthread_create(&admin_thrid, &attr_thr, admin_thread, NULL); if (rc != 0) { LogFatal(COMPONENT_THREAD, "Could not create admin_thread, error = %d (%s)", errno, strerror(errno)); } LogEvent(COMPONENT_THREAD, "admin thread was started successfully"); /* Starting the reaper thread */ rc = reaper_init(); if (rc != 0) { LogFatal(COMPONENT_THREAD, "Could not create reaper_thread, error = %d (%s)", errno, strerror(errno)); } LogEvent(COMPONENT_THREAD, "reaper thread was started successfully"); /* Starting the general fridge */ rc = general_fridge_init(); if (rc != 0) { LogFatal(COMPONENT_THREAD, "Could not create general fridge, error = %d (%s)", errno, strerror(errno)); } LogEvent(COMPONENT_THREAD, "General fridge was started successfully"); }
int nfs_get_fsalpathlib_conf(char *configPath, path_str_t * PathLib, unsigned int *plen) { int var_max; int var_index; int err; char *key_name; char *key_value; config_item_t block; unsigned int found = FALSE; config_file_t config_struct; unsigned int index = 0 ; /* Is the config tree initialized ? */ if(configPath == NULL || PathLib == NULL) LogFatal(COMPONENT_CONFIG, "nfs_get_fsalpathlib_conf configPath=%p PathLib=%p", configPath, PathLib); config_struct = config_ParseFile(configPath); if(!config_struct) LogFatal(COMPONENT_CONFIG, "Error while parsing %s: %s", configPath, config_GetErrorMsg()); /* Get the config BLOCK */ if((block = config_FindItemByName(config_struct, CONF_LABEL_NFS_CORE)) == NULL) { LogFatal(COMPONENT_CONFIG, "Cannot read item \"%s\" from configuration file", CONF_LABEL_NFS_CORE); } else if(config_ItemType(block) != CONFIG_ITEM_BLOCK) { /* Expected to be a block */ LogFatal(COMPONENT_CONFIG, "Item \"%s\" is expected to be a block", CONF_LABEL_NFS_CORE); } var_max = config_GetNbItems(block); for(var_index = 0; var_index < var_max; var_index++) { config_item_t item; item = config_GetItemByIndex(block, var_index); /* Get key's name */ if((err = config_GetKeyValue(item, &key_name, &key_value)) != 0) { LogFatal(COMPONENT_CONFIG, "Error reading key[%d] from section \"%s\" of configuration file.", var_index, CONF_LABEL_NFS_CORE); } if(!strcasecmp(key_name, "FSAL_Shared_Library")) { strncpy(PathLib[index], key_value, MAXPATHLEN); index += 1 ; found = TRUE; /* Do not exceed array size */ if( index == *plen ) break ; } } if(!found) { LogFatal(COMPONENT_CONFIG, "FSAL_Shared_Library not found"); return 1; } *plen = index ; return 0; } /* nfs_get_fsalpathlib_conf */
static void nfs_Init(const nfs_start_info_t *p_start_info) { cache_inode_status_t cache_status; state_status_t state_status; int rc = 0; #ifdef _HAVE_GSSAPI gss_buffer_desc gss_service_buf; OM_uint32 maj_stat, min_stat; char GssError[MAXNAMLEN + 1]; #endif #ifdef USE_DBUS /* DBUS init */ gsh_dbus_pkginit(); #ifdef USE_DBUS_STATS dbus_export_init(); dbus_client_init(); #endif #endif /* Cache Inode Initialisation */ cache_status = cache_inode_init(); if (cache_status != CACHE_INODE_SUCCESS) { LogFatal(COMPONENT_INIT, "Cache Inode Layer could not be initialized, status=%s", cache_inode_err_str(cache_status)); } state_status = state_lock_init(nfs_param.cache_param.cookie_param); if (state_status != STATE_SUCCESS) { LogFatal(COMPONENT_INIT, "State Lock Layer could not be initialized, status=%s", state_err_str(state_status)); } LogInfo(COMPONENT_INIT, "Cache Inode library successfully initialized"); /* Cache Inode LRU (call this here, rather than as part of cache_inode_init() so the GC policy has been set */ rc = cache_inode_lru_pkginit(); if (rc != 0) { LogFatal(COMPONENT_INIT, "Unable to initialize LRU subsystem: %d.", rc); } /* finish the job with exports by caching the root entries */ exports_pkginit(); nfs41_session_pool = pool_init("NFSv4.1 session pool", sizeof(nfs41_session_t), pool_basic_substrate, NULL, NULL, NULL); request_pool = pool_init("Request pool", sizeof(request_data_t), pool_basic_substrate, NULL, NULL /* FASTER constructor_request_data_t */ , NULL); if (!request_pool) { LogCrit(COMPONENT_INIT, "Error while allocating request pool"); LogError(COMPONENT_INIT, ERR_SYS, ERR_MALLOC, errno); Fatal(); } request_data_pool = pool_init("Request Data Pool", sizeof(nfs_request_data_t), pool_basic_substrate, NULL, NULL /* FASTER constructor_nfs_request_data_t */ , NULL); if (!request_data_pool) { LogCrit(COMPONENT_INIT, "Error while allocating request data pool"); LogError(COMPONENT_INIT, ERR_SYS, ERR_MALLOC, errno); Fatal(); } dupreq_pool = pool_init("Duplicate Request Pool", sizeof(dupreq_entry_t), pool_basic_substrate, NULL, NULL, NULL); if (!(dupreq_pool)) { LogCrit(COMPONENT_INIT, "Error while allocating duplicate request pool"); LogError(COMPONENT_INIT, ERR_SYS, ERR_MALLOC, errno); Fatal(); } #ifdef _USE_ASYNC_CACHE_INODE /* Start the TAD and synclets for writeback cache inode */ cache_inode_async_init(nfs_param.cache_layers_param. cache_inode_client_param); #endif /* If rpcsec_gss is used, set the path to the keytab */ #ifdef _HAVE_GSSAPI #ifdef HAVE_KRB5 if (nfs_param.krb5_param.active_krb5) { OM_uint32 gss_status = GSS_S_COMPLETE; if (nfs_param.krb5_param.keytab[0] != '\0') gss_status = krb5_gss_register_acceptor_identity(nfs_param. krb5_param. keytab); if (gss_status != GSS_S_COMPLETE) { log_sperror_gss(GssError, gss_status, 0); LogFatal(COMPONENT_INIT, "Error setting krb5 keytab to value %s is %s", nfs_param.krb5_param.keytab, GssError); } LogInfo(COMPONENT_INIT, "krb5 keytab path successfully set to %s", nfs_param.krb5_param.keytab); #endif /* HAVE_KRB5 */ /* Set up principal to be use for GSSAPPI within GSSRPC/KRB5 */ gss_service_buf.value = nfs_param.krb5_param.svc.principal; gss_service_buf.length = strlen(nfs_param.krb5_param.svc.principal) + 1; /* The '+1' is not to be forgotten, for the '\0' at the end */ maj_stat = gss_import_name(&min_stat, &gss_service_buf, (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &nfs_param.krb5_param.svc.gss_name); if (maj_stat != GSS_S_COMPLETE) { log_sperror_gss(GssError, maj_stat, min_stat); LogFatal(COMPONENT_INIT, "Error importing gss principal %s is %s", nfs_param.krb5_param.svc.principal, GssError); } if (nfs_param.krb5_param.svc.gss_name == GSS_C_NO_NAME) LogInfo(COMPONENT_INIT, "Regression: svc.gss_name == GSS_C_NO_NAME"); LogInfo(COMPONENT_INIT, "gss principal \"%s\" successfully set", nfs_param.krb5_param.svc.principal); /* Set the principal to GSSRPC */ if (!svcauth_gss_set_svc_name (nfs_param.krb5_param.svc.gss_name)) { LogFatal(COMPONENT_INIT, "Impossible to set gss principal to GSSRPC"); } /* Don't release name until shutdown, it will be used by the * backchannel. */ #ifdef HAVE_KRB5 } /* if( nfs_param.krb5_param.active_krb5 ) */ #endif /* HAVE_KRB5 */ #endif /* _HAVE_GSSAPI */ /* RPC Initialisation - exits on failure */ nfs_Init_svc(); LogInfo(COMPONENT_INIT, "RPC ressources successfully initialized"); /* Admin initialisation */ nfs_Init_admin_thread(); LogEvent(COMPONENT_INIT, "Initializing ID Mapper."); if (!idmapper_init()) LogFatal(COMPONENT_INIT, "Failed initializing ID Mapper."); else LogEvent(COMPONENT_INIT, "ID Mapper successfully initialized."); /* Init the NFSv4 Clientid cache */ LogDebug(COMPONENT_INIT, "Now building NFSv4 clientid cache"); if (nfs_Init_client_id(&nfs_param.client_id_param) != CLIENT_ID_SUCCESS) { LogFatal(COMPONENT_INIT, "Error while initializing NFSv4 clientid cache"); } LogInfo(COMPONENT_INIT, "NFSv4 clientid cache successfully initialized"); /* Init duplicate request cache */ dupreq2_pkginit(); LogInfo(COMPONENT_INIT, "duplicate request hash table cache successfully initialized"); /* Init the IP/name cache */ LogDebug(COMPONENT_INIT, "Now building IP/name cache"); if (nfs_Init_ip_name(nfs_param.ip_name_param) != IP_NAME_SUCCESS) { LogFatal(COMPONENT_INIT, "Error while initializing IP/name cache"); } LogInfo(COMPONENT_INIT, "IP/name cache successfully initialized"); /* Init The NFSv4 State id cache */ LogDebug(COMPONENT_INIT, "Now building NFSv4 State Id cache"); if (nfs4_Init_state_id(&nfs_param.state_id_param) != 0) { LogFatal(COMPONENT_INIT, "Error while initializing NFSv4 State Id cache"); } LogInfo(COMPONENT_INIT, "NFSv4 State Id cache successfully initialized"); /* Init The NFSv4 Open Owner cache */ LogDebug(COMPONENT_INIT, "Now building NFSv4 Owner cache"); if (Init_nfs4_owner(&nfs_param.nfs4_owner_param) != 0) { LogFatal(COMPONENT_INIT, "Error while initializing NFSv4 Owner cache"); } LogInfo(COMPONENT_INIT, "NFSv4 Open Owner cache successfully initialized"); if (nfs_param.core_param.enable_NLM) { /* Init The NLM Owner cache */ LogDebug(COMPONENT_INIT, "Now building NLM Owner cache"); if (Init_nlm_hash() != 0) { LogFatal(COMPONENT_INIT, "Error while initializing NLM Owner cache"); } LogInfo(COMPONENT_INIT, "NLM Owner cache successfully initialized"); nlm_init(); } #ifdef _USE_9P /* Init the 9P lock owner cache */ LogDebug(COMPONENT_INIT, "Now building 9P Owner cache"); if (Init_9p_hash() != 0) { LogFatal(COMPONENT_INIT, "Error while initializing 9P Owner cache"); } LogInfo(COMPONENT_INIT, "9P Owner cache successfully initialized"); #endif LogDebug(COMPONENT_INIT, "Now building NFSv4 Session Id cache"); if (nfs41_Init_session_id(&nfs_param.session_id_param) != 0) { LogFatal(COMPONENT_INIT, "Error while initializing NFSv4 Session Id cache"); } LogInfo(COMPONENT_INIT, "NFSv4 Session Id cache successfully initialized"); LogDebug(COMPONENT_INIT, "Now building NFSv4 ACL cache"); if (nfs4_acls_init() != 0) { LogCrit(COMPONENT_INIT, "Error while initializing NFSv4 ACLs"); exit(1); } LogInfo(COMPONENT_INIT, "NFSv4 ACL cache successfully initialized"); #ifdef _USE_9P LogDebug(COMPONENT_INIT, "Now building 9P resources"); if (_9p_init(&nfs_param._9p_param)) { LogCrit(COMPONENT_INIT, "Error while initializing 9P Resources"); exit(1); } LogInfo(COMPONENT_INIT, "9P resources successfully initialized"); #endif /* _USE_9P */ /* Creates the pseudo fs */ LogDebug(COMPONENT_INIT, "Now building pseudo fs"); rc = nfs4_ExportToPseudoFS(); if (rc != 0) LogFatal(COMPONENT_INIT, "Error %d while initializing NFSv4 pseudo file system", rc); LogInfo(COMPONENT_INIT, "NFSv4 pseudo file system successfully initialized"); /* Save Ganesha thread credentials with Frank's routine for later use */ fsal_save_ganesha_credentials(); /* Create stable storage directory, this needs to be done before * starting the recovery thread. */ nfs4_create_recov_dir(); /* initialize grace and read in the client IDs */ nfs4_init_grace(); nfs4_load_recov_clids(NULL); /* Start grace period */ nfs4_start_grace(NULL); /* callback dispatch */ nfs_rpc_cb_pkginit(); #ifdef _USE_CB_SIMULATOR nfs_rpc_cbsim_pkginit(); #endif /* _USE_CB_SIMULATOR */ } /* nfs_Init */
bool C4Application::DoInit() { assert(AppState == C4AS_None); // Config overwrite by parameter StdStrBuf sConfigFilename; char szParameter[_MAX_PATH + 1]; for (int32_t iPar = 0; SGetParameter(GetCommandLine(), iPar, szParameter, _MAX_PATH); iPar++) if (SEqual2NoCase(szParameter, "/config:")) sConfigFilename.Copy(szParameter + 8); // Config check Config.Init(); Config.Load(true, sConfigFilename.getData()); Config.Save(); // sometimes, the configuration can become corrupted due to loading errors or // w/e // check this and reset defaults if necessary if (Config.IsCorrupted()) { if (sConfigFilename) { // custom config corrupted: Fail Log("Warning: Custom configuration corrupted - program abort!\n"); return false; } else { // default config corrupted: Restore default Log("Warning: Configuration corrupted - restoring default!\n"); Config.Default(); Config.Save(); Config.Load(); } } MMTimer = Config.General.MMTimer != 0; // Init C4Group C4Group_SetMaker(Config.General.Name); C4Group_SetProcessCallback(&ProcessCallback); C4Group_SetTempPath(Config.General.TempPath); C4Group_SetSortList(C4CFN_FLS); // Open log if (!OpenLog()) return false; // init system group if (!SystemGroup.Open(C4CFN_System)) { // Error opening system group - no LogFatal, because it needs language // table. // This will *not* use the FatalErrors stack, but this will cause the game // to instantly halt, anyway. Log("Error opening system group file (System.c4g)!"); return false; } // Language override by parameter const char *pLanguage; if (pLanguage = SSearchNoCase(GetCommandLine(), "/Language:")) SCopyUntil(pLanguage, Config.General.LanguageEx, ' ', CFG_MaxString); // Init external language packs Languages.Init(); // Load language string table if (!Languages.LoadLanguage(Config.General.LanguageEx)) // No language table was loaded - bad luck... if (!IsResStrTableLoaded()) Log("WARNING: No language string table loaded!"); // Set unregistered user name C4Group_SetMaker(LoadResStr("IDS_PRC_UNREGUSER")); // Parse command line Game.ParseCommandLine(GetCommandLine()); #ifdef WIN32 // Windows: handle incoming updates directly, even before starting up the gui // because updates will be applied in the console anyway. if (Application.IncomingUpdate) if (C4UpdateDlg::ApplyUpdate(Application.IncomingUpdate.getData(), false, NULL)) return true; #endif // activate Active = TRUE; // Init carrier window if (isFullScreen) { if (!(pWindow = FullScreen.Init(this))) { Clear(); return false; } } else { if (!(pWindow = Console.Init(this))) { Clear(); return false; } } // init timers (needs window) if (!InitTimer()) { LogFatal(LoadResStr("IDS_ERR_TIMER")); Clear(); return false; } // Engine header message Log(C4ENGINEINFOLONG); LogF("Version: %s %s", C4VERSION, C4_OS); #if defined(USE_DIRECTX) && defined(_WIN32) // DDraw emulation warning DWORD DDrawEmulationState; if (GetRegistryDWord(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\DirectDraw", "EmulationOnly", &DDrawEmulationState)) if (DDrawEmulationState) Log("WARNING: DDraw Software emulation is activated!"); #endif // Initialize D3D/OpenGL DDraw = DDrawInit(this, isFullScreen, FALSE, Config.Graphics.BitDepth, Config.Graphics.Engine, Config.Graphics.Monitor); if (!DDraw) { LogFatal(LoadResStr("IDS_ERR_DDRAW")); Clear(); return false; } #if defined(_WIN32) && !defined(USE_CONSOLE) // Register clonk file classes - notice: under Vista this will only work if we // have administrator rights char szModule[_MAX_PATH + 1]; GetModuleFileName(NULL, szModule, _MAX_PATH); SetC4FileClasses(szModule); #endif // Initialize gamepad if (!pGamePadControl && Config.General.GamepadEnabled) pGamePadControl = new C4GamePadControl(); AppState = C4AS_PreInit; return true; }
static fsal_status_t makenode(struct fsal_obj_handle *dir_hdl, const struct req_op_context *opctx, const char *name, object_file_type_t nodetype, fsal_dev_t * dev, struct attrlist *attrib, struct fsal_obj_handle **handle) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct stat sb; struct glfs_object *glhandle = NULL; unsigned char globjhdl[GLAPI_HANDLE_LENGTH]; struct glusterfs_handle *objhandle = NULL; dev_t ndev = { 0, }; struct glusterfs_export *glfs_export = container_of(dir_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *parenthandle = container_of(dir_hdl, struct glusterfs_handle, handle); mode_t create_mode; #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif switch (nodetype) { case BLOCK_FILE: if (!dev) return fsalstat(ERR_FSAL_INVAL, 0); /* FIXME: This needs a feature flag test? */ ndev = makedev(dev->major, dev->minor); create_mode = S_IFBLK; break; case CHARACTER_FILE: if (!dev) return fsalstat(ERR_FSAL_INVAL, 0); ndev = makedev(dev->major, dev->minor); create_mode = S_IFCHR; break; case FIFO_FILE: create_mode = S_IFIFO; break; case SOCKET_FILE: create_mode = S_IFSOCK; break; default: LogMajor(COMPONENT_FSAL, "Invalid node type in FSAL_mknode: %d", nodetype); return fsalstat(ERR_FSAL_INVAL, 0); } rc = setglustercreds(glfs_export, &opctx->creds->caller_uid, &opctx->creds->caller_gid, opctx->creds->caller_glen, opctx->creds->caller_garray); if (rc != 0) { status = gluster2fsal_error(EPERM); LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials"); goto out; } /* FIXME: what else from attrib should we use? */ glhandle = glfs_h_mknod(glfs_export->gl_fs, parenthandle->glhandle, name, create_mode | fsal2unix_mode(attrib->mode), ndev, &sb); rc = setglustercreds(glfs_export, NULL, NULL, 0, NULL); if (rc != 0) { status = gluster2fsal_error(EPERM); LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials"); goto out; } if (glhandle == NULL) { status = gluster2fsal_error(errno); goto out; } rc = glfs_h_extract_handle(glhandle, globjhdl, GLAPI_HANDLE_LENGTH); if (rc < 0) { status = gluster2fsal_error(errno); goto out; } rc = construct_handle(glfs_export, &sb, glhandle, globjhdl, GLAPI_HANDLE_LENGTH, &objhandle); if (rc != 0) { status = gluster2fsal_error(rc); goto out; } *handle = &objhandle->handle; *attrib = objhandle->handle.attributes; out: if (status.major != ERR_FSAL_NO_ERROR) { gluster_cleanup_vars(glhandle); } #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_makenode); #endif return status; }
/* Loads the RD */ void ModuleMgrInit(MCoreBootDescriptor *BootDescriptor) { /* Get pointers */ MCoreRamDiskHeader_t *RdHeader = (MCoreRamDiskHeader_t*)BootDescriptor->RamDiskAddress; /* Sanity */ if (BootDescriptor->RamDiskAddress == 0 || BootDescriptor->RamDiskSize == 0) return; /* Info */ LogInformation("MDMG", "Initializing"); /* Parse Kernel Exports */ PeLoadKernelExports(BootDescriptor->KernelAddress, BootDescriptor->ExportsAddress); /* Validate Members */ if (RdHeader->Magic != RAMDISK_MAGIC) { /* Error! */ LogFatal("MDMG", "Invalid Magic in Ramdisk - 0x%x", RdHeader->Magic); return; } /* Valid Version? */ if (RdHeader->Version != RAMDISK_VERSION_1) { /* Error! */ LogFatal("MDMG", "Invalid RamDisk Version - 0x%x", RdHeader->Version); return; } /* Allocate list */ GlbModMgrModules = list_create(LIST_NORMAL); /* Save Module-Count */ uint32_t FileCount = RdHeader->FileCount; Addr_t RdPtr = BootDescriptor->RamDiskAddress + sizeof(MCoreRamDiskHeader_t); /* Point to first entry */ MCoreRamDiskFileHeader_t *FilePtr = (MCoreRamDiskFileHeader_t*)RdPtr; /* Iterate */ while (FileCount != 0) { /* We only care about modules */ if (FilePtr->Type == RAMDISK_MODULE) { /* Get a pointer to the module header */ MCoreRamDiskModuleHeader_t *ModuleHeader = (MCoreRamDiskModuleHeader_t*)(BootDescriptor->RamDiskAddress + FilePtr->DataOffset); /* Allocate a new module */ MCoreModule_t *Module = (MCoreModule_t*)kmalloc(sizeof(MCoreModule_t)); /* Set */ Module->Name = MStringCreate(ModuleHeader->ModuleName, StrUTF8); Module->Header = ModuleHeader; Module->Descriptor = NULL; /* Add to list */ list_append(GlbModMgrModules, list_create_node(0, Module)); } /* Next! */ FilePtr++; FileCount--; } /* Info */ LogInformation("MDMG", "Found %i Modules", GlbModMgrModules->length); /* Done! */ GlbModMgrInitialized = 1; }
void nlm_startup(void) { if(nlm_async_callback_init() == -1) LogFatal(COMPONENT_INIT, "Could not start NLM async thread"); }
static void open4_ex(OPEN4args *arg, compound_data_t *data, OPEN4res *res_OPEN4, nfs_client_id_t *clientid, state_owner_t *owner, state_t **file_state, bool *new_state) { /* Parent directory in which to open the file. */ struct fsal_obj_handle *parent = NULL; /* The entry we associated with the desired file before open. */ struct fsal_obj_handle *file_obj = NULL; /* Indicator that file_obj came from lookup. */ bool looked_up_file_obj = false; /* The in_obj to pass to fsal_open2. */ struct fsal_obj_handle *in_obj = NULL; /* The entry open associated with the file. */ struct fsal_obj_handle *out_obj = NULL; fsal_openflags_t openflags = 0; fsal_openflags_t old_openflags = 0; enum fsal_create_mode createmode = FSAL_NO_CREATE; /* The filename to create */ char *filename = NULL; /* The supplied calim type */ open_claim_type4 claim = arg->claim.claim; fsal_verifier_t verifier; struct attrlist sattr; /* Status for fsal calls */ fsal_status_t status = {0, 0}; /* The open state for the file */ bool state_lock_held = false; /* Make sure the attributes are initialized */ memset(&sattr, 0, sizeof(sattr)); /* Make sure... */ *file_state = NULL; *new_state = false; /* Pre-process the claim type */ switch (claim) { case CLAIM_NULL: /* Check parent */ parent = data->current_obj; in_obj = parent; /* Parent must be a directory */ if (parent->type != DIRECTORY) { if (parent->type == SYMBOLIC_LINK) { res_OPEN4->status = NFS4ERR_SYMLINK; goto out; } else { res_OPEN4->status = NFS4ERR_NOTDIR; goto out; } } /* Validate and convert the utf8 filename */ res_OPEN4->status = nfs4_utf8string2dynamic(&arg->claim.open_claim4_u.file, UTF8_SCAN_ALL, &filename); if (res_OPEN4->status != NFS4_OK) goto out; /* Set the createmode if appropriate) */ if (arg->openhow.opentype == OPEN4_CREATE) { open4_ex_create_args(arg, data, res_OPEN4, verifier, &createmode, &sattr); if (res_OPEN4->status != NFS4_OK) goto out; } status = fsal_lookup(parent, filename, &file_obj, NULL); if (!FSAL_IS_ERROR(status)) { /* Check create situations. */ if (arg->openhow.opentype == OPEN4_CREATE) { if (createmode >= FSAL_EXCLUSIVE) { /* Could be a replay, need to continue. */ LogFullDebug(COMPONENT_STATE, "EXCLUSIVE open with existing file %s", filename); } else if (createmode == FSAL_GUARDED) { /* This will be a failure no matter' * what. */ looked_up_file_obj = true; res_OPEN4->status = NFS4ERR_EXIST; goto out; } else { /* FSAL_UNCHECKED, may be a truncate * and we need to pass in the case * of fsal_reopen2 case. */ if (FSAL_TEST_MASK(sattr.valid_mask, ATTR_SIZE) && sattr.filesize == 0) { LogFullDebug(COMPONENT_STATE, "Truncate"); openflags |= FSAL_O_TRUNC; } } } /* We found the file by lookup, discard the filename * and remember that we found the entry by lookup. */ looked_up_file_obj = true; gsh_free(filename); filename = NULL; } else if (status.major != ERR_FSAL_NOENT || arg->openhow.opentype != OPEN4_CREATE) { /* A real error occurred */ res_OPEN4->status = nfs4_Errno_status(status); goto out; } break; /* Both of these just use the current filehandle. */ case CLAIM_PREVIOUS: owner->so_owner.so_nfs4_owner.so_confirmed = true; if (!nfs4_check_deleg_reclaim(clientid, &data->currentFH)) { /* It must have been revoked. Can't reclaim.*/ LogInfo(COMPONENT_NFS_V4, "Can't reclaim delegation"); res_OPEN4->status = NFS4ERR_RECLAIM_BAD; goto out; } openflags |= FSAL_O_RECLAIM; file_obj = data->current_obj; break; case CLAIM_FH: file_obj = data->current_obj; break; case CLAIM_DELEGATE_PREV: /* FIXME: Remove this when we have full support * for CLAIM_DELEGATE_PREV and delegpurge operations */ res_OPEN4->status = NFS4ERR_NOTSUPP; goto out; case CLAIM_DELEGATE_CUR: res_OPEN4->status = open4_claim_deleg(arg, data); if (res_OPEN4->status != NFS4_OK) goto out; openflags |= FSAL_O_RECLAIM; file_obj = data->current_obj; break; default: LogFatal(COMPONENT_STATE, "Programming error. Invalid claim after check."); } if ((arg->share_access & OPEN4_SHARE_ACCESS_READ) != 0) openflags |= FSAL_O_READ; if ((arg->share_access & OPEN4_SHARE_ACCESS_WRITE) != 0) openflags |= FSAL_O_WRITE; if ((arg->share_deny & OPEN4_SHARE_DENY_READ) != 0) openflags |= FSAL_O_DENY_READ; if ((arg->share_deny & OPEN4_SHARE_DENY_WRITE) != 0) openflags |= FSAL_O_DENY_WRITE_MAND; /* Check if file_obj a REGULAR_FILE */ if (file_obj != NULL && file_obj->type != REGULAR_FILE) { LogDebug(COMPONENT_NFS_V4, "Wrong file type expected REGULAR_FILE actual %s", object_file_type_to_str(file_obj->type)); if (file_obj->type == DIRECTORY) { res_OPEN4->status = NFS4ERR_ISDIR; } else { /* All special nodes must return NFS4ERR_SYMLINK for * proper client behavior per this linux-nfs post: * http://marc.info/?l=linux-nfs&m=131342421825436&w=2 */ res_OPEN4->status = NFS4ERR_SYMLINK; } goto out; } if (file_obj != NULL) { /* Go ahead and take the state lock now. */ PTHREAD_RWLOCK_wrlock(&file_obj->state_hdl->state_lock); state_lock_held = true; in_obj = file_obj; /* Check if any existing delegations conflict with this open. * Delegation recalls will be scheduled if there is a conflict. */ if (state_deleg_conflict(file_obj, (arg->share_access & OPEN4_SHARE_ACCESS_WRITE) != 0)) { res_OPEN4->status = NFS4ERR_DELAY; goto out; } /* Check if there is already a state for this entry and owner. */ *file_state = nfs4_State_Get_Obj(file_obj, owner); if (isFullDebug(COMPONENT_STATE) && *file_state != NULL) { char str[LOG_BUFF_LEN] = "\0"; struct display_buffer dspbuf = {sizeof(str), str, str}; display_stateid(&dspbuf, *file_state); LogFullDebug(COMPONENT_STATE, "Found existing state %s", str); } /* Check if open from another export */ if (*file_state != NULL && !state_same_export(*file_state, op_ctx->ctx_export)) { LogEvent(COMPONENT_STATE, "Lock Owner Export Conflict, Lock held for export %" PRIu16" request for export %"PRIu16, state_export_id(*file_state), op_ctx->ctx_export->export_id); res_OPEN4->status = NFS4ERR_INVAL; goto out; } } /* If that did not succeed, allocate a state from the FSAL. */ if (*file_state == NULL) { *file_state = op_ctx->fsal_export->exp_ops.alloc_state( op_ctx->fsal_export, STATE_TYPE_SHARE, NULL); /* Remember we allocated a new state */ *new_state = true; /* We are ready to perform the open (with possible create). * in_obj has been set to the file itself or the parent. * filename is NULL if in_obj is the file itself. * * Permission check has been done on directory if appropriate, * otherwise fsal_open2 will do a directory permission * check. * * fsal_open2 handles the permission check on the file * itself and also handles all the share reservation stuff. * * fsal_open2 returns with a ref on out_obj, which should be * passed to the state. */ LogFullDebug(COMPONENT_STATE, "Calling open2 for %s", filename); status = fsal_open2(in_obj, *file_state, openflags, createmode, filename, &sattr, verifier, &out_obj, NULL); if (FSAL_IS_ERROR(status)) { res_OPEN4->status = nfs4_Errno_status(status); goto out; } } else if (createmode >= FSAL_EXCLUSIVE) { /* We have an EXCLUSIVE create with an existing * state. We still need to verify it, but no need * to call reopen2. */ LogFullDebug(COMPONENT_STATE, "Calling verify2 "); status = fsal_verify2(file_obj, verifier); if (FSAL_IS_ERROR(status)) { res_OPEN4->status = nfs4_Errno_status(status); goto out; } /* We need an extra reference below. */ file_obj->obj_ops->get_ref(file_obj); } else { old_openflags = file_obj->obj_ops->status2(file_obj, *file_state); /* Open upgrade */ LogFullDebug(COMPONENT_STATE, "Calling reopen2"); status = fsal_reopen2(file_obj, *file_state, openflags | old_openflags, false); if (FSAL_IS_ERROR(status)) { res_OPEN4->status = nfs4_Errno_status(status); goto out; } /* We need an extra reference below. */ file_obj->obj_ops->get_ref(file_obj); } if (file_obj == NULL) { /* We have a new cache inode entry, take the state lock. */ file_obj = out_obj; PTHREAD_RWLOCK_wrlock(&file_obj->state_hdl->state_lock); state_lock_held = true; } /* Now the state_lock is held for sure and we have an extra LRU * reference to file_obj, which is the opened file. */ if (*new_state) { /* The state data to be added */ union state_data candidate_data; /* Tracking data for the open state */ struct state_refer refer, *p_refer = NULL; state_status_t state_status; candidate_data.share.share_access = arg->share_access & OPEN4_SHARE_ACCESS_BOTH; candidate_data.share.share_deny = arg->share_deny; candidate_data.share.share_access_prev = (1 << candidate_data.share.share_access); candidate_data.share.share_deny_prev = (1 << candidate_data.share.share_deny); LogFullDebug(COMPONENT_STATE, "Creating new state access=%x deny=%x access_prev=%x deny_prev=%x", candidate_data.share.share_access, candidate_data.share.share_deny, candidate_data.share.share_access_prev, candidate_data.share.share_deny_prev); /* Record the sequence info */ if (data->minorversion > 0) { memcpy(refer.session, data->session->session_id, sizeof(sessionid4)); refer.sequence = data->sequence; refer.slot = data->slot; p_refer = &refer; } /* We need to register this state now. */ state_status = state_add_impl(file_obj, STATE_TYPE_SHARE, &candidate_data, owner, file_state, p_refer); if (state_status != STATE_SUCCESS) { /* state_add_impl failure closed and freed state. * file_state will also be NULL at this point. Also * release the ref on file_obj, since the state add * failed. */ file_obj->obj_ops->put_ref(file_obj); res_OPEN4->status = nfs4_Errno_state(state_status); *new_state = false; goto out; } glist_init(&(*file_state)->state_data.share.share_lockstates); } res_OPEN4->status = open4_create_fh(data, file_obj, true); if (res_OPEN4->status != NFS4_OK) { if (*new_state) { /* state_del_locked will close the file. */ state_del_locked(*file_state); *file_state = NULL; *new_state = false; } else { /*Do an open downgrade to the old open flags */ status = file_obj->obj_ops->reopen2(file_obj, *file_state, old_openflags); if (FSAL_IS_ERROR(status)) { LogCrit(COMPONENT_NFS_V4, "Failed to allocate handle, reopen2 failed with %s", fsal_err_txt(status)); } /* Need to release the state_lock before the put_ref * call. */ PTHREAD_RWLOCK_unlock(&file_obj->state_hdl->state_lock); state_lock_held = false; /* Release the extra LRU reference on file_obj. */ file_obj->obj_ops->put_ref(file_obj); goto out; } } /* Since open4_create_fh succeeded the LRU reference to file_obj was * consumed by data->current_obj. */ if (!(*new_state)) { LogFullDebug(COMPONENT_STATE, "Open upgrade old access=%x deny=%x access_prev=%x deny_prev=%x", (*file_state)->state_data.share.share_access, (*file_state)->state_data.share.share_deny, (*file_state)->state_data.share.share_access_prev, (*file_state)->state_data.share.share_deny_prev); LogFullDebug(COMPONENT_STATE, "Open upgrade to access=%x deny=%x", arg->share_access, arg->share_deny); /* Update share_access and share_deny */ (*file_state)->state_data.share.share_access |= arg->share_access & OPEN4_SHARE_ACCESS_BOTH; (*file_state)->state_data.share.share_deny |= arg->share_deny; /* Update share_access_prev and share_deny_prev */ (*file_state)->state_data.share.share_access_prev |= (1 << (arg->share_access & OPEN4_SHARE_ACCESS_BOTH)); (*file_state)->state_data.share.share_deny_prev |= (1 << arg->share_deny); LogFullDebug(COMPONENT_STATE, "Open upgrade new access=%x deny=%x access_prev=%x deny_prev=%x", (*file_state)->state_data.share.share_access, (*file_state)->state_data.share.share_deny, (*file_state)->state_data.share.share_access_prev, (*file_state)->state_data.share.share_deny_prev); } do_delegation(arg, res_OPEN4, data, owner, *file_state, clientid); out: /* Release the attributes (may release an inherited ACL) */ fsal_release_attrs(&sattr); if (state_lock_held) PTHREAD_RWLOCK_unlock(&file_obj->state_hdl->state_lock); if (filename) gsh_free(filename); if (res_OPEN4->status != NFS4_OK) { /* Cleanup state on error */ if (*new_state) (*file_state) ->state_exp->exp_ops.free_state( (*file_state)->state_exp, *file_state); else if (*file_state != NULL) dec_state_t_ref(*file_state); *file_state = NULL; } if (looked_up_file_obj) { /* We got file_obj via lookup, we need to unref it. */ file_obj->obj_ops->put_ref(file_obj); } }
C4Group *C4GroupSet::RegisterParentFolders(const char *szScenFilename) { // the scenario filename may be a scenario or directly a group folder C4Group *pParentGroup=nullptr; bool fParentC4F; char szParentfolder[_MAX_PATH+1]; if (SEqualNoCase(GetExtension(szScenFilename), "ocf")) { fParentC4F = true; SCopy(szScenFilename, szParentfolder, _MAX_PATH); } else { GetParentPath(szScenFilename,szParentfolder); fParentC4F = SEqualNoCase(GetExtension(szParentfolder), "ocf"); } if (fParentC4F) { // replace all (back)slashes with zero-fields int32_t iOriginalLen=SLen(szParentfolder); for (int32_t i=0; i<iOriginalLen; ++i) if (szParentfolder[i]==DirectorySeparator || szParentfolder[i]=='/') szParentfolder[i]=0; // trace back until the file extension is no more .ocf int32_t iPos=iOriginalLen-1; while (iPos) { // ignore additional zero fields (double-backslashes) while (iPos && !szParentfolder[iPos]) --iPos; // break if end has been reached if (!iPos) break; // trace back until next zero field while (iPos && szParentfolder[iPos]) --iPos; // check extension of this folder if (!SEqualNoCase(GetExtension(szParentfolder+iPos+1), "ocf", 3)) break; // continue } // trace backwards, putting the (back)slashes in place again if (iPos) { szParentfolder[iPos+1+SLen(szParentfolder+iPos+1)]=szParentfolder[iPos]=DirectorySeparator; while (iPos--) if (!szParentfolder[iPos]) szParentfolder[iPos]=DirectorySeparator; ++iPos; } // trace forward again, opening all folders (iPos is 0 again) int32_t iGroupIndex=0; while (iPos<iOriginalLen) { // ignore additional zero-fields while (iPos<iOriginalLen && !szParentfolder[iPos]) ++iPos; // break if end has been reached if (iPos>=iOriginalLen) break; // open this folder C4Group *pGroup = new C4Group(); if (pParentGroup) { if (!pGroup->OpenAsChild(pParentGroup, szParentfolder+iPos)) { LogFatal(FormatString("%s: %s", LoadResStr("IDS_PRC_FILENOTFOUND"), szParentfolder+iPos).getData()); delete pGroup; return nullptr; } } else if (!Reloc.Open(*pGroup, szParentfolder+iPos)) { LogFatal(FormatString("%s: %s", LoadResStr("IDS_PRC_FILENOTFOUND"), szParentfolder+iPos).getData()); delete pGroup; return nullptr; } // set this group as new parent pParentGroup=pGroup; // add to group set, if this is a true scenario folder int32_t iContentsMask; if (WildcardMatch(C4CFN_FolderFiles, pParentGroup->GetName())) iContentsMask = C4GSCnt_Folder; else iContentsMask = C4GSCnt_Directory; if (!RegisterGroup(*pParentGroup, true, C4GSPrio_Folder+iGroupIndex++, iContentsMask)) { delete pParentGroup; LogFatal ("RegGrp: internal error"); return nullptr; } // advance by file name length iPos+=SLen(szParentfolder+iPos); } } return pParentGroup; }
bool C4LoaderScreen::Init(const char *szLoaderSpec) { // Determine loader specification if (!szLoaderSpec || !szLoaderSpec[0]) szLoaderSpec = "Loader*"; char szLoaderSpecPng[128 + 1 + 4], szLoaderSpecBmp[128 + 1 + 4]; char szLoaderSpecJpg[128 + 1 + 4], szLoaderSpecJpeg[128 + 1 + 5]; SCopy(szLoaderSpec, szLoaderSpecPng); DefaultExtension(szLoaderSpecPng, "png"); SCopy(szLoaderSpec, szLoaderSpecBmp); DefaultExtension(szLoaderSpecBmp, "bmp"); SCopy(szLoaderSpec, szLoaderSpecJpg); DefaultExtension(szLoaderSpecJpg, "jpg"); SCopy(szLoaderSpec, szLoaderSpecJpeg); DefaultExtension(szLoaderSpecJpeg, "jpeg"); int iLoaders=0; C4Group *pGroup=NULL,*pChosenGrp=NULL; char ChosenFilename[_MAX_PATH+1]; // query groups of equal priority in set while (pGroup=Game.GroupSet.FindGroup(C4GSCnt_Loaders, pGroup, true)) { iLoaders+=SeekLoaderScreens(*pGroup, szLoaderSpecPng, iLoaders, ChosenFilename, &pChosenGrp); iLoaders+=SeekLoaderScreens(*pGroup, szLoaderSpecJpeg, iLoaders, ChosenFilename, &pChosenGrp); iLoaders+=SeekLoaderScreens(*pGroup, szLoaderSpecJpg, iLoaders, ChosenFilename, &pChosenGrp); // lower the chance for any loader other than png iLoaders*=2; iLoaders+=SeekLoaderScreens(*pGroup, szLoaderSpecBmp, iLoaders, ChosenFilename, &pChosenGrp); } // nothing found? seek in main gfx grp C4Group GfxGrp; if (!iLoaders) { // open it GfxGrp.Close(); if (!GfxGrp.Open(Config.AtExePath(C4CFN_Graphics))) { LogFatal(FormatString(LoadResStr("IDS_PRC_NOGFXFILE"),C4CFN_Graphics,GfxGrp.GetError()).getData()); return FALSE; } // seek for png-loaders iLoaders=SeekLoaderScreens(GfxGrp, szLoaderSpecPng, iLoaders, ChosenFilename, &pChosenGrp); iLoaders+=SeekLoaderScreens(GfxGrp, szLoaderSpecJpg, iLoaders, ChosenFilename, &pChosenGrp); iLoaders+=SeekLoaderScreens(GfxGrp, szLoaderSpecJpeg, iLoaders, ChosenFilename, &pChosenGrp); iLoaders*=2; // seek for bmp-loaders iLoaders+=SeekLoaderScreens(GfxGrp, szLoaderSpecBmp, iLoaders, ChosenFilename, &pChosenGrp); // Still nothing found: fall back to general loader spec in main graphics group if (!iLoaders) { iLoaders = SeekLoaderScreens(GfxGrp, "Loader*.png", 0, ChosenFilename, &pChosenGrp); iLoaders += SeekLoaderScreens(GfxGrp, "Loader*.jpg", iLoaders, ChosenFilename, &pChosenGrp); iLoaders += SeekLoaderScreens(GfxGrp, "Loader*.jpeg", iLoaders, ChosenFilename, &pChosenGrp); } // Not even default loaders available? Fail. if (!iLoaders) { LogFatal(FormatString("No loaders found for loader specification: %s/%s/%s/%s", szLoaderSpecPng, szLoaderSpecBmp, szLoaderSpecJpg, szLoaderSpecJpeg).getData()); return FALSE; } } // load loader fctBackground.GetFace().SetBackground(); if (!fctBackground.Load(*pChosenGrp,ChosenFilename, C4FCT_Full,C4FCT_Full,true)) return FALSE; // load info if (szInfo) { delete [] szInfo; szInfo=NULL; } /*size_t iInfoSize; if (Game.ScenarioFile.AccessEntry(C4CFN_Info, &iInfoSize)) { szInfo = new char[iInfoSize+1]; // load info file Game.ScenarioFile.Read(szInfo, iInfoSize); // terminate buffer szInfo[iInfoSize]=0; // insert linebreaks SReplaceChar(szInfo, 0x0a, '|'); }*/ // init fonts if (!Game.GraphicsResource.InitFonts()) return false; // initial draw C4Facet cgo; cgo.Set(Application.DDraw->lpPrimary,0,0,Config.Graphics.ResX,Config.Graphics.ResY); Draw(cgo); // done, success! return TRUE; }
bool C4Application::DoInit(int argc, char * argv[]) { assert(AppState == C4AS_None); // Config overwrite by parameter StdStrBuf sConfigFilename; for (int32_t iPar=0; iPar < argc; iPar++) if (SEqual2NoCase(argv[iPar], "--config=")) sConfigFilename.Copy(argv[iPar] + 9); // Config check Config.Init(); Config.Load(sConfigFilename.getData()); Config.Save(); // sometimes, the configuration can become corrupted due to loading errors or w/e // check this and reset defaults if necessary if (Config.IsCorrupted()) { if (sConfigFilename) { // custom config corrupted: Fail Log("ERROR: Custom configuration corrupted - program abort!\n"); return false; } else { // default config corrupted: Restore default Log("Warning: Configuration corrupted - restoring default!\n"); Config.Default(); Config.Save(); Config.Load(); } } // Open log OpenLog(); Revision.Ref(C4REVISION); // Engine header message Log(C4ENGINECAPTION); LogF("Version: %s %s (%s)", C4VERSION, C4_OS, Revision.getData()); LogF("ExePath: \"%s\"", Config.General.ExePath.getData()); LogF("SystemDataPath: \"%s\"", Config.General.SystemDataPath); LogF("UserDataPath: \"%s\"", Config.General.UserDataPath); // Init C4Group C4Group_SetProcessCallback(&ProcessCallback); C4Group_SetTempPath(Config.General.TempPath.getData()); C4Group_SetSortList(C4CFN_FLS); // Cleanup temp folders left behind Config.CleanupTempUpdateFolder(); // Initialize game data paths Reloc.Init(); // init system group if (!Reloc.Open(SystemGroup, C4CFN_System)) { // Error opening system group - no LogFatal, because it needs language table. // This will *not* use the FatalErrors stack, but this will cause the game // to instantly halt, anyway. const char *szMessage = "Error opening system group file (System.ocg)!"; Log(szMessage); // Fatal error, game cannot start - have player notice MessageDialog(szMessage); return false; } // Parse command line ParseCommandLine(argc, argv); // Open additional logs that depend on command line OpenExtraLogs(); // Init external language packs Languages.Init(); // Load language string table if (!Languages.LoadLanguage(Config.General.LanguageEx)) // No language table was loaded - bad luck... if (!Languages.HasStringTable()) Log("WARNING: No language string table loaded!"); #if defined(WIN32) && defined(WITH_AUTOMATIC_UPDATE) // Windows: handle incoming updates directly, even before starting up the gui // because updates will be applied in the console anyway. if (Application.IncomingUpdate) if (C4UpdateDlg::ApplyUpdate(Application.IncomingUpdate.getData(), false, NULL)) return true; #endif // Fixup resolution if (!Config.Graphics.Windowed) ApplyResolutionConstraints(); // activate Active=true; // Init carrier window if (!isEditor) { if (!(pWindow = FullScreen.Init(this))) { Clear(); ShowGfxErrorDialog(); return false; } } else { if (!(pWindow = Console.Init(this))) { Clear(); return false; } } // init timers (needs window) Add(pGameTimer = new C4ApplicationGameTimer()); // Initialize OpenGL bool success = DDrawInit(this, GetConfigWidth(), GetConfigHeight(), Config.Graphics.BitDepth, Config.Graphics.Monitor); if (!success) { LogFatal(LoadResStr("IDS_ERR_DDRAW")); Clear(); ShowGfxErrorDialog(); return false; } if (!isEditor) { if (!SetVideoMode(Application.GetConfigWidth(), Application.GetConfigHeight(), Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed)) pWindow->SetSize(Config.Graphics.WindowX, Config.Graphics.WindowY); } // Initialize gamepad if (!pGamePadControl && Config.General.GamepadEnabled) pGamePadControl = new C4GamePadControl(); AppState = C4AS_PreInit; return true; }
/** * @brief Up Thread * * @param Arg reference to void * */ void *GPFSFSAL_UP_Thread(void *Arg) { struct gpfs_filesystem *gpfs_fs = Arg; struct fsal_up_vector *event_func; char thr_name[16]; int rc = 0; struct pnfs_deviceid devid; struct stat buf; struct glock fl; struct callback_arg callback; struct gpfs_file_handle handle; int reason = 0; int flags = 0; unsigned int *fhP; int retry = 0; struct gsh_buffdesc key; uint32_t expire_time_attr = 0; uint32_t upflags; int errsv = 0; fsal_status_t fsal_status = {0,}; #ifdef _VALGRIND_MEMCHECK memset(&handle, 0, sizeof(handle)); memset(&buf, 0, sizeof(buf)); memset(&fl, 0, sizeof(fl)); memset(&devid, 0, sizeof(devid)); #endif snprintf(thr_name, sizeof(thr_name), "fsal_up_%"PRIu64".%"PRIu64, gpfs_fs->fs->dev.major, gpfs_fs->fs->dev.minor); SetNameFunction(thr_name); LogFullDebug(COMPONENT_FSAL_UP, "Initializing FSAL Callback context for %d.", gpfs_fs->root_fd); /* wait for nfs init completion to get general_fridge * initialized which is needed for processing some upcall events */ nfs_init_wait(); /* Start querying for events and processing. */ while (1) { LogFullDebug(COMPONENT_FSAL_UP, "Requesting event from FSAL Callback interface for %d.", gpfs_fs->root_fd); handle.handle_size = GPFS_MAX_FH_SIZE; handle.handle_key_size = OPENHANDLE_KEY_LEN; handle.handle_version = OPENHANDLE_VERSION; callback.interface_version = GPFS_INTERFACE_VERSION + GPFS_INTERFACE_SUB_VER; callback.mountdirfd = gpfs_fs->root_fd; callback.handle = &handle; callback.reason = &reason; callback.flags = &flags; callback.buf = &buf; callback.fl = &fl; callback.dev_id = &devid; callback.expire_attr = &expire_time_attr; rc = gpfs_ganesha(OPENHANDLE_INODE_UPDATE, &callback); errsv = errno; if (rc != 0) { rc = -(rc); if (rc > GPFS_INTERFACE_VERSION) { LogFatal(COMPONENT_FSAL_UP, "Ganesha version %d mismatch GPFS version %d.", callback.interface_version, rc); return NULL; } if (errsv == EINTR) continue; LogCrit(COMPONENT_FSAL_UP, "OPENHANDLE_INODE_UPDATE failed for %d. rc %d, errno %d (%s) reason %d", gpfs_fs->root_fd, rc, errsv, strerror(errsv), reason); /* @todo 1000 retry logic will go away once the * OPENHANDLE_INODE_UPDATE ioctl separates EINTR * and EUNATCH. */ if (errsv == EUNATCH && ++retry > 1000) LogFatal(COMPONENT_FSAL_UP, "GPFS file system %d has gone away.", gpfs_fs->root_fd); continue; } retry = 0; /* flags is int, but only the least significant 2 bytes * are valid. We are getting random bits into the upper * 2 bytes! Workaround this until the kernel module * gets fixed. */ flags = flags & 0xffff; LogDebug(COMPONENT_FSAL_UP, "inode update: rc %d reason %d update ino %" PRId64 " flags:%x", rc, reason, callback.buf->st_ino, flags); LogFullDebug(COMPONENT_FSAL_UP, "inode update: flags:%x callback.handle:%p handle size = %u handle_type:%d handle_version:%d key_size = %u handle_fsid=%X.%X f_handle:%p expire: %d", *callback.flags, callback.handle, callback.handle->handle_size, callback.handle->handle_type, callback.handle->handle_version, callback.handle->handle_key_size, callback.handle->handle_fsid[0], callback.handle->handle_fsid[1], callback.handle->f_handle, expire_time_attr); callback.handle->handle_version = OPENHANDLE_VERSION; fhP = (int *)&(callback.handle->f_handle[0]); LogFullDebug(COMPONENT_FSAL_UP, " inode update: handle %08x %08x %08x %08x %08x %08x %08x", fhP[0], fhP[1], fhP[2], fhP[3], fhP[4], fhP[5], fhP[6]); /* Here is where we decide what type of event this is * ... open,close,read,...,invalidate? */ key.addr = &handle; key.len = handle.handle_key_size; LogDebug(COMPONENT_FSAL_UP, "Received event to process for %d", gpfs_fs->root_fd); /* We need valid up_vector while processing some of the * events below. Setup up vector and hold the mutex while * processing the event for the entire duration. */ PTHREAD_MUTEX_lock(&gpfs_fs->upvector_mutex); if (!setup_up_vector(gpfs_fs)) { PTHREAD_MUTEX_unlock(&gpfs_fs->upvector_mutex); return NULL; } event_func = gpfs_fs->up_vector; switch (reason) { case INODE_LOCK_GRANTED: /* Lock Event */ case INODE_LOCK_AGAIN: /* Lock Event */ { LogMidDebug(COMPONENT_FSAL_UP, "%s: owner %p pid %d type %d start %lld len %lld", reason == INODE_LOCK_GRANTED ? "inode lock granted" : "inode lock again", fl.lock_owner, fl.flock.l_pid, fl.flock.l_type, (long long)fl.flock.l_start, (long long)fl.flock.l_len); fsal_lock_param_t lockdesc = { .lock_sle_type = FSAL_POSIX_LOCK, .lock_type = fl.flock.l_type, .lock_start = fl.flock.l_start, .lock_length = fl.flock.l_len }; if (reason == INODE_LOCK_AGAIN) fsal_status = up_async_lock_avail( general_fridge, event_func, &key, fl.lock_owner, &lockdesc, NULL, NULL); else fsal_status = up_async_lock_grant( general_fridge, event_func, &key, fl.lock_owner, &lockdesc, NULL, NULL); } break; case BREAK_DELEGATION: /* Delegation Event */ LogDebug(COMPONENT_FSAL_UP, "delegation recall: flags:%x ino %" PRId64, flags, callback.buf->st_ino); fsal_status = up_async_delegrecall(general_fridge, event_func, &key, NULL, NULL); break; case LAYOUT_FILE_RECALL: /* Layout file recall Event */ { struct pnfs_segment segment = { .offset = 0, .length = UINT64_MAX, .io_mode = LAYOUTIOMODE4_ANY }; LogDebug(COMPONENT_FSAL_UP, "layout file recall: flags:%x ino %" PRId64, flags, callback.buf->st_ino); fsal_status = up_async_layoutrecall( general_fridge, event_func, &key, LAYOUT4_NFSV4_1_FILES, false, &segment, NULL, NULL, NULL, NULL); } break; case LAYOUT_RECALL_ANY: /* Recall all layouts Event */ LogDebug(COMPONENT_FSAL_UP, "layout recall any: flags:%x ino %" PRId64, flags, callback.buf->st_ino); /** * @todo This functionality needs to be implemented as a * bulk FSID CB_LAYOUTRECALL. RECALL_ANY isn't suitable * since it can't be restricted to just one FSAL. Also * an FSID LAYOUTRECALL lets you have multiplke * filesystems exported from one FSAL and not yank layouts * on all of them when you only need to recall them for one. */ break; case LAYOUT_NOTIFY_DEVICEID: /* Device update Event */ LogDebug(COMPONENT_FSAL_UP, "layout dev update: flags:%x ino %" PRId64 " seq %d fd %d fsid 0x%" PRIx64, flags, callback.buf->st_ino, devid.device_id2, devid.device_id4, devid.devid); memset(&devid, 0, sizeof(devid)); devid.fsal_id = FSAL_ID_GPFS; fsal_status = up_async_notify_device(general_fridge, event_func, NOTIFY_DEVICEID4_DELETE_MASK, LAYOUT4_NFSV4_1_FILES, &devid, true, NULL, NULL); break; case INODE_UPDATE: /* Update Event */ { struct attrlist attr; LogMidDebug(COMPONENT_FSAL_UP, "inode update: flags:%x update ino %" PRId64 " n_link:%d", flags, callback.buf->st_ino, (int)callback.buf->st_nlink); /** @todo: This notification is completely * asynchronous. If we happen to change some * of the attributes later, we end up over * writing those with these possibly stale * values as we don't know when we get to * update with these up call values. We should * probably use time stamp or let the up call * always provide UP_TIMES flag in which case * we can compare the current ctime vs up call * provided ctime before updating the * attributes. * * For now, we think size attribute is more * important than others, so invalidate the * attributes and let ganesha fetch attributes * as needed if this update includes a size * change. We are careless for other attribute * changes, and we may end up with stale values * until this gets fixed! */ if (flags & (UP_SIZE | UP_SIZE_BIG)) { fsal_status = event_func->invalidate( event_func, &key, FSAL_UP_INVALIDATE_CACHE); break; } /* Check for accepted flags, any other changes just invalidate. */ if (flags & ~(UP_SIZE | UP_NLINK | UP_MODE | UP_OWN | UP_TIMES | UP_ATIME | UP_SIZE_BIG)) { fsal_status = event_func->invalidate( event_func, &key, FSAL_UP_INVALIDATE_CACHE); } else { /* buf may not have all attributes set. * Set the mask to what is changed */ attr.valid_mask = 0; attr.acl = NULL; upflags = 0; if (flags & UP_SIZE) attr.valid_mask |= ATTR_CHGTIME | ATTR_CHANGE | ATTR_SIZE | ATTR_SPACEUSED; if (flags & UP_SIZE_BIG) { attr.valid_mask |= ATTR_CHGTIME | ATTR_CHANGE | ATTR_SIZE | ATTR_SPACEUSED; upflags |= fsal_up_update_filesize_inc | fsal_up_update_spaceused_inc; } if (flags & UP_MODE) attr.valid_mask |= ATTR_CHGTIME | ATTR_CHANGE | ATTR_MODE; if (flags & UP_OWN) attr.valid_mask |= ATTR_CHGTIME | ATTR_CHANGE | ATTR_OWNER | ATTR_GROUP | ATTR_MODE; if (flags & UP_TIMES) attr.valid_mask |= ATTR_CHGTIME | ATTR_CHANGE | ATTR_ATIME | ATTR_CTIME | ATTR_MTIME; if (flags & UP_ATIME) attr.valid_mask |= ATTR_CHGTIME | ATTR_CHANGE | ATTR_ATIME; if (flags & UP_NLINK) attr.valid_mask |= ATTR_NUMLINKS; attr.request_mask = attr.valid_mask; attr.expire_time_attr = expire_time_attr; posix2fsal_attributes(&buf, &attr); fsal_status = event_func->update( event_func, &key, &attr, upflags); if ((flags & UP_NLINK) && (attr.numlinks == 0)) { upflags = fsal_up_nlink; attr.valid_mask = 0; attr.request_mask = 0; fsal_status = up_async_update (general_fridge, event_func, &key, &attr, upflags, NULL, NULL); } } } break; case THREAD_STOP: /* We wanted to terminate this thread */ LogDebug(COMPONENT_FSAL_UP, "Terminating the GPFS up call thread for %d", gpfs_fs->root_fd); PTHREAD_MUTEX_unlock(&gpfs_fs->upvector_mutex); return NULL; case INODE_INVALIDATE: LogMidDebug(COMPONENT_FSAL_UP, "inode invalidate: flags:%x update ino %" PRId64, flags, callback.buf->st_ino); upflags = FSAL_UP_INVALIDATE_CACHE; fsal_status = event_func->invalidate_close( event_func, &key, upflags); break; case THREAD_PAUSE: /* File system image is probably going away, but * we don't need to do anything here as we * eventually get other errors that stop this * thread. */ PTHREAD_MUTEX_unlock(&gpfs_fs->upvector_mutex); continue; /* get next event */ default: PTHREAD_MUTEX_unlock(&gpfs_fs->upvector_mutex); LogWarn(COMPONENT_FSAL_UP, "Unknown event: %d", reason); continue; } PTHREAD_MUTEX_unlock(&gpfs_fs->upvector_mutex); if (FSAL_IS_ERROR(fsal_status) && fsal_status.major != ERR_FSAL_NOENT) { LogWarn(COMPONENT_FSAL_UP, "Event %d could not be processed for fd %d rc %s", reason, gpfs_fs->root_fd, fsal_err_txt(fsal_status)); } } return NULL; } /* GPFSFSAL_UP_Thread */
/** * _9p_rdma_dispatcher_thread: 9P/RDMA dispatcher * * @param Arg the socket number cast as a void * in pthread_create * * @return NULL * */ void * _9p_rdma_dispatcher_thread( void * Arg ) { msk_trans_t *trans; msk_trans_t *child_trans; msk_trans_attr_t trans_attr; pthread_attr_t attr_thr ; pthread_t thrid_handle_trans ; memset(&trans_attr, 0, sizeof(msk_trans_attr_t)); trans_attr.server = nfs_param._9p_param._9p_rdma_backlog ; trans_attr.rq_depth = _9P_RDMA_OUT+1; trans_attr.addr.sa_in.sin_family = AF_INET; trans_attr.addr.sa_in.sin_port = htons(nfs_param._9p_param._9p_rdma_port) ; trans_attr.disconnect_callback = _9p_rdma_callback_disconnect; inet_pton(AF_INET, "0.0.0.0", &trans_attr.addr.sa_in.sin_addr); trans_attr.worker_count = -1; trans_attr.debug = MSK_DEBUG_EVENT; trans_attr.worker_queue_size = 256; SetNameFunction("_9p_rdma_dispatch_thr" ) ; /* Calling dispatcher main loop */ LogInfo(COMPONENT_9P_DISPATCH, "Entering 9P/RDMA dispatcher"); LogDebug(COMPONENT_9P_DISPATCH, "My pthread id is %p", (caddr_t) pthread_self()); /* Prepare attr_thr for dispatch */ memset( (char *)&attr_thr, 0 , sizeof( attr_thr ) ) ; /* Set the pthread attributes */ if( pthread_attr_init( &attr_thr ) ) LogFatal( COMPONENT_9P, "9P/RDMA dispatcher could not init pthread_attr_t" ) ; if( pthread_attr_setscope(&attr_thr, PTHREAD_SCOPE_SYSTEM) ) LogFatal( COMPONENT_9P, "9P/RDMA dispatcher could not set pthread_attr_t:scope_system" ) ; if( pthread_attr_setdetachstate(&attr_thr, PTHREAD_CREATE_JOINABLE ) ) LogFatal( COMPONENT_9P, "9P/RDMA dispatcher could not set pthread_attr_t:create_joignable" ) ; /* Init RDMA via mooshika */ if( msk_init( &trans, &trans_attr ) ) LogFatal( COMPONENT_9P, "9P/RDMA dispatcher could not start mooshika engine" ) ; else LogEvent( COMPONENT_9P, "Mooshika engine is started" ) ; /* Bind Mooshika */ if( msk_bind_server(trans ) ) LogFatal( COMPONENT_9P, "9P/RDMA dispatcher could not bind mooshika engine" ) ; else LogEvent( COMPONENT_9P, "Mooshika engine is bound" ) ; /* Start infinite loop here */ while( 1 ) { if( ( child_trans = msk_accept_one( trans ) ) == NULL ) LogMajor( COMPONENT_9P, "9P/RDMA : dispatcher failed to accept a new client" ) ; else { if( pthread_create( &thrid_handle_trans, &attr_thr, _9p_rdma_thread, child_trans ) ) LogMajor( COMPONENT_9P, "9P/RDMA : dispatcher accepted a new client but could not spawn a related thread" ) ; else LogEvent( COMPONENT_9P, "9P/RDMA: thread #%x spawned to managed new child_trans [%p]", (unsigned int)thrid_handle_trans, child_trans ) ; } } /* for( ;; ) */ return NULL ; } /* _9p_rdma_dispatcher_thread */
bool C4Startup::DoStartup() { assert(!fInStartup); assert(Game.pGUI); // now in startup! fInStartup = true; fLastDlgWasBack = false; // first run: Splash video #ifndef USE_CONSOLE if (!fFirstRun) { fFirstRun = true; if (!Config.Startup.NoSplash && !Application.NoSplash) { Game.VideoPlayer.PlayVideo(C4CFN_Splash); } } #endif // make sure loader is drawn after splash Game.GraphicsSystem.EnableLoaderDrawing(); // Play some music! if (Config.Sound.FEMusic) Application.MusicSystem.Play(); // clear any previous if (pLastDlg) { delete pLastDlg; pLastDlg = NULL; } if (pCurrDlg) { delete pCurrDlg; pCurrDlg = NULL; } // start with the last dlg that was shown - at first startup main dialog if (!SwitchDialog(eLastDlgID)) return false; // show error dlg if restart if (Game.fQuitWithError || GetFatalError()) { Game.fQuitWithError = false; // preferred: Show fatal error const char *szErr = GetFatalError(); if (szErr) { Game.pGUI->ShowMessage(szErr, LoadResStr("IDS_DLG_LOG"), C4GUI::Ico_Error); } else { // fallback to showing complete log StdStrBuf sLastLog; if (GetLogSection(Game.StartupLogPos, Game.QuitLogPos - Game.StartupLogPos, sLastLog)) if (!sLastLog.isNull()) Game.pGUI->ShowRemoveDlg(new C4GUI::InfoDialog(LoadResStr("IDS_DLG_LOG"), 10, sLastLog)); } ResetFatalError(); } // while state startup: keep looping while(fInStartup && Game.pGUI && !pCurrDlg->IsAborted()) if (Application.HandleMessage() == HR_Failure) return false; // check whether startup was aborted; first checking Game.pGUI // (because an external call to Game.Clear() would invalidate dialogs) if (!Game.pGUI) return false; if (pLastDlg) { delete pLastDlg; pLastDlg = NULL; } if (pCurrDlg) { // deinit last shown dlg if (pCurrDlg->IsAborted()) { // force abort flag if dlg abort done by user fAborted = true; } else if (pCurrDlg->IsShown()) { pCurrDlg->Close(true); } delete pCurrDlg; pCurrDlg = NULL; } // now no more in startup! fInStartup = false; // after startup: cleanup if (Game.pGUI) Game.pGUI->CloseAllDialogs(true); // reinit keyboard to reflect any config changes that might have been done // this is a good time to do it, because no GUI dialogs are opened if (Game.pGUI) if (!Game.InitKeyboard()) LogFatal(LoadResStr("IDS_ERR_NOKEYBOARD")); // all okay; return whether startup finished with a game start selection return !fAborted; }
bool C4MaterialMap::CrossMapMaterials(const char* szEarthMaterial) // Called after load { // Check material number if (::MaterialMap.Num>C4MaxMaterial) { LogFatal(LoadResStr("IDS_PRC_TOOMANYMATS")); return false; } // build reaction function map delete [] ppReactionMap; typedef C4MaterialReaction * C4MaterialReactionPtr; ppReactionMap = new C4MaterialReactionPtr[(Num+1)*(Num+1)]; for (int32_t iMatPXS=-1; iMatPXS<Num; iMatPXS++) { C4Material *pMatPXS = (iMatPXS+1) ? Map+iMatPXS : NULL; for (int32_t iMatLS=-1; iMatLS<Num; iMatLS++) { C4MaterialReaction *pReaction = NULL; C4Material *pMatLS = ( iMatLS+1) ? Map+ iMatLS : NULL; // natural stuff: material conversion here? if (pMatPXS && pMatPXS->sInMatConvert.getLength() && SEqualNoCase(pMatPXS->sInMatConvert.getData(), pMatLS ? pMatLS->Name : C4TLS_MatSky)) pReaction = &DefReactConvert; // non-sky reactions else if (pMatPXS && pMatLS) { // incindiary vs extinguisher if ((pMatPXS->Incendiary && pMatLS->Extinguisher) || (pMatPXS->Extinguisher && pMatLS->Incendiary)) pReaction = &DefReactPoof; // incindiary vs inflammable else if ((pMatPXS->Incendiary && pMatLS->Inflammable) || (pMatPXS->Inflammable && pMatLS->Incendiary)) pReaction = &DefReactIncinerate; // corrosive vs corrode else if (pMatPXS->Corrosive && pMatLS->Corrode) pReaction = &DefReactCorrode; // liquid hitting liquid or solid: Material insertion else if (DensityLiquid(MatDensity(iMatPXS)) && DensitySemiSolid(MatDensity(iMatLS))) pReaction = &DefReactInsert; // solid hitting solid: Material insertion else if (DensitySolid(MatDensity(iMatPXS)) && DensitySolid(MatDensity(iMatLS))) pReaction = &DefReactInsert; } // assign the function; or NULL for no reaction SetMatReaction(iMatPXS, iMatLS, pReaction); } } // reset max shape size max_shape_width=max_shape_height=0; // material-specific initialization int32_t cnt; for (cnt=0; cnt<Num; cnt++) { C4Material *pMat = Map+cnt; const char *szTextureOverlay = NULL; // newgfx: init pattern if (Map[cnt].sTextureOverlay.getLength()) if (::TextureMap.GetTexture(Map[cnt].sTextureOverlay.getLength())) { szTextureOverlay = Map[cnt].sTextureOverlay.getData(); // backwards compatibility: if a pattern was specified although the no-pattern flag was set, overwrite that flag if (Map[cnt].OverlayType & C4MatOv_None) { DebugLogF("Error in overlay of material %s: Flag C4MatOv_None ignored because a custom overlay (%s) was specified!", Map[cnt].Name, szTextureOverlay); Map[cnt].OverlayType &= ~C4MatOv_None; } } // default to first texture in texture map int iTexMapIx; if (!szTextureOverlay && (iTexMapIx = ::TextureMap.GetIndex(Map[cnt].Name, NULL, false))) szTextureOverlay = TextureMap.GetEntry(iTexMapIx)->GetTextureName(); // default to smooth if (!szTextureOverlay) szTextureOverlay = "none"; // search/create entry in texmap Map[cnt].DefaultMatTex = ::TextureMap.GetIndex(Map[cnt].Name, szTextureOverlay, true, FormatString("DefaultMatTex of mat %s", Map[cnt].Name).getData()); // init PXS facet C4Surface * sfcTexture; C4Texture * Texture; if (Map[cnt].sPXSGfx.getLength()) if ((Texture=::TextureMap.GetTexture(Map[cnt].sPXSGfx.getData()))) if ((sfcTexture=Texture->Surface32)) Map[cnt].PXSFace.Set(sfcTexture, Map[cnt].PXSGfxRt.x, Map[cnt].PXSGfxRt.y, Map[cnt].PXSGfxRt.Wdt, Map[cnt].PXSGfxRt.Hgt); // evaluate reactions for that material for (unsigned int iRCnt = 0; iRCnt < pMat->CustomReactionList.size(); ++iRCnt) { C4MaterialReaction *pReact = &(pMat->CustomReactionList[iRCnt]); if (pReact->sConvertMat.getLength()) pReact->iConvertMat = Get(pReact->sConvertMat.getData()); else pReact->iConvertMat = -1; // evaluate target spec int32_t tmat; if (MatValid(tmat=Get(pReact->TargetSpec.getData()))) { // single material target if (pReact->fInverseSpec) for (int32_t cnt2=-1; cnt2<Num; cnt2++) { if (cnt2!=tmat) SetMatReaction(cnt, cnt2, pReact); else SetMatReaction(cnt, tmat, pReact); } } else if (SEqualNoCase(pReact->TargetSpec.getData(), "All")) { // add to all materials, including sky if (!pReact->fInverseSpec) for (int32_t cnt2=-1; cnt2<Num; cnt2++) SetMatReaction(cnt, cnt2, pReact); } else if (SEqualNoCase(pReact->TargetSpec.getData(), "Solid")) { // add to all solid materials if (pReact->fInverseSpec) SetMatReaction(cnt, -1, pReact); for (int32_t cnt2=0; cnt2<Num; cnt2++) if (DensitySolid(Map[cnt2].Density) != pReact->fInverseSpec) SetMatReaction(cnt, cnt2, pReact); } else if (SEqualNoCase(pReact->TargetSpec.getData(), "SemiSolid")) { // add to all semisolid materials if (pReact->fInverseSpec) SetMatReaction(cnt, -1, pReact); for (int32_t cnt2=0; cnt2<Num; cnt2++) if (DensitySemiSolid(Map[cnt2].Density) != pReact->fInverseSpec) SetMatReaction(cnt, cnt2, pReact); } else if (SEqualNoCase(pReact->TargetSpec.getData(), "Background")) { // add to all BG materials, including sky if (!pReact->fInverseSpec) SetMatReaction(cnt, -1, pReact); for (int32_t cnt2=0; cnt2<Num; cnt2++) if (!Map[cnt2].Density != pReact->fInverseSpec) SetMatReaction(cnt, cnt2, pReact); } else if (SEqualNoCase(pReact->TargetSpec.getData(), "Sky")) { // add to sky if (!pReact->fInverseSpec) SetMatReaction(cnt, -1, pReact); else for (int32_t cnt2=0; cnt2<Num; cnt2++) SetMatReaction(cnt, cnt2, pReact); } else if (SEqualNoCase(pReact->TargetSpec.getData(), "Incendiary") || SEqualNoCase(pReact->TargetSpec.getData(), "Incindiary")) { // add to all incendiary materials if (pReact->fInverseSpec) SetMatReaction(cnt, -1, pReact); for (int32_t cnt2=0; cnt2<Num; cnt2++) if (!Map[cnt2].Incendiary == pReact->fInverseSpec) SetMatReaction(cnt, cnt2, pReact); } else if (SEqualNoCase(pReact->TargetSpec.getData(), "Extinguisher")) { // add to all incendiary materials if (pReact->fInverseSpec) SetMatReaction(cnt, -1, pReact); for (int32_t cnt2=0; cnt2<Num; cnt2++) if (!Map[cnt2].Extinguisher == pReact->fInverseSpec) SetMatReaction(cnt, cnt2, pReact); } else if (SEqualNoCase(pReact->TargetSpec.getData(), "Inflammable")) { // add to all incendiary materials if (pReact->fInverseSpec) SetMatReaction(cnt, -1, pReact); for (int32_t cnt2=0; cnt2<Num; cnt2++) if (!Map[cnt2].Inflammable == pReact->fInverseSpec) SetMatReaction(cnt, cnt2, pReact); } else if (SEqualNoCase(pReact->TargetSpec.getData(), "Corrosive")) { // add to all incendiary materials if (pReact->fInverseSpec) SetMatReaction(cnt, -1, pReact); for (int32_t cnt2=0; cnt2<Num; cnt2++) if (!Map[cnt2].Corrosive == pReact->fInverseSpec) SetMatReaction(cnt, cnt2, pReact); } else if (SEqualNoCase(pReact->TargetSpec.getData(), "Corrode")) { // add to all incendiary materials if (pReact->fInverseSpec) SetMatReaction(cnt, -1, pReact); for (int32_t cnt2=0; cnt2<Num; cnt2++) if (!Map[cnt2].Corrode == pReact->fInverseSpec) SetMatReaction(cnt, cnt2, pReact); } } } // second loop (DefaultMatTex is needed by GetIndexMatTex) for (cnt=0; cnt<Num; cnt++) { if (Map[cnt].sBlastShiftTo.getLength()) Map[cnt].BlastShiftTo=::TextureMap.GetIndexMatTex(Map[cnt].sBlastShiftTo.getData(), NULL, true, FormatString("BlastShiftTo of mat %s", Map[cnt].Name).getData()); if (Map[cnt].sInMatConvertTo.getLength()) Map[cnt].InMatConvertTo=Get(Map[cnt].sInMatConvertTo.getData()); if (Map[cnt].sBelowTempConvertTo.getLength()) Map[cnt].BelowTempConvertTo=::TextureMap.GetIndexMatTex(Map[cnt].sBelowTempConvertTo.getData(), NULL, true, FormatString("BelowTempConvertTo of mat %s", Map[cnt].Name).getData()); if (Map[cnt].sAboveTempConvertTo.getLength()) Map[cnt].AboveTempConvertTo=::TextureMap.GetIndexMatTex(Map[cnt].sAboveTempConvertTo.getData(), NULL, true, FormatString("AboveTempConvertTo of mat %s", Map[cnt].Name).getData()); } // Get hardcoded system material indices const C4TexMapEntry* earth_entry = ::TextureMap.GetEntry(::TextureMap.GetIndexMatTex(szEarthMaterial)); if(!earth_entry) { LogFatal(FormatString("Earth material \"%s\" not found!", szEarthMaterial).getData()); return false; } MVehic = Get("Vehicle"); MCVehic = Mat2PixColDefault(MVehic); MHalfVehic = Get("HalfVehicle"); MCHalfVehic = Mat2PixColDefault(MHalfVehic); MTunnel = Get("Tunnel"); MWater = Get("Water"); MEarth = Get(earth_entry->GetMaterialName()); if ((MVehic==MNone) || (MTunnel==MNone)) { LogFatal(LoadResStr("IDS_PRC_NOSYSMATS")); return false; } return true; }
BOOL C4Playback::Open(C4Group &rGrp) { // clean up Clear(); fLoadSequential = false; iLastSequentialFrame = 0; bool fStrip = false; // get text record file StdStrBuf TextBuf; if (rGrp.LoadEntryString(C4CFN_CtrlRecText, TextBuf)) { if (!ReadText(TextBuf)) return FALSE; } else { // open group? Then do some sequential reading for large files // Can't do this when a dump is forced, because the dump needs all data // Also can't do this when stripping is desired if (!rGrp.IsPacked()) if (!Game.RecordDumpFile.getLength()) if (!fStrip) fLoadSequential = true; // get record file if (fLoadSequential) { if (!rGrp.FindEntry(C4CFN_CtrlRec)) return FALSE; if (!playbackFile.Open( FormatString("%s%c%s", rGrp.GetFullName().getData(), (char)DirectorySeparator, (const char *)C4CFN_CtrlRec).getData())) return FALSE; // forcing first chunk to be read; will call ReadBinary currChunk = chunks.end(); if (!NextSequentialChunk()) { // empty replay??! LogFatal("Record: Binary read error."); return FALSE; } } else { // non-sequential reading: Just read as a whole StdBuf BinaryBuf; if (rGrp.LoadEntry(C4CFN_CtrlRec, BinaryBuf)) { if (!ReadBinary(BinaryBuf)) return FALSE; } else { // file too large? Try sequential loading and parsing /* size_t iSize; if (rGrp.AccessEntry(C4CFN_CtrlRec, &iSize)) { CStdFile fOut; fOut.Create(Game.RecordDumpFile.getData()); fLoadSequential = true; const size_t iChunkSize = 1024*1024*16; // 16M while (iSize) { size_t iLoadSize = Min<size_t>(iChunkSize, iSize); BinaryBuf.SetSize(iLoadSize); if (!rGrp.Read(BinaryBuf.getMData(), iLoadSize)) { LogFatal("Record: Binary load error!"); return FALSE; } iSize -= iLoadSize; if (!ReadBinary(BinaryBuf)) return FALSE; LogF("%d binary remaining", iSize); currChunk = chunks.begin(); if (fStrip) Strip(); StdStrBuf s(ReWriteText()); fOut.WriteString(s.getData()); LogF("Wrote %d text bytes (%d binary remaining)", s.getLength(), iSize); chunks.clear(); } fOut.Close(); fLoadSequential = false; } else*/ { // no control data? LogFatal("Record: No control data found!"); return FALSE; } } } } // rewrite record if (fStrip) Strip(); if (Game.RecordDumpFile.getLength()) { if (SEqualNoCase(GetExtension(Game.RecordDumpFile.getData()), "txt")) ReWriteText().SaveToFile(Game.RecordDumpFile.getData()); else ReWriteBinary().SaveToFile(Game.RecordDumpFile.getData()); } // reset status currChunk = chunks.begin(); Finished = false; // external debugrec file #if defined(DEBUGREC_EXTFILE) && defined(DEBUGREC) #ifdef DEBUGREC_EXTFILE_WRITE if (!DbgRecFile.Create(DEBUGREC_EXTFILE)) { LogFatal("DbgRec: Creation of external file \"" DEBUGREC_EXTFILE "\" failed!"); return FALSE; } else Log("DbgRec: Writing to \"" DEBUGREC_EXTFILE "\"..."); #else if (!DbgRecFile.Open(DEBUGREC_EXTFILE)) { LogFatal("DbgRec: Opening of external file \"" DEBUGREC_EXTFILE "\" failed!"); return FALSE; } else Log("DbgRec: Checking against \"" DEBUGREC_EXTFILE "\"..."); #endif #endif // ok return TRUE; }