18 Commits
v1.1 ... master

Author SHA1 Message Date
Maximilian Luz
14cb1ee69f rmtfs: Fix command line argument parsing for '-o' optarg
Commit 2ee01bf ("storage: Try opening the slot-suffixed partition")
introduced a bug where option '-o' is incorrectly specified as having no
argument. Therefore, passing -o with a path incorrectly sets that path
to the default '/boot' one as optarg evaluates to NULL. Fix this by
telling getopt that we expect an argument.

Fixes: 2ee01bf ("storage: Try opening the slot-suffixed partition")
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
2026-01-23 20:11:07 -06:00
Dmitry Baryshkov
f9847a777c Merge pull request #27 from quic-kdybcio/topic/slotsuffix
storage: Try opening the slot-suffixed partition
2025-12-23 04:55:11 +02:00
Konrad Dybcio
f7566e4c82 Merge pull request #28 from z3ntu/modem_study
storage: Add modem_study into partition_table
2025-09-26 13:41:45 +02:00
Luca Weiss
27b3a6f00f storage: Add modem_study into partition_table
The partition /boot/modem_study needs to be served on the Milos/SM7635
Fairphone (Gen. 6) smartphone.

Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
2025-07-28 16:35:04 +02:00
Konrad Dybcio
2ee01bf752 storage: Try opening the slot-suffixed partition
Some devices ship 2 copies of remote partitions (see e.g. #22), which
the current code can't cope with.

Add parsing of a slot suffix (via '-S', single character) and if
passed, retry opening partition (via a partlabel) with it.

Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
2025-07-02 12:58:29 +02:00
Konrad Dybcio
586372e575 Merge pull request #26 from quic-kdybcio/topic/formatspecifier
sharedmem: Fix build warning on 32-bit arm
2025-06-30 17:39:29 +02:00
Konrad Dybcio
19d1acb728 sharedmem: Fix build warning on 32-bit arm
Format specifiers won't stop biting.

Closes: https://github.com/linux-msm/rmtfs/issues/25
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
2025-06-30 17:35:31 +02:00
Konrad Dybcio
44facf5694 Merge pull request #24 from loicpoulain/rb1
rmtfs.service: Fix start/stop ordering between rmtfs and NetworkManager
2025-06-30 16:25:23 +02:00
Loic Poulain
5b214f61b9 rmtfs.service: Fix start/stop ordering between rmtfs and NetworkManager
Since rmtfs typically provides resources for wireless and modem-related
processors, it's important to ensure that this service starts before
and stops after NetworkManager.

On platforms like QCOM RB1, this sequencing prevents the Wi-Fi interface(s)
from being left in a dangling state while NetworkManager attempts to tear
down the interface(s):
https://github.com/qualcomm-linux/qcom-deb-images/issues/40#issuecomment-2944265370

The 'Before' dependency directive is ignored if NetworkManager is disabled or absent.

Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
2025-06-10 15:10:15 +02:00
Dmitry Baryshkov
b61c22b1cd Merge pull request #23 from lumag/rmtfs-dir-no-qrtr-ns
rmtfs-dir.service.in: Remove dependency on qrtr-ns.service
2025-05-02 03:58:59 +03:00
Luca Weiss
b46235296f rmtfs-dir.service.in: Remove dependency on qrtr-ns.service
The QRTR nameserver has been built into the kernel for years now, drop
the dependency since qrtr-ns.service won't do anything anyways.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
2025-04-24 22:10:21 +03:00
Dmitry Baryshkov
f24570816b Merge pull request #19 from martinezjavier/add-rmtfs-dir-service
Add systemd service to load EFS data from a directory
2025-02-13 21:43:44 +02:00
Konrad Dybcio
33e1e40615 Merge pull request #18 from ipearworks/fix
sharedmem: Fix incorrect usages of `strerror`
2024-03-18 17:09:52 +01:00
Konrad Dybcio
a2df4bd096 Merge pull request #20 from z3ntu/qrtr-ns
rmtfs.service.in: Remove dependency on qrtr-ns.service
2024-03-18 17:09:02 +01:00
Luca Weiss
44fcb2ec64 rmtfs.service.in: Remove dependency on qrtr-ns.service
The QRTR nameserver has been built into the kernel for years now, drop
the dependency since qrtr-ns.service won't do anything anyways.
2024-03-11 11:02:29 +01:00
Javier Martinez Canillas
0caf528637 rmtfs-dir.service: Add systemd service to load EFS data from a directory
The EFS data can either be in a partition or a filesystem path. The rmtfs
allows both, but there is only a systemd service to use the former.

Add another systemd service that does the latter. By default, the EFS path
is /var/lib/rmtfs (which is the directory used by msm-cros-efs-loader.sh
and other tools that extract the EFS data) but this can be changed during
build by setting the RMTFS_EFS_PATH environment variable.

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
2024-02-07 15:03:20 +01:00
Javier Martinez Canillas
cc5d4df973 rmtfs: Fix a couple of possible uninitialized variables usage
GCC version 13.2.1 20231205 complains about the following:

  cc -Wall -g -O2   -c -o storage.o storage.c
  In function ‘rmtfs_iovec’,
      inlined from ‘handle_rmtfs’ at rmtfs.c:403:4:
  rmtfs.c:224:12: warning: ‘is_write’ may be used uninitialized [-Wmaybe-uninitialized]
    224 |         if (is_write)
        |            ^
  rmtfs.c: In function ‘handle_rmtfs’:
  rmtfs.c:158:17: note: ‘is_write’ was declared here
    158 |         uint8_t is_write;
        |                 ^
  In function ‘rmtfs_iovec’,
      inlined from ‘handle_rmtfs’ at rmtfs.c:403:4:
  rmtfs.c:225:17: warning: ‘rmtfd’ may be used uninitialized [-Wmaybe-uninitialized]
    225 |                 storage_sync(rmtfd);
        |                 ^~~~~~~~~~~~~~~~~~~
  rmtfs.c: In function ‘handle_rmtfs’:
  rmtfs.c:154:23: note: ‘rmtfd’ was declared here
    154 |         struct rmtfd *rmtfd;
        |                       ^~~~~

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
2024-02-07 15:03:20 +01:00
Tianyi Liu
75cb81d197 sharedmem: Fix incorrect usages of strerror
`strerror` takes the `errno` directly as its argument,
negating it will result in an "Unknown error".

Signed-off-by: Tianyi Liu <i.pear@outlook.com>
2024-02-06 15:03:46 +08:00
7 changed files with 86 additions and 37 deletions

View File

@@ -6,6 +6,8 @@ prefix = /usr/local
bindir := $(prefix)/bin
servicedir := $(prefix)/lib/systemd/system
RMTFS_EFS_PATH ?= /var/lib/rmtfs
SRCS := qmi_rmtfs.c rmtfs.c rproc.c sharedmem.c storage.c util.c
OBJS := $(SRCS:.c=.o)
@@ -15,13 +17,15 @@ $(OUT): $(OBJS)
%.c: %.qmi
qmic -k < $<
rmtfs.service: rmtfs.service.in
@sed 's+RMTFS_PATH+$(bindir)+g' $< > $@
%.service: %.service.in
@sed -e 's+RMTFS_PATH+$(bindir)+g' -e 's+RMTFS_EFS_PATH+$(RMTFS_EFS_PATH)+g' $< > $@
install: $(OUT) rmtfs.service
install: $(OUT) rmtfs.service rmtfs-dir.service
@install -D -m 755 $(OUT) $(DESTDIR)$(prefix)/bin/$(OUT)
@install -D -m 644 rmtfs.service $(DESTDIR)$(servicedir)/rmtfs.service
@install -D -m 644 rmtfs-dir.service $(DESTDIR)$(servicedir)/rmtfs-dir.service
clean:
rm -f $(OUT) $(OBJS) rmtfs.service
rm -f $(OUT) $(OBJS) rmtfs-dir.service

11
rmtfs-dir.service.in Normal file
View File

@@ -0,0 +1,11 @@
[Unit]
Description=Qualcomm remotefs service
Before=NetworkManager.service
[Service]
ExecStart=RMTFS_PATH/rmtfs -s -o RMTFS_EFS_PATH
Restart=always
RestartSec=1
[Install]
WantedBy=multi-user.target

23
rmtfs.c
View File

@@ -27,6 +27,7 @@
static struct rmtfs_mem *rmem;
static sig_atomic_t sig_int_count;
static char slot_suffix[SLOT_SUFFIX_LEN];
static bool dbgprintf_enabled;
static void dbgprintf(const char *fmt, ...)
@@ -69,7 +70,7 @@ static void rmtfs_open(int sock, const struct qrtr_packet *pkt)
goto respond;
}
rmtfd = storage_open(pkt->node, req.path);
rmtfd = storage_open(pkt->node, req.path, slot_suffix);
if (!rmtfd) {
qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL);
goto respond;
@@ -151,11 +152,11 @@ static void rmtfs_iovec(int sock, struct qrtr_packet *pkt)
struct rmtfs_iovec_resp resp = {};
struct rmtfs_iovec_req req = {};
DEFINE_QRTR_PACKET(resp_buf, 256);
struct rmtfd *rmtfd;
struct rmtfd *rmtfd = NULL;
uint32_t caller_id = 0;
size_t num_entries = 0;
off_t sector_base;
uint8_t is_write;
uint8_t is_write = 0;
off_t phys_base;
uint8_t force = 0;
unsigned txn;
@@ -504,7 +505,7 @@ int main(int argc, char **argv)
int option;
const char *storage_root = NULL;
while ((option = getopt(argc, argv, "o:Prsv")) != -1) {
while ((option = getopt(argc, argv, "o:S:Prsv")) != -1) {
switch (option) {
/*
* -o sets the directory where EFS images are stored,
@@ -535,6 +536,20 @@ int main(int argc, char **argv)
break;
/* Partlabel slot suffix on A/B devices */
case 'S':
if (strnlen(optarg, 1 + 1) != 1) {
fprintf(stderr, "Couldn't parse slot name (too long?)\n");
return -1;
}
ret = snprintf(slot_suffix, SLOT_SUFFIX_LEN, "_%s", optarg);
if (ret != SLOT_SUFFIX_LEN - 1)
return -1;
dbgprintf("Using slot %s\n", slot_suffix);
break;
/* -v is for verbose */
case 'v':
dbgprintf_enabled = 1;

View File

@@ -26,7 +26,8 @@ ssize_t rmtfs_mem_write(struct rmtfs_mem *rmem, unsigned long phys_address, cons
struct rmtfd;
int storage_init(const char *storage_root, bool read_only, bool use_partitions);
struct rmtfd *storage_open(unsigned node, const char *path);
#define SLOT_SUFFIX_LEN (2 + 1) /* "_a" or "_b", null-terminated */
struct rmtfd *storage_open(unsigned node, const char *path, const char *slot_suffix);
struct rmtfd *storage_get(unsigned node, int caller_id);
void storage_close(struct rmtfd *rmtfd);
int storage_get_caller_id(const struct rmtfd *rmtfd);

View File

@@ -1,7 +1,6 @@
[Unit]
Description=Qualcomm remotefs service
Requires=qrtr-ns.service
After=qrtr-ns.service
Before=NetworkManager.service
[Service]
ExecStart=RMTFS_PATH/rmtfs -r -P -s

View File

@@ -4,6 +4,7 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#ifndef ANDROID
#include <libudev.h>
#else
@@ -322,7 +323,7 @@ int64_t rmtfs_mem_alloc(struct rmtfs_mem *rmem, size_t alloc_size)
{
if (alloc_size > rmem->size) {
fprintf(stderr,
"[RMTFS] rmtfs shared memory not large enough for allocation request 0x%zx vs 0x%lx\n",
"[RMTFS] rmtfs shared memory not large enough for allocation request 0x%zx vs %" PRIu64 "\n",
alloc_size, rmem->size);
return -EINVAL;
}
@@ -418,7 +419,7 @@ static int rmtfs_mem_enumerate(struct rmtfs_mem *rmem)
if (!dir) {
fprintf(stderr,
"Unable to open reserved-memory device tree node: %s\n",
strerror(-errno));
strerror(errno));
close(basefd);
return -1;
}
@@ -430,7 +431,7 @@ static int rmtfs_mem_enumerate(struct rmtfs_mem *rmem)
dirfd = openat(basefd, de->d_name, O_DIRECTORY);
if (dirfd < 0) {
fprintf(stderr, "failed to open %s: %s\n",
de->d_name, strerror(-errno));
de->d_name, strerror(errno));
ret = -1;
goto out;
}
@@ -438,7 +439,7 @@ static int rmtfs_mem_enumerate(struct rmtfs_mem *rmem)
regfd = openat(dirfd, "reg", O_RDONLY);
if (regfd < 0) {
fprintf(stderr, "failed to open reg of %s: %s\n",
de->d_name, strerror(-errno));
de->d_name, strerror(errno));
ret = -1;
goto out;
}
@@ -452,7 +453,7 @@ static int rmtfs_mem_enumerate(struct rmtfs_mem *rmem)
rmem->size = be64toh(reg.qw[1]);
} else {
fprintf(stderr, "failed to read reg of %s: %s\n",
de->d_name, strerror(-errno));
de->d_name, strerror(errno));
ret = -1;
}

