From 494f7ae2bbd05b26a4a1b3dc2b57120bb7025dd6 Mon Sep 17 00:00:00 2001 From: srs5694 Date: Tue, 1 Sep 2015 21:55:46 -0400 Subject: [PATCH] Add support for bit 60 (read-only) and 63 (do-not-automount) partition attributes in Discoverable Partition Specification code. --- NEWS.txt | 11 +++++++++++ refind/config.c | 9 +++++---- refind/global.h | 1 + refind/gpt.c | 25 ------------------------- refind/lib.c | 34 ++++++++++++++++++---------------- refind/lib.h | 5 +++++ refind/main.c | 2 +- 7 files changed, 41 insertions(+), 46 deletions(-) diff --git a/NEWS.txt b/NEWS.txt index 7ffda3f..69a5d8d 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,6 +1,17 @@ 0.9.1 (?/??/2015): ------------------ +- When rEFInd identifies the root (/) partition via the Freedesktop.org + Discoverable Partitions Specification, it now checks two of the + partition's attributes, as per the DPS (see + http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/): + - The partition's read-only attribute determines whether to pass a "rw" + or "ro" option to the kernel. + - If the partition's do-not-automount flag is set, rEFInd will not pass + it as a "root=" option to the kernel. This flag can be used to remove + all but one partition from consideration as a root (/) partition if a + system has more than one with the correct type code. + - Improved Freedesktop.org Discoverable Partitions Specification support: Previously, if no refind_linux.conf file was present but an /etc/fstab file was found, rEFInd ignored the Discoverable Partitions Specification diff --git a/refind/config.c b/refind/config.c index 6227c67..afededb 100644 --- a/refind/config.c +++ b/refind/config.c @@ -1029,25 +1029,26 @@ static REFIT_FILE * GenerateOptionsFromEtcFstab(REFIT_VOLUME *Volume) { // filesystem according to the Freedesktop.org Discoverable Partitions Spec // (http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/), // this function returns an appropriate file with two lines, one with -// "ro root=PARTUUID={GUID}" and the other with that plus "single". +// "ro root=/dev/disk/by-partuuid/{GUID}" and the other with that plus "single". // Note that this function returns the LAST partition found with the // appropriate type code, so this will work poorly on dual-boot systems or // if the type code is set incorrectly. static REFIT_FILE * GenerateOptionsFromPartTypes(VOID) { REFIT_FILE *Options = NULL; - CHAR16 *Line, *GuidString; + CHAR16 *Line, *GuidString, *WriteStatus; if (GlobalConfig.DiscoveredRoot) { Options = AllocateZeroPool(sizeof(REFIT_FILE)); if (Options) { Options->Encoding = ENCODING_UTF16_LE; GuidString = GuidAsString(&(GlobalConfig.DiscoveredRoot->PartGuid)); + WriteStatus = GlobalConfig.DiscoveredRoot->IsMarkedReadOnly ? L"ro" : L"rw"; ToLower(GuidString); if (GuidString) { - Line = PoolPrint(L"\"Boot with normal options\" \"ro root=/dev/disk/by-partuuid/%s\"\n", GuidString); + Line = PoolPrint(L"\"Boot with normal options\" \"%s root=/dev/disk/by-partuuid/%s\"\n", WriteStatus, GuidString); MergeStrings((CHAR16 **) &(Options->Buffer), Line, 0); MyFreePool(Line); - Line = PoolPrint(L"\"Boot into single-user mode\" \"ro root=/dev/disk/by-partuuid/%s single\"\n", GuidString); + Line = PoolPrint(L"\"Boot into single-user mode\" \"%s root=/dev/disk/by-partuuid/%s single\"\n", WriteStatus, GuidString); MergeStrings((CHAR16**) &(Options->Buffer), Line, 0); MyFreePool(Line); MyFreePool(GuidString); diff --git a/refind/global.h b/refind/global.h index 2871c61..e8d57eb 100644 --- a/refind/global.h +++ b/refind/global.h @@ -206,6 +206,7 @@ typedef struct { EFI_GUID VolUuid; EFI_GUID PartGuid; EFI_GUID PartTypeGuid; + BOOLEAN IsMarkedReadOnly; UINTN VolNumber; EG_IMAGE *VolIconImage; EG_IMAGE *VolBadgeImage; diff --git a/refind/gpt.c b/refind/gpt.c index 60da3bb..cc6c70b 100644 --- a/refind/gpt.c +++ b/refind/gpt.c @@ -185,31 +185,6 @@ EFI_STATUS ReadGptData(REFIT_VOLUME *Volume, GPT_DATA **Data) { return Status; } // EFI_STATUS ReadGptData() -// // Look in gPartitions for a partition with the specified Guid. If found, return -// // a pointer to that partition's name string. If not found, return a NULL pointer. -// // The calling function is responsible for freeing the returned memory. -// CHAR16 * PartNameFromGuid(EFI_GUID *Guid) { -// UINTN i; -// CHAR16 *Found = NULL; -// GPT_DATA *GptData; -// -// if ((Guid == NULL) || (gPartitions == NULL)) -// return NULL; -// -// GptData = gPartitions; -// while ((GptData != NULL) && (!Found)) { -// i = 0; -// while ((i < GptData->Header->entry_count) && (!Found)) { -// if (GuidsAreEqual((EFI_GUID*) &(GptData->Entries[i].partition_guid), Guid)) -// Found = StrDuplicate(GptData->Entries[i].name); -// else -// i++; -// } // while(scanning entries) -// GptData = GptData->NextEntry; -// } // while(scanning GPTs) -// return Found; -// } // CHAR16 * PartNameFromGuid() - // Look in gPartitions for a partition with the specified Guid. If found, return // a pointer to that partition's data. If not found, return a NULL pointer. // The calling function is responsible for freeing the returned memory. diff --git a/refind/lib.c b/refind/lib.c index 92abfd0..40c1814 100644 --- a/refind/lib.c +++ b/refind/lib.c @@ -853,23 +853,25 @@ static VOID SetPartGuidAndName(REFIT_VOLUME *Volume, EFI_DEVICE_PATH_PROTOCOL *D HARDDRIVE_DEVICE_PATH *HdDevicePath; GPT_ENTRY *PartInfo; - if ((Volume == NULL) || (DevicePath == NULL)) - return; + if ((Volume == NULL) || (DevicePath == NULL)) + return; - if ((DevicePath->Type == MEDIA_DEVICE_PATH) && (DevicePath->SubType == MEDIA_HARDDRIVE_DP)) { - HdDevicePath = (HARDDRIVE_DEVICE_PATH*) DevicePath; - if (HdDevicePath->SignatureType == SIGNATURE_TYPE_GUID) { - Volume->PartGuid = *((EFI_GUID*) HdDevicePath->Signature); - PartInfo = FindPartWithGuid(&(Volume->PartGuid)); - if (PartInfo) { - Volume->PartName = StrDuplicate(PartInfo->name); - CopyMem(&(Volume->PartTypeGuid), PartInfo->type_guid, sizeof(EFI_GUID)); - if (GuidsAreEqual (&(Volume->PartTypeGuid), &gFreedesktopRootGuid)) { - GlobalConfig.DiscoveredRoot = Volume; - } // if (GUIDs match) - } // if (PartInfo exists) - } // if (GPT disk) - } // if (disk device) + if ((DevicePath->Type == MEDIA_DEVICE_PATH) && (DevicePath->SubType == MEDIA_HARDDRIVE_DP)) { + HdDevicePath = (HARDDRIVE_DEVICE_PATH*) DevicePath; + if (HdDevicePath->SignatureType == SIGNATURE_TYPE_GUID) { + Volume->PartGuid = *((EFI_GUID*) HdDevicePath->Signature); + PartInfo = FindPartWithGuid(&(Volume->PartGuid)); + if (PartInfo) { + Volume->PartName = StrDuplicate(PartInfo->name); + CopyMem(&(Volume->PartTypeGuid), PartInfo->type_guid, sizeof(EFI_GUID)); + if (GuidsAreEqual(&(Volume->PartTypeGuid), &gFreedesktopRootGuid) && + ((PartInfo->attributes & GPT_NO_AUTOMOUNT) == 0)) { + GlobalConfig.DiscoveredRoot = Volume; + } // if (GUIDs match && automounting OK) + Volume->IsMarkedReadOnly = ((PartInfo->attributes & GPT_READ_ONLY) > 0); + } // if (PartInfo exists) + } // if (GPT disk) + } // if (disk device) } // VOID SetPartGuid() // Return TRUE if NTFS boot files are found or if Volume is unreadable, diff --git a/refind/lib.h b/refind/lib.h index 552b11f..a148f6a 100644 --- a/refind/lib.h +++ b/refind/lib.h @@ -79,6 +79,11 @@ typedef struct { #define IS_EXTENDED_PART_TYPE(type) ((type) == 0x05 || (type) == 0x0f || (type) == 0x85) +// GPT attributes of interest to us for Freedesktop.org Discoverable +// Partitions Specification.... +#define GPT_READ_ONLY 0x1000000000000000 +#define GPT_NO_AUTOMOUNT 0x8000000000000000 + // Partition names to be ignored when setting volume name #define IGNORE_PARTITION_NAMES L"Microsoft basic data,Linux filesystem,Apple HFS/HFS+" diff --git a/refind/main.c b/refind/main.c index 7c998cf..0b2742b 100644 --- a/refind/main.c +++ b/refind/main.c @@ -173,7 +173,7 @@ static VOID AboutrEFInd(VOID) if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.9.0.4"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.9.0.5"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2015 Roderick W. Smith"); -- 2.39.2