Example #1
0
void fuse_chan_destroy(struct fuse_chan *ch)
{
    fuse_session_remove_chan(ch);
    if (ch->op.destroy)
        ch->op.destroy(ch);
    free(ch);
}
Example #2
0
int main(int argc, char *argv[])
{
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
	struct fuse_chan *ch;
	char *mountpoint;
	int err = -1;

	if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
	    (ch = fuse_mount(mountpoint, &args)) != NULL) {
		struct fuse_session *se;

		se = fuse_lowlevel_new(&args, &hello_ll_oper,
				       sizeof(hello_ll_oper), NULL);
		if (se != NULL) {
			if (fuse_set_signal_handlers(se) != -1) {
				fuse_session_add_chan(se, ch);
				err = fuse_session_loop(se);
				fuse_remove_signal_handlers(se);
				fuse_session_remove_chan(ch);
			}
			fuse_session_destroy(se);
		}
		fuse_unmount(mountpoint, ch);
	}
	fuse_opt_free_args(&args);

	return err ? 1 : 0;
}
Example #3
0
int main(int argc, char *argv[]){
  // Initialize an empty argument list                                                  
  struct fuse_args mountpt = FUSE_ARGS_INIT(0, NULL);
  // add program and mountpoint                                   
  fuse_opt_add_arg(&mountpt, argv[0]);
  fuse_opt_add_arg(&mountpt, argv[1]);
  //fuse_opt_add_arg(&mountpt, argv[2]);// for debug                            
  //fuse_opt_add_arg(&mountpt, argv[3]);// for debug                   

  log_file_path= argv[2];
  fs_size=atoi(argv[3])*1000000;
  num_blocks=fs_size/block_size;
  if(num_blocks < 1000){
    free_space =block_size;
  }else
  free_space=block_size*4;

  dictionary= malloc(num_blocks*sizeof(int));
  log_fp = fopen (log_file_path,"a+");
  if (log_fp == NULL) {
    printf ("Data file could not be opened\n");
    return 1;
  }
  initialize_dictionary();
  mount=time(NULL);

  struct fuse_args args = FUSE_ARGS_INIT(mountpt.argc, mountpt.argv);
  struct fuse_chan *ch;
  char *mountpoint;
  int err = -1;
  if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
      (ch = fuse_mount(mountpoint, &args)) != NULL) {
    struct fuse_session *se;
    se = fuse_lowlevel_new(&args, &lfs_ll_oper,
			   sizeof(lfs_ll_oper), NULL);
    if (se != NULL) {
      if (fuse_set_signal_handlers(se) != -1) {
	fuse_session_add_chan(se, ch);
	/* Block until ctrl+c or fusermount -u */
	err = fuse_session_loop(se);
	fuse_remove_signal_handlers(se);
	fuse_session_remove_chan(ch);
      }
      fuse_session_destroy(se);
      unmount=time(NULL);
      write_stats();
    }
    fuse_unmount(mountpoint, ch);
  }
  fuse_opt_free_args(&args);
  free(dictionary);
  fclose(log_fp);
  return err ? 1 : 0;

}
Example #4
0
int main(int argc, char *argv[])
{
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
	struct fuse_chan *ch;
	char *mountpoint;
	int ret = -1;
	struct lo_data lo = { .debug = 0 };

	if (fuse_opt_parse(&args, &lo, lo_opts, NULL) == -1)
		exit(1);
	lo.root.next = lo.root.prev = &lo.root;
	lo.root.fd = open("/", O_PATH);
	lo.root.nlookup = 2;
	if (lo.root.fd == -1)
		err(1, "open(\"/\", O_PATH)");

	if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
	    (ch = fuse_mount(mountpoint, &args)) != NULL) {
		struct fuse_session *se;
		se = fuse_lowlevel_new(&args, &lo_oper, sizeof(lo_oper), &lo);
		if (se != NULL) {
			if (fuse_set_signal_handlers(se) != -1) {
				fuse_session_add_chan(se, ch);
				ret = fuse_session_loop(se);
				fuse_remove_signal_handlers(se);
				fuse_session_remove_chan(ch);
			}
			fuse_session_destroy(se);
		}
		fuse_unmount(mountpoint, ch);
		free(mountpoint);
	}
	fuse_opt_free_args(&args);

	while (lo.root.next != &lo.root)
		lo_free(lo.root.next);

	return ret ? 1 : 0;
}
Example #5
0
static void
fuse_unmount_all(void)
{
    	VERIFY(pthread_mutex_lock(&sysmtx) == 0);

    	for(int i = nfds-1; i >= 1; i--) {
		if(fds[i].fd == -1)
	    		continue;

#ifdef DEBUG
		fprintf(stderr, "Filesystem %i (%s) is being unmounted\n", i, mountpoints[i]);
#endif
		/* unmount before shuting down... */
		fuse_session_remove_chan(fsinfo[i].ch);
		fuse_session_destroy(fsinfo[i].se);
		fsinfo[i].se = NULL;
		fuse_unmount(mountpoints[i],fsinfo[i].ch);
		close(fds[i].fd);
		fds[i].fd = -1;
		kmem_free(mountpoints[i],fsinfo[i].mntlen+1); 
    	}

    	VERIFY(pthread_mutex_unlock(&sysmtx) == 0);
}
Example #6
0
/**
*  Init of the pseudo fuse thread 

  @param ch : initial channel
  @param se : initial session
  @param rozofs_fuse_buffer_count : number of request buffers (corresponds to the number of fuse save context)  
  
  @retval 0 on success
  @retval -1 on error
*/
int rozofs_fuse_init(struct fuse_chan *ch,struct fuse_session *se,int rozofs_fuse_buffer_count)
{
  int status = 0;
  
//   return 0;
   
  int fileflags;
  rozofs_fuse_ctx_p = malloc(sizeof (rozofs_fuse_ctx_t));
  if (rozofs_fuse_ctx_p == NULL) 
  {
    /*
    ** cannot allocate memory for fuse rozofs context
    */
    return -1;
  }
  /*
  ** clear read/write merge stats table
  */
  memset(rozofs_write_merge_stats_tab,0,sizeof(uint64_t)*RZ_FUSE_WRITE_MAX);
  memset (rozofs_write_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX);
  memset (rozofs_read_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX);
  memset(&rozofs_fuse_read_write_stats_buf,0,sizeof(rozofs_fuse_read_write_stats));
  /*
  ** init of the context
  */
  rozofs_fuse_ctx_p->fuseReqPoolRef = NULL;
  rozofs_fuse_ctx_p->ch             = NULL;
  rozofs_fuse_ctx_p->se             = se;
  rozofs_fuse_ctx_p->bufsize        = 0; 
  rozofs_fuse_ctx_p->buf_fuse_req_p = NULL;
  rozofs_fuse_ctx_p->initBufCount   = rozofs_fuse_buffer_count;
  
  while (1)
  {
     /*
     ** get the receive buffer size for former channel in order to create the request distributor
     */
     int bufsize = fuse_chan_bufsize(ch);
     rozofs_fuse_ctx_p->bufsize = bufsize;
     /*
     ** create the pool
     */
     rozofs_fuse_ctx_p->fuseReqPoolRef = ruc_buf_poolCreate(rozofs_fuse_buffer_count,sizeof(rozofs_fuse_save_ctx_t));
     if (rozofs_fuse_ctx_p->fuseReqPoolRef == NULL)
     {
        ERRLOG "rozofs_fuse_init buffer pool creation error(%d,%d)", (int)rozofs_fuse_buffer_count, (int)sizeof(rozofs_fuse_save_ctx_t) ENDERRLOG ;
        status = -1;
        break;
     }
     /*
     ** allocate a buffer for receiving the fuse request
     */
     rozofs_fuse_ctx_p->buf_fuse_req_p = malloc(bufsize);
     if (rozofs_fuse_ctx_p == NULL) 
     {     
        ERRLOG "rozofs_fuse_init out of memory %d", bufsize ENDERRLOG ;
        status = -1;
        break;     
     }
     /*
     ** get the fd of the channel
     */
     rozofs_fuse_ctx_p->fd = fuse_chan_fd(ch);
     /*
     ** create a new channel with the specific operation for rozofs (non-blocking)
     */  
     rozofs_fuse_ctx_p->ch = fuse_chan_new(&rozofs_fuse_ch_ops,fuse_chan_fd(ch),fuse_chan_bufsize(ch),rozofs_fuse_ctx_p);  
     if (rozofs_fuse_ctx_p->ch == NULL)
     {
        ERRLOG "rozofs_fuse_init fuse_chan_new error"  ENDERRLOG ;
        status = -1;
        break;          
     }
     /*
     ** remove the association between the initial session and channel
     */
     fuse_session_remove_chan(ch);  
     /*
     ** OK, now add the new channel
     */
     fuse_session_add_chan(se,rozofs_fuse_ctx_p->ch );  
     /*
     ** set the channel in non blocking mode
     */
     if((fileflags=fcntl(rozofs_fuse_ctx_p->fd,F_GETFL,0))==-1)
     {
       RUC_WARNING(errno);
       status = -1; 
       break;   
     }

     if((fcntl(rozofs_fuse_ctx_p->fd,F_SETFL,fileflags|O_NDELAY))==-1)
     {
       RUC_WARNING(errno);
       status = -1; 
       break;   
     }
     /*
     ** perform the connection with the socket controller
     */
   /*
   ** OK, we are almost done, just need to connect with the socket controller
   */
   rozofs_fuse_ctx_p->connectionId = ruc_sockctl_connect(rozofs_fuse_ctx_p->fd,  // Reference of the socket
                                              "rozofs_fuse",                 // name of the socket
                                              3,                             // Priority within the socket controller
                                              (void*)rozofs_fuse_ctx_p,      // user param for socketcontroller callback
                                              &rozofs_fuse_callBack_sock);   // Default callbacks
    if (rozofs_fuse_ctx_p->connectionId == NULL)
    {
       /*
       ** Fail to connect with the socket controller
       */
       RUC_WARNING(-1);
       status = -1; 
       break;   
    } 

     status = 0;
     break;
  }
  
  uma_dbg_addTopic("fuse", rozofs_fuse_show);
  return status;
  
}
Example #7
0
int mainloop(struct fuse_args *args,const char* mp,int mt,int fg) {
	struct fuse_session *se;
	struct fuse_chan *ch;
	struct rlimit rls;
	int piped[2];
	char s;
	int err;
	int i;
	md5ctx ctx;
	uint8_t md5pass[16];

	if (mfsopts.passwordask && mfsopts.password==NULL && mfsopts.md5pass==NULL) {
		mfsopts.password = getpass("MFS Password:"******"bad md5 definition (md5 should be given as 32 hex digits)\n");
				return 1;
			}
			p++;
			if (*p>='0' && *p<='9') {
				md5pass[i]+=(*p-'0');
			} else if (*p>='a' && *p<='f') {
				md5pass[i]+=(*p-'a'+10);
			} else if (*p>='A' && *p<='F') {
				md5pass[i]+=(*p-'A'+10);
			} else {
				fprintf(stderr,"bad md5 definition (md5 should be given as 32 hex digits)\n");
				return 1;
			}
			p++;
		}
		if (*p) {
			fprintf(stderr,"bad md5 definition (md5 should be given as 32 hex digits)\n");
			return 1;
		}
		memset(mfsopts.md5pass,0,strlen(mfsopts.md5pass));
	}

	if (mfsopts.delayedinit) {
		fs_init_master_connection(mfsopts.bindhost,mfsopts.masterhost,mfsopts.masterport,mfsopts.meta,mp,mfsopts.subfolder,(mfsopts.password||mfsopts.md5pass)?md5pass:NULL,mfsopts.donotrememberpassword,1);
	} else {
		if (fs_init_master_connection(mfsopts.bindhost,mfsopts.masterhost,mfsopts.masterport,mfsopts.meta,mp,mfsopts.subfolder,(mfsopts.password||mfsopts.md5pass)?md5pass:NULL,mfsopts.donotrememberpassword,0)<0) {
			return 1;
		}
	}
	memset(md5pass,0,16);

	if (fg==0) {
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY , LOG_DAEMON);
	} else {
#if defined(LOG_PERROR)
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_USER);
#else
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY, LOG_USER);
#endif
	}

	i = mfsopts.nofile;
	while (1) {
		rls.rlim_cur = i;
		rls.rlim_max = i;
		if (setrlimit(RLIMIT_NOFILE,&rls)<0) {
			i /= 2;
			if (i<1000) {
				break;
			}
		} else {
			break;
		}
	}
	if (i != (int)(mfsopts.nofile)) {
		fprintf(stderr,"can't set open file limit to %d\n",mfsopts.nofile);
		if (i>=1000) {
			fprintf(stderr,"open file limit set to: %d\n",i);
		}
	}

	setpriority(PRIO_PROCESS,getpid(),mfsopts.nice);