View File

@@ -41,6 +41,7 @@ static const struct partition partition_table[] = {
{ "/boot/modem_fs2", "modem_fs2", "modemst2" },
{ "/boot/modem_fsc", "modem_fsc", "fsc" },
{ "/boot/modem_fsg", "modem_fsg", "fsg" },
{ "/boot/modem_study", "modem_study", "study" },
{ "/boot/modem_tunning", "modem_tunning", "tunning" },
{ "/boot/modem_tng", "modem_tng", "tunning" },
{}
@@ -74,16 +75,43 @@ int storage_init(const char *storage_root, bool read_only, bool use_partitions)
return 0;
}
struct rmtfd *storage_open(unsigned node, const char *path)
static int fd_open(struct rmtfd *rmtfd, const char *fspath, const struct partition *part)
{
int saved_errno;
int ret;
int fd;
if (!storage_read_only) {
fd = open(fspath, O_RDWR);
if (fd < 0) {
saved_errno = errno;
fprintf(stderr, "[storage] failed to open '%s' (requested '%s'): %s\n",
fspath, part->path, strerror(saved_errno));
return saved_errno;
}
rmtfd->fd = fd;
rmtfd->shadow_len = 0;
} else {
ret = storage_populate_shadow_buf(rmtfd, fspath);
if (ret < 0) {
saved_errno = errno;
fprintf(stderr, "[storage] failed to open '%s' (requested '%s'): %s\n",
fspath, part->path, strerror(saved_errno));
return saved_errno;
}
}
return 0;
}
struct rmtfd *storage_open(unsigned node, const char *path, const char *slot_suffix)
{
char *fspath;
const struct partition *part;
struct rmtfd *rmtfd = NULL;
const char *file;
size_t pathlen;
int saved_errno;
int ret;
int fd;
int i;
for (part = partition_table; part->path; part++) {
@@ -119,29 +147,19 @@ found:
else
file = part->actual;
pathlen = strlen(storage_dir) + strlen(file) + 2;
pathlen = strlen(storage_dir) + strlen(file) + 2 + strnlen(slot_suffix, SLOT_SUFFIX_LEN);
fspath = alloca(pathlen);
snprintf(fspath, pathlen, "%s/%s", storage_dir, file);
if (!storage_read_only) {
fd = open(fspath, O_RDWR);
if (fd < 0) {
saved_errno = errno;
fprintf(stderr, "[storage] failed to open '%s' (requested '%s'): %s\n",
fspath, part->path, strerror(saved_errno));
errno = saved_errno;
ret = fd_open(rmtfd, fspath, part);
if (ret) {
/* Try again with the slot suffix before giving up */
if (!slot_suffix)
return NULL;
}
rmtfd->fd = fd;
rmtfd->shadow_len = 0;
} else {
ret = storage_populate_shadow_buf(rmtfd, fspath);
if (ret < 0) {
saved_errno = errno;
fprintf(stderr, "[storage] failed to open '%s' (requested '%s'): %s\n",
fspath, part->path, strerror(saved_errno));
errno = saved_errno;
snprintf(fspath, pathlen, "%s/%s%s", storage_dir, file, slot_suffix);
ret = fd_open(rmtfd, fspath, part);
if (ret)
return NULL;
}
}
rmtfd->node = node;