1/* 2 * volume_id - reads filesystem label and uuid 3 * 4 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation version 2 of the License. 9 */ 10 11#ifndef _GNU_SOURCE 12#define _GNU_SOURCE 1 13#endif 14 15#ifdef HAVE_CONFIG_H 16# include <config.h> 17#endif 18 19#include <stdio.h> 20#include <stdlib.h> 21#include <unistd.h> 22#include <string.h> 23#include <errno.h> 24#include <ctype.h> 25 26#include "libvolume_id.h" 27#include "util.h" 28 29struct lvm1_super_block { 30 uint8_t id[2]; 31} PACKED; 32 33struct lvm2_super_block { 34 uint8_t id[8]; 35 uint64_t sector_xl; 36 uint32_t crc_xl; 37 uint32_t offset_xl; 38 uint8_t type[8]; 39} PACKED; 40 41#define LVM1_SB_OFF 0x400 42#define LVM1_MAGIC "HM" 43 44int volume_id_probe_lvm1(struct volume_id *id, uint64_t off, uint64_t size) 45{ 46 const uint8_t *buf; 47 struct lvm1_super_block *lvm; 48 49 info("probing at offset 0x%llx", (unsigned long long) off); 50 51 buf = volume_id_get_buffer(id, off + LVM1_SB_OFF, 0x800); 52 if (buf == NULL) 53 return -1; 54 55 lvm = (struct lvm1_super_block *) buf; 56 57 if (memcmp(lvm->id, LVM1_MAGIC, 2) != 0) 58 return -1; 59 60 volume_id_set_usage(id, VOLUME_ID_RAID); 61 id->type = "LVM1_member"; 62 63 return 0; 64} 65 66#define LVM2_LABEL_ID "LABELONE" 67#define LVM2LABEL_SCAN_SECTORS 4 68 69int volume_id_probe_lvm2(struct volume_id *id, uint64_t off, uint64_t size) 70{ 71 const uint8_t *buf; 72 unsigned int soff; 73 struct lvm2_super_block *lvm; 74 75 dbg("probing at offset 0x%llx", (unsigned long long) off); 76 77 buf = volume_id_get_buffer(id, off, LVM2LABEL_SCAN_SECTORS * 0x200); 78 if (buf == NULL) 79 return -1; 80 81 82 for (soff = 0; soff < LVM2LABEL_SCAN_SECTORS * 0x200; soff += 0x200) { 83 lvm = (struct lvm2_super_block *) &buf[soff]; 84 85 if (memcmp(lvm->id, LVM2_LABEL_ID, 8) == 0) 86 goto found; 87 } 88 89 return -1; 90 91found: 92 memcpy(id->type_version, lvm->type, 8); 93 volume_id_set_usage(id, VOLUME_ID_RAID); 94 id->type = "LVM2_member"; 95 96 return 0; 97} 98