2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Copyright 2017 The go-ethereum Authors  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This file is part of the go-ethereum library.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The go-ethereum library is free software: you can redistribute it and/or modify  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU Lesser General Public License as published by  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation, either version 3 of the License, or  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The go-ethereum library 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 Lesser General Public License for more details.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU Lesser General Public License  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// +build linux darwin freebsd  
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								package  fuse  
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2018-07-09 14:11:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"os" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"path/filepath" 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-30 11:21:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"bazil.org/fuse" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"bazil.org/fuse/fs" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/ethereum/go-ethereum/common" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/ethereum/go-ethereum/swarm/api" 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/ethereum/go-ethereum/swarm/log" 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									errEmptyMountPoint       =  errors . New ( "need non-empty mount point" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errNoRelativeMountPoint  =  errors . New ( "invalid path for mount point (need absolute path)" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errMaxMountCount         =  errors . New ( "max FUSE mount count reached" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errMountTimeout          =  errors . New ( "mount timeout" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errAlreadyMounted        =  errors . New ( "mount point is already serving" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  isFUSEUnsupportedError ( err  error )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  perr ,  ok  :=  err . ( * os . PathError ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  perr . Op  ==  "open"  &&  perr . Path  ==  "/dev/fuse" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err  ==  fuse . ErrOSXFUSENotFound 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// MountInfo contains information about every active mount  
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  MountInfo  struct  {  
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									MountPoint      string 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StartManifest   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LatestManifest  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rootDir         * SwarmDir 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									fuseConnection  * fuse . Conn 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									swarmApi        * api . API 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									lock            * sync . RWMutex 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									serveClose      chan  struct { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  NewMountInfo ( mhash ,  mpoint  string ,  sapi  * api . API )  * MountInfo  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log . Debug ( "swarmfs NewMountInfo" ,  "hash" ,  mhash ,  "mount point" ,  mpoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newMountInfo  :=  & MountInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										MountPoint :      mpoint , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										StartManifest :   mhash , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										LatestManifest :  mhash , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rootDir :         nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fuseConnection :  nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										swarmApi :        sapi , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lock :            & sync . RWMutex { } , 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										serveClose :      make ( chan  struct { } ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  newMountInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( swarmfs  * SwarmFS )  Mount ( mhash ,  mountpoint  string )  ( * MountInfo ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log . Info ( "swarmfs" ,  "mounting hash" ,  mhash ,  "mount point" ,  mountpoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  mountpoint  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errEmptyMountPoint 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! strings . HasPrefix ( mountpoint ,  "/" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errNoRelativeMountPoint 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cleanedMountPoint ,  err  :=  filepath . Abs ( filepath . Clean ( mountpoint ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									log . Trace ( "swarmfs mount" ,  "cleanedMountPoint" ,  cleanedMountPoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									swarmfs . swarmFsLock . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  swarmfs . swarmFsLock . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									noOfActiveMounts  :=  len ( swarmfs . activeMounts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log . Debug ( "swarmfs mount" ,  "# active mounts" ,  noOfActiveMounts ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  noOfActiveMounts  >=  maxFuseMounts  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errMaxMountCount 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  ok  :=  swarmfs . activeMounts [ cleanedMountPoint ] ;  ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errAlreadyMounted 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									log . Trace ( "swarmfs mount: getting manifest tree" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-09 14:11:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  manifestEntryMap ,  err  :=  swarmfs . swarmApi . BuildDirectoryTree ( context . TODO ( ) ,  mhash ,  true ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-06 23:22:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									log . Trace ( "swarmfs mount: building mount info" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mi  :=  NewMountInfo ( mhash ,  cleanedMountPoint ,  swarmfs . swarmApi ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dirTree  :=  map [ string ] * SwarmDir { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rootDir  :=  NewSwarmDir ( "/" ,  mi ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									log . Trace ( "swarmfs mount" ,  "rootDir" ,  rootDir ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mi . rootDir  =  rootDir 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									log . Trace ( "swarmfs mount: traversing manifest map" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  suffix ,  entry  :=  range  manifestEntryMap  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-18 09:56:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  suffix  ==  ""  {  //empty suffix means that the file has no name - i.e. this is the default entry in a manifest. Since we cannot have files without a name, let us ignore this entry 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Warn ( "Manifest has an empty-path (default) entry which will be ignored in FUSE mount." ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										addr  :=  common . Hex2Bytes ( entry . Hash ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										fullpath  :=  "/"  +  suffix 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										basepath  :=  filepath . Dir ( fullpath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										parentDir  :=  rootDir 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dirUntilNow  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										paths  :=  strings . Split ( basepath ,  "/" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  i  :=  range  paths  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  paths [ i ]  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												thisDir  :=  paths [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dirUntilNow  =  dirUntilNow  +  "/"  +  thisDir 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  ok  :=  dirTree [ dirUntilNow ] ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													dirTree [ dirUntilNow ]  =  NewSwarmDir ( dirUntilNow ,  mi ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													parentDir . directories  =  append ( parentDir . directories ,  dirTree [ dirUntilNow ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													parentDir  =  dirTree [ dirUntilNow ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													parentDir  =  dirTree [ dirUntilNow ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										thisFile  :=  NewSwarmFile ( basepath ,  filepath . Base ( fullpath ) ,  mi ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										thisFile . addr  =  addr 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										parentDir . files  =  append ( parentDir . files ,  thisFile ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fconn ,  err  :=  fuse . Mount ( cleanedMountPoint ,  fuse . FSName ( "swarmfs" ) ,  fuse . VolumeName ( mhash ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isFUSEUnsupportedError ( err )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Error ( "swarmfs error - FUSE not installed" ,  "mountpoint" ,  cleanedMountPoint ,  "err" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										fuse . Unmount ( cleanedMountPoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Error ( "swarmfs error mounting swarm manifest" ,  "mountpoint" ,  cleanedMountPoint ,  "err" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mi . fuseConnection  =  fconn 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									serverr  :=  make ( chan  error ,  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									go  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Info ( "swarmfs" ,  "serving hash" ,  mhash ,  "at" ,  cleanedMountPoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										filesys  :=  & SwarmRoot { root :  rootDir } 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//start serving the actual file system; see note below 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  :=  fs . Serve ( fconn ,  filesys ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											log . Warn ( "swarmfs could not serve the requested hash" ,  "error" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											serverr  <-  err 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										mi . serveClose  <-  struct { } { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/ * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   IMPORTANT  NOTE :  the  fs . Serve  function  is  blocking ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   Serve  builds  up  the  actual  fuse  file  system  by  calling  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   Attr  functions  on  each  SwarmFile ,  creating  the  file  inodes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   specifically  calling  the  swarm ' s  LazySectionReader . Size ( )  to  set  the  file  size . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   This  can  take  some  time ,  and  it  appears  that  if  we  access  the  fuse  file  system 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   too  early ,  we  can  bring  the  tests  to  deadlock .  The  assumption  so  far  is  that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   at  this  point ,  the  fuse  driver  didn ' t  finish  to  initialize  the  file  system . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   Accessing  files  too  early  not  only  deadlocks  the  tests ,  but  locks  the  access 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   of  the  fuse  file  completely ,  resulting  in  blocked  resources  at  OS  system  level . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   Even  a  simple  ` ls /tmp/testDir/testMountDir `  could  deadlock  in  a  shell . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   Workaround  so  far  is  to  wait  some  time  to  give  the  OS  enough  time  to  initialize 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   the  fuse  file  system .  During  tests ,  this  seemed  to  address  the  issue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   HOWEVER  IT  SHOULD  BE  NOTED  THAT  THIS  MAY  ONLY  BE  AN  EFFECT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   AND  THE  DEADLOCK  CAUSED  BY  SOMETHING  ELSE  BLOCKING  ACCESS  DUE  TO  SOME  RACE  CONDITION 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   ( caused  in  the  bazil . org  library  and / or  the  SwarmRoot ,  SwarmDir  and  SwarmFile  implementations ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									time . Sleep ( 2  *  time . Second ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									timer  :=  time . NewTimer ( mountTimeout ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  timer . Stop ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Check if the mount process has an error to report. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									select  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  <- timer . C : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Warn ( "swarmfs timed out mounting over FUSE" ,  "mountpoint" ,  cleanedMountPoint ,  "err" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  fuse . Unmount ( cleanedMountPoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errMountTimeout 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  err  :=  <- serverr : 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Warn ( "swarmfs error serving over FUSE" ,  "mountpoint" ,  cleanedMountPoint ,  "err" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  fuse . Unmount ( cleanedMountPoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  <- fconn . Ready : 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//this signals that the actual mount point from the fuse.Mount call is ready; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//it does not signal though that the file system from fs.Serve is actually fully built up 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  fconn . MountError ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Error ( "Mounting error from fuse driver: " ,  "err" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Info ( "swarmfs now served over FUSE" ,  "manifest" ,  mhash ,  "mountpoint" ,  cleanedMountPoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									timer . Stop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									swarmfs . activeMounts [ cleanedMountPoint ]  =  mi 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  mi ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( swarmfs  * SwarmFS )  Unmount ( mountpoint  string )  ( * MountInfo ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									swarmfs . swarmFsLock . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  swarmfs . swarmFsLock . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cleanedMountPoint ,  err  :=  filepath . Abs ( filepath . Clean ( mountpoint ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mountInfo  :=  swarmfs . activeMounts [ cleanedMountPoint ] 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  mountInfo  ==  nil  ||  mountInfo . MountPoint  !=  cleanedMountPoint  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "swarmfs %s is not mounted" ,  cleanedMountPoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  fuse . Unmount ( cleanedMountPoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-30 11:21:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err1  :=  externalUnmount ( cleanedMountPoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err1  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											errStr  :=  fmt . Sprintf ( "swarmfs unmount error: %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											log . Warn ( errStr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  mountInfo . fuseConnection . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									delete ( swarmfs . activeMounts ,  cleanedMountPoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									<- mountInfo . serveClose 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									succString  :=  fmt . Sprintf ( "swarmfs unmounting %v succeeded" ,  cleanedMountPoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 05:36:02 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									log . Info ( succString ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  mountInfo ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( swarmfs  * SwarmFS )  Listmounts ( )  [ ] * MountInfo  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									swarmfs . swarmFsLock . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  swarmfs . swarmFsLock . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rows  :=  make ( [ ] * MountInfo ,  0 ,  len ( swarmfs . activeMounts ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  mi  :=  range  swarmfs . activeMounts  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rows  =  append ( rows ,  mi ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 12:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  rows 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-20 14:06:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( swarmfs  * SwarmFS )  Stop ( )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  mp  :=  range  swarmfs . activeMounts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mountInfo  :=  swarmfs . activeMounts [ mp ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										swarmfs . Unmount ( mountInfo . MountPoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-23 19:26:06 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}