MythTV master
fs_util.py
Go to the documentation of this file.
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
23from builtins import object
24import os
25
26# We cache the contents of /etc/mtab ... the following variables are used
27# to keep our cache in sync
28mtab_mtime = None
29mtab_map = []
30
31class MntEntObj(object):
32 mnt_fsname = None #* name of mounted file system */
33 mnt_dir = None #* file system path prefix */
34 mnt_type = None #* mount type (see mntent.h) */
35 mnt_opts = None #* mount options (see mntent.h) */
36 mnt_freq = 0 #* dump frequency in days */
37 mnt_passno = 0 #* pass number on parallel fsck */
38
39 def __init__(self,input=None):
40 if input and isinstance(input, str):
41 (self.mnt_fsname, self.mnt_dir, self.mnt_type, self.mnt_opts, \
42 self.mnt_freq, self.mnt_passno) = input.split()
43 def __dict__(self):
44 return {"mnt_fsname": self.mnt_fsname, "mnt_dir": self.mnt_dir, \
45 "mnt_type": self.mnt_type, "mnt_opts": self.mnt_opts, \
46 "mnt_freq": self.mnt_freq, "mnt_passno": self.mnt_passno}
47 def __str__(self):
48 return "%s %s %s %s %s %s" % (self.mnt_fsname, self.mnt_dir, self.mnt_type, \
49 self.mnt_opts, self.mnt_freq, self.mnt_passno)
50
51class FileSystem(object):
52 def __init__(self, mntent):
53 self.mnt_dev = mntent.mnt_fsname
54 self.mnt_pnt = mntent.mnt_dir
55 self.fs_type = mntent.mnt_type
56 try:
57 stat_res = os.statvfs('%s' % self.mnt_pnt)
58 except OSError:
59 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"
60 else:
61 self.f_bsize = stat_res.f_bsize
62 self.f_frsize = stat_res.f_frsize
63 self.f_blocks = stat_res.f_blocks
64 self.f_bfree = stat_res.f_bfree
65 self.f_bavail = stat_res.f_bavail
66 self.f_files = stat_res.f_files
67 self.f_ffree = stat_res.f_ffree
68 self.f_favail = stat_res.f_favail
69
70 def to_dict(self):
71 return dict(mnt_pnt=self.mnt_pnt, fs_type=self.fs_type, f_favail=self.f_favail,
72 f_bsize=self.f_bsize, f_frsize=self.f_frsize, f_blocks=self.f_blocks,
73 f_bfree=self.f_bfree, f_bavail=self.f_bavail, f_files=self.f_files,
74 f_ffree=self.f_ffree)
75
76 def __str__(self):
77 return "%s %s %s %s %s %s %s %s %s %s %s" % \
78 (self.mnt_dev, self.mnt_pnt, self.fs_type,
79 self.f_bsize, self.f_frsize, self.f_blocks,
80 self.f_bfree, self.f_bavail, self.f_files,
81 self.f_ffree, self.f_favail)
82
83
84
85def get_mtab(mtab="/proc/mounts", vfstype=None):
86 global mtab_mtime, mtab_map
87
88 mtab_stat = os.stat(mtab)
89 if mtab_stat.st_mtime != mtab_mtime:
90 #print '''cache is stale ... refresh'''
91 mtab_mtime = mtab_stat.st_mtime
92 mtab_map = __cache_mtab__(mtab)
93
94 # was a specific fstype requested?
95 if vfstype:
96 return [ent for ent in mtab_map if ent.mnt_type == vfstype]
97
98 return mtab_map
99
101 return [FileSystem(mnt) for mnt in get_mtab()]
102
103def __cache_mtab__(mtab="/proc/mounts"):
104 global mtab_mtime
105
106 f = open(mtab)
107 #don't want empty lines
108 mtab = [MntEntObj(line) for line in f.read().split('\n') if len(line) > 0]
109 f.close()
110
111 return mtab
112
114 '''What this function attempts to do is take a file and return:
115 - the device the file is on
116 - the path of the file relative to the device.
117 For example:
118 /boot/vmlinuz -> (/dev/sda3, /vmlinuz)
119 /boot/efi/efi/redhat/elilo.conf -> (/dev/cciss0, /elilo.conf)
120 /etc/fstab -> (/dev/sda4, /etc/fstab)
121 '''
122
123 # resolve any symlinks
124 fname = os.path.realpath(fname)
125
126 # convert mtab to a dict
127 mtab_dict = {}
128 for ent in get_mtab():
129 mtab_dict[ent.mnt_dir] = ent.mnt_fsname
130
131 # find a best match
132 fdir = os.path.dirname(fname)
133 match = fdir in mtab_dict
134 while not match:
135 fdir = os.path.realpath(os.path.join(fdir, os.path.pardir))
136 match = fdir in mtab_dict
137
138 # construct file path relative to device
139 if fdir != os.path.sep:
140 fname = fname[len(fdir):]
141
142 return (mtab_dict[fdir], fname)
143
def __init__(self, mntent)
Definition: fs_util.py:52
def __init__(self, input=None)
Definition: fs_util.py:39
def __cache_mtab__(mtab="/proc/mounts")
Definition: fs_util.py:103
def get_mtab(mtab="/proc/mounts", vfstype=None)
Definition: fs_util.py:85
def get_file_device_path(fname)
Definition: fs_util.py:113