loop(4)

NUME
loop, loop-control - dispozitive de buclă

SINOPSIS
#include <linux/loop.h>

DESCRIERE
Dispozitivul de buclă este un dispozitiv de blocuri care cartografiază blocurile sale de date nu la un dispozitiv fizic, cum ar fi un disc dur sau o unitate de disc optic, ci la blocurile unui fișier obișnuit dintr-un sistem de fișiere sau la un alt dispozitiv de blocuri. Acest lucru poate fi util, de exemplu, pentru a furniza un dispozitiv de blocuri pentru o imagine a sistemului de fișiere stocată într-un fișier, astfel încât acesta să poată fi montat cu comanda mount(8). Ați putea face

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

Vedeți losetup(8) pentru un alt exemplu.

O funcție de transfer poate fi specificată pentru fiecare dispozitiv de buclă în scopul criptării și decriptării.

Următoarele operații ioctl(2) sunt furnizate de dispozitivul de blocuri al buclei:

LOOP_SET_FD
    Asociază dispozitivul buclei cu fișierul deschis al cărui descriptor de fișier este pasat ca (al treilea) argument al ioctl(2).

LOOP_CLR_FD
    Dezasociază dispozitivul buclei de orice descriptor de fișier.

LOOP_SET_STATUS
    Stabilește starea dispozitivului buclei utilizând (al treilea) argument al ioctl(2). Acest argument este un indicator către o structură loop_info, definită în <linux/loop.h> ca:

        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 înainte de
                                             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];
        };

    Tipul de criptare (lo_encrypt_type) trebuie să fie unul dintre LO_CRYPT_NONE, LO_CRYPT_XOR, LO_CRYPT_DES, LO_CRYPT_FISH2, LO_CRYPT_BLOW, LO_CRYPT_CAST128, LO_CRYPT_IDEA, LO_CRYPT_DUMMY, LO_CRYPT_SKIPJACK sau ( începând cu Linux 2. 6.0) LO_CRYPT_CRYPTOAPI.

    Câmpul lo_flags este o mască de biți care poate include niciuna sau mai multe dintre următoarele:

    LO_FLAGS_READ_ONLY
        Dispozitivul de buclă este numa-pentru-citire.

    LO_FLAGS_AUTOCLEAR (începând cu Linux 2.6.25)
        Dispozitivul de buclă se va autodistruge la ultima închidere.

    LO_FLAGS_PARTSCAN (începând cu Linux 3.2)
        Permite scanarea automată a partițiilor.

    LO_FLAGS_DIRECT_IO (începând cu Linux 4.10)
        Utilizează modul In/Ieș direct pentru a accesa fișierul de susținere.

    Singurele lo_flags care pot fi modificate de LOOP_SET_STATUS sunt LO_FLAGS_AUTOCLEAR și LO_FLAGS_PARTSCAN.

LOOP_GET_STATUS
    Obține starea dispozitivului buclei. Argumentul (al treilea) al ioctl(2) trebuie să fie un indicator către o structură struct loop_info.

LOOP_CHANGE_FD (începând cu Linux 2.6.5)
    Comută stocarea de susținere a dispozitivului de buclă la noul descriptor de fișier identificat în fișierul specificat în (al treilea) argument al ioctl(2), care este un număr întreg. Această operație este posibilă numai în cazul în care dispozitivul de buclă este numai pentru citire, iar noua stocare de susținere are aceeași dimensiune și același tip ca vechea stocare de susținere.

LOOP_SET_CAPACITY (începând cu Linux 2.6.30)
    Redimensionează un dispozitiv de buclă activ. Se poate modifica dimensiunea stocării de susținere subiacente și apoi se poate utiliza această operație astfel încât controlorul buclei să afle despre noua dimensiune. Această operație nu are niciun argument.

LOOP_SET_DIRECT_IO (începând cu Linux 4.10)
    Stabilește modul de In/Ieș DIRECT pe dispozitivul de buclă, astfel încât acesta să poată fi utilizat pentru a deschide fișierul de susținere. Al (treilea) argument al ioctl(2) este o valoare lungă fără semn. O valoare diferită de zero reprezintă modul de In/Ieș direct.

