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 swap_header_v1_2 { 30 uint8_t bootbits[1024]; 31 uint32_t version; 32 uint32_t last_page; 33 uint32_t nr_badpages; 34 uint8_t uuid[16]; 35 uint8_t volume_name[16]; 36} PACKED; 37 38#define LARGEST_PAGESIZE 0x4000 39 40int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off, uint64_t size) 41{ 42 const uint8_t *buf; 43 unsigned int page; 44 struct swap_header_v1_2 *sw; 45 46 info("probing at offset 0x%llx", (unsigned long long) off); 47 48 /* eek, the swap signature is at the end of the PAGE_SIZE */ 49 for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) { 50 buf = volume_id_get_buffer(id, off + page-10, 10); 51 if (buf == NULL) 52 return -1; 53 54 if (memcmp(buf, "SWAP-SPACE", 10) == 0) { 55 strcpy(id->type_version, "1"); 56 goto found; 57 } 58 59 if (memcmp(buf, "SWAPSPACE2", 10) == 0) { 60 id->type = "swap"; 61 strcpy(id->type_version, "2"); 62 goto found_label; 63 } 64 65 if (memcmp(buf, "S1SUSPEND", 9) == 0) { 66 id->type = "suspend"; 67 strcpy(id->type_version, "s1suspend"); 68 goto found_label; 69 } 70 71 if (memcmp(buf, "ULSUSPEND", 9) == 0) { 72 id->type = "suspend"; 73 strcpy(id->type_version, "ulsuspend"); 74 goto found_label; 75 } 76 } 77 return -1; 78 79found_label: 80 sw = (struct swap_header_v1_2 *) volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2)); 81 if (sw != NULL) { 82 volume_id_set_label_raw(id, sw->volume_name, 16); 83 volume_id_set_label_string(id, sw->volume_name, 16); 84 volume_id_set_uuid(id, sw->uuid, 0, UUID_DCE); 85 } 86 87found: 88 volume_id_set_usage(id, VOLUME_ID_OTHER); 89 return 0; 90} 91