1 /*	$NetBSD: dev-swap.c,v 1.2 2009/12/02 01:53:25 haad Exp $	*/
2 
3 /*
4  * Copyright (C) 2009 Red Hat, Inc. All rights reserved.
5  *
6  * This file is part of LVM2.
7  *
8  * This copyrighted material is made available to anyone wishing to use,
9  * modify, copy, or redistribute it subject to the terms and conditions
10  * of the GNU Lesser General Public License v.2.1.
11  *
12  * You should have received a copy of the GNU Lesser General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16 
17 #include "lib.h"
18 #include "metadata.h"
19 #include "xlate.h"
20 #include "filter.h"
21 
22 #ifdef linux
23 
24 #define MAX_PAGESIZE	(64 * 1024)
25 #define SIGNATURE_SIZE  10
26 
27 static int
28 _swap_detect_signature(const char *buf)
29 {
30 	if (memcmp(buf, "SWAP-SPACE", 10) == 0 ||
31             memcmp(buf, "SWAPSPACE2", 10) == 0)
32 		return 1;
33 
34 	if (memcmp(buf, "S1SUSPEND", 9) == 0 ||
35 	    memcmp(buf, "S2SUSPEND", 9) == 0 ||
36 	    memcmp(buf, "ULSUSPEND", 9) == 0 ||
37 	    memcmp(buf, "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8) == 0)
38 		return 1;
39 
40 	return 0;
41 }
42 
43 int dev_is_swap(struct device *dev, uint64_t *signature)
44 {
45 	char buf[10];
46 	uint64_t size;
47 	int page;
48 
49 	if (!dev_get_size(dev, &size)) {
50 		stack;
51 		return -1;
52 	}
53 
54 	if (!dev_open(dev)) {
55 		stack;
56 		return -1;
57 	}
58 
59 	*signature = 0;
60 
61 	for (page = 0x1000; page <= MAX_PAGESIZE; page <<= 1) {
62 		/*
63 		 * skip 32k pagesize since this does not seem to be supported
64 		 */
65 		if (page == 0x8000)
66 			continue;
67 		if (size < page)
68 			break;
69 		if (!dev_read(dev, page - SIGNATURE_SIZE,
70 			      SIGNATURE_SIZE, buf)) {
71 			stack;
72 			return -1;
73 		}
74 		if (_swap_detect_signature(buf)) {
75 			*signature = page - SIGNATURE_SIZE;
76 			break;
77 		}
78 	}
79 
80 	if (!dev_close(dev))
81 		stack;
82 
83 	if (*signature)
84 		return 1;
85 
86 	return 0;
87 }
88 
89 #else
90 
91 #if defined(__NetBSD__) || defined(__DragonFly__)
92 int dev_is_swap(struct device *dev, uint64_t *signature)
93 {
94 	return 0;
95 }
96 #endif
97 
98 #endif
99