#define __arguments_h
#include <getopt.h>
+#include <stdint.h>
struct lxc_arguments;
/* lxc-create */
char *bdevtype, *configfile, *template;
char *fstype;
- unsigned long fssize;
+ uint64_t fssize;
char *lvname, *vgname, *thinpool;
char *zfsroot, *lowerdir, *dir;
*/
#define _GNU_SOURCE
#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
#include <unistd.h>
#include <errno.h>
#include <sched.h>
#define LO_FLAGS_AUTOCLEAR 4
#endif
+#define DEFAULT_FS_SIZE 1073741824
+#define DEFAULT_FSTYPE "ext3"
+
lxc_log_define(bdev, lxc);
static int do_rsync(const char *src, const char *dest)
}
/*
- * return block size of dev->src
+ * return block size of dev->src in units of bytes
*/
-static int blk_getsize(struct bdev *bdev, unsigned long *size)
+static int blk_getsize(struct bdev *bdev, uint64_t *size)
{
int fd, ret;
char *path = bdev->src;
fd = open(path, O_RDONLY);
if (fd < 0)
return -1;
- ret = ioctl(fd, BLKGETSIZE64, size);
+
+ ret = ioctl(fd, BLKGETSIZE64, size); // size of device in bytes
close(fd);
return ret;
}
*/
static int dir_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
const char *cname, const char *oldpath, const char *lxcpath, int snap,
- unsigned long newsize)
+ uint64_t newsize)
{
int len, ret;
static int zfs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
const char *cname, const char *oldpath, const char *lxcpath, int snap,
- unsigned long newsize)
+ uint64_t newsize)
{
int len, ret;
* a valid thin pool, and if so, we'll create the requested lv from that thin
* pool.
*/
-static int do_lvm_create(const char *path, unsigned long size, const char *thinpool)
+static int do_lvm_create(const char *path, uint64_t size, const char *thinpool)
{
int ret, pid, len;
char sz[24], *pathdup, *vg, *lv, *tp = NULL;
if (pid > 0)
return wait_for_pid(pid);
- // lvcreate default size is in M, not bytes.
- ret = snprintf(sz, 24, "%lu", size/1000000);
+ // specify bytes to lvcreate
+ ret = snprintf(sz, 24, "%"PRIu64"b", size);
if (ret < 0 || ret >= 24)
exit(1);
exit(1);
}
-static int lvm_snapshot(const char *orig, const char *path, unsigned long size)
+static int lvm_snapshot(const char *orig, const char *path, uint64_t size)
{
int ret, pid;
char sz[24], *pathdup, *lv;
if (pid > 0)
return wait_for_pid(pid);
- // lvcreate default size is in M, not bytes.
- ret = snprintf(sz, 24, "%lu", size/1000000);
+ // specify bytes to lvcreate
+ ret = snprintf(sz, 24, "%"PRIu64"b", size);
if (ret < 0 || ret >= 24)
exit(1);
static int lvm_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
const char *cname, const char *oldpath, const char *lxcpath, int snap,
- unsigned long newsize)
+ uint64_t newsize)
{
char fstype[100];
- unsigned long size = newsize;
+ uint64_t size = newsize;
int len, ret;
if (!orig->src || !orig->dest)
} else {
sprintf(fstype, "ext3");
if (!newsize)
- size = 1000000000; // default to 1G
+ size = DEFAULT_FS_SIZE;
}
if (snap) {
return wait_for_pid(pid);
}
-#define DEFAULT_FS_SIZE 1024000000
-#define DEFAULT_FSTYPE "ext3"
static int lvm_create(struct bdev *bdev, const char *dest, const char *n,
struct bdev_specs *specs)
{
const char *vg, *thinpool, *fstype, *lv = n;
- unsigned long sz;
+ uint64_t sz;
int ret, len;
if (!specs)
sz = DEFAULT_FS_SIZE;
if (do_lvm_create(bdev->src, sz, thinpool) < 0) {
- ERROR("Error creating new lvm blockdev %s size %lu", bdev->src, sz);
+ ERROR("Error creating new lvm blockdev %s size %"PRIu64" bytes", bdev->src, sz);
return -1;
}
static int btrfs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
const char *cname, const char *oldpath, const char *lxcpath, int snap,
- unsigned long newsize)
+ uint64_t newsize)
{
if (!orig->dest || !orig->src)
return -1;
return ret;
}
-static int do_loop_create(const char *path, unsigned long size, const char *fstype)
+static int do_loop_create(const char *path, uint64_t size, const char *fstype)
{
int fd, ret;
// create the new loopback file.
*/
static int loop_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
const char *cname, const char *oldpath, const char *lxcpath, int snap,
- unsigned long newsize)
+ uint64_t newsize)
{
char fstype[100];
- unsigned long size = newsize;
+ uint64_t size = newsize;
int len, ret;
char *srcdev;
} else {
sprintf(fstype, "%s", DEFAULT_FSTYPE);
if (!newsize)
- size = DEFAULT_FS_SIZE; // default to 1G
+ size = DEFAULT_FS_SIZE;
}
return do_loop_create(srcdev, size, fstype);
}
struct bdev_specs *specs)
{
const char *fstype;
- unsigned long sz;
+ uint64_t sz;
int ret, len;
char *srcdev;
static int overlayfs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
const char *cname, const char *oldpath, const char *lxcpath, int snap,
- unsigned long newsize)
+ uint64_t newsize)
{
if (!snap) {
ERROR("overlayfs is only for snapshot clones");
*/
struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname,
const char *oldpath, const char *lxcpath, const char *bdevtype,
- int flags, const char *bdevdata, unsigned long newsize,
+ int flags, const char *bdevdata, uint64_t newsize,
int *needs_rdep)
{
struct bdev *orig, *new;
*/
#include "config.h"
+#include <stdint.h>
#include <lxc/lxccontainer.h>
struct bdev;
*/
struct bdev_specs {
char *fstype;
- unsigned long fssize; // fs size in bytes
+ uint64_t fssize; // fs size in bytes
struct {
char *zfsroot;
} zfs;
/* given original mount, rename the paths for cloned container */
int (*clone_paths)(struct bdev *orig, struct bdev *new, const char *oldname,
const char *cname, const char *oldpath, const char *lxcpath,
- int snap, unsigned long newsize);
+ int snap, uint64_t newsize);
bool can_snapshot;
};
struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname,
const char *oldpath, const char *lxcpath, const char *bdevtype,
- int flags, const char *bdevdata, unsigned long newsize,
+ int flags, const char *bdevdata, uint64_t newsize,
int *needs_rdep);
struct bdev *bdev_create(const char *dest, const char *type,
const char *cname, struct bdev_specs *specs);
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
+#include <stdint.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <errno.h>
lxc_log_define(lxc_clone, lxc);
-static unsigned long get_fssize(char *s)
+/* we pass fssize in bytes */
+static uint64_t get_fssize(char *s)
{
- unsigned long ret;
- char *end;
-
- ret = strtoul(s, &end, 0);
- if (end == s)
- return 0;
- while (isblank(*end))
- end++;
- if (!(*end))
- return ret;
- if (*end == 'g' || *end == 'G')
- ret *= 1000000000;
- else if (*end == 'm' || *end == 'M')
- ret *= 1000000;
- else if (*end == 'k' || *end == 'K')
- ret *= 1000;
- return ret;
+ uint64_t ret;
+ char *end;
+
+ ret = strtoull(s, &end, 0);
+ if (end == s)
+ {
+ fprintf(stderr, "Invalid blockdev size '%s', using default size\n", s);
+ return 0;
+ }
+ while (isblank(*end))
+ end++;
+ if (*end == '\0')
+ ret *= 1024ULL * 1024ULL; // MB by default
+ else if (*end == 'b' || *end == 'B')
+ ret *= 1ULL;
+ else if (*end == 'k' || *end == 'K')
+ ret *= 1024ULL;
+ else if (*end == 'm' || *end == 'M')
+ ret *= 1024ULL * 1024ULL;
+ else if (*end == 'g' || *end == 'G')
+ ret *= 1024ULL * 1024ULL * 1024ULL;
+ else if (*end == 't' || *end == 'T')
+ ret *= 1024ULL * 1024ULL * 1024ULL * 1024ULL;
+ else
+ {
+ fprintf(stderr, "Invalid blockdev unit size '%c' in '%s', using default size\n", *end, s);
+ return 0;
+ }
+ return ret;
}
static void usage(const char *me)
{
- printf("Usage: %s [-s] [-B backingstore] [-L size] [-K] [-M] [-H]\n", me);
+ printf("Usage: %s [-s] [-B backingstore] [-L size[unit]] [-K] [-M] [-H]\n", me);
printf(" [-p lxcpath] [-P newlxcpath] orig new\n");
printf("\n");
printf(" -s: snapshot rather than copy\n");
printf(" -B: use specified new backingstore. Default is the same as\n");
printf(" the original. Options include btrfs, lvm, overlayfs, \n");
printf(" dir and loop\n");
- printf(" -L: for blockdev-backed backingstore, use specified size\n");
+ printf(" -L: for blockdev-backed backingstore, use specified size * specified\n");
+ printf(" unit. Default size is the size of the source blockdev, default\n");
+ printf(" unit is MB\n");
printf(" -K: Keep name - do not change the container name\n");
printf(" -M: Keep macaddr - do not choose a random new mac address\n");
printf(" -p: use container orig from custom lxcpath\n");
struct lxc_container *c1 = NULL, *c2 = NULL;
int snapshot = 0, keepname = 0, keepmac = 0;
int flags = 0, option_index;
- long newsize = 0;
+ uint64_t newsize = 0;
char *bdevtype = NULL, *lxcpath = NULL, *newpath = NULL, *fstype = NULL;
char *orig = NULL, *new = NULL, *vgname = NULL;
char **args = NULL;
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
+#include <stdint.h>
#include "lxc.h"
#include "log.h"
lxc_log_define(lxc_create, lxc);
-/* we pass fssize in bytes */
-static unsigned long get_fssize(char *s)
+static uint64_t get_fssize(char *s)
{
- unsigned long ret;
+ uint64_t ret;
char *end;
- ret = strtoul(s, &end, 0);
+ ret = strtoull(s, &end, 0);
if (end == s)
+ {
+ fprintf(stderr, "Invalid blockdev size '%s', using default size\n", s);
return 0;
+ }
while (isblank(*end))
end++;
- if (!(*end))
- return ret;
- if (*end == 'g' || *end == 'G')
- ret *= 1000000000;
- else if (*end == 'm' || *end == 'M')
- ret *= 1000000;
+ if (*end == '\0')
+ ret *= 1024ULL * 1024ULL; // MB by default
+ else if (*end == 'b' || *end == 'B')
+ ret *= 1ULL;
else if (*end == 'k' || *end == 'K')
- ret *= 1000;
+ ret *= 1024ULL;
+ else if (*end == 'm' || *end == 'M')
+ ret *= 1024ULL * 1024ULL;
+ else if (*end == 'g' || *end == 'G')
+ ret *= 1024ULL * 1024ULL * 1024ULL;
+ else if (*end == 't' || *end == 'T')
+ ret *= 1024ULL * 1024ULL * 1024ULL * 1024ULL;
+ else
+ {
+ fprintf(stderr, "Invalid blockdev unit size '%c' in '%s', using default size\n", *end, s);
+ return 0;
+ }
return ret;
}
--lvname=LVNAME Use LVM lv name LVNAME\n\
(Default: container name)\n\
--vgname=VG Use LVM vg called VG\n\
- (Default: lxc))\n\
+ (Default: lxc)\n\
--thinpool=TP Use LVM thin pool called TP\n\
- (Default: lxc))\n\
+ (Default: lxc)\n\
--fstype=TYPE Create fstype TYPE\n\
- (Default: ext3))\n\
- --fssize=SIZE Create filesystem of size SIZE\n\
- (Default: 1G))\n\
+ (Default: ext3)\n\
+ --fssize=SIZE[U] Create filesystem of size SIZE * unit U (bBkKmMgGtT)\n\
+ (Default: 1G, default unit: M)\n\
--dir=DIR Place rootfs directory under DIR\n\
--zfsroot=PATH Create zfs under given zfsroot\n\
- (Default: tank/lxc))\n",
+ (Default: tank/lxc)\n",
.options = my_longopts,
.parser = my_parser,
.checker = NULL,
#include <sched.h>
#include <arpa/inet.h>
#include <libgen.h>
+#include <stdint.h>
#include <lxc/lxccontainer.h>
#include <lxc/version.h>
}
static int copy_storage(struct lxc_container *c0, struct lxc_container *c,
- const char *newtype, int flags, const char *bdevdata, unsigned long newsize)
+ const char *newtype, int flags, const char *bdevdata, uint64_t newsize)
{
struct bdev *bdev;
int need_rdep;
static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *newname,
const char *lxcpath, int flags,
- const char *bdevtype, const char *bdevdata, unsigned long newsize,
+ const char *bdevtype, const char *bdevdata, uint64_t newsize,
char **hookargs)
{
struct lxc_container *c2 = NULL;
#include <semaphore.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <stdint.h>
#include <lxc/attach_options.h>
*/
struct lxc_container *(*clone)(struct lxc_container *c, const char *newname,
const char *lxcpath, int flags, const char *bdevtype,
- const char *bdevdata, unsigned long newsize, char **hookargs);
+ const char *bdevdata, uint64_t newsize, char **hookargs);
/*!
* \brief Allocate a console tty for the container.