aboutsummaryrefslogtreecommitdiffstats
path: root/swsusp.h
blob: 2aae184b1c066fa430cbe152bcb94a4a07738989 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
 * swsusp.h
 *
 * Common definitions for user space suspend and resume handlers.
 *
 * Copyright (C) 2005 Rafael J. Wysocki <rjw@sisk.pl>
 *
 * This file is released under the GPLv2.
 *
 */

#include <stdint.h>
#include <linux/fs.h>
#include <linux/suspend_ioctls.h>

#include "encrypt.h"

#define	LINUX_REBOOT_MAGIC1	0xfee1dead
#define	LINUX_REBOOT_MAGIC2	672274793

#define LINUX_REBOOT_CMD_RESTART	0x01234567
#define LINUX_REBOOT_CMD_HALT		0xCDEF0123
#define LINUX_REBOOT_CMD_POWER_OFF	0x4321FEDC
#define LINUX_REBOOT_CMD_RESTART2	0xA1B2C3D4
#define LINUX_REBOOT_CMD_SW_SUSPEND	0xD000FCE2

struct new_utsname {
	char sysname[65];
	char nodename[65];
	char release[65];
	char version[65];
	char machine[65];
	char domainname[65];
};

struct swsusp_info {
	struct new_utsname	uts;
	uint32_t		version_code;
	unsigned long		num_physpages;
	int			cpus;
	unsigned long		image_pages;
	unsigned long		pages;
	unsigned long		size;
};

#define SNAPSHOT_ATOMIC_SNAPSHOT	_IOW(SNAPSHOT_IOC_MAGIC, 3, void *)
#define SNAPSHOT_SET_IMAGE_SIZE		_IOW(SNAPSHOT_IOC_MAGIC, 6, unsigned long)
#define SNAPSHOT_AVAIL_SWAP		_IOR(SNAPSHOT_IOC_MAGIC, 7, void *)
#define SNAPSHOT_GET_SWAP_PAGE		_IOR(SNAPSHOT_IOC_MAGIC, 8, void *)
#define SNAPSHOT_SET_SWAP_FILE	_IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int)
#define SNAPSHOT_PMOPS		_IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int)

#define PMOPS_PREPARE	1
#define PMOPS_ENTER	2
#define PMOPS_FINISH	3

struct image_header_info {
	unsigned long		pages;
	uint32_t		flags;
	loff_t			map_start;
	loff_t			image_data_size;
	unsigned char		checksum[16];
#ifdef CONFIG_ENCRYPT
	unsigned char		salt[CIPHER_BLOCK];
	struct RSA_data	rsa;
	struct encrypted_key	key;
#endif
	double			writeout_time;
	int			resume_pause;
};

#define IMAGE_CHECKSUM		0x0001
#define IMAGE_COMPRESSED	0x0002
#define IMAGE_ENCRYPTED		0x0004
#define IMAGE_USE_RSA		0x0008
#define PLATFORM_SUSPEND	0x0010

#define SWSUSP_SIG	"ULSUSPEND"

struct swsusp_header {
	loff_t image;
	char	orig_sig[10];
	char	sig[10];
} __attribute__((packed));

static inline void report_unsupported_ioctl(char *name)
{
	printf("The %s ioctl is not supported by the kernel\n", name);
}

static inline int freeze(int dev)
{
	return ioctl(dev, SNAPSHOT_FREEZE, 0);
}

static inline int unfreeze(int dev)
{
	return ioctl(dev, SNAPSHOT_UNFREEZE, 0);
}

static inline int platform_prepare(int dev)
{
	int error;

	error = ioctl(dev, SNAPSHOT_PLATFORM_SUPPORT, 1);
	if (error && errno == ENOTTY) {
		report_unsupported_ioctl("SNAPSHOT_PLATFORM_SUPPORT");
		error = ioctl(dev, SNAPSHOT_PMOPS, PMOPS_PREPARE);
	}
	return error;
}

static inline void reboot(void)
{
	syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
		LINUX_REBOOT_CMD_RESTART, 0);
}

static inline void power_off(void)
{
	syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
		LINUX_REBOOT_CMD_POWER_OFF, 0);
}

#ifndef SYS_sync_file_range
 #ifdef __i386__
  #define SYS_sync_file_range	314
 #endif
 #ifdef __x86_64__
  #define SYS_sync_file_range	277
 #endif
 #define SYNC_FILE_RANGE_WRITE	2
#endif

static inline int start_writeout(int fd)
{
#ifdef SYS_sync_file_range
	return syscall(SYS_sync_file_range, fd,
			(loff_t)0, (loff_t)0, SYNC_FILE_RANGE_WRITE);
#else
	errno = ENOSYS;
	return -1;
#endif
}

struct extent {
	loff_t start;
	loff_t end;
};

/* The number 1 below is arbitrary.  The actual size of data[] is variable */
struct buf_block {
	size_t size;
	char data[1];
} __attribute__((packed));

#define SNAPSHOT_DEVICE	"/dev/snapshot"
#define RESUME_DEVICE ""

#define IMAGE_SIZE	(500 * 1024 * 1024)

#define SUSPEND_LOGLEVEL	1
#define MAX_LOGLEVEL		8

#define SUSPEND_SWAPPINESS	100

#define RESUME_PAUSE_MAX	60

#define GENERIC_NAME_SIZE	256

#define WRITE_BUFFERS	4

extern char *my_name;

#ifdef CONFIG_COMPRESS
extern unsigned int compress_buf_size;
#else
#define LZO1X_1_MEM_COMPRESS 0
#define compress_buf_size 0
#endif

#define MIN_TEST_IMAGE_PAGES	1024

int read_or_verify(int dev, int fd, struct image_header_info *header,
                   loff_t start, int verify, int test);