uci: use per-session save directory and register session destroy callback to purge leftover deltas
This commit is contained in:
parent
ad8e937f97
commit
b3a5c08e08
2 changed files with 103 additions and 0 deletions
96
uci.c
96
uci.c
|
@ -168,6 +168,28 @@ rpc_uci_status(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup per-session delta save directory. If the passed "sid" blob attribute
|
||||||
|
* pointer is NULL then the precedure was not invoked through the ubus-rpc so
|
||||||
|
* we do not perform session isolation and use the default save directory.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
rpc_uci_set_savedir(struct blob_attr *sid)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
|
if (!sid)
|
||||||
|
{
|
||||||
|
uci_set_savedir(cursor, "/tmp/.uci");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path) - 1,
|
||||||
|
"/tmp/.uci-rpc-%s", (char *)blobmsg_data(sid));
|
||||||
|
|
||||||
|
uci_set_savedir(cursor, path);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test read access to given config. If the passed "sid" blob attribute pointer
|
* Test read access to given config. If the passed "sid" blob attribute pointer
|
||||||
* is NULL then the precedure was not invoked through the ubus-rpc so we do not
|
* is NULL then the precedure was not invoked through the ubus-rpc so we do not
|
||||||
|
@ -176,6 +198,8 @@ rpc_uci_status(void)
|
||||||
static bool
|
static bool
|
||||||
rpc_uci_read_access(struct blob_attr *sid, struct blob_attr *config)
|
rpc_uci_read_access(struct blob_attr *sid, struct blob_attr *config)
|
||||||
{
|
{
|
||||||
|
rpc_uci_set_savedir(sid);
|
||||||
|
|
||||||
if (!sid)
|
if (!sid)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -191,6 +215,8 @@ rpc_uci_read_access(struct blob_attr *sid, struct blob_attr *config)
|
||||||
static bool
|
static bool
|
||||||
rpc_uci_write_access(struct blob_attr *sid, struct blob_attr *config)
|
rpc_uci_write_access(struct blob_attr *sid, struct blob_attr *config)
|
||||||
{
|
{
|
||||||
|
rpc_uci_set_savedir(sid);
|
||||||
|
|
||||||
if (!sid)
|
if (!sid)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -1085,6 +1111,69 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove given delta save directory (if any).
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
rpc_uci_purge_savedir(const char *path)
|
||||||
|
{
|
||||||
|
DIR *d;
|
||||||
|
struct stat s;
|
||||||
|
struct dirent *e;
|
||||||
|
char file[PATH_MAX];
|
||||||
|
|
||||||
|
if (stat(path, &s) || !S_ISDIR(s.st_mode))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((d = opendir(path)) != NULL)
|
||||||
|
{
|
||||||
|
while ((e = readdir(d)) != NULL)
|
||||||
|
{
|
||||||
|
snprintf(file, sizeof(file) - 1, "%s/%s", path, e->d_name);
|
||||||
|
|
||||||
|
if (stat(file, &s) || !S_ISREG(s.st_mode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unlink(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(d);
|
||||||
|
|
||||||
|
rmdir(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Session destroy callback to purge associated delta directory.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
rpc_uci_purge_savedir_cb(struct rpc_session *ses, void *priv)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path) - 1, "/tmp/.uci-rpc-%s", ses->id);
|
||||||
|
rpc_uci_purge_savedir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removes all delta directories which match the /tmp/.uci-rpc-* pattern.
|
||||||
|
* This is used to clean up garbage when starting rpcd.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
rpc_uci_purge_savedirs(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
glob_t gl;
|
||||||
|
|
||||||
|
if (!glob("/tmp/.uci-rpc-*", 0, NULL, &gl))
|
||||||
|
{
|
||||||
|
for (i = 0; i < gl.gl_pathc; i++)
|
||||||
|
rpc_uci_purge_savedir(gl.gl_pathv[i]);
|
||||||
|
|
||||||
|
globfree(&gl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int rpc_uci_api_init(struct ubus_context *ctx)
|
int rpc_uci_api_init(struct ubus_context *ctx)
|
||||||
{
|
{
|
||||||
static const struct ubus_method uci_methods[] = {
|
static const struct ubus_method uci_methods[] = {
|
||||||
|
@ -1110,10 +1199,17 @@ int rpc_uci_api_init(struct ubus_context *ctx)
|
||||||
.n_methods = ARRAY_SIZE(uci_methods),
|
.n_methods = ARRAY_SIZE(uci_methods),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct rpc_session_cb cb = {
|
||||||
|
.cb = rpc_uci_purge_savedir_cb
|
||||||
|
};
|
||||||
|
|
||||||
cursor = uci_alloc_context();
|
cursor = uci_alloc_context();
|
||||||
|
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
return UBUS_STATUS_UNKNOWN_ERROR;
|
return UBUS_STATUS_UNKNOWN_ERROR;
|
||||||
|
|
||||||
|
rpc_uci_purge_savedirs();
|
||||||
|
rpc_session_destroy_cb(&cb);
|
||||||
|
|
||||||
return ubus_add_object(ctx, &obj);
|
return ubus_add_object(ctx, &obj);
|
||||||
}
|
}
|
||||||
|
|
7
uci.h
7
uci.h
|
@ -19,6 +19,13 @@
|
||||||
#ifndef __RPC_UCI_H
|
#ifndef __RPC_UCI_H
|
||||||
#define __RPC_UCI_H
|
#define __RPC_UCI_H
|
||||||
|
|
||||||
|
#include <glob.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <libubus.h>
|
#include <libubus.h>
|
||||||
#include <uci.h>
|
#include <uci.h>
|
||||||
|
|
Loading…
Reference in a new issue