support bind and subvolume mount
This commit is contained in:
parent
98042add0c
commit
228cfb40bf
3 changed files with 38 additions and 15 deletions
|
@ -103,8 +103,8 @@ xgetcwd (void)
|
||||||
can't deal with the multiple-device case yet, but in the meantime, we can
|
can't deal with the multiple-device case yet, but in the meantime, we can
|
||||||
at least cope with the single-device case by scanning
|
at least cope with the single-device case by scanning
|
||||||
/proc/self/mountinfo. */
|
/proc/self/mountinfo. */
|
||||||
static char *
|
char *
|
||||||
find_root_device_from_mountinfo (const char *dir)
|
grub_find_root_device_from_mountinfo (const char *dir, char **relroot)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
@ -115,6 +115,9 @@ find_root_device_from_mountinfo (const char *dir)
|
||||||
if (! fp)
|
if (! fp)
|
||||||
return NULL; /* fall through to other methods */
|
return NULL; /* fall through to other methods */
|
||||||
|
|
||||||
|
if (relroot)
|
||||||
|
*relroot = NULL;
|
||||||
|
|
||||||
while (getline (&buf, &len, fp) > 0)
|
while (getline (&buf, &len, fp) > 0)
|
||||||
{
|
{
|
||||||
int mnt_id, parent_mnt_id;
|
int mnt_id, parent_mnt_id;
|
||||||
|
@ -131,9 +134,6 @@ find_root_device_from_mountinfo (const char *dir)
|
||||||
&count) < 6)
|
&count) < 6)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strcmp (enc_root, "/") != 0)
|
|
||||||
continue; /* only a subtree is mounted */
|
|
||||||
|
|
||||||
enc_path_len = strlen (enc_path);
|
enc_path_len = strlen (enc_path);
|
||||||
if (strncmp (dir, enc_path, enc_path_len) != 0 ||
|
if (strncmp (dir, enc_path, enc_path_len) != 0 ||
|
||||||
(dir[enc_path_len] && dir[enc_path_len] != '/'))
|
(dir[enc_path_len] && dir[enc_path_len] != '/'))
|
||||||
|
@ -147,9 +147,6 @@ find_root_device_from_mountinfo (const char *dir)
|
||||||
free (ret);
|
free (ret);
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
|
|
||||||
if (major != 0)
|
|
||||||
continue; /* not a virtual device */
|
|
||||||
|
|
||||||
sep = strstr (buf + count, " - ");
|
sep = strstr (buf + count, " - ");
|
||||||
if (!sep)
|
if (!sep)
|
||||||
continue;
|
continue;
|
||||||
|
@ -158,13 +155,9 @@ find_root_device_from_mountinfo (const char *dir)
|
||||||
if (sscanf (sep, "%s %s", fstype, device) != 2)
|
if (sscanf (sep, "%s %s", fstype, device) != 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (stat (device, &st) < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!S_ISBLK (st.st_mode))
|
|
||||||
continue; /* not a block device */
|
|
||||||
|
|
||||||
ret = strdup (device);
|
ret = strdup (device);
|
||||||
|
if (relroot)
|
||||||
|
*relroot = strdup (enc_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (buf);
|
free (buf);
|
||||||
|
@ -531,7 +524,7 @@ grub_guess_root_device (const char *dir)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
os_dev = find_root_device_from_mountinfo (dir);
|
os_dev = grub_find_root_device_from_mountinfo (dir, NULL);
|
||||||
if (os_dev)
|
if (os_dev)
|
||||||
return os_dev;
|
return os_dev;
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ */
|
||||||
|
|
|
@ -415,6 +415,18 @@ grub_make_system_path_relative_to_its_root (const char *path)
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
{
|
{
|
||||||
free (buf);
|
free (buf);
|
||||||
|
#ifdef __linux__
|
||||||
|
{
|
||||||
|
char *bind;
|
||||||
|
grub_free (grub_find_root_device_from_mountinfo (buf2, &bind));
|
||||||
|
if (bind && bind[0] && bind[1])
|
||||||
|
{
|
||||||
|
buf3 = bind;
|
||||||
|
goto parsedir;
|
||||||
|
}
|
||||||
|
grub_free (bind);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
free (buf2);
|
free (buf2);
|
||||||
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
||||||
if (poolfs)
|
if (poolfs)
|
||||||
|
@ -437,6 +449,21 @@ grub_make_system_path_relative_to_its_root (const char *path)
|
||||||
}
|
}
|
||||||
free (buf);
|
free (buf);
|
||||||
buf3 = xstrdup (buf2 + offset);
|
buf3 = xstrdup (buf2 + offset);
|
||||||
|
buf2[offset] = 0;
|
||||||
|
#ifdef __linux__
|
||||||
|
{
|
||||||
|
char *bind;
|
||||||
|
grub_free (grub_find_root_device_from_mountinfo (buf2, &bind));
|
||||||
|
if (bind && bind[0] && bind[1])
|
||||||
|
{
|
||||||
|
char *temp = buf3;
|
||||||
|
buf3 = grub_xasprintf ("%s%s%s", bind, buf3[0] == '/' ?"":"/", buf3);
|
||||||
|
grub_free (temp);
|
||||||
|
}
|
||||||
|
grub_free (bind);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
free (buf2);
|
free (buf2);
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
|
@ -452,6 +479,7 @@ grub_make_system_path_relative_to_its_root (const char *path)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
parsedir:
|
||||||
/* Remove trailing slashes, return empty string if root directory. */
|
/* Remove trailing slashes, return empty string if root directory. */
|
||||||
len = strlen (buf3);
|
len = strlen (buf3);
|
||||||
while (len > 0 && buf3[len - 1] == '/')
|
while (len > 0 && buf3[len - 1] == '/')
|
||||||
|
|
|
@ -78,4 +78,6 @@ extern char * canonicalize_file_name (const char *path);
|
||||||
int grub_device_mapper_supported (void);
|
int grub_device_mapper_supported (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char *grub_find_root_device_from_mountinfo (const char *dir, char **relroot);
|
||||||
|
|
||||||
#endif /* GRUB_EMU_MISC_H */
|
#endif /* GRUB_EMU_MISC_H */
|
||||||
|
|
Loading…
Add table
Reference in a new issue