[mythtv] Mythfrontend hang with CVS
Stacey Son
mythdev at son.org
Tue Jun 8 15:03:43 EDT 2004
Yes, nesting calls to getfsent() is not good given that it is using a
static buffer. This is most likely the reason mythfrontend is hanging
for you.
After looking at the code I don't see the reason for calling getfsent()
again in addDevice(). Attached is a patch to mythmediamonitor.cpp and
mythmediamonitor.h that add another overloaded addDevice(). This
eliminates the nested calls to getfsent(). Please give this patch a try
and let me know if it fixes the hanging problem.
-stacey.
Leo Weppelman wrote:
>It looks like the changes for the FreeBSD port broke the mediamonitor.
>The first problem is getmntent() being replaced by getfsent(). The latter
>cannot be nested. This causes the 'hang'. MediaMonitor::addFSTab() uses
>getfsent() to get device names and calls MediaMonitor::addDevice which
>also calls getfsent(). This works with getmntent(), it won't work with
>getfsent().
>I quickly hacked MediaMonitor::addFSTab() to use getmntent() again and
>then you'll get a SIGSEGV because of a stack overflow :-(
>This seems to be caused by MythCDROMLinux::unlock() calling openDevice()
>which seems to be calling unlock().....
>
>Sorry, no fixes, just investigations...
>
>Leo.
>
>
>------------------------------------------------------------------------
>
>_______________________________________________
>mythtv-dev mailing list
>mythtv-dev at mythtv.org
>http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev
>
>
-------------- next part --------------
Index: ./libs/libmyth/mythmediamonitor.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/mythmediamonitor.cpp,v
retrieving revision 1.5
diff -u -r1.5 mythmediamonitor.cpp
--- ./libs/libmyth/mythmediamonitor.cpp 4 Jun 2004 21:21:05 -0000 1.5
+++ ./libs/libmyth/mythmediamonitor.cpp 8 Jun 2004 18:16:43 -0000
@@ -82,7 +82,7 @@
{
perror("setfsent");
cerr << "MediaMonitor::addFSTab - Failed to open "
- _PATH_FSTAB
+ _PATH_FSTAB
" for reading." << endl;
return false;
}
@@ -90,7 +90,7 @@
{
// Add all the entries
while ((mep = getfsent()) != NULL)
- addDevice(mep->fs_spec);
+ (void) addDevice(mep);
endfsent();
}
@@ -109,6 +109,94 @@
m_Devices.push_back( pDevice );
}
+// Given a fstab entry to a media device determine what type of device it is
+bool MediaMonitor::addDevice(struct fstab * mep)
+{
+ QString devicePath( mep->fs_spec );
+ //cout << "addDevice - " << devicePath << endl;
+
+ MythMediaDevice* pDevice = NULL;
+ struct stat sbuf;
+
+ bool is_supermount = false;
+ bool is_cdrom = false;
+
+ if (mep == NULL)
+ return false;
+
+ if (! stat(mep->fs_spec, &sbuf))
+ return false;
+
+ // Can it be mounted?
+ if ( ! ( ((strstr(mep->fs_mntops, "owner") &&
+ (sbuf.st_mode & S_IRUSR)) || strstr(mep->fs_mntops, "user")) &&
+ (strstr(mep->fs_vfstype, MNTTYPE_ISO9660) ||
+ strstr(mep->fs_vfstype, MNTTYPE_UDF) ||
+ strstr(mep->fs_vfstype, MNTTYPE_AUTO)) ) )
+ {
+ if ( strstr(mep->fs_mntops, MNTTYPE_ISO9660) &&
+ strstr(mep->fs_vfstype, MNTTYPE_SUPERMOUNT) )
+ {
+ is_supermount = true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (strstr(mep->fs_mntops, MNTTYPE_ISO9660) ||
+ strstr(mep->fs_vfstype, MNTTYPE_ISO9660))
+ {
+ is_cdrom = true;
+ //cout << "Device is a CDROM" << endl;
+ }
+
+ if (!is_supermount)
+ {
+ if (is_cdrom)
+ pDevice = MythCDROM::get(this, QString(mep->fs_spec),
+ is_supermount, m_AllowEject);
+ }
+ else
+ {
+ char *dev;
+ int len = 0;
+ dev = strstr(mep->fs_mntops, SUPER_OPT_DEV);
+ dev += sizeof(SUPER_OPT_DEV)-1;
+ while (dev[len] != ',' && dev[len] != ' ' && dev[len] != 0)
+ len++;
+
+ if (dev[len] != 0)
+ {
+ char devstr[256];
+ strncpy(devstr, dev, len);
+ devstr[len] = 0;
+ if (is_cdrom)
+ MythCDROM::get(this, QString(devstr),
+ is_supermount, m_AllowEject);
+ }
+ else
+ return false;
+ }
+
+ if (pDevice)
+ {
+ pDevice->setMountPath(mep->fs_file);
+ VERBOSE(VB_ALL, QString("Mediamonitor: Adding %1")
+ .arg(pDevice->getDevicePath()));
+ if (pDevice->testMedia() == MEDIAERR_OK)
+ {
+ addDevice(pDevice);
+ return true;
+ }
+ else
+ delete pDevice;
+ }
+
+ return false;
+}
+
// Given a path to a media device determine what type of device it is and
// add it to our collection.
bool MediaMonitor::addDevice(const char* devPath )
@@ -116,13 +204,8 @@
QString devicePath( devPath );
//cout << "addDevice - " << devicePath << endl;
- MythMediaDevice* pDevice = NULL;
-
struct fstab * mep = NULL;
char lpath[PATH_MAX];
- struct stat sbuf;
- bool is_supermount = false;
- bool is_cdrom = false;
// Resolve the simlink for the device.
int len = readlink(devicePath, lpath, PATH_MAX);
@@ -134,7 +217,7 @@
{
perror("setfsent");
cerr << "MediaMonitor::addDevice - Failed to open "
- _PATH_FSTAB
+ _PATH_FSTAB
" for reading." << endl;
return false;
}
@@ -157,79 +240,13 @@
(len && (strcmp(lpath, mep->fs_spec) != 0)))
continue;
- stat(mep->fs_spec, &sbuf);
-
- if (((strstr(mep->fs_mntops, "owner") &&
- (sbuf.st_mode & S_IRUSR)) || strstr(mep->fs_mntops, "user")) &&
- (strstr(mep->fs_vfstype, MNTTYPE_ISO9660) ||
- strstr(mep->fs_vfstype, MNTTYPE_UDF) ||
- strstr(mep->fs_vfstype, MNTTYPE_AUTO)))
- {
- break;
- }
-
- if (strstr(mep->fs_mntops, MNTTYPE_ISO9660) &&
- strstr(mep->fs_vfstype, MNTTYPE_SUPERMOUNT))
- {
- is_supermount = true;
- break;
- }
}
endfsent();
}
if (mep)
- {
- if (strstr(mep->fs_mntops, MNTTYPE_ISO9660) ||
- strstr(mep->fs_vfstype, MNTTYPE_ISO9660))
- {
- is_cdrom = true;
- //cout << "Device is a CDROM" << endl;
- }
-
- if (!is_supermount)
- {
- if (is_cdrom)
- pDevice = MythCDROM::get(this, QString(mep->fs_spec),
- is_supermount, m_AllowEject);
- }
- else
- {
- char *dev;
- int len = 0;
- dev = strstr(mep->fs_mntops, SUPER_OPT_DEV);
- dev += sizeof(SUPER_OPT_DEV)-1;
- while (dev[len] != ',' && dev[len] != ' ' && dev[len] != 0)
- len++;
-
- if (dev[len] != 0)
- {
- char devstr[256];
- strncpy(devstr, dev, len);
- devstr[len] = 0;
- if (is_cdrom)
- MythCDROM::get(this, QString(devstr),
- is_supermount, m_AllowEject);
- }
- else
- return false;
- }
-
- if (pDevice)
- {
- pDevice->setMountPath(mep->fs_file);
- VERBOSE(VB_ALL, QString("Mediamonitor: Adding %1")
- .arg(pDevice->getDevicePath()));
- if (pDevice->testMedia() == MEDIAERR_OK)
- {
- addDevice(pDevice);
- return true;
- }
- else
- delete pDevice;
- }
- }
+ return addDevice(mep);
return false;
}
Index: ./libs/libmyth/mythmediamonitor.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/mythmediamonitor.h,v
retrieving revision 1.2
diff -u -r1.2 mythmediamonitor.h
--- ./libs/libmyth/mythmediamonitor.h 4 Jun 2004 02:31:22 -0000 1.2
+++ ./libs/libmyth/mythmediamonitor.h 8 Jun 2004 18:16:43 -0000
@@ -5,6 +5,7 @@
#include <qvaluelist.h>
#include <qguardedptr.h>
#include <qthread.h>
+#include <fstab.h>
const int kMediaEventType = 30042;
@@ -48,6 +49,7 @@
bool addFSTab(void);
void addDevice(MythMediaDevice* pDevice);
bool addDevice(const char* dev);
+ bool addDevice(struct fstab* mep);
bool isActive(void) const { return m_Active; }
void checkDevices(void);
More information about the mythtv-dev
mailing list