/**
* @file
*
* @ingroup rtems_bdpart
*
* @brief Block Device Partition Management
*/
/*
* Copyright (c) 2009, 2012 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <rtems.h>
#include <rtems/bdpart.h>
static char *create_logical_disk_name( const char *disk_name, char **marker)
{
size_t disk_name_size = strlen( disk_name);
char *logical_disk_name = malloc( disk_name_size + RTEMS_BDPART_NUMBER_SIZE);
if (logical_disk_name != NULL) {
/* The string is NUL terminated by (A) ... */
memcpy( logical_disk_name, disk_name, disk_name_size);
*marker = logical_disk_name + disk_name_size;
}
return logical_disk_name;
}
static rtems_status_code update_logical_disk_name(
char *logical_disk_marker,
size_t i
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int rv = 0;
/* ... (A) */
rv = snprintf( logical_disk_marker, RTEMS_BDPART_NUMBER_SIZE, "%zu", i + 1);
if (rv >= RTEMS_BDPART_NUMBER_SIZE) {
sc = RTEMS_INVALID_NAME;
}
return sc;
}
rtems_status_code rtems_bdpart_register(
const char *disk_name,
const rtems_bdpart_partition *pt,
size_t count
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_status_code esc = RTEMS_SUCCESSFUL;
rtems_blkdev_bnum disk_end = 0;
char *logical_disk_name = NULL;
char *logical_disk_marker = NULL;
size_t i = 0;
int fd = -1;
rtems_disk_device *dd = NULL;
/* Get disk data */
sc = rtems_bdpart_get_disk_data( disk_name, &fd, &dd, &disk_end);
if (sc != RTEMS_SUCCESSFUL) {
return sc;
}
/* Create logical disk name */
logical_disk_name = create_logical_disk_name(
disk_name,
&logical_disk_marker
);
if (logical_disk_name == NULL) {
esc = sc;
goto cleanup;
}
/* Create a logical disk for each partition */
for (i = 0; i < count; ++i) {
const rtems_bdpart_partition *p = pt + i;
/* Set partition number for logical disk name */
sc = update_logical_disk_name( logical_disk_marker, i);
if (sc != RTEMS_SUCCESSFUL) {
esc = sc;
goto cleanup;
}
/* Create logical disk */
sc = rtems_blkdev_create_partition(
logical_disk_name,
disk_name,
p->begin,
p->end - p->begin
);
if (sc != RTEMS_SUCCESSFUL) {
esc = sc;
goto cleanup;
}
}
cleanup:
free( logical_disk_name);
close( fd);
return esc;
}
rtems_status_code rtems_bdpart_register_from_disk( const char *disk_name)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_bdpart_format format;
rtems_bdpart_partition pt [RTEMS_BDPART_PARTITION_NUMBER_HINT];
size_t count = RTEMS_BDPART_PARTITION_NUMBER_HINT;
/* Read partitions */
sc = rtems_bdpart_read( disk_name, &format, pt, &count);
if (sc != RTEMS_SUCCESSFUL) {
return sc;
}
/* Register partitions */
return rtems_bdpart_register( disk_name, pt, count);
}
rtems_status_code rtems_bdpart_unregister(
const char *disk_name,
const rtems_bdpart_partition *pt RTEMS_UNUSED,
size_t count
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_status_code esc = RTEMS_SUCCESSFUL;
rtems_blkdev_bnum disk_end = 0;
char *logical_disk_name = NULL;
char *logical_disk_marker = NULL;
size_t i = 0;
int fd = -1;
rtems_disk_device *dd = NULL;
/* Get disk data */
sc = rtems_bdpart_get_disk_data( disk_name, &fd, &dd, &disk_end);
if (sc != RTEMS_SUCCESSFUL) {
return sc;
}
/* Create logical disk name */
logical_disk_name = create_logical_disk_name(
disk_name,
&logical_disk_marker
);
if (logical_disk_name == NULL) {
esc = sc;
goto cleanup;
}
/* Delete the logical disk for each partition */
for (i = 0; i < count; ++i) {
int rv = 0;
/* Set partition number for logical disk name */
sc = update_logical_disk_name( logical_disk_marker, i);
if (sc != RTEMS_SUCCESSFUL) {
esc = sc;
goto cleanup;
}
/* Delete logical disk */
rv = unlink( logical_disk_name);
if (rv != 0) {
esc = sc;
goto cleanup;
}
}
cleanup:
free( logical_disk_name);
close( fd);
return esc;
}