public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] applied: [PATCH container 1/5] ct start: track lxc-start stderr and print in error case
@ 2020-09-09 19:12 Thomas Lamprecht
  2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 2/5] implement debug start Thomas Lamprecht
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Thomas Lamprecht @ 2020-09-09 19:12 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
 src/PVE/LXC.pm             | 15 +++++++++++++++
 src/pve-container@.service |  2 +-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index e13f7e6..f9aaaa9 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -2167,6 +2167,17 @@ sub userns_command {
     return [];
 }
 
+my sub print_ct_stderr_log {
+    my ($vmid) = @_;
+    my $log = eval { file_get_contents("/run/pve/ct-$vmid.stderr") };
+    return if !$log;
+
+    while ($log =~ /^\h*(lxc-start:?\s+$vmid:?\s*\S+\s*)?(.*?)\h*$/gm) {
+	my $line = $2;
+	print STDERR "$line\n";
+    }
+}
+
 my sub monitor_state_change($$) {
     my ($monitor_socket, $vmid) = @_;
     die "no monitor socket\n" if !defined($monitor_socket);
@@ -2201,6 +2212,7 @@ my sub monitor_start($$) {
     if (my $err = $@) {
 	warn "problem with monitor socket, but continuing anyway: $err\n";
     } elsif (!$success) {
+	print_ct_stderr_log($vmid);
 	die "startup for container '$vmid' failed\n";
     }
 }
@@ -2233,6 +2245,9 @@ sub vm_start {
     my $monitor_socket = eval { PVE::LXC::Monitor::get_monitor_socket() };
     warn $@ if $@;
 
+    unlink "/run/pve/ct-$vmid.stderr"; # systemd does not truncate log files
+
+    my $base_unit = $conf->{debug} ? 'pve-container-debug' : 'pve-container';
 
     my $cmd = ['systemctl', 'start', "pve-container\@$vmid"];
 
diff --git a/src/pve-container@.service b/src/pve-container@.service
index d9185bc..fdc373e 100644
--- a/src/pve-container@.service
+++ b/src/pve-container@.service
@@ -19,4 +19,4 @@ ExecStop=/usr/share/lxc/pve-container-stop-wrapper %i
 # Environment=CONSOLETYPE=serial
 # Prevent container init from putting all its output into the journal
 StandardOutput=null
-StandardError=null
+StandardError=file:/run/pve/ct-%i.stderr
-- 
2.20.1





^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] applied: [PATCH container 2/5] implement debug start
  2020-09-09 19:12 [pve-devel] applied: [PATCH container 1/5] ct start: track lxc-start stderr and print in error case Thomas Lamprecht
@ 2020-09-09 19:12 ` Thomas Lamprecht
  2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 3/5] protected_call: remove left-over rootdir/dev mkdir Thomas Lamprecht
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Thomas Lamprecht @ 2020-09-09 19:12 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
 src/Makefile                     |  6 ++++--
 src/PVE/API2/LXC/Status.pm       |  8 +++++++-
 src/PVE/LXC.pm                   | 10 +++++++---
 src/PVE/LXC/Config.pm            |  6 ++++++
 src/pve-container-debug@.service | 22 ++++++++++++++++++++++
 5 files changed, 46 insertions(+), 6 deletions(-)
 create mode 100644 src/pve-container-debug@.service

diff --git a/src/Makefile b/src/Makefile
index 7166708..450a8eb 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -38,8 +38,9 @@ check: test
 	make -C test
 
 .PHONY: install
-install: pct lxc-pve.conf lxc-pve-prestart-hook lxc-pve-autodev-hook lxc-pve-poststop-hook	    \
-	    lxcnetaddbr pct.1 pct.conf.5 pct.bash-completion pct.zsh-completion pve-userns.seccomp
+install: pct lxc-pve.conf pct.1 pct.conf.5 pct.bash-completion pct.zsh-completion \
+    pve-userns.seccomp pve-container@.service pve-container-debug@.service \
+    lxc-pve-prestart-hook lxc-pve-autodev-hook lxc-pve-poststop-hook lxcnetaddbr
 	PVE_GENERATING_DOCS=1 perl -I. -T -e "use PVE::CLI::pct; PVE::CLI::pct->verify_api();"
 	install -d ${SBINDIR}
 	install -m 0755 pct ${SBINDIR}
@@ -48,6 +49,7 @@ install: pct lxc-pve.conf lxc-pve-prestart-hook lxc-pve-autodev-hook lxc-pve-pos
 	install -m 0755 pve-container-stop-wrapper ${LXC_SCRIPT_DIR}
 	install -d -m0755 ${SERVICEDIR}
 	install -m0644 pve-container@.service ${SERVICEDIR}/
+	install -m0644 pve-container-debug@.service ${SERVICEDIR}/
 	install -m0644 'system-pve\x2dcontainer.slice' ${SERVICEDIR}/
 	install -d ${LXC_HOOK_DIR}
 	install -m 0755 lxc-pve-prestart-hook ${LXC_HOOK_DIR}
diff --git a/src/PVE/API2/LXC/Status.pm b/src/PVE/API2/LXC/Status.pm
index 89186ae..766c2ce 100644
--- a/src/PVE/API2/LXC/Status.pm
+++ b/src/PVE/API2/LXC/Status.pm
@@ -130,6 +130,12 @@ __PACKAGE__->register_method({
 	    node => get_standard_option('pve-node'),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_stopped }),
 	    skiplock => get_standard_option('skiplock'),
+	    debug => {
+		optional => 1,
+		type => 'boolean',
+		description => "If set, enables very verbose debug log-level on start.",
+		default => 0,
+	    },
 	},
     },
     returns => {
@@ -188,7 +194,7 @@ __PACKAGE__->register_method({
 		    });
 		}
 
-		PVE::LXC::vm_start($vmid, $conf, $skiplock);
+		PVE::LXC::vm_start($vmid, $conf, $skiplock, $param->{debug});
 	    };
 
 	    my $lockcmd = sub {
diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index f9aaaa9..b3e3581 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -2218,7 +2218,7 @@ my sub monitor_start($$) {
 }
 
 sub vm_start {
-    my ($vmid, $conf, $skiplock) = @_;
+    my ($vmid, $conf, $skiplock, $debug) = @_;
 
     # apply pending changes while starting
     if (scalar(keys %{$conf->{pending}})) {
@@ -2247,15 +2247,19 @@ sub vm_start {
 
     unlink "/run/pve/ct-$vmid.stderr"; # systemd does not truncate log files
 
-    my $base_unit = $conf->{debug} ? 'pve-container-debug' : 'pve-container';
+    my $is_debug = $debug || (!defined($debug) && $conf->{debug});
+    my $base_unit = $is_debug ? 'pve-container-debug' : 'pve-container';
 
-    my $cmd = ['systemctl', 'start', "pve-container\@$vmid"];
+    my $cmd = ['systemctl', 'start', "$base_unit\@$vmid"];
 
     PVE::GuestHelpers::exec_hookscript($conf, $vmid, 'pre-start', 1);
     eval {
 	PVE::Tools::run_command($cmd);
 
 	monitor_start($monitor_socket, $vmid) if defined($monitor_socket);
+
+	# if debug is requested, print the log it also when the start succeeded
+	print_ct_stderr_log($vmid) if $is_debug;
     };
     if (my $err = $@) {
 	unlink $skiplock_flag_fn;
diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
index 044e2e1..4cd669c 100644
--- a/src/PVE/LXC/Config.pm
+++ b/src/PVE/LXC/Config.pm
@@ -508,6 +508,12 @@ my $confdesc = {
 	description => 'Tags of the Container. This is only meta information.',
 	optional => 1,
     },
+    debug => {
+	optional => 1,
+	type => 'boolean',
+	description => "Try to be more verbose. For now this only enables debug log-level on start.",
+	default => 0,
+    },
 };
 
 my $valid_lxc_conf_keys = {
diff --git a/src/pve-container-debug@.service b/src/pve-container-debug@.service
new file mode 100644
index 0000000..7cfebaa
--- /dev/null
+++ b/src/pve-container-debug@.service
@@ -0,0 +1,22 @@
+# based on lxc@.service, but without an install section because
+# starting and stopping should be initiated by PVE code, not
+# systemd.
+[Unit]
+Description=PVE LXC Container: %i
+DefaultDependencies=No
+After=lxc.service
+Wants=lxc.service
+Documentation=man:lxc-start man:lxc man:pct
+
+[Service]
+Type=simple
+Delegate=yes
+KillMode=mixed
+TimeoutStopSec=120s
+ExecStart=/usr/bin/lxc-start -F -n %i -o /dev/stderr -l DEBUG
+ExecStop=/usr/share/lxc/pve-container-stop-wrapper %i
+# Environment=BOOTUP=serial
+# Environment=CONSOLETYPE=serial
+# Prevent container init from putting all its output into the journal
+StandardOutput=null
+StandardError=file:/run/pve/ct-%i.stderr
-- 
2.20.1





^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] applied: [PATCH container 3/5] protected_call: remove left-over rootdir/dev mkdir
  2020-09-09 19:12 [pve-devel] applied: [PATCH container 1/5] ct start: track lxc-start stderr and print in error case Thomas Lamprecht
  2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 2/5] implement debug start Thomas Lamprecht
@ 2020-09-09 19:12 ` Thomas Lamprecht
  2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 4/5] alpine: setup net: pass whole config to parent method Thomas Lamprecht
  2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 5/5] setup: heuristically warn if the FS hosting /etc is not mounted Thomas Lamprecht
  3 siblings, 0 replies; 5+ messages in thread
