New upstream version 2017.6
This commit is contained in:
commit
e3060b1b87
168 files changed
+5181
-3686
No files matched your search
@@ -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_ */
|
||||
@@ -1,13 +1,13 @@
|
||||
/* -*- c-file-style: "gnu" -*-
|
||||
* Switch to new root directory and start init.
|
||||
*
|
||||
*
|
||||
* Copyright 2011,2012,2013 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* Based on code from util-linux/sys-utils/switch_root.c,
|
||||
* Based on code from util-linux/sys-utils/switch_root.c,
|
||||
* Copyright 2002-2009 Red Hat, Inc. All rights reserved.
|
||||
* Authors:
|
||||
* Peter Jones <pjones@redhat.com>
|
||||
* Jeremy Katz <katzj@redhat.com>
|
||||
* Peter Jones <pjones@redhat.com>
|
||||
* Jeremy Katz <katzj@redhat.com>
|
||||
*
|
||||
* Relicensed with permission to LGPLv2+.
|
||||
*
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -115,8 +53,8 @@ static void
|
||||
touch_run_ostree (void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open ("/run/ostree-booted", O_CREAT | O_WRONLY | O_NOCTTY, 0640);
|
||||
|
||||
fd = open ("/run/ostree-booted", O_CREAT | O_WRONLY | O_NOCTTY | O_CLOEXEC, 0640);
|
||||
/* We ignore failures here in case /run isn't mounted...not much we
|
||||
* can do about that, but we don't want to fail.
|
||||
*/
|
||||
@@ -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. */
|
||||
@@ -239,11 +180,11 @@ main(int argc, char *argv[])
|
||||
* later boot and `systemd-remount-fs.service`.
|
||||
*/
|
||||
if (path_is_on_readonly_fs ("."))
|
||||
{
|
||||
if (mount (".", ".", NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
|
||||
err (EXIT_FAILURE, "failed to remount rootfs writable (for overlayfs)");
|
||||
}
|
||||
|
||||
{
|
||||
if (mount (".", ".", NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
|
||||
err (EXIT_FAILURE, "failed to remount rootfs writable (for overlayfs)");
|
||||
}
|
||||
|
||||
if (mount ("overlay", "usr", "overlay", 0, usr_ovl_options) < 0)
|
||||
err (EXIT_FAILURE, "failed to mount /usr overlayfs");
|
||||
}
|
||||
|
||||
@@ -38,28 +38,10 @@
|
||||
|
||||
#include "ostree-mount-util.h"
|
||||
|
||||
/* Having a writeable /var is necessary for full system functioning.
|
||||
* If /var isn't writeable, we mount tmpfs over it. While this is
|
||||
* somewhat outside of ostree's scope, having all /var twiddling
|
||||
* in one place will make future maintenance easier.
|
||||
*/
|
||||
static void
|
||||
maybe_mount_tmpfs_on_var (void)
|
||||
{
|
||||
if (!path_is_on_readonly_fs ("/var"))
|
||||
return;
|
||||
|
||||
if (umount ("/var") < 0 && errno != EINVAL)
|
||||
warn ("failed to unmount /var prior to mounting tmpfs, mounting over");
|
||||
|
||||
if (mount ("tmpfs", "/var", "tmpfs", 0, NULL) < 0)
|
||||
err (EXIT_FAILURE, "failed to mount tmpfs on /var");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
const char *remounts[] = { "/sysroot", "/etc", "/home", "/root", "/tmp", "/var", NULL };
|
||||
const char *remounts[] = { "/sysroot", "/var", NULL };
|
||||
struct stat stbuf;
|
||||
int i;
|
||||
|
||||
@@ -69,8 +51,6 @@ main(int argc, char *argv[])
|
||||
* to clear the readonly flag in that case.
|
||||
*/
|
||||
|
||||
maybe_mount_tmpfs_on_var ();
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -84,17 +64,25 @@ main(int argc, char *argv[])
|
||||
*/
|
||||
if (S_ISLNK (stbuf.st_mode))
|
||||
continue;
|
||||
/* If not a mountpoint, skip it */
|
||||
struct statvfs stvfsbuf;
|
||||
if (statvfs (target, &stvfsbuf) == -1)
|
||||
continue;
|
||||
/* If no read-only flag, skip it */
|
||||
if ((stvfsbuf.f_flag & ST_RDONLY) == 0)
|
||||
continue;
|
||||
/* It's a mounted, read-only fs; remount it */
|
||||
if (mount (target, target, NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
|
||||
{
|
||||
{
|
||||
/* Also ignore ENINVAL - if the target isn't a mountpoint
|
||||
* already, then assume things are OK.
|
||||
*/
|
||||
if (errno != EINVAL)
|
||||
err (EXIT_FAILURE, "failed to remount %s", target);
|
||||
}
|
||||
}
|
||||
else
|
||||
printf ("Remounted: %s\n", target);
|
||||
}
|
||||
|
||||
maybe_mount_tmpfs_on_var ();
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user