~ubuntu-branches/debian/stretch/btrfs-tools/stretch

« back to all changes in this revision

Viewing changes to cmds-send.c

  • Committer: Package Import Robot
  • Author(s): Dimitri John Ledkov
  • Date: 2014-04-19 12:12:11 UTC
  • mfrom: (1.2.12) (6.1.37 sid)
  • Revision ID: package-import@ubuntu.com-20140419121211-mski0g757tsdv4x1
Tags: 3.14.1-1
* New upstream release.
* Switch to git-dpm.
* Rebase and cleanup patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include "ioctl.h"
40
40
#include "commands.h"
41
41
#include "list.h"
 
42
#include "utils.h"
42
43
 
43
44
#include "send.h"
44
45
#include "send-utils.h"
57
58
        struct subvol_uuid_search sus;
58
59
};
59
60
 
60
 
int find_mount_root(const char *path, char **mount_root)
61
 
{
62
 
        FILE *mnttab;
63
 
        int fd;
64
 
        struct mntent *ent;
65
 
        int len;
66
 
        int ret;
67
 
        int longest_matchlen = 0;
68
 
        char *longest_match = NULL;
69
 
 
70
 
        fd = open(path, O_RDONLY | O_NOATIME);
71
 
        if (fd < 0)
72
 
                return -errno;
73
 
        close(fd);
74
 
 
75
 
        mnttab = fopen("/proc/mounts", "r");
76
 
        if (!mnttab)
77
 
                return -errno;
78
 
 
79
 
        while ((ent = getmntent(mnttab))) {
80
 
                len = strlen(ent->mnt_dir);
81
 
                if (strncmp(ent->mnt_dir, path, len) == 0) {
82
 
                        /* match found */
83
 
                        if (longest_matchlen < len) {
84
 
                                free(longest_match);
85
 
                                longest_matchlen = len;
86
 
                                longest_match = strdup(ent->mnt_dir);
87
 
                        }
88
 
                }
89
 
        }
90
 
        fclose(mnttab);
91
 
 
92
 
        if (!longest_match) {
93
 
                fprintf(stderr,
94
 
                        "ERROR: Failed to find mount root for path %s.\n",
95
 
                        path);
96
 
                return -ENOENT;
97
 
        }
98
 
 
99
 
        ret = 0;
100
 
        *mount_root = realpath(longest_match, NULL);
101
 
        if (!*mount_root)
102
 
                ret = -errno;
103
 
 
104
 
        free(longest_match);
105
 
        return ret;
106
 
}
107
 
 
108
61
static int get_root_id(struct btrfs_send *s, const char *path, u64 *root_id)
109
62
{
110
63
        struct subvol_info *si;
282
235
        return ERR_PTR(ret);
283
236
}
284
237
 
285
 
static int do_send(struct btrfs_send *send, u64 root_id, u64 parent_root_id,
286
 
                   int is_first_subvol, int is_last_subvol)
 
238
static int do_send(struct btrfs_send *send, u64 parent_root_id,
 
239
                   int is_first_subvol, int is_last_subvol, char *subvol)
287
240
{
288
241
        int ret;
289
242
        pthread_t t_read;
290
243
        pthread_attr_t t_attr;
291
244
        struct btrfs_ioctl_send_args io_send;
292
 
        struct subvol_info *si;
293
245
        void *t_err = NULL;
294
246
        int subvol_fd = -1;
295
247
        int pipefd[2] = {-1, -1};
296
248
 
297
 
        si = subvol_uuid_search(&send->sus, root_id, NULL, 0, NULL,
298
 
                        subvol_search_by_root_id);
299
 
        if (!si) {
300
 
                ret = -ENOENT;
301
 
                fprintf(stderr, "ERROR: could not find subvol info for %llu",
302
 
                                root_id);
303
 
                goto out;
304
 
        }
305
 
 
306
 
        subvol_fd = openat(send->mnt_fd, si->path, O_RDONLY | O_NOATIME);
 
249
        subvol_fd = openat(send->mnt_fd, subvol, O_RDONLY | O_NOATIME);
307
250
        if (subvol_fd < 0) {
308
251
                ret = -errno;
309
 
                fprintf(stderr, "ERROR: open %s failed. %s\n", si->path,
 
252
                fprintf(stderr, "ERROR: open %s failed. %s\n", subvol,
310
253
                                strerror(-ret));
311
254
                goto out;
312
255
        }
385
328
                close(pipefd[0]);
386
329
        if (pipefd[1] != -1)
387
330
                close(pipefd[1]);
388
 
        if (si) {
389
 
                free(si->path);
390
 
                free(si);
391
 
        }
392
331
        return ret;
393
332
}
394
333
 
518
457
                                                "root_id for %s\n", subvol);
