aboutsummaryrefslogtreecommitdiff
blob: ec19b80d79b59f28f27b462d8fc2f807ea21921a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env python2

import subprocess
import time
import os
import sys


class logger:
  socketname=''
  readytolaunch=False
  mountlist=["/dev/","/proc/","/sys/"]
  rootmountpath="/mnt/logfs_root_"+str(time.time())+"/"
#  rootmountpath="/mnt/logfs_roott_"+"/"
  
  def __init__(self, socketname):
	self.socketname=socketname
	
	if os.geteuid() != 0:
	  print "only root user can use FUSE approach for logging"
	  exit(1)
	
	print "mounting root filesystem into %s. Please, DON'T DELETE THIS FOLDER!!" % self.rootmountpath
	
	#for mount in self.mountlist:
	try:
	  os.mkdir(self.rootmountpath)
	except OSError,e:
	  if e.errno==17: # 17 is a "file exists" errno
		pass			# all is ok
	  else:
		print "failed to make mount directory %s: %s" % (self.rootmountpath,e)
		print "this error is fatal"
		exit(1)
		  
	ret=subprocess.call(['mount','-o','bind','/',self.rootmountpath])
	if ret!=0:
	  print "failed to bind root filesystem to %s. Check messages above"%self.rootmountpath
	  exit(1)
	
	#env["LOG_SOCKET"]=self.socketname
	os.environ["LOG_SOCKET"]=self.socketname


	ret=subprocess.call(['/home/bay/gsoc/logger/src/hook_fusefs/hookfs',self.rootmountpath,
						 '-o','allow_other,suid'])
	if ret!=0:
	  print "failed to launch FUSE logger. Check messages above"
	
	for mount in self.mountlist:
	  ret=subprocess.call(['mount','-o','bind',mount,self.rootmountpath+mount])
	  if ret!=0:
		print "failed to mount bind %s directory to %s. Check messages above" % (
			   mount,self.rootmountpath)
		exit(1)
	self.readytolaunch=True;
	
  def __del__(self):
	#we will delete the object manually after execprog
	pass
  
  # launches command, if it returns not 0 waits for 1 second and launches again
  # for various umounts
  def smartcommandlauncher(self,args):
	for waittime in (1,1,2):
	  ret=subprocess.call(args)
	  if ret==0:
		return
	  print "Auto-retrying after %d sec" % waittime
	  time.sleep(waittime)
	print "Giving up. Command %s failed" % args
	
  
  def execprog(self,prog_name,arguments):
	pid=os.fork()
	if pid==0:
	  try:
		cwd=os.getcwd()
		os.chroot(self.rootmountpath)
		os.chdir(cwd)
		
		env=os.environ.copy()

		os.execvpe(prog_name, arguments, env)
		sys.exit(1)
	  except OSError, e:
		print "Error while chrooting and starting a program: %s" % e
		sys.exit(1)
	  
	else:
	  exitcode=os.wait()[1];
	  try:
		print "Unmounting partitions"
		self.mountlist.reverse()
		for mount in self.mountlist:
		  self.smartcommandlauncher(['umount','-l',self.rootmountpath+mount])
		self.smartcommandlauncher(['fusermount','-z','-u',self.rootmountpath]);
		self.smartcommandlauncher(['umount','-l',self.rootmountpath]);
		os.rmdir(self.rootmountpath)

	  except OSError, e:
		print "Error while unmounting fuse filesystem: %s" % e
		sys.exit(1)
		
	  sys.exit(int(exitcode/256))