MythTV  master
fs_util.py
Go to the documentation of this file.
1 #
2 # fs_util.py - misc. routines not categorized in other modules
3 #
4 # Copyright 2008 Mike McGrath
5 # This file incorporates work covered by the following copyright
6 # Copyright 2006-2007 Red Hat, Inc.
7 #
8 # This copyrighted material is made available to anyone wishing to use, modify,
9 # copy, or redistribute it subject to the terms and conditions of the GNU
10 # General Public License v.2. This program is distributed in the hope that it
11 # will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
12 # implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 # See the GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License along with
16 # this program; if not, write to the Free Software Foundation, Inc., 51
17 # Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
18 # trademarks that are incorporated in the source code or documentation are not
19 # subject to the GNU General Public License and may only be used or replicated
20 # with the express permission of Red Hat, Inc.
21 #
22 
23 import os
24 
25 # We cache the contents of /etc/mtab ... the following variables are used
26 # to keep our cache in sync
27 mtab_mtime = None
28 mtab_map = []
29 
30 class MntEntObj(object):
31  mnt_fsname = None #* name of mounted file system */
32  mnt_dir = None #* file system path prefix */
33  mnt_type = None #* mount type (see mntent.h) */
34  mnt_opts = None #* mount options (see mntent.h) */
35  mnt_freq = 0 #* dump frequency in days */
36  mnt_passno = 0 #* pass number on parallel fsck */
37 
38  def __init__(self,input=None):
39  if input and isinstance(input, str):
40  (self.mnt_fsname, self.mnt_dir, self.mnt_type, self.mnt_opts, \
41  self.mnt_freq, self.mnt_passno) = input.split()
42  def __dict__(self):
43  return {"mnt_fsname": self.mnt_fsname, "mnt_dir": self.mnt_dir, \
44  "mnt_type": self.mnt_type, "mnt_opts": self.mnt_opts, \
45  "mnt_freq": self.mnt_freq, "mnt_passno": self.mnt_passno}
46  def __str__(self):
47  return "%s %s %s %s %s %s" % (self.mnt_fsname, self.mnt_dir, self.mnt_type, \
48  self.mnt_opts, self.mnt_freq, self.mnt_passno)
49 
50 class FileSystem(object):
51  def __init__(self, mntent):
52  self.mnt_dev = mntent.mnt_fsname
53  self.mnt_pnt = mntent.mnt_dir
54  self.fs_type = mntent.mnt_type
55  try:
56  stat_res = os.statvfs('%s' % self.mnt_pnt)
57  except OSError:
58  stat_res = self.f_bsize = self.f_frsize = self.f_blocks = self.f_blocks = self.f_bfree = self.f_bavail = self.f_files = self.f_ffree = self.f_favail = "UNKNOWN"
59  else:
60  self.f_bsize = stat_res.f_bsize
61  self.f_frsize = stat_res.f_frsize
62  self.f_blocks = stat_res.f_blocks
63  self.f_bfree = stat_res.f_bfree
64  self.f_bavail = stat_res.f_bavail
65  self.f_files = stat_res.f_files
66  self.f_ffree = stat_res.f_ffree
67  self.f_favail = stat_res.f_favail
68 
69  def to_dict(self):
70  return dict(mnt_pnt=self.mnt_pnt, fs_type=self.fs_type, f_favail=self.f_favail,
71  f_bsize=self.f_bsize, f_frsize=self.f_frsize, f_blocks=self.f_blocks,
72  f_bfree=self.f_bfree, f_bavail=self.f_bavail, f_files=self.f_files,
73  f_ffree=self.f_ffree)
74 
75  def __str__(self):
76  return "%s %s %s %s %s %s %s %s %s %s %s" % \
77  (self.mnt_dev, self.mnt_pnt, self.fs_type,
78  self.f_bsize, self.f_frsize, self.f_blocks,
79  self.f_bfree, self.f_bavail, self.f_files,
80  self.f_ffree, self.f_favail)
81 
82 
83 
84 def get_mtab(mtab="/proc/mounts", vfstype=None):
85  global mtab_mtime, mtab_map
86 
87  mtab_stat = os.stat(mtab)
88  if mtab_stat.st_mtime != mtab_mtime:
89  #print '''cache is stale ... refresh'''
90  mtab_mtime = mtab_stat.st_mtime
91  mtab_map = __cache_mtab__(mtab)
92 
93  # was a specific fstype requested?
94  if vfstype:
95  return [ent for ent in mtab_map if ent.mnt_type == vfstype]
96 
97  return mtab_map
98 
99 def get_fslist():
100  return [FileSystem(mnt) for mnt in get_mtab()]
101 
102 def __cache_mtab__(mtab="/proc/mounts"):
103  global mtab_mtime
104 
105  f = open(mtab)
106  #don't want empty lines
107  mtab = [MntEntObj(line) for line in f.read().split('\n') if len(line) > 0]
108  f.close()
109 
110  return mtab
111 
113  '''What this function attempts to do is take a file and return:
114  - the device the file is on
115  - the path of the file relative to the device.
116  For example:
117  /boot/vmlinuz -> (/dev/sda3, /vmlinuz)
118  /boot/efi/efi/redhat/elilo.conf -> (/dev/cciss0, /elilo.conf)
119  /etc/fstab -> (/dev/sda4, /etc/fstab)
120  '''
121 
122  # resolve any symlinks
123  fname = os.path.realpath(fname)
124 
125  # convert mtab to a dict
126  mtab_dict = {}
127  for ent in get_mtab():
128  mtab_dict[ent.mnt_dir] = ent.mnt_fsname
129 
130  # find a best match
131  fdir = os.path.dirname(fname)
132  match = mtab_dict.has_key(fdir)
133  while not match:
134  fdir = os.path.realpath(os.path.join(fdir, os.path.pardir))
135  match = mtab_dict.has_key(fdir)
136 
137  # construct file path relative to device
138  if fdir != os.path.sep:
139  fname = fname[len(fdir):]
140 
141  return (mtab_dict[fdir], fname)
142 
def get_mtab(mtab="/proc/mounts", vfstype=None)
Definition: fs_util.py:84
def __init__(self, mntent)
Definition: fs_util.py:51
def __init__(self, input=None)
Definition: fs_util.py:38
def get_file_device_path(fname)
Definition: fs_util.py:112
def __cache_mtab__(mtab="/proc/mounts")
Definition: fs_util.py:102