Search code examples
mountc

How do I loop mount programmatically?


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?


Solution

  • 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