4
* A simple user space resume handler for swsusp.
6
* Copyright (C) 2005 Rafael J. Wysocki <rjw@sisk.pl>
8
* This file is released under the GPLv2.
13
#include <sys/types.h>
15
#include <sys/ioctl.h>
17
#include <sys/mount.h>
27
#ifdef CONFIG_COMPRESS
30
#define lzf_decompress(a, b, c, d) 0
38
static char snapshot_dev_name[MAX_STR_LEN] = SNAPSHOT_DEVICE;
39
static char resume_dev_name[MAX_STR_LEN] = RESUME_DEVICE;
40
static int suspend_loglevel = SUSPEND_LOGLEVEL;
41
static int max_loglevel = MAX_LOGLEVEL;
42
static char verify_checksum;
43
#ifdef CONFIG_COMPRESS
44
static char decompress;
53
static char splash_param;
55
static struct splash splash;
57
static struct config_par parameters[PARAM_NO] = {
59
.name = "snapshot device",
61
.ptr = snapshot_dev_name,
65
.name = "resume device",
67
.ptr = resume_dev_name,
71
.name = "suspend loglevel",
73
.ptr = &suspend_loglevel,
76
.name = "max loglevel",
86
.name = "compute checksum",
90
#ifdef CONFIG_COMPRESS
104
.name = "RSA key file",
110
.name = "early writeout",
117
.ptr = &splash_param,
120
.name = "shutdown method",
126
static unsigned int page_size;
127
static unsigned int buffer_size;
128
static void *mem_pool;
131
* read_area - Read data from a swap location.
132
* @fd: File handle of the resume partition
133
* @buf: Pointer to the area we're reading into
134
* @offset: Swap offset of the place to read from
135
* @size: The number of bytes to read
138
static int read_area(int fd, void *buf, loff_t offset, unsigned int size)
144
if (lseek(fd, offset, SEEK_SET) == offset)
145
cnt = read(fd, buf, size);
146
if (cnt < (ssize_t)size) {
157
* The swap_map_handle structure is used for handling the swap map in
161
struct swap_map_handle {
164
struct swap_area *areas;
165
unsigned short areas_per_page;
167
unsigned int area_size;
168
unsigned int cur_size;
172
#ifdef CONFIG_ENCRYPT
173
char *decrypt_buffer;
174
gcry_cipher_hd_t cipher_handle;
178
#define READ_AHEAD_SIZE (8*1024*1024)
181
* The following functions allow us to read data using a swap map
182
* in a file-alike way
185
static int fill_buffer(struct swap_map_handle *handle)
187
void *dst = handle->read_buffer;
190
int read_ahead_areas = READ_AHEAD_SIZE/buffer_size;
191
int advise_first, advise_last, i;
194
/* we've got a new map page */
196
advise_last = read_ahead_areas;
198
advise_first = handle->k + read_ahead_areas;
199
advise_last = advise_first;
202
for (i = advise_first;
203
i <= advise_last && i < handle->areas_per_page;
205
if (handle->areas[i].offset == 0)
208
error = posix_fadvise(handle->fd, handle->areas[i].offset,
209
handle->areas[i].size, POSIX_FADV_NOREUSE);
211
perror("posix_fadvise");
216
handle->area_size = handle->areas[handle->k].size;
217
if (handle->area_size > buffer_size)
219
#ifdef CONFIG_ENCRYPT
221
dst = handle->decrypt_buffer;
223
error = read_area(handle->fd, dst,
224
handle->areas[handle->k].offset,
226
#ifdef CONFIG_ENCRYPT
227
if (!error && decrypt)
228
error = gcry_cipher_decrypt(handle->cipher_handle,
229
(void *)handle->read_buffer, handle->area_size,
230
dst, handle->area_size);
235
static int init_swap_reader(struct swap_map_handle *handle, int fd, loff_t start, void *buf)
242
handle->areas_per_page = (page_size - sizeof(loff_t)) /
243
sizeof(struct swap_area);
244
handle->next_swap = (loff_t *)(handle->areas + handle->areas_per_page);
245
handle->page_buffer = (char *)buf + page_size;
246
handle->read_buffer = handle->page_buffer + page_size;
247
#ifdef CONFIG_ENCRYPT
248
handle->decrypt_buffer = handle->read_buffer + buffer_size;
250
error = read_area(fd, handle->areas, start, page_size);
255
error = fill_buffer(handle);
258
handle->cur_size = 0;
260
md5_init_ctx(&handle->ctx);
264
static int restore(struct swap_map_handle *handle, int disp)
266
struct buf_block *block;
267
void *buf = handle->page_buffer;
269
block = (struct buf_block *)(handle->read_buffer + disp);
271
unsigned short cnt = block->size;
273
if (cnt == page_size) {
274
memcpy(buf, block->data, page_size);
275
} else if (cnt < page_size) {
276
cnt = lzf_decompress(block->data, cnt, buf, page_size);
277
if (cnt != page_size)
282
block->size += sizeof(short);
285
memcpy(buf, block, page_size);
289
static inline int swap_read_page(struct swap_map_handle *handle)
295
if (handle->cur_size < handle->area_size) {
296
/* Get the data from the read buffer */
297
size = restore(handle, handle->cur_size);
300
handle->cur_size += size;
304
/* There are no more data in the read buffer. Read more */
305
if (++handle->k >= handle->areas_per_page) {
307
offset = *handle->next_swap;
309
error = read_area(handle->fd, handle->areas, offset, page_size);
314
error = fill_buffer(handle);
318
size = restore(handle, 0);
321
handle->cur_size = size;
325
md5_process_block(handle->page_buffer, page_size, &handle->ctx);
331
* load_image - load the image using the swap map handle
332
* @handle and the snapshot handle @snapshot
333
* (assume there are @nr_pages pages to load)
336
static inline int load_image(struct swap_map_handle *handle, int dev,
337
unsigned int nr_pages)
343
printf("Loading image data pages (%u pages) ... ", nr_pages);
349
error = swap_read_page(handle);
352
ret = write(dev, handle->page_buffer, page_size);
353
if (ret < (int)page_size) {
354
error = ret < 0 ? -errno : -ENOSPC;
358
printf("\b\b\b\b%3d%%", n / m);
360
splash.progress(n / m);
363
} while (n < nr_pages);
369
static char * print_checksum(char * buf, unsigned char *checksum)
373
for (j = 0; j < 16; j++)
374
buf += sprintf(buf, "%02hhx ", checksum[j]);
379
#ifdef CONFIG_ENCRYPT
380
static int decrypt_key(struct swsusp_info *header, unsigned char *key,
381
unsigned char *ivec, void *buffer)
383
gcry_ac_handle_t rsa_hd;
384
gcry_ac_data_t rsa_data_set, key_set;
385
gcry_ac_key_t rsa_priv;
387
unsigned char *buf, *out, *key_buf, *ivec_buf;
390
struct RSA_data *rsa;
391
gcry_cipher_hd_t sym_hd;
396
ret = gcry_ac_open(&rsa_hd, GCRY_AC_RSA, 0);
401
ret = gcry_cipher_open(&sym_hd, PK_CIPHER,
402
GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE);
408
key_buf = (unsigned char *)pass_buf + PASS_SIZE;
409
ivec_buf = key_buf + PK_KEY_SIZE;
410
out = ivec_buf + PK_CIPHER_BLOCK;
412
splash.read_password(pass_buf, 0);
413
memset(ivec_buf, 0, PK_CIPHER_BLOCK);
414
strncpy((char *)ivec_buf, pass_buf, PK_CIPHER_BLOCK);
416
md5_process_bytes(pass_buf, strlen(pass_buf), &ctx);
417
md5_finish_ctx(&ctx, key_buf);
418
ret = gcry_cipher_setkey(sym_hd, key_buf, PK_KEY_SIZE);
420
ret = gcry_cipher_setiv(sym_hd, ivec_buf,
424
ret = gcry_cipher_encrypt(sym_hd,
426
KEY_TEST_DATA, KEY_TEST_SIZE);
431
ret = memcmp(out, rsa->key_test, KEY_TEST_SIZE);
434
printf("resume: Wrong passphrase, try again.\n");
437
gcry_cipher_close(sym_hd);
439
ret = gcry_cipher_open(&sym_hd, PK_CIPHER,
440
GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE);
445
ret = gcry_cipher_setkey(sym_hd, key_buf, PK_KEY_SIZE);
447
ret = gcry_cipher_setiv(sym_hd, ivec_buf, PK_CIPHER_BLOCK);
450
ret = gcry_ac_data_new(&rsa_data_set);
453
gcry_cipher_close(sym_hd);
458
for (j = 0; j < RSA_FIELDS; j++) {
459
size_t s = rsa->size[j];
461
/* We need to decrypt some components */
462
if (j >= RSA_FIELDS_PUB) {
463
/* We use the in-place decryption */
464
ret = gcry_cipher_decrypt(sym_hd, buf, s, NULL, 0);
469
gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, buf, s, NULL);
470
ret = gcry_ac_data_set(rsa_data_set, GCRY_AC_FLAG_COPY,
472
gcry_mpi_release(mpi);
479
ret = gcry_ac_key_init(&rsa_priv, rsa_hd,
480
GCRY_AC_KEY_SECRET, rsa_data_set);
483
ret = gcry_ac_data_new(&key_set);
485
gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, header->key.data,
486
header->key.size, NULL);
487
ret = gcry_ac_data_set(key_set, GCRY_AC_FLAG_COPY,
490
gcry_mpi_release(mpi);
491
ret = gcry_ac_data_decrypt(rsa_hd, 0, rsa_priv,
498
gcry_mpi_aprint(GCRYMPI_FMT_USG, &res, &s, mpi);
499
if (s == KEY_SIZE + CIPHER_BLOCK) {
500
memcpy(key, res, KEY_SIZE);
501
memcpy(ivec, res + KEY_SIZE,
508
gcry_mpi_release(mpi);
509
gcry_ac_data_destroy(key_set);
511
gcry_ac_key_destroy(rsa_priv);
513
gcry_ac_data_destroy(rsa_data_set);
516
gcry_cipher_close(sym_hd);
519
gcry_ac_close(rsa_hd);
525
static int read_image(int dev, char *resume_dev_name)
527
static struct swsusp_header swsusp_header;
528
static struct swap_map_handle handle;
529
static unsigned char orig_checksum[16], checksum[16];
530
int fd, ret, error = 0;
531
struct swsusp_info *header = mem_pool;
532
char *buffer = (char *)mem_pool + page_size;
533
unsigned int nr_pages;
534
unsigned int size = sizeof(struct swsusp_header);
535
unsigned int shift = page_size - size;
538
fd = open(resume_dev_name, O_RDWR);
541
fprintf(stderr,"resume: Could not open the resume device\n");
544
if (lseek(fd, shift, SEEK_SET) != shift)
546
ret = read(fd, &swsusp_header, size);
548
if (memcmp(SWSUSP_SIG, swsusp_header.sig, 10))
551
error = ret < 0 ? ret : -EIO;
554
error = read_area(fd, header, swsusp_header.image, page_size);
556
if(header->image_flags & IMAGE_CHECKSUM) {
557
memcpy(orig_checksum, header->checksum, 16);
558
printf("resume: MD5 checksum %s\n",
559
print_checksum(buffer, orig_checksum));
563
if (header->image_flags & IMAGE_COMPRESSED) {
564
printf("resume: Compressed image\n");
565
#ifdef CONFIG_COMPRESS
568
fprintf(stderr,"resume: Compression not supported\n");
572
if (!error && (header->image_flags & IMAGE_ENCRYPTED)) {
573
#ifdef CONFIG_ENCRYPT
574
static unsigned char key[KEY_SIZE], ivec[CIPHER_BLOCK];
576
printf("resume: Encrypted image\n");
577
if (header->image_flags & IMAGE_USE_RSA) {
578
error = decrypt_key(header, key, ivec, buffer);
582
splash.read_password(buffer, 0);
583
encrypt_init(key, ivec, buffer);
584
for (j = 0; j < CIPHER_BLOCK; j++)
585
ivec[j] ^= header->salt[j];
589
error = gcry_cipher_open(&handle.cipher_handle,
590
IMAGE_CIPHER, GCRY_CIPHER_MODE_CFB,
594
error = gcry_cipher_setkey(handle.cipher_handle,
598
error = gcry_cipher_setiv(handle.cipher_handle,
603
gcry_cipher_close(handle.cipher_handle);
605
fprintf(stderr, "resume: libgcrypt error: %s\n",
606
gcry_strerror(error));
609
fprintf(stderr, "resume: Encryption not supported\n");
614
error = init_swap_reader(&handle, fd,
615
header->map_start, buffer);
616
nr_pages = header->pages - 1;
617
ret = write(dev, header, page_size);
618
if (ret < (int)page_size)
619
error = ret < 0 ? ret : -EIO;
622
struct timeval begin, end;
623
double delta, mb = header->size / (1024.0 * 1024.0);
625
gettimeofday(&begin, NULL);
626
error = load_image(&handle, dev, nr_pages);
627
gettimeofday(&end, NULL);
629
timersub(&end, &begin, &end);
630
delta = end.tv_usec / 1000000.0 + end.tv_sec;
632
printf("wrote %0.1lf MB in %0.1lf seconds (%0.1lf MB/s)\n",
633
mb, header->writeout_time, mb / header->writeout_time);
635
printf("read %0.1lf MB in %0.1lf seconds (%0.1lf MB/s)\n",
636
mb, delta, mb / delta);
639
delta += header->writeout_time;
640
printf("total image i/o %0.1lf MB in %0.1lf seconds (%0.1lf MB/s)\n",
641
mb, delta, mb / delta);
646
"\nresume: The system snapshot image could not be read.\n\n"
647
#ifdef CONFIG_ENCRYPT
648
"\tThis might be a result of booting a wrong kernel\n"
649
"\tor typing in a wrong passphrase.\n\n"
651
"\tThis might be a result of booting a wrong kernel.\n\n"
653
"\tYou can continue to boot the system and lose the saved state\n"
654
"\tor reboot and try again.\n\n"
655
"\t[Notice that you may not mount any filesystem between\n"
656
"\tnow and successful resume. That would badly damage\n"
657
"\taffected filesystems.]\n\n"
658
"\tDo you want to continue boot (Y/n)? ");
659
ret = (c == 'n' || c == 'N');
665
if (!error || !ret) {
666
if (!error && verify_checksum) {
667
md5_finish_ctx(&handle.ctx, checksum);
668
if (memcmp(orig_checksum, checksum, 16)) {
669
fprintf(stderr,"resume: MD5 checksum does not match\n");
670
fprintf(stderr,"resume: Computed MD5 checksum %s\n",
671
print_checksum(buffer, checksum));
675
/* Reset swap signature now */
676
memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
677
if (lseek(fd, shift, SEEK_SET) != shift) {
680
ret = write(fd, &swsusp_header, size);
682
error = ret < 0 ? -errno : -EIO;
684
"resume: Could not restore the partition header\n");
690
#ifdef CONFIG_ENCRYPT
692
gcry_cipher_close(handle.cipher_handle);
696
printf("resume: Image successfully loaded\n");
698
sprintf(buffer, "resume: Error %d loading the image\n"
699
"\nPress ENTER to continue\n", error);
700
splash.dialog(buffer);
705
static void set_kernel_console_loglevel(int level)
708
struct stat stat_buf;
709
char *procname = "/proc/sys/kernel/printk";
710
int proc_mounted = 0;
712
if (stat(procname, &stat_buf) && errno == ENOENT) {
713
if (mount("none", "/proc", "proc", 0, NULL)) {
714
fprintf(stderr, "resume: Could not mount proc\n");
719
file = fopen(procname, "w");
721
fprintf(file, "%d\n", level);
728
int main(int argc, char *argv[])
730
unsigned int mem_size;
731
struct stat stat_buf;
735
page_size = getpagesize();
736
buffer_size = BUFFER_PAGES * page_size;
738
#ifdef CONFIG_ENCRYPT
739
printf("resume: libgcrypt version: %s\n", gcry_check_version(NULL));
740
gcry_control(GCRYCTL_INIT_SECMEM, page_size, 0);
741
mem_size = 3 * page_size + 2 * buffer_size;
743
mem_size = 3 * page_size + buffer_size;
745
mem_pool = malloc(mem_size);
748
fprintf(stderr, "resume: Could not allocate memory\n");
752
if (get_config("resume", argc, argv, PARAM_NO, parameters, resume_dev_name))
755
if (splash_param != 'y' && splash_param != 'Y')
758
while (stat(resume_dev_name, &stat_buf)) {
760
"resume: Could not stat the resume device file.\n"
761
"\tPlease type in the file name to try again"
762
"\tor press ENTER to boot the system: ");
763
fgets(resume_dev_name, MAX_STR_LEN - 1, stdin);
764
n = strlen(resume_dev_name) - 1;
767
if (resume_dev_name[n] == '\n')
768
resume_dev_name[n] = '\0';
771
set_kernel_console_loglevel(suspend_loglevel);
773
setvbuf(stdout, NULL, _IONBF, 0);
774
setvbuf(stderr, NULL, _IONBF, 0);
776
if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
777
fprintf(stderr, "resume: Could not lock myself\n");
781
splash_prepare(&splash, splash_param);
784
dev = open(snapshot_dev_name, O_WRONLY);
787
error = read_image(dev, resume_dev_name);
789
fprintf(stderr, "resume: Could not read the image\n");
795
fprintf(stderr, "resume: Could not freeze processes\n");
804
set_kernel_console_loglevel(max_loglevel);