Domanda

Sto scrivendo un'applicazione che in qualche fase esegue operazioni su disco di basso livello in ambiente Linux.L'app in realtà è composta da 2 parti, una funziona su Windows e interagisce con un utente e un'altra è una parte Linux che viene eseguita da un LiveCD.L'utente sceglie le lettere dell'unità Windows e quindi una parte Linux esegue azioni con le partizioni corrispondenti.Il problema è trovare una corrispondenza tra la lettera di un'unità Windows (come C:) e il nome di un dispositivo Linux (come /dev/sda1).Questa è la mia soluzione attuale che considero brutta:

  • memorizzare informazioni sulle partizioni (ad es.lettera di unità, numero di blocchi, numero di serie dell'unità, ecc.) in Windows in una posizione predefinita (ad es.la radice della partizione di sistema).

  • leggere un elenco di partizioni da /proc/partitions.Ottieni solo quelle partizioni che hanno un numero maggiore per i dischi rigidi SCSI o IDE e un numero minore che le identifica come partizioni reali e non come dischi interi.

  • Prova a montarli ciascuno con file system ntfs o vfat.Controlla se la partizione montata contiene le informazioni archiviate dall'app Windows.

  • Dopo aver trovato le informazioni richieste scritte dall'app Windows, effettua la corrispondenza effettiva.Per ogni partizione trovata in /proc/partitions acquisire il numero di serie dell'unità (tramite la chiamata di sistema HDIO_GET_IDENTITY), il numero di blocchi (da /proc/partitions) e l'offset dell'unità (/sys/blocks/drive_path/partition_name/start), confrontarlo con Windows informazioni e, se corrispondono, memorizza una lettera di unità Windows insieme al nome del dispositivo Linux.

Ci sono un paio di problemi in questo schema:

  • Questo è brutto.Scrivere dati in Windows e poi leggerli in Linux rende i test un incubo.

  • Il numero principale del dispositivo Linux viene confrontato solo con i dispositivi IDE o SCSI.Questo probabilmente fallirebbe, ad es.su dischi USB o FireWire.È possibile aggiungere questi tipi di dischi, ma limitare l'app solo a un sottoinsieme noto di possibili dispositivi sembra essere una pessima idea.

  • sembra che HDIO_GET_IDENTITY funzioni solo su unità IDE e SATA.

  • /sys/block potrebbe non funzionare su unità diverse da IDE o SATA.

Qualche idea su come migliorare questo schema?Forse esiste un altro modo per determinare i nomi di Windows senza scrivere tutti i dati nell'app Windows?

PSIl linguaggio dell'app è C++.Non posso cambiarlo.

È stato utile?

Soluzione

Alle partizioni sono associati degli UUID.Non so come trovarli in Windows ma in Linux puoi trovare l'UUID per ogni partizione con:

sudo vol_id -u dispositivo (ad es./dev/sda1)

Se esiste una funzione equivalente in Windows, potresti semplicemente memorizzare gli UUID per qualunque partizione scelgano, quindi scorrere tutte le partizioni conosciute in Linux e abbinare gli UUID.

Modificare: Questa potrebbe essere una cosa solo per Linux, e potrebbe essere in particolare l'utility volid che li genera da qualcosa (invece di leggere i metadati per l'unità).Detto questo, non c'è nulla che ti impedisca di ottenere la fonte di volid e di verificare cosa fa.

Altri suggerimenti

Alle partizioni sono associati degli UUID

La mia conoscenza di questo è molto superficiale, ma pensavo che fosse vero solo per i dischi formattati con partizioni GPT (Guid Partition Table), piuttosto che con il formato MBR vecchio stile a cui è ancora bloccato il 99% del mondo?

La mia conoscenza di questo è molto superficiale, ma ho pensato che fosse vero solo per i dischi formattati con le partizioni GPT (Guid Partition Table), piuttosto che il formato MBR in stile vecchio con cui il 99% del mondo è ancora bloccato?

