Skip to content

new --exclude-from=FILE option #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/caencoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,30 @@ static int dirent_bsearch_func(const void *key, const void *member) {
return strcmp(k, (*m)->d_name);
}

int ca_encoder_set_exclude_from(CaEncoder *e, const char *path) {
CaEncoderNode *root;
_cleanup_(ca_match_unrefp) CaMatch *match = NULL;
int r;

if (!e)
return -EINVAL;

if (!path)
return -EINVAL;

root = ca_encoder_current_node(e);

r = ca_match_new_from_file(root->fd, path, &match);
if (r < 0)
return r;

r = ca_match_merge(&root->exclude_match, match);
if (r < 0)
return r;

return 0;
}

static int ca_encoder_node_load_exclude_file(CaEncoderNode *n) {
int r;
assert(n);
Expand Down
3 changes: 3 additions & 0 deletions src/caencoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ int ca_encoder_set_uid_range(CaEncoder *e, uid_t u);
int ca_encoder_set_base_fd(CaEncoder *e, int fd);
int ca_encoder_get_base_fd(CaEncoder *e);

/* Path to exclude filter */
int ca_encoder_set_exclude_from(CaEncoder *e, const char *path);

int ca_encoder_step(CaEncoder *e);

/* Output: archive stream data */
Expand Down
15 changes: 14 additions & 1 deletion src/casync-tool.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ static bool arg_dry_run = false;
static bool arg_exclude_nodump = true;
static bool arg_exclude_submounts = false;
static bool arg_exclude_file = true;
static char *arg_exclude_from = NULL;
static bool arg_reflink = true;
static bool arg_hardlink = false;
static bool arg_punch_holes = true;
Expand Down Expand Up @@ -328,6 +329,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_EXCLUDE_NODUMP,
ARG_EXCLUDE_SUBMOUNTS,
ARG_EXCLUDE_FILE,
ARG_EXCLUDE_FROM,
ARG_UNDO_IMMUTABLE,
ARG_PUNCH_HOLES,
ARG_REFLINK,
Expand Down Expand Up @@ -361,6 +363,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "exclude-nodump", required_argument, NULL, ARG_EXCLUDE_NODUMP },
{ "exclude-submounts", required_argument, NULL, ARG_EXCLUDE_SUBMOUNTS },
{ "exclude-file", required_argument, NULL, ARG_EXCLUDE_FILE },
{ "exclude-from", required_argument, NULL, ARG_EXCLUDE_FROM },
{ "undo-immutable", required_argument, NULL, ARG_UNDO_IMMUTABLE },
{ "delete", required_argument, NULL, ARG_DELETE },
{ "punch-holes", required_argument, NULL, ARG_PUNCH_HOLES },
Expand Down Expand Up @@ -521,7 +524,11 @@ static int parse_argv(int argc, char *argv[]) {
arg_exclude_file = r;
break;

case ARG_UNDO_IMMUTABLE:
case ARG_EXCLUDE_FROM:
arg_exclude_from = strdup(optarg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing OOM check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why strdup? This now causes a leak when the program exits. I think it should be fine to use the optarg here.

break;

case ARG_UNDO_IMMUTABLE:
r = parse_boolean(optarg);
if (r < 0) {
log_error("Failed to parse --undo-immutable= parameter: %s", optarg);
Expand Down Expand Up @@ -1294,6 +1301,12 @@ static int verb_make(int argc, char *argv[]) {
return log_error_errno(r, "Failed to set cache: %m");
}

if (IN_SET(operation, MAKE_ARCHIVE_INDEX, MAKE_ARCHIVE) && arg_exclude_from) {
r = ca_sync_set_exclude_from(s, arg_exclude_from);
if (r < 0)
return log_error_errno(r, "Failed to set exclude-from: %m");
}

(void) send_notify("READY=1");

for (;;) {
Expand Down
24 changes: 24 additions & 0 deletions src/casync.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ typedef struct CaSync {
char *base_path, *temporary_base_path;
char *boundary_path;
char *archive_path, *temporary_archive_path;
char *exclude_from;

mode_t base_mode;
mode_t make_mode;
Expand Down Expand Up @@ -200,6 +201,21 @@ CaSync *ca_sync_new_decode(void) {
return s;
}

int ca_sync_set_exclude_from(CaSync *s, const char *path) {

if (!s)
return -EINVAL;

if (s->direction != CA_SYNC_ENCODE)
return -EINVAL;

s->exclude_from = strdup(path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If s->exclude_from was previously set, it needs to be freed before reassigning.
A corresponding free at the end is also needed. Prolly where archive_path is being freed.

if (!s->exclude_from)
return -ENOMEM;

return 0;
}

int ca_sync_set_chunk_size_min(CaSync *s, uint64_t v) {
int r;

Expand Down Expand Up @@ -1319,6 +1335,14 @@ static int ca_sync_start(CaSync *s) {
return r;
}

if (s->exclude_from) {
r = ca_encoder_set_exclude_from(s->encoder, s->exclude_from);
if (r < 0) {
s->encoder = ca_encoder_unref(s->encoder);
return r;
}
}

s->base_fd = -1;

r = ca_encoder_set_uid_shift(s->encoder, s->uid_shift);
Expand Down
3 changes: 3 additions & 0 deletions src/casync.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ int ca_sync_add_seed_path(CaSync *sync, const char *path);
int ca_sync_set_cache_fd(CaSync *sync, int fd);
int ca_sync_set_cache_path(CaSync *sync, const char *path);

/* Path to exclude filter */
int ca_sync_set_exclude_from(CaSync *s, const char *path);

int ca_sync_step(CaSync *sync);
int ca_sync_poll(CaSync *s, uint64_t timeout_nsec, const sigset_t *ss);

Expand Down