mirror of
https://github.com/ostreedev/ostree.git
synced 2025-03-23 10:50:31 +03:00
Switch to using a systemd generator for /var
If one wants to set up a mount for `/var` in `/etc/fstab`, it won't be mounted since `ostree-prepare-root` set up a bind mount for `/var` to `/sysroot/ostree/$stateroot/var`, and systemd will take the already extant mount over what's in `/etc/fstab`. There are a few options to fix this, but what I settled on is parsing `/etc/fstab` in a generator (exactly like `systemd-fstab-generator` does), except here we look for an explicit mount for `/var`, and if one *isn't* found, synthesize the default ostree mount to the stateroot. Another nice property is that if an admin creates a `var.mount` unit in `/etc` for example, that will also override our mount. Note that today ostree doesn't hard depend on systemd, so this behavior only kicks in if we're built with systemd *and* libmount support (for parsing `/etc/fstab`). I didn't really test that case though. Initially I started writing this as a "pure libc" program, but at one point decided to use `libostree.so` to find the booted deployment. That didn't work out because `/boot` wasn't necessarily mounted and hence we couldn't find the bootloader config. A leftover artifact from this is that the generator code calls into libostree via the "cmd private" infrastructure. But it's an easy way to share code, and doesn't hurt. Closes: #859 Approved by: jlebon
This commit is contained in:
parent
d815ba2a81
commit
30705889cb
@ -115,6 +115,7 @@ libostree_1_la_SOURCES = \
|
||||
src/libostree/ostree-sysroot-cleanup.c \
|
||||
src/libostree/ostree-sysroot-deploy.c \
|
||||
src/libostree/ostree-sysroot-upgrader.c \
|
||||
src/libostree/ostree-impl-system-generator.c \
|
||||
src/libostree/ostree-bootconfig-parser.c \
|
||||
src/libostree/ostree-deployment.c \
|
||||
src/libostree/ostree-bootloader.h \
|
||||
|
@ -27,6 +27,7 @@ ostree_prepare_root_SOURCES = \
|
||||
src/switchroot/ostree-mount-util.h \
|
||||
src/switchroot/ostree-prepare-root.c \
|
||||
$(NULL)
|
||||
ostree_prepare_root_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
|
||||
if BUILDOPT_USE_STATIC_COMPILER
|
||||
# ostree-prepare-root can be used as init in a system without a populated /lib.
|
||||
@ -45,7 +46,6 @@ ostree-prepare-root : $(ostree_prepare_root_SOURCES)
|
||||
$(STATIC_COMPILER) -o $@ -static $(ostree_prepare_root_SOURCES) $(AM_CPPFLAGS) $(AM_CFLAGS) $(DEFAULT_INCLUDES)
|
||||
else
|
||||
ostree_boot_PROGRAMS += ostree-prepare-root
|
||||
|
||||
ostree_prepare_root_CFLAGS = $(AM_CFLAGS) -Isrc/switchroot
|
||||
endif
|
||||
|
||||
@ -53,4 +53,19 @@ ostree_remount_SOURCES = \
|
||||
src/switchroot/ostree-mount-util.h \
|
||||
src/switchroot/ostree-remount.c \
|
||||
$(NULL)
|
||||
ostree_remount_CFLAGS = $(AM_CFLAGS) -Isrc/switchroot
|
||||
ostree_remount_CPPFLAGS = $(AM_CPPFLAGS) -Isrc/switchroot
|
||||
|
||||
# This is the "new mode" of using a generator for /var; see
|
||||
# https://github.com/ostreedev/ostree/issues/855
|
||||
if BUILDOPT_SYSTEMD_AND_LIBMOUNT
|
||||
ostree_prepare_root_CPPFLAGS += -DHAVE_SYSTEMD_AND_LIBMOUNT=1
|
||||
ostree_remount_CPPFLAGS += -DHAVE_SYSTEMD_AND_LIBMOUNT=1
|
||||
|
||||
systemdsystemgenerator_PROGRAMS = ostree-system-generator
|
||||
GITIGNOREFILES += $(systemdsystemgenerator_PROGRAMS)
|
||||
ostree_system_generator_SOURCES = src/switchroot/ostree-mount-util.h \
|
||||
src/switchroot/ostree-system-generator.c
|
||||
ostree_system_generator_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libostree
|
||||
ostree_system_generator_CFLAGS = $(AM_CFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS)
|
||||
ostree_system_generator_LDADD = $(AM_LDFLAGS) libglnx.la libostree-1.la $(OT_INTERNAL_GIO_UNIX_LIBS)
|
||||
endif
|
||||
|
11
configure.ac
11
configure.ac
@ -389,8 +389,19 @@ AS_IF([test "x$have_libsystemd" = "xyes"], [
|
||||
AS_IF([test "x$with_systemdsystemunitdir" != "xno"], [
|
||||
AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
|
||||
])
|
||||
AC_ARG_WITH([systemdsystemgeneratordir],
|
||||
AS_HELP_STRING([--with-systemdsystemgeneratordir=DIR], [Directory for systemd generators]),
|
||||
[],
|
||||
[with_systemdsystemgeneratordir=$($PKG_CONFIG --variable=systemdsystemgeneratordir systemd)])
|
||||
AS_IF([test "x$with_systemdsystemgeneratordir" != "xno"], [
|
||||
AC_SUBST([systemdsystemgeneratordir], [$with_systemdsystemgeneratordir])
|
||||
])
|
||||
])
|
||||
AM_CONDITIONAL(BUILDOPT_SYSTEMD, test x$with_systemd = xyes)
|
||||
dnl If we have both, we use the "new /var" model with ostree-system-generator
|
||||
AM_CONDITIONAL(BUILDOPT_SYSTEMD_AND_LIBMOUNT,[test x$with_systemd = xyes && test x$with_libmount = xyes])
|
||||
AM_COND_IF(BUILDOPT_SYSTEMD_AND_LIBMOUNT,
|
||||
AC_DEFINE([BUILDOPT_LIBSYSTEMD_AND_LIBMOUNT], 1, [Define if systemd and libmount]))
|
||||
|
||||
AC_ARG_WITH(builtin-grub2-mkconfig,
|
||||
AS_HELP_STRING([--with-builtin-grub2-mkconfig],
|
||||
|
@ -45,6 +45,7 @@ const OstreeCmdPrivateVTable *
|
||||
ostree_cmd__private__ (void)
|
||||
{
|
||||
static OstreeCmdPrivateVTable table = {
|
||||
_ostree_impl_system_generator,
|
||||
impl_ostree_generate_grub2_config,
|
||||
_ostree_repo_static_delta_dump,
|
||||
_ostree_repo_static_delta_query_exists,
|
||||
|
@ -24,7 +24,10 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean _ostree_impl_system_generator (const char *ostree_cmdline, const char *normal_dir, const char *early_dir, const char *late_dir, GError **error);
|
||||
|
||||
typedef struct {
|
||||
gboolean (* ostree_system_generator) (const char *ostree_cmdline, const char *normal_dir, const char *early_dir, const char *late_dir, GError **error);
|
||||
gboolean (* ostree_generate_grub2_config) (OstreeSysroot *sysroot, int bootversion, int target_fd, GCancellable *cancellable, GError **error);
|
||||
gboolean (* ostree_static_delta_dump) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error);
|
||||
gboolean (* ostree_static_delta_query_exists) (OstreeRepo *repo, const char *delta_id, gboolean *out_exists, GCancellable *cancellable, GError **error);
|
||||
|
219
src/libostree/ostree-impl-system-generator.c
Normal file
219
src/libostree/ostree-impl-system-generator.c
Normal file
@ -0,0 +1,219 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2017 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-unix.h>
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_LIBMOUNT
|
||||
#include <libmount.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#include "otutil.h"
|
||||
|
||||
#include "ostree.h"
|
||||
#include "ostree-core-private.h"
|
||||
#include "ostree-cmdprivate.h"
|
||||
|
||||
#ifdef HAVE_LIBMOUNT
|
||||
typedef FILE OtLibMountFile;
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtLibMountFile, endmntent);
|
||||
|
||||
/* Taken from systemd path-util.c */
|
||||
static bool
|
||||
is_path (const char *p)
|
||||
{
|
||||
return !!strchr (p, '/');
|
||||
}
|
||||
|
||||
/* Taken from systemd path-util.c */
|
||||
static char*
|
||||
path_kill_slashes (char *path)
|
||||
{
|
||||
char *f, *t;
|
||||
bool slash = false;
|
||||
|
||||
/* Removes redundant inner and trailing slashes. Modifies the
|
||||
* passed string in-place.
|
||||
*
|
||||
* For example: ///foo///bar/ becomes /foo/bar
|
||||
*/
|
||||
|
||||
for (f = path, t = path; *f; f++)
|
||||
{
|
||||
if (*f == '/')
|
||||
{
|
||||
slash = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (slash)
|
||||
{
|
||||
slash = false;
|
||||
*(t++) = '/';
|
||||
}
|
||||
|
||||
*(t++) = *f;
|
||||
}
|
||||
|
||||
/* Special rule, if we are talking of the root directory, a
|
||||
trailing slash is good */
|
||||
|
||||
if (t == path && slash)
|
||||
*(t++) = '/';
|
||||
|
||||
*t = 0;
|
||||
return path;
|
||||
}
|
||||
|
||||
/* Written by ostree-sysroot-deploy.c. We parse out the stateroot here since we
|
||||
* need to know it to mount /var. Unfortunately we can't easily use the
|
||||
* libostree API to find the booted deployment since /boot might not have been
|
||||
* mounted yet.
|
||||
*/
|
||||
static char *
|
||||
stateroot_from_ostree_cmdline (const char *ostree_cmdline,
|
||||
GError **error)
|
||||
{
|
||||
static GRegex *regex;
|
||||
static gsize regex_initialized;
|
||||
if (g_once_init_enter (®ex_initialized))
|
||||
{
|
||||
regex = g_regex_new ("^/ostree/boot.[01]/([^/]+)/", 0, 0, NULL);
|
||||
g_assert (regex);
|
||||
g_once_init_leave (®ex_initialized, 1);
|
||||
}
|
||||
|
||||
g_autoptr(GMatchInfo) match = NULL;
|
||||
if (!g_regex_match (regex, ostree_cmdline, 0, &match))
|
||||
return glnx_null_throw (error, "Failed to parse %s", ostree_cmdline);
|
||||
|
||||
return g_match_info_fetch (match, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Implementation of ostree-system-generator */
|
||||
gboolean
|
||||
_ostree_impl_system_generator (const char *ostree_cmdline,
|
||||
const char *normal_dir,
|
||||
const char *early_dir,
|
||||
const char *late_dir,
|
||||
GError **error)
|
||||
{
|
||||
#ifdef HAVE_LIBMOUNT
|
||||
/* Not currently cancellable, but define a var in case we care later */
|
||||
GCancellable *cancellable = NULL;
|
||||
/* Some path constants to avoid typos */
|
||||
static const char fstab_path[] = "/etc/fstab";
|
||||
static const char var_path[] = "/var";
|
||||
|
||||
/* ostree-prepare-root was patched to write the stateroot to this file */
|
||||
g_autofree char *stateroot = stateroot_from_ostree_cmdline (ostree_cmdline, error);
|
||||
if (!stateroot)
|
||||
return FALSE;
|
||||
|
||||
/* Load /etc/fstab if it exists, and look for a /var mount */
|
||||
g_autoptr(OtLibMountFile) fstab = setmntent (fstab_path, "re");
|
||||
gboolean found_var_mnt = FALSE;
|
||||
if (!fstab)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
return glnx_throw_errno_prefix (error, "Reading %s", fstab_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Parse it */
|
||||
struct mntent *me;
|
||||
while ((me = getmntent (fstab)))
|
||||
{
|
||||
g_autofree char *where = g_strdup (me->mnt_dir);
|
||||
if (is_path (where))
|
||||
path_kill_slashes (where);
|
||||
|
||||
/* We're only looking for /var here */
|
||||
if (strcmp (where, var_path) != 0)
|
||||
continue;
|
||||
|
||||
found_var_mnt = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we found /var, we're done */
|
||||
if (found_var_mnt)
|
||||
return TRUE;
|
||||
|
||||
/* Prepare to write to the output unit dir; we use the "normal" dir
|
||||
* that overrides /usr, but not /etc.
|
||||
*/
|
||||
glnx_fd_close int normal_dir_dfd = -1;
|
||||
if (!glnx_opendirat (AT_FDCWD, normal_dir, TRUE, &normal_dir_dfd, error))
|
||||
return FALSE;
|
||||
|
||||
/* Generate our bind mount unit */
|
||||
const char *stateroot_var_path = glnx_strjoina ("/sysroot/ostree/deploy/", stateroot, "/var");
|
||||
|
||||
glnx_fd_close int tmpfd = -1;
|
||||
g_autofree char *tmppath = NULL;
|
||||
if (!glnx_open_tmpfile_linkable_at (normal_dir_dfd, ".", O_WRONLY,
|
||||
&tmpfd, &tmppath, error))
|
||||
return FALSE;
|
||||
g_autoptr(GOutputStream) outstream = g_unix_output_stream_new (tmpfd, FALSE);
|
||||
gsize bytes_written;
|
||||
/* This code is inspired by systemd's fstab-generator.c.
|
||||
*
|
||||
* Note that our unit doesn't run if systemd.volatile is enabled;
|
||||
* see https://github.com/ostreedev/ostree/pull/856
|
||||
*/
|
||||
if (!g_output_stream_printf (outstream, &bytes_written, cancellable, error,
|
||||
"##\n# Automatically generated by ostree-system-generator\n##\n\n"
|
||||
"[Unit]\n"
|
||||
"Documentation=man:ostree(1)\n"
|
||||
"ConditionKernelCommandLine=!systemd.volatile\n"
|
||||
/* We need /sysroot mounted writable first */
|
||||
"After=ostree-remount.service\n"
|
||||
"Before=local-fs.target\n"
|
||||
"\n"
|
||||
"[Mount]\n"
|
||||
"Where=%s\n"
|
||||
"What=%s\n"
|
||||
"Options=bind\n",
|
||||
var_path,
|
||||
stateroot_var_path))
|
||||
return FALSE;
|
||||
if (!g_output_stream_flush (outstream, cancellable, error))
|
||||
return FALSE;
|
||||
g_clear_object (&outstream);
|
||||
/* It should be readable */
|
||||
if (fchmod (tmpfd, 0644) < 0)
|
||||
return glnx_throw_errno_prefix (error, "fchmod");
|
||||
/* Error out if somehow it already exists, that'll help us debug conflicts */
|
||||
if (!glnx_link_tmpfile_at (normal_dir_dfd, GLNX_LINK_TMPFILE_NOREPLACE,
|
||||
tmpfd, tmppath, normal_dir_dfd,
|
||||
"var.mount", error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
return glnx_throw (error, "Not implemented");
|
||||
#endif
|
||||
}
|
@ -1379,6 +1379,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
|
||||
|
||||
val = ostree_bootconfig_parser_get (bootconfig, "options");
|
||||
|
||||
/* Note this is parsed in ostree-impl-system-generator.c */
|
||||
g_autofree char *ostree_kernel_arg = g_strdup_printf ("ostree=/ostree/boot.%d/%s/%s/%d",
|
||||
new_bootversion, osname, bootcsum,
|
||||
ostree_deployment_get_bootserial (deployment));
|
||||
|
@ -25,6 +25,10 @@
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
static inline int
|
||||
path_is_on_readonly_fs (char *path)
|
||||
@ -37,4 +41,66 @@ path_is_on_readonly_fs (char *path)
|
||||
return (stvfsbuf.f_flag & ST_RDONLY) != 0;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
read_proc_cmdline (void)
|
||||
{
|
||||
FILE *f = fopen("/proc/cmdline", "r");
|
||||
char *cmdline = NULL;
|
||||
size_t len;
|
||||
|
||||
if (!f)
|
||||
goto out;
|
||||
|
||||
/* Note that /proc/cmdline will not end in a newline, so getline
|
||||
* will fail unelss we provide a length.
|
||||
*/
|
||||
if (getline (&cmdline, &len, f) < 0)
|
||||
goto out;
|
||||
/* ... but the length will be the size of the malloc buffer, not
|
||||
* strlen(). Fix that.
|
||||
*/
|
||||
len = strlen (cmdline);
|
||||
|
||||
if (cmdline[len-1] == '\n')
|
||||
cmdline[len-1] = '\0';
|
||||
out:
|
||||
if (f)
|
||||
fclose (f);
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
read_proc_cmdline_ostree (void)
|
||||
{
|
||||
char *cmdline = NULL;
|
||||
const char *iter;
|
||||
char *ret = NULL;
|
||||
|
||||
cmdline = read_proc_cmdline ();
|
||||
if (!cmdline)
|
||||
err (EXIT_FAILURE, "failed to read /proc/cmdline");
|
||||
|
||||
iter = cmdline;
|
||||
while (iter != NULL)
|
||||
{
|
||||
const char *next = strchr (iter, ' ');
|
||||
const char *next_nonspc = next;
|
||||
while (next_nonspc && *next_nonspc == ' ')
|
||||
next_nonspc += 1;
|
||||
if (strncmp (iter, "ostree=", strlen ("ostree=")) == 0)
|
||||
{
|
||||
const char *start = iter + strlen ("ostree=");
|
||||
if (next)
|
||||
ret = strndup (start, next - start);
|
||||
else
|
||||
ret = strdup (start);
|
||||
break;
|
||||
}
|
||||
iter = next_nonspc;
|
||||
}
|
||||
|
||||
free (cmdline);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __OSTREE_MOUNT_UTIL_H_ */
|
||||
|
@ -46,68 +46,6 @@
|
||||
|
||||
#include "ostree-mount-util.h"
|
||||
|
||||
static char *
|
||||
read_proc_cmdline (void)
|
||||
{
|
||||
FILE *f = fopen("/proc/cmdline", "r");
|
||||
char *cmdline = NULL;
|
||||
size_t len;
|
||||
|
||||
if (!f)
|
||||
goto out;
|
||||
|
||||
/* Note that /proc/cmdline will not end in a newline, so getline
|
||||
* will fail unelss we provide a length.
|
||||
*/
|
||||
if (getline (&cmdline, &len, f) < 0)
|
||||
goto out;
|
||||
/* ... but the length will be the size of the malloc buffer, not
|
||||
* strlen(). Fix that.
|
||||
*/
|
||||
len = strlen (cmdline);
|
||||
|
||||
if (cmdline[len-1] == '\n')
|
||||
cmdline[len-1] = '\0';
|
||||
out:
|
||||
if (f)
|
||||
fclose (f);
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
static char *
|
||||
parse_ostree_cmdline (void)
|
||||
{
|
||||
char *cmdline = NULL;
|
||||
const char *iter;
|
||||
char *ret = NULL;
|
||||
|
||||
cmdline = read_proc_cmdline ();
|
||||
if (!cmdline)
|
||||
err (EXIT_FAILURE, "failed to read /proc/cmdline");
|
||||
|
||||
iter = cmdline;
|
||||
while (iter != NULL)
|
||||
{
|
||||
const char *next = strchr (iter, ' ');
|
||||
const char *next_nonspc = next;
|
||||
while (next_nonspc && *next_nonspc == ' ')
|
||||
next_nonspc += 1;
|
||||
if (strncmp (iter, "ostree=", strlen ("ostree=")) == 0)
|
||||
{
|
||||
const char *start = iter + strlen ("ostree=");
|
||||
if (next)
|
||||
ret = strndup (start, next - start);
|
||||
else
|
||||
ret = strdup (start);
|
||||
break;
|
||||
}
|
||||
iter = next_nonspc;
|
||||
}
|
||||
|
||||
free (cmdline);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This is an API for other projects to determine whether or not the
|
||||
* currently running system is ostree-controlled.
|
||||
*/
|
||||
@ -132,7 +70,7 @@ resolve_deploy_path (const char * root_mountpoint)
|
||||
struct stat stbuf;
|
||||
char *ostree_target, *deploy_path;
|
||||
|
||||
ostree_target = parse_ostree_cmdline ();
|
||||
ostree_target = read_proc_cmdline_ostree ();
|
||||
if (!ostree_target)
|
||||
errx (EXIT_FAILURE, "No OSTree target; expected ostree=/ostree/boot.N/...");
|
||||
|
||||
@ -211,9 +149,12 @@ main(int argc, char *argv[])
|
||||
if (chdir (deploy_path) < 0)
|
||||
err (EXIT_FAILURE, "failed to chdir to deploy_path");
|
||||
|
||||
/* In the systemd case, this is handled by ostree-system-generator */
|
||||
#ifndef HAVE_SYSTEMD_AND_LIBMOUNT
|
||||
/* Link to the deployment's /var */
|
||||
if (mount ("../../var", "var", NULL, MS_MGC_VAL|MS_BIND, NULL) < 0)
|
||||
err (EXIT_FAILURE, "failed to bind mount ../../var to var");
|
||||
#endif
|
||||
|
||||
/* If /boot is on the same partition, use a bind mount to make it visible
|
||||
* at /boot inside the deployment. */
|
||||
|
67
src/switchroot/ostree-system-generator.c
Normal file
67
src/switchroot/ostree-system-generator.c
Normal file
@ -0,0 +1,67 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2017 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ostree-cmdprivate.h"
|
||||
#include "ostree-mount-util.h"
|
||||
|
||||
static const char *arg_dest = "/tmp";
|
||||
static const char *arg_dest_late = "/tmp";
|
||||
|
||||
/* This program is a simple stub that calls the implementation that
|
||||
* lives inside libostree.
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
/* Important: if this isn't an ostree-booted system, do nothing; people could
|
||||
* have the package installed as a dependency for flatpak or whatever.
|
||||
*/
|
||||
{ struct stat stbuf;
|
||||
if (fstatat (AT_FDCWD, "/run/ostree-booted", &stbuf, 0) < 0)
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (argc > 1 && argc != 4)
|
||||
errx (EXIT_FAILURE, "This program takes three or no arguments");
|
||||
|
||||
if (argc > 1)
|
||||
arg_dest = argv[1];
|
||||
if (argc > 3)
|
||||
arg_dest_late = argv[3];
|
||||
|
||||
char *ostree_cmdline = read_proc_cmdline_ostree ();
|
||||
if (!ostree_cmdline)
|
||||
errx (EXIT_FAILURE, "Failed to find ostree= kernel argument");
|
||||
|
||||
{ g_autoptr(GError) local_error = NULL;
|
||||
if (!ostree_cmd__private__()->ostree_system_generator (ostree_cmdline, arg_dest, NULL, arg_dest_late, &local_error))
|
||||
errx (EXIT_FAILURE, "%s", local_error->message);
|
||||
}
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user