2005-01-31 07:28:44 +03:00
/*
* volume_id - reads filesystem label and uuid
*
* Copyright ( C ) 2004 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>
2006-03-23 12:50:55 +03:00
# include "libvolume_id.h"
2005-02-23 04:58:31 +03:00
# include "util.h"
2005-01-31 07:28:44 +03:00
2005-02-09 03:02:18 +03:00
struct lvm1_super_block {
2005-08-01 03:33:36 +04:00
uint8_t id [ 2 ] ;
2006-02-21 20:44:18 +03:00
} PACKED ;
2005-02-09 03:02:18 +03:00
struct lvm2_super_block {
2005-08-01 03:33:36 +04:00
uint8_t id [ 8 ] ;
uint64_t sector_xl ;
uint32_t crc_xl ;
uint32_t offset_xl ;
uint8_t type [ 8 ] ;
2006-02-21 20:44:18 +03:00
} PACKED ;
2005-02-09 03:02:18 +03:00
2007-12-16 21:22:32 +03:00
struct lvm2_pv_header {
uint8_t id [ 32 ] ;
uint64_t devsize_xl ;
} PACKED ;
2005-01-31 07:28:44 +03:00
# define LVM1_SB_OFF 0x400
# define LVM1_MAGIC "HM"
2006-07-25 16:59:50 +04:00
int volume_id_probe_lvm1 ( struct volume_id * id , uint64_t off , uint64_t size )
2005-01-31 07:28:44 +03:00
{
2005-08-01 03:33:36 +04:00
const uint8_t * buf ;
2005-02-09 03:02:18 +03:00
struct lvm1_super_block * lvm ;
2008-04-20 23:07:06 +04:00
info ( " probing at offset 0x%llx \n " , ( unsigned long long ) off ) ;
2005-01-31 07:28:44 +03:00
buf = volume_id_get_buffer ( id , off + LVM1_SB_OFF , 0x800 ) ;
if ( buf = = NULL )
return - 1 ;
2005-02-09 03:02:18 +03:00
lvm = ( struct lvm1_super_block * ) buf ;
2005-01-31 07:28:44 +03:00
2005-02-05 06:10:48 +03:00
if ( memcmp ( lvm - > id , LVM1_MAGIC , 2 ) ! = 0 )
2005-01-31 07:28:44 +03:00
return - 1 ;
volume_id_set_usage ( id , VOLUME_ID_RAID ) ;
id - > type = " LVM1_member " ;
return 0 ;
}
# define LVM2_LABEL_ID "LABELONE"
# define LVM2LABEL_SCAN_SECTORS 4
2006-07-25 16:59:50 +04:00
int volume_id_probe_lvm2 ( struct volume_id * id , uint64_t off , uint64_t size )
2005-01-31 07:28:44 +03:00
{
2005-08-01 03:33:36 +04:00
const uint8_t * buf ;
2005-01-31 07:28:44 +03:00
unsigned int soff ;
2005-02-09 03:02:18 +03:00
struct lvm2_super_block * lvm ;
2007-12-16 21:22:32 +03:00
struct lvm2_pv_header * pvhdr ;
2005-02-09 03:02:18 +03:00
2008-04-20 23:07:06 +04:00
dbg ( " probing at offset 0x%llx \n " , ( unsigned long long ) off ) ;
2005-01-31 07:28:44 +03:00
buf = volume_id_get_buffer ( id , off , LVM2LABEL_SCAN_SECTORS * 0x200 ) ;
if ( buf = = NULL )
return - 1 ;
for ( soff = 0 ; soff < LVM2LABEL_SCAN_SECTORS * 0x200 ; soff + = 0x200 ) {
lvm = ( struct lvm2_super_block * ) & buf [ soff ] ;
2005-02-05 06:10:48 +03:00
if ( memcmp ( lvm - > id , LVM2_LABEL_ID , 8 ) = = 0 )
2005-01-31 07:28:44 +03:00
goto found ;
}
return - 1 ;
found :
2008-04-20 23:07:06 +04:00
dbg ( " found at offset 0x%x (pv hdr offset 0x%x) \n " ,
2007-12-16 21:22:32 +03:00
soff , cpu_to_le32 ( lvm - > offset_xl ) ) ;
soff + = cpu_to_le32 ( lvm - > offset_xl ) ;
pvhdr = ( struct lvm2_pv_header * ) & buf [ soff ] ;
2005-08-01 03:33:36 +04:00
memcpy ( id - > type_version , lvm - > type , 8 ) ;
2005-01-31 07:28:44 +03:00
volume_id_set_usage ( id , VOLUME_ID_RAID ) ;
2007-12-16 21:22:32 +03:00
volume_id_set_uuid ( id , pvhdr - > id , 0 , UUID_LVM ) ;
2005-01-31 07:28:44 +03:00
id - > type = " LVM2_member " ;
return 0 ;
}