From: Thomas Lamprecht @ 2020-09-09 19:12 UTC (permalink / raw)
  To: pve-devel

commit 797e12e8a5df246d8afc53b045e632977cdf0088 got rid of our "just
bind-mount the root /dev to the CT temporarily for some stuff" for
good a while ago (2015), but creating the /dev directory in the CT
root was kept, from what I can tell, by mistake.

This can be a problem if, whyever, the CT rootfs is not mounted, as
we then break a future mount as we create this /dev directory inside
what would be the CTs rootfs mount point. It is then not empty
anymore and a normal mount cannot happen, failing with "directory is
not empty"

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
 src/PVE/LXC/Setup.pm | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/PVE/LXC/Setup.pm b/src/PVE/LXC/Setup.pm
index d424aaa..fb0be37 100644
--- a/src/PVE/LXC/Setup.pm
+++ b/src/PVE/LXC/Setup.pm
@@ -134,11 +134,6 @@ sub protected_call {
     # avoid recursion:
     return $sub->() if $self->{in_chroot};
 
-    my $rootdir = $self->{rootdir};
-    if (!-d "$rootdir/dev" && !mkdir("$rootdir/dev")) {
-	die "failed to create temporary /dev directory: $!\n";
-    }
-
     pipe(my $res_in, my $res_out) or die "pipe failed: $!\n";
 
     my $child = fork();
@@ -149,6 +144,7 @@ sub protected_call {
 	# avoid recursive forks
 	$self->{in_chroot} = 1;
 	eval {
+	    my $rootdir = $self->{rootdir};
 	    chroot($rootdir) or die "failed to change root to: $rootdir: $!\n";
 	    chdir('/') or die "failed to change to root directory\n";
 	    my $res = $sub->();
-- 
2.20.1





^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] applied: [PATCH container 4/5] alpine: setup net: pass whole config to parent method
  2020-09-09 19:12 [pve-devel] applied: [PATCH container 1/5] ct start: track lxc-start stderr and print in error case Thomas Lamprecht
  2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 2/5] implement debug start Thomas Lamprecht
  2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 3/5] protected_call: remove left-over rootdir/dev mkdir Thomas Lamprecht
