LOOP - Linux手册页

时间:2019-08-20 18:01:46  来源:igfitidea点击:

Linux程序员手册 第4部分
更新日期: 2020-06-09

名称

loop, loop-control-回路设备

语法

#include <linux/loop.h>

说明

循环设备是一种块设备,它不将其数据块映射到物理设备(例如硬盘或光盘驱动器),而是映射到文件系统中常规文件的块或另一个块设备。例如,这对于为存储在文件中的文件系统映像提供块设备很有用,以便可以使用mount(8)命令挂载它。你可以做

$ dd if=/dev/zero of=file.img bs=1MiB count=10
$ sudo losetup /dev/loop4 file.img
$ sudo mkfs -t ext4 /dev/loop4
$ sudo mkdir /myloopdev
$ sudo mount /dev/loop4 /myloopdev

有关另一个示例,请参见lostup(8)。

可以为每个环路设备指定一个传递函数,以进行加密和解密。

循环块设备提供以下ioctl(2)操作:

LOOP_SET_FD
将循环设备与打开的文件相关联,该文件的文件描述符作为(第三个)ioctl(2)参数传递。
LOOP_CLR_FD
取消循环设备与任何文件描述符的关联。
LOOP_SET_STATUS
使用(第三个)ioctl(2)参数设置循环设备的状态。此参数是loop_info结构的指针,定义为:
struct loop_info {
    int           lo_number;      /* ioctl r/o */
    dev_t         lo_device;      /* ioctl r/o */
    unsigned long lo_inode;       /* ioctl r/o */
    dev_t         lo_rdevice;     /* ioctl r/o */
    int           lo_offset;
    int           lo_encrypt_type;
    int           lo_encrypt_key_size;  /* ioctl w/o */
    int           lo_flags;       /* ioctl r/w (r/o before
                                     Linux 2.6.25) */
    char          lo_name[LO_NAME_SIZE];
    unsigned char lo_encrypt_key[LO_KEY_SIZE];
                                  /* ioctl w/o */
    unsigned long lo_init[2];
    char          reserved[4];
};
加密类型(lo_encrypt_type)应该是LO_CRYPT_NONELO_CRYPT_XORLO_CRYPT_DESLO_CRYPT_FISH2LO_CRYPT_BLOWLO_CRYPT_CAST128LO_CRYPT_IDEALO_CRYPT_DUMMY,LO_CRYPT_SK。
The lo_flags

field is a bit mask that can include zero or more of the following:

LO_FLAGS_READ_ONLY
环回设备是只读的。
LO_FLAGS_AUTOCLEAR(since Linux 2.6.25)
环回设备将在最后一次关闭时自动销毁。
LO_FLAGS_PARTSCAN(since Linux 3.2)
允许自动分区扫描。
LOOP_GET_STATUS
获取环路设备的状态。第三个ioctl(2)参数必须是指向struct loop_info的指针。
LOOP_CHANGE_FD(since Linux 2.6.5)
将循环设备的后备存储切换到在(第三)ioctl(2)参数中指定的新文件标识的文件描述符,该文件描述符是整数。仅当循环设备为只读并且新的后备存储与旧的后备存储具有相同的大小和类型时,此操作才可能进行。
LOOP_SET_CAPACITY(since Linux 2.6.30)
调整实时循环设备的大小。可以更改基础后备存储的大小,然后使用此操作,以便循环驱动程序了解新的大小。此操作不带任何参数。
LOOP_SET_DIRECT_IO(since Linux 4.10)
在循环设备上设置DIRECT I / O模式,以便可以用来打开备份文件。第三个ioctl(2)参数是一个无符号的long值。非零表示直接I / O模式。
LOOP_SET_BLOCK_SIZE(since Linux 4.14)
设置回路设备的块大小。第三个ioctl(2)参数是一个无符号的long值。该值必须是[512,pagesize]范围内的2的幂。否则,将产生EINVAL错误。

从Linux 2.6开始,有两个新的ioctl(2)操作:

LOOP_SET_STATUS64, LOOP_GET_STATUS64
这些类似于上述的LOOP_SET_STATUS和LOOP_GET_STATUS,但是使用loop_info64结构,该结构具有一些其他字段,并且对于其他一些字段的范围更大:
struct loop_info64 {
    uint64_t lo_device;           /* ioctl r/o */
    uint64_t lo_inode;            /* ioctl r/o */
    uint64_t lo_rdevice;          /* ioctl r/o */
    uint64_t lo_offset;
    uint64_t lo_sizelimit;  /* bytes, 0 == max available */
    uint32_t lo_number;           /* ioctl r/o */
    uint32_t lo_encrypt_type;
    uint32_t lo_encrypt_key_size; /* ioctl w/o */
    uint32_t lo_flags; i          /* ioctl r/w (r/o before
                                     Linux 2.6.25) */
    uint8_t  lo_file_name[LO_NAME_SIZE];
    uint8_t  lo_crypt_name[LO_NAME_SIZE];
    uint8_t  lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
    uint64_t lo_init[2];
};

/dev/loop-control

从Linux 3.1开始,内核提供了/ dev / loop-control设备,它允许应用程序动态查找空闲设备,并从系统中添加和删除循环设备。要执行这些操作,首先打开/ dev / loop-control,然后使用以下ioctl(2)操作之一:

LOOP_CTL_GET_FREE
分配或找到一个空闲环路设备以供使用。成功后,将返回呼叫的设备编号。此操作不带任何参数。
LOOP_CTL_ADD
在第三个ioctl(2)参数中添加其设备号指定为长整数的新循环设备。成功后,设备索引将作为调用结果返回。如果设备已经分配,​​则调用失败,错误为EEXIST。
LOOP_CTL_REMOVE
删除在第三个ioctl(2)参数中将设备号指定为长整数的循环设备。成功后,将返回呼叫的设备编号。如果设备在使用中,则调用失败,并显示错误EBUSY。

文件

/dev/loop*
循环阻止特殊设备文件。

示例

下面的程序使用/ dev / loop-control设备查找一个空闲的循环设备,打开该循环设备,打开一个文件用作该设备的基础存储,然后将循环设备与后备存储关联。以下shell会话演示了该程序的用法:

$ dd if=/dev/zero of=file.img bs=1MiB count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00609385 s, 1.7 GB/s
$ sudo ./mnt_loop file.img
loopname = /dev/loop5

Program source

#include <fcntl.h>
#include <linux/loop.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                        } while (0)

int
main(int argc, char *argv[])
{
    int loopctlfd, loopfd, backingfile;
    long devnr;
    char loopname[4096];

    if (argc != 2) {
        fprintf(stderr, "Usage: %s backing-file\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    loopctlfd = open("/dev/loop-control", O_RDWR);
    if (loopctlfd == -1)
        errExit("open: /dev/loop-control");

    devnr = ioctl(loopctlfd, LOOP_CTL_GET_FREE);
    if (devnr == -1)
        errExit("ioctl-LOOP_CTL_GET_FREE");

    sprintf(loopname, "/dev/loop%ld", devnr);
    printf("loopname = %s\n", loopname);

    loopfd = open(loopname, O_RDWR);
    if (loopfd == -1)
        errExit("open: loopname");

    backingfile = open(argv[1], O_RDWR);
    if (backingfile == -1)
        errExit("open: backing-file");

    if (ioctl(loopfd, LOOP_SET_FD, backingfile) == -1)
        errExit("ioctl-LOOP_SET_FD");

    exit(EXIT_SUCCESS);
}

另外参见

losttup(8),mount(8)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/