"Fossies" - the Fresh Open Source Software archive 
Member "LVM/1.0.8/tools/lib/lvm_check_partitioned_dev.c" of archive lvm_1.0.8.tar.gz:
/*
* tools/lib/lvm_check_partitioned_dev.c
*
* Copyright (C) 1999 - 2001 Heinz Mauelshagen, Sistina Software
*
* March,July,August 1999
* January,April 2000
* February,November 2001
* January 2002
*
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
*
*/
/*
* Changelog
*
* 05/07/1999 - added 2.3.x new IDE majors
* 20/08/1999 - added DAC960 majors
* 31/01/2000 - use debug_enter()/debug_leave()
* 26/04/2000 - added DASD major support
* 07/02/2001 - added COMPAQ_CISS & SMART2 major support
* 17/08/2001 - added dynamic major support (Stefan Bader)
* 10/09/2001 - fixed support for *non* partitioned MDs (Luca Bera)
* 27/11/2001 - added support for DAC960 in 2.2/2.4 (Adrian Phillips)
* 27/11/2001 - fixed lvm_get_device_type() to avoid name/type mismatch
* as that caused by the DAC960 fix (Andreas Dilger)
* 16/01/2002 - ATARAID support
*
*/
#include <liblvm.h>
int lvm_partition_count(dev_t);
const lvm_device_type_t lvm_get_device_type(dev_t device);
int lvm_check_partitioned_dev(dev_t st_rdev)
{
int ret = FALSE;
debug_enter("lvm_check_partitioned_dev -- CALLED\n");
if (st_rdev == 0)
ret = -LVM_EPARAM;
else {
switch (lvm_get_device_type(st_rdev)) {
case LVM_DEVICE_TYPE_INVALID:
case LVM_DEVICE_TYPE_NBD:
case LVM_DEVICE_TYPE_LOOP:
case LVM_DEVICE_TYPE_MD:
case LVM_DEVICE_TYPE_ATARAID:
break;
default:
ret = TRUE;
}
}
debug_leave("lvm_check_partitioned_dev -- LEAVING with ret: %s\n",
ret ? "TRUE" : "FALSE");
return ret;
}
int lvm_check_whole_disk_dev(dev_t st_rdev)
{
int ret = UNDEF;
debug_enter("lvm_check_whole_disk_dev -- CALLED\n");
if (st_rdev == 0) {
ret = -LVM_EPARAM;
} else if ((MINOR(st_rdev) % lvm_partition_count(st_rdev)) == 0) {
ret = TRUE;
}
debug_leave("lvm_check_whole_disk_dev -- LEAVING with ret: %s\n",
ret ? "TRUE" : "FALSE");
return ret;
}
/* st_rdev must be valid if you are not checking the return value */
int lvm_partition_count(dev_t st_rdev)
{
int ret = -LVM_EPARAM;
debug_enter("lvm_partition_count -- CALLED for 0x%x\n", st_rdev);
if (st_rdev != 0) {
switch (lvm_get_device_type(st_rdev)) {
case LVM_DEVICE_TYPE_DASD:
ret = 4;
break;
case LVM_DEVICE_TYPE_DAC960:
ret = 8;
break;
case LVM_DEVICE_TYPE_IDE:
ret = 64;
break;
default:
ret = 16;
}
}
debug_leave("lvm_partition_count -- LEAVING with ret: %d\n", ret);
return ret;
}
int lvm_check_extended_partition(dev_t st_rdev)
{
int ret = FALSE;
debug_enter("lvm_check_extended_partition -- CALLED\n");
if (st_rdev == 0)
ret = -LVM_EPARAM;
else if (MINOR(st_rdev) % lvm_partition_count(st_rdev) > 4)
ret = TRUE;
debug_leave("lvm_check_extended_partition -- LEAVING with ret: %d\n", ret);
return ret;
}
/*
* Given the device number, find out the type of a block device by looking
* in /proc/devices and matching the major numbers.
*/
const lvm_device_type_t lvm_get_device_type(dev_t device)
{
char line[80];
struct devname_type {
char *name;
lvm_device_type_t type;
} device_names[] = {
{ "ide", LVM_DEVICE_TYPE_IDE }, /* IDE disk */
{ "sd", LVM_DEVICE_TYPE_SD }, /* SCSI disk */
{ "md", LVM_DEVICE_TYPE_MD }, /* Multiple Disk driver (SoftRAID) */
{ "loop", LVM_DEVICE_TYPE_LOOP }, /* Loop device */
{ "dasd", LVM_DEVICE_TYPE_DASD }, /* DASD disk (IBM S/390, zSeries) */
{ "rd", LVM_DEVICE_TYPE_DAC960 }, /* DAC960 (2.2 kernel name) */
{ "dac960", LVM_DEVICE_TYPE_DAC960 },/* DAC960 (2.4 kernel name) */
{ "nbd", LVM_DEVICE_TYPE_NBD }, /* Network Block Device */
{ "ida", LVM_DEVICE_TYPE_COMPAQ_SMART2 },/* Compaq SMART2 */
{ "cciss", LVM_DEVICE_TYPE_COMPAQ_CISS },/* Compaq CISS array */
{ "ubd", LVM_DEVICE_TYPE_UBD }, /* User-mode virtual block device */
{ "ataraid", LVM_DEVICE_TYPE_ATARAID }, /* ATA Raid */
{ "i2o_block", LVM_DEVICE_TYPE_I2O }, /* i2o disk */
{ NULL, LVM_DEVICE_TYPE_INVALID } /* Device not recognized */
};
FILE *procdevices = NULL;
lvm_device_type_t ret = LVM_DEVICE_TYPE_INVALID;
debug_enter("lvm_get_device_type called\n");
if ((procdevices = fopen("/proc/devices", "r")) != NULL) {
int seek_major = MAJOR(device);
int blocksection = 0;
while (fgets(line, 80, procdevices) != NULL) {
char devname[NAME_LEN];
unsigned line_major;
if (memcmp(line, "Block", 5) == 0) {
blocksection = 1;
continue;
}
/* We only want block devices ... */
if (!blocksection)
continue;
if (sscanf(line, " %u %s", &line_major, devname) != 2)
continue;
if (line_major == seek_major) {
int j;
for (j = 0; device_names[j].name != NULL; j++) {
if (strncmp(device_names[j].name, devname,
strlen(device_names[j].name)) == 0) {
ret = device_names[j].type;
break;
}
}
break;
}
}
fclose(procdevices);
}
debug_leave("lvm_get_device_type leaving with %d\n", ret);
return (ret);
}