Index: libs/libmyth/util.cpp =================================================================== RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/util.cpp,v retrieving revision 1.41 diff -u -r1.41 util.cpp --- libs/libmyth/util.cpp 29 Nov 2004 21:23:35 -0000 1.41 +++ libs/libmyth/util.cpp 16 Dec 2004 00:06:41 -0000 @@ -5,6 +5,19 @@ #include #include +#ifdef __linux__ +#include +#include +#endif +#if defined(__FreeBSD__) || defined(CONFIG_DARWIN) +#include +#include +#include +#endif +#ifdef CONFIG_DARWIN +#include +#endif + #include using namespace std; @@ -18,6 +31,11 @@ } #endif +#if defined(Q_WS_MACX) +#import +#import +#endif + #include #include #include @@ -744,3 +762,123 @@ str[20] = '\0'; return str; } + +bool getUptime(time_t &uptime) +{ +#ifdef __linux__ + struct sysinfo sinfo; + if (sysinfo(&sinfo) == -1) + { + VERBOSE(VB_ALL, "sysinfo() error"); + return false; + } + else + uptime = sinfo.uptime; + +#elif defined(__FreeBSD__) || defined(CONFIG_DARWIN) + + int mib[2]; + struct timeval bootTime; + size_t len; + + // Uptime is calculated. Get this machine's boot time + // and subtract it from the current machine time + len = sizeof(bootTime); + mib[0] = CTL_KERN; + mib[1] = KERN_BOOTTIME; + if (sysctl(mib, 2, &bootTime, &len, NULL, 0) == -1) + { + VERBOSE(VB_ALL, "sysctl() error"); + return false; + } + else + uptime = time(NULL) - bootTime.tv_sec; + +#else + // Hmmm. Not Linux, not FreeBSD or Darwin. What else is there :-) + VERBOSE(VB_ALL, "Unknown platform. How do I get the uptime?"); + return false; +#endif + + return true; +} + +#define MB (1024*1024) + +static bool diskUsage(const char *fs, + double &total, double &used, double &free) +{ + // stat the file system + +#ifdef __linux__ +#define STAT statvfs +#elif defined(__FreeBSD__) || defined(CONFIG_DARWIN) +#define STAT statfs +#endif + + struct STAT sbuff; + if (STAT(fs, &sbuff) == -1) + return false; + + // see http://en.wikipedia.org/wiki/Megabyte + + total = (double)sbuff.f_blocks * sbuff.f_bsize / MB; + free = (double)sbuff.f_bfree * sbuff.f_bsize / MB; + used = total - free; + return true; +} + +bool getMemStats(int &totalMB, int &freeMB, int &totalVM, int &freeVM) +{ +#ifdef __linux__ + struct sysinfo sinfo; + if (sysinfo(&sinfo) == -1) + { + VERBOSE(VB_ALL, "sysinfo() error"); + return false; + } + else + totalMB = sinfo.totalram/MB, + freeMB = sinfo.freeram/MB, + totalVM = sinfo.totalswap/MB, + freeVM = sinfo.freeswap/MB; + +#elif defined(CONFIG_DARWIN) + mach_port_t mp; + mach_msg_type_number_t count, pageSize; + vm_statistics_data_t s; + + mp = mach_host_self(); + + // VM page size + if (host_page_size(mp, &pageSize) != KERN_SUCCESS) + pageSize = 4096; // If we can't look it up, 4K is a good guess + + count = HOST_VM_INFO_COUNT; + if (host_statistics(mp, HOST_VM_INFO, + (host_info_t)&s, &count) != KERN_SUCCESS) + { + VERBOSE(VB_ALL, "Failed to get vm statistics."); + return false; + } + + pageSize >>= 10; // This gives usages in KB + totalMB = (s.active_count + s.inactive_count + + s.wire_count + s.free_count) * pageSize / 1024; + freeMB = s.free_count * pageSize / 1024; + + + // This is a real hack. I have not found a way to ask the kernel how much + // swap it is using, and the dynamic_pager daemon doesn't even seem to be + // able to report what filesystem it is using for the swapfiles. So, we do: + double total, used, free; + diskUsage("/private/var/vm", total, used, free); + totalVM = (int)total, freeVM = (int)free; + +#else + VERBOSE(VB_ALL, "Unknown platform. How do I get the memory stats?"); + return false; +#endif + + return true; +} Index: libs/libmyth/util.h =================================================================== RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/util.h,v retrieving revision 1.17 diff -u -r1.17 util.h --- libs/libmyth/util.h 14 Oct 2004 04:30:59 -0000 1.17 +++ libs/libmyth/util.h 16 Dec 2004 00:06:41 -0000 @@ -47,4 +47,8 @@ long long stringToLongLong(const QString &str); QString longLongToString(long long ll); + +bool diskUsage(const char *path, double &total, double &used, double &free); +bool getUptime(time_t &uptime); +bool getMemStats(int &totalMB, int &freeMB, int &totalVM, int &freeVM); #endif Index: libs/libmythtv/remoteutil.cpp =================================================================== RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/remoteutil.cpp,v retrieving revision 1.29 diff -u -r1.29 remoteutil.cpp --- libs/libmythtv/remoteutil.cpp 13 Oct 2004 01:49:55 -0000 1.29 +++ libs/libmythtv/remoteutil.cpp 16 Dec 2004 00:06:41 -0000 @@ -58,6 +58,57 @@ } } +bool RemoteGetLoad(float load[3]) +{ + QStringList strlist = QString("QUERY_LOAD"); + + if (gContext->SendReceiveStringList(strlist)) + { + load[0] = strlist[0].toFloat(); + load[1] = strlist[1].toFloat(); + load[2] = strlist[2].toFloat(); + return true; + } + + return false; +} + +bool RemoteGetUptime(time_t &uptime) +{ + QStringList strlist = QString("QUERY_UPTIME"); + + if (!gContext->SendReceiveStringList(strlist)) + return false; + + if (!strlist[0].at(0).isNumber()) + return false; + + if (sizeof(time_t) == sizeof(int)) + uptime = strlist[0].toUInt(); + else if (sizeof(time_t) == sizeof(long)) + uptime = strlist[0].toULong(); + else if (sizeof(time_t) == sizeof(long long)) + uptime = strlist[0].toULongLong(); + + return false; +} + +bool RemoteGetMemStats(int &totalMB, int &freeMB, int &totalVM, int &freeVM) +{ + QStringList strlist = QString("QUERY_MEMSTATS"); + + if (gContext->SendReceiveStringList(strlist)) + { + totalMB = strlist[0].toInt(); + freeMB = strlist[1].toInt(); + totalVM = strlist[2].toInt(); + freeVM = strlist[3].toInt(); + return true; + } + + return false; +} + bool RemoteCheckFile(ProgramInfo *pginfo) { QStringList strlist = "QUERY_CHECKFILE"; Index: libs/libmythtv/remoteutil.h =================================================================== RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/remoteutil.h,v retrieving revision 1.23 diff -u -r1.23 remoteutil.h --- libs/libmythtv/remoteutil.h 13 Oct 2004 01:49:55 -0000 1.23 +++ libs/libmythtv/remoteutil.h 16 Dec 2004 00:06:41 -0000 @@ -9,6 +9,9 @@ vector *RemoteGetRecordedList(bool deltype); void RemoteGetFreeSpace(int &totalspace, int &usedspace); +bool RemoteGetLoad(float load[3]); +bool RemoteGetUptime(time_t &uptime); +bool RemoteGetMemStats(int &totalMB, int &freeMB, int &totalVM, int &freeVM); bool RemoteCheckFile(ProgramInfo *pginfo); void RemoteStopRecording(ProgramInfo *pginfo); void RemoteDeleteRecording(ProgramInfo *pginfo, bool forgetHistory); Index: programs/mythbackend/mainserver.cpp =================================================================== RCS file: /var/lib/mythcvs/mythtv/programs/mythbackend/mainserver.cpp,v retrieving revision 1.165 diff -u -r1.165 mainserver.cpp --- programs/mythbackend/mainserver.cpp 8 Dec 2004 09:03:51 -0000 1.165 +++ programs/mythbackend/mainserver.cpp 16 Dec 2004 00:06:42 -0000 @@ -238,6 +238,18 @@ { HandleQueryFreeSpace(pbs); } + else if (command == "QUERY_LOAD") + { + HandleQueryLoad(pbs); + } + else if (command == "QUERY_UPTIME") + { + HandleQueryUptime(pbs); + } + else if (command == "QUERY_MEMSTATS") + { + HandleQueryMemStats(pbs); + } else if (command == "QUERY_CHECKFILE") { HandleQueryCheckFile(listline, pbs); @@ -1522,6 +1534,52 @@ SendResponse(pbssock, strlist); } +void MainServer::HandleQueryLoad(PlaybackSock *pbs) +{ + QSocket *pbssock = pbs->getSocket(); + + QStringList strlist; + + double loads[3]; + if (getloadavg(loads,3) == -1) + strlist << "getloadavg() failed"; + else + strlist << QString::number(loads[0]) + << QString::number(loads[1]) + << QString::number(loads[2]); + + SendResponse(pbssock, strlist); +} + +void MainServer::HandleQueryUptime(PlaybackSock *pbs) +{ + QSocket *pbssock = pbs->getSocket(); + QStringList strlist; + time_t uptime; + + if (getUptime(uptime)) + strlist << QString::number(uptime); + else + strlist << "Could not determine uptime."; + + SendResponse(pbssock, strlist); +} + +void MainServer::HandleQueryMemStats(PlaybackSock *pbs) +{ + QSocket *pbssock = pbs->getSocket(); + QStringList strlist; + int totalMB, freeMB, totalVM, freeVM; + + if (getMemStats(totalMB, freeMB, totalVM, freeVM)) + strlist << QString::number(totalMB) << QString::number(freeMB) + << QString::number(totalVM) << QString::number(freeVM); + else + strlist << "Could not determine memory stats."; + + SendResponse(pbssock, strlist); +} + void MainServer::HandleQueryCheckFile(QStringList &slist, PlaybackSock *pbs) { QSocket *pbssock = pbs->getSocket(); Index: programs/mythfrontend/statusbox.cpp =================================================================== RCS file: /var/lib/mythcvs/mythtv/programs/mythfrontend/statusbox.cpp,v retrieving revision 1.15 diff -u -r1.15 statusbox.cpp --- programs/mythfrontend/statusbox.cpp 15 Dec 2004 18:42:54 -0000 1.15 +++ programs/mythfrontend/statusbox.cpp 16 Dec 2004 00:06:42 -0000 @@ -32,6 +32,7 @@ #include "programinfo.h" #include "tv.h" #include "jobqueue.h" +#include "util.h" StatusBox::StatusBox(MythMainWindow *parent, const char *name) : MythDialog(parent, name) @@ -1019,33 +1020,6 @@ .arg((int)(100*free/total)); } -static bool diskUsage(const char *fs, - double &total, double &used, double &free) -{ - // stat the file system - -#ifdef __linux__ -#define STAT statvfs -#elif defined(__FreeBSD__) || defined(CONFIG_DARWIN) -#define STAT statfs -#endif - - struct STAT sbuff; - if (!STAT(fs, &sbuff)) - { - // see http://en.wikipedia.org/wiki/Megabyte - - total = (double)sbuff.f_blocks * sbuff.f_bsize / MB; - free = (double)sbuff.f_bfree * sbuff.f_bsize / MB; - //total /= MB; - //free /= MB; - used = total - free; - return true; - } - else - return false; -} - static const QString diskUsageStr(const char *path) { double total, free, used; @@ -1054,8 +1028,6 @@ return usageStr (total, used, free); else return QString("%1 - %2").arg(path).arg(strerror(errno)); - //return QString("statfs() error (%1) on %2") - //.arg(strerror(errno)).arg(path); } static const QString uptimeStr(time_t uptime) @@ -1099,52 +1071,13 @@ } } -#ifdef CONFIG_DARWIN -static void getMachMemStats(long &totalM, long &usedM, long &freeM, - long &totalS, long &usedS, long &freeS) -{ - mach_port_t mp; - mach_msg_type_number_t count, pageSize; - vm_statistics_data_t s; - - mp = mach_host_self(); - - // VM page size - if (host_page_size(mp, &pageSize) != KERN_SUCCESS) - pageSize = 4096; // If we can't look it up, 4K is a good guess - - count = HOST_VM_INFO_COUNT; - if (host_statistics(mp, HOST_VM_INFO, - (host_info_t)&s, &count) != KERN_SUCCESS) - { - cerr << "Failed to get vm statistics.\n"; - return; - } - - pageSize >>= 10; // This gives usages in KB - usedM = (s.active_count + - s.inactive_count + s.wire_count) * pageSize / 1024; - totalM = (s.free_count + s.active_count + - s.inactive_count + s.wire_count) * pageSize / 1024; - freeM = s.free_count * pageSize / 1024; - - - // This is a real hack. I have not found a way to ask the kernel how much - // swap it is using, and the dynamic_pager daemon doesn't even seem to be - // able to report what filesystem it is using for the swapfiles. So, we do: - double total, used, free; - diskUsage("/private/var/vm", total, used, free); - totalS = (long)total, usedS = (long)used, freeS = (long)free; -} -#endif - void StatusBox::doMachineStatus() { QSqlDatabase *db(QSqlDatabase::database()); int count(0); - long totalM, usedM, freeM; // Physical memory - long totalS, usedS, freeS; // Virtual memory (swap) + int totalM, usedM, freeM; // Physical memory + int totalS, usedS, freeS; // Virtual memory (swap) time_t uptime; contentLines.clear(); @@ -1157,84 +1090,36 @@ else contentLines[count++] = QObject::tr("This machine") + ":"; -#ifdef __linux__ - struct sysinfo sinfo; - if (sysinfo(&sinfo)) - contentLines[count++] = QString(" sysinfo() error"); - else - { - uptime = sinfo.uptime; + // uptime + if (!getUptime(uptime)) + uptime = 0; + contentLines[count] = uptimeStr(uptime); + + // weighted average loads + contentLines[count].append(". " + QObject::tr("Load") + ": "); - totalM = sinfo.totalram/MB; - freeM = sinfo.freeram/MB; - usedM = totalM - freeM; - totalS = sinfo.totalswap/MB; - freeS = sinfo.freeswap/MB; - usedS = totalS - freeS; - -#elif defined(__FreeBSD__) || defined(CONFIG_DARWIN) - - int mib[2]; - struct timeval bootTime; - size_t len; - - // Uptime is calculated. Get this machine's boot time - // and subtract it from the current machine time - len = sizeof(bootTime); - mib[0] = CTL_KERN; - mib[1] = KERN_BOOTTIME; - if (sysctl(mib, 2, &bootTime, &len, NULL, 0) == -1) - contentLines[count++] = QString(" sysctl() error"); + double loads[3]; + if (getloadavg(loads,3) == -1) + contentLines[count].append(QObject::tr("unknown") + + " - getloadavg() " + QObject::tr("failed")); else { - uptime = time(NULL) - bootTime.tv_sec; - - // We can easily look up the Physical memory statistics: - unsigned int totalBytes; - len = sizeof(totalBytes); - mib[0] = CTL_HW; - mib[1] = HW_PHYSMEM; - if (sysctl(mib, 2, &totalBytes, &len, NULL, 0) == -1) - totalM = -1; - else - totalM = totalBytes/MB; - - usedM = freeM = 0; + char buff[30]; - // VM stats are a bit harder. - totalS = usedS = freeS = 0; - - #ifdef CONFIG_DARWIN - getMachMemStats(totalM, usedM, freeM, totalS, usedS, freeS); - #endif -#else - { // Hmmm. Not Linux, not FreeBSD or Darwin. What else is there :-) -#endif - // uptime - contentLines[count] = uptimeStr(uptime); - - // weighted average loads - contentLines[count].append(". " + QObject::tr("Load") + ": "); - - double loads[3]; - if (getloadavg(loads,sizeof(loads)/sizeof(*loads)) == -1) - contentLines[count].append(QObject::tr("unknown") + - " - getloadavg() " + - QObject::tr("failed")); - else - { - char buff[512]; - - sprintf(buff, "%0.2f, %0.2f, %0.2f", loads[0], loads[1], loads[2]); - contentLines[count].append(QString(buff)); - } - count++; + sprintf(buff, "%0.2lf, %0.2lf, %0.2lf", loads[0], loads[1], loads[2]); + contentLines[count].append(QString(buff)); + } + count++; - // memory usage + // memory usage + if (getMemStats(totalM, freeM, totalS, freeS)) + { + usedM = totalM - freeM; if (totalM > 0) contentLines[count++] = " " + QObject::tr("RAM") + ": " + usageStr(totalM, usedM, freeM); + usedS = totalS - freeS; if (totalS > 0) contentLines[count++] = " " + QObject::tr("Swap") + @@ -1246,24 +1131,35 @@ contentLines[count++] = QObject::tr("MythTV server") + ":"; // uptime - uptime = 0; + if (!RemoteGetUptime(uptime)) + uptime = 0; contentLines[count] = uptimeStr(uptime); // weighted average loads contentLines[count].append(". " + QObject::tr("Load") + ": "); + float loads[3]; + if (RemoteGetLoad(loads)) + { + char buff[30]; - // How will I get this from the backend. A new query? - contentLines[count++].append(QObject::tr("unknown")); + sprintf(buff, "%0.2f, %0.2f, %0.2f", loads[0], loads[1], loads[2]); + contentLines[count].append(QString(buff)); + } + else + contentLines[count++].append(QObject::tr("unknown")); // memory usage - totalM = usedM = freeM = 0; - if (totalM > 0) - contentLines[count++] = " " + QObject::tr("RAM") + - ": " + usageStr(totalM, usedM, freeM); - totalS = usedS = freeS = 0; - if (totalS > 0) - contentLines[count++] = " " + QObject::tr("Swap") + - ": " + usageStr(totalS, usedS, freeS); + if (RemoteGetMemStats(totalM, freeM, totalS, freeS)) + { + usedM = totalM - freeM; + if (totalM > 0) + contentLines[count++] = " " + QObject::tr("RAM") + + ": " + usageStr(totalM, usedM, freeM); + usedS = totalS - freeS; + if (totalS > 0) + contentLines[count++] = " " + QObject::tr("Swap") + + ": " + usageStr(totalS, usedS, freeS); + } } // get free disk space