C/C++ how to create snapshots from C/C ++ ?

fcorbelli

Active Member

Reaction score: 54
Messages: 167

Hello, I'm looking for (if it already exists, so I don't have to do it myself)
the source of a zfs-like (zfs ".exe") program to create snapshots.
Basically, inside another C ++ software, I would like to have a snapshot created / destroyed.
I have to reduce everything to a single file (no includes, no libraries and so on).
In short, how to create a snapshot from a C / C ++ program?

Something like this

Thanks for any help
 

Zirias

Daemon

Reaction score: 1,341
Messages: 2,362

A "ZFS-like" snapshot must be implemented at the filesystem level. For any write to the snapshot or the original dataset, the filesystem must do the correct thing (copy-on-write, so you end up with a set of changes). You can't just magically create a snapshot that will work that way later.
 
OP
fcorbelli

fcorbelli

Active Member

Reaction score: 54
Messages: 167

I don't want to take a zfs-like snapshot, I just want a real zfs snapshot.

In the source (of openzfs) that I put there is a program that does just that (it is none other than the zfs command).

The problem is that it is "fused" with other sources and libraries, while I need a single source that I can merge with another program.
Basically a mini-source of the zfs command binary

Suppose you have, for clarity, an archiver (7z, zip, rar it doesn't matter) with its source.
I want to do a command in the binary that FIRST takes a snapshot, takes files from it, then deletes it.
Normally this would be done with a bash script
Code:
make zfs snapshot
(...) do something (...)
delete zfs snapshot [/ CODE]
 

Zirias

Daemon

Reaction score: 1,341
Messages: 2,362

Uhm, well, you were writing "zfs-like". If you just want to create a snapshot on a real-life ZFS filesystem, I'd say using the host's tool is the preferred way anyways (I wouldn't rely on APIs in different ZFS implementations to be compatible). E.g. poudriere just invokes the zfs commands. It does it from its shellscript parts, but of course, you can invoke a command from C code as well.
 
OP
fcorbelli

fcorbelli

Active Member

Reaction score: 54
Messages: 167

zfs-like (zfs ".exe") program
In fact I already do this (under Windows) to create VSS (make a script, then execute), but I was wondering what happened "behind the scenes" to create a snapshot from a software.
Code:
/*
 * zfs snapshot [-r] [-o prop=value] ... <fs@snap>
 *
 * Creates a snapshot with the given name.  While functionally equivalent to
 * 'zfs create', it is a separate command to differentiate intent.
 */
static int
zfs_do_snapshot(int argc, char **argv)
{
    int ret = 0;
    int c;
    nvlist_t *props;
    snap_cbdata_t sd = { 0 };
    boolean_t multiple_snaps = B_FALSE;

    if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
        nomem();
    if (nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) != 0)
        nomem();

    /* check options */
    while ((c = getopt(argc, argv, "ro:")) != -1) {
        switch (c) {
        case 'o':
            if (!parseprop(props, optarg)) {
                nvlist_free(sd.sd_nvl);
                nvlist_free(props);
                return (1);
            }
            break;
        case 'r':
            sd.sd_recursive = B_TRUE;
            multiple_snaps = B_TRUE;
            break;
        case '?':
            (void) fprintf(stderr, gettext("invalid option '%c'\n"),
                optopt);
            goto usage;
        }
    }

    argc -= optind;
    argv += optind;

    /* check number of arguments */
    if (argc < 1) {
        (void) fprintf(stderr, gettext("missing snapshot argument\n"));
        goto usage;
    }

    if (argc > 1)
        multiple_snaps = B_TRUE;
    for (; argc > 0; argc--, argv++) {
        char *atp;
        zfs_handle_t *zhp;

        atp = strchr(argv[0], '@');
        if (atp == NULL)
            goto usage;
        *atp = '\0';
        sd.sd_snapname = atp + 1;
        zhp = zfs_open(g_zfs, argv[0],
            ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
        if (zhp == NULL)
            goto usage;
        if (zfs_snapshot_cb(zhp, &sd) != 0)
            goto usage;
    }

    ret = zfs_snapshot_nvl(g_zfs, sd.sd_nvl, props);
    nvlist_free(sd.sd_nvl);
    nvlist_free(props);
    if (ret != 0 && multiple_snaps)
        (void) fprintf(stderr, gettext("no snapshots were created\n"));
    return (ret != 0);

usage:
    nvlist_free(sd.sd_nvl);
    nvlist_free(props);
    usage(B_FALSE);
    return (-1);
}
 

mtu

Active Member

Reaction score: 104
Messages: 158

This could be useful to you:

 
Top