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
Suspend-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/suspend-devel

Reply via email to