Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3155128
iddev.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
iddev.c
View Options
/******************************************************************************
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
** Copyright (C) 2004 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
** of the GNU General Public License v.2.
**
*******************************************************************************
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "linux_endian.h"
#include "iddev.h"
/**
* check_for_gfs - check to see if GFS is on this device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* An EINVAL returned from lseek means that the device was too
* small -- at least on Linux.
*
* Returns: -1 on error (with errno set), 1 if not GFS,
* 0 if GFS found (with type set)
*/
static int
check_for_gfs(int fd, char *type, unsigned type_len)
{
unsigned char buf[512];
uint32_t *p = (uint32_t *)buf;
int error;
error = lseek(fd, 65536, SEEK_SET);
if (error < 0)
return (errno == EINVAL) ? 1 : error;
else if (error != 65536) {
errno = EINVAL;
return -1;
}
error = read(fd, buf, 512);
if (error < 0)
return error;
else if (error < 8)
return 1;
if (be32_to_cpu(*p) != 0x01161970 ||
be32_to_cpu(*(p + 1)) != 1)
return 1;
snprintf(type, type_len, "GFS filesystem");
return 0;
}
/**
* check_for_pool - check to see if Pool is on this device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* Returns: -1 on error (with errno set), 1 if not Pool,
* 0 if Pool found (with type set)
*/
static int
check_for_pool(int fd, char *type, unsigned type_len)
{
unsigned char buf[512];
uint64_t *p = (uint64_t *)buf;
int error;
error = lseek(fd, 0, SEEK_SET);
if (error < 0)
return error;
else if (error != 0) {
errno = EINVAL;
return -1;
}
error = read(fd, buf, 512);
if (error < 0)
return error;
else if (error < 8)
return 1;
if (be64_to_cpu(*p) != 0x11670)
return 1;
snprintf(type, type_len, "Pool subdevice");
return 0;
}
/**
* check_for_partition - check to see if Partition is on this device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* Returns: -1 on error (with errno set), 1 if not Partition,
* 0 if Partition found (with type set)
*/
static int
check_for_partition(int fd, char *type, unsigned type_len)
{
unsigned char buf[512];
int error;
error = lseek(fd, 0, SEEK_SET);
if (error < 0)
return error;
else if (error != 0) {
errno = EINVAL;
return -1;
}
error = read(fd, buf, 512);
if (error < 0)
return error;
else if (error < 512)
return 1;
if (buf[510] != 0x55 || buf[511] != 0xAA)
return 1;
snprintf(type, type_len, "partition information");
return 0;
}
/**
* check_for_ext23 - check to see if EXT23 is on this device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* An EINVAL returned from lseek means that the device was too
* small -- at least on Linux.
*
* Returns: -1 on error (with errno set), 1 if not EXT23,
* 0 if EXT23 found (with type set)
*/
static int
check_for_ext23(int fd, char *type, unsigned type_len)
{
unsigned char buf[512];
uint16_t *p = (uint16_t *)buf;
int error;
error = lseek(fd, 1024, SEEK_SET);
if (error < 0)
return (errno == EINVAL) ? 1 : error;
else if (error != 1024) {
errno = EINVAL;
return -1;
}
error = read(fd, buf, 512);
if (error < 0)
return error;
else if (error < 58)
return 1;
if (le16_to_cpu(p[28]) != 0xEF53)
return 1;
snprintf(type, type_len, "EXT2/3 filesystem");
return 0;
}
/**
* check_for_swap - check to see if SWAP is on this device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* Returns: -1 on error (with errno set), 1 if not SWAP,
* 0 if SWAP found (with type set)
*/
static int
check_for_swap(int fd, char *type, unsigned type_len)
{
unsigned char buf[8192];
int error;
error = lseek(fd, 0, SEEK_SET);
if (error < 0)
return error;
else if (error != 0) {
errno = EINVAL;
return -1;
}
error = read(fd, buf, 8192);
if (error < 0)
return error;
else if (error < 4096)
return 1;
if (memcmp(buf + 4086, "SWAP-SPACE", 10) &&
memcmp(buf + 4086, "SWAPSPACE2", 10))
return 1;
snprintf(type, type_len, "swap device");
return 0;
}
/**
* check_for_lvm1 - check to see if LVM1 is on this device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* Returns: -1 on error (with errno set), 1 if not LVM1,
* 0 if LVM1 found (with type set)
*/
static int
check_for_lvm1(int fd, char *type, unsigned type_len)
{
unsigned char buf[512];
int error;
error = lseek(fd, 0, SEEK_SET);
if (error < 0)
return error;
else if (error != 0) {
errno = EINVAL;
return -1;
}
error = read(fd, buf, 512);
if (error < 0)
return error;
else if (error < 2)
return 1;
if (buf[0] != 'H' || buf[1] != 'M')
return 1;
snprintf(type, type_len, "lvm1 subdevice");
return 0;
}
/**
* check_for_lvm2 - check to see if LVM2 is on this device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* Returns: -1 on error (with errno set), 1 if not LVM2,
* 0 if LVM1 found (with type set)
*/
static int
check_for_lvm2(int fd, char *type, unsigned type_len)
{
unsigned char buf[512];
int error;
int i;
/* LVM 2 labels can start in sectors 1-4 */
for (i = 1; i < 5; i++) {
error = lseek(fd, 512 * i, SEEK_SET);
if (error < 0)
return (errno == EINVAL) ? 1 : error;
else if (error != 512 * i) {
errno = EINVAL;
return -1;
}
error = read(fd, buf, 512);
if (error < 0)
return error;
else if (error < 32)
return 1;
if (strncmp(buf, "LABELONE", 8) != 0)
continue;
if (((uint64_t *) buf)[1] != i)
continue;
/* FIXME: should check the CRC of the label here */
if (strncmp(&buf[24], "LVM2 001", 8) != 0)
continue;
snprintf(type, type_len, "lvm2 subdevice");
return 0;
}
return 1;
}
/**
* check_for_cidev - check to see if CIDEV is on this device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* Returns: -1 on error (with errno set), 1 if not CIDEV,
* 0 if CIDEV found (with type set)
*/
static int
check_for_cidev(int fd, char *type, unsigned type_len)
{
unsigned char buf[512];
uint32_t *p = (uint32_t *) buf;
int error;
error = lseek(fd, 0, SEEK_SET);
if (error < 0)
return error;
else if (error != 0) {
errno = EINVAL;
return -1;
}
error = read(fd, buf, 512);
if (error < 0)
return error;
else if (error < 4)
return 1;
if (be32_to_cpu(*p) != 0x47465341)
return 1;
snprintf(type, type_len, "CIDEV");
return 0;
}
/**
* check_for_cca - check to see if CCA is on this device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* Returns: -1 on error (with errno set), 1 if not CCA,
* 0 if CCA found (with type set)
*/
static int
check_for_cca(int fd, char *type, unsigned type_len)
{
unsigned char buf[512];
uint32_t *p = (uint32_t *) buf;
int error;
error = lseek(fd, 0, SEEK_SET);
if (error < 0)
return error;
else if (error != 0) {
errno = EINVAL;
return -1;
}
error = read(fd, buf, 512);
if (error < 0)
return error;
else if (error < 4)
return 1;
if (be32_to_cpu(*p) != 0x122473)
return 1;
snprintf(type, type_len, "CCA device");
return 0;
}
/**
* check_for_reiserfs - check to see if reisterfs is on this device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* Returns: -1 on error (with errno set), 1 if not reiserfs,
* 0 if CCA found (with type set)
*/
static int
check_for_reiserfs(int fd, char *type, unsigned type_len)
{
unsigned int pass;
uint64_t offset;
unsigned char buf[512];
int error;
for (pass = 0; pass < 2; pass++) {
offset = (pass) ? 65536 : 8192;
error = lseek(fd, offset, SEEK_SET);
if (error < 0)
return (errno == EINVAL) ? 1 : error;
else if (error != offset) {
errno = EINVAL;
return -1;
}
error = read(fd, buf, 512);
if (error < 0)
return error;
else if (error < 62)
return 1;
if (strncmp(buf + 52, "ReIsErFs", 8) == 0 ||
strncmp(buf + 52, "ReIsEr2Fs", 9) == 0 ||
strncmp(buf + 52, "ReIsEr3Fs", 9) == 0) {
snprintf(type, type_len, "Reiserfs filesystem");
return 0;
}
}
return 1;
}
/**
* identify_device - figure out what's on a device
* @fd: a file descriptor open on a device open for (at least) reading
* @type: a buffer that contains the type of filesystem
* @type_len: the amount of space pointed to by @type
*
* The offset of @fd will be changed by this function.
* This routine will not write to the device.
*
* Returns: -1 on error (with errno set), 1 if unabled to identify,
* 0 if device identified (with type set)
*/
int
identify_device(int fd, char *type, unsigned type_len)
{
int error;
if (!type || !type_len) {
errno = EINVAL;
return -1;
}
error = check_for_pool(fd, type, type_len);
if (error <= 0)
return error;
error = check_for_lvm1(fd, type, type_len);
if (error <= 0)
return error;
error = check_for_lvm2(fd, type, type_len);
if (error <= 0)
return error;
error = check_for_cidev(fd, type, type_len);
if (error <= 0)
return error;
error = check_for_cca(fd, type, type_len);
if (error <= 0)
return error;
error = check_for_gfs(fd, type, type_len);
if (error <= 0)
return error;
error = check_for_ext23(fd, type, type_len);
if (error <= 0)
return error;
error = check_for_reiserfs(fd, type, type_len);
if (error <= 0)
return error;
error = check_for_swap(fd, type, type_len);
if (error <= 0)
return error;
error = check_for_partition(fd, type, type_len);
if (error <= 0)
return error;
return 1;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Wed, Feb 26, 7:44 PM (2 h, 31 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1465704
Default Alt Text
iddev.c (11 KB)
Attached To
Mode
rF Fence Agents
Attached
Detach File
Event Timeline
Log In to Comment