2

質問:

このようにファイルをループマウントすると

mount /volumes/jfs.dsk /mnt/jfs -t jfs -o loop

舞台裏で起こっていることは

losetup /dev/loop1 /volumes/jfs.dsk
mount /dev/loop1 /mnt/jfs -t jfs -o loop

私の質問:
/dev/loop1 がある場合、このデバイスが属するファイルを見つけるにはどうすればよいですか?
たとえば、入力として「/dev/loop1」が与えられた場合、どうすれば /volumes/jfs.dsk を取り戻すことができますか?

4

3 に答える 3

1

losetup(8)のマニュアルページから

loopdev引数のみが指定されている場合は、対応するループデバイスのステータスが表示されます。

だからあなたは使う必要があるだけです

$ losetup /dev/loop1
/dev/loop1: [0802]:4751362 (/volumes/jfs.dsk)

最近のカーネル(2.6.37以降)を使用している場合は、でターゲットファイルを取得することもできます/sys/block/loopX/loop/backing_file

$ cat /sys/block/loop1/loop/backing_file
/volumes/jfs.dsk

問題を抱えてそれを実行したい場合(明確に示していないが、cタグを追加した場合)、LOOP_GET_STATUSまたはLOOP_GET_STATUS64ioctl呼び出しを使用する必要があります。

于 2012-05-31T13:03:05.983 に答える
1

誰も具体的な答えを知らなかったので、他の人の参考としてここで答えます:

public static string loopfile_from_sysfs(string device)
{
    string res = null;
    Mono.Unix.Native.Stat st;
    System.IntPtr f;

    //if (stat(device, &st) || !S_ISBLK(st.st_mode))
    //if (System.Convert.ToBoolean(Mono.Unix.Native.Syscall.stat(device, out st)) || !S_ISBLK((int) st.st_mode))
    //  return null;

    Mono.Unix.Native.Syscall.stat(device, out st);

    const string _PATH_SYS_DEVBLOCK = "/sys/dev/block";
    string strPath = string.Format("{0}/{1}:{2}/loop/backing_file", _PATH_SYS_DEVBLOCK, gnu_dev_major(st.st_rdev), gnu_dev_minor(st.st_rdev));

    f = Mono.Unix.Native.Syscall.fopen(strPath, "r");
    if (f == IntPtr.Zero)
        return null;

    Mono.Unix.Native.Syscall.fclose(f);

    res = System.IO.File.ReadAllText(strPath);
    strPath = null;
    return res;
} // End Function loopfile_from_sysfs


public static string loopdev_get_loopfile(string device)
{
    string res = loopfile_from_sysfs(device);

    if (res == null)
    {
        loop_info lo = new loop_info();
        loop_info64 lo64 = new loop_info64();

        int fd;

        if ((fd = Mono.Unix.Native.Syscall.open(device, Mono.Unix.Native.OpenFlags.O_RDONLY)) < 0)
            return null;

        if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS64, ref lo64) == 0)
        {
            //lo64.lo_file_name[LO_NAME_SIZE-2] = '*';
            //lo64.lo_file_name[LO_NAME_SIZE-1] = 0;
            //res = strdup((char *) lo64.lo_file_name);
            res = lo64.lo_file_name;
            Console.WriteLine("LOOP_GET_STATUS64");

        }
        else if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS, ref lo) == 0)
        {
            //lo.lo_name[LO_NAME_SIZE-2] = '*';
            //lo.lo_name[LO_NAME_SIZE-1] = 0;
            //res = strdup((char *) lo.lo_name);
            res = lo.lo_name;
            Console.WriteLine("LOOP_GET_STATUS");
        }

        Mono.Unix.Native.Syscall.close(fd);
    } // End if (res == null)

    return res;
} // End Function loopdev_get_loopfile

そして、これはCバージョンです:

static char *loopfile_from_sysfs(const char *device)
{
    FILE *f;
    struct stat st;
    char buf[PATH_MAX], *res = NULL;
    // PATH_MAX: 4096

    if (stat(device, &st) || !S_ISBLK(st.st_mode))
        return NULL;

    #define _PATH_SYS_DEVBLOCK "/sys/dev/block"
    snprintf(buf, sizeof(buf), _PATH_SYS_DEVBLOCK "/%d:%d/loop/backing_file",
            major(st.st_rdev), minor(st.st_rdev));

    f = fopen(buf, "r");
    if (!f)
        return NULL;

    if (fgets(buf, sizeof(buf), f)) {
        size_t sz = strlen(buf);
        if (sz) {
            buf[sz - 1] = '\0';
            res = strdup(buf);
        }
    }

    fclose(f);

    printf("loopfile_from_sysfs Result: %s\n", res);
    return res;
}



char *loopdev_get_loopfile(const char *device)
{
    char *res = loopfile_from_sysfs(device);

    if (!res) {
        struct loop_info lo;
        struct loop_info64 lo64;
        int fd;

        if ((fd = open(device, O_RDONLY)) < 0)
            return NULL;

        if (ioctl(fd, LOOP_GET_STATUS64, &lo64) == 0) {
            lo64.lo_file_name[LO_NAME_SIZE-2] = '*';
            lo64.lo_file_name[LO_NAME_SIZE-1] = 0;
            res = strdup((char *) lo64.lo_file_name);
            printf("LOOP_GET_STATUS64\n");

        } else if (ioctl(fd, LOOP_GET_STATUS, &lo) == 0) {
            lo.lo_name[LO_NAME_SIZE-2] = '*';
            lo.lo_name[LO_NAME_SIZE-1] = 0;
            res = strdup((char *) lo.lo_name);
            printf("LOOP_GET_STATUS\n");
        }
        close(fd);
    }
    return res;
}
于 2012-06-16T07:20:43.647 に答える