Browse Source

HV: * Initial vbs_fs rewrite (now with correct author creds)

git-svn-id: svn+ssh://code.jive.eu/code/svn/vbs_fs@1 5b2df0cb-e17b-44c8-90c8-480d528b6e0d
master
JIVE Software Dev 7 years ago
commit
c4ba015829
4 changed files with 391 additions and 0 deletions
  1. +15
    -0
      Makefile
  2. +63
    -0
      evlbidebug.cc
  3. +77
    -0
      evlbidebug.h
  4. +236
    -0
      vbs_fs.cc

+ 15
- 0
Makefile View File

@@ -0,0 +1,15 @@
CXX=g++
INCS=-I.
CXXOPT=-g -fPIC $(OPT) -Wall -W -Werror -Wextra -pedantic -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D__STDC_FORMAT_MACROS -Wcast-qual -Wwrite-strings -Wredundant-decls -Wfloat-equal -Wshadow -D_FILE_OFFSET_BITS=64

OBJS=evlbidebug.o


vbs_fs: vbs_fs.cc $(OBJS)
$(CXX) $(INCS) $(CXXOPT) -o vbs_fs vbs_fs.cc $(OBJS) -lpthread -lfuse

%.o: %.cc
$(CXX) $(INCS) -c $(CXXOPT) -o $@ $<

clean:
-rm -f $(OBJS) vbs_fs

+ 63
- 0
evlbidebug.cc View File

@@ -0,0 +1,63 @@
// implementation
// Copyright (C) 2007-2008 Harro Verkouter
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
// PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// Author: Harro Verkouter - verkouter@jive.nl
// Joint Institute for VLBI in Europe
// P.O. Box 2
// 7990 AA Dwingeloo
#include <iostream>

// Yah we rly need to lock during outputting stuff
// to the screen ...
#include <pthread.h>

// for ::strerror()
#include <string.h>

static int dbglev_val = 1;
// if msglevel>fnthres_val level => functionnames are printed in DEBUG()
static int fnthres_val = 5;
static pthread_mutex_t evlbidebug_cerr_lock = PTHREAD_MUTEX_INITIALIZER;

int dbglev_fn( void ) {
return dbglev_val;
}

int dbglev_fn( int n ) {
int rv = dbglev_val;
dbglev_val = n;
return rv;
}

int fnthres_fn( void ) {
return fnthres_val;
}

int fnthres_fn( int n ) {
int rv = fnthres_val;
fnthres_val = n;
return rv;
}

void do_cerr_lock( void ) {
int rv;
if( (rv=::pthread_mutex_lock(&evlbidebug_cerr_lock))!=0 )
std::cerr << "do_cerr_lock() failed - " << ::strerror(rv) << std::endl;
}
void do_cerr_unlock( void ) {
int rv;
if( (rv=::pthread_mutex_unlock(&evlbidebug_cerr_lock))!=0 )
std::cerr << "do_cerr_unlock() failed - " << ::strerror(rv) << std::endl;
}

+ 77
- 0
evlbidebug.h View File

@@ -0,0 +1,77 @@
// macros for debugging
// Copyright (C) 2007-2008 Harro Verkouter
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
// PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// Author: Harro Verkouter - verkouter@jive.nl
// Joint Institute for VLBI in Europe
// P.O. Box 2
// 7990 AA Dwingeloo
#ifndef EVLBI5A_EVLBIDEBUG_H
#define EVLBI5A_EVLBIDEBUG_H

#include <iostream>
#include <sstream>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>

#ifdef __GNUC__
#define EVDBG_FUNC "[" << __PRETTY_FUNCTION__ << "] "
#else
#define EVDBG_FUNC ""
#endif



int dbglev_fn( void ); // get current debuglevel
int dbglev_fn( int n ); // set current level to 'n', returns previous level

// functionname printing threshold:
// if dbglev()>fnthres() then the functionnames
// where the DEBUG() was issued from will be printed as well
// [that is: if the __PRETTY_FUNCTION__ is available otherwise
// it has no effect]
int fnthres_fn( void ); // get current threshold value
int fnthres_fn( int n ); // set current threshold value, returns previous level

void do_cerr_lock( void );
void do_cerr_unlock( void );

