From cd3c6e46ceec12447e08b108ea5bcce410b821dd Mon Sep 17 00:00:00 2001 From: NicoHood Date: Sat, 6 Feb 2016 12:37:19 +0100 Subject: [PATCH 1/2] Treat data partition special - If the item has "data partition" in it, do not allow it to be installed alone. Closes #103 - If the first partition is not a FAT partition, treat it as not bootable. Do not show it in the boot menu, and do not write config.txt to it. Closes #102 Adapted from 843059136100b780d73407e571aee0083deb2722 https://github.com/raspberrypi/noobs/commit/843059136100b780d73407e571aee0083deb2722#diff-7bd3a48ac1bcbb236a941bd9c1b24587 --- recovery/mainwindow.cpp | 14 ++++++++++--- recovery/multiimagewritethread.cpp | 32 ++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/recovery/mainwindow.cpp b/recovery/mainwindow.cpp index 4245713d..b2e8d5c3 100644 --- a/recovery/mainwindow.cpp +++ b/recovery/mainwindow.cpp @@ -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() @@ -1290,6 +1292,7 @@ void MainWindow::updateNeeded() bool enableOk = false; QColor colorNeededLabel = Qt::black; bool bold = false; + bool datapartition = false; _neededMB = 0; QList selected = selectedItems(); @@ -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))); @@ -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; } } diff --git a/recovery/multiimagewritethread.cpp b/recovery/multiimagewritethread.cpp index db6085bb..4e8fdc9b 100644 --- a/recovery/multiimagewritethread.cpp +++ b/recovery/multiimagewritethread.cpp @@ -362,6 +362,11 @@ bool MultiImageWriteThread::processImage(OsInfo *image) qDebug() << "Processing OS:" << os_name; QList *partitions = image->partitions(); + if (partitions->isEmpty()) + { + emit error(tr("No partitions defined in partitions.json")); + return false; + } foreach (PartitionInfo *p, *partitions) { @@ -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) @@ -473,6 +469,21 @@ bool MultiImageWriteThread::processImage(OsInfo *image) QString language = settings.value("language", "en").toString(); QString keyboard = settings.value("keyboard_layout", "gb").toString(); + 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) + { + emit error(tr("%1: Error mounting file system").arg(os_name)); + return false; + } + + emit statusUpdate(tr("%1: Creating os_config.json").arg(os_name)); + QVariantMap qm; qm.insert("flavour", image->flavour()); qm.insert("release_date", image->releaseDate()); @@ -558,6 +569,7 @@ bool MultiImageWriteThread::processImage(OsInfo *image) { emit error(tr("%1: Error unmounting").arg(os_name)); } + } /* Save information about installed operating systems in installed_os.json */ QVariantMap ventry; @@ -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)) From bf668013eaa0b23b6880eed5d6e5df910239503d Mon Sep 17 00:00:00 2001 From: NicoHood Date: Sat, 6 Feb 2016 14:12:45 +0100 Subject: [PATCH 2/2] Indent code correct after data partition fix To get a better overview of the changes, this commit only indent the lines correct after the previous commit added a new if level. --- recovery/multiimagewritethread.cpp | 154 ++++++++++++++--------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/recovery/multiimagewritethread.cpp b/recovery/multiimagewritethread.cpp index 4e8fdc9b..06f762e3 100644 --- a/recovery/multiimagewritethread.cpp +++ b/recovery/multiimagewritethread.cpp @@ -484,91 +484,91 @@ bool MultiImageWriteThread::processImage(OsInfo *image) emit statusUpdate(tr("%1: Creating os_config.json").arg(os_name)); - 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) + 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)) { - 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 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; + qDebug() << "part" << part << uuid << label; - args << "part"+nr+"="+part << "id"+nr+"="+id; - env.insert("part"+nr, part); - env.insert("id"+nr, id); - pnr++; - } + 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(); + 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; + 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 */