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>
This commit is contained in:
Konrad Dybcio
2025-07-01 12:06:15 +02:00
parent 586372e575
commit 2ee01bf752
3 changed files with 58 additions and 25 deletions

19
rmtfs.c
View File

@@ -27,6 +27,7 @@
static struct rmtfs_mem *rmem; static struct rmtfs_mem *rmem;
static sig_atomic_t sig_int_count; static sig_atomic_t sig_int_count;
static char slot_suffix[SLOT_SUFFIX_LEN];
static bool dbgprintf_enabled; static bool dbgprintf_enabled;
static void dbgprintf(const char *fmt, ...) static void dbgprintf(const char *fmt, ...)
@@ -69,7 +70,7 @@ static void rmtfs_open(int sock, const struct qrtr_packet *pkt)
goto respond; goto respond;
} }
rmtfd = storage_open(pkt->node, req.path); rmtfd = storage_open(pkt->node, req.path, slot_suffix);
if (!rmtfd) { if (!rmtfd) {
qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL); qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL);
goto respond; goto respond;
@@ -504,7 +505,7 @@ int main(int argc, char **argv)
int option; int option;
const char *storage_root = NULL; const char *storage_root = NULL;
while ((option = getopt(argc, argv, "o:Prsv")) != -1) { while ((option = getopt(argc, argv, "oS:Prsv")) != -1) {
switch (option) { switch (option) {
/* /*
* -o sets the directory where EFS images are stored, * -o sets the directory where EFS images are stored,
@@ -535,6 +536,20 @@ int main(int argc, char **argv)
break; 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 */ /* -v is for verbose */
case 'v': case 'v':
dbgprintf_enabled = 1; 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; struct rmtfd;
int storage_init(const char *storage_root, bool read_only, bool use_partitions); 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); struct rmtfd *storage_get(unsigned node, int caller_id);
void storage_close(struct rmtfd *rmtfd); void storage_close(struct rmtfd *rmtfd);
int storage_get_caller_id(const struct rmtfd *rmtfd); int storage_get_caller_id(const struct rmtfd *rmtfd);

View File

@@ -74,16 +74,43 @@ int storage_init(const char *storage_root, bool read_only, bool use_partitions)
return 0; 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; char *fspath;
const struct partition *part; const struct partition *part;
struct rmtfd *rmtfd = NULL; struct rmtfd *rmtfd = NULL;
const char *file; const char *file;
size_t pathlen; size_t pathlen;
int saved_errno;
int ret; int ret;
int fd;
int i; int i;
for (part = partition_table; part->path; part++) { for (part = partition_table; part->path; part++) {
@@ -119,29 +146,19 @@ found:
else else
file = part->actual; 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); fspath = alloca(pathlen);
snprintf(fspath, pathlen, "%s/%s", storage_dir, file); snprintf(fspath, pathlen, "%s/%s", storage_dir, file);
if (!storage_read_only) { ret = fd_open(rmtfd, fspath, part);
fd = open(fspath, O_RDWR); if (ret) {
if (fd < 0) { /* Try again with the slot suffix before giving up */
saved_errno = errno; if (!slot_suffix)
fprintf(stderr, "[storage] failed to open '%s' (requested '%s'): %s\n",
fspath, part->path, strerror(saved_errno));
errno = saved_errno;
return NULL; return NULL;
}
rmtfd->fd = fd; snprintf(fspath, pathlen, "%s/%s%s", storage_dir, file, slot_suffix);
rmtfd->shadow_len = 0; ret = fd_open(rmtfd, fspath, part);
} else { if (ret)
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;
return NULL; return NULL;
}
} }
rmtfd->node = node; rmtfd->node = node;