Non sembra un cliché per gli utenti Linux, ma per me funziona..Lo uso con partizioni NTFS e non ho avuto problemi.Come ho detto nella mia modifica, vol_id potrebbe generarli da solo.Se così fosse non ci sarebbe affidamento su alcun particolare formato di partizione, il che sarebbe fantastico.

Alle partizioni sono associati degli UUID.Non so come trovarli in Windows ma in Linux puoi trovare l'UUID per ogni partizione con:

sudo vol_id -u dispositivo (ad es./dev/sda1)

Se esiste una funzione equivalente in Windows, potresti semplicemente memorizzare gli UUID per qualunque partizione scelgano, quindi scorrere tutte le partizioni conosciute in Linux e abbinare gli UUID.

Questo è un buon punto, grazie!Ho esaminato i sorgenti di vol_id (una parte del tarball udev) e sembra che per FAT(32) e NTFS generi UUUD utilizzando il numero di serie del volume che viene letto dalla posizione predefinita sulla partizione.Poiché non mi aspetto altro che fat32 e ntfs, considero di utilizzare queste informazioni come identificatore di partizione.

È necessario contrassegnare l'unità in qualche modo (ad es.scrivere un file ecc.) o trovare un identificatore associato solo a quella particolare unità.

È molto difficile, quasi impossibile, capire quale lettera Windows assegnerebbe a una particolare partizione del disco, senza eseguire effettivamente Windows.Questo perché Windows associa sempre l'unità da cui viene eseguito con C:.Potrebbe trattarsi di qualsiasi unità, se è installato più di un sistema operativo.Windows ti consente anche di scegliere quale lettera di unità proverà per prima, per una partizione specifica, causando ulteriori problemi.

Sarebbe molto più semplice realizzare le operazioni della GUI all'interno di Linux, piuttosto che provare questa soluzione mista Windows/Linux.Non sto dicendo di non provarlo in questo modo, quello che sto dicendo è che ci sono moltissime possibili insidie ​​​​con questo approccio.Sono sicuro di non conoscerli nemmeno tutti.

Un'altra opzione sarebbe vedere se potresti effettivamente fare la parte Linux, all'interno di Windows.Se sei un ottimo programmatore Windows, puoi effettivamente accedere al file system raw.Probabilmente ci sono altrettante insidie ​​​​con questo approccio, perché Windows funzionerà mentre tutto questo è in funzione.

Quindi, per ribadire, vedrei se potresti fare tutto da Linux, se puoi.È semplicemente molto più semplice a lungo termine.

In Windows puoi leggere il "Numero di serie del volume NTFS" che sembra corrispondere all'UUID sotto Linux.

Possibilità di ottenere il "Volume seriale NTFS" da finestre:

  • riga di comando da XP: fsutil.exe fsinfo ntfsinfo C:

  • sotto C++

    HANDLE fileHandle = CreateFile(L"\\\\.\\C:", // or use syntax "\\?\Volume{GUID}" 
                                   GENERIC_READ,
                                   FILE_SHARE_READ|FILE_SHARE_WRITE,
                                   NULL,
                                   OPEN_EXISTING,
                                   NULL,
                                   NULL);
    DWORD i;
    NTFS_VOLUME_DATA_BUFFER ntfsInfo;
    DeviceIoControl(fileHandle, 
                    FSCTL_GET_NTFS_VOLUME_DATA, 
                    NULL, 
                    0, 
                    &ntfsInfo,
                    sizeof(ntfsInfo), 
                    &i, 
                    NULL));
    cout << "UUID is " << std::hex << ntfsInfo.VolumeSerialNumber.HighPart << std::hex << ntfsInfo.VolumeSerialNumber.LowPart << endl;
    

Possibilità di ottenere l'UUID Linux:

  • ls -l /dev/disk/by-uuid
  • ls -l /dev/disco/per-etichetta
  • blkid /dev/sda1
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top