// Prepare the debugstring in a local variable.
// We do that so the amount of time spent holding the lock
// is minimal.
// this printed the actual level of the message. taken that out
// OsS_ZyP << a << " ";
#define DEBUG(a, b) \
do {\
if( a<=dbglev_fn() ) {\
std::ostringstream OsS_ZyP;\
char t1m3_buff3r[32];\
struct timeval raw_t1m3; \
::gettimeofday(&raw_t1m3, NULL); \
::strftime( t1m3_buff3r, sizeof(t1m3_buff3r), "%Y-%m-%d %H:%M:%S", gmtime(&raw_t1m3.tv_sec) ); \
::sprintf( t1m3_buff3r + 19, ".%02ld: ", (long int)(raw_t1m3.tv_usec / 10000) ); \
OsS_ZyP << t1m3_buff3r;\
if( dbglev_fn()>fnthres_fn() ) \
OsS_ZyP << EVDBG_FUNC; \
OsS_ZyP << b;\
do_cerr_lock();\
std::cerr << OsS_ZyP.str();\
do_cerr_unlock();\
}\
} while( 0 );



#endif

+ 236
- 0
vbs_fs.cc View File

@@ -0,0 +1,236 @@
// FUSE file system for vlbi_streamer style recordings
#define FUSE_USE_VERSION 26
#include <fuse.h>

#include <evlbidebug.h>

#include <iostream>
#include <cstddef>



using namespace std;

///////////////////////////////////////////////
// Keep state of the FUSE file system in
// a struct of this type. It's a global
// variable.
///////////////////////////////////////////////
const string defaultRootDir = "/mnt";

struct vbs_state_type {
string rootDir;

vbs_state_type() {}
};

vbs_state_type* vbs_state = 0;


///////////////////////////////////////////////
// Here follow the implementations
// of the file system functions
// that we support
///////////////////////////////////////////////
void* vbs_init(struct fuse_conn_info* /*conn*/) {
DEBUG(-1, "vbs_init" << endl);
return (void*)vbs_state;
}

void vbs_destroy(void* ptr) {
DEBUG(-1, "vbs_destroy" << endl);
if( ptr==(void*)vbs_state )
DEBUG(-1, "Yes, it was our global pointer" << endl);
delete (vbs_state_type*)ptr;
vbs_state = 0;
}


///////////////////////////////////////////////
// A filesystem must define a set
// of operations with callback functions
// on the file system objects it
// represents. All callbacks are
// registered in the fuse_operations struct
///////////////////////////////////////////////
struct vbs_fuse_operations :
public fuse_operations {

vbs_fuse_operations() {
init = &vbs_init;
destroy = &vbs_destroy;
}
};

vbs_fuse_operations vbs_oper;
#if 0
struct fuse_operations vbs_oper = {
//.getattr = vbs_getattr,
//.readdir = vbs_readdir,
//.open = vbs_open,
//.read = vbs_read,
//.readlink = vbs_readlink,
// no .getdir -- that's deprecated
//.getdir = NULL,
//.mknod = vbs_mknod,
//.mkdir = vbs_mkdir,
//.unlink = vbs_unlink,
//.rmdir = vbs_rmdir,
//.symlink = vbs_symlink,
//.rename = vbs_rename,
//.link = vbs_link,
//.chmod = vbs_chmod,
//.chown = vbs_chown,
//.truncate = vbs_truncate,
//.utime = vbs_utime,
//.write = vbs_write,
/** Just a placeholder, don't set */ // huh???
//.statfs = vbs_statfs,
//.flush = vbs_flush,
//.release = vbs_release,
//.fsync = vbs_fsync,
//.setxattr = vbs_setxattr,
//.getxattr = vbs_getxattr,
//.listxattr = vbs_listxattr,
//.removexattr = vbs_removexattr,
//.opendir = vbs_opendir,
//.releasedir = vbs_releasedir,
//.fsyncdir = vbs_fsyncdir,
.init = vbs_init,
.destroy = vbs_destroy,
//.access = vbs_access,
//.create = vbs_create,
//.ftruncate = vbs_ftruncate,
};
#endif


