Hi,
On Wednesday, 8 November 2006 18:58, Luca wrote:
> I've been working on a small program to find the first valid block of a
> swapfile. If I understand it correctly we need the first contiguos cluster
> of blocks (not counting the header) which is at least PAGE_SIZE big and
> the starting block must be page aligned.
> The block number must then be converted in an offset from the start of
> the device and the number must be expressed in multiple of PAGE_SIZE.
>
> This is what I've come up with ;)
It doesn't look bad, but you shouldn't skip the header, actually. The header
is what we need. ;-)
> #include <stdio.h>
> #include <string.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <sys/ioctl.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <linux/fs.h>
> #include <errno.h>
>
> #define SWAP_SIG "SWAPSPACE2"
>
> int main(int argc, char **argv) {
> int block, last_block, first_block;
Don't use int here, please. loff_t will do, or long long int verbatim.
Generally, beware of huge numbers. :-)
> int size, blk_size;
> int fd;
> int i;
> struct stat stat;
> unsigned char buf[10];
> int err = 0;
> int const page_size = getpagesize();
>
> if (argc < 2)
> return EINVAL;
>
> fd = open(argv[1], O_RDONLY);
> if (fd < 0) {
> perror("open()");
> return ENOENT;
> }
>
> /* Check swap signature */
> lseek(fd, page_size - 10, SEEK_SET);
> read(fd, buf, 10);
The return values of the two above should be checked, just in case.
> if (memcmp(buf, SWAP_SIG, 10)) {
> fprintf(stderr, "Swap signature not found\n");
> err = EINVAL;
> goto out;
> }
>
> fstat(fd, &stat);
> ioctl(fd, FIGETBSZ, &blk_size);
Ditto.
> /* Skip swap header (1 page) */
Don't skip!
> i = page_size / blk_size;
>
> size = 0;
> last_block = 0;
> first_block = 0;
> for (; i < stat.st_blocks; i++) {
> block = i;
>
> if (ioctl(fd, FIBMAP, &block)) {
I think
err = errno;
here ...
> perror("ioctl()");
> err = EIO;
... and drop this one.
> goto out;
> }
>
> if (block != last_block + 1) {
> /* Swap space must be page aligned */
> if (block * blk_size % page_size)
> continue;
> first_block = block;
> size = 0;
> }
>
> size += blk_size;
> last_block = block;
>
> if (size >= page_size)
> break;
> }
> if (size < page_size) {
> fprintf(stderr, "Invalid swapfile\n");
I'd say a bit more in the message (why it's invalid, in our opinion).
> err = EINVAL;
> } else
> printf("%d\n", first_block * blk_size / page_size);
If you do
printf("resume offset = %ld\n", first_block * blk_size /
page_size);
then someone will be able to use it in a script directly to modify suspend.conf
>
> out:
> close(fd);
>
> return err;
> }
>
> How does it look?
Not too bad, IMO, but some work is still needed. :-)
Greetings,
Rafael
--
You never change things by fighting the existing reality.
R. Buckminster Fuller
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Suspend-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/suspend-devel