#ifdef MFS_USE_MEMLOCK
	if (mfsopts.memlock) {
		rls.rlim_cur = RLIM_INFINITY;
		rls.rlim_max = RLIM_INFINITY;
		if (setrlimit(RLIMIT_MEMLOCK,&rls)<0) {
			mfsopts.memlock=0;
		}
	}
#endif

	piped[0] = piped[1] = -1;
	if (fg==0) {
		if (pipe(piped)<0) {
			fprintf(stderr,"pipe error\n");
			return 1;
		}
		err = fork();
		if (err<0) {
			fprintf(stderr,"fork error\n");
			return 1;
		} else if (err>0) {
			close(piped[1]);
			err = read(piped[0],&s,1);
			if (err==0) {
				s=1;
			}
			return s;
		}
		close(piped[0]);
		s=1;
	}


#ifdef MFS_USE_MEMLOCK
	if (mfsopts.memlock) {
		if (mlockall(MCL_CURRENT|MCL_FUTURE)==0) {
			syslog(LOG_NOTICE,"process memory was successfully locked in RAM");
		}
	}
#endif

/* glibc malloc tuning */
#ifdef MFS_USE_MALLOPT
	if (mfsopts.limitarenas) {
		if (!getenv("MALLOC_ARENA_MAX")) {
			syslog(LOG_NOTICE,"setting glibc malloc arena max to 8");
			mallopt(M_ARENA_MAX, mfsopts.limitarenas);
		}
		if (!getenv("MALLOC_ARENA_TEST")) {
			syslog(LOG_NOTICE,"setting glibc malloc arena test to 1");
			mallopt(M_ARENA_TEST, 1);
		}
	} else {
		syslog(LOG_NOTICE,"setting glibc malloc arenas turned off");
	}