519
458
                                goto out;
520
459
                        }
 
460
 
 
461
                        ret = is_subvol_ro(&send, subvol);
 
462
                        if (ret < 0)
 
463
                                goto out;
 
464
                        if (!ret) {
 
465
                                ret = -EINVAL;
 
466
                                fprintf(stderr,
 
467
                                "ERROR: cloned subvol %s is not read-only.\n",
 
468
                                        subvol);
 
469
                                goto out;
 
470
                        }
 
471
 
521
472
                        add_clone_source(&send, root_id);
522
473
                        subvol_uuid_search_finit(&send.sus);
523
474
                        free(subvol);
546
497
                                                "%s\n", optarg, strerror(-ret));
547
498
                                goto out;
548
499
                        }
 
500
 
 
501
                        ret = is_subvol_ro(&send, snapshot_parent);
 
502
                        if (ret < 0)
 
503
                                goto out;
 
504
                        if (!ret) {
 
505
                                ret = -EINVAL;
 
506
                                fprintf(stderr,
 
507
                                        "ERROR: parent %s is not read-only.\n",
 
508
                                        snapshot_parent);
 
509
                                goto out;
 
510
                        }
 
511
 
549
512
                        full_send = 0;
550
513
                        break;
551
514
                case 'i':
561
524
                }
562
525
        }
563
526
 
564
 
        if (optind == argc) {
565
 
                fprintf(stderr, "ERROR: send needs path to snapshot\n");
566
 
                ret = 1;
567
 
                goto out;
568
 
        }
 
527
        if (optind == argc)
 
528
                usage(cmd_send_usage);
569
529
 
570
530
        if (outname != NULL) {
571
531
                send.dump_fd = creat(outname, 0600);
664
624
                        goto out;
665
625
                }
666
626
 
667
 
                ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
668
 
                                &root_id);
669
 
                if (ret < 0) {
670
 
                        fprintf(stderr, "ERROR: could not resolve root_id "
671
 
                                        "for %s\n", subvol);
672
 
                        goto out;
673
 
                }
674
 
 
675
627
                if (!full_send && !parent_root_id) {
676
628
                        ret = find_good_parent(&send, root_id, &parent_root_id);
677
629
                        if (ret < 0) {
700
652
                        is_first_subvol = 1;
701
653
                        is_last_subvol = 1;
702
654
                }
703
 
                ret = do_send(&send, root_id, parent_root_id,
704
 
                              is_first_subvol, is_last_subvol);
 
655
                ret = do_send(&send, parent_root_id, is_first_subvol,
 
656
                              is_last_subvol, subvol);
705
657
                if (ret < 0)
706
658
                        goto out;
707
659
 
726
678
}
727
679
 
728
680
const char * const cmd_send_usage[] = {
729
 
        "btrfs send [-ve] [-p <parent>] [-c <clone-src>] [-f <outfile>] <subvol>",
730
 
        "Send the subvolume to stdout.",
731
 
        "Sends the subvolume specified by <subvol> to stdout.",
 
681
        "btrfs send [-ve] [-p <parent>] [-c <clone-src>] [-f <outfile>] <subvol> [<subvol>...]",
 
682
        "Send the subvolume(s) to stdout.",
 
683
        "Sends the subvolume(s) specified by <subvol> to stdout.",
732
684
        "By default, this will send the whole subvolume. To do an incremental",
733
685
        "send, use '-p <parent>'. If you want to allow btrfs to clone from",
734
686
        "any additional local snapshots, use '-c <clone-src>' (multiple times",