blob: bbbcff15d9a91b1c1f952be425886a3f92303cb3 [file] [log] [blame]
diff --git a/src/trace.c b/src/trace.c
index 240a17f..bb4d696 100644
--- a/src/trace.c
+++ b/src/trace.c
@@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <sys/param.h>
#include <errno.h>
#include <fcntl.h>
@@ -88,6 +89,7 @@
/* Prototypes for static functions */
static int read_trace (const void *parent,
int dfd, const char *path,
+ const PathPrefixOption *path_prefix,
PackFile **files, size_t *num_files);
static void fix_path (char *pathname);
static int trace_add_path (const void *parent, const char *pathname,
@@ -114,7 +116,9 @@ sig_interrupt (int signum)
int
trace (int daemonise,
- int timeout)
+ int timeout,
+ const char *filename_to_replace,
+ const PathPrefixOption *path_prefix)
{
int dfd;
FILE *fp;
@@ -248,7 +252,7 @@ trace (int daemonise,
;
/* Read trace log */
- if (read_trace (NULL, dfd, "trace", &files, &num_files) < 0)
+ if (read_trace (NULL, dfd, "trace", path_prefix, &files, &num_files) < 0)
goto error;
/*
@@ -284,6 +288,15 @@ trace (int daemonise,
continue;
}
+ /* If filename_to_replace is not NULL, only write out the
+ * file and skip others.
+ */
+ if (filename_to_replace &&
+ strcmp (filename_to_replace, filename)) {
+ nih_info ("Skipping %s", filename);
+ continue;
+ }
+
nih_info ("Writing %s", filename);
/* We only need to apply additional sorting to the
@@ -320,6 +333,7 @@ static int
read_trace (const void *parent,
int dfd,
const char *path,
+ const PathPrefixOption *path_prefix,
PackFile ** files,
size_t * num_files)
{
@@ -328,6 +342,7 @@ read_trace (const void *parent,
char *line;
nih_assert (path != NULL);
+ nih_assert (path_prefix != NULL);
nih_assert (files != NULL);
nih_assert (num_files != NULL);
@@ -373,9 +388,22 @@ read_trace (const void *parent,
*end = '\0';
fix_path (ptr);
+ if (path_prefix->st_dev != NODEV && ptr[0] == '/') {
+ struct stat stbuf;
+ char *rewritten = nih_sprintf (
+ line, "%s%s", path_prefix->prefix, ptr);
+ if (! lstat (rewritten, &stbuf) &&
+ stbuf.st_dev == path_prefix->st_dev) {
+ /* If |rewritten| exists on the same device as
+ * path_prefix->st_dev, record the rewritten one
+ * instead of the original path.
+ */
+ ptr = rewritten;
+ }
+ }
trace_add_path (parent, ptr, files, num_files);
- nih_free (line);
+ nih_free (line); /* also frees |rewritten| */
}
if (fclose (fp) < 0)
diff --git a/src/trace.h b/src/trace.h
index 8e10890..986b10c 100644
--- a/src/trace.h
+++ b/src/trace.h
@@ -19,6 +19,7 @@
#ifndef UREADAHEAD_TRACE_H
#define UREADAHEAD_TRACE_H
+#include <limits.h>
#include <sys/types.h>
#include <nih/macros.h>
@@ -27,7 +28,14 @@
NIH_BEGIN_EXTERN
-int trace (int daemonise, int timeout);
+typedef struct path_prefix_option {
+ dev_t st_dev;
+ char prefix[PATH_MAX];
+} PathPrefixOption;
+
+int trace (int daemonise, int timeout,
+ const char *filename_to_replace,
+ const PathPrefixOption *path_prefix);
NIH_END_EXTERN
diff --git a/src/ureadahead.c b/src/ureadahead.c
index 0cd4994..0e91693 100644
--- a/src/ureadahead.c
+++ b/src/ureadahead.c
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
@@ -86,6 +87,47 @@ static int dump_pack = FALSE;
**/
static SortOption sort_pack = SORT_OPEN;
+/**
+ * path_prefix:
+ *
+ * path_prefix.st_dev is set to >=0 if we should prepend path_prefix.prefix
+ * to all path names on the device.
+ **/
+static PathPrefixOption path_prefix = { NODEV };
+
+static int
+path_prefix_option (NihOption *option,
+ const char *arg)
+{
+ PathPrefixOption *value;
+ struct stat st;
+ dev_t st_dev;
+
+ nih_assert (option != NULL);
+ nih_assert (option->value != NULL);
+ nih_assert (arg != NULL);
+
+ value = (PathPrefixOption *)option->value;
+
+ if (strlen (arg) >= PATH_MAX) {
+ goto error;
+ }
+
+ if (lstat (arg, &st) < 0 || !S_ISDIR (st.st_mode)) {
+ goto error;
+ }
+
+ value->st_dev = st.st_dev;
+ strcpy (value->prefix, arg);
+
+ return 0;
+
+error:
+ fprintf (stderr, _("%s: illegal argument: %s\n"),
+ program_name, arg);
+ nih_main_suggest_help ();
+ return -1;
+}
static int
sort_option (NihOption *option,
@@ -134,6 +176,8 @@ static NihOption options[] = {
NULL, NULL, &dump_pack, NULL },
{ 0, "sort", N_("how to sort the pack file when dumping [default: path]"),
NULL, "SORT", &sort_pack, sort_option },
+ { 0, "path-prefix", N_("pathname to prepend for files on the device"),
+ NULL, "PREFIX", &path_prefix, path_prefix_option },
NIH_OPTION_LAST
};
@@ -165,13 +209,14 @@ main (int argc,
if (! args)
exit (1);
+ /* Lookup the filename for the pack based on the path given
+ * (if any).
+ */
+ filename = pack_file_name (NULL, args[0]);
+
if (! force_trace) {
NihError *err;
- /* Lookup the filename for the pack based on the path given
- * (if any).
- */
- filename = pack_file_name (NULL, args[0]);
if (! filename) {
NihError *err;
@@ -220,7 +265,7 @@ main (int argc,
}
/* Trace to generate new pack files */
- if (trace (daemonise, timeout) < 0) {
+ if (trace (daemonise, timeout, filename, &path_prefix) < 0) {
NihError *err;
err = nih_error_get ();