summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--discover/device-handler.c56
-rw-r--r--discover/device-handler.h4
-rw-r--r--discover/parser.c29
-rw-r--r--discover/parser.h9
-rw-r--r--test/parser/utils.c30
5 files changed, 125 insertions, 3 deletions
diff --git a/discover/device-handler.c b/discover/device-handler.c
index fc280af..04a4484 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -721,12 +721,15 @@ static bool check_existing_mount(struct discover_device *dev)
continue;
if (mntstat.st_rdev == devstat.st_rdev) {
- pb_debug("%s: %s is already mounted at %s\n"
- __func__, dev->device_path,
- mnt->mnt_dir);
dev->mount_path = talloc_strdup(dev, mnt->mnt_dir);
+ dev->mounted_rw = !!hasmntopt(mnt, "rw");
dev->mounted = true;
dev->unmount = false;
+
+ pb_debug("%s: %s is already mounted (r%c) at %s\n",
+ __func__, dev->device_path,
+ dev->mounted_rw ? 'w' : 'o',
+ mnt->mnt_dir);
break;
}
}
@@ -763,6 +766,7 @@ static int mount_device(struct discover_device *dev)
"-o", "ro", NULL);
if (!rc) {
dev->mounted = true;
+ dev->mounted_rw = false;
dev->unmount = true;
return 0;
}
@@ -773,6 +777,7 @@ static int mount_device(struct discover_device *dev)
if (!rc) {
dev->mounted = true;
+ dev->mounted_rw = true;
dev->unmount = true;
return 0;
}
@@ -805,6 +810,39 @@ static int umount_device(struct discover_device *dev)
return 0;
}
+
+int device_request_write(struct discover_device *dev, bool *release)
+{
+ int rc;
+
+ *release = false;
+
+ if (!dev->mounted)
+ return -1;
+
+ if (dev->mounted_rw)
+ return 0;
+
+ rc = process_run_simple(dev, pb_system_apps.mount, dev->mount_path,
+ "-o", "remount,rw", NULL);
+ if (rc)
+ return -1;
+
+ dev->mounted_rw = true;
+ *release = true;
+ return 0;
+}
+
+void device_release_write(struct discover_device *dev, bool release)
+{
+ if (!release)
+ return;
+
+ process_run_simple(dev, pb_system_apps.mount, dev->mount_path,
+ "-o", "remount,ro", NULL);
+ dev->mounted_rw = false;
+}
+
#else
static int umount_device(struct discover_device *dev __attribute__((unused)))
@@ -818,5 +856,17 @@ static int __attribute__((unused)) mount_device(
return 0;
}
+int device_request_write(struct discover_device *dev __attribute__((unused)),
+ bool *release)
+{
+ *release = true;
+ return 0;
+}
+
+void device_release_write(struct discover_device *dev __attribute__((unused)),
+ bool release __attribute__((unused)))
+{
+}
+
#endif
diff --git a/discover/device-handler.h b/discover/device-handler.h
index 5dbc349..6b36e07 100644
--- a/discover/device-handler.h
+++ b/discover/device-handler.h
@@ -36,6 +36,7 @@ struct discover_device {
char *mount_path;
const char *device_path;
bool mounted;
+ bool mounted_rw;
bool unmount;
bool notified;
@@ -124,4 +125,7 @@ void device_handler_boot(struct device_handler *handler,
struct boot_command *cmd);
void device_handler_cancel_default(struct device_handler *handler);
+int device_request_write(struct discover_device *dev, bool *release);
+void device_release_write(struct discover_device *dev, bool release);
+
#endif /* _DEVICE_HANDLER_H */
diff --git a/discover/parser.c b/discover/parser.c
index d34600d..4816916 100644
--- a/discover/parser.c
+++ b/discover/parser.c
@@ -49,6 +49,35 @@ int parser_request_file(struct discover_context *ctx,
return rc;
}
+int parser_replace_file(struct discover_context *ctx,
+ struct discover_device *dev, const char *filename,
+ char *buf, int len)
+{
+ bool release;
+ char *path;
+ int rc;
+
+ if (!dev->mounted)
+ return -1;
+
+ rc = device_request_write(dev, &release);
+ if (rc) {
+ pb_log("Can't write file %s: device doesn't allow write\n",
+ dev->device_path);
+ return -1;
+ }
+
+ path = local_path(ctx, dev, filename);
+
+ rc = replace_file(path, buf, len);
+
+ talloc_free(path);
+
+ device_release_write(dev, release);
+
+ return rc;
+}
+
static int download_config(struct discover_context *ctx, char **buf, int *len)
{
struct load_url_result *result;
diff --git a/discover/parser.h b/discover/parser.h
index c1b4012..2aaa077 100644
--- a/discover/parser.h
+++ b/discover/parser.h
@@ -51,8 +51,17 @@ void parser_init(void);
void iterate_parsers(struct discover_context *ctx, enum conf_method method);
int parse_user_event(struct discover_context *ctx, struct event *event);
+/* File IO functions for parsers; these should be the only interface that
+ * parsers use to access a device's filesystem.
+ *
+ * These are intended for small amounts of data, typically text configuration
+ * and state files.
+ */
int parser_request_file(struct discover_context *ctx,
struct discover_device *dev, const char *filename,
char **buf, int *len);
+int parser_replace_file(struct discover_context *ctx,
+ struct discover_device *dev, const char *filename,
+ char *buf, int len);
#endif /* _PARSER_H */
diff --git a/test/parser/utils.c b/test/parser/utils.c
index d1ced73..33efda8 100644
--- a/test/parser/utils.c
+++ b/test/parser/utils.c
@@ -186,6 +186,36 @@ int parser_request_file(struct discover_context *ctx,
return -1;
}
+int parser_replace_file(struct discover_context *ctx,
+ struct discover_device *dev, const char *filename,
+ char *buf, int len)
+{
+ struct parser_test *test = ctx->test_data;
+ struct test_file *f, *file;
+
+ list_for_each_entry(&test->files, f, list) {
+ if (f->dev != dev)
+ continue;
+ if (strcmp(f->name, filename))
+ continue;
+
+ file = f;
+ break;
+ }
+
+ if (!file) {
+ file = talloc_zero(test, struct test_file);
+ file->dev = dev;
+ file->name = filename;
+ list_add(&test->files, &file->list);
+ } else {
+ talloc_free(file->data);
+ }
+
+ file->data = talloc_memdup(test, buf, len);
+ file->size = len;
+ return 0;
+}
int test_run_parser(struct parser_test *test, const char *parser_name)
{
struct p_item* i;
OpenPOWER on IntegriCloud