Ticket #601: hotplug_hdd.diff
File hotplug_hdd.diff, 30.0 KB (added by , 18 years ago) |
---|
-
libs/libmyth/mythmedia.cpp
17 17 18 18 // end for testing 19 19 20 static const QString PATHTO_PMOUNT("/usr/bin/pmount"); 21 static const QString PATHTO_PUMOUNT("/usr/bin/pumount"); 20 22 static const QString PATHTO_MOUNT("/bin/mount"); 21 23 static const QString PATHTO_UNMOUNT("/bin/umount"); 22 24 static const QString PATHTO_MOUNTS("/proc/mounts"); … … 25 27 { 26 28 "MEDIASTAT_ERROR", 27 29 "MEDIASTAT_UNKNOWN", 30 "MEDIASTAT_UNPLUGGED", 28 31 "MEDIASTAT_OPEN", 29 32 "MEDIASTAT_USEABLE", 30 33 "MEDIASTAT_NOTMOUNTED", … … 57 60 m_Locked = false; 58 61 m_DeviceHandle = -1; 59 62 m_SuperMount = SuperMount; 60 m_Status = (isMounted(true)) ? MEDIASTAT_MOUNTED : MEDIASTAT_NOTMOUNTED; 63 m_Status = MEDIASTAT_UNKNOWN; 64 m_MediaType = MEDIATYPE_UNKNOWN; 61 65 } 62 66 63 67 bool MythMediaDevice::openDevice() … … 98 102 if (!m_SuperMount) 99 103 { 100 104 // Build a command line for mount/unmount and execute it... Is there a better way to do this? 101 MountCommand = QString("%1 %2") 102 .arg((DoMount) ? PATHTO_MOUNT : PATHTO_UNMOUNT) 103 .arg(m_DevicePath); 105 if (QFile(PATHTO_PMOUNT).exists() && QFile(PATHTO_PUMOUNT).exists()) 106 MountCommand = QString("%1 %2") 107 .arg((DoMount) ? PATHTO_PMOUNT : PATHTO_PUMOUNT) 108 .arg(m_DevicePath); 109 else 110 MountCommand = QString("%1 %2") 111 .arg((DoMount) ? PATHTO_MOUNT : PATHTO_UNMOUNT) 112 .arg(m_DevicePath); 104 113 105 114 VERBOSE(VB_ALL, QString("Executing '%1'").arg(MountCommand)); 106 115 if (0 == myth_system(MountCommand)) 107 116 { 108 117 if (DoMount) 109 118 { 119 // we cannot tell beforehand what the pmount mount point is 120 // so verify the mount status of the device 121 isMounted(true); 110 122 m_Status = MEDIASTAT_MOUNTED; 111 123 onDeviceMounted(); 112 124 } … … 213 225 // the disk is not / should not be mounted. 214 226 case MEDIASTAT_ERROR: 215 227 case MEDIASTAT_OPEN: 216 if (MEDIASTAT_MOUNTED == OldStatus)217 unmount();218 break;219 228 case MEDIASTAT_NOTMOUNTED: 220 if ( MEDIASTAT_MOUNTED == OldStatus)229 if (isMounted(true)) 221 230 unmount(); 222 // If we're here it's possible there's unmounted media in the device so try to mount it.223 // The case of no media in the deivce whould be handeled by derived classes and sent224 // as MEDIASTAT_OPEN, MEDISTAT_ERROR or MEDIASTAT_UNKNOWN.225 mount();226 231 break; 227 232 case MEDIASTAT_UNKNOWN: 228 233 case MEDIASTAT_USEABLE: 229 234 case MEDIASTAT_MOUNTED: 235 case MEDIASTAT_UNPLUGGED: 230 236 // get rid of the compiler warning... 231 237 break; 232 238 } -
libs/libmyth/mythmediamonitor.h
48 48 { 49 49 Q_OBJECT 50 50 public: 51 ~MediaMonitor(); 52 51 53 bool addFSTab(void); 54 #ifdef linux 55 bool addPMountable(void); 56 #endif 52 57 void addDevice(MythMediaDevice* pDevice); 53 58 bool addDevice(const char* dev); 54 59 bool addDevice(struct fstab* mep); 60 #ifdef linux 61 bool addSysFSDevice(const QString &dev, bool checkPartitions); 62 bool removeDevice(const QString &dev); 63 void checkUDev(); 64 #endif 55 65 56 66 bool isActive(void) const { return m_Active; } 57 67 void checkDevices(void); 58 68 void startMonitoring(void); 59 69 void stopMonitoring(void); 60 70 QValueList <MythMediaDevice*> getMedias(MediaType mediatype); 71 72 void chooseAndEjectMedia(); 61 73 62 74 static MediaMonitor* getMediaMonitor(); 63 75 … … 70 82 bool m_Active; 71 83 MonitorThread m_Thread; 72 84 bool m_AllowEject; 85 #ifdef linux 86 int fifo; 87 #endif 88 89 private: 90 #ifdef linux 91 QString getDeviceFile(QString sysfs); 92 QStringList getCDROMBlockDevices(); 93 #endif 73 94 }; 74 95 75 96 #endif -
libs/libmyth/mythhdd.h
1 #ifndef MYTHHDD_H 2 #define MYTHHDD_H 3 4 #include "mythmedia.h" 5 6 class MythHDD : public MythMediaDevice 7 { 8 // Q_OBJECT 9 public: 10 MythHDD(QObject* par, const char* DevicePath, bool SuperMount, 11 bool AllowEject); 12 virtual ~MythHDD() {}; 13 14 // Commented out functions are implemented in MythMediaDevice, so can't 15 // be abstract here. 16 17 //virtual MediaError testMedia(void); 18 //virtual bool openDevice(void); 19 virtual MediaStatus checkMedia(void); 20 //virtual MediaError eject(void) = 0; 21 //virtual MediaError lock(void) = 0; 22 //virtual MediaError unlock(void) = 0; 23 24 static MythHDD* get(QObject* par, const char* devicePath, bool SuperMount, 25 bool AllowEject); 26 27 protected: 28 //virtual void onDeviceMounted(); 29 }; 30 31 #endif -
libs/libmyth/mythcdrom.h
19 19 virtual bool checkOK(void) = 0; 20 20 virtual bool openDevice(void); 21 21 virtual MediaStatus checkMedia(void) = 0; 22 //virtual MediaError eject( void) = 0;22 //virtual MediaError eject(bool open_close = true) = 0; 23 23 //virtual MediaError lock(void) = 0; 24 24 //virtual MediaError unlock(void) = 0; 25 25 … … 42 42 virtual bool mediaChanged(void); 43 43 virtual bool checkOK(void); 44 44 virtual MediaStatus checkMedia(void); 45 virtual MediaError eject( void);45 virtual MediaError eject(bool open_close = true); 46 46 virtual MediaError lock(void); 47 47 virtual MediaError unlock(void); 48 48 }; … … 60 60 virtual bool mediaChanged(void); 61 61 virtual bool checkOK(void); 62 62 virtual MediaStatus checkMedia(void); 63 virtual MediaError eject( void);63 virtual MediaError eject(bool open_close = true); 64 64 virtual MediaError lock(void); 65 65 virtual MediaError unlock(void); 66 66 }; -
libs/libmyth/mythdialogs.cpp
234 234 RegisterKey("Global", "7", "7", "7"); 235 235 RegisterKey("Global", "8", "8", "8"); 236 236 RegisterKey("Global", "9", "9", "9"); 237 238 RegisterKey("Global", "EJECT", "Eject Removable Media", "e"); 237 239 } 238 240 239 241 MythMainWindow::~MythMainWindow() … … 1099 1101 } 1100 1102 else if (action == "MENU") 1101 1103 emit menuButtonPressed(); 1104 else if (action == "EJECT") 1105 { 1106 MediaMonitor *mon = MediaMonitor::getMediaMonitor(); 1107 if (mon) 1108 mon->chooseAndEjectMedia(); 1109 } 1102 1110 else 1103 1111 handled = false; 1104 1112 } -
libs/libmyth/libmyth.pro
68 68 } 69 69 70 70 unix { 71 SOURCES += myth cdrom.cpp mythmediamonitor.cpp72 HEADERS += myth cdrom.h mythmediamonitor.h73 inc.files += myth cdrom.h mythmediamonitor.h71 SOURCES += mythhdd.cpp mythcdrom.cpp mythmediamonitor.cpp 72 HEADERS += mythhdd.cpp mythcdrom.h mythmediamonitor.h 73 inc.files += mythhdd.h mythcdrom.h mythmediamonitor.h 74 74 } 75 75 76 76 macx { -
libs/libmyth/mythmediamonitor.cpp
1 1 #include "mythmediamonitor.h" 2 2 #include "mythcdrom.h" 3 #include "mythhdd.h" 3 4 #include <qapplication.h> 5 #include <qprocess.h> 6 #include <qdir.h> 7 #include <qfile.h> 4 8 #include <sys/file.h> 5 9 #include <fcntl.h> 6 10 #include <dirent.h> … … 9 13 #include <iostream> 10 14 #include <sys/types.h> 11 15 #include <sys/stat.h> 16 #include <sys/wait.h> 12 17 #include <unistd.h> 13 18 14 19 #include "config.h" 15 20 #include "mythcontext.h" 21 #include "mythdialogs.h" 16 22 17 23 // For testing 18 24 #if 0 … … 40 46 #endif 41 47 #define SUPER_OPT_DEV "dev=" 42 48 49 #ifndef UDEV_FIFO 50 #define UDEV_FIFO "/tmp/mythtv_media" 51 #endif 52 43 53 using namespace std; 44 54 45 55 MediaMonitor *theMonitor = NULL; … … 53 63 { 54 64 theMonitor = new MediaMonitor(NULL, 500, true); 55 65 theMonitor->addFSTab(); 66 #ifdef linux 67 theMonitor->addPMountable(); 68 #endif 56 69 } 57 70 } 58 71 59 72 return theMonitor; 60 73 } 61 74 75 /** \fn MediaMonitor::chooseAndEjectMedia() 76 * \brief Unmounts and ejects removable media devices. 77 * 78 * If no media devices are known to the MediaMonitor this function does 79 * nothing. If a single device is known, it is unmounted and ejected if 80 * possible. If mulitple devices are known, a popup box is display so the 81 * user can choose which device to eject. 82 */ 83 void MediaMonitor::chooseAndEjectMedia() 84 { 85 MythMediaDevice *selected = NULL; 86 87 if (m_Devices.count() == 1) 88 { 89 selected = m_Devices.first(); 90 } 91 else if (m_Devices.count() > 1) 92 { 93 MythPopupBox ejectbox(gContext->GetMainWindow(), "eject media"); 94 95 ejectbox.addLabel(tr("Select removable media to eject")); 96 97 QValueList <MythMediaDevice *>::Iterator it = m_Devices.begin(); 98 while (it != m_Devices.end()) 99 { 100 if ((*it)->getVolumeID() != "") 101 ejectbox.addButton((*it)->getVolumeID()); 102 else 103 ejectbox.addButton((*it)->getDevicePath()); 104 105 it++; 106 } 107 108 ejectbox.addButton(tr("Cancel"))->setFocus(); 109 110 int ret = ejectbox.ExecPopup(); 111 112 if (ret < (int)m_Devices.count()) 113 selected = m_Devices[ret]; 114 } 115 116 if (selected) 117 { 118 switch (selected->getStatus()) 119 { 120 case MEDIASTAT_OPEN : selected->eject(false); 121 break; 122 case MEDIASTAT_MOUNTED : cerr << "media is mounted" << endl; 123 selected->unmount(); 124 125 if (selected->isMounted(true)) 126 { 127 MythPopupBox::showOkPopup( 128 gContext->GetMainWindow(), 129 "eject unmount fail", 130 QString(tr("Failed unmounting %1")) 131 .arg(selected->getDevicePath())); 132 break; 133 } 134 default : // attempt to unlock and eject media 135 selected->unlock(); 136 if (selected->eject() == MEDIAERR_UNSUPPORTED) 137 { 138 MythPopupBox::showOkPopup( 139 gContext->GetMainWindow(), 140 "eject success", 141 QString(tr("You may safely remove %1")) 142 .arg(selected->getDevicePath())); 143 } 144 else if (selected->eject() == MEDIAERR_FAILED) 145 { 146 MythPopupBox::showOkPopup( 147 gContext->GetMainWindow(), 148 "eject fail", 149 QString(tr("Failed Ejecting %1")) 150 .arg(selected->getDevicePath())); 151 } 152 } 153 } 154 } 155 62 156 // MonitorThread 63 157 MonitorThread::MonitorThread(MediaMonitor* pMon, unsigned long interval) 64 158 : QThread() … … 88 182 m_AllowEject = allowEject; 89 183 m_Active = false; 90 184 m_Thread.setMonitor(this); 185 #ifdef linux 186 fifo = 0; 187 #endif 91 188 } 92 189 190 MediaMonitor::~MediaMonitor() 191 { 192 #ifdef linux 193 if (fifo) 194 { 195 close(fifo); 196 unlink(UDEV_FIFO); 197 } 198 #endif 199 } 200 93 201 // Loop through the file system table and add any supported devices. 94 202 bool MediaMonitor::addFSTab() 95 203 { … … 119 227 return true; 120 228 } 121 229 230 #ifdef linux 231 /** \fn MediaMonitor::addPMountable() 232 * \brief Search /sys/block for valid removable media devices. 233 * 234 * This function creates MediaDevice instances for valid removable media 235 * devices found under the /sys/block filesystem in Linux. CD and DVD 236 * devices are created as MythCDROM instances. MythHDD instances will be 237 * created for each partition on removable hard disc devices, if they exists. 238 * Otherwise a single MythHDD instance will be created for the entire disc. 239 * Floppy discs are ignored. 240 */ 241 bool MediaMonitor::addPMountable() 242 { 243 mkfifo(UDEV_FIFO, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); 244 fifo = open(UDEV_FIFO, O_RDONLY | O_NONBLOCK); 245 246 QDir sysfs("/sys/block"); 247 sysfs.setFilter(QDir::Dirs); 248 249 QStringList devices = sysfs.entryList(); 250 251 for (QStringList::Iterator it = devices.begin(); it != devices.end(); ++it) 252 { 253 if (*it == "." || *it == "..") 254 continue; 255 256 // we don't do floppies. 257 if ((*it).startsWith("fd")) 258 continue; 259 260 sysfs.cd(*it); 261 262 QFile removable(sysfs.absFilePath("removable")); 263 if (removable.exists()) 264 { 265 removable.open(IO_ReadOnly); 266 int c = removable.getch(); 267 removable.close(); 268 269 if (c == '1') 270 addSysFSDevice(sysfs.absPath(), true); 271 } 272 sysfs.cdUp(); 273 } 274 return true; 275 } 276 277 /** \fn MediaMonitor::getDeviceFile(QString) 278 * \brief Returns the device special file associated with the /sys/block node. 279 * \param [in]sysfs sysfs path of removable block device. 280 * \return path to the device special file 281 */ 282 QString MediaMonitor::getDeviceFile(QString sysfs) 283 { 284 QProcess udevinfo(this); 285 udevinfo.addArgument("udevinfo"); 286 udevinfo.addArgument("-q"); 287 udevinfo.addArgument("name"); 288 udevinfo.addArgument("-p"); 289 udevinfo.addArgument(sysfs); 290 udevinfo.setCommunication(QProcess::Stdout); 291 292 udevinfo.start(); 293 294 int status; 295 waitpid(udevinfo.processIdentifier(), &status, 0); 296 297 QString ret = udevinfo.readLineStdout(); 298 if (ret == "device not found in database") 299 return QString::null; 300 else 301 return ret; 302 } 303 304 /** \fn MediaMonitor::getCDROMBlockDevices() 305 * \brief Reads the list devices known to be CD or DVD devices. 306 * \return list of CD and DVD device names. 307 */ 308 QStringList MediaMonitor::getCDROMBlockDevices() 309 { 310 QStringList l; 311 312 QFile file("/proc/sys/dev/cdrom/info"); 313 if (file.open(IO_ReadOnly)) 314 { 315 QTextStream stream(&file); 316 QString line; 317 while (!stream.atEnd()) 318 { 319 line = stream.readLine(); 320 if (line.startsWith("drive name:")) 321 { 322 QString s = line.section('\t', 2, 2); 323 l.append(s); 324 } 325 } 326 file.close(); 327 } 328 return l; 329 } 330 #endif 331 122 332 // Given a media deivce add it to our collection. 123 333 void MediaMonitor::addDevice(MythMediaDevice* pDevice) 124 334 { … … 271 481 return false; 272 482 } 273 483 484 #ifdef linux 485 /** \fn MediaMonitor::addSysFSDevice(const QString &, bool) 486 * \brief Creates MythMedia instances for sysfs removable media devices. 487 * \param [in]dev path to sysfs block device. 488 * \param [in]checkPartitions check for partitions on block device. 489 * \return true if MythMedia instances are created. 490 * 491 * Block devices are represented as directories in sysfs with directories for 492 * each partition underneath the parent device directory. 493 * 494 * This function recursively calls itself to find all partitions on a block 495 * device and creates a MythHDD instance for each partition found. If no 496 * partitions are found and the device is a CD or DVD device a MythCDROM 497 * instance is created. Otherwise a MythHDD instance is created for the 498 * entire block device. 499 */ 500 bool MediaMonitor::addSysFSDevice(const QString &dev, bool checkPartitions) 501 { 502 if (checkPartitions) 503 { 504 // check for partitions 505 QDir sysfs(dev); 506 sysfs.setFilter(QDir::Dirs); 507 508 bool found_partitions = false; 509 QStringList parts = sysfs.entryList(); 510 for (QStringList::Iterator pit = parts.begin(); 511 pit != parts.end(); pit++) 512 { 513 if (*pit == "." || *pit == "..") 514 continue; 515 516 found_partitions |= addSysFSDevice(sysfs.absFilePath(*pit), false); 517 } 518 519 // no partitions on block device, use main device 520 if (!found_partitions) 521 found_partitions |= addSysFSDevice(sysfs.absPath(), false); 522 523 return found_partitions; 524 } 525 else 526 { 527 QStringList cdroms = getCDROMBlockDevices(); 528 529 if (cdroms.contains(dev.section('/', -1))) 530 { 531 // found cdrom device 532 QString device_file = getDeviceFile(dev); 533 if (!device_file.isNull()) 534 { 535 device_file.prepend("/dev/"); 536 //cerr << "cdrom: " << device_file.ascii() << endl; 537 538 addDevice(MythCDROM::get(this, device_file, false, m_AllowEject)); 539 return true; 540 } 541 } 542 else 543 { 544 // found block or partition device 545 QString device_file = getDeviceFile(dev); 546 if (!device_file.isNull()) 547 { 548 device_file.prepend("/dev/"); 549 //cerr << "block: " << device_file.ascii() << endl; 550 551 addDevice(MythHDD::get(this, device_file, false, false)); 552 553 return true; 554 } 555 } 556 } 557 return false; 558 } 559 560 /** \fn MediaMonitor::removeDevice(const QString &) 561 * \brief Remove a device from the media monitor. 562 * \param [in]dev path to device special file to remove. 563 * \return true if device is removed from the Media Monitor. 564 * 565 * This function is usually called after a hotpluggable device is unplugged. 566 */ 567 bool MediaMonitor::removeDevice(const QString &dev) 568 { 569 QValueList<MythMediaDevice*>::iterator it; 570 for (it = m_Devices.begin(); it != m_Devices.end(); it++) 571 { 572 if ((*it)->getDevicePath() == dev) 573 { 574 m_Devices.remove(it); 575 //cerr << "remove device: " << dev.ascii() << endl; 576 return true; 577 } 578 } 579 return false; 580 } 581 582 /** \fn MediaMonitor::checkUDev() 583 * \brief Checks the named pipe, UDEV_FIFO, for hotplug events from the udev system. 584 */ 585 void MediaMonitor::checkUDev() 586 { 587 char buffer[256]; 588 QString qBuffer; 589 590 if (fifo) 591 { 592 int size = read(fifo, buffer, 255); 593 while (size > 0) 594 { 595 // append buffer to QString 596 buffer[size] = '\0'; 597 598 qBuffer.append(buffer); 599 600 size = read(fifo, buffer, 255); 601 } 602 QStringList devs = QStringList::split('\n', qBuffer); 603 604 for (QStringList::Iterator it = devs.begin(); it != devs.end(); it++) 605 { 606 if ((*it).startsWith("add")) 607 { 608 QString dev = (*it).section(' ', 1, 1); 609 610 // check if removeable 611 QFile removable(dev + "/removable"); 612 if (removable.exists()) 613 { 614 removable.open(IO_ReadOnly); 615 int c = removable.getch(); 616 removable.close(); 617 618 if (c == '1') 619 addSysFSDevice((*it).section(' ', 1, 1), true); 620 } 621 } 622 else if ((*it).startsWith("remove")) 623 { 624 removeDevice((*it).section(' ', 2, 2)); 625 } 626 } 627 } 628 } 629 #endif 630 274 631 // Poll the devices in our list. 275 632 void MediaMonitor::checkDevices() 276 633 { 634 #ifdef linux 635 /* check if new devices have been plugged in */ 636 checkUDev(); 637 #endif 638 277 639 QValueList<MythMediaDevice*>::iterator itr = m_Devices.begin(); 278 640 MythMediaDevice* pDev; 279 641 while (itr != m_Devices.end()) … … 317 679 pDev = *itr; 318 680 if ((pDev->getMediaType()==mediatype) && 319 681 ((pDev->getStatus()==MEDIASTAT_USEABLE) || 320 (pDev->getStatus()==MEDIASTAT_MOUNTED))) 682 (pDev->getStatus()==MEDIASTAT_MOUNTED) || 683 (pDev->getStatus()==MEDIASTAT_NOTMOUNTED))) 321 684 medias.push_back(pDev); 322 685 itr++; 323 686 } … … 345 708 new MediaEvent(oldStatus, pMedia)); 346 709 } 347 710 } 711 -
libs/libmyth/mythhdd.cpp
1 #include "mythhdd.h" 2 3 #include <iostream> 4 5 /** \fn MythHDD::get(QObject*, const char*, bool, bool) 6 * \brief Helper function used to create a new instance of a hard disc device. 7 * \param [in]devicePath path to the device special file representing the device. 8 * \return new MythHDD instance. 9 */ 10 MythHDD *MythHDD::get(QObject* par, const char* devicePath, bool SuperMount, 11 bool AllowEject) 12 { 13 return new MythHDD(par, devicePath, SuperMount, AllowEject); 14 } 15 16 /** \fn MythHDD::MythHDD(QObject *, const char *, bool, bool) 17 * \brief Creates a new instance of a hard disc device. 18 * \param [in]DevicePath path to the device special file representing the device. 19 * \return new MythHDD instance. 20 */ 21 MythHDD::MythHDD(QObject *par, const char *DevicePath, bool SuperMount, 22 bool AllowEject) 23 : MythMediaDevice(par, DevicePath, SuperMount, AllowEject) 24 { 25 m_Status = MEDIASTAT_UNPLUGGED; 26 m_MediaType = MEDIATYPE_DATA; // default type is data 27 } 28 29 /** \fn MythHDD::checkMedia() 30 * \brief Checks the status of this media device. 31 */ 32 MediaStatus MythHDD::checkMedia() 33 { 34 if (isMounted(true)) 35 { 36 // device is mounted, trigger event 37 //std::cerr << "status -> mounted" << std::endl; 38 return setStatus(MEDIASTAT_MOUNTED); 39 } 40 else 41 { 42 // device is not mounted 43 if (m_Status == MEDIASTAT_UNPLUGGED) 44 { 45 // a removable device was just plugged in try to mount it. 46 mount(); 47 if (isMounted(true)) 48 { 49 m_Status = MEDIASTAT_NOTMOUNTED; 50 return setStatus(MEDIASTAT_MOUNTED); 51 } 52 else 53 return setStatus(MEDIASTAT_NOTMOUNTED); 54 } 55 else if (m_Status == MEDIASTAT_MOUNTED) 56 { 57 // device was mounted and someone unmounted it. 58 // set its status to NOTMOUNTED */ 59 //std::cerr << "status -> useable (via unmount)" << std::endl; 60 return m_Status = setStatus(MEDIASTAT_NOTMOUNTED); 61 } 62 else 63 { 64 // leave device state as is 65 return m_Status; 66 } 67 } 68 } -
libs/libmyth/mythcdrom-linux.cpp
8 8 9 9 #define ASSUME_WANT_AUDIO 1 10 10 11 MediaError MythCDROMLinux::eject( )11 MediaError MythCDROMLinux::eject(bool open_close) 12 12 { 13 return (ioctl(m_DeviceHandle, CDROMEJECT) == 0) ? MEDIAERR_OK : 14 MEDIAERR_FAILED; 13 if (open_close) 14 return (ioctl(m_DeviceHandle, CDROMEJECT) == 0) ? MEDIAERR_OK : 15 MEDIAERR_FAILED; 16 else 17 return (ioctl(m_DeviceHandle, CDROMCLOSETRAY) == 0) ? MEDIAERR_OK : 18 MEDIAERR_FAILED; 15 19 } 16 20 17 21 bool MythCDROMLinux::mediaChanged() … … 85 89 { 86 90 case CDS_DISC_OK: 87 91 //cout << "disk ok - "; 88 if (isMounted(true)) 89 //cout << "it's mounted" << endl; 92 // If the disc is ok and we already know it's mediatype 93 // returns MOUNTED. 94 if (isMounted(true) && m_MediaType != MEDIATYPE_UNKNOWN) 90 95 return setStatus(MEDIASTAT_MOUNTED, OpenedHere); 91 96 // If the disk is ok but not yet mounted we'll test it further down after this switch exits. 92 97 break; … … 110 115 if (mediaChanged()) 111 116 { 112 117 //cout << "media changed - "; 113 // Regardless of the actual status lie here and say it's open for now, so we can over the case of a missed open.118 // Regardless of the actual status lie here and say it's open for now, so we can cover the case of a missed open. 114 119 return setStatus(MEDIASTAT_OPEN, OpenedHere); 115 120 } 116 121 else … … 136 141 this->m_KeyID = QString("%1%2") 137 142 .arg(this->m_VolumeID) 138 143 .arg(QString(buf.creation_date).left(16)); 139 // We'll return NOTMOUNTED here because we're switching media. 140 // The base class will try to mount the deivce causing the next pass to pick up the MOUNTED status. 141 return setStatus(MEDIASTAT_NOTMOUNTED, OpenedHere); 144 145 // attempt to mount the disc 146 // the base class's onDeviceMounted will do fine 147 // grained detection of the type of data on this disc 148 mount(); 149 150 if (isMounted(true)) 151 { 152 // pretend we're NOTMOUNTED so setStatus emits 153 // a signal 154 m_Status = MEDIASTAT_NOTMOUNTED; 155 return setStatus(MEDIASTAT_MOUNTED, OpenedHere); 156 } 157 else 158 return setStatus(MEDIASTAT_NOTMOUNTED, OpenedHere); 142 159 break; 143 160 case CDS_AUDIO: 144 161 //cout << "found an audio disk" << endl; … … 154 171 return setStatus(MEDIASTAT_USEABLE, OpenedHere); 155 172 #else 156 173 mount(); 157 return setStatus(MEDIASTAT_NOTMOUNTED, OpenedHere); 174 if (isMounted(true)) 175 { 176 // pretend we're NOTMOUNTED so setStatus 177 // emits a signal 178 m_Status = MEDIASTAT_NOTMOUNTED; 179 return setStatus(MEDIASTAT_MOUNTED, OpenedHere); 180 } 181 else 182 return setStatus(MEDIASTAT_USEABLE, OpenedHere); 158 183 #endif 159 184 break; 160 185 case CDS_NO_INFO: … … 174 199 m_Status == MEDIASTAT_NOTMOUNTED) 175 200 { 176 201 //cout << "current status == " << MythMediaDevice::MediaStatusStrings[m_Status] << " setting status to not mounted - "; 177 setStatus(MEDIASTAT_NOTMOUNTED, OpenedHere); 202 if (isMounted(true)) 203 setStatus(MEDIASTAT_MOUNTED, OpenedHere); 204 else 205 setStatus(MEDIASTAT_NOTMOUNTED, OpenedHere); 178 206 } 179 207 180 208 if (m_AllowEject) -
libs/libmyth/mythcdrom-freebsd.cpp
7 7 8 8 #define ASSUME_WANT_AUDIO 1 9 9 10 MediaError MythCDROMFreeBSD::eject( )10 MediaError MythCDROMFreeBSD::eject(bool open_close) 11 11 { 12 if (ioctl(m_DeviceHandle, CDIOCEJECT) == 0) 13 return MEDIAERR_OK; 14 return MEDIAERR_FAILED; 12 if (open_close) 13 return (ioctl(m_DeviceHandle, CDIOCEJECT) == 0) ? MEDIAERR_OK : 14 MEDIAERR_FAILED; 15 else 16 return MEDIAERR_UNSUPPORTED; 15 17 } 16 18 17 19 bool MythCDROMFreeBSD::mediaChanged() -
libs/libmyth/mythmedia.h
7 7 typedef enum { 8 8 MEDIASTAT_ERROR, 9 9 MEDIASTAT_UNKNOWN, 10 MEDIASTAT_UNPLUGGED, 10 11 MEDIASTAT_OPEN, 11 12 MEDIASTAT_USEABLE, 12 13 MEDIASTAT_NOTMOUNTED, … … 65 66 virtual bool openDevice(); 66 67 virtual bool closeDevice(); 67 68 virtual MediaStatus checkMedia() = 0; // Derived classes MUST implement this. 68 virtual MediaError eject( ) { return MEDIAERR_UNSUPPORTED; }69 virtual MediaError eject(bool open_close = true) { return MEDIAERR_UNSUPPORTED; } 69 70 virtual MediaError lock(); 70 71 virtual MediaError unlock(); 71 72 virtual bool performMountCmd( bool DoMount ); -
contrib/mythtv_media_monitor.sh
1 #!/bin/sh -e 2 3 MYTH_FIFO=/tmp/mythtv_media 4 5 if [ -p $MYTH_FIFO ]; then 6 echo $ACTION /sys$DEVPATH $DEVNAME > $MYTH_FIFO 7 fi -
contrib/mythtv.rules
1 2 SUBSYSTEM="block", RUN+="/etc/udev/scripts/mythtv.sh"