LOOP_SET_BLOCK_SIZE (începând cu Linux 4.14)
    Stabilește dimensiunea blocului dispozitivului buclei. Al (treilea) argument al ioctl(2) este o valoare lungă fără semn. Această valoare trebuie să fie o putere de doi în intervalul [512,dimensiune-pagină]; în caz contrar, rezultă o eroare EINVAL.

LOOP_CONFIGURE (începând cu Linux 5.8)
    Stabilește și configurează toți parametrii dispozitivului buclei într-un singur pas utilizând argumentul (al treilea) al ioctl(2). Acest argument este un indicator către o structură loop_config, definită în <linux/loop.h> ca:

        struct loop_config {
            __u32               fd;
            __u32               block_size;
            struct loop_info64  info;
            __u64               __reserved[8];
        };

    În plus față de ceea ce poate face LOOP_SET_STATUS, LOOP_CONFIGURE poate fi utilizat și pentru a face următoarele:

    •   stabilește imediat dimensiunea corectă a blocului prin parametrul loop_config.block_size;

    •   solicită în mod explicit modul de I/O direct prin definirea LO_FLAGS_DIRECT_IO în loop_config.info.lo_flags; și

    •   solicită în mod explicit modul numai-citire prin definirea LO_FLAGS_READ_ONLY în loop_config.info.lo_flags.

Începând cu Linux 2.6, există două noi operații ioctl(2):

LOOP_SET_STATUS64
LOOP_GET_STATUS64
    Acestea sunt similare cu LOOP_SET_STATUS și LOOP_GET_STATUS descrise mai sus, dar utilizează structura loop_info64, care are câteva câmpuri suplimentare și un interval mai mare pentru alte câmpuri:

        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;  /* octeți, 0 == maxim disponibil */
            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 înainte de
                                             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
Începând cu Linux 3.1, nucleul oferă dispozitivul /dev/loop-control, care permite unei aplicații să găsească în mod dinamic un dispozitiv liber și să adauge și să elimine dispozitive de buclă din sistem. Pentru a efectua aceste operații, se deschide mai întâi /dev/loop-control și apoi se utilizează una dintre următoarele operații ioctl(2):

LOOP_CTL_GET_FREE
    Alocă sau găsește un dispozitiv de buclă liber pentru utilizare. În caz de succes, numărul dispozitivului este returnat ca rezultat al apelului. Această operație nu are niciun argument.

LOOP_CTL_ADD
    Adaugă noul dispozitiv de buclă al cărui număr de dispozitiv este specificat ca număr întreg lung în al treilea argument al ioctl(2). În caz de succes, indicele dispozitivului este returnat ca rezultat al apelului. Dacă dispozitivul este deja alocat, apelul eșuează cu eroarea EEXIST.

LOOP_CTL_REMOVE
    Elimină dispozitivul buclei al cărui număr de dispozitiv este specificat ca număr întreg lung în al treilea argument al ioctl(2). În caz de succes, numărul dispozitivului este returnat ca rezultat al apelului. Dacă dispozitivul este în uz, apelul eșuează cu eroarea EBUSY.

FIȘIERE

/dev/loop*
    Fișierele dispozitivelor speciale de blocuri ai buclei.

EXEMPLE
Programul de mai jos utilizează dispozitivul /dev/loop-control pentru a găsi un dispozitiv de buclă liber, deschide dispozitivul de buclă, deschide un fișier care să fie utilizat ca spațiu de stocare de bază pentru dispozitiv și apoi asociază dispozitivul de buclă cu spațiul de stocare de bază. Următoarea sesiune shell demonstrează utilizarea programului:

    $ 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

  Sursa programului
    #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, "Utilizare: %s fișier-susținere\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: fișier-susținere");

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

        exit(EXIT_SUCCESS);
    }

CONSULTAȚI ȘI
losetup(8), mount(8)

TRADUCERE
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 (https://www.gnu.org/licenses/gpl-3.0.html) sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.