FS#10100: Wait for the system to remount the player after bootloader installation.

OS X requires to unmount the player during bootloader installation on Sansas / Ipods. The system remounts the player automatically after a short while.
Not waiting for the system to remount the player will result in a changed mount point, making the small / full install write the main build to the wrong
 location.
This currently waits up to 60 seconds for the player to get remounted until it errors out. This value seems to be sufficient, if it's not please report
so we can adjust it. Also, the waiting can't be interrupted right now.



git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23716 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dominik Riebeling 2009-11-22 22:13:25 +00:00
parent 46e56582b0
commit 38dde55c27
7 changed files with 116 additions and 7 deletions

View File

@ -26,7 +26,6 @@
#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
#include <stdio.h>
#include <usb.h>
#endif
#if defined(Q_OS_LINUX)
#include <mntent.h>

View File

@ -23,6 +23,12 @@
#include "bootloaderinstallbase.h"
#include "utils.h"
#if defined(Q_OS_MACX)
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#endif
BootloaderInstallBase::BootloaderType BootloaderInstallBase::installed(void)
{
return BootloaderUnknown;
@ -189,6 +195,52 @@ QString BootloaderInstallBase::postinstallHints(QString model)
}
#if defined(Q_OS_MACX)
void BootloaderInstallBase::waitRemount()
{
m_remountTries = 600;
emit logItem(tr("Waiting for system to remount player"), LOGINFO);
QTimer::singleShot(100, this, SLOT(checkRemount()));
}
#endif
void BootloaderInstallBase::checkRemount()
{
#if defined(Q_OS_MACX)
if(m_remountTries--) {
int status = 0;
// check if device has been remounted
QCoreApplication::processEvents();
int num;
struct statfs *mntinf;
num = getmntinfo(&mntinf, MNT_WAIT);
while(num--) {
if(QString(mntinf->f_mntfromname).startsWith(m_remountDevice)
&& QString(mntinf->f_fstypename).contains("msdos", Qt::CaseInsensitive))
status = 1;
mntinf++;
}
if(!status) {
// still not remounted, restart timer.
QTimer::singleShot(500, this, SLOT(checkRemount()));
qDebug() << "player not remounted yet" << m_remountDevice;
}
else {
emit logItem(tr("Player remounted"), LOGINFO);
emit remounted(true);
}
}
else {
emit logItem(tr("Timeout on remount"), LOGERROR);
emit remounted(false);
}
#endif
}
//! @brief set list of possible bootloader files and pick the existing one.
//! @param sl list of possible bootloader files.
void BootloaderInstallBase::setBlFile(QStringList sl)

View File

@ -74,6 +74,10 @@ class BootloaderInstallBase : public QObject
void downloadReqFinished(int id, bool error);
void downloadBlFinish(bool error);
void installBlfile(void);
// NOTE: we need to keep this slot even on targets that don't need it
// -- using the preprocessor here confused moc.
void checkRemount(void);
protected:
enum LogMode
{ LogAdd, LogRemove };
@ -88,11 +92,22 @@ class BootloaderInstallBase : public QObject
QTemporaryFile m_tempfile; //! temporary file for download
QDateTime m_blversion; //! download timestamp used for version information
QString m_offile; //! path to the offile
#if defined(Q_OS_MACX)
void waitRemount(void);
int m_remountTries;
QString m_remountDevice;
#endif
signals:
void downloadDone(void); //! internal signal sent when download finished.
void done(bool);
void logItem(QString, int); //! set logger item
void logProgress(int, int); //! set progress bar.
// NOTE: we need to keep this signal even on targets that don't need it
// -- using the preprocessor here confused moc.
void remounted(bool);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(BootloaderInstallBase::Capabilities)

View File

@ -129,10 +129,14 @@ void BootloaderInstallIpod::installStage2(void)
m_tempfile.close();
if(add_bootloader(&ipod, blfile.toLatin1().data(), FILETYPE_DOT_IPOD) == 0) {
emit logItem(tr("Successfull added bootloader"), LOGOK);
logInstall(LogAdd);
emit done(false);
ipod_close(&ipod);
return;
#if defined(Q_OS_MACX)
m_remountDevice = ipod.diskname;
connect(this, SIGNAL(remounted(bool)), this, SLOT(installStage3(bool)));
waitRemount();
#else
installStage3(true);
#endif
}
else {
emit logItem(tr("Failed to add bootloader"), LOGERROR);
@ -140,6 +144,21 @@ void BootloaderInstallIpod::installStage2(void)
emit done(true);
return;
}
}
void BootloaderInstallIpod::installStage3(bool mounted)
{
if(mounted) {
logInstall(LogAdd);
emit logItem(tr("Bootloader Installation complete."), LOGINFO);
emit done(false);
return;
}
else {
emit logItem(tr("Writing log aborted"), LOGERROR);
emit done(true);
}
qDebug() << "[BootloaderInstallIpod] version installed:" << m_blversion.toString(Qt::ISODate);
}
@ -248,6 +267,8 @@ bool BootloaderInstallIpod::ipodInitialize(struct ipod_t *ipod)
}
else {
ipod_scan(ipod);
qDebug() << "[BootloaderInstallIpod] ipodpatcher: scanning, found device"
<< ipod->diskname;
}
if(ipod_open(ipod, 0) < 0) {
emit logItem(tr("Could not open Ipod"), LOGERROR);

View File

@ -40,6 +40,7 @@ class BootloaderInstallIpod : public BootloaderInstallBase
private slots:
void installStage2(void);
void installStage3(bool mounted);
private:
bool ipodInitialize(struct ipod_t *);

View File

@ -134,10 +134,14 @@ void BootloaderInstallSansa::installStage2(void)
if(sansa_add_bootloader(&sansa, blfile.toLatin1().data(),
FILETYPE_MI4) == 0) {
emit logItem(tr("Successfully installed bootloader"), LOGOK);
logInstall(LogAdd);
emit done(false);
sansa_close(&sansa);
return;
#if defined(Q_OS_MACX)
m_remountDevice = sansa.diskname;
connect(this, SIGNAL(remounted(bool)), this, SLOT(installStage3(bool)));
waitRemount();
#else
installStage3(true);
#endif
}
else {
emit logItem(tr("Failed to install bootloader"), LOGERROR);
@ -149,6 +153,22 @@ void BootloaderInstallSansa::installStage2(void)
}
void BootloaderInstallSansa::installStage3(bool mounted)
{
if(mounted) {
logInstall(LogAdd);
emit logItem(tr("Bootloader Installation complete."), LOGINFO);
emit done(false);
return;
}
else {
emit logItem(tr("Writing log aborted"), LOGERROR);
emit done(true);
}
qDebug() << "version installed:" << m_blversion.toString(Qt::ISODate);
}
/** Uninstall the bootloader.
*/
bool BootloaderInstallSansa::uninstall(void)

View File

@ -42,6 +42,7 @@ class BootloaderInstallSansa : public BootloaderInstallBase
private slots:
void installStage2(void);
void installStage3(bool);
};