///////////////////////////////////////////////
// Command line handling
// There's only a few options
// that we support
// -m <int> setting debug level
// -r <path> set root dir for disks
// -f FUSE 'foreground' flag
///////////////////////////////////////////////
struct vbs_settings {
int debug_level;
bool help;
bool foreground;
char const* root_dir;

// Initialize with defaults
vbs_settings():
debug_level( 0 ), help( false ), foreground( false ), root_dir( 0 )
{}
};

ostream& operator<<(ostream& os, const vbs_settings& vbo) {
os << "-m " << vbo.debug_level << " ";
if( vbo.root_dir )
os << "-r " << vbo.root_dir << " ";
if( vbo.help )
os << "-h" << " ";
if( vbo.foreground )
os << "-f" << " ";
return os;
}

#define KEY_FOREGROUND 42
#define KEY_HELP 666
#define VBSFS_OPT(t, p, v) { t, offsetof(struct vbs_settings, p), v }
struct fuse_opt vbs_options[] = {
VBSFS_OPT("-m %i", debug_level, 0),
VBSFS_OPT("-r %s", root_dir, 0),
// The FUSE_OPT_KEY() ones are handled
// by vbs_option_proc()
//FUSE_OPT_KEY("-f", KEY_FOREGROUND),
//FUSE_OPT_KEY("-h", KEY_HELP),
FUSE_OPT_END
};

int vbs_option_proc(void* data, const char* arg, int key, struct fuse_args* /*outargs*/) {
int rv = 1;
const string arg_s( arg );
vbs_settings* settingsptr = (vbs_settings*)data;

if( key==KEY_FOREGROUND ) {
rv = 0;
settingsptr->foreground = true;
} else if( key==KEY_HELP ) {
rv = 0;
settingsptr->help = true;
} else {
DEBUG(-1, "vbs_option_proc/Unrecognized arg=" << arg << " (key=" << key << ")" << endl);
}
if( arg_s=="-h" )
settingsptr->help = true;
return rv;
}

void Usage( void ) {
cout << "VBS specific command line arguments:" << endl
#if 0
<< " -h print this message" << endl
<< " -f run FUSE in the foreground, not as daemon" << endl
#endif
<< " -m <int> set VBS_FS debug print level to <n>" << endl
<< " higher <n> => more output, default 0 (no output)" << endl
<< " -r <path> path to vbs_fs 'root' directory; assume all disks" << endl
<< " are mounted under <path>/disk<n> with <n> being" << endl
<< " a non-negative integer" << endl;
return;
}



///////////////////////////////////////////////
//
// The main function
//
///////////////////////////////////////////////
int main(int argc, char** argv) {
// Before doing _anything_ check if we're not root/suid root
if( ::getuid()==0 || ::geteuid()==0 ) {
DEBUG(-1, "Running vbs_fuse as root opens unnacceptable security holes" << endl);
return -11;
}

// Now we can safely start parsing
int fuse_stat;
vbs_settings settings;
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);

vbs_state = new vbs_state_type();

// Do command line parsing
::fuse_opt_parse(&args, (void*)&settings, &vbs_options[0], vbs_option_proc);
DEBUG(1, "fuse_opt_arg done [" << settings << "]" << endl);

#if 0
// Append to FUSE 'command line'
if( settings.foreground && ::fuse_opt_add_arg(&args, "-f")!=0 ) {
DEBUG(-1, "fuse_opt_add_arg(.., \"-f\") fails?!" << endl);
return -12;
}
if( settings.help && ::fuse_opt_add_arg(&args, "-h")!=0 ) {
DEBUG(-1, "fuse_opt_add_arg(.., \"-h\") fails?!" << endl);
return -13;
}
#endif
if( settings.help )
Usage();
// If no root dir given, default to "/mnt"
if( settings.root_dir==0 )
DEBUG(-1, "WARN: No root dir specified for disks, defaulting to " << defaultRootDir << endl);
vbs_state->rootDir = (settings.root_dir==0?defaultRootDir:string(settings.root_dir));


// Now it's about time to drop into FUSE's main loop
DEBUG(3, "dropping into fuse_main" << endl);
fuse_stat = fuse_main(args.argc, args.argv, &vbs_oper, vbs_state);

DEBUG(3, "fuse_stat returned " << fuse_stat << endl);
return fuse_stat;
}

Loading…
Cancel
Save