diff --git a/selfdrive/ui/qt/widgets/external_storage.cc b/selfdrive/ui/qt/widgets/external_storage.cc index ab2edca541..0f90e2652f 100644 --- a/selfdrive/ui/qt/widgets/external_storage.cc +++ b/selfdrive/ui/qt/widgets/external_storage.cc @@ -27,8 +27,6 @@ ExternalStorageControl::ExternalStorageControl() : unmountStorage(); } else if (text() == tr("FORMAT")) { if (ConfirmationDialog::confirm(tr("Are you sure you want to format this drive? This will erase all data."), tr("Format"), this)) { - setText(tr("formatting")); - setEnabled(false); formatStorage(); } } @@ -37,55 +35,54 @@ ExternalStorageControl::ExternalStorageControl() : } void ExternalStorageControl::refresh() { - bool isMounted = isStorageMounted(); - bool hasFilesystem = isFilesystemPresent(); - QString storageInfo = ""; + QProcess *mntCheck = new QProcess(this); + connect(mntCheck, static_cast(&QProcess::finished), this, [=](int, QProcess::ExitStatus) { + bool isMounted = !mntCheck->readAllStandardOutput().trimmed().isEmpty(); + mntCheck->deleteLater(); - if (isMounted) { - QProcess process; - process.start("sh", QStringList() << "-c" << "df -h /mnt/external_realdata | awk 'NR==2 {print $3 \"/\" $2}'"); - process.waitForFinished(); - storageInfo = process.readAllStandardOutput().trimmed(); - } + QProcess *fsCheck = new QProcess(this); + connect(fsCheck, static_cast(&QProcess::finished), this, [=](int, QProcess::ExitStatus) { + bool hasFs = fsCheck->exitCode() == 0; + fsCheck->deleteLater(); - if (!hasFilesystem) { - setValue(tr("insert drive")); - setText(tr("CHECK")); - } else if (!isDriveInitialized()) { - setValue(tr("needs format")); - setText(tr("FORMAT")); - } else if (isMounted) { - setValue(storageInfo); - setText(tr("UNMOUNT")); - } else { - setValue(tr("")); - setText(tr("MOUNT")); - } + if (!hasFs) { + setValue(tr("insert drive")); + setText(tr("CHECK")); + setEnabled(true); + return; + } - setEnabled(true); -} + QProcess *labelCheck = new QProcess(this); + connect(labelCheck, static_cast(&QProcess::finished), this, [=](int, QProcess::ExitStatus) { + bool isInit = labelCheck->exitCode() == 0; + labelCheck->deleteLater(); -bool ExternalStorageControl::isStorageMounted() { - QProcess process; - process.start("sh", QStringList() << "-c" << "findmnt -n /mnt/external_realdata"); - process.waitForFinished(); + if (!isInit) { + setValue(tr("needs format")); + setText(tr("FORMAT")); + } else if (isMounted) { + QProcess *usage = new QProcess(this); + connect(usage, static_cast(&QProcess::finished), this, [=](int, QProcess::ExitStatus) { + QString info = usage->readAllStandardOutput().trimmed(); + setValue(info); + setText(tr("UNMOUNT")); + usage->deleteLater(); + setEnabled(true); + }); + usage->start("sh", QStringList() << "-c" << "df -h /mnt/external_realdata | awk 'NR==2 {print $3 \"/\" $2}'"); + return; + } else { + setValue(""); + setText(tr("MOUNT")); + } - QString output = process.readAllStandardOutput().trimmed(); - return !output.isEmpty(); -} - -bool ExternalStorageControl::isFilesystemPresent() { - QProcess process; - process.start("sh", QStringList() << "-c" << "lsblk -f /dev/sdg1 | grep -q ext4"); - process.waitForFinished(); - return process.exitCode() == 0; -} - -bool ExternalStorageControl::isDriveInitialized() { - QProcess process; - process.start("sh", QStringList() << "-c" << "sudo blkid /dev/sdg1 | grep -q 'LABEL=\"openpilot\"'"); - process.waitForFinished(); - return process.exitCode() == 0; + setEnabled(true); + }); + labelCheck->start("sh", QStringList() << "-c" << "sudo blkid /dev/sdg1 | grep -q 'LABEL=\"openpilot\"'"); + }); + fsCheck->start("sh", QStringList() << "-c" << "lsblk -f /dev/sdg1 | grep -q ext4"); + }); + mntCheck->start("sh", QStringList() << "-c" << "findmnt -n /mnt/external_realdata"); } void ExternalStorageControl::mountStorage() { @@ -94,20 +91,22 @@ void ExternalStorageControl::mountStorage() { QCoreApplication::processEvents(); QProcess *process = new QProcess(this); - connect(process, QOverload::of(&QProcess::finished), + connect(process, static_cast(&QProcess::finished), this, [=](int, QProcess::ExitStatus) { process->deleteLater(); refresh(); }); process->start("sh", QStringList() << "-c" << - "sudo mount -o remount,rw / && " + "sudo mount -o remount,rw / && " "sudo mkdir -p /mnt/external_realdata && " + "grep -q '/dev/sdg1 /mnt/external_realdata' /etc/fstab || " + "echo '/dev/sdg1 /mnt/external_realdata ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstab && " + "sudo systemctl daemon-reexec && " "sudo chown -R $(whoami):$(whoami) /mnt/external_realdata && " "sudo chmod -R 775 /mnt/external_realdata && " "sudo mount -o remount,ro / && " - "sudo mount /mnt/external_realdata" - ); + "sudo mount /mnt/external_realdata"); } void ExternalStorageControl::unmountStorage() { @@ -116,7 +115,7 @@ void ExternalStorageControl::unmountStorage() { QCoreApplication::processEvents(); QProcess *process = new QProcess(this); - connect(process, QOverload::of(&QProcess::finished), + connect(process, static_cast(&QProcess::finished), this, [=](int, QProcess::ExitStatus) { process->deleteLater(); refresh(); @@ -125,42 +124,40 @@ void ExternalStorageControl::unmountStorage() { } void ExternalStorageControl::formatStorage() { - unmountStorage(); + setText(tr("unmounting")); + setEnabled(false); + QCoreApplication::processEvents(); + QProcess *umount = new QProcess(this); + connect(umount, static_cast(&QProcess::finished), + this, [=](int, QProcess::ExitStatus) { + umount->deleteLater(); + runFormat(); + }); + umount->start("sh", QStringList() << "-c" << "sudo umount /mnt/external_realdata"); +} + +void ExternalStorageControl::runFormat() { setText(tr("formatting")); setEnabled(false); QCoreApplication::processEvents(); QProcess *process = new QProcess(this); - connect(process, QOverload::of(&QProcess::finished), - this, [=](int exitCode, QProcess::ExitStatus exitStatus) { - if (exitCode == 0 && exitStatus == QProcess::NormalExit) { - mountStorage(); + connect(process, static_cast(&QProcess::finished), + this, [=](int exitCode, QProcess::ExitStatus status) { + process->deleteLater(); + if (exitCode == 0 && status == QProcess::NormalExit) { QProcess::execute("sh", QStringList() << "-c" << "sudo e2label /dev/sdg1 openpilot"); + mountStorage(); } else { qWarning() << "Formatting failed with exit code" << exitCode; + setText(tr("FORMAT")); + setEnabled(true); } - process->deleteLater(); - refresh(); }); - process->start("sh", QStringList() << "-c" << "sudo mkfs.ext4 -F /dev/sdg1"); } -void ExternalStorageControl::checkAndUpdateFstab() { - QString fstabEntry = "/dev/sdg1 /mnt/external_realdata ext4 defaults,nofail 0 2"; - QProcess checkProcess; - checkProcess.start("sh", QStringList() << "-c" << "grep -Fxq '" + fstabEntry + "' /etc/fstab"); - checkProcess.waitForFinished(); - - if (checkProcess.exitCode() != 0) { - QProcess::execute("sh", QStringList() << "-c" << "sudo mount -o remount,rw /"); - QProcess::execute("sh", QStringList() << "-c" << "echo '" + fstabEntry + "' | sudo tee -a /etc/fstab"); - QProcess::execute("sh", QStringList() << "-c" << "sudo systemctl daemon-reload"); - QProcess::execute("sh", QStringList() << "-c" << "sudo mount -o remount,ro /"); - } -} - void ExternalStorageControl::showEvent(QShowEvent *event) { ButtonControl::showEvent(event); QTimer::singleShot(100, this, &ExternalStorageControl::refresh); diff --git a/selfdrive/ui/qt/widgets/external_storage.h b/selfdrive/ui/qt/widgets/external_storage.h index 1eadf2165d..7c27156533 100644 --- a/selfdrive/ui/qt/widgets/external_storage.h +++ b/selfdrive/ui/qt/widgets/external_storage.h @@ -30,5 +30,5 @@ private: void mountStorage(); void unmountStorage(); void formatStorage(); - void checkAndUpdateFstab(); + void runFormat(); };