intel partition map: implement changing the active partition
Implement the needed parts in both the userland add-on (loaded in DriveSetup) and the kernel side one (used by disk system manager in the kernel). This allows changing the active partition in DriveSetup. Change-Id: Ia65768b5f8f11d626ef24621ae7735723dcbc39d Reviewed-on: https://review.haiku-os.org/c/haiku/+/3771 Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
parent
8f5c5225da
commit
9274ca847b
@ -236,7 +236,6 @@ PartitionMapHandle::SupportedChildOperations(const BMutablePartition* child,
|
||||
{
|
||||
return B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
|
||||
| B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD
|
||||
| B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE
|
||||
| B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS
|
||||
| B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD;
|
||||
}
|
||||
@ -295,6 +294,44 @@ PartitionMapHandle::GetPartitioningInfo(BPartitioningInfo* info)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PartitionMapHandle::ValidateSetParameters(const BMutablePartition* child,
|
||||
const char* parameters)
|
||||
{
|
||||
if (child == NULL || parameters == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
void* handle = parse_driver_settings_string(parameters);
|
||||
if (handle == NULL)
|
||||
return B_BAD_DATA;
|
||||
|
||||
delete_driver_settings(handle);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PartitionMapHandle::SetParameters(BMutablePartition* child,
|
||||
const char* parameters)
|
||||
{
|
||||
void* handle = parse_driver_settings_string(parameters);
|
||||
if (handle == NULL)
|
||||
return B_BAD_DATA;
|
||||
|
||||
bool active = get_driver_boolean_parameter(handle, "active", false, true);
|
||||
delete_driver_settings(handle);
|
||||
|
||||
// Update our local state
|
||||
PrimaryPartition* partition = (PrimaryPartition*)child->ChildCookie();
|
||||
partition->SetActive(active);
|
||||
|
||||
// Forward the request to the BMutablePartition so it can be committed to
|
||||
// disk
|
||||
return child->SetParameters(parameters);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PartitionMapHandle::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type,
|
||||
BPartitionParameterEditor** editor)
|
||||
|
@ -49,6 +49,13 @@ public:
|
||||
|
||||
virtual status_t GetPartitioningInfo(BPartitioningInfo* info);
|
||||
|
||||
virtual status_t ValidateSetParameters(
|
||||
const BMutablePartition* child,
|
||||
const char* parameters);
|
||||
virtual status_t SetParameters(
|
||||
BMutablePartition* child,
|
||||
const char* parameters);
|
||||
|
||||
virtual status_t GetParameterEditor(
|
||||
B_PARAMETER_EDITOR_TYPE type,
|
||||
BPartitionParameterEditor** editor);
|
||||
@ -59,7 +66,7 @@ public:
|
||||
const char* type, const char* name,
|
||||
const char* parameters,
|
||||
BMutablePartition** child);
|
||||
virtual status_t DeleteChild(BMutablePartition* child);
|
||||
virtual status_t DeleteChild(BMutablePartition* child);
|
||||
|
||||
private:
|
||||
PartitionMap fPartitionMap;
|
||||
|
@ -44,10 +44,15 @@ status_t
|
||||
PrimaryPartitionEditor::ParameterChanged(const char* name,
|
||||
const BVariant& variant)
|
||||
{
|
||||
if (!strcmp(name, "type")) {
|
||||
if (strcmp(name, "type") == 0) {
|
||||
fActiveCheckBox->SetEnabled(strcmp(variant.ToString(),
|
||||
kPartitionTypeIntelExtended) != 0);
|
||||
fActiveCheckBox->SetValue(false);
|
||||
}
|
||||
|
||||
if (strcmp(name, "active") == 0)
|
||||
fActiveCheckBox->SetValue(variant.ToBool());
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -494,8 +494,8 @@ static partition_module_info intel_partition_map_module =
|
||||
NULL, // set_name
|
||||
NULL, // set_content_name
|
||||
pm_set_type, // set_type
|
||||
NULL, // set_parameters
|
||||
NULL, // set_content_parameters
|
||||
pm_set_parameters, // set_parameters
|
||||
pm_set_parameters, // set_content_parameters
|
||||
pm_initialize, // initialize
|
||||
pm_uninitialize, // uninitialize
|
||||
pm_create_child, // create_child
|
||||
|
@ -1249,6 +1249,80 @@ pm_set_type(int fd, partition_id partitionID, const char* type, disk_job_id job)
|
||||
}
|
||||
|
||||
|
||||
// pm_set_parameters
|
||||
status_t
|
||||
pm_set_parameters(int fd, partition_id partitionID, const char* parameters,
|
||||
disk_job_id job)
|
||||
{
|
||||
TRACE(("intel: pm_set_parameters\n"));
|
||||
|
||||
if (fd < 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// Nothing to do if there are no parameters provided
|
||||
if (parameters == NULL)
|
||||
return B_OK;
|
||||
|
||||
PartitionWriteLocker locker(partitionID);
|
||||
if (!locker.IsLocked())
|
||||
return B_ERROR;
|
||||
|
||||
// get parent partition, child and partition map structure
|
||||
partition_data* partition = get_parent_partition(partitionID);
|
||||
partition_data* child = get_partition(partitionID);
|
||||
if (partition == NULL || child == NULL)
|
||||
return B_BAD_VALUE;
|
||||
PartitionMap* map = (PartitionMap*)partition->content_cookie;
|
||||
PrimaryPartition* primary = (PrimaryPartition*)child->cookie;
|
||||
if (map ==NULL || primary == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check parameters
|
||||
void* handle = parse_driver_settings_string(parameters);
|
||||
if (handle == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
bool active = get_driver_boolean_parameter(handle, "active", false, true);
|
||||
delete_driver_settings(handle);
|
||||
|
||||
// if the old type is the same, there is nothing to do
|
||||
if (primary->Active() == active) {
|
||||
TRACE(("intel: pm_set_parameters: no changes required.\n"));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
update_disk_device_job_progress(job, 0.0);
|
||||
|
||||
// set the active flags to false for other partitions
|
||||
if (active) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
PrimaryPartition* partition = map->PrimaryPartitionAt(i);
|
||||
partition->SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool oldActive = primary->Active();
|
||||
primary->SetActive(active);
|
||||
|
||||
// TODO: The partition is not supposed to be locked at this point!
|
||||
PartitionMapWriter writer(fd, primary->BlockSize());
|
||||
// TODO: disk size?
|
||||
status_t error = writer.WriteMBR(map, false);
|
||||
if (error != B_OK) {
|
||||
TRACE(("intel: pm_set_parameters: Failed to rewrite MBR: %s\n",
|
||||
strerror(error)));
|
||||
// something went wrong - putting into previous state
|
||||
primary->SetType(oldActive);
|
||||
return error;
|
||||
}
|
||||
|
||||
// all changes applied
|
||||
update_disk_device_job_progress(job, 1.0);
|
||||
partition_modified(partitionID);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// pm_initialize
|
||||
status_t
|
||||
pm_initialize(int fd, partition_id partitionID, const char* name,
|
||||
|
@ -46,6 +46,8 @@ status_t pm_move_child(int fd, partition_id partitionID,
|
||||
partition_id childID, off_t offset, disk_job_id job);
|
||||
status_t pm_set_type(int fd, partition_id partitionID, const char* type,
|
||||
disk_job_id job);
|
||||
status_t pm_set_parameters(int fd, partition_id partitionID,
|
||||
const char* parameters, disk_job_id job);
|
||||
status_t pm_initialize(int fd, partition_id partitionID, const char* name,
|
||||
const char* parameters, off_t partitionSize, disk_job_id job);
|
||||
status_t pm_uninitialize(int fd, partition_id partitionID,
|
||||
|
@ -109,24 +109,28 @@ ChangeParametersPanel::Go(BString& name, BString& type, BString& parameters,
|
||||
|
||||
|
||||
void
|
||||
ChangeParametersPanel::CreateChangeControls(BPartition* parent)
|
||||
ChangeParametersPanel::CreateChangeControls(BPartition* partition)
|
||||
{
|
||||
fNameTextControl = new BTextControl("Name Control",
|
||||
B_TRANSLATE("Partition name:"), "", NULL);
|
||||
fSupportsName = parent->SupportsChildName();
|
||||
B_TRANSLATE("Partition name:"), partition->Name(), NULL);
|
||||
fSupportsName = partition->CanSetName();
|
||||
|
||||
fTypePopUpMenu = new BPopUpMenu("Partition Type");
|
||||
|
||||
int32 cookie = 0;
|
||||
BString supportedType;
|
||||
while (parent->GetNextSupportedChildType(&cookie, &supportedType) == B_OK) {
|
||||
BMessage* message = new BMessage(MSG_PARTITION_TYPE);
|
||||
message->AddString("type", supportedType);
|
||||
BMenuItem* item = new BMenuItem(supportedType, message);
|
||||
fTypePopUpMenu->AddItem(item);
|
||||
BPartition* parent = partition->Parent();
|
||||
if (parent != NULL) {
|
||||
while (parent->GetNextSupportedChildType(&cookie, &supportedType)
|
||||
== B_OK) {
|
||||
BMessage* message = new BMessage(MSG_PARTITION_TYPE);
|
||||
message->AddString("type", supportedType);
|
||||
BMenuItem* item = new BMenuItem(supportedType, message);
|
||||
fTypePopUpMenu->AddItem(item);
|
||||
|
||||
if (strcmp(supportedType, kPartitionTypeBFS) == 0)
|
||||
item->SetMarked(true);
|
||||
if (strcmp(supportedType, kPartitionTypeBFS) == 0)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
}
|
||||
|
||||
fTypeMenuField = new BMenuField(B_TRANSLATE("Partition type:"),
|
||||
|
@ -410,9 +410,10 @@ DiskDeviceJobGenerator::_GenerateRemainingJobs(BPartition* parent,
|
||||
}
|
||||
|
||||
// parameters
|
||||
if ((changeFlags & B_PARTITION_CHANGED_PARAMETERS)
|
||||
|| compare_string(partition->Parameters(),
|
||||
partitionData->parameters)) {
|
||||
if ((partition->Parameters() != NULL)
|
||||
&& ((changeFlags & B_PARTITION_CHANGED_PARAMETERS) != 0
|
||||
|| compare_string(partition->Parameters(),
|
||||
partitionData->parameters))) {
|
||||
if (!parent)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
@ -441,9 +442,10 @@ DiskDeviceJobGenerator::_GenerateRemainingJobs(BPartition* parent,
|
||||
}
|
||||
|
||||
// content parameters
|
||||
if ((changeFlags & B_PARTITION_CHANGED_PARAMETERS)
|
||||
|| compare_string(partition->ContentParameters(),
|
||||
partitionData->content_parameters)) {
|
||||
if ((partition->ContentParameters() != NULL)
|
||||
&& ((changeFlags & B_PARTITION_CHANGED_PARAMETERS) != 0
|
||||
|| compare_string(partition->ContentParameters(),
|
||||
partitionData->content_parameters))) {
|
||||
status_t error = _GenerateSetContentParametersJob(partition);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "DiskDeviceJobQueue.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
@ -54,7 +55,8 @@ DiskDeviceJobQueue::Execute()
|
||||
|
||||
status_t error = job->Do();
|
||||
if (error != B_OK) {
|
||||
TRACE("DiskDeviceJobQueue::Execute(): executing job failed\n");
|
||||
TRACE("DiskDeviceJobQueue::Execute(): executing job failed: %s\n",
|
||||
strerror(error));
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user