On Friday, 10 November 2006 18:59, Luca Tettamanti wrote:
> Il Thu, Nov 09, 2006 at 10:35:13PM +0100, Rafael J. Wysocki ha scritto: 
> > On Thursday, 9 November 2006 22:30, Luca Tettamanti wrote:
> > > On 11/9/06, Rafael J. Wysocki <[EMAIL PROTECTED]> wrote:
> > > > I think that the swap header need not be continuous.  This actually also
> > > > follows from the sys_swapon() code which reads one page from the file
> > > > using its mapping.  It looks like setup_swap_extents() omits the first
> > > > continuous PAGE_SIZE "block" just in case it contains the header, but
> > > > the swap-handling will work even if it doesn't.
> > > >
> > > > However, in case this happens, swsusp and s2disk/s2both won't be
> > > > able to use the swap file for the suspend, because swap_type_of() will
> > > > fail.
> > > >
> > > > Now if that really is what happens (could you please verify with your 
> > > > setup?),
> > > 
> > > It seems so. What I see is the following:
> > > 
> > > 0x0000-0x1000: header, not contiguous
> > > 0x1000-0x2000: nothing, this page is left empty
> > > 0x2000-EOF: swap data
> > > 
> > > > it would be nice if your program detected such situations and informed 
> > > > the
> > > > user that the swap file could not be used.
> > > 
> > > Basically:
> > > - find the first block of the swapfile
> > > - check that there's a contiguous PAGE_SIZE cluster
> > > - check signature
> > 
> > ... and print the number if everything fits.
> 
> Yeah :)

Looks good, one small comment below.

_However_,

I think we can do one more thing.  Namely, if the header is not continuous,
the kernel will leave the first continuous PAGE_SIZE "block" of the swap file
untouched.  So, why don't we copy the swap signature into that "block",
to the place in which it would be if the the header was there, and return
its offset as the offset of the header?  Then, swsusp and s2disk should work
normally as well as the swap.

I don't think the program should do this automatically, but there may be a
flag allowing the user to modify a swap file with non-continuous header so
that it can be used for suspending.


> #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, blocks_per_page;
>       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 */
>       if (lseek(fd, page_size - 10, SEEK_SET) == (off_t)-1) {
>               err = errno;
>               perror("lseek()");
>               goto out;
>       }
>       i = read(fd, buf, 10);
>       if (i == -1) {

I'd use (i < 0) here.

>               err = errno;
>               perror("read()");
>               goto out;
>       } else if (i < 10) {
>               fprintf(stderr, "Failed to read swap signature: file is too 
> short.\n");
>               err = EINVAL;
>               goto out;
>       }
> 
>       if (memcmp(buf, SWAP_SIG, 10)) {
>               fprintf(stderr, "Swap signature not found.\n");
>               err = EINVAL;
>               goto out;
>       }
> 
>       if (fstat(fd, &stat)) {
>               err = errno;
>               perror("fstat()");
>               goto out;
>       }
>       if (ioctl(fd, FIGETBSZ, &blk_size)) {
>               err = errno;
>               perror("ioctl(FIGETBSZ) failed");
>               goto out;
>       }
> 
>       blocks_per_page = page_size / blk_size;
> 
>       /* Check that the header is contiguous */
>       last_block = 0;
>       first_block = 0;
>       size = 0;
>       for (i = 0; i < blocks_per_page; i++) {
>               block = i;
> 
>               if (ioctl(fd, FIBMAP, &block)) {
>                       err = errno;
>                       perror("ioctl(FIBMAP) failed");
> 
>                       goto out;
>               }
>               
>               if (last_block && block != last_block + 1)
>                       break;
>               if (!first_block)
>                       first_block = block;
> 
>               size += blk_size;
>               last_block = block;
>       }
>       if (size < page_size) {
>               fprintf(stderr, "Swapfile header is not contiguous and cannot 
> be used"
>                               "for suspension.\n");
>               err = EINVAL;
>       } else
>               printf("resume offset = %d\n", first_block * blk_size / 
> page_size);
> 
> out:
>       close(fd);
> 
>       return err;
> }
> 
> 
> Luca

-- 
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