#endif /* glibc malloc tuning */

	syslog(LOG_NOTICE,"monotonic clock function: %s",monotonic_method());
	syslog(LOG_NOTICE,"monotonic clock speed: %"PRIu32" ops / 10 mili seconds",monotonic_speed());

	conncache_init(200);
	chunkloc_cache_init();
	symlink_cache_init();
	negentry_cache_init(mfsopts.negentrycacheto);
//	dir_cache_init();
	fs_init_threads(mfsopts.ioretries);
	if (masterproxy_init(mfsopts.proxyhost)<0) {
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

//	fs_term();
//	negentry_cache_term();
//	symlink_cache_term();
//	chunkloc_cache_term();
//	return 1;

	if (mfsopts.meta==0) {
		csdb_init();
		delay_init();
		read_data_init(mfsopts.readaheadsize*1024*1024,mfsopts.readaheadleng,mfsopts.readaheadtrigger,mfsopts.ioretries);
		write_data_init(mfsopts.writecachesize*1024*1024,mfsopts.ioretries);
	}

 	ch = fuse_mount(mp, args);
	if (ch==NULL) {
		fprintf(stderr,"error in fuse_mount\n");
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

	if (mfsopts.meta) {
		mfs_meta_init(mfsopts.debug,mfsopts.entrycacheto,mfsopts.attrcacheto);
		se = fuse_lowlevel_new(args, &mfs_meta_oper, sizeof(mfs_meta_oper), (void*)piped);
	} else {
		mfs_init(mfsopts.debug,mfsopts.keepcache,mfsopts.direntrycacheto,mfsopts.entrycacheto,mfsopts.attrcacheto,mfsopts.xattrcacheto,mfsopts.groupscacheto,mfsopts.mkdircopysgid,mfsopts.sugidclearmode,1,mfsopts.fsyncbeforeclose,mfsopts.noxattrs,mfsopts.noposixlocks,mfsopts.nobsdlocks); //mfsopts.xattraclsupport);
		se = fuse_lowlevel_new(args, &mfs_oper, sizeof(mfs_oper), (void*)piped);
	}
	if (se==NULL) {
		fuse_unmount(mp,ch);
		fprintf(stderr,"error in fuse_lowlevel_new\n");
		portable_usleep(100000);	// time for print other error messages by FUSE
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

//	fprintf(stderr,"check\n");
	fuse_session_add_chan(se, ch);

	if (fuse_set_signal_handlers(se)<0) {
		fprintf(stderr,"error in fuse_set_signal_handlers\n");
		fuse_session_remove_chan(ch);
		fuse_session_destroy(se);
		fuse_unmount(mp,ch);
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

	if (mfsopts.debug==0 && fg==0) {
		setsid();
		setpgid(0,getpid());
		if ((i = open("/dev/null", O_RDWR, 0)) != -1) {
			(void)dup2(i, STDIN_FILENO);
			(void)dup2(i, STDOUT_FILENO);
			(void)dup2(i, STDERR_FILENO);
			if (i>2) close (i);
		}
	}

	if (mt) {
		err = fuse_session_loop_mt(se);
	} else {
		err = fuse_session_loop(se);
	}
	if (err) {
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				syslog(LOG_ERR,"pipe write error: %s",strerr(errno));
			}
			close(piped[1]);
		}
	}
	fuse_remove_signal_handlers(se);
	fuse_session_remove_chan(ch);
	fuse_session_destroy(se);
	fuse_unmount(mp,ch);
	if (mfsopts.meta==0) {
		write_data_term();
		read_data_term();
		delay_term();
		csdb_term();
	}
	masterproxy_term();
	fs_term();
//	dir_cache_term();
	negentry_cache_term();
	symlink_cache_term();
	chunkloc_cache_term();
	return err ? 1 : 0;
}
Example #8
0
int main(int argc, char **argv)
{
    extern void init_ops(fuse_lowlevel_ops *ops);
    struct options options;

    std::memset(&options, 0, sizeof(options));

    struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
    struct fuse_chan *ch;
    char *mountpoint = NULL;
    int err = -1;
    std::string mountPath;
    unsigned format = 0;

    int foreground = false;
    int multithread = false;
    
    
    Pascal::VolumeEntryPointer volume;
    
	
    init_ops(&pascal_ops);


    // scan the argument list, looking for the name of the disk image.
    if (fuse_opt_parse(&args, &options ,pascal_options, pascal_option_proc) == -1)
        exit(1);
    
    if (fDiskImage.empty())
    {
        usage();
        exit(1);
    }

    // default prodos-order disk image.
    if (options.format)
    {
        format = Device::BlockDevice::ImageType(options.format);
        if (!format)
            std::fprintf(stderr, "Warning: Unknown image type ``%s''\n", options.format);
    }

        
    try
    {        
        Device::BlockDevicePointer device;
        
        device = Device::BlockDevice::Open(fDiskImage.c_str(), File::ReadOnly, format);
        
       
        if (!device.get())
        {
            std::fprintf(stderr, "Error: Unknown or unsupported device type.\n");
            exit(1);
        }
        
        volume = Pascal::VolumeEntry::Open(device);
    }
    catch (::Exception &e)
    {
        std::fprintf(stderr, "%s\n", e.what());
        std::fprintf(stderr, "%s\n", std::strerror(e.error()));
        return -1;
    }    

    
    
    
    #ifdef __APPLE__
    {
        // Macfuse supports custom volume names (displayed in Finder)
        std::string str("-ovolname=");
        str += volume->name();
        fuse_opt_add_arg(&args, str.c_str());
    
        // 512 byte blocksize.    
        fuse_opt_add_arg(&args, "-oiosize=512");
        
    }
    #endif  

    fuse_opt_add_arg(&args, "-ofsname=PascalFS");

    if (!options.readOnly)
        fuse_opt_add_arg(&args, "-ordonly");
        
    if (options.readWrite)
    {
        std::fprintf(stderr, "Warning:  write support is not yet enabled.\n");
    }

    if (fuse_parse_cmdline(&args, &mountpoint, &multithread, &foreground) == -1)
    {
        usage();
        return -1;
    }
    
#ifdef __APPLE__
      
        if (mountpoint == NULL || *mountpoint == 0)
        {
            if (make_mount_dir(volume->name(), mountPath))
                mountpoint = (char *)mountPath.c_str();
        }
        
#endif    
    
    
    if ((ch = fuse_mount(mountpoint, &args)) != NULL)
    {
        struct fuse_session* se;

        std::printf("Mounting ``%s'' on ``%s''\n", volume->name(), mountpoint);
        
        se = fuse_lowlevel_new(&args, &pascal_ops, sizeof(pascal_ops), volume.get());

        if (se) do {

            
            err = fuse_daemonize(foreground);
            if (err < 0 ) break;
            
            err = fuse_set_signal_handlers(se);
            if (err < 0) break;
            
            fuse_session_add_chan(se, ch);
        
            if (multithread) err = fuse_session_loop_mt(se);
            else err = fuse_session_loop(se);
        
            fuse_remove_signal_handlers(se);
            fuse_session_remove_chan(ch);
        
        } while (false);
        if (se) fuse_session_destroy(se);
        fuse_unmount(mountpoint, ch);
    }



    fuse_opt_free_args(&args);


#ifdef __APPLE__
    if (!mountPath.empty()) rmdir(mountPath.c_str());
#endif


    return err ? 1 : 0;
}
Example #9
0
/**
*  Init of the pseudo fuse thread 

  @param ch : initial channel
  @param se : initial session
  @param rozofs_fuse_buffer_count : number of request buffers (corresponds to the number of fuse save context)  
  
  @retval 0 on success
  @retval -1 on error
*/
int rozofs_fuse_init(struct fuse_chan *ch,struct fuse_session *se,int rozofs_fuse_buffer_count)
{
  int status = 0;
  int i;
  
//   return 0;

  fuse_sharemem_init_done = 0;   
  
  int fileflags;
  rozofs_fuse_ctx_p = malloc(sizeof (rozofs_fuse_ctx_t));
  if (rozofs_fuse_ctx_p == NULL) 
  {
    /*
    ** cannot allocate memory for fuse rozofs context
    */
    return -1;
  }
  memset(rozofs_fuse_ctx_p,0,sizeof (rozofs_fuse_ctx_t));
  /*
  ** clear read/write merge stats table
  */
  memset(rozofs_write_merge_stats_tab,0,sizeof(uint64_t)*RZ_FUSE_WRITE_MAX);
  memset (rozofs_write_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX);
  memset (rozofs_read_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX);
  memset(&rozofs_fuse_read_write_stats_buf,0,sizeof(rozofs_fuse_read_write_stats));
  /*
  ** init of the context
  */
  rozofs_fuse_ctx_p->fuseReqPoolRef = NULL;
  rozofs_fuse_ctx_p->ch             = NULL;
  rozofs_fuse_ctx_p->se             = se;
  rozofs_fuse_ctx_p->bufsize        = 0; 
  rozofs_fuse_ctx_p->buf_fuse_req_p = NULL;
  rozofs_fuse_ctx_p->dir_attr_invalidate = 0;
  rozofs_fuse_ctx_p->initBufCount   = rozofs_fuse_buffer_count;
  
  while (1)
  {
     /*
     ** get the receive buffer size for former channel in order to create the request distributor:
     ** note: by default the fuse buffer is 4K+128K: for RozoFS the payload can reach 512K (x4)
     */
     int bufsize = fuse_chan_bufsize(ch)*4;
     rozofs_fuse_ctx_p->bufsize = bufsize;
     /*
     ** create the distributor fro receiving data from fuse kernel
     */
     status = rozofs_fuse_init_rcv_buffer_pool(ROZOFS_FUSE_RECV_BUF_COUNT,bufsize);
     if (status < 0)
     {
        severe( "rozofs_fuse_init fuse buffer pool creation error(%d,%d)", (int)ROZOFS_FUSE_RECV_BUF_COUNT, (int)bufsize ) ;
        status = -1;
        break;     
     
     }
     /*
     ** create the pool
     */
     rozofs_fuse_ctx_p->fuseReqPoolRef = ruc_buf_poolCreate(rozofs_fuse_buffer_count,sizeof(rozofs_fuse_save_ctx_t));
     if (rozofs_fuse_ctx_p->fuseReqPoolRef == NULL)
     {
        severe( "rozofs_fuse_init buffer pool creation error(%d,%d)", (int)rozofs_fuse_buffer_count, (int)sizeof(rozofs_fuse_save_ctx_t) ) ;
        status = -1;
        break;
     }
     ruc_buffer_debug_register_pool("fuseCtx",  rozofs_fuse_ctx_p->fuseReqPoolRef);
     /*
     ** Allocate a head of list for queueing pending lookup requests
     */
     for (i=0; i< ROZOFS_MAX_LKUP_QUEUE ; i++)
     {
       ruc_listHdrInit(&rozofs_lookup_queue[i]);
     }
     
     
     /*
     ** allocate a buffer for receiving the fuse request
     */
     rozofs_fuse_ctx_p->buf_fuse_req_p = malloc(bufsize);
     if (rozofs_fuse_ctx_p == NULL) 
     {     
        severe( "rozofs_fuse_init out of memory %d", bufsize ) ;
        status = -1;
        break;     
     }
     /*
     ** get the fd of the channel
     */
     rozofs_fuse_ctx_p->fd = fuse_chan_fd(ch);
     /*
     ** wait the end of the share memroy init prior providing it to fuse
     */
     while (rozofs_shared_mem_init_done == 0) sleep(1);  
     /*
     ** create a new channel with the specific operation for rozofs (non-blocking)
     */  
     rozofs_fuse_ctx_p->ch = fuse_chan_new(&rozofs_fuse_ch_ops,fuse_chan_fd(ch),bufsize,rozofs_fuse_ctx_p);  
     if (rozofs_fuse_ctx_p->ch == NULL)
     {
        severe( "rozofs_fuse_init fuse_chan_new error"  ) ;
        status = -1;
        break;          
     }
     /*
     ** remove the association between the initial session and channel
     */
     fuse_session_remove_chan(ch);  
     /*
     ** OK, now add the new channel
     */
     fuse_session_add_chan(se,rozofs_fuse_ctx_p->ch );  
     /*
     ** set the channel in non blocking mode
     */
     if((fileflags=fcntl(rozofs_fuse_ctx_p->fd,F_GETFL,0))==-1)
     {
       RUC_WARNING(errno);
       status = -1; 
       break;   
     }

     if((fcntl(rozofs_fuse_ctx_p->fd,F_SETFL,fileflags|O_NDELAY))==-1)
     {
       RUC_WARNING(errno);
       status = -1; 
       break;   
     }
     /*
     ** send XON to the fuse channel
     */
     {
        int ret;
	rozofs_fuse_ctx_p->ioctl_supported = 1;
	rozofs_fuse_ctx_p->data_xon        = 1;
     
        while(1)
	{	
	  ret = ioctl(rozofs_fuse_ctx_p->fd,1,NULL);
	  if (ret < 0) 
	  {
	     warning("ioctl error %s",strerror(errno));
	     rozofs_fuse_ctx_p->ioctl_supported = 0;
	     break;

	  }
          if (rozofs_fuse_ctx_p->dir_attr_invalidate == 0)
	  {
	    ret = ioctl(rozofs_fuse_ctx_p->fd,3,NULL);
	    if (ret < 0) 
	    {
	       warning("ioctl error %s",strerror(errno));
//	       rozofs_fuse_ctx_p->ioctl_supported = 0;
	       rozofs_fuse_ctx_p->dir_attr_invalidate = 1;
	       break;
	    }		
	  }
	  break;     
        }
     }
     /*
     ** perform the connection with the socket controller
     */
   /*
   ** OK, we are almost done, just need to connect with the socket controller
   */
   rozofs_fuse_ctx_p->connectionId = ruc_sockctl_connect(rozofs_fuse_ctx_p->fd,  // Reference of the socket
                                              "rozofs_fuse",                 // name of the socket
                                              3,                             // Priority within the socket controller
                                              (void*)rozofs_fuse_ctx_p,      // user param for socketcontroller callback
                                              &rozofs_fuse_callBack_sock);   // Default callbacks
    if (rozofs_fuse_ctx_p->connectionId == NULL)
    {
       /*
       ** Fail to connect with the socket controller
       */
       RUC_WARNING(-1);
       status = -1; 
       break;   
    } 
    rozofs_fuse_get_ticker();

     status = 0;
     break;
  }
  /*
  ** attach the callback on socket controller
  */
//#warning no poller
  ruc_sockCtrl_attach_applicative_poller(rozofs_fuse_scheduler_entry_point); 
  for(i = 0; i < 3;i++) fuse_profile[i] = 0;
  
  uma_dbg_addTopic("fuse", rozofs_fuse_show);
  return status;
  
}
Example #10
0
int main(int argc, char *argv[]) {
	struct fuse_args args;
	sqfs_opts opts;
	
	char *mountpoint = NULL;
	int mt, fg;
	
	int err;
	sqfs_ll *ll;
	
	struct fuse_lowlevel_ops sqfs_ll_ops;
	memset(&sqfs_ll_ops, 0, sizeof(sqfs_ll_ops));
	sqfs_ll_ops.getattr		= sqfs_ll_op_getattr;
	sqfs_ll_ops.opendir		= sqfs_ll_op_opendir;
	sqfs_ll_ops.releasedir	= sqfs_ll_op_releasedir;
	sqfs_ll_ops.readdir		= sqfs_ll_op_readdir;
	sqfs_ll_ops.lookup		= sqfs_ll_op_lookup;
	sqfs_ll_ops.open		= sqfs_ll_op_open;
	sqfs_ll_ops.release		= sqfs_ll_op_release;
	sqfs_ll_ops.read		= sqfs_ll_op_read;
	sqfs_ll_ops.readlink	= sqfs_ll_op_readlink;
	sqfs_ll_ops.listxattr	= sqfs_ll_op_listxattr;
	sqfs_ll_ops.getxattr	= sqfs_ll_op_getxattr;
	sqfs_ll_ops.forget		= sqfs_ll_op_forget;
   
	/* PARSE ARGS */
	args.argc = argc;
	args.argv = argv;
	args.allocated = 0;
	
	opts.progname = argv[0];
	opts.image = NULL;
	opts.mountpoint = 0;
	if (fuse_opt_parse(&args, &opts, NULL, sqfs_opt_proc) == -1)
		sqfs_usage(argv[0], true);

	if (fuse_parse_cmdline(&args, &mountpoint, &mt, &fg) == -1)
		sqfs_usage(argv[0], true);
	if (mountpoint == NULL)
		sqfs_usage(argv[0], true);
	
	/* OPEN FS */
	err = !(ll = sqfs_ll_open(opts.image));
	
	/* STARTUP FUSE */
	if (!err) {
		sqfs_ll_chan ch;
		err = -1;
		if (sqfs_ll_mount(&ch, mountpoint, &args) == SQFS_OK) {
			struct fuse_session *se = fuse_lowlevel_new(&args,
				&sqfs_ll_ops, sizeof(sqfs_ll_ops), ll);	
			if (se != NULL) {
				if (sqfs_ll_daemonize(fg) != -1) {
					if (fuse_set_signal_handlers(se) != -1) {
						fuse_session_add_chan(se, ch.ch);
						/* FIXME: multithreading */
						err = fuse_session_loop(se);
						fuse_remove_signal_handlers(se);
						#if HAVE_DECL_FUSE_SESSION_REMOVE_CHAN
							fuse_session_remove_chan(ch.ch);
						#endif
					}
				}
				fuse_session_destroy(se);
			}
			sqfs_ll_destroy(ll);
			sqfs_ll_unmount(&ch, mountpoint);
		}
	}
	fuse_opt_free_args(&args);
	free(ll);
	free(mountpoint);
	
	return -err;
}