3333import errno
3434from functools import wraps
3535import grp
36- import logging
37- import logging .handlers
3836import os
3937import pwd
4038import re
4139import stat
4240import sys
43- import time
44-
45- try :
46- from time import time_ns
47- except ImportError :
48- from time import time as _time
49- time_ns = lambda : int (_time () * 1e9 )
5041
5142from fuse import (
5243 FUSE ,
6152except ImportError :
6253 fuse_features = {}
6354
64-
65- # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
66- # LOGGING: Support nano-second timestamps
67- # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
68-
69- class _LogRecord_ns_ (logging .LogRecord ):
70- def __init__ (self , * args , ** kwargs ):
71- self .created_ns = time_ns () # Fetch precise timestamp
72- super ().__init__ (* args , ** kwargs )
73-
74- class _Formatter_ns_ (logging .Formatter ):
75- default_nsec_format = '%s,%09d'
76- def formatTime (self , record , datefmt = None ):
77- if datefmt is not None : # Do not handle custom formats here ...
78- return super ().formatTime (record , datefmt ) # ... leave to original implementation
79- ct = self .converter (record .created_ns / 1e9 )
80- t = time .strftime (self .default_time_format , ct )
81- s = self .default_nsec_format % (t , record .created_ns - (record .created_ns // 10 ** 9 ) * 10 ** 9 )
82- return s
83-
84- logging .setLogRecordFactory (_LogRecord_ns_ )
55+ from .log import get_logger
56+ from .timing import time
8557
8658
8759# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -98,15 +70,15 @@ def loggedfs_factory(directory, **kwargs):
9870 directory ,
9971 raw_fi = True ,
10072 nothreads = True ,
101- foreground = bool ( kwargs [ 'fuse_foreground_bool' ]) if 'fuse_foreground_bool' in kwargs . keys () else False ,
102- allow_other = bool ( kwargs [ 'fuse_allowother_bool' ]) if 'fuse_allowother_bool' in kwargs . keys () else False ,
103- default_permissions = bool ( kwargs [ 'fuse_allowother_bool' ]) if 'fuse_allowother_bool' in kwargs . keys () else False ,
73+ foreground = kwargs . get ( 'fuse_foreground_bool' , False ) ,
74+ allow_other = kwargs . get ( 'fuse_allowother_bool' , False ) ,
75+ default_permissions = kwargs . get ( 'fuse_allowother_bool' , False ) ,
10476 attr_timeout = 0 ,
10577 entry_timeout = 0 ,
10678 negative_timeout = 0 ,
107- # sync_read = True,
108- # max_readahead = 0,
109- # direct_io = True,
79+ sync_read = False , # relying on fuse.Operations class defaults?
80+ # max_readahead = 0, # relying on fuse.Operations class defaults?
81+ # direct_io = True, # relying on fuse.Operations class defaults?
11082 nonempty = True , # common options taken from LoggedFS
11183 use_ino = True # common options taken from LoggedFS
11284 )
@@ -350,7 +322,8 @@ def __init__(self,
350322 if log_excludes is None :
351323 log_excludes = []
352324
353- self ._init_logger (log_enabled , log_file , log_syslog , log_printprocessname )
325+ self ._log_printprocessname = bool (log_printprocessname )
326+ self .logger = get_logger ('LoggedFS-python' , log_enabled , log_file , log_syslog )
354327
355328 if bool (fuse_foreground_bool ):
356329 self .logger .info ('LoggedFS-python not running as a daemon' )
@@ -383,40 +356,6 @@ def __init__(self,
383356 self ._compile_filter (log_includes , log_excludes )
384357
385358
386- def _init_logger (self , log_enabled , log_file , log_syslog , log_printprocessname ):
387-
388- log_formater = _Formatter_ns_ ('%(asctime)s (%(name)s) %(message)s' )
389- log_formater_short = _Formatter_ns_ ('%(message)s' )
390-
391- self ._log_printprocessname = bool (log_printprocessname )
392-
393- self .logger = logging .getLogger ('LoggedFS-python' )
394-
395- if not bool (log_enabled ):
396- self .logger .setLevel (logging .CRITICAL )
397- return
398- self .logger .setLevel (logging .DEBUG )
399-
400- ch = logging .StreamHandler ()
401- ch .setLevel (logging .DEBUG )
402- ch .setFormatter (log_formater )
403- self .logger .addHandler (ch )
404-
405- if bool (log_syslog ):
406- sl = logging .handlers .SysLogHandler (address = '/dev/log' ) # TODO Linux only
407- sl .setLevel (logging .DEBUG )
408- sl .setFormatter (log_formater_short )
409- self .logger .addHandler (sl )
410-
411- if log_file is None :
412- return
413-
414- fh = logging .FileHandler (os .path .join (log_file )) # TODO
415- fh .setLevel (logging .DEBUG )
416- fh .setFormatter (log_formater )
417- self .logger .addHandler (fh )
418-
419-
420359 def _compile_filter (self , include_list , exclude_list ):
421360
422361 def proc_filter_item (in_item ):
@@ -466,7 +405,32 @@ def _rel_path(partial_path):
466405
467406
468407# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
469- # CORE CLASS: Filesystem & file methods
408+ # CORE CLASS: Filesystem & file methods - STUBS
409+ # ... addressing https://github.com/fusepy/fusepy/issues/81
410+ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
411+
412+ def create (self , path , mode , fi = None ):
413+
414+ raise FuseOSError (errno .ENOSYS )
415+
416+
417+ def flush (self , path , fip ):
418+
419+ raise FuseOSError (errno .ENOSYS )
420+
421+
422+ def ioctl (self , path , cmd , arg , fh , flags , data ):
423+
424+ raise FuseOSError (errno .ENOSYS )
425+
426+
427+ def lock (self , path , fh , cmd , lock ):
428+
429+ raise FuseOSError (errno .ENOSYS )
430+
431+
432+ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
433+ # CORE CLASS: Filesystem & file methods - IMPLEMENTATION
470434# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
471435
472436 @__log__ (format_pattern = '{0}' , abs_path_fields = [0 ])
@@ -488,12 +452,6 @@ def chown(self, path, uid, gid):
488452 os .chown (self ._rel_path (path ), uid , gid , dir_fd = self .root_path_fd , follow_symlinks = False )
489453
490454
491- # Ugly HACK, addressing https://github.com/fusepy/fusepy/issues/81
492- def create (self , path , mode , fi = None ):
493-
494- raise FuseOSError (errno .ENOSYS )
495-
496-
497455 @__log__ (format_pattern = '{0}' )
498456 def destroy (self , path ):
499457
@@ -522,20 +480,10 @@ def getattr(self, path, fip):
522480 return ret_dict
523481
524482
525- # @__log__(format_pattern = '{0} (fh={1})')
526- # Ugly HACK, addressing https://github.com/fusepy/fusepy/issues/81 ????????
527- def flush (self , path , fip ):
528-
529- # os.fsync(fip.fh)
530- raise FuseOSError (errno .ENOSYS )
531-
532-
533- # Ugly HACK, addressing https://github.com/fusepy/fusepy/issues/81 ????????
534483 @__log__ (format_pattern = '{0} (fh={2})' , abs_path_fields = [0 ], fip_fields = [2 ])
535484 def fsync (self , path , datasync , fip ):
536485
537- # raise FuseOSError(errno.ENOSYS)
538- return 0
486+ return 0 # the original loggedfs does that
539487
540488
541489 @__log__ (format_pattern = '{0}' )
@@ -544,12 +492,6 @@ def init(self, path):
544492 os .fchdir (self .root_path_fd )
545493
546494
547- # Ugly HACK, addressing https://github.com/fusepy/fusepy/issues/81 ????????
548- def ioctl (self , path , cmd , arg , fh , flags , data ):
549-
550- raise FuseOSError (errno .ENOSYS )
551-
552-
553495 @__log__ (format_pattern = '{1} to {0}' , abs_path_fields = [0 , 1 ])
554496 def link (self , target_path , source_path ):
555497
@@ -564,12 +506,6 @@ def link(self, target_path, source_path):
564506 os .lchown (target_rel_path , uid , gid )
565507
566508
567- # Ugly HACK, addressing https://github.com/fusepy/fusepy/issues/81
568- def lock (self , path , fh , cmd , lock ):
569-
570- raise FuseOSError (errno .ENOSYS )
571-
572-
573509 @__log__ (format_pattern = '{0} {1}' , abs_path_fields = [0 ])
574510 def mkdir (self , path , mode ):
575511
@@ -609,14 +545,12 @@ def open(self, path, fip):
609545
610546 fip .fh = os .open (self ._rel_path (path ), fip .flags , dir_fd = self .root_path_fd )
611547
612- return 0 # Must return handle or zero # TODO ?
548+ return 0
613549
614550
615551 @__log__ (format_pattern = '{1} bytes from {0} at offset {2} (fh={3})' , abs_path_fields = [0 ], fip_fields = [3 ])
616552 def read (self , path , length , offset , fip ):
617553
618- # ret is a bytestring!
619-
620554 ret = os .pread (fip .fh , length , offset )
621555
622556 return ret
@@ -647,11 +581,9 @@ def readlink(self, path):
647581 return pathname
648582
649583
650- # Ugly HACK, addressing https://github.com/fusepy/fusepy/issues/81
651584 @__log__ (format_pattern = '{0} (fh={1})' , abs_path_fields = [0 ], fip_fields = [1 ])
652585 def release (self , path , fip ):
653586
654- # raise FuseOSError(errno.ENOSYS)
655587 os .close (fip .fh )
656588
657589
@@ -696,7 +628,10 @@ def truncate(self, path, length, fip = None):
696628
697629 if fip is None :
698630
699- os .truncate (self ._rel_path (path ), length )
631+ fd = os .open (self ._rel_path (path ), flags = os .O_WRONLY , dir_fd = self .root_path_fd )
632+ ret = os .ftruncate (fd , length )
633+ os .close (fd )
634+ return ret
700635
701636 else :
702637
@@ -720,7 +655,7 @@ def _fix_time_(atime, mtime):
720655 if mtime in [UTIME_OMIT , None ]:
721656 mtime = st .st_mtime_ns
722657 if UTIME_NOW in (atime , mtime ):
723- now = time_ns ()
658+ now = time . time_ns ()
724659 if atime == UTIME_NOW :
725660 atime = now
726661 if mtime == UTIME_NOW :
@@ -738,8 +673,6 @@ def _fix_time_(atime, mtime):
738673 @__log__ (format_pattern = '{1} bytes to {0} at offset {2} (fh={3})' , abs_path_fields = [0 ], length_fields = [1 ], fip_fields = [3 ])
739674 def write (self , path , buf , offset , fip ):
740675
741- # buf is a bytestring!
742-
743676 res = os .pwrite (fip .fh , buf , offset )
744677
745678 return res
0 commit comments