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