MythTV  master
filesysteminfo.cpp
Go to the documentation of this file.
1 #include <unistd.h>
2 #include <cstdlib>
3 #include "compat.h"
4 
5 #ifdef linux
6 #include <sys/vfs.h>
7 #include <sys/sysinfo.h>
8 #endif
9 
10 #if CONFIG_DARWIN
11 #include <mach/mach.h>
12 #endif
13 
14 #ifdef BSD
15 #include <sys/param.h>
16 #include <sys/mount.h> // for struct statfs
17 #endif
18 
19 #include <QList>
20 #include <QString>
21 #include <QStringList>
22 #include <utility>
23 
24 #include "filesysteminfo.h"
25 #include "mythcoreutil.h"
26 
27 // for serialization
28 #define INT_TO_LIST(x) do { list << QString::number(x); } while (false)
29 #define STR_TO_LIST(x) do { list << (x); } while (false)
30 
31 // for deserialization
32 #define NEXT_STR() do { if (it == listend) \
33  { \
34  LOG(VB_GENERAL, LOG_ALERT, listerror); \
35  clear(); \
36  return false; \
37  } \
38  ts = *it++; } while (false)
39 #define INT_FROM_LIST(x) do { NEXT_STR(); (x) = ts.toLongLong(); } while (false)
40 #define ENUM_FROM_LIST(x, y) do { NEXT_STR(); (x) = ((y)ts.toInt()); } while (false)
41 #define STR_FROM_LIST(x) do { NEXT_STR(); (x) = ts; } while (false)
42 
43 #define LOC QString("FileSystemInfo: ")
44 
46 {
47  FileSystemInfo::clone(other);
48 }
49 
50 FileSystemInfo::FileSystemInfo(QString hostname, QString path, bool local,
51  int fsid, int groupid, int blksize, int64_t total, int64_t used) :
52  m_hostname(std::move(hostname)), m_path(std::move(path)), m_local(local), m_fsid(fsid),
53  m_grpid(groupid), m_blksize(blksize), m_total(total), m_used(used)
54 {
55 }
56 
57 FileSystemInfo::FileSystemInfo(QStringList::const_iterator &it,
58  const QStringList::const_iterator& end)
59 {
60  FromStringList(it, end);
61 }
62 
63 FileSystemInfo::FileSystemInfo(const QStringList &slist)
64 {
65  FromStringList(slist);
66 }
67 
69 {
70  m_hostname = other.m_hostname;
71  m_path = other.m_path;
72  m_local = other.m_local;
73  m_fsid = other.m_fsid;
74  m_grpid = other.m_grpid;
75  m_blksize = other.m_blksize;
76  m_total = other.m_total;
77  m_used = other.m_used;
78  m_weight = other.m_weight;
79 }
80 
82 {
83  if (this == &other)
84  return *this;
85 
86  clone(other);
87  return *this;
88 }
89 
91 {
92  m_hostname = "";
93  m_path = "";
94  m_local = false;
95  m_fsid = -1;
96  m_grpid = -1;
97  m_blksize = 4096;
98  m_total = 0;
99  m_used = 0;
100  m_weight = 0;
101 }
102 
103 bool FileSystemInfo::ToStringList(QStringList &list) const
104 {
113 
114  return true;
115 }
116 
117 bool FileSystemInfo::FromStringList(const QStringList &slist)
118 {
119  QStringList::const_iterator it = slist.constBegin();
120  return FromStringList(it, slist.constEnd());
121 }
122 
123 bool FileSystemInfo::FromStringList(QStringList::const_iterator &it,
124  const QStringList::const_iterator& listend)
125 {
126  QString listerror = LOC + "FromStringList, not enough items in list.";
127  QString ts;
128 
137 
138  m_weight = 0;
139 
140  return true;
141 }
142 
143 QList<FileSystemInfo> FileSystemInfo::RemoteGetInfo(MythSocket *sock)
144 {
145  FileSystemInfo fsInfo;
146  QList<FileSystemInfo> fsInfos;
147  QStringList strlist(QString("QUERY_FREE_SPACE_LIST"));
148 
149  bool sent = false;
150 
151  if (sock)
152  sent = sock->SendReceiveStringList(strlist);
153  else
154  sent = gCoreContext->SendReceiveStringList(strlist);
155 
156  if (sent)
157  {
158  int numdisks = strlist.size()/NUMDISKINFOLINES;
159 
160  QStringList::const_iterator it = strlist.cbegin();
161  for (int i = 0; i < numdisks; i++)
162  {
163  fsInfo.FromStringList(it, strlist.cend());
164  fsInfos.append(fsInfo);
165  }
166  }
167 
168  return fsInfos;
169 }
170 
171 void FileSystemInfo::Consolidate(QList<FileSystemInfo> &disks,
172  bool merge, int64_t fuzz)
173 {
174  int newid = 0;
175 
176  for (auto it1 = disks.begin(); it1 != disks.end(); ++it1)
177  {
178  if (it1->getFSysID() == -1)
179  {
180  it1->setFSysID(newid++);
181  if (merge)
182  it1->setPath(it1->getHostname().section(".", 0, 0)
183  + ":" + it1->getPath());
184  }
185 
186  for (auto it2 = it1+1; it2 != disks.end(); ++it2)
187  {
188  if (it2->getFSysID() != -1) // disk has already been matched
189  continue;
190 
191  int bSize = std::max(32, std::max(it1->getBlockSize(), it2->getBlockSize())
192  / 1024);
193  int64_t diffSize = it1->getTotalSpace() - it2->getTotalSpace();
194  int64_t diffUsed = it1->getUsedSpace() - it2->getUsedSpace();
195 
196  if (diffSize < 0)
197  diffSize = 0 - diffSize;
198  if (diffUsed < 0)
199  diffUsed = 0 - diffUsed;
200 
201  if ((diffSize <= bSize) && (diffUsed <= fuzz))
202  {
203  it2->setFSysID(it1->getFSysID());
204 
205  if (merge)
206  {
207  if (!it1->getHostname().contains(it2->getHostname()))
208  it1->setHostname(it1->getHostname()
209  + "," + it2->getHostname());
210  it1->setPath(it1->getPath() + ","
211  + it2->getHostname().section(".", 0, 0) + ":"
212  + it2->getPath());
213  disks.erase(it2);
214  it2 = it1;
215  }
216  }
217  }
218  }
219 }
220 
222 {
223  int64_t total = -1;
224  int64_t used = -1;
225  getDiskSpace(getPath().toLatin1().constData(), total, used);
226  setTotalSpace(total);
227  setUsedSpace(used);
228 }
229 
231 {
232  struct statfs statbuf {};
233 
234  if (statfs(getPath().toLocal8Bit().constData(), &statbuf) == 0)
235  {
236 #if CONFIG_DARWIN
237  char *fstypename = statbuf.f_fstypename;
238  if ((!strcmp(fstypename, "nfs")) || // NFS|FTP
239  (!strcmp(fstypename, "afpfs")) || // AppleShare
240  (!strcmp(fstypename, "smbfs"))) // SMB
241  setLocal(false);
242 #elif __linux__
243  long fstype = statbuf.f_type;
244  if ((fstype == 0x6969) || // NFS
245  (fstype == 0x517B) || // SMB
246  (fstype == (long)0xFF534D42)) // CIFS
247  setLocal(false);
248 #endif
249  setBlockSize(statbuf.f_bsize);
250  }
251 }
filesysteminfo.h
FileSystemInfo::setUsedSpace
void setUsedSpace(int64_t size)
Definition: filesysteminfo.h:54
FileSystemInfo::m_total
int64_t m_total
Definition: filesysteminfo.h:76
FileSystemInfo::m_fsid
int m_fsid
Definition: filesysteminfo.h:73
INT_TO_LIST
#define INT_TO_LIST(x)
Definition: filesysteminfo.cpp:28
FileSystemInfo::m_path
QString m_path
Definition: filesysteminfo.h:71
MythSocket::SendReceiveStringList
bool SendReceiveStringList(QStringList &list, uint min_reply_length=0, uint timeoutMS=kLongTimeout)
Definition: mythsocket.cpp:342
MythCoreContext::SendReceiveStringList
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
Definition: mythcorecontext.cpp:1380
getDiskSpace
int64_t getDiskSpace(const QString &file_on_disk, int64_t &total, int64_t &used)
Definition: mythcoreutil.cpp:43
FileSystemInfo::FromStringList
bool FromStringList(const QStringList &slist)
Definition: filesysteminfo.cpp:117
STR_TO_LIST
#define STR_TO_LIST(x)
Definition: filesysteminfo.cpp:29
FileSystemInfo::getPath
QString getPath(void) const
Definition: filesysteminfo.h:34
FileSystemInfo::Consolidate
static void Consolidate(QList< FileSystemInfo > &disks, bool merge=true, int64_t fuzz=14000)
Definition: filesysteminfo.cpp:171
mythcoreutil.h
LOC
#define LOC
Definition: filesysteminfo.cpp:43
FileSystemInfo::ToStringList
bool ToStringList(QStringList &slist) const
Definition: filesysteminfo.cpp:103
FileSystemInfo::FileSystemInfo
FileSystemInfo()=default
INT_FROM_LIST
#define INT_FROM_LIST(x)
Definition: filesysteminfo.cpp:39
MythSocket
Class for communcating between myth backends and frontends.
Definition: mythsocket.h:27
FileSystemInfo::setTotalSpace
void setTotalSpace(int64_t size)
Definition: filesysteminfo.h:53
NUMDISKINFOLINES
#define NUMDISKINFOLINES
Definition: filesysteminfo.h:3
FileSystemInfo::RemoteGetInfo
static QList< FileSystemInfo > RemoteGetInfo(MythSocket *sock=nullptr)
Definition: filesysteminfo.cpp:143
FileSystemInfo::m_hostname
QString m_hostname
Definition: filesysteminfo.h:70
FileSystemInfo::setLocal
void setLocal(bool local=true)
Definition: filesysteminfo.h:49
statfs
int statfs(const char *path, struct statfs *buffer)
Definition: compat.h:179
compat.h
STR_FROM_LIST
#define STR_FROM_LIST(x)
Definition: filesysteminfo.cpp:41
FileSystemInfo::m_local
bool m_local
Definition: filesysteminfo.h:72
FileSystemInfo::clone
virtual void clone(const FileSystemInfo &other)
Definition: filesysteminfo.cpp:68
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
FileSystemInfo::PopulateFSProp
void PopulateFSProp(void)
Definition: filesysteminfo.cpp:230
FileSystemInfo::PopulateDiskSpace
void PopulateDiskSpace(void)
Definition: filesysteminfo.cpp:221
FileSystemInfo::m_weight
int m_weight
Definition: filesysteminfo.h:78
statfs
Definition: compat.h:167
FileSystemInfo
Definition: filesysteminfo.h:16
FileSystemInfo::m_blksize
int m_blksize
Definition: filesysteminfo.h:75
statfs::f_bsize
long f_bsize
Definition: compat.h:169
FileSystemInfo::setBlockSize
void setBlockSize(int size)
Definition: filesysteminfo.h:52
FileSystemInfo::m_used
int64_t m_used
Definition: filesysteminfo.h:77
musicbrainzngs.caa.hostname
string hostname
Definition: caa.py:17
FileSystemInfo::m_grpid
int m_grpid
Definition: filesysteminfo.h:74
FileSystemInfo::clear
void clear(void)
Definition: filesysteminfo.cpp:90
FileSystemInfo::operator=
FileSystemInfo & operator=(const FileSystemInfo &other)
Definition: filesysteminfo.cpp:81