@ 2020-09-09 19:12 ` Thomas Lamprecht
  2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 5/5] setup: heuristically warn if the FS hosting /etc is not mounted Thomas Lamprecht
  3 siblings, 0 replies; 5+ messages in thread
From: Thomas Lamprecht @ 2020-09-09 19:12 UTC (permalink / raw)
  To: pve-devel

We expected the whole $conf to be passed in a call to setup_network,
a bit ago it worked if their where only the netX keys present, for
some plugin that still is the case.
But, in the Debian version, reused by Alpine, we now check if the CT
distro version is recent enough to support (or need) the address in
CIDR format.
So, at least "ostype" needs to be passed to, else we get ugly
warnings in the syslog (or the recently added --debug log CLI switch)

Just pass the whole config, the setup_network method need to cope
with that anyway.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
 src/PVE/LXC/Setup/Alpine.pm | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/PVE/LXC/Setup/Alpine.pm b/src/PVE/LXC/Setup/Alpine.pm
index 75d6ebe..e486971 100644
--- a/src/PVE/LXC/Setup/Alpine.pm
+++ b/src/PVE/LXC/Setup/Alpine.pm
@@ -86,21 +86,24 @@ sub setup_network {
     # at least with the workaround the networking starts and if an ipv4 is
     # configured slaac for ipv6 works (unless accept_ra = 0 in the node)
 
-    my $netconf = {};
+    my $newconf = {};
     my $networks = {};
     foreach my $k (keys %$conf) {
+	my $value = $conf->{$k};
+	$newconf->{$k} = $value;
 	next if $k !~ m/^net(\d+)$/;
-	my $netstring = $conf->{$k};
+
+	my $netstring = $value;
 	# check for dhcp6:
 	my $d = PVE::LXC::Config->parse_lxc_network($netstring);
 	if (defined($d->{ip6}) && ($d->{ip6} eq 'dhcp' || $d->{ip6} eq 'auto')) {
 	    $d->{ip6} = 'manual';
 	    $netstring = PVE::LXC::Config->print_lxc_network($d);
 	}
-	$netconf->{$k} = $netstring;
+	$newconf->{$k} = $netstring;
     }
 
-    PVE::LXC::Setup::Debian::setup_network($self, $netconf);
+    PVE::LXC::Setup::Debian::setup_network($self, $newconf);
 }
 
 1;
-- 
2.20.1





^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] applied: [PATCH container 5/5] setup: heuristically warn if the FS hosting /etc is not mounted
  2020-09-09 19:12 [pve-devel] applied: [PATCH container 1/5] ct start: track lxc-start stderr and print in error case Thomas Lamprecht
                   ` (2 preceding siblings ...)
  2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 4/5] alpine: setup net: pass whole config to parent method Thomas Lamprecht
