/**
 * _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 */
Beispiel #3
0
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;
}
Beispiel #6
0
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
}
Beispiel #7
0
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;
}
Beispiel #8
0
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 */
Beispiel #9
0
/**
 * _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,
			&centvingt, sizeof(centvingt)) == -1) ||
	    (setsockopt(sock,
			IPPROTO_TCP, TCP_KEEPINTVL,
			&centvingt, 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 */
Beispiel #10
0
/* 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;
}
Beispiel #11
0
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(&current_time_struct, localtime(&current_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 ) */
Beispiel #13
0
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;
}
Beispiel #14
0
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;
	}
Beispiel #15
0
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 */
Beispiel #17
0
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 */
Beispiel #18
0
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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
/* 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;
}
Beispiel #21
0
void nlm_startup(void)
{
  if(nlm_async_callback_init() == -1)
    LogFatal(COMPONENT_INIT,
             "Could not start NLM async thread");
}
Beispiel #22
0
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);
	}
}
Beispiel #23
0
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;
}
Beispiel #26
0
/**
 * @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 */
Beispiel #28
0
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;
	}
Beispiel #29
0
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;
}
Beispiel #30
0
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;
}