daemon: Move all the kernel command line parsing to the init script.

Instead of parsing /proc/cmdline from the daemon, move all of that
parsing into the init script, and pass the argument via the daemon
command line.

For example, previously the daemon and init script both looked for
guestfs_network=1 in /proc/cmdline.  Now the init script still looks
for it, and if found it runs `guestfsd --network'.
This commit is contained in:
Richard W.M. Jones
2015-06-25 15:08:52 +01:00
parent 64ff631127
commit 8cb1a35d75
3 changed files with 60 additions and 90 deletions

View File

@@ -88,11 +88,26 @@ for f in /sys/block/{h,s,ub,v}d*/queue/scheduler; do echo noop > $f; done
# Update the system clock.
hwclock -u -s
# Parse the kernel command line.
if grep -sq guestfs_verbose=1 /proc/cmdline; then
guestfs_verbose=1
fi
if grep -sq guestfs_network=1 /proc/cmdline; then
guestfs_network=1
fi
if grep -sq guestfs_rescue=1 /proc/cmdline; then
guestfs_rescue=1
fi
if grep -sq guestfs_noreboot=1 /proc/cmdline; then
guestfs_noreboot=1
fi
eval `grep -Eo 'guestfs_channel=[^[:space:]]+' /proc/cmdline`
# Set up the network.
ip addr add 127.0.0.1/8 brd + dev lo scope host
ip link set dev lo up
if grep -sq guestfs_network=1 /proc/cmdline; then
if test "$guestfs_network" = 1; then
if dhclient --version >/dev/null 2>&1; then
dhclient
else
@@ -113,7 +128,7 @@ lvm vgchange -aay --sysinit
ldmtool create all
# These are useful when debugging.
if grep -sq guestfs_verbose=1 /proc/cmdline; then
if test "$guestfs_verbose" = 1; then
uname -a
ls -lR /dev
cat /proc/mounts
@@ -132,7 +147,7 @@ if grep -sq guestfs_verbose=1 /proc/cmdline; then
echo -n "uptime: "; cat /proc/uptime
fi
if ! grep -sq guestfs_rescue=1 /proc/cmdline; then
if ! test "$guestfs_rescue" = 1; then
# Run the daemon.
# Run the daemon under valgrind if ./configure --enable-valgrind-daemon
@@ -145,7 +160,19 @@ if ! grep -sq guestfs_rescue=1 /proc/cmdline; then
fi
# Run guestfsd, under valgrind if asked.
$vg guestfsd
cmd="$vg guestfsd"
if test "x$guestfs_channel" != "x"; then
cmd="$cmd --channel $guestfs_channel"
fi
if test "$guestfs_verbose" = 1; then
cmd="$cmd --verbose"
fi
if test "$guestfs_network" = 1; then
cmd="$cmd --network"
fi
echo $cmd
$cmd
if [ $? -eq 119 ]; then
echo "DAEMON VALGRIND FAILED"
# Sleep so valgrind messages are seen by the host. Note this
@@ -181,7 +208,7 @@ fi
sync
if ! grep -sq guestfs_noreboot=1 /proc/cmdline; then
if ! test "$guestfs_noreboot" = 1; then
# qemu has the -no-reboot flag, so issuing a reboot here actually
# causes qemu to exit gracefully.
reboot -f

View File

@@ -58,8 +58,6 @@
GUESTFSD_EXT_CMD(str_udevadm, udevadm);
static char *read_cmdline (void);
#ifndef MAX
# define MAX(a,b) ((a)>(b)?(a):(b))
#endif
@@ -139,16 +137,18 @@ usage (void)
int
main (int argc, char *argv[])
{
static const char *options = "lrtv?";
static const char *options = "c:lnrtv?";
static const struct option long_options[] = {
{ "help", 0, 0, '?' },
{ "channel", 1, 0, 'c' },
{ "listen", 0, 0, 'l' },
{ "network", 0, 0, 'n' },
{ "test", 0, 0, 't' },
{ "verbose", 0, 0, 'v' },
{ 0, 0, 0, 0 }
};
int c;
char *cmdline;
const char *channel = NULL;
int listen_mode = 0;
ignore_value (chdir ("/"));
@@ -188,10 +188,18 @@ main (int argc, char *argv[])
if (c == -1) break;
switch (c) {
case 'c':
channel = optarg;
break;
case 'l':
listen_mode = 1;
break;
case 'n':
enable_network = 1;
break;
/* The -r flag is used when running standalone. It changes
* several aspects of the daemon.
*/
@@ -225,23 +233,6 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
cmdline = read_cmdline ();
/* Set the verbose flag. */
verbose = verbose ||
(cmdline && strstr (cmdline, "guestfs_verbose=1") != NULL);
if (verbose)
printf ("verbose daemon enabled\n");
if (verbose) {
if (cmdline)
printf ("linux command line: %s\n", cmdline);
else
printf ("could not read linux command line\n");
}
enable_network = cmdline && strstr (cmdline, "guestfs_network=1") != NULL;
#ifndef WIN32
/* Make sure SIGPIPE doesn't kill us. */
struct sigaction sa;
@@ -283,17 +274,8 @@ main (int argc, char *argv[])
copy_lvm ();
/* Connect to virtio-serial channel. */
char *channel, *p;
if (cmdline && (p = strstr (cmdline, "guestfs_channel=")) != NULL) {
p += 16;
channel = strndup (p, strcspn (p, " \n"));
}
else
channel = strdup (VIRTIO_SERIAL_CHANNEL);
if (!channel) {
perror ("strdup");
exit (EXIT_FAILURE);
}
if (!channel)
channel = VIRTIO_SERIAL_CHANNEL;
if (verbose)
printf ("trying to open virtio-serial channel '%s'\n", channel);
@@ -347,10 +329,6 @@ main (int argc, char *argv[])
if (STRPREFIX (channel, "/dev/ttyS"))
makeraw (channel, sock);
/* cmdline, channel not used after this point */
free (cmdline);
free (channel);
/* Wait for udev devices to be created. If you start libguestfs,
* especially with disks that contain complex (eg. mdadm) data
* already, then it is possible for the 'mdadm' and LVM commands
@@ -384,55 +362,6 @@ main (int argc, char *argv[])
exit (EXIT_SUCCESS);
}
/* Read /proc/cmdline. */
static char *
read_cmdline (void)
{
int fd = open ("/proc/cmdline", O_RDONLY|O_CLOEXEC);
if (fd == -1) {
perror ("/proc/cmdline");
return NULL;
}
size_t len = 0;
ssize_t n;
char buf[256];
char *r = NULL;
for (;;) {
n = read (fd, buf, sizeof buf);
if (n == -1) {
perror ("read");
free (r);
close (fd);
return NULL;
}
if (n == 0)
break;
char *newr = realloc (r, len + n + 1); /* + 1 is for terminating NUL */
if (newr == NULL) {
perror ("realloc");
free (r);
close (fd);
return NULL;
}
r = newr;
memcpy (&r[len], buf, n);
len += n;
}
if (r)
r[len] = '\0';
if (close (fd) == -1) {
perror ("close");
free (r);
return NULL;
}
return r;
}
/* Try to make the socket raw, but don't fail if it's not possible. */
static void
makeraw (const char *channel, int fd)

View File

@@ -50,6 +50,14 @@ removed.
Display brief help.
=item B<-c> CHANNEL
=item B<--channel> CHANNEL
Pass the name of the virtio-serial channel, serial port, etc. over
which guestfsd will communicate with the library. If this parameter
is not given, then an internal default port is used.
=item B<-l>
=item B<--listen>
@@ -59,6 +67,12 @@ already exists, create the channel as a Unix domain socket, listen on
it, and accept a single connection. This is mainly used for testing
the daemon.
=item B<-n>
=item B<--network>
Enable network features in the daemon.
=item B<-r>
Set the root filesystem to be F</> (instead of the default which is