Support btrfs multi-volume probe.
* util/getroot.c (btrfs_ioctl_dev_info_args) [__linux__]: New struct. (btrfs_ioctl_fs_info_args) [__linux__]: Likewise. (BTRFS_IOC_DEV_INFO) [__linux__]: New define. (BTRFS_IOC_FS_INFO) [__linux__]: Likewise. (grub_find_root_devices_from_btrfs) [__linux__]: New function. (grub_find_root_devices_from_mountinfo) [__linux__]: Use grub_find_root_devices_from_btrfs if on btrfs.
This commit is contained in:
parent
c36e5cd162
commit
b913642798
2 changed files with 92 additions and 4 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2012-02-27 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Support btrfs multi-volume probe.
|
||||||
|
|
||||||
|
* util/getroot.c (btrfs_ioctl_dev_info_args) [__linux__]: New struct.
|
||||||
|
(btrfs_ioctl_fs_info_args) [__linux__]: Likewise.
|
||||||
|
(BTRFS_IOC_DEV_INFO) [__linux__]: New define.
|
||||||
|
(BTRFS_IOC_FS_INFO) [__linux__]: Likewise.
|
||||||
|
(grub_find_root_devices_from_btrfs) [__linux__]: New function.
|
||||||
|
(grub_find_root_devices_from_mountinfo) [__linux__]: Use
|
||||||
|
grub_find_root_devices_from_btrfs if on btrfs.
|
||||||
|
|
||||||
2012-02-27 Vladimir Serbinenko <phcoder@gmail.com>
|
2012-02-27 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
Remove any awareness of *.c util files about target.
|
Remove any awareness of *.c util files about target.
|
||||||
|
|
|
@ -142,6 +142,33 @@
|
||||||
# endif /* ! RAW_FLOPPY_MAJOR */
|
# endif /* ! RAW_FLOPPY_MAJOR */
|
||||||
#endif /* defined(__NetBSD__) */
|
#endif /* defined(__NetBSD__) */
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
/* Defines taken from btrfs/ioctl.h. */
|
||||||
|
|
||||||
|
struct btrfs_ioctl_dev_info_args
|
||||||
|
{
|
||||||
|
grub_uint64_t devid;
|
||||||
|
grub_uint8_t uuid[16];
|
||||||
|
grub_uint64_t bytes_used;
|
||||||
|
grub_uint64_t total_bytes;
|
||||||
|
grub_uint64_t unused[379];
|
||||||
|
grub_uint8_t path[1024];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct btrfs_ioctl_fs_info_args
|
||||||
|
{
|
||||||
|
grub_uint64_t max_id;
|
||||||
|
grub_uint64_t num_devices;
|
||||||
|
grub_uint8_t fsid[16];
|
||||||
|
grub_uint64_t reserved[124];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BTRFS_IOC_DEV_INFO _IOWR(0x94, 30, \
|
||||||
|
struct btrfs_ioctl_dev_info_args)
|
||||||
|
#define BTRFS_IOC_FS_INFO _IOR(0x94, 31, \
|
||||||
|
struct btrfs_ioctl_fs_info_args)
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
strip_extra_slashes (char *dir)
|
strip_extra_slashes (char *dir)
|
||||||
{
|
{
|
||||||
|
@ -365,13 +392,52 @@ unescape (char *str)
|
||||||
*optr = 0;
|
*optr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char **
|
||||||
|
grub_find_root_devices_from_btrfs (const char *dir)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct btrfs_ioctl_fs_info_args fsi;
|
||||||
|
int i, j;
|
||||||
|
char **ret;
|
||||||
|
|
||||||
|
fd = open (dir, 0);
|
||||||
|
if (!fd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (ioctl (fd, BTRFS_IOC_FS_INFO, &fsi) < 0)
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = xmalloc ((fsi.num_devices + 1) * sizeof (ret[0]));
|
||||||
|
|
||||||
|
for (i = 1; i <= fsi.max_id && j < fsi.num_devices; i++)
|
||||||
|
{
|
||||||
|
struct btrfs_ioctl_dev_info_args devi;
|
||||||
|
memset (&devi, 0, sizeof (devi));
|
||||||
|
devi.devid = i;
|
||||||
|
if (ioctl (fd, BTRFS_IOC_DEV_INFO, &devi) < 0)
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
free (ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret[j++] = xstrdup ((char *) devi.path);
|
||||||
|
if (j >= fsi.num_devices)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close (fd);
|
||||||
|
ret[j] = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
|
grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
char **ret = NULL;
|
|
||||||
grub_size_t entry_len = 0, entry_max = 4;
|
grub_size_t entry_len = 0, entry_max = 4;
|
||||||
struct mountinfo_entry *entries;
|
struct mountinfo_entry *entries;
|
||||||
struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" };
|
struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" };
|
||||||
|
@ -471,6 +537,7 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
|
||||||
/* Now scan visible mounts for the ones we're interested in. */
|
/* Now scan visible mounts for the ones we're interested in. */
|
||||||
for (i = entry_len - 1; i >= 0; i--)
|
for (i = entry_len - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
|
char **ret = NULL;
|
||||||
if (!*entries[i].device)
|
if (!*entries[i].device)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -493,7 +560,13 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
|
||||||
*relroot = xasprintf ("/%s@%s", slash + 1, entries[i].enc_root);
|
*relroot = xasprintf ("/%s@%s", slash + 1, entries[i].enc_root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (grub_strcmp (entries[i].fstype, "btrfs") == 0)
|
||||||
|
{
|
||||||
|
ret = grub_find_root_devices_from_btrfs (dir);
|
||||||
|
if (relroot)
|
||||||
|
*relroot = strdup (entries[i].enc_root);
|
||||||
|
}
|
||||||
|
if (!ret)
|
||||||
{
|
{
|
||||||
ret = xmalloc (2 * sizeof (ret[0]));
|
ret = xmalloc (2 * sizeof (ret[0]));
|
||||||
ret[0] = strdup (entries[i].device);
|
ret[0] = strdup (entries[i].device);
|
||||||
|
@ -501,13 +574,16 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
|
||||||
if (relroot)
|
if (relroot)
|
||||||
*relroot = strdup (entries[i].enc_root);
|
*relroot = strdup (entries[i].enc_root);
|
||||||
}
|
}
|
||||||
break;
|
free (buf);
|
||||||
|
free (entries);
|
||||||
|
fclose (fp);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
free (buf);
|
free (buf);
|
||||||
free (entries);
|
free (entries);
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
return ret;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ */
|
||||||
|
|
Loading…
Reference in a new issue