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
_swap_detect_signature(const char * buf)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 
dev_is_swap(struct device * dev,uint64_t * signature)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 #ifdef __NetBSD__
dev_is_swap(struct device * dev,uint64_t * signature)92 int dev_is_swap(struct device *dev, uint64_t *signature)
93 {
94           return 0;
95 }
96 #endif
97 
98 #endif
99