From 7c5d29a687fc0b9808962fbbbc855fc5d923988b Mon Sep 17 00:00:00 2001 From: "M. Liebmann" Date: Fri, 21 Feb 2014 00:00:37 +0100 Subject: [PATCH] hddmenu: Support ext4 for formating disk - Support ext4 for formating disk (require /sbin/mkfs.ext4) - Support ext4 for check disk (require /sbin/fsck.ext4 or /sbin/e2fsck) - Display disk format in menu (require /sbin/blkid) - 'ext4' and 'display disk format' disabled when required files not present --- data/locale/deutsch.locale | 6 +- data/locale/english.locale | 6 +- src/gui/hdd_menu.cpp | 127 +++++++++++++++++++++++++++++-------- src/gui/hdd_menu.h | 7 ++ src/system/locals.h | 4 +- src/system/locals_intern.h | 4 +- 6 files changed, 118 insertions(+), 36 deletions(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 7fb113b8b..7364b7a54 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -611,18 +611,17 @@ hdd_60min 60 min. hdd_activate Übernehmen hdd_check Dateisystemprüfung hdd_check_failed Festplattenprüfung fehlgeschlagen -hdd_ext3 ext3 +hdd_check_format_bad Überprüfung von Datenträgern mit Format %s wird nicht unterstützt. hdd_extended_settings Erweiterte Festplatteneinstellungen hdd_fast Schnell hdd_format Formatiere Festplatte hdd_format_failed Formatierung fehlgeschlagen hdd_format_warn Formatierung wird gestartet -hdd_fs Dateisystem +hdd_fs Dateisystem zum formatieren hdd_manage Laufwerke verwalten hdd_middle Mittel hdd_noise Akustikkontrolle (AAM) hdd_not_found Keine Festplatte -hdd_reiser ReiserFS hdd_removable_device Wechseldatenträger hdd_settings Laufwerke hdd_sleep Ausschalten nach... @@ -862,6 +861,7 @@ menu.hint_games Zeige Liste der installierten Spiele menu.hint_hdd Formatierung und Prüfung der Datenträger menu.hint_hdd_apply Die veränderten Einstellungen zum Sleep- und Akustik-Modus werden übernommen menu.hint_hdd_check Überprüft das Dateisystem und führt gegebenfalls eine Reparatur durch (fsck) +menu.hint_hdd_fmt Wählen Sie das Datenträgerformat aus menu.hint_hdd_format Erstellt eine Partition auf dem Datenträger und formatiert diese menu.hint_hdd_noise Setzen Sie Parameter für das Automatic Acoustic Management.\nNicht alle Laufwerke unterstützen diese Funktion menu.hint_hdd_sleep Dieser Wert definiert, nach wieviel Minuten die Festplatte bei Inaktivität in den Sleep-Modus geschaltet wird diff --git a/data/locale/english.locale b/data/locale/english.locale index c3b65d989..689ef1bf5 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -611,18 +611,17 @@ hdd_60min 60 min. hdd_activate Apply settings hdd_check Check filesystem hdd_check_failed HDD-check failed! -hdd_ext3 ext3 +hdd_check_format_bad Checking of disks with format %s is not supported. hdd_extended_settings Extended HDD-Settings hdd_fast Fast hdd_format Formating drive... hdd_format_failed Formating failed! hdd_format_warn Start format... -hdd_fs Filesystem +hdd_fs Filesystem used to format hdd_manage Manage drives hdd_middle Mid hdd_noise Acoustic-control (AAM) hdd_not_found No HDD found -hdd_reiser ReiserFS hdd_removable_device Removable device hdd_settings Hard Disk Drive/USB hdd_sleep Switch off after... @@ -862,6 +861,7 @@ menu.hint_games Show list of installed games menu.hint_hdd Format / check hard disk drive menu.hint_hdd_apply Apply sleep/noise parameters menu.hint_hdd_check Check filesystem (fsck) +menu.hint_hdd_fmt Select the disk format menu.hint_hdd_format Create HDD partition and format it menu.hint_hdd_noise Set Automatic Acoustic Management\nnot all drives support this menu.hint_hdd_sleep Select time to stop hdd on inactivity diff --git a/src/gui/hdd_menu.cpp b/src/gui/hdd_menu.cpp index 9c3dd1852..0087c5219 100644 --- a/src/gui/hdd_menu.cpp +++ b/src/gui/hdd_menu.cpp @@ -55,6 +55,13 @@ #include #include +#define e2fsckBinary "/sbin/e2fsck" +#define ext3FsckBinary "/sbin/fsck.ext3" +#define ext4FsckBinary "/sbin/fsck.ext4" +#define ext3MkfsBinary "/sbin/mkfs.ext3" +#define ext4MkfsBinary "/sbin/mkfs.ext4" +#define blkidBinary "/sbin/blkid" + #define HDD_NOISE_OPTION_COUNT 4 const CMenuOptionChooser::keyval HDD_NOISE_OPTIONS[HDD_NOISE_OPTION_COUNT] = { @@ -64,12 +71,11 @@ const CMenuOptionChooser::keyval HDD_NOISE_OPTIONS[HDD_NOISE_OPTION_COUNT] = { 254, LOCALE_HDD_FAST } }; -#define HDD_FILESYS_OPTION_COUNT 3 -const CMenuOptionChooser::keyval HDD_FILESYS_OPTIONS[HDD_FILESYS_OPTION_COUNT] = +#define HDD_FILESYS_OPTION_COUNT 2 +const CMenuOptionChooser::keyval_ext HDD_FILESYS_OPTIONS[HDD_FILESYS_OPTION_COUNT] = { - { 0, LOCALE_HDD_EXT3 }, - { 1, LOCALE_HDD_REISER }, - { 2, LOCALE_OPTIONS_OFF } + { fs_ext3, NONEXISTANT_LOCALE, "ext3" }, + { fs_ext4, NONEXISTANT_LOCALE, "ext4" } }; #define HDD_SLEEP_OPTION_COUNT 6 const CMenuOptionChooser::keyval HDD_SLEEP_OPTIONS[HDD_SLEEP_OPTION_COUNT] = @@ -90,6 +96,27 @@ static int my_filter(const struct dirent * dent) return 0; } +std::string getFmtType(const char* name, int num) +{ + pid_t pid; + std::string ret = ""; + std::string pcmd = blkidBinary + (std::string)" -s TYPE /dev/" + (std::string)name + to_string(num); + dprintf(DEBUG_INFO, ">>>>>[%s #%d] pcmd: %s\n", __func__, __LINE__, pcmd.c_str()); + FILE* f = my_popen(pid, pcmd.c_str(), "r"); + if (f != NULL) { + char buff[512]; + fgets(buff, sizeof(buff), f); + fclose(f); + ret = buff; + std::string search = "TYPE=\""; + size_t pos = ret.find(search); + ret = ret.substr(pos + search.length()); + pos = ret.find("\""); + ret = ret.substr(0, pos); + } + return ret; +} + CHDDMenuHandler::CHDDMenuHandler() { width = w_max (58, 10); @@ -117,6 +144,9 @@ int CHDDMenuHandler::doMenu () struct stat s; int root_dev = -1; + bool ext4MkfsBinaryExist = (!access(ext4MkfsBinary, X_OK)); + bool blkidBinaryExist = (!access(blkidBinary, X_OK)); + bool hdd_found = 0; int n = scandir("/sys/block", &namelist, my_filter, alphasort); @@ -226,12 +256,27 @@ int CHDDMenuHandler::doMenu () bool enabled = !CNeutrinoApp::getInstance()->recordingstatus && !removable && !isroot; - snprintf(str, sizeof(str), "%s %s %ld %s", vendor, model, (long)(megabytes < 10000 ? megabytes : megabytes/1000), megabytes < 10000 ? "MB" : "GB"); + std::string fmt_type = ""; + if (blkidBinaryExist) + fmt_type = getFmtType(namelist[i]->d_name, 1); + std::string tmpType = (fmt_type == "") ? "" : " (" + fmt_type + (std::string)")"; + + snprintf(str, sizeof(str), "%s %s %ld %s%s", vendor, model, (long)(megabytes < 10000 ? megabytes : megabytes/1000), megabytes < 10000 ? "MB" : "GB", tmpType.c_str()); printf("HDD: %s\n", str); tmp_str[i]=str; tempMenu[i] = new CMenuWidget(str, NEUTRINO_ICON_SETTINGS); tempMenu[i]->addIntroItems(); - //tempMenu->addItem( new CMenuOptionChooser(LOCALE_HDD_FS, &g_settings.hdd_fs, HDD_FILESYS_OPTIONS, HDD_FILESYS_OPTION_COUNT, true)); + if (fmt_type == "ext3") + g_settings.hdd_fs = fs_ext3; + else if (fmt_type == "ext4") + g_settings.hdd_fs = fs_ext4; + else + g_settings.hdd_fs = fs_ext3; + if (!ext4MkfsBinaryExist) + g_settings.hdd_fs = fs_ext3; + mc = new CMenuOptionChooser(LOCALE_HDD_FS, &g_settings.hdd_fs, HDD_FILESYS_OPTIONS, HDD_FILESYS_OPTION_COUNT, ext4MkfsBinaryExist); + mc->setHint("", LOCALE_MENU_HINT_HDD_FMT); + tempMenu[i]->addItem(mc); mf = new CMenuForwarder(LOCALE_HDD_FORMAT, true, "", &fmtexec, namelist[i]->d_name); mf->setHint("", LOCALE_MENU_HINT_HDD_FORMAT); @@ -412,11 +457,11 @@ int CHDDFmtExec::exec(CMenuTarget* /*parent*/, const std::string& key) //sleep(1); switch(g_settings.hdd_fs) { - case 0: - snprintf(cmd, sizeof(cmd), "/sbin/mkfs.ext3 -T largefile -m0 %s", src); + case fs_ext3: + snprintf(cmd, sizeof(cmd), "%s -T largefile -m0 %s", ext3MkfsBinary, src); break; - case 1: - snprintf(cmd, sizeof(cmd), "/sbin/mkreiserfs -f -f %s", src); + case fs_ext4: + snprintf(cmd, sizeof(cmd), "%s -T largefile -m0 %s", ext4MkfsBinary, src); break; default: return 0; @@ -506,13 +551,13 @@ _remount: delete progress; switch(g_settings.hdd_fs) { - case 0: + case fs_ext3: safe_mkdir(dst); res = mount(src, dst, "ext3", 0, NULL); break; - case 1: + case fs_ext4: safe_mkdir(dst); - res = mount(src, dst, "reiserfs", 0, NULL); + res = mount(src, dst, "ext4", 0, NULL); break; default: break; @@ -558,6 +603,26 @@ int CHDDChkExec::exec(CMenuTarget* /*parent*/, const std::string& key) int oldpass = 0, pass, step, total; int percent = 0, opercent = 0; + bool ext4FsckBinaryExist = (!access(ext4FsckBinary, X_OK)); + bool e2fsckBinaryExist = (!access(e2fsckBinary, X_OK)); + bool blkidBinaryExist = (!access(blkidBinary, X_OK)); + + if (blkidBinaryExist) { + std::string fmt_type = getFmtType(key.c_str(), 1); + if (((fmt_type != "ext2") && (fmt_type != "ext3") && (fmt_type != "ext4")) || + ((fmt_type == "ext4") && (!ext4FsckBinaryExist) && (!e2fsckBinaryExist))) { + + char msg1[512], msg2[512]; + snprintf(msg1, sizeof(msg1)-1, "%s", g_Locale->getText(LOCALE_HDD_CHECK_FORMAT_BAD)); + snprintf(msg2, sizeof(msg2)-1, msg1, fmt_type.c_str()); + hintbox = new CHintBox(LOCALE_HDD_CHECK, msg2); + hintbox->paint(); + sleep(3); + delete hintbox; + return menu_return::RETURN_REPAINT; + } + } + snprintf(src, sizeof(src), "/dev/%s1", key.c_str()); snprintf(dst, sizeof(dst), "/media/%s1", key.c_str()); @@ -576,15 +641,25 @@ printf("CHDDChkExec: key %s\n", key.c_str()); return menu_return::RETURN_REPAINT; } - switch(g_settings.hdd_fs) { - case 0: - snprintf(cmd, sizeof(cmd), "/sbin/fsck.ext3 -C 1 -f -y %s", src); - break; - case 1: - snprintf(cmd, sizeof(cmd), "/sbin/reiserfsck --fix-fixable %s", src); - break; - default: - return 0; + if (e2fsckBinaryExist) { + snprintf(cmd, sizeof(cmd), "%s -C 1 -f -y %s", e2fsckBinary, src); + } else { + snprintf(cmd, sizeof(cmd), "%s -C 1 -f -y %s", ext3FsckBinary, src); + if ((ext4FsckBinaryExist) && (g_settings.hdd_fs == fs_ext4)) + snprintf(cmd, sizeof(cmd), "%s -C 1 -f -y %s", ext4FsckBinary, src); + +#if 0 + switch(g_settings.hdd_fs) { + case fs_ext3: + snprintf(cmd, sizeof(cmd), "%s -C 1 -f -y %s", ext3FsckBinary, src); + break; + case fs_ext4: + snprintf(cmd, sizeof(cmd), "%s -C 1 -f -y %s", ext4FsckBinary, src); + break; + default: + return 0; + } +#endif } printf("CHDDChkExec: Executing %s\n", cmd); @@ -636,13 +711,13 @@ printf("CHDDChkExec: key %s\n", key.c_str()); ret1: switch(g_settings.hdd_fs) { - case 0: + case fs_ext3: safe_mkdir(dst); res = mount(src, dst, "ext3", 0, NULL); break; - case 1: + case fs_ext4: safe_mkdir(dst); - res = mount(src, dst, "reiserfs", 0, NULL); + res = mount(src, dst, "ext4", 0, NULL); break; default: break; diff --git a/src/gui/hdd_menu.h b/src/gui/hdd_menu.h index ce80e7470..cd91e8ac9 100644 --- a/src/gui/hdd_menu.h +++ b/src/gui/hdd_menu.h @@ -28,6 +28,13 @@ using namespace std; +enum { + fs_ext3, + fs_ext4, + + fs_max +}; + class CHDDDestExec : public CMenuTarget { public: diff --git a/src/system/locals.h b/src/system/locals.h index 3e94dbda8..0525619d2 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -638,7 +638,7 @@ typedef enum LOCALE_HDD_ACTIVATE, LOCALE_HDD_CHECK, LOCALE_HDD_CHECK_FAILED, - LOCALE_HDD_EXT3, + LOCALE_HDD_CHECK_FORMAT_BAD, LOCALE_HDD_EXTENDED_SETTINGS, LOCALE_HDD_FAST, LOCALE_HDD_FORMAT, @@ -649,7 +649,6 @@ typedef enum LOCALE_HDD_MIDDLE, LOCALE_HDD_NOISE, LOCALE_HDD_NOT_FOUND, - LOCALE_HDD_REISER, LOCALE_HDD_REMOVABLE_DEVICE, LOCALE_HDD_SETTINGS, LOCALE_HDD_SLEEP, @@ -889,6 +888,7 @@ typedef enum LOCALE_MENU_HINT_HDD, LOCALE_MENU_HINT_HDD_APPLY, LOCALE_MENU_HINT_HDD_CHECK, + LOCALE_MENU_HINT_HDD_FMT, LOCALE_MENU_HINT_HDD_FORMAT, LOCALE_MENU_HINT_HDD_NOISE, LOCALE_MENU_HINT_HDD_SLEEP, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index cdfab817f..50df4d51a 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -638,7 +638,7 @@ const char * locale_real_names[] = "hdd_activate", "hdd_check", "hdd_check_failed", - "hdd_ext3", + "hdd_check_format_bad", "hdd_extended_settings", "hdd_fast", "hdd_format", @@ -649,7 +649,6 @@ const char * locale_real_names[] = "hdd_middle", "hdd_noise", "hdd_not_found", - "hdd_reiser", "hdd_removable_device", "hdd_settings", "hdd_sleep", @@ -889,6 +888,7 @@ const char * locale_real_names[] = "menu.hint_hdd", "menu.hint_hdd_apply", "menu.hint_hdd_check", + "menu.hint_hdd_fmt", "menu.hint_hdd_format", "menu.hint_hdd_noise", "menu.hint_hdd_sleep",