2005-01-31 07:28:44 +03:00
/*
2006-03-21 18:16:55 +03:00
* volume_id - reads volume label and uuid
2005-01-31 07:28:44 +03:00
*
* Copyright ( C ) 2005 Kay Sievers < kay . sievers @ vrfy . org >
*
2005-09-27 18:27:35 +04:00
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation version 2 of the License .
2005-01-31 07:28:44 +03:00
*/
# ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# endif
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# include <errno.h>
# include <ctype.h>
# include <fcntl.h>
# include <sys/stat.h>
2006-03-23 12:50:55 +03:00
# include "libvolume_id.h"
2005-01-31 07:28:44 +03:00
# include "util.h"
2006-03-27 19:59:22 +04:00
/* the user can overwrite this log function */
static void default_log ( int priority , const char * file , int line , const char * format , . . . )
{
return ;
}
2006-03-28 04:52:58 +04:00
volume_id_log_fn_t volume_id_log_fn = default_log ;
2005-01-31 07:28:44 +03:00
2006-02-21 20:48:28 +03:00
int volume_id_probe_raid ( struct volume_id * id , uint64_t off , uint64_t size )
2005-01-31 07:28:44 +03:00
{
if ( id = = NULL )
return - EINVAL ;
2006-04-28 19:52:09 +04:00
info ( " probing at offset 0x%llx, size 0x%llx " ,
( unsigned long long ) off , ( unsigned long long ) size ) ;
2006-03-27 22:22:00 +04:00
/* probe for raid first, because fs probes may be successful on raid members */
2005-03-12 02:14:38 +03:00
if ( size ) {
if ( volume_id_probe_linux_raid ( id , off , size ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-03-12 02:14:38 +03:00
if ( volume_id_probe_intel_software_raid ( id , off , size ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-03-12 02:14:38 +03:00
if ( volume_id_probe_lsi_mega_raid ( id , off , size ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-03-12 02:14:38 +03:00
if ( volume_id_probe_via_raid ( id , off , size ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-03-12 02:14:38 +03:00
if ( volume_id_probe_silicon_medley_raid ( id , off , size ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-03-12 02:14:38 +03:00
if ( volume_id_probe_nvidia_raid ( id , off , size ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-03-12 02:14:38 +03:00
if ( volume_id_probe_promise_fasttrack_raid ( id , off , size ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-03-12 02:14:38 +03:00
if ( volume_id_probe_highpoint_45x_raid ( id , off , size ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-03-12 02:14:38 +03:00
}
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_lvm1 ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_lvm2 ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
2005-03-12 02:14:38 +03:00
if ( volume_id_probe_highpoint_37x_raid ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
2006-02-21 21:14:43 +03:00
return - 1 ;
found :
2006-02-21 20:48:28 +03:00
/* If recognized, we free the allocated buffers */
volume_id_free_buffer ( id ) ;
return 0 ;
}
int volume_id_probe_filesystem ( struct volume_id * id , uint64_t off , uint64_t size )
{
if ( id = = NULL )
return - EINVAL ;
2006-04-28 19:52:09 +04:00
info ( " probing at offset 0x%llx, size 0x%llx " ,
( unsigned long long ) off , ( unsigned long long ) size ) ;
2005-02-23 04:58:31 +03:00
if ( volume_id_probe_luks ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-02-23 04:58:31 +03:00
2005-01-31 07:28:44 +03:00
/* signature in the first block, only small buffer needed */
if ( volume_id_probe_vfat ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_xfs ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
/* fill buffer with maximum */
volume_id_get_buffer ( id , 0 , SB_BUFFER_SIZE ) ;
if ( volume_id_probe_linux_swap ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_ext ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_reiserfs ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_jfs ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_udf ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_iso9660 ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_hfs_hfsplus ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_ufs ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
if ( volume_id_probe_ntfs ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-01-31 07:28:44 +03:00
2005-02-05 06:10:48 +03:00
if ( volume_id_probe_cramfs ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-02-05 06:10:48 +03:00
2005-02-09 03:02:18 +03:00
if ( volume_id_probe_romfs ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-02-09 03:02:18 +03:00
if ( volume_id_probe_hpfs ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-02-09 03:02:18 +03:00
2005-02-23 04:58:31 +03:00
if ( volume_id_probe_sysv ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-02-23 04:58:31 +03:00
2005-03-06 14:16:32 +03:00
if ( volume_id_probe_minix ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-03-06 14:16:32 +03:00
2005-10-23 18:08:56 +04:00
if ( volume_id_probe_ocfs1 ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-10-23 18:08:56 +04:00
2005-07-17 17:54:40 +04:00
if ( volume_id_probe_ocfs2 ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-07-17 17:54:40 +04:00
2005-10-23 18:31:13 +04:00
if ( volume_id_probe_vxfs ( id , off ) = = 0 )
2006-02-21 21:14:43 +03:00
goto found ;
2005-10-23 18:31:13 +04:00
2006-03-08 21:44:28 +03:00
if ( volume_id_probe_squashfs ( id , off ) = = 0 )
goto found ;
2006-05-09 10:46:07 +04:00
if ( volume_id_probe_netware ( id , off ) = = 0 )
goto found ;
2005-01-31 07:28:44 +03:00
return - 1 ;
2006-02-21 21:14:43 +03:00
found :
2006-02-21 20:48:28 +03:00
/* If recognized, we free the allocated buffers */
2005-01-31 07:28:44 +03:00
volume_id_free_buffer ( id ) ;
return 0 ;
}
2006-02-21 20:48:28 +03:00
int volume_id_probe_all ( struct volume_id * id , uint64_t off , uint64_t size )
{
if ( id = = NULL )
return - EINVAL ;
if ( volume_id_probe_raid ( id , off , size ) = = 0 )
return 0 ;
if ( volume_id_probe_filesystem ( id , off , size ) = = 0 )
return 0 ;
return - 1 ;
}
2005-01-31 07:28:44 +03:00
/* open volume by already open file descriptor */
struct volume_id * volume_id_open_fd ( int fd )
{
struct volume_id * id ;
id = malloc ( sizeof ( struct volume_id ) ) ;
if ( id = = NULL )
return NULL ;
memset ( id , 0x00 , sizeof ( struct volume_id ) ) ;
id - > fd = fd ;
return id ;
}
/* open volume by device node */
struct volume_id * volume_id_open_node ( const char * path )
{
struct volume_id * id ;
int fd ;
fd = open ( path , O_RDONLY ) ;
if ( fd < 0 ) {
dbg ( " unable to open '%s' " , path ) ;
return NULL ;
}
id = volume_id_open_fd ( fd ) ;
if ( id = = NULL )
return NULL ;
/* close fd on device close */
id - > fd_close = 1 ;
return id ;
}
void volume_id_close ( struct volume_id * id )
{
if ( id = = NULL )
return ;
if ( id - > fd_close ! = 0 )
close ( id - > fd ) ;
volume_id_free_buffer ( id ) ;
free ( id ) ;
}