Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I loop mount programmatically?

Tags:

c

mount

I have recently written a guide on how to mount partitions from image files on Raspberry Pi.SE. The instructions are rather complicated and I have a bit of time, so want to replace them by a C program. I have successfully listed the partitions of the image and calculated to appropriate offsets.

In the original instructions, we needed to run

$ sudo mount -o loop,offset=80740352 debian6-19-04-2012.img /mnt

I now need to do this in code. I have found the mount function and libmount in util-linux.

I have now found loopdev.c in util-linux. Is there an easy way to create loop devices or do I have to learn from this code and use ioctl?

like image 757
Alex Chamberlain Avatar asked Jul 02 '12 11:07

Alex Chamberlain


People also ask

What is Loop in mount command?

A "loop" device in Linux is an abstraction that lets you treat a file like a block device. It's specifically meant for a use like your example, where you can mount a file containing a CD image and interact with the filesystem in it as if it were burned to a CD and placed in your drive.

What is a loop block device?

The loop device is a block device that maps its data blocks not to a physical device such as a hard disk or optical disk drive, but to the blocks of a regular file in a filesystem or to another block device.

What is Dev loop control?

The special /dev/loop-control file can be used to create and destroy loop devices or to find the first available loop device. Associating a file with a specific device, or setting other parameters like offsets or block sizes, is done with ioctl() calls on the device itself.


1 Answers

The following function binds the loop device device to file at offset. It returns 0 on success, 1 otherwise.

int loopdev_setup_device(const char * file, uint64_t offset, const char * device) {
  int file_fd = open(file, O_RDWR);
  int device_fd = -1; 

  struct loop_info64 info;

  if(file_fd < 0) {
    fprintf(stderr, "Failed to open backing file (%s).\n", file);
    goto error;
  }

  if((device_fd = open(device, O_RDWR)) < 0) {
    fprintf(stderr, "Failed to open device (%s).\n", device);
    goto error;
  }

  if(ioctl(device_fd, LOOP_SET_FD, file_fd) < 0) {
    fprintf(stderr, "Failed to set fd.\n");
    goto error;
  }

  close(file_fd);
  file_fd = -1; 

  memset(&info, 0, sizeof(struct loop_info64)); /* Is this necessary? */
  info.lo_offset = offset;
  /* info.lo_sizelimit = 0 => max avilable */
  /* info.lo_encrypt_type = 0 => none */

  if(ioctl(device_fd, LOOP_SET_STATUS64, &info)) {
    fprintf(stderr, "Failed to set info.\n");
    goto error;
  }

  close(device_fd);
  device_fd = -1; 

  return 0;

  error:
    if(file_fd >= 0) {
      close(file_fd);
    }   
    if(device_fd >= 0) {
      ioctl(device_fd, LOOP_CLR_FD, 0); 
      close(device_fd);
    }   
    return 1;
}

References

  1. linux/loop.h
  2. piimg
like image 190
Alex Chamberlain Avatar answered Oct 16 '22 12:10

Alex Chamberlain