mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
C2: Add icsneoc2_device_force_disk_config_update
This commit is contained in:
committed by
Kyle Schwarz
parent
9d91524dc0
commit
19232def41
@@ -71,6 +71,7 @@ icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* valu
|
||||
"Close failed", // icsneoc2_error_close_failed
|
||||
"Reconnect failed", // icsneoc2_error_reconnect_failed
|
||||
"Invalid data", // icsneoc2_error_invalid_data
|
||||
"Force disk config update failed", // icsneoc2_error_force_disk_config_update_failed
|
||||
};
|
||||
static_assert(std::size(error_strings) == icsneoc2_error_maxsize,
|
||||
"error_strings is out of sync with _icsneoc2_error_t enum - update both together");
|
||||
@@ -1097,6 +1098,21 @@ icsneoc2_error_t icsneoc2_device_format_disk(const icsneoc2_device_t* device, ic
|
||||
return icsneoc2_error_success;
|
||||
}
|
||||
|
||||
icsneoc2_error_t icsneoc2_device_force_disk_config_update(const icsneoc2_device_t* device, icsneoc2_disk_details_t* disk_details) {
|
||||
auto res = icsneoc2_device_is_valid(device);
|
||||
if(res != icsneoc2_error_success) {
|
||||
return res;
|
||||
}
|
||||
if(!disk_details || !disk_details->details) {
|
||||
return icsneoc2_error_invalid_parameters;
|
||||
}
|
||||
|
||||
if(!device->device->forceDiskConfigUpdate(*disk_details->details)) {
|
||||
return icsneoc2_error_force_disk_config_update_failed;
|
||||
}
|
||||
return icsneoc2_error_success;
|
||||
}
|
||||
|
||||
static icsneoc2_error_t get_supported_networks(const icsneoc2_device_t* device, const std::vector<Network>& nets, icsneoc2_netid_t* networks, size_t* count) {
|
||||
auto res = icsneoc2_device_is_valid(device);
|
||||
if(res != icsneoc2_error_success) {
|
||||
|
||||
@@ -109,6 +109,85 @@ int main() {
|
||||
}
|
||||
}
|
||||
|
||||
/* Choose operation */
|
||||
printf("\n\tChoose operation:\n");
|
||||
printf("\t [f] Format the disk(s)\n");
|
||||
printf("\t [u] Update the disk configuration without formatting\n");
|
||||
printf("\t [q] Quit\n");
|
||||
printf("\tSelection [f/u/q]: ");
|
||||
char choice[8] = {0};
|
||||
if(scanf("%7s", choice) != 1) {
|
||||
choice[0] = 'q';
|
||||
}
|
||||
|
||||
if(choice[0] == 'u' || choice[0] == 'U') {
|
||||
/* Force a disk config update (e.g. changing the disk layout) without formatting.
|
||||
* Unlike a format, this preserves the existing data on the disk(s). */
|
||||
printf("\n\tChoose disk layout:\n");
|
||||
printf("\t [s] Spanned\n");
|
||||
printf("\t [r] RAID0\n");
|
||||
printf("\tSelection [s/r] (current: %s): ", layout == icsneoc2_disk_layout_raid0 ? "RAID0" : "Spanned");
|
||||
char layout_choice[8] = {0};
|
||||
if(scanf("%7s", layout_choice) != 1) {
|
||||
layout_choice[0] = '\0';
|
||||
}
|
||||
if(layout_choice[0] == 'r' || layout_choice[0] == 'R') {
|
||||
icsneoc2_disk_details_layout_set(details, icsneoc2_disk_layout_raid0);
|
||||
} else if(layout_choice[0] == 's' || layout_choice[0] == 'S') {
|
||||
icsneoc2_disk_details_layout_set(details, icsneoc2_disk_layout_spanned);
|
||||
} else {
|
||||
printf("\tKeeping current layout.\n");
|
||||
}
|
||||
|
||||
/* Enable/disable individual disks in the configuration. A disk's enabled
|
||||
* state is carried by the FORMATTED flag; only present disks can be enabled. */
|
||||
for(size_t i = 0; i < detail_count; i++) {
|
||||
icsneoc2_disk_format_flags_t flags = 0;
|
||||
icsneoc2_disk_details_flags_get(details, i, &flags);
|
||||
if(!(flags & ICSNEOC2_DISK_FORMAT_FLAGS_PRESENT)) {
|
||||
continue; /* Can't enable a disk that isn't present */
|
||||
}
|
||||
printf("\tEnable disk [%zu]? [y/N] (currently %s): ", i,
|
||||
(flags & ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED) ? "enabled" : "disabled");
|
||||
char disk_choice[8] = {0};
|
||||
if(scanf("%7s", disk_choice) != 1) {
|
||||
disk_choice[0] = '\0';
|
||||
}
|
||||
if(disk_choice[0] == 'y' || disk_choice[0] == 'Y') {
|
||||
flags |= ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED;
|
||||
} else {
|
||||
flags &= ~(icsneoc2_disk_format_flags_t)ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED;
|
||||
}
|
||||
icsneoc2_disk_details_flags_set(details, i, flags);
|
||||
}
|
||||
|
||||
icsneoc2_disk_layout_t new_layout = 0;
|
||||
icsneoc2_disk_details_layout_get(details, &new_layout);
|
||||
printf("\n\tForcing disk config update on %s to %s layout (no data will be erased)...\n",
|
||||
description, new_layout == icsneoc2_disk_layout_raid0 ? "RAID0" : "Spanned");
|
||||
res = icsneoc2_device_force_disk_config_update(device, details);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_error_code("\tForce disk config update failed", res);
|
||||
icsneoc2_disk_details_free(details);
|
||||
icsneoc2_device_close(device);
|
||||
icsneoc2_device_free(device);
|
||||
return -1;
|
||||
}
|
||||
printf("\tDisk config update complete!\n");
|
||||
icsneoc2_disk_details_free(details);
|
||||
icsneoc2_device_close(device);
|
||||
icsneoc2_device_free(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(choice[0] != 'f' && choice[0] != 'F') {
|
||||
printf("\tAborted.\n");
|
||||
icsneoc2_disk_details_free(details);
|
||||
icsneoc2_device_close(device);
|
||||
icsneoc2_device_free(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Build format config: mark present disks for formatting */
|
||||
bool any_present = false;
|
||||
for(size_t i = 0; i < detail_count; i++) {
|
||||
|
||||
@@ -18,7 +18,8 @@ enum class DiskLayout : uint8_t {
|
||||
struct DiskInfo {
|
||||
bool present; // Disk is connected
|
||||
bool initialized; // Disk is initialized
|
||||
bool formatted; // Disk is formatted
|
||||
// getDiskDetails: disk is formatted | formatDisk: disk to format | forceDiskConfigUpdate: disk enabled in layout (also reported as formatted)
|
||||
bool formatted;
|
||||
|
||||
uint64_t sectors;
|
||||
uint32_t bytesPerSector;
|
||||
|
||||
@@ -47,6 +47,7 @@ typedef enum _icsneoc2_error_t {
|
||||
icsneoc2_error_close_failed, // Failed to close device
|
||||
icsneoc2_error_reconnect_failed, // Failed to reconnect to device
|
||||
icsneoc2_error_invalid_data, // Failed to get/set data due to invalid data pointer or size
|
||||
icsneoc2_error_force_disk_config_update_failed, // Failed to force a disk config update
|
||||
// NOTE: Any new values added here should be updated in icsneoc2_error_code_get
|
||||
icsneoc2_error_maxsize
|
||||
} _icsneoc2_error_t;
|
||||
@@ -846,6 +847,24 @@ icsneoc2_error_t icsneoc2_disk_details_full_format_set(const icsneoc2_disk_detai
|
||||
*/
|
||||
icsneoc2_error_t icsneoc2_device_format_disk(const icsneoc2_device_t* device, icsneoc2_disk_details_t* disk_details, icsneoc2_disk_format_progress_fn progress_callback, void* user_data);
|
||||
|
||||
/**
|
||||
* Force a disk layout/configuration change on a device without formatting.
|
||||
*
|
||||
* Unlike icsneoc2_device_format_disk(), this applies the configuration described by the
|
||||
* disk details handle (such as the disk layout) and enables the change without erasing data.
|
||||
*
|
||||
* @param[in] device The device whose disk configuration should be updated.
|
||||
* @param[in] disk_details A disk details handle describing the desired configuration.
|
||||
* Use icsneoc2_device_disk_details_get() to obtain a handle, then modify it
|
||||
* (e.g. set the layout with icsneoc2_disk_details_layout_set()).
|
||||
* In this context the per-disk ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED flag
|
||||
* selects whether that disk is enabled in the layout (no formatting occurs).
|
||||
*
|
||||
* @return icsneoc2_error_t icsneoc2_error_success if successful,
|
||||
* icsneoc2_error_force_disk_config_update_failed otherwise.
|
||||
*/
|
||||
icsneoc2_error_t icsneoc2_device_force_disk_config_update(const icsneoc2_device_t* device, icsneoc2_disk_details_t* disk_details);
|
||||
|
||||
/**
|
||||
* Get the list of networks this device supports for receiving.
|
||||
*
|
||||
|
||||
@@ -413,7 +413,7 @@ typedef uint8_t icsneoc2_disk_layout_t;
|
||||
|
||||
#define ICSNEOC2_DISK_FORMAT_FLAGS_PRESENT 0x1 // Indicates that the disk is present
|
||||
#define ICSNEOC2_DISK_FORMAT_FLAGS_INITIALIZED 0x2 // Indicates that the disk is initialized
|
||||
#define ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED 0x4 // Indicates that the disk is already formatted
|
||||
#define ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED 0x4 // disk_details_get: disk is formatted | format_disk: disk to format | force_disk_config_update: disk enabled in layout (also reported as formatted)
|
||||
|
||||
typedef uint32_t icsneoc2_disk_format_flags_t;
|
||||
|
||||
|
||||
@@ -338,6 +338,7 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
|
||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_supports_disk_formatting(NULL, &placeholderBool));
|
||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_disk_details_get(NULL, NULL));
|
||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_format_disk(NULL, NULL, NULL, NULL));
|
||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_force_disk_config_update(NULL, NULL));
|
||||
|
||||
// Disk details accessors with NULL details
|
||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_disk_details_count_get(NULL, &placeholderSizeT));
|
||||
@@ -1391,6 +1392,16 @@ TEST(icsneoc2, test_icsneoc2_format_disk_error_code)
|
||||
ASSERT_STREQ(error_str, "Disk format failed");
|
||||
}
|
||||
|
||||
TEST(icsneoc2, test_icsneoc2_force_disk_config_update_error_code)
|
||||
{
|
||||
// Verify the new error code exists and has a valid string
|
||||
char error_str[64] = {0};
|
||||
size_t error_str_len = sizeof(error_str);
|
||||
ASSERT_EQ(icsneoc2_error_success, icsneoc2_error_code_get(icsneoc2_error_force_disk_config_update_failed, error_str, &error_str_len));
|
||||
ASSERT_GT(error_str_len, 0u);
|
||||
ASSERT_STREQ(error_str, "Force disk config update failed");
|
||||
}
|
||||
|
||||
TEST(icsneoc2, test_icsneoc2_memory_type_enums)
|
||||
{
|
||||
// Memory type enum values should match Disk::MemoryType
|
||||
|
||||
Reference in New Issue
Block a user