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
|
return B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
|
||||||
| B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD
|
| B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD
|
||||||
| B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE
|
|
||||||
| B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS
|
| B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS
|
||||||
| B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD;
|
| 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
|
status_t
|
||||||
PartitionMapHandle::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type,
|
PartitionMapHandle::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type,
|
||||||
BPartitionParameterEditor** editor)
|
BPartitionParameterEditor** editor)
|
||||||
|
@ -49,6 +49,13 @@ public:
|
|||||||
|
|
||||||
virtual status_t GetPartitioningInfo(BPartitioningInfo* info);
|
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(
|
virtual status_t GetParameterEditor(
|
||||||
B_PARAMETER_EDITOR_TYPE type,
|
B_PARAMETER_EDITOR_TYPE type,
|
||||||
BPartitionParameterEditor** editor);
|
BPartitionParameterEditor** editor);
|
||||||
@ -59,7 +66,7 @@ public:
|
|||||||
const char* type, const char* name,
|
const char* type, const char* name,
|
||||||
const char* parameters,
|
const char* parameters,
|
||||||
BMutablePartition** child);
|
BMutablePartition** child);
|
||||||
virtual status_t DeleteChild(BMutablePartition* child);
|
virtual status_t DeleteChild(BMutablePartition* child);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PartitionMap fPartitionMap;
|
PartitionMap fPartitionMap;
|
||||||
|
@ -44,10 +44,15 @@ status_t
|
|||||||
PrimaryPartitionEditor::ParameterChanged(const char* name,
|
PrimaryPartitionEditor::ParameterChanged(const char* name,
|
||||||
const BVariant& variant)
|
const BVariant& variant)
|
||||||
{
|
{
|
||||||
if (!strcmp(name, "type")) {
|
if (strcmp(name, "type") == 0) {
|
||||||
fActiveCheckBox->SetEnabled(strcmp(variant.ToString(),
|
fActiveCheckBox->SetEnabled(strcmp(variant.ToString(),
|
||||||
kPartitionTypeIntelExtended) != 0);
|
kPartitionTypeIntelExtended) != 0);
|
||||||
|
fActiveCheckBox->SetValue(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(name, "active") == 0)
|
||||||
|
fActiveCheckBox->SetValue(variant.ToBool());
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,8 +494,8 @@ static partition_module_info intel_partition_map_module =
|
|||||||
NULL, // set_name
|
NULL, // set_name
|
||||||
NULL, // set_content_name
|
NULL, // set_content_name
|
||||||
pm_set_type, // set_type
|
pm_set_type, // set_type
|
||||||
NULL, // set_parameters
|
pm_set_parameters, // set_parameters
|
||||||
NULL, // set_content_parameters
|
pm_set_parameters, // set_content_parameters
|
||||||
pm_initialize, // initialize
|
pm_initialize, // initialize
|
||||||
pm_uninitialize, // uninitialize
|
pm_uninitialize, // uninitialize
|
||||||
pm_create_child, // create_child
|
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
|
// pm_initialize
|
||||||
status_t
|
status_t
|
||||||
pm_initialize(int fd, partition_id partitionID, const char* name,
|
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);
|
partition_id childID, off_t offset, disk_job_id job);
|
||||||
status_t pm_set_type(int fd, partition_id partitionID, const char* type,
|
status_t pm_set_type(int fd, partition_id partitionID, const char* type,
|
||||||
disk_job_id job);
|
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,
|
status_t pm_initialize(int fd, partition_id partitionID, const char* name,
|
||||||
const char* parameters, off_t partitionSize, disk_job_id job);
|
const char* parameters, off_t partitionSize, disk_job_id job);
|
||||||
status_t pm_uninitialize(int fd, partition_id partitionID,
|
status_t pm_uninitialize(int fd, partition_id partitionID,
|
||||||
|
@ -109,24 +109,28 @@ ChangeParametersPanel::Go(BString& name, BString& type, BString& parameters,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ChangeParametersPanel::CreateChangeControls(BPartition* parent)
|
ChangeParametersPanel::CreateChangeControls(BPartition* partition)
|
||||||
{
|
{
|
||||||
fNameTextControl = new BTextControl("Name Control",
|
fNameTextControl = new BTextControl("Name Control",
|
||||||
B_TRANSLATE("Partition name:"), "", NULL);
|
B_TRANSLATE("Partition name:"), partition->Name(), NULL);
|
||||||
fSupportsName = parent->SupportsChildName();
|
fSupportsName = partition->CanSetName();
|
||||||
|
|
||||||
fTypePopUpMenu = new BPopUpMenu("Partition Type");
|
fTypePopUpMenu = new BPopUpMenu("Partition Type");
|
||||||
|
|
||||||
int32 cookie = 0;
|
int32 cookie = 0;
|
||||||
BString supportedType;
|
BString supportedType;
|
||||||
while (parent->GetNextSupportedChildType(&cookie, &supportedType) == B_OK) {
|
BPartition* parent = partition->Parent();
|
||||||
BMessage* message = new BMessage(MSG_PARTITION_TYPE);
|
if (parent != NULL) {
|
||||||
message->AddString("type", supportedType);
|
while (parent->GetNextSupportedChildType(&cookie, &supportedType)
|
||||||
BMenuItem* item = new BMenuItem(supportedType, message);
|
== B_OK) {
|
||||||
fTypePopUpMenu->AddItem(item);
|
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)
|
if (strcmp(supportedType, kPartitionTypeBFS) == 0)
|
||||||
item->SetMarked(true);
|
item->SetMarked(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fTypeMenuField = new BMenuField(B_TRANSLATE("Partition type:"),
|
fTypeMenuField = new BMenuField(B_TRANSLATE("Partition type:"),
|
||||||
|
@ -410,9 +410,10 @@ DiskDeviceJobGenerator::_GenerateRemainingJobs(BPartition* parent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
if ((changeFlags & B_PARTITION_CHANGED_PARAMETERS)
|
if ((partition->Parameters() != NULL)
|
||||||
|| compare_string(partition->Parameters(),
|
&& ((changeFlags & B_PARTITION_CHANGED_PARAMETERS) != 0
|
||||||
partitionData->parameters)) {
|
|| compare_string(partition->Parameters(),
|
||||||
|
partitionData->parameters))) {
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
@ -441,9 +442,10 @@ DiskDeviceJobGenerator::_GenerateRemainingJobs(BPartition* parent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// content parameters
|
// content parameters
|
||||||
if ((changeFlags & B_PARTITION_CHANGED_PARAMETERS)
|
if ((partition->ContentParameters() != NULL)
|
||||||
|| compare_string(partition->ContentParameters(),
|
&& ((changeFlags & B_PARTITION_CHANGED_PARAMETERS) != 0
|
||||||
partitionData->content_parameters)) {
|
|| compare_string(partition->ContentParameters(),
|
||||||
|
partitionData->content_parameters))) {
|
||||||
status_t error = _GenerateSetContentParametersJob(partition);
|
status_t error = _GenerateSetContentParametersJob(partition);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "DiskDeviceJobQueue.h"
|
#include "DiskDeviceJobQueue.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
@ -54,7 +55,8 @@ DiskDeviceJobQueue::Execute()
|
|||||||
|
|
||||||
status_t error = job->Do();
|
status_t error = job->Do();
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
TRACE("DiskDeviceJobQueue::Execute(): executing job failed\n");
|
TRACE("DiskDeviceJobQueue::Execute(): executing job failed: %s\n",
|
||||||
|
strerror(error));
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user