Home | History | Annotate | Line # | Download | only in device
      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 #ifdef __NetBSD__
     92 int dev_is_swap(struct device *dev, uint64_t *signature)
     93 {
     94 	return 0;
     95 }
     96 #endif
     97 
     98 #endif
     99