SELinux relabel API
by Richard W.M. Jones
[
I realized that we were discussing adding this feature, in various
private email, IRC, and this long bugzilla thread:
https://bugzilla.redhat.com/show_bug.cgi?id=1060423
That's not how we should do things. Let's discuss it on the
mailing list.
]
One thing that virt-customize/virt-sysprep/virt-builder have to do is
relabel SELinux guests.
What we do at the moment is run:
if load_policy && fixfiles restore; then
rm -f /.autorelabel
else
touch /.autorelabel
echo '%s: SELinux relabelling failed, will relabel at boot instead.'
fi
while chrooted into the guest (using the 'guestfs_sh' API).
This has a number of problems:
- It has to load the policy using 'load_policy', but this doesn't
work sometimes:
* RHEL 5 load_policy takes a parameter.
* Doesn't work if appliance kernel is significantly different from
guest kernel version, because the binary policy format changes
irregularly and is not backwards compatible.
* Requires the appliance [host] kernel to be compiled with
LSM/SELinux support.
- Touching /.autorelabel is often broken, eg. it's broken in Fedora 20
because of systemd (RHBZ#1049656).
- /etc/resolv.conf will not be relabelled if guestfs network is on,
because of resolv.conf shenanigans in libguestfs.git/daemon/command.c
- It requires running guest code, which we'd like to avoid.
What would be nice would be to have an API to just do this
relabelling. Libguestfs could change this API as required to handle
different guests.
Dan Walsh helpfully pointed out to us that we've been doing it wrong
all along :-) A much better way to relabel is to run:
setfiles /etc/selinux/targeted/contexts/files/file_contexts DIR
where 'file_contexts' is a file which contains the default labels for
files (a set of regexps), and 'DIR' is the directory at which
relabelling starts. Note that 'setfiles' would be the libguestfs
appliance binary, so no guest binary needs to be run.
A simple API could just look like this:
guestfs_selinux_relabel (g);
which would always use the 'targeted' policy from the guest, and
always start relabelling at the root. This would work fine for
virt-builder.
For Colin's requirements for Project Atomic, I suspect he will want to
be able to set the file_contexts file and the root directory, but I'll
leave him to describe what would be useful.
A couple of notes:
- I'd like to avoid baking in assumptions from the 'setfiles' command
as far as possible. libguestfs APIs last for many years and some
have caused us many years of regret (but that's our job) :-/
- Is it a good idea to tie this into inspection in some way -- for
example, inspection could provide us with the path to the current or
default SELinux policy.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
8 years, 11 months
missing btrfs subvol support
by Olaf Hering
Is btrfs subvol support failing just for me? Looks like nothing adds the
required '@/' string. virt-ls uses the first variant of the command:
><rescue> mount -vo subvol=var/spool,ro /dev/sda2 /sysroot/
[ 113.852047] BTRFS info (device sda2): disk space caching is enabled
[ 113.852869] BTRFS: has skinny extents
mount: mount(2) failed: No such file or directory
><rescue> mount -vo subvol=@var/spool,ro /dev/sda2 /sysroot/
[ 116.082642] BTRFS info (device sda2): disk space caching is enabled
[ 116.083476] BTRFS: has skinny extents
mount: mount(2) failed: No such file or directory
><rescue> mount -vo subvol=@/var/spool,ro /dev/sda2 /sysroot/
[ 123.995343] BTRFS info (device sda2): disk space caching is enabled
[ 123.996238] BTRFS: has skinny extents
mount: /dev/sda2 mounted on /sysroot.
><rescue> exit
fstab is:
UUID=d538a81f-9778-424d-96cc-e48dd2d4a323 swap swap defaults 0 0
UUID=65b72f12-eccb-4cf2-a4f4-9c4bb462456f / btrfs defaults 0 0
UUID=65b72f12-eccb-4cf2-a4f4-9c4bb462456f /var/spool btrfs subvol=@/var/spool 0 0
Olaf
9 years, 2 months
[libguestfs] conversion issue on NFS shares
by Artur Krzywdzinski
Hi
T'm trying to convert XEN virtual machine image into raw. Source file is on
NFS export and destination is also on nfs export. (both exports are mounted
on migration servers RW access). I'm getting permission denied.
I have RW access to both exports - I can create, delete objects on both
exports from migration server. But when I copy img file onto migration
server local filesystem, conversion works, from local fs to nfs export.
However when I tried to run guestfish against file located on NFS - I'm
getting the same erro - Permission denied .
[root@kvm01 export]# virt-v2v -i disk migr01.img -o local -os /tmp
[ 0.0] Opening the source -i disk migr01.img
[ 0.0] Creating an overlay to protect the source from being modified
[ 0.0] Opening the overlay
virt-v2v: error: libguestfs error: could not create appliance through
libvirt.
Try running qemu directly without libvirt using this environment variable:
export LIBGUESTFS_BACKEND=direct
Original error from libvirt: internal error: process exited while
connecting to monitor: 2014-10-16T14:25:13.729270Z qemu-kvm: -drive
file=/var/tmp/v2vovl60e1a0.qcow2,if=none,id=drive-scsi0-0-0-0,format=qcow2,cache=unsafe,discard=unmap:
could not open disk image /var/tmp/v2vovl60e1a0.qcow2: Could not open
backing file: Could not open '/mnt/xen01/export/migr01.img': Permission
denied
[code=1 domain=10]
If reporting bugs, run virt-v2v with debugging enabled and include the
complete output:
virt-v2v -v -x [...]
[root@kvm01 export]#
--
Artur Krzywdzinski
9 years, 6 months
[PATCH v5 REBASE 0/4] virt-resize: add support for resizing logical
by Hu Tao
Hi Rich,
This is rebase of v5 series. Meanwhile, I found a bug when shrinking
partitions, and the fix is incuded in this version (patch 2).
Regards,
Hu
changes to v4:
1. add support to resize extended partition (--resize or --expand extended partition)
2. fix the problem of deficit of 512 bytes when expanding a logical partition
(this problem can be reproduced in v4 by only expanding a logical partition, without resizing any other partitions)
3. update the test script to support logical partitions and extended partition
changes to v3:
1. merge patch 1 and patch 3 in v3
2. let mbr_part_type return 'primary' for GPT partitions
3. add test for resizing logical partitions
4. fix extending the extended partition (yet). see patch 7.
changes to v2:
1. remove p_part_num
2. remove filter_parts
3. name the function calculate_target_partitions
4. remove the code to restart guest introduced in v2
changes to v1:
1. spit the patches so it's easier to review
2. fix the parted error caused by unaligned logical partitions
3. extend the content of logical partitions
4. refactor to make logical partitions a seperate list
Hu Tao (4):
resize: add partition type LogicalPartition
resize: add support to resize logical partitions
resize: support resize extended partition
resize: test: add support for resizing extended and logical partitions
resize/resize.ml | 123 +++++++++++++++++++++++++++++++++++++++------
resize/test-virt-resize.pl | 32 ++----------
2 files changed, 112 insertions(+), 43 deletions(-)
--
1.9.3
9 years, 8 months
[PATCH 0/4] fix bad commit ids referenced in commit messages
by Hu Tao
Hi,
This series fix two bad commit ids referenced in commit messages, by
first reverting the two commits and then re-applying them with correct
commit ids referenced. No big problem, but for clarity.
Hu Tao (4):
Revert "Update gobject/Makefile.inc and POTFILES"
Revert "Update gobject/Makefile.inc and POTFILES"
Update gobject/Makefile.inc and POTFILES
Update gobject/Makefile.inc and POTFILES
--
1.9.3
9 years, 11 months
[PATCH] fish: show synopsis if command syntax is wrong
by Hu Tao
This patch lets guestfish show command synopsis if the syntax of command issued
by user is wrong, rather than telling user that the number of parameters is wrong.
Signed-off-by: Hu Tao <hutao(a)cn.fujitsu.com>
---
fish/cmds-gperf.h | 1 +
generator/fish.ml | 33 ++++++++++++---------------------
2 files changed, 13 insertions(+), 21 deletions(-)
diff --git a/fish/cmds-gperf.h b/fish/cmds-gperf.h
index 74db69d..bcb3b5d 100644
--- a/fish/cmds-gperf.h
+++ b/fish/cmds-gperf.h
@@ -25,6 +25,7 @@
struct command_entry {
const char *name; /* Short name. */
const char *help; /* Online help. */
+ const char *synopsis; /* Synopsis. */
/* The run_* function. */
int (*run) (const char *cmd, size_t argc, char *argv[]);
diff --git a/generator/fish.ml b/generator/fish.ml
index 3f53ffa..951b376 100644
--- a/generator/fish.ml
+++ b/generator/fish.ml
@@ -190,6 +190,7 @@ Guestfish will prompt for these separately."
pr "struct command_entry %s_cmd_entry = {\n" name;
pr " .name = \"%s\",\n" name2;
pr " .help = \"%s\",\n" (c_quote text);
+ pr " .synopsis = \"%s\",\n" (c_quote synopsis);
pr " .run = run_%s\n" name;
pr "};\n";
pr "\n";
@@ -393,30 +394,14 @@ Guestfish will prompt for these separately."
if argc_minimum = argc_maximum then (
pr " if (argc != %d) {\n" argc_minimum;
- if argc_minimum = 0 then (
- pr " fprintf (stderr, _(\"%%s should have no parameters\\n\"), cmd);\n";
- ) else (
- pr " fprintf (stderr, ngettext(\"%%s should have %%d parameter\\n\",\n";
- pr " \"%%s should have %%d parameters\\n\",\n";
- pr " %d),\n"
- argc_minimum;
- pr " cmd, %d);\n"
- argc_minimum;
- )
+ pr " ret = -2;\n";
) else if argc_minimum = 0 then (
pr " if (argc > %d) {\n" argc_maximum;
- pr " fprintf (stderr, ngettext(\"%%s should have at most %%d parameter\\n\",\n";
- pr " \"%%s should have at most %%d parameters\\n\",\n";
- pr " %d),\n"
- argc_maximum;
- pr " cmd, %d);\n"
- argc_maximum;
+ pr " ret = -2;\n";
) else (
pr " if (argc < %d || argc > %d) {\n" argc_minimum argc_maximum;
- pr " fprintf (stderr, _(\"%%s should have %%d-%%d parameter(s)\\n\"), cmd, %d, %d);\n"
- argc_minimum argc_maximum;
+ pr " ret = -2;\n";
);
- pr " fprintf (stderr, _(\"type 'help %%s' for help on %%s\\n\"), cmd, cmd);\n";
pr " goto out_noargs;\n";
pr " }\n";
@@ -694,10 +679,16 @@ Guestfish will prompt for these separately."
pr "run_action (const char *cmd, size_t argc, char *argv[])\n";
pr "{\n";
pr " const struct command_table *ct;\n";
+ pr " int ret = -1;\n";
pr "\n";
pr " ct = lookup_fish_command (cmd, strlen (cmd));\n";
- pr " if (ct)\n";
- pr " return ct->entry->run (cmd, argc, argv);\n";
+ pr " if (ct) {\n";
+ pr " ret = ct->entry->run (cmd, argc, argv);\n";
+ pr " if (ret == -2) {\n";
+ pr " fprintf (stderr, _(\"usage: %%s\\n\"), ct->entry->synopsis);\n";
+ pr " fprintf (stderr, _(\"type 'help %%s' for more help on %%s\\n\"), cmd, cmd);\n";
+ pr " }\n";
+ pr " }\n";
pr " else {\n";
pr " fprintf (stderr, _(\"%%s: unknown command\\n\"), cmd);\n";
pr " if (command_num == 1)\n";
--
1.9.3
9 years, 11 months
[PATCH] lib: Add COMPILE_REGEXP macro to hide regexp constructors/destructors.
by Richard W.M. Jones
[NOTE: this is not the complete patch. Once ACKed, I will make the
same mechanical change to all the other places in the library that use
this pattern.]
---
src/guestfs-internal.h | 24 ++++++++
src/inspect-fs-unix.c | 164 +++++++++++--------------------------------------
2 files changed, 59 insertions(+), 129 deletions(-)
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index fd0c4a1..33d28f5 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -667,6 +667,30 @@ extern int guestfs___match6 (guestfs_h *g, const char *str, const pcre *re, char
#define match4 guestfs___match4
#define match6 guestfs___match6
+/* Macro which compiles the regexp once when the library is loaded,
+ * and frees it when the library is unloaded.
+ */
+#define COMPILE_REGEXP(name,pattern,options) \
+ static void compile_regexp_##name (void) __attribute__((constructor)); \
+ static void free_regexp_##name (void) __attribute__((destructor)); \
+ static pcre *name; \
+ static void \
+ compile_regexp_##name (void) \
+ { \
+ const char *err; \
+ int offset; \
+ name = pcre_compile ((pattern), (options), &err, &offset, NULL); \
+ if (name == NULL) { \
+ ignore_value (write (2, err, strlen (err))); \
+ abort (); \
+ } \
+ } \
+ static void \
+ free_regexp_##name (void) \
+ { \
+ pcre_free (name); \
+ }
+
/* stringsbuf.c */
struct stringsbuf {
char **argv;
diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c
index fb5cc1a..01a59f1 100644
--- a/src/inspect-fs-unix.c
+++ b/src/inspect-fs-unix.c
@@ -45,135 +45,41 @@
#include "guestfs-internal-actions.h"
#include "guestfs_protocol.h"
-/* Compile all the regular expressions once when the shared library is
- * loaded. PCRE is thread safe so we're supposedly OK here if
- * multiple threads call into the libguestfs API functions below
- * simultaneously.
- */
-static pcre *re_fedora;
-static pcre *re_rhel_old;
-static pcre *re_rhel;
-static pcre *re_rhel_no_minor;
-static pcre *re_centos_old;
-static pcre *re_centos;
-static pcre *re_centos_no_minor;
-static pcre *re_scientific_linux_old;
-static pcre *re_scientific_linux;
-static pcre *re_scientific_linux_no_minor;
-static pcre *re_oracle_linux_old;
-static pcre *re_oracle_linux;
-static pcre *re_oracle_linux_no_minor;
-static pcre *re_major_minor;
-static pcre *re_xdev;
-static pcre *re_cciss;
-static pcre *re_mdN;
-static pcre *re_freebsd_mbr;
-static pcre *re_freebsd_gpt;
-static pcre *re_diskbyid;
-static pcre *re_netbsd;
-static pcre *re_opensuse;
-static pcre *re_sles;
-static pcre *re_nld;
-static pcre *re_opensuse_version;
-static pcre *re_sles_version;
-static pcre *re_sles_patchlevel;
-static pcre *re_minix;
-static pcre *re_hurd_dev;
-
-static void compile_regexps (void) __attribute__((constructor));
-static void free_regexps (void) __attribute__((destructor));
-
-static void
-compile_regexps (void)
-{
- const char *err;
- int offset;
-
-#define COMPILE(re,pattern,options) \
- do { \
- re = pcre_compile ((pattern), (options), &err, &offset, NULL); \
- if (re == NULL) { \
- ignore_value (write (2, err, strlen (err))); \
- abort (); \
- } \
- } while (0)
-
- COMPILE (re_fedora, "Fedora release (\\d+)", 0);
- COMPILE (re_rhel_old,
- "Red Hat.*release (\\d+).*Update (\\d+)", 0);
- COMPILE (re_rhel,
- "Red Hat.*release (\\d+)\\.(\\d+)", 0);
- COMPILE (re_rhel_no_minor,
- "Red Hat.*release (\\d+)", 0);
- COMPILE (re_centos_old,
- "CentOS.*release (\\d+).*Update (\\d+)", 0);
- COMPILE (re_centos,
- "CentOS.*release (\\d+)\\.(\\d+)", 0);
- COMPILE (re_centos_no_minor,
- "CentOS.*release (\\d+)", 0);
- COMPILE (re_scientific_linux_old,
- "Scientific Linux.*release (\\d+).*Update (\\d+)", 0);
- COMPILE (re_scientific_linux,
- "Scientific Linux.*release (\\d+)\\.(\\d+)", 0);
- COMPILE (re_scientific_linux_no_minor,
- "Scientific Linux.*release (\\d+)", 0);
- COMPILE (re_oracle_linux_old,
- "Oracle Linux.*release (\\d+).*Update (\\d+)", 0);
- COMPILE (re_oracle_linux,
- "Oracle Linux.*release (\\d+)\\.(\\d+)", 0);
- COMPILE (re_oracle_linux_no_minor,
- "Oracle Linux.*release (\\d+)", 0);
- COMPILE (re_major_minor, "(\\d+)\\.(\\d+)", 0);
- COMPILE (re_xdev, "^/dev/(h|s|v|xv)d([a-z]+)(\\d*)$", 0);
- COMPILE (re_cciss, "^/dev/(cciss/c\\d+d\\d+)(?:p(\\d+))?$", 0);
- COMPILE (re_mdN, "^(/dev/md\\d+)$", 0);
- COMPILE (re_freebsd_mbr, "^/dev/(ada{0,1}|vtbd)(\\d+)s(\\d+)([a-z])$", 0);
- COMPILE (re_freebsd_gpt, "^/dev/(ada{0,1}|vtbd)(\\d+)p(\\d+)$", 0);
- COMPILE (re_diskbyid, "^/dev/disk/by-id/.*-part(\\d+)$", 0);
- COMPILE (re_netbsd, "^NetBSD (\\d+)\\.(\\d+)", 0);
- COMPILE (re_opensuse, "^(openSUSE|SuSE Linux|SUSE LINUX) ", 0);
- COMPILE (re_sles, "^SUSE (Linux|LINUX) Enterprise ", 0);
- COMPILE (re_nld, "^Novell Linux Desktop ", 0);
- COMPILE (re_opensuse_version, "^VERSION = (\\d+)\\.(\\d+)", 0);
- COMPILE (re_sles_version, "^VERSION = (\\d+)", 0);
- COMPILE (re_sles_patchlevel, "^PATCHLEVEL = (\\d+)", 0);
- COMPILE (re_minix, "^(\\d+)\\.(\\d+)(\\.(\\d+))?", 0);
- COMPILE (re_hurd_dev, "^/dev/(h)d(\\d+)s(\\d+)$", 0);
-}
-
-static void
-free_regexps (void)
-{
- pcre_free (re_fedora);
- pcre_free (re_rhel_old);
- pcre_free (re_rhel);
- pcre_free (re_rhel_no_minor);
- pcre_free (re_centos_old);
- pcre_free (re_centos);
- pcre_free (re_centos_no_minor);
- pcre_free (re_scientific_linux_old);
- pcre_free (re_scientific_linux);
- pcre_free (re_scientific_linux_no_minor);
- pcre_free (re_oracle_linux_old);
- pcre_free (re_oracle_linux);
- pcre_free (re_oracle_linux_no_minor);
- pcre_free (re_major_minor);
- pcre_free (re_xdev);
- pcre_free (re_cciss);
- pcre_free (re_mdN);
- pcre_free (re_freebsd_mbr);
- pcre_free (re_freebsd_gpt);
- pcre_free (re_diskbyid);
- pcre_free (re_netbsd);
- pcre_free (re_opensuse);
- pcre_free (re_sles);
- pcre_free (re_nld);
- pcre_free (re_opensuse_version);
- pcre_free (re_sles_version);
- pcre_free (re_sles_patchlevel);
- pcre_free (re_minix);
- pcre_free (re_hurd_dev);
-}
+COMPILE_REGEXP (re_fedora, "Fedora release (\\d+)", 0)
+COMPILE_REGEXP (re_rhel_old, "Red Hat.*release (\\d+).*Update (\\d+)", 0)
+COMPILE_REGEXP (re_rhel, "Red Hat.*release (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_rhel_no_minor, "Red Hat.*release (\\d+)", 0)
+COMPILE_REGEXP (re_centos_old, "CentOS.*release (\\d+).*Update (\\d+)", 0)
+COMPILE_REGEXP (re_centos, "CentOS.*release (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_centos_no_minor, "CentOS.*release (\\d+)", 0)
+COMPILE_REGEXP (re_scientific_linux_old,
+ "Scientific Linux.*release (\\d+).*Update (\\d+)", 0)
+COMPILE_REGEXP (re_scientific_linux,
+ "Scientific Linux.*release (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_scientific_linux_no_minor,
+ "Scientific Linux.*release (\\d+)", 0)
+ COMPILE_REGEXP (re_oracle_linux_old,
+ "Oracle Linux.*release (\\d+).*Update (\\d+)", 0)
+COMPILE_REGEXP (re_oracle_linux,
+ "Oracle Linux.*release (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_oracle_linux_no_minor, "Oracle Linux.*release (\\d+)", 0)
+COMPILE_REGEXP (re_major_minor, "(\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_xdev, "^/dev/(h|s|v|xv)d([a-z]+)(\\d*)$", 0)
+COMPILE_REGEXP (re_cciss, "^/dev/(cciss/c\\d+d\\d+)(?:p(\\d+))?$", 0)
+COMPILE_REGEXP (re_mdN, "^(/dev/md\\d+)$", 0)
+COMPILE_REGEXP (re_freebsd_mbr,
+ "^/dev/(ada{0,1}|vtbd)(\\d+)s(\\d+)([a-z])$", 0)
+COMPILE_REGEXP (re_freebsd_gpt, "^/dev/(ada{0,1}|vtbd)(\\d+)p(\\d+)$", 0)
+COMPILE_REGEXP (re_diskbyid, "^/dev/disk/by-id/.*-part(\\d+)$", 0)
+COMPILE_REGEXP (re_netbsd, "^NetBSD (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_opensuse, "^(openSUSE|SuSE Linux|SUSE LINUX) ", 0)
+COMPILE_REGEXP (re_sles, "^SUSE (Linux|LINUX) Enterprise ", 0)
+COMPILE_REGEXP (re_nld, "^Novell Linux Desktop ", 0)
+COMPILE_REGEXP (re_opensuse_version, "^VERSION = (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_sles_version, "^VERSION = (\\d+)", 0)
+COMPILE_REGEXP (re_sles_patchlevel, "^PATCHLEVEL = (\\d+)", 0)
+COMPILE_REGEXP (re_minix, "^(\\d+)\\.(\\d+)(\\.(\\d+))?", 0)
+COMPILE_REGEXP (re_hurd_dev, "^/dev/(h)d(\\d+)s(\\d+)$", 0)
static void check_architecture (guestfs_h *g, struct inspect_fs *fs);
static int check_hostname_unix (guestfs_h *g, struct inspect_fs *fs);
--
2.1.0
9 years, 12 months
[PATCH 1/1] inspect: Fix a bug in the *BSD root detection
by Nikos Skalkotos
The assumption that Linux will map the MBR partition to /dev/sda1
and the BSD 'a' partition to /dev/sda5 is not always correct.
Signed-off-by: Nikos Skalkotos <skalkoto(a)grnet.gr>
---
src/guestfs-internal.h | 1 +
src/inspect-fs.c | 55 +++++++++++++++++++++++++++++++++-----------------
src/inspect.c | 6 ++++++
3 files changed, 43 insertions(+), 19 deletions(-)
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index fd0c4a1..2460d25 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -746,6 +746,7 @@ extern int guestfs___is_file_nocase (guestfs_h *g, const char *);
extern int guestfs___is_dir_nocase (guestfs_h *g, const char *);
extern int guestfs___check_for_filesystem_on (guestfs_h *g,
const char *mountable);
+extern void guestfs___check_for_dublicated_bsd_root(guestfs_h *g);
extern int guestfs___parse_unsigned_int (guestfs_h *g, const char *str);
extern int guestfs___parse_unsigned_int_ignore_trailing (guestfs_h *g, const char *str);
extern int guestfs___parse_major_minor (guestfs_h *g, struct inspect_fs *fs);
diff --git a/src/inspect-fs.c b/src/inspect-fs.c
index 539d814..99a8658 100644
--- a/src/inspect-fs.c
+++ b/src/inspect-fs.c
@@ -47,7 +47,7 @@
* multiple threads call into the libguestfs API functions below
* simultaneously.
*/
-static pcre *re_first_partition;
+static pcre *re_primary_partition;
static pcre *re_major_minor;
static void compile_regexps (void) __attribute__((constructor));
@@ -68,14 +68,14 @@ compile_regexps (void)
} \
} while (0)
- COMPILE (re_first_partition, "^/dev/(?:h|s|v)d.1$", 0);
+ COMPILE (re_primary_partition, "^/dev/(?:h|s|v)d.[1234]$", 0);
COMPILE (re_major_minor, "(\\d+)\\.(\\d+)", 0);
}
static void
free_regexps (void)
{
- pcre_free (re_first_partition);
+ pcre_free (re_primary_partition);
pcre_free (re_major_minor);
}
@@ -84,6 +84,39 @@ static int check_filesystem (guestfs_h *g, const char *mountable,
int whole_device);
static int extend_fses (guestfs_h *g);
+/* On *BSD systems, sometimes /dev/sda[1234] is a shadow of the real root
+ * filesystem that is probably /dev/sda5
+ * (see: http://www.freebsd.org/doc/handbook/disk-organization.html)
+ */
+void
+guestfs___check_for_dublicated_bsd_root(guestfs_h *g)
+{
+ size_t i;
+ bool is_primary, is_bsd;
+ struct inspect_fs *fs, *bsd_primary = NULL;
+
+ for (i = 0; i < g->nr_fses; ++i) {
+ fs = &g->fses[i];
+
+ is_primary = match (g, fs->mountable, re_primary_partition);
+ is_bsd = ((fs->type == OS_TYPE_FREEBSD) || \
+ (fs->type == OS_TYPE_NETBSD) || \
+ (fs->type == OS_TYPE_OPENBSD));
+
+ if (fs->is_root && is_primary && is_bsd) {
+ bsd_primary = fs;
+ continue;
+ }
+
+ if (fs->is_root && bsd_primary && (bsd_primary->type == fs->type)) {
+ /* remove the is root flag from the bsd_primary */
+ bsd_primary->is_root = 0;
+ bsd_primary->format = OS_FORMAT_UNKNOWN;
+ return;
+ }
+ }
+}
+
/* Find out if 'device' contains a filesystem. If it does, add
* another entry in g->fses.
*/
@@ -207,14 +240,6 @@ check_filesystem (guestfs_h *g, const char *mountable,
is_dir_bin &&
guestfs_is_file (g, "/etc/freebsd-update.conf") > 0 &&
guestfs_is_file (g, "/etc/fstab") > 0) {
- /* Ignore /dev/sda1 which is a shadow of the real root filesystem
- * that is probably /dev/sda5 (see:
- * http://www.freebsd.org/doc/handbook/disk-organization.html)
- */
- if (m->im_type == MOUNTABLE_DEVICE &&
- match (g, m->im_device, re_first_partition))
- return 0;
-
fs->is_root = 1;
fs->format = OS_FORMAT_INSTALLED;
if (guestfs___check_freebsd_root (g, fs) == -1)
@@ -225,14 +250,6 @@ check_filesystem (guestfs_h *g, const char *mountable,
guestfs_is_file (g, "/netbsd") > 0 &&
guestfs_is_file (g, "/etc/fstab") > 0 &&
guestfs_is_file (g, "/etc/release") > 0) {
- /* Ignore /dev/sda1 which is a shadow of the real root filesystem
- * that is probably /dev/sda5 (see:
- * http://www.freebsd.org/doc/handbook/disk-organization.html)
- */
- if (m->im_type == MOUNTABLE_DEVICE &&
- match (g, m->im_device, re_first_partition))
- return 0;
-
fs->is_root = 1;
fs->format = OS_FORMAT_INSTALLED;
if (guestfs___check_netbsd_root (g, fs) == -1)
diff --git a/src/inspect.c b/src/inspect.c
index 9248b06..048b059 100644
--- a/src/inspect.c
+++ b/src/inspect.c
@@ -64,6 +64,12 @@ guestfs__inspect_os (guestfs_h *g)
}
}
+ /* Check if the same filesystem was listed twice as root in g->fses.
+ * This may happen for the *BSD root partition where an MBR partition
+ * is a shadow of the real root partition probably /dev/sda5
+ */
+ guestfs___check_for_dublicated_bsd_root(g);
+
/* At this point we have, in the handle, a list of all filesystems
* found and data about each one. Now we assemble the list of
* filesystems which are root devices and return that to the user.
--
2.1.3
9 years, 12 months
[PATCH 1/3] uuid: add support to change uuid of swap partition
by Hu Tao
Signed-off-by: Hu Tao <hutao(a)cn.fujitsu.com>
---
daemon/uuids.c | 19 +++++++++++++++++++
sysprep/sysprep_operation_fs_uuids.ml | 2 --
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/daemon/uuids.c b/daemon/uuids.c
index 672f3db..431d867 100644
--- a/daemon/uuids.c
+++ b/daemon/uuids.c
@@ -29,6 +29,7 @@
GUESTFSD_EXT_CMD(str_tune2fs, tune2fs);
GUESTFSD_EXT_CMD(str_xfs_admin, xfs_admin);
+GUESTFSD_EXT_CMD(str_swaplabel, swaplabel);
static int
e2uuid (const char *device, const char *uuid)
@@ -75,6 +76,21 @@ xfsuuid (const char *device, const char *uuid)
return 0;
}
+static int
+swapuuid (const char *device, const char *uuid)
+{
+ int r;
+ CLEANUP_FREE char *err = NULL;
+
+ r = command (NULL, &err, str_swaplabel, "-U", uuid, device, NULL);
+ if (r == -1) {
+ reply_with_error ("%s", err);
+ return -1;
+ }
+
+ return 0;
+}
+
int
do_set_uuid (const char *device, const char *uuid)
{
@@ -91,6 +107,9 @@ do_set_uuid (const char *device, const char *uuid)
else if (STREQ (vfs_type, "xfs"))
r = xfsuuid (device, uuid);
+ else if (STREQ (vfs_type, "swap"))
+ r = swapuuid (device, uuid);
+
else {
reply_with_error ("don't know how to set the UUID for '%s' filesystems",
vfs_type);
diff --git a/sysprep/sysprep_operation_fs_uuids.ml b/sysprep/sysprep_operation_fs_uuids.ml
index ccd8ef6..b67c131 100644
--- a/sysprep/sysprep_operation_fs_uuids.ml
+++ b/sysprep/sysprep_operation_fs_uuids.ml
@@ -29,8 +29,6 @@ let rec fs_uuids_perform ~verbose ~quiet g root side_effects =
let fses = g#list_filesystems () in
List.iter (function
| _, "unknown" -> ()
- | _, "swap" ->
- (* XXX Not implemented *) ()
| dev, typ ->
let new_uuid = Common_utils.uuidgen ~prog () in
try
--
1.9.3
9 years, 12 months
[PATCH 0/1] inspect: Fix a bug in the *BSD root detection
by Nikos Skalkotos
Hello,
I've been reading the *BSD detection code in check_filesystem() in
inspect-fs.c in order to write a patch for OpenBSD detection that is
missing. Both, in FreeBSD and in NetBSD you have this piece of code:
/* Ignore /dev/sda1 which is a shadow of the real root filesystem
* that is probably /dev/sda5 (see:
* http://www.freebsd.org/doc/handbook/disk-organization.html)
*/
if (m->im_type == MOUNTABLE_DEVICE &&
match (g, m->im_device, re_first_partition))
return 0;
This assumption is not always true. First of all, the MBR partition
that hosts the disklabel could be any of the primary partitions. Not
just the first one. The OpenBSD installer for example will by default
use the 4th partition. I'm pretty sure you can change this in FreeBSD
and NetBSD too.
The other thing is that /dev/sda5 will not always be there. The problem
is the weird way the kernel maps the disklabel partitions:
https://github.com/torvalds/linux/blob/master/block/partitions/msdos.c#L3...
The kernel will not map a disklabel subpartition if it has the same
boundaries with the parent (MBR) partition or if its boundaries exceed
the disklabel.
In the disklabel's partition table 'a' is always the root partition, 'b'
is the swap, in OpenBSD and FreeBSD 'c' is the full hard disk. In NetBSD
'c' is the disklabel partition itself and 'd' is the full hard disk.
Those partitions are invalid for the kernel. If I have a *BSD
installation with just root and swap, the kernel will show 3 partitions:
/dev/sda1 for the disklabel, /dev/sda5 for root and /dev/sda6 for swap,
but If I only have a root partition then this will likely have the same
boundaries with the MBR partition and the kernel will not map it again
to /dev/sda5. In this case inspect_os() will completely miss the OS.
I tried to fix this by removing the code above and checking again for
duplicated *BSD root partitions after all the file systems have been
scanned to unmark the is_root. It's not the prettiest thing in the
world but I couldn't think of something better.
Nikos
Nikos Skalkotos (1):
inspect: Fix a bug in the *BSD root detection
src/guestfs-internal.h | 1 +
src/inspect-fs.c | 55 +++++++++++++++++++++++++++++++++-----------------
src/inspect.c | 6 ++++++
3 files changed, 43 insertions(+), 19 deletions(-)
--
2.1.3
9 years, 12 months