@ 2020-09-09 19:12 ` Thomas Lamprecht
  3 siblings, 0 replies; 5+ messages in thread
From: Thomas Lamprecht @ 2020-09-09 19:12 UTC (permalink / raw)
  To: pve-devel

Check for the existence of /etc, use -e as it could also be a symlink
(and it's just a heuristic). But only do so if the expected ostype
from the config does not match the detected one, this normally
indicates that we had a "reals" distro running but detected the
fallback "unmanaged". Only warn though, as a hint for the user.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
 src/PVE/LXC/Setup.pm | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/PVE/LXC/Setup.pm b/src/PVE/LXC/Setup.pm
index fb0be37..8b8fee9 100644
--- a/src/PVE/LXC/Setup.pm
+++ b/src/PVE/LXC/Setup.pm
@@ -96,8 +96,11 @@ sub new {
 	$type = &$autodetect_type($self, $rootdir, $os_release);
 	my $expected_type = $conf->{ostype} || $type;
 
-	warn "got unexpected ostype ($type != $expected_type)\n"
-	    if $type ne $expected_type;
+	if ($type ne $expected_type) {
+	    warn "WARNING: /etc not present in CT, is the rootfs mounted?\n"
+		if ! -e "$rootdir/etc";
+	    warn "got unexpected ostype ($type != $expected_type)\n"
+	}
     }
 
     if ($type eq 'unmanaged') {
-- 
2.20.1





^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-09-09 19:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-09 19:12 [pve-devel] applied: [PATCH container 1/5] ct start: track lxc-start stderr and print in error case Thomas Lamprecht
2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 2/5] implement debug start Thomas Lamprecht
2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 3/5] protected_call: remove left-over rootdir/dev mkdir Thomas Lamprecht
2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 4/5] alpine: setup net: pass whole config to parent method Thomas Lamprecht
2020-09-09 19:12 ` [pve-devel] applied: [PATCH container 5/5] setup: heuristically warn if the FS hosting /etc is not mounted Thomas Lamprecht

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal