[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