Skip to content
This repository has been archived by the owner on Feb 27, 2023. It is now read-only.

Treat data partition special #306

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions recovery/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,9 @@ void MainWindow::onQuery(const QString &msg, const QString &title, QMessageBox::
void MainWindow::on_list_currentRowChanged()
{
QListWidgetItem *item = ui->list->currentItem();
ui->actionEdit_config->setEnabled(item && item->data(Qt::UserRole).toMap().contains("partitions"));
ui->actionEdit_config->setEnabled(item
&& item->data(Qt::UserRole).toMap().contains("partitions")
&& item->data(Qt::UserRole).toMap().value("bootable", true) == true );
}

void MainWindow::update_window_title()
Expand Down Expand Up @@ -1290,6 +1292,7 @@ void MainWindow::updateNeeded()
bool enableOk = false;
QColor colorNeededLabel = Qt::black;
bool bold = false;
bool datapartition = false;

_neededMB = 0;
QList<QListWidgetItem *> selected = selectedItems();
Expand All @@ -1305,6 +1308,10 @@ void MainWindow::updateNeeded()
int startSector = getFileContents("/sys/class/block/mmcblk0p2/start").trimmed().toULongLong();
_neededMB += (RISCOS_SECTOR_OFFSET - startSector)/2048;
}
if (entry.value("name").toString().contains("data partition", Qt::CaseInsensitive))
{
datapartition = true;
}
}

ui->neededLabel->setText(QString("%1: %2 MB").arg(tr("Needed"), QString::number(_neededMB)));
Expand All @@ -1318,9 +1325,10 @@ void MainWindow::updateNeeded()
}
else
{
if (_neededMB)
if (_neededMB && !(datapartition && selected.count() == 1))
{
/* Enable OK button if a selection has been made that fits on the card */
/* Enable OK button if a selection has been made that fits on the card
and it is not only the data partition that has been selected */
enableOk = true;
}
}
Expand Down
182 changes: 97 additions & 85 deletions recovery/multiimagewritethread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,11 @@ bool MultiImageWriteThread::processImage(OsInfo *image)
qDebug() << "Processing OS:" << os_name;

QList<PartitionInfo *> *partitions = image->partitions();
if (partitions->isEmpty())
{
emit error(tr("No partitions defined in partitions.json"));
return false;
}

foreach (PartitionInfo *p, *partitions)
{
Expand Down Expand Up @@ -453,15 +458,6 @@ bool MultiImageWriteThread::processImage(OsInfo *image)
_part++;
}

emit statusUpdate(tr("%1: Mounting FAT partition").arg(os_name));
if (QProcess::execute("mount "+partitions->first()->partitionDevice()+" /mnt2") != 0)
{
emit error(tr("%1: Error mounting file system").arg(os_name));
return false;
}

emit statusUpdate(tr("%1: Creating os_config.json").arg(os_name));

QString description = getDescription(image->folder(), image->flavour());
QVariantList vpartitions;
foreach (PartitionInfo *p, *partitions)
Expand All @@ -473,90 +469,106 @@ bool MultiImageWriteThread::processImage(OsInfo *image)
QString language = settings.value("language", "en").toString();
QString keyboard = settings.value("keyboard_layout", "gb").toString();

QVariantMap qm;
qm.insert("flavour", image->flavour());
qm.insert("release_date", image->releaseDate());
qm.insert("imagefolder", image->folder());
qm.insert("description", description);
qm.insert("videomode", videomode);
qm.insert("partitions", vpartitions);
qm.insert("language", language);
qm.insert("keyboard", keyboard);

Json::saveToFile("/mnt2/os_config.json", qm);

emit statusUpdate(tr("%1: Saving display mode to config.txt").arg(os_name));
patchConfigTxt();

/* Partition setup script can either reside in the image folder
* or inside the boot partition tarball */
QString postInstallScript = image->folder()+"/partition_setup.sh";
if (!QFile::exists(postInstallScript))
postInstallScript = "/mnt2/partition_setup.sh";

if (QFile::exists(postInstallScript))
{
emit statusUpdate(tr("%1: Running partition setup script").arg(os_name));
QProcess proc;
QProcessEnvironment env;
QStringList args(postInstallScript);
env.insert("PATH", "/bin:/usr/bin:/sbin:/usr/sbin");

/* - Parameters to the partition-setup script are supplied both as
* command line parameters and set as environement variables
* - Boot partition is mounted, working directory is set to its mnt folder
*
* partition_setup.sh part1=/dev/mmcblk0p3 id1=LABEL=BOOT part2=/dev/mmcblk0p4
* id2=UUID=550e8400-e29b-41d4-a716-446655440000
*/
int pnr = 1;
foreach (PartitionInfo *p, *partitions)
QByteArray fstypeFirstPartition = partitions->first()->fsType();
bool firstPartitionIsFat = (fstypeFirstPartition == "FAT" || fstypeFirstPartition == "fat");
bool firstPartitionIsBootable = image->bootable() && firstPartitionIsFat;

if (firstPartitionIsBootable)
{
emit statusUpdate(tr("%1: Mounting FAT partition").arg(os_name));
if (QProcess::execute("mount "+partitions->first()->partitionDevice()+" /mnt2") != 0)
{
QString part = p->partitionDevice();
QString nr = QString::number(pnr);
QString uuid = getUUID(part);
QString label = getLabel(part);
QString id;
if (!label.isEmpty())
id = "LABEL="+label;
else
id = "UUID="+uuid;
emit error(tr("%1: Error mounting file system").arg(os_name));
return false;
}

qDebug() << "part" << part << uuid << label;
emit statusUpdate(tr("%1: Creating os_config.json").arg(os_name));

args << "part"+nr+"="+part << "id"+nr+"="+id;
env.insert("part"+nr, part);
env.insert("id"+nr, id);
pnr++;
}
QVariantMap qm;
qm.insert("flavour", image->flavour());
qm.insert("release_date", image->releaseDate());
qm.insert("imagefolder", image->folder());
qm.insert("description", description);
qm.insert("videomode", videomode);
qm.insert("partitions", vpartitions);
qm.insert("language", language);
qm.insert("keyboard", keyboard);

qDebug() << "Executing: sh" << args;
qDebug() << "Env:" << env.toStringList();
proc.setProcessChannelMode(proc.MergedChannels);
proc.setProcessEnvironment(env);
proc.setWorkingDirectory("/mnt2");
proc.start("/bin/sh", args);
proc.waitForFinished(-1);
qDebug() << proc.exitStatus();
Json::saveToFile("/mnt2/os_config.json", qm);

if (proc.exitCode() != 0)
emit statusUpdate(tr("%1: Saving display mode to config.txt").arg(os_name));
patchConfigTxt();

/* Partition setup script can either reside in the image folder
* or inside the boot partition tarball */
QString postInstallScript = image->folder()+"/partition_setup.sh";
if (!QFile::exists(postInstallScript))
postInstallScript = "/mnt2/partition_setup.sh";

if (QFile::exists(postInstallScript))
{
emit error(tr("%1: Error executing partition setup script").arg(os_name)+"\n"+proc.readAll());
return false;
emit statusUpdate(tr("%1: Running partition setup script").arg(os_name));
QProcess proc;
QProcessEnvironment env;
QStringList args(postInstallScript);
env.insert("PATH", "/bin:/usr/bin:/sbin:/usr/sbin");

/* - Parameters to the partition-setup script are supplied both as
* command line parameters and set as environement variables
* - Boot partition is mounted, working directory is set to its mnt folder
*
* partition_setup.sh part1=/dev/mmcblk0p3 id1=LABEL=BOOT part2=/dev/mmcblk0p4
* id2=UUID=550e8400-e29b-41d4-a716-446655440000
*/
int pnr = 1;
foreach (PartitionInfo *p, *partitions)
{
QString part = p->partitionDevice();
QString nr = QString::number(pnr);
QString uuid = getUUID(part);
QString label = getLabel(part);
QString id;
if (!label.isEmpty())
id = "LABEL="+label;
else
id = "UUID="+uuid;

qDebug() << "part" << part << uuid << label;

args << "part"+nr+"="+part << "id"+nr+"="+id;
env.insert("part"+nr, part);
env.insert("id"+nr, id);
pnr++;
}

qDebug() << "Executing: sh" << args;
qDebug() << "Env:" << env.toStringList();
proc.setProcessChannelMode(proc.MergedChannels);
proc.setProcessEnvironment(env);
proc.setWorkingDirectory("/mnt2");
proc.start("/bin/sh", args);
proc.waitForFinished(-1);
qDebug() << proc.exitStatus();

if (proc.exitCode() != 0)
{
emit error(tr("%1: Error executing partition setup script").arg(os_name)+"\n"+proc.readAll());
return false;
}
}
}

PartitionInfo *p = partitions->first();
if (!p->bcdFile().isEmpty())
{
emit statusUpdate(tr("%1: Patching BCD file").arg(os_name));
patchBcdFile("/mnt2/"+p->bcdFile(), p->bcdDiskId(), p->bcdEfiSector(), p->bcdMainSector() );
}
PartitionInfo *p = partitions->first();
if (!p->bcdFile().isEmpty())
{
emit statusUpdate(tr("%1: Patching BCD file").arg(os_name));
patchBcdFile("/mnt2/"+p->bcdFile(), p->bcdDiskId(), p->bcdEfiSector(), p->bcdMainSector() );
}

emit statusUpdate(tr("%1: Unmounting FAT partition").arg(os_name));
if (QProcess::execute("umount /mnt2") != 0)
{
emit error(tr("%1: Error unmounting").arg(os_name));
emit statusUpdate(tr("%1: Unmounting FAT partition").arg(os_name));
if (QProcess::execute("umount /mnt2") != 0)
{
emit error(tr("%1: Error unmounting").arg(os_name));
}
}

/* Save information about installed operating systems in installed_os.json */
Expand All @@ -566,7 +578,7 @@ bool MultiImageWriteThread::processImage(OsInfo *image)
ventry["folder"] = image->folder();
ventry["release_date"]= image->releaseDate();
ventry["partitions"] = vpartitions;
ventry["bootable"] = image->bootable();
ventry["bootable"] = firstPartitionIsBootable;
QString iconfilename = image->folder()+"/"+image->flavour()+".png";
iconfilename.replace(" ", "_");
if (QFile::exists(iconfilename))
Expand Down