Hello community,
here is the log from the commit of package suspend
checked in at Fri Apr 7 17:02:38 CEST 2006.
--------
--- arch/i386/suspend/suspend.changes 2006-04-03 18:34:33.000000000 +0200
+++ suspend/suspend.changes 2006-04-06 23:10:05.000000000 +0200
@@ -1,0 +2,11 @@
+Thu Apr 6 23:06:39 CEST 2006 - seife@suse.de
+
+- consolidate the --force fix
+- Whitelist updates:
+ - Acer Travelmate 3000
+ - Asus L2400D
+ - Dell D800
+ - ThinkPad T60p
+ - LG M1
+
+-------------------------------------------------------------------
Old:
----
s2ram-force-fix.diff
suspend-20060327.tar.bz2
whitelist-update.diff
New:
----
suspend-20060406.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ suspend.spec ++++++
--- /var/tmp/diff_new_pack.oro27U/_old 2006-04-07 17:01:37.000000000 +0200
+++ /var/tmp/diff_new_pack.oro27U/_new 2006-04-07 17:01:37.000000000 +0200
@@ -1,5 +1,5 @@
#
-# spec file for package suspend (Version 20060327)
+# spec file for package suspend (Version 20060406)
#
# Copyright (c) 2006 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
@@ -12,15 +12,13 @@
Name: suspend
BuildRequires: pciutils-devel
-Version: 20060327
-Release: 3
+Version: 20060406
+Release: 1
Summary: A Set Of Tools To Support Sleep Modes
License: GPL
URL: http://sourceforge.net/projects/suspend
Group: System/Console
Source: %{name}-%{version}.tar.bz2
-Patch1: s2ram-force-fix.diff
-Patch2: whitelist-update.diff
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Supplements: powersave
@@ -36,8 +34,6 @@
%prep
%setup -q
-%patch1 -p1
-%patch2 -p1
%build
make s2ram ARCH=%_arch
@@ -56,6 +52,14 @@
%doc README README.s2ram-whitelist
%changelog -n suspend
+* Thu Apr 06 2006 - seife@suse.de
+- consolidate the --force fix
+- Whitelist updates:
+- Acer Travelmate 3000
+- Asus L2400D
+- Dell D800
+- ThinkPad T60p
+- LG M1
* Mon Apr 03 2006 - seife@suse.de
- Whitelist updates:
- Acer Travelmate 650
++++++ suspend-20060327.tar.bz2 -> suspend-20060406.tar.bz2 ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/suspend-20060327/Makefile new/suspend-20060406/Makefile
--- old/suspend-20060327/Makefile 2006-03-26 23:22:44.000000000 +0200
+++ new/suspend-20060406/Makefile 2006-04-04 23:34:10.000000000 +0200
@@ -1,6 +1,8 @@
#CONFIG_COMPRESS=yes
#CONFIG_ENCRYPT=yes
+ARCH:=$(shell uname -m)
+
CC_FLAGS=-I/usr/local/include
LD_FLAGS=-L/usr/local/lib
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/suspend-20060327/resume.c new/suspend-20060406/resume.c
--- old/suspend-20060327/resume.c 2006-03-26 23:20:09.000000000 +0200
+++ new/suspend-20060406/resume.c 2006-04-04 23:33:11.000000000 +0200
@@ -101,8 +101,9 @@
#endif
};
-static char page_buffer[PAGE_SIZE];
-static struct swsusp_header swsusp_header;
+static unsigned int page_size;
+static unsigned int buffer_size;
+static void *mem_pool;
/**
* read_area - Read data from a swap location.
@@ -130,24 +131,24 @@
return res;
}
-static char read_buffer[BUFFER_SIZE];
-#ifdef CONFIG_ENCRYPT
-static char decrypt_buffer[BUFFER_SIZE];
-#endif
-
/*
* The swap_map_handle structure is used for handling the swap map in
* a file-alike way
*/
struct swap_map_handle {
- struct swap_map_page cur;
+ char *page_buffer;
+ char *read_buffer;
+ struct swap_area *areas;
+ unsigned short areas_per_page;
+ loff_t *next_swap;
unsigned int area_size;
unsigned int cur_size;
unsigned int k;
int fd;
struct md5_ctx ctx;
#ifdef CONFIG_ENCRYPT
+ char *decrypt_buffer;
BF_KEY key;
unsigned char ivec[IVEC_SIZE];
int num;
@@ -161,33 +162,44 @@
static int fill_buffer(struct swap_map_handle *handle)
{
- void *dst = read_buffer;
+ void *dst = handle->read_buffer;
int error;
- handle->area_size = handle->cur.entries[handle->k].size;
+ handle->area_size = handle->areas[handle->k].size;
+ if (handle->area_size > buffer_size)
+ return -ENOMEM;
#ifdef CONFIG_ENCRYPT
if (decrypt)
- dst = decrypt_buffer;
+ dst = handle->decrypt_buffer;
#endif
error = read_area(handle->fd, dst,
- handle->cur.entries[handle->k].offset,
+ handle->areas[handle->k].offset,
handle->area_size);
#ifdef CONFIG_ENCRYPT
if (!error && decrypt)
- BF_cfb64_encrypt(dst, (unsigned char *)read_buffer,
+ BF_cfb64_encrypt(dst, (unsigned char *)handle->read_buffer,
handle->area_size, &handle->key, handle->ivec,
&handle->num, BF_DECRYPT);
#endif
return error;
}
-static int init_swap_reader(struct swap_map_handle *handle, int fd, loff_t start)
+static int init_swap_reader(struct swap_map_handle *handle, int fd, loff_t start, void *buf)
{
int error;
- if (!start)
+ if (!start || !buf)
return -EINVAL;
- error = read_area(fd, &handle->cur, start, sizeof(struct swap_map_page));
+ handle->areas = buf;
+ handle->areas_per_page = (page_size - sizeof(loff_t)) /
+ sizeof(struct swap_area);
+ handle->next_swap = (loff_t *)(handle->areas + handle->areas_per_page);
+ handle->page_buffer = (char *)buf + page_size;
+ handle->read_buffer = handle->page_buffer + page_size;
+#ifdef CONFIG_ENCRYPT
+ handle->decrypt_buffer = handle->read_buffer + buffer_size;
+#endif
+ error = read_area(fd, handle->areas, start, page_size);
if (error)
return error;
handle->fd = fd;
@@ -201,18 +213,20 @@
return 0;
}
-static int restore(void *buf, int disp)
+static int restore(struct swap_map_handle *handle, int disp)
{
- struct buf_block *block = (struct buf_block *)(read_buffer + disp);
+ struct buf_block *block;
+ void *buf = handle->page_buffer;
+ block = (struct buf_block *)(handle->read_buffer + disp);
if (decompress) {
unsigned short cnt = block->size;
- if (cnt == PAGE_SIZE) {
- memcpy(buf, block->data, PAGE_SIZE);
- } else if (cnt < PAGE_SIZE) {
- cnt = lzf_decompress(block->data, cnt, buf, PAGE_SIZE);
- if (cnt != PAGE_SIZE)
+ if (cnt == page_size) {
+ memcpy(buf, block->data, page_size);
+ } else if (cnt < page_size) {
+ cnt = lzf_decompress(block->data, cnt, buf, page_size);
+ if (cnt != page_size)
return -ENODATA;
} else {
return -EINVAL;
@@ -220,11 +234,11 @@
block->size += sizeof(short);
return block->size;
}
- memcpy(buf, block, PAGE_SIZE);
- return PAGE_SIZE;
+ memcpy(buf, block, page_size);
+ return page_size;
}
-static inline int swap_read_page(struct swap_map_handle *handle, void *buf)
+static inline int swap_read_page(struct swap_map_handle *handle)
{
loff_t offset;
size_t size;
@@ -232,7 +246,7 @@
if (handle->cur_size < handle->area_size) {
/* Get the data from the read buffer */
- size = restore(buf, handle->cur_size);
+ size = restore(handle, handle->cur_size);
if (size < 0)
return size;
handle->cur_size += size;
@@ -240,12 +254,11 @@
}
/* There are no more data in the read buffer. Read more */
- if (++handle->k >= MAP_PAGE_ENTRIES) {
+ if (++handle->k >= handle->areas_per_page) {
handle->k = 0;
- offset = handle->cur.next_swap;
+ offset = *handle->next_swap;
if (offset)
- error = read_area(handle->fd, &handle->cur, offset,
- sizeof(struct swap_map_page));
+ error = read_area(handle->fd, handle->areas, offset, page_size);
else
error = -EINVAL;
}
@@ -254,14 +267,14 @@
if (error)
return error;
- size = restore(buf, 0);
+ size = restore(handle, 0);
if (size < 0)
return size;
handle->cur_size = size;
MD5:
if (verify_checksum)
- md5_process_block(buf, PAGE_SIZE, &handle->ctx);
+ md5_process_block(handle->page_buffer, page_size, &handle->ctx);
return 0;
}
@@ -285,11 +298,11 @@
m = 1;
n = 0;
do {
- error = swap_read_page(handle, page_buffer);
+ error = swap_read_page(handle);
if (error)
break;
- ret = write(dev, page_buffer, PAGE_SIZE);
- if (ret < (int)PAGE_SIZE) {
+ ret = write(dev, handle->page_buffer, page_size);
+ if (ret < (int)page_size) {
error = ret < 0 ? -errno : -ENOSPC;
break;
}
@@ -311,7 +324,8 @@
}
#ifdef CONFIG_ENCRYPT
-static int decrypt_key(struct swsusp_info *header, BF_KEY *key, unsigned char *ivec)
+static int decrypt_key(struct swsusp_info *header, BF_KEY *key, unsigned char *ivec,
+ void *buffer)
{
RSA *rsa;
unsigned char *buf, *out, *key_buf;
@@ -331,8 +345,8 @@
rsa->e = BN_mpi2bn(buf, rsa_data->e_size, NULL);
buf += rsa_data->e_size;
- pass_buf = read_buffer;
- key_buf = (unsigned char *)read_buffer + PASS_SIZE;
+ pass_buf = buffer;
+ key_buf = (unsigned char *)pass_buf + PASS_SIZE;
do {
read_password(pass_buf, 0);
memset(ivec, 0, IVEC_SIZE);
@@ -347,7 +361,7 @@
printf("resume: Wrong passphrase, try again.\n");
} while (ret);
- out = (unsigned char *)decrypt_buffer;
+ out = key_buf + KEY_SIZE;
BF_cfb64_encrypt(buf, out, rsa_data->d_size, key, ivec, &n, BF_DECRYPT);
rsa->d = BN_mpi2bn(out, rsa_data->d_size, NULL);
if (!rsa->n || !rsa->e || !rsa->d) {
@@ -373,11 +387,15 @@
static int read_image(int dev, char *resume_dev_name)
{
+ static struct swsusp_header swsusp_header;
static struct swap_map_handle handle;
static unsigned char orig_checksum[16], checksum[16];
int fd, ret, error = 0;
- struct swsusp_info *header;
+ struct swsusp_info *header = mem_pool;
+ char *buffer = (char *)mem_pool + page_size;
unsigned int nr_pages;
+ unsigned int size = sizeof(struct swsusp_header);
+ unsigned int shift = page_size - size;
char c;
fd = open(resume_dev_name, O_RDWR);
@@ -386,18 +404,18 @@
printf("resume: Could not open the resume device\n");
return ret;
}
- memset(&swsusp_header, 0, sizeof(swsusp_header));
- ret = read(fd, &swsusp_header, PAGE_SIZE);
- if (ret == PAGE_SIZE) {
+ if (lseek(fd, shift, SEEK_SET) != shift)
+ return -EIO;
+ ret = read(fd, &swsusp_header, size);
+ if (ret == size) {
if (memcmp(SWSUSP_SIG, swsusp_header.sig, 10))
return -EINVAL;
} else {
error = ret < 0 ? ret : -EIO;
}
if (!error)
- error = read_area(fd, page_buffer, swsusp_header.image, PAGE_SIZE);
+ error = read_area(fd, header, swsusp_header.image, page_size);
if (!error) {
- header = (struct swsusp_info *)page_buffer;
if(header->image_flags & IMAGE_CHECKSUM) {
memcpy(orig_checksum, header->checksum, 16);
printf("resume: MD5 checksum ");
@@ -418,13 +436,14 @@
#ifdef CONFIG_ENCRYPT
if (header->image_flags & IMAGE_USE_RSA) {
handle.num = 0;
- error = decrypt_key(header, &handle.key, handle.ivec);
+ error = decrypt_key(header, &handle.key,
+ handle.ivec, buffer);
} else {
int j;
printf("resume: Encrypted image\n");
encrypt_init(&handle.key, handle.ivec, &handle.num,
- read_buffer, decrypt_buffer, 0);
+ buffer, buffer + page_size, 0);
for (j = 0; j < IVEC_SIZE; j++)
handle.ivec[j] ^= header->salt[j];
}
@@ -436,10 +455,11 @@
#endif
}
if (!error) {
- error = init_swap_reader(&handle, fd, header->map_start);
+ error = init_swap_reader(&handle, fd,
+ header->map_start, buffer);
nr_pages = header->pages - 1;
- ret = write(dev, header, PAGE_SIZE);
- if (ret < (int)PAGE_SIZE)
+ ret = write(dev, header, page_size);
+ if (ret < (int)page_size)
error = ret < 0 ? ret : -EIO;
}
if (!error)
@@ -480,12 +500,15 @@
}
/* Reset swap signature now */
memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
- ret = lseek(fd, 0, SEEK_SET);
- if (!ret)
- ret = write(fd, &swsusp_header, PAGE_SIZE);
- if (ret < (int)PAGE_SIZE) {
- error = ret < 0 ? -errno : -EIO;
- fprintf(stderr, "resume: Could not restore the partition header\n");
+ if (lseek(fd, shift, SEEK_SET) != shift) {
+ error = -EIO;
+ } else {
+ ret = write(fd, &swsusp_header, size);
+ if (ret != size) {
+ error = ret < 0 ? -errno : -EIO;
+ fprintf(stderr,
+ "resume: Could not restore the partition header\n");
+ }
}
}
fsync(fd);
@@ -525,10 +548,26 @@
int main(int argc, char *argv[])
{
+ unsigned int mem_size;
struct stat stat_buf;
int dev;
int n, error = 0;
+ page_size = getpagesize();
+ buffer_size = BUFFER_PAGES * page_size;
+
+#ifdef CONFIG_ENCRYPT
+ mem_size = 3 * page_size + 2 * buffer_size;
+#else
+ mem_size = 3 * page_size + buffer_size;
+#endif
+ mem_pool = malloc(mem_size);
+ if (!mem_pool) {
+ error = errno;
+ fprintf(stderr, "resume: Could not allocate memory\n");
+ return error;
+ }
+
if (get_config("resume", argc, argv, PARAM_NO, parameters, resume_dev_name))
return EINVAL;
@@ -575,5 +614,7 @@
set_kernel_console_loglevel(max_loglevel);
+ free(mem_pool);
+
return error;
}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/suspend-20060327/s2ram.c new/suspend-20060406/s2ram.c
--- old/suspend-20060327/s2ram.c 2006-03-26 01:12:44.000000000 +0100
+++ new/suspend-20060406/s2ram.c 2006-04-05 11:56:47.000000000 +0200
@@ -18,7 +18,7 @@
static void *vbe_buffer;
/* Flags set from whitelist */
-static int flags, id;
+static int flags;
char bios_version[1024], sys_vendor[1024], sys_product[1024], sys_version[1024];
/* return codes for s2ram_prepare */
@@ -128,24 +128,16 @@
return -1;
}
-/* Code that can only be run on non-frozen system. It does not matter now
- * but will matter once we'll do suspend-to-both.
- * returns 0 if everything went ok.
- */
-int s2ram_check(void)
+int s2ram_check(int id)
{
int ret = S2RAM_OK;
- dmi_scan();
- id = machine_match();
-
if (id < 0) {
ret = S2RAM_UNKNOWN;
} else {
flags = whitelist[id].flags;
- if ((flags & NOFB) && is_framebuffer()) {
+ if ((flags & NOFB) && is_framebuffer())
ret = S2RAM_NOFB;
- }
}
return ret;
@@ -180,9 +172,11 @@
int s2ram_prepare(void)
{
- int ret;
+ int ret, id;
- ret = s2ram_check();
+ dmi_scan();
+ id = machine_match();
+ ret = s2ram_check(id);
if (ret)
return ret;
@@ -262,7 +256,7 @@
int main(int argc, char *argv[])
{
- int i, ret, test_mode = 0, force = 0;
+ int i, id = -1, ret = 0, test_mode = 0, force = 0;
int active_console = -1;
struct option options[] = {
{ "test", no_argument, NULL, 'n'},
@@ -318,9 +312,13 @@
usage();
}
- ret = s2ram_check();
+ if (!force) {
+ dmi_scan();
+ id = machine_match();
+ ret = s2ram_check(id);
+ }
- if (!force && ret == S2RAM_UNKNOWN) {
+ if (ret == S2RAM_UNKNOWN) {
printf("Machine is unknown.\n");
identify_machine();
goto out;
@@ -334,7 +332,7 @@
goto out;
}
- if (!force && ret)
+ if (ret)
goto out;
/* switch to console 1 first, since we might be in X */
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/suspend-20060327/s2ram.h new/suspend-20060406/s2ram.h
--- old/suspend-20060327/s2ram.h 2006-03-23 16:33:52.000000000 +0100
+++ new/suspend-20060406/s2ram.h 2006-03-28 15:16:21.000000000 +0200
@@ -13,11 +13,8 @@
void dmi_scan(void);
/* from s2ram.c */
-int s2ram_check(void);
+int s2ram_check(int id);
int s2ram_hacks(void);
int s2ram_prepare(void);
int s2ram_do(void);
void s2ram_resume(void);
-
-
-
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/suspend-20060327/suspend.c new/suspend-20060406/suspend.c
--- old/suspend-20060327/suspend.c 2006-03-26 23:25:38.000000000 +0200
+++ new/suspend-20060406/suspend.c 2006-04-04 23:35:55.000000000 +0200
@@ -57,6 +57,8 @@
#endif
static char s2ram;
+static int suspend_swappiness = SUSPEND_SWAPPINESS;
+
static struct config_par parameters[PARAM_NO] = {
{
.name = "snapshot device",
@@ -117,8 +119,14 @@
},
};
-static char page_buffer[PAGE_SIZE];
-static struct swsusp_header swsusp_header;
+static unsigned int page_size;
+/* This MUST NOT be less than page_size */
+static unsigned int max_block_size;
+static unsigned int buffer_size;
+static void *mem_pool;
+#ifdef CONFIG_ENCRYPT
+struct key_data *key_data;
+#endif
static inline loff_t check_free_swap(int dev)
{
@@ -178,20 +186,17 @@
return res;
}
-static char write_buffer[BUFFER_SIZE];
-/* This MUST NOT be less than PAGE_SIZE */
-static unsigned int max_block_size = PAGE_SIZE;
-#ifdef CONFIG_ENCRYPT
-static unsigned char encrypt_buffer[BUFFER_SIZE];
-#endif
-
/*
* The swap_map_handle structure is used for handling swap in
* a file-alike way
*/
struct swap_map_handle {
- struct swap_map_page cur;
+ char *page_buffer;
+ char *write_buffer;
+ struct swap_area *areas;
+ unsigned short areas_per_page;
+ loff_t *next_swap;
struct swap_area cur_area;
unsigned int cur_alloc;
loff_t cur_swap;
@@ -199,15 +204,28 @@
int dev, fd;
struct md5_ctx ctx;
#ifdef CONFIG_ENCRYPT
+ unsigned char *encrypt_buffer;
BF_KEY key;
unsigned char ivec[IVEC_SIZE];
int num;
#endif
};
-static int init_swap_writer(struct swap_map_handle *handle, int dev, int fd)
+static int init_swap_writer(struct swap_map_handle *handle, int dev, int fd, void *buf)
{
- memset(&handle->cur, 0, sizeof(struct swap_map_page));
+ if (!buf)
+ return -EINVAL;
+ handle->areas = buf;
+ handle->areas_per_page = (page_size - sizeof(loff_t)) /
+ sizeof(struct swap_area);
+ handle->next_swap = (loff_t *)(handle->areas + handle->areas_per_page);
+ handle->page_buffer = (char *)buf + page_size;
+ handle->write_buffer = handle->page_buffer + page_size;
+#ifdef CONFIG_ENCRYPT
+ handle->encrypt_buffer = (unsigned char *)(handle->write_buffer +
+ buffer_size);
+#endif
+ memset(handle->areas, 0, page_size);
handle->cur_swap = get_swap_page(dev);
if (!handle->cur_swap)
return -ENOSPC;
@@ -215,7 +233,7 @@
if (!handle->cur_area.offset)
return -ENOSPC;
handle->cur_area.size = 0;
- handle->cur_alloc = PAGE_SIZE;
+ handle->cur_alloc = page_size;
handle->k = 0;
handle->dev = dev;
handle->fd = fd;
@@ -224,28 +242,30 @@
return 0;
}
-static int prepare(void *buf, int disp)
+static int prepare(struct swap_map_handle *handle, int disp)
{
- struct buf_block *block = (struct buf_block *)(write_buffer + disp);
+ struct buf_block *block;
+ void *buf = handle->page_buffer;
+ block = (struct buf_block *)(handle->write_buffer + disp);
if (compress) {
unsigned short cnt;
- cnt = lzf_compress(buf, PAGE_SIZE,
- block->data, PAGE_SIZE - sizeof(short));
+ cnt = lzf_compress(buf, page_size,
+ block->data, page_size - sizeof(short));
if (!cnt) {
- memcpy(block->data, buf, PAGE_SIZE);
- cnt = PAGE_SIZE;
+ memcpy(block->data, buf, page_size);
+ cnt = page_size;
} else {
- compr_diff += PAGE_SIZE - cnt;
+ compr_diff += page_size - cnt;
}
compr_diff -= sizeof(short);
block->size = cnt;
cnt += sizeof(short);
return cnt;
}
- memcpy(block, buf, PAGE_SIZE);
- return PAGE_SIZE;
+ memcpy(block, buf, page_size);
+ return page_size;
}
static int try_get_more_swap(struct swap_map_handle *handle)
@@ -257,10 +277,10 @@
if (!offset)
return -ENOSPC;
if (offset == handle->cur_area.offset + handle->cur_alloc) {
- handle->cur_alloc += PAGE_SIZE;
+ handle->cur_alloc += page_size;
} else {
handle->cur_area.offset = offset;
- handle->cur_alloc = PAGE_SIZE;
+ handle->cur_alloc = page_size;
}
}
return 0;
@@ -268,50 +288,50 @@
static int flush_buffer(struct swap_map_handle *handle)
{
- void *src = write_buffer;
+ void *src = handle->write_buffer;
int error;
#ifdef CONFIG_ENCRYPT
if (encrypt) {
- BF_cfb64_encrypt(src, encrypt_buffer, handle->cur_area.size,
+ BF_cfb64_encrypt(src, handle->encrypt_buffer, handle->cur_area.size,
&handle->key, handle->ivec, &handle->num, BF_ENCRYPT);
- src = encrypt_buffer;
+ src = handle->encrypt_buffer;
}
#endif
error = write_area(handle->fd, src, handle->cur_area.offset,
handle->cur_area.size);
if (error)
return error;
- handle->cur.entries[handle->k].offset = handle->cur_area.offset;
- handle->cur.entries[handle->k].size = handle->cur_area.size;
+ handle->areas[handle->k].offset = handle->cur_area.offset;
+ handle->areas[handle->k].size = handle->cur_area.size;
return 0;
}
-static int swap_write_page(struct swap_map_handle *handle, void *buf)
+static int swap_write_page(struct swap_map_handle *handle)
{
loff_t offset = 0;
int error;
if (compute_checksum)
- md5_process_block(buf, PAGE_SIZE, &handle->ctx);
+ md5_process_block(handle->page_buffer, page_size, &handle->ctx);
if (!handle->cur_area.size) {
/* No data in the write buffer */
- handle->cur_area.size = prepare(buf, 0);
+ handle->cur_area.size = prepare(handle, 0);
return try_get_more_swap(handle);
}
- if (handle->cur_alloc + max_block_size <= BUFFER_SIZE) {
+ if (handle->cur_alloc + max_block_size <= buffer_size) {
if (handle->cur_area.size + max_block_size <= handle->cur_alloc) {
- handle->cur_area.size += prepare(buf, handle->cur_area.size);
+ handle->cur_area.size += prepare(handle, handle->cur_area.size);
return 0;
}
offset = get_swap_page(handle->dev);
if (!offset)
return -ENOSPC;
if (offset == handle->cur_area.offset + handle->cur_alloc) {
- handle->cur_alloc += PAGE_SIZE;
- handle->cur_area.size += prepare(buf, handle->cur_area.size);
+ handle->cur_alloc += page_size;
+ handle->cur_area.size += prepare(handle, handle->cur_area.size);
return try_get_more_swap(handle);
}
}
@@ -328,21 +348,21 @@
return -ENOSPC;
}
handle->cur_area.offset = offset;
- handle->cur_alloc = PAGE_SIZE;
- handle->cur_area.size = prepare(buf, 0);
+ handle->cur_alloc = page_size;
+ handle->cur_area.size = prepare(handle, 0);
error = try_get_more_swap(handle);
if (error)
return error;
- if (++handle->k >= MAP_PAGE_ENTRIES) {
+ if (++handle->k >= handle->areas_per_page) {
offset = get_swap_page(handle->dev);
if (!offset)
return -ENOSPC;
- handle->cur.next_swap = offset;
- error = write_area(handle->fd, &handle->cur, handle->cur_swap,
- sizeof(struct swap_map_page));
+ *handle->next_swap = offset;
+ error = write_area(handle->fd, handle->areas, handle->cur_swap,
+ page_size);
if (error)
return error;
- memset(&handle->cur, 0, sizeof(struct swap_map_page));
+ memset(handle->areas, 0, page_size);
handle->cur_swap = offset;
handle->k = 0;
}
@@ -360,8 +380,8 @@
error = flush_buffer(handle);
if (!error)
/* Save the last swap map page */
- error = write_area(handle->fd, &handle->cur, handle->cur_swap,
- sizeof(struct swap_map_page));
+ error = write_area(handle->fd, handle->areas, handle->cur_swap,
+ page_size);
return error;
}
@@ -383,9 +403,9 @@
m = 1;
nr_pages = 0;
do {
- ret = read(handle->dev, page_buffer, PAGE_SIZE);
+ ret = read(handle->dev, handle->page_buffer, page_size);
if (ret > 0) {
- error = swap_write_page(handle, page_buffer);
+ error = swap_write_page(handle);
if (error)
break;
if (!(nr_pages % m))
@@ -415,20 +435,26 @@
return free_swap > size;
}
+static struct swsusp_header swsusp_header;
+
static int mark_swap(int fd, loff_t start)
{
int error = 0;
+ unsigned int size = sizeof(struct swsusp_header);
+ unsigned int shift = page_size - size;
- lseek(fd, 0, SEEK_SET);
- if (read(fd, &swsusp_header, PAGE_SIZE) < (ssize_t)PAGE_SIZE)
+ if (lseek(fd, shift, SEEK_SET) != shift)
+ return -EIO;
+ if (read(fd, &swsusp_header, size) < size)
return -EIO;
if (!memcmp("SWAP-SPACE", swsusp_header.sig, 10) ||
!memcmp("SWAPSPACE2", swsusp_header.sig, 10)) {
memcpy(swsusp_header.orig_sig, swsusp_header.sig, 10);
memcpy(swsusp_header.sig, SWSUSP_SIG, 10);
swsusp_header.image = start;
- lseek(fd, 0, SEEK_SET);
- if (write(fd, &swsusp_header, PAGE_SIZE) < (ssize_t)PAGE_SIZE)
+ if (lseek(fd, shift, SEEK_SET) != shift)
+ return -EIO;
+ if (write(fd, &swsusp_header, size) < size)
error = -EIO;
} else {
error = -ENODEV;
@@ -443,8 +469,7 @@
int write_image(int snapshot_fd, int resume_fd)
{
static struct swap_map_handle handle;
- static char header_buffer[PAGE_SIZE];
- struct swsusp_info *header = (struct swsusp_info *)header_buffer;
+ struct swsusp_info *header = mem_pool;
loff_t start;
int error;
@@ -452,44 +477,43 @@
start = get_swap_page(snapshot_fd);
if (!start)
return -ENOSPC;
- error = read(snapshot_fd, header_buffer, PAGE_SIZE);
- if (error < (int)PAGE_SIZE)
+ error = read(snapshot_fd, header, page_size);
+ if (error < (int)page_size)
return error < 0 ? error : -EFAULT;
printf("suspend: Image size: %lu kilobytes\n", header->size / 1024);
if (!enough_swap(snapshot_fd, header->size) && !compress) {
printf("suspend: Not enough free swap\n");
return -ENOSPC;
}
- error = init_swap_writer(&handle, snapshot_fd, resume_fd);
+ error = init_swap_writer(&handle, snapshot_fd, resume_fd,
+ (char *)mem_pool + page_size);
if (!error) {
header->map_start = handle.cur_swap;
header->image_flags = 0;
+ max_block_size = page_size;
if (compute_checksum)
header->image_flags |= IMAGE_CHECKSUM;
if (compress) {
header->image_flags |= IMAGE_COMPRESSED;
- max_block_size = sizeof(struct buf_block);
+ max_block_size += sizeof(short);
}
#ifdef CONFIG_ENCRYPT
if (encrypt) {
if (use_RSA) {
- struct key_data *key_data;
-
- key_data = (struct key_data *)encrypt_buffer;
BF_set_key(&handle.key, KEY_SIZE, key_data->key);
memcpy(handle.ivec, key_data->ivec, IVEC_SIZE);
handle.num = 0;
header->image_flags |= IMAGE_ENCRYPTED | IMAGE_USE_RSA;
memcpy(&header->rsa_data, &key_data->rsa_data,
sizeof(struct RSA_data));
- memcpy(&header->key_data,
- encrypt_buffer + sizeof(struct key_data),
+ memcpy(&header->key_data, key_data + 1,
sizeof(struct encrypted_key));
} else {
int j;
encrypt_init(&handle.key, handle.ivec, &handle.num,
- write_buffer, encrypt_buffer, 1);
+ handle.write_buffer,
+ handle.encrypt_buffer, 1);
get_random_salt(header->salt, IVEC_SIZE);
for (j = 0; j < IVEC_SIZE; j++)
handle.ivec[j] ^= header->salt[j];
@@ -505,7 +529,7 @@
md5_finish_ctx(&handle.ctx, header->checksum);
}
if (!error)
- error = write_area(resume_fd, header, start, PAGE_SIZE);
+ error = write_area(resume_fd, header, start, page_size);
if (!error) {
if (compress) {
double delta = header->size - compr_diff;
@@ -526,30 +550,33 @@
static int reset_signature(int fd)
{
int ret, error = 0;
+ unsigned int size = sizeof(struct swsusp_header);
+ unsigned int shift = page_size - size;
- error = lseek(fd, 0, SEEK_SET);
+ if (lseek(fd, shift, SEEK_SET) != shift)
+ return -EIO;
- if (!error) {
- memset(&swsusp_header, 0, sizeof(swsusp_header));
- ret = read(fd, &swsusp_header, PAGE_SIZE);
- if (ret == PAGE_SIZE) {
- if (memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
- /* Impossible? We wrote signature and it is not there?! */
- error = -EINVAL;
- }
- } else {
- error = ret < 0 ? ret : -EIO;
+ memset(&swsusp_header, 0, size);
+ ret = read(fd, &swsusp_header, size);
+ if (ret == size) {
+ if (memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
+ /* Impossible? We wrote signature and it is not there?! */
+ error = -EINVAL;
}
+ } else {
+ error = ret < 0 ? ret : -EIO;
}
if (!error) {
/* Reset swap signature now */
memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
- error = lseek(fd, 0, SEEK_SET);
- }
- if (!error) {
- ret = write(fd, &swsusp_header, PAGE_SIZE);
- error = (ret != PAGE_SIZE);
+ if (lseek(fd, shift, SEEK_SET) == shift) {
+ ret = write(fd, &swsusp_header, size);
+ if (ret != size)
+ error = ret < 0 ? ret : -EIO;
+ } else {
+ error = -EIO;
+ }
}
fsync(fd);
if (error) {
@@ -668,7 +695,7 @@
#define TIOCL_GETKMSGREDIRECT 17
#endif
-static int kmsg_redirect = -1;
+static int set_kmsg_redirect;
/**
* prepare_console - find a spare virtual terminal, open it and attach
@@ -679,21 +706,35 @@
static int prepare_console(int *orig_vc, int *new_vc)
{
int fd, error, vt = -1;
- char *vt_name = page_buffer;
+ char *vt_name = mem_pool;
struct vt_stat vtstat;
- char tiocl[2];
+ char clear_vt, tiocl[2];
fd = console_fd("/dev/console");
if (fd < 0)
return fd;
+
+ tiocl[0] = TIOCL_GETKMSGREDIRECT;
+ if (!ioctl(fd, TIOCLINUX, tiocl)) {
+ if (tiocl[0] > 0)
+ vt = tiocl[0];
+ }
+
+ clear_vt = 0;
error = ioctl(fd, VT_GETSTATE, &vtstat);
if (!error) {
*orig_vc = vtstat.v_active;
- error = ioctl(fd, VT_OPENQRY, &vt);
+ if (vt < 0) {
+ clear_vt = 1;
+ error = ioctl(fd, VT_OPENQRY, &vt);
+ }
}
+
close(fd);
+
if (error || vt < 0)
return -1;
+
sprintf(vt_name, "/dev/tty%d", vt);
fd = open(vt_name, O_RDWR);
if (fd < 0)
@@ -710,23 +751,29 @@
fflush(stderr);
goto Close_fd;
}
- char *msg = "\33[H\33[J";
- write(fd, msg, strlen(msg));
+
+ if (clear_vt) {
+ char *msg = "\33[H\33[J";
+ write(fd, msg, strlen(msg));
+ }
+
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
*new_vc = vt;
- tiocl[0] = TIOCL_GETKMSGREDIRECT;
- if (!ioctl(fd, TIOCLINUX, tiocl)) {
- kmsg_redirect = tiocl[0];
+
+ set_kmsg_redirect = !tiocl[0];
+ if (set_kmsg_redirect) {
tiocl[0] = TIOCL_SETKMSGREDIRECT;
tiocl[1] = vt;
if (ioctl(fd, TIOCLINUX, tiocl)) {
fprintf(stderr, "Failed to redirect kernel messages to VT %d\n"
"Reason: %s\n", vt, strerror(errno));
fflush(stderr);
+ set_kmsg_redirect = 0;
}
}
+
return fd;
Close_fd:
close(fd);
@@ -753,11 +800,11 @@
fprintf(stderr, "VT %d activation failed\n", orig_vc);
fflush(stderr);
}
- if (kmsg_redirect >= 0) {
+ if (set_kmsg_redirect) {
char tiocl[2];
tiocl[0] = TIOCL_SETKMSGREDIRECT;
- tiocl[1] = kmsg_redirect;
+ tiocl[1] = 0;
ioctl(fd, TIOCLINUX, tiocl);
}
Close_fd:
@@ -797,15 +844,50 @@
fclose(printk_file);
}
+static FILE *swappiness_file;
+
+static inline void open_swappiness(void)
+{
+ swappiness_file = fopen("/proc/sys/vm/swappiness", "r+");
+}
+
+static inline int get_swappiness(void)
+{
+ int swappiness = -1;
+
+ if (swappiness_file) {
+ rewind(swappiness_file);
+ fscanf(swappiness_file, "%d", &swappiness);
+ }
+ return swappiness;
+}
+
+static inline void set_swappiness(int swappiness)
+{
+ if (swappiness_file) {
+ rewind(swappiness_file);
+ fprintf(swappiness_file, "%d\n", swappiness);
+ fflush(swappiness_file);
+ }
+}
+
+static inline void close_swappiness(void)
+{
+ if (swappiness_file)
+ fclose(swappiness_file);
+}
+
#ifdef CONFIG_ENCRYPT
static void generate_key(void)
{
RSA *rsa;
int fd, rnd_fd;
- struct key_data *key_data;
struct RSA_data *rsa_data;
unsigned char *buf;
+ if (!key_data)
+ return;
+
fd = open(key_name, O_RDONLY);
if (fd < 0)
return;
@@ -814,7 +896,6 @@
if (!rsa)
goto Close;
- key_data = (struct key_data *)encrypt_buffer;
rsa_data = &key_data->rsa_data;
if (read(fd, rsa_data, sizeof(struct RSA_data)) <= 0)
goto Free_rsa;
@@ -834,8 +915,7 @@
struct encrypted_key *enc_key;
int ret;
- enc_key = (struct encrypted_key *)(encrypt_buffer
- + sizeof(struct key_data));
+ enc_key = (struct encrypted_key *)(key_data + 1);
ret = RSA_public_encrypt(size, key_data->key,
enc_key->data, rsa, RSA_PKCS1_PADDING);
if (ret > 0) {
@@ -854,11 +934,12 @@
int main(int argc, char *argv[])
{
- char *chroot_path = page_buffer;
+ unsigned int mem_size;
+ char *chroot_path;
struct stat stat_buf;
int resume_fd, snapshot_fd, vt_fd, orig_vc = -1, suspend_vc = -1;
dev_t resume_dev;
- int orig_loglevel, ret;
+ int orig_loglevel, orig_swappiness, ret;
/* Make sure the 0, 1, 2 descriptors are open before opening the
* snapshot and resume devices
@@ -882,14 +963,34 @@
compress = 0;
#endif
#ifdef CONFIG_ENCRYPT
- if (encrypt == 'y' || encrypt == 'Y')
- generate_key();
- else
+ if (encrypt != 'y' && encrypt != 'Y')
encrypt = 0;
#endif
if (s2ram != 'y' && s2ram != 'Y')
s2ram = 0;
+ page_size = getpagesize();
+ buffer_size = BUFFER_PAGES * page_size;
+
+ mem_size = 3 * page_size + buffer_size;
+#ifdef CONFIG_ENCRYPT
+ if (encrypt)
+ mem_size += buffer_size;
+#endif
+ mem_pool = malloc(mem_size);
+ if (!mem_pool) {
+ ret = errno;
+ fprintf(stderr, "suspend: Could not allocate memory\n");
+ return ret;
+ }
+#ifdef CONFIG_ENCRYPT
+ if (encrypt) {
+ mem_size -= buffer_size;
+ key_data = (struct key_data *)((char *)mem_pool + mem_size);
+ generate_key();
+ }
+#endif
+
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
@@ -957,6 +1058,11 @@
orig_loglevel = get_kernel_console_loglevel();
set_kernel_console_loglevel(suspend_loglevel);
+ open_swappiness();
+ orig_swappiness = get_swappiness();
+ set_swappiness(suspend_swappiness);
+
+ chroot_path = mem_pool;
sprintf(chroot_path, "/proc/%d", getpid());
if (!s2ram && chroot(chroot_path)) {
ret = errno;
@@ -973,6 +1079,10 @@
set_kernel_console_loglevel(orig_loglevel);
close_printk();
+ if(orig_swappiness >= 0)
+ set_swappiness(orig_swappiness);
+ close_swappiness();
+
Restore_console:
restore_console(vt_fd, orig_vc);
Close_snapshot_fd:
@@ -980,5 +1090,7 @@
Close_resume_fd:
close(resume_fd);
+ free(mem_pool);
+
return ret;
}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/suspend-20060327/swsusp.h new/suspend-20060406/swsusp.h
--- old/suspend-20060327/swsusp.h 2006-03-26 23:25:38.000000000 +0200
+++ new/suspend-20060406/swsusp.h 2006-04-04 23:35:55.000000000 +0200
@@ -9,7 +9,6 @@
*
*/
-#include