int do_luks_kill_slot (const char *device, const char *key, int keyslot) { char *tempfile = write_key_to_temp (key); if (!tempfile) return -1; const char *argv[MAX_ARGS]; char keyslot_s[16]; size_t i = 0; ADD_ARG (argv, i, str_cryptsetup); ADD_ARG (argv, i, "-q"); ADD_ARG (argv, i, "-d"); ADD_ARG (argv, i, tempfile); ADD_ARG (argv, i, "luksKillSlot"); ADD_ARG (argv, i, device); snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot); ADD_ARG (argv, i, keyslot_s); ADD_ARG (argv, i, NULL); char *err; int r = commandv (NULL, &err, (const char * const *) argv); remove_temp (tempfile); if (r == -1) { reply_with_error ("%s", err); free (err); return -1; } free (err); return 0; }
int do_vg_activate (int activate, char *const *volgroups) { int r, i, argc; CLEANUP_FREE char *err = NULL; CLEANUP_FREE const char **argv = NULL; argc = count_strings (volgroups) + 4; argv = malloc (sizeof (char *) * (argc+1)); if (argv == NULL) { reply_with_perror ("malloc"); return -1; } argv[0] = str_lvm; argv[1] = "vgchange"; argv[2] = "-a"; argv[3] = activate ? "y" : "n"; for (i = 4; i < argc+1; ++i) argv[i] = volgroups[i-4]; r = commandv (NULL, &err, (const char * const*) argv); if (r == -1) { reply_with_error ("vgchange: %s", err); return -1; } udev_settle (); return 0; }
/* Internal function used to wipe disks before we do 'mkfs'-type * operations on them. For the rationale see RHBZ#889888 and * RHBZ#907554. * * Note this is really destructive, so only call it just before doing * the 'mkfs' operation (ie. after doing as much pre-checking as * possible). Otherwise you could end up with a 'mkfs' operation * failing with an error but still wiping data. */ void wipe_device_before_mkfs (const char *device) { int force; const size_t MAX_ARGS = 16; const char *argv[MAX_ARGS]; size_t i = 0; force = wipefs_has_force_option (); if (force == -1) return; ADD_ARG (argv, i, str_wipefs); ADD_ARG (argv, i, "-a"); if (force) ADD_ARG (argv, i, "--force"); ADD_ARG (argv, i, device); ADD_ARG (argv, i, NULL); ignore_value (commandv (NULL, NULL, argv)); /* XXX We could fall back to overwriting bits of disk here, but if * they don't have working wipefs, it seems unlikely they are using * btrfs which is what mostly causes this problem. See: * http://www.spinics.net/lists/linux-btrfs/msg21197.html */ }
int do_vgcreate (const char *volgroup, char *const *physvols) { int r, argc, i; CLEANUP_FREE char *err = NULL; CLEANUP_FREE const char **argv = NULL; argc = count_strings (physvols) + 3; argv = malloc (sizeof (char *) * (argc + 1)); if (argv == NULL) { reply_with_perror ("malloc"); return -1; } argv[0] = str_lvm; argv[1] = "vgcreate"; argv[2] = volgroup; for (i = 3; i < argc+1; ++i) argv[i] = physvols[i-3]; r = commandv (NULL, &err, (const char * const*) argv); if (r == -1) { reply_with_error ("%s", err); return -1; } udev_settle (); return 0; }
int do_wipefs (const char *device) { int force; int r; CLEANUP_FREE char *err = NULL; const size_t MAX_ARGS = 16; const char *argv[MAX_ARGS]; size_t i = 0; force = wipefs_has_force_option (); if (force == -1) return -1; ADD_ARG (argv, i, str_wipefs); ADD_ARG (argv, i, "-a"); if (force) ADD_ARG (argv, i, "--force"); ADD_ARG (argv, i, device); ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("%s", err); return -1; } return 0; }
/* List files in the appliance. */ static char * debug_ll (const char *subcmd, size_t argc, char *const *const argv) { const size_t len = guestfs_int_count_strings (argv); CLEANUP_FREE const char **cargv = NULL; size_t i; int r; char *out; CLEANUP_FREE char *err = NULL; cargv = malloc (sizeof (char *) * (len+3)); if (cargv == NULL) { reply_with_perror ("malloc"); return NULL; } cargv[0] = "ls"; cargv[1] = "-la"; for (i = 0; i < len; ++i) cargv[2+i] = argv[i]; cargv[2+len] = NULL; r = commandv (&out, &err, (void *) cargv); if (r == -1) { reply_with_error ("ll: %s", err); free (out); return NULL; } return out; }
/* Takes optional arguments, consult optargs_bitmask. */ int do_ntfsfix (const char *device, int clearbadsectors) { const char *argv[MAX_ARGS]; size_t i = 0; int r; CLEANUP_FREE char *err = NULL; ADD_ARG (argv, i, str_ntfsfix); if ((optargs_bitmask & GUESTFS_NTFSFIX_CLEARBADSECTORS_BITMASK) && clearbadsectors) ADD_ARG (argv, i, "-b"); ADD_ARG (argv, i, device); ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("%s: %s", device, err); return -1; } return 0; }
static int rsync (const char *src, const char *src_orig, const char *dest, const char *dest_orig, int archive, int deletedest) { const char *argv[MAX_ARGS]; size_t i = 0; int r; CLEANUP_FREE char *err = NULL; ADD_ARG (argv, i, str_rsync); if (archive) ADD_ARG (argv, i, "--archive"); if (deletedest) ADD_ARG (argv, i, "--delete"); ADD_ARG (argv, i, src); ADD_ARG (argv, i, dest); ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("'%s' to '%s': %s", src_orig, dest_orig, err); return -1; } return 0; }
int do_vgcreate (const char *volgroup, char *const *physvols) { char *err; int r, argc, i; const char **argv; argc = count_strings (physvols) + 3; argv = malloc (sizeof (char *) * (argc + 1)); if (argv == NULL) { reply_with_perror ("malloc"); return -1; } argv[0] = "lvm"; argv[1] = "vgcreate"; argv[2] = volgroup; for (i = 3; i <= argc; ++i) argv[i] = physvols[i-3]; r = commandv (NULL, &err, (const char * const*) argv); if (r == -1) { reply_with_error ("%s", err); free (err); free (argv); return -1; } free (err); free (argv); udev_settle (); return 0; }
/* List files in the appliance. */ static char * debug_ll (const char *subcmd, size_t argc, char *const *const argv) { size_t len = count_strings (argv); const char *cargv[len+3]; size_t i; int r; char *out; CLEANUP_FREE char *err = NULL; cargv[0] = str_ls; cargv[1] = "-la"; for (i = 0; i < len; ++i) cargv[2+i] = argv[i]; cargv[2+len] = NULL; r = commandv (&out, &err, (void *) cargv); if (r == -1) { reply_with_error ("ll: %s", err); free (out); return NULL; } return out; }
int do_md_stop (const char *md) { int r; CLEANUP_FREE char *err = NULL; const char *mdadm[] = { str_mdadm, "--stop", md, NULL}; r = commandv (NULL, &err, mdadm); if (r == -1) { reply_with_error ("%s", err); return -1; } return 0; }
static int luks_open (const char *device, const char *key, const char *mapname, int readonly) { /* Sanity check: /dev/mapper/mapname must not exist already. Note * that the device-mapper control device (/dev/mapper/control) is * always there, so you can't ever have mapname == "control". */ size_t len = strlen (mapname); char devmapper[len+32]; snprintf (devmapper, len+32, "/dev/mapper/%s", mapname); if (access (devmapper, F_OK) == 0) { reply_with_error ("%s: device already exists", devmapper); return -1; } char *tempfile = write_key_to_temp (key); if (!tempfile) return -1; const char *argv[MAX_ARGS]; size_t i = 0; ADD_ARG (argv, i, str_cryptsetup); ADD_ARG (argv, i, "-d"); ADD_ARG (argv, i, tempfile); if (readonly) ADD_ARG (argv, i, "--readonly"); ADD_ARG (argv, i, "luksOpen"); ADD_ARG (argv, i, device); ADD_ARG (argv, i, mapname); ADD_ARG (argv, i, NULL); char *err; int r = commandv (NULL, &err, (const char * const *) argv); remove_temp (tempfile); if (r == -1) { reply_with_error ("%s", err); free (err); return -1; } free (err); udev_settle (); return 0; }
int do_md_stop(const char *md) { int r; char *err = NULL; const char *mdadm[] = { "mdadm", "--stop", md, NULL}; r = commandv(NULL, &err, mdadm); if (r == -1) { reply_with_error("%s", err); free(err); return -1; } free (err); return 0; }
/* Takes optional arguments, consult optargs_bitmask. */ int do_mkswap (const char *device, const char *label, const char *uuid) { const size_t MAX_ARGS = 64; const char *argv[MAX_ARGS]; size_t i = 0; int r; CLEANUP_FREE char *err = NULL; ADD_ARG (argv, i, "mkswap"); ADD_ARG (argv, i, "-f"); if (optargs_bitmask & GUESTFS_MKSWAP_LABEL_BITMASK) { assert (label != NULL); /* suppress a warning with -O3 */ if (strlen (label) > SWAP_LABEL_MAX) { reply_with_error ("%s: Linux swap labels are limited to %d bytes", label, SWAP_LABEL_MAX); return -1; } ADD_ARG (argv, i, "-L"); ADD_ARG (argv, i, label); } if (optargs_bitmask & GUESTFS_MKSWAP_UUID_BITMASK) { ADD_ARG (argv, i, "-U"); ADD_ARG (argv, i, uuid); } ADD_ARG (argv, i, device); ADD_ARG (argv, i, NULL); wipe_device_before_mkfs (device); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("%s: %s", device, err); return -1; } udev_settle (); return 0; }
static int luks_format (const char *device, const char *key, int keyslot, const char *cipher) { char *tempfile = write_key_to_temp (key); if (!tempfile) return -1; const char *argv[MAX_ARGS]; char keyslot_s[16]; size_t i = 0; ADD_ARG (argv, i, str_cryptsetup); ADD_ARG (argv, i, "-q"); if (cipher) { ADD_ARG (argv, i, "--cipher"); ADD_ARG (argv, i, cipher); } ADD_ARG (argv, i, "--key-slot"); snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot); ADD_ARG (argv, i, keyslot_s); ADD_ARG (argv, i, "luksFormat"); ADD_ARG (argv, i, device); ADD_ARG (argv, i, tempfile); ADD_ARG (argv, i, NULL); char *err; int r = commandv (NULL, &err, (const char * const *) argv); remove_temp (tempfile); if (r == -1) { reply_with_error ("%s", err); free (err); return -1; } free (err); udev_settle (); return 0; }
/* Takes optional arguments, consult optargs_bitmask. */ int do_ntfsresize (const char *device, int64_t size, int force) { char *err; int r; const char *argv[MAX_ARGS]; size_t i = 0; char size_str[32]; ADD_ARG (argv, i, str_ntfsresize); ADD_ARG (argv, i, "-P"); if (optargs_bitmask & GUESTFS_NTFSRESIZE_SIZE_BITMASK) { if (size <= 0) { reply_with_error ("size is zero or negative"); return -1; } snprintf (size_str, sizeof size_str, "%" PRIi64, size); ADD_ARG (argv, i, "--size"); ADD_ARG (argv, i, size_str); } if (optargs_bitmask & GUESTFS_NTFSRESIZE_FORCE_BITMASK && force) ADD_ARG (argv, i, "--force"); ADD_ARG (argv, i, device); ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("%s: %s", device, err); free (err); return -1; } free (err); return 0; }
/* Takes optional arguments, consult optargs_bitmask. */ int do_md_create (const char *name, char *const *devices, int64_t missingbitmap, int nrdevices, int spare, int64_t chunk, const char *level) { char nrdevices_s[32]; char spare_s[32]; char chunk_s[32]; size_t j; int r; char *err; uint64_t umissingbitmap = (uint64_t) missingbitmap; /* Check the optional parameters and set defaults where appropriate. */ if (!(optargs_bitmask & GUESTFS_MD_CREATE_MISSINGBITMAP_BITMASK)) umissingbitmap = 0; if (optargs_bitmask & GUESTFS_MD_CREATE_SPARE_BITMASK) { if (spare < 0) { reply_with_error ("spare must not be negative"); return -1; } } else spare = 0; if (optargs_bitmask & GUESTFS_MD_CREATE_NRDEVICES_BITMASK) { if (nrdevices < 2) { reply_with_error ("nrdevices is less than 2"); return -1; } } else nrdevices = count_strings (devices) + count_bits (umissingbitmap); if (optargs_bitmask & GUESTFS_MD_CREATE_LEVEL_BITMASK) { if (STRNEQ (level, "linear") && STRNEQ (level, "raid0") && STRNEQ (level, "0") && STRNEQ (level, "stripe") && STRNEQ (level, "raid1") && STRNEQ (level, "1") && STRNEQ (level, "mirror") && STRNEQ (level, "raid4") && STRNEQ (level, "4") && STRNEQ (level, "raid5") && STRNEQ (level, "5") && STRNEQ (level, "raid6") && STRNEQ (level, "6") && STRNEQ (level, "raid10") && STRNEQ (level, "10")) { reply_with_error ("unknown level parameter: %s", level); return -1; } } else level = "raid1"; if (optargs_bitmask & GUESTFS_MD_CREATE_CHUNK_BITMASK) { /* chunk is bytes in the libguestfs API, but K when we pass it to mdadm */ if ((chunk & 1023) != 0) { reply_with_error ("chunk size must be a multiple of 1024 bytes"); return -1; } } /* Check invariant. */ if (count_strings (devices) + count_bits (umissingbitmap) != (size_t) (nrdevices + spare)) { reply_with_error ("devices (%zu) + bits set in missingbitmap (%zu) is not equal to nrdevices (%d) + spare (%d)", count_strings (devices), count_bits (umissingbitmap), nrdevices, spare); return -1; } size_t MAX_ARGS = nrdevices + 16; const char *argv[MAX_ARGS]; size_t i = 0; ADD_ARG (argv, i, "mdadm"); ADD_ARG (argv, i, "--create"); /* --run suppresses "Continue creating array" question */ ADD_ARG (argv, i, "--run"); ADD_ARG (argv, i, name); ADD_ARG (argv, i, "--level"); ADD_ARG (argv, i, level); ADD_ARG (argv, i, "--raid-devices"); snprintf (nrdevices_s, sizeof nrdevices_s, "%d", nrdevices); ADD_ARG (argv, i, nrdevices_s); if (optargs_bitmask & GUESTFS_MD_CREATE_SPARE_BITMASK) { ADD_ARG (argv, i, "--spare-devices"); snprintf (spare_s, sizeof spare_s, "%d", spare); ADD_ARG (argv, i, spare_s); } if (optargs_bitmask & GUESTFS_MD_CREATE_CHUNK_BITMASK) { ADD_ARG (argv, i, "--chunk"); snprintf (chunk_s, sizeof chunk_s, "%" PRIi64, chunk / 1024); ADD_ARG (argv, i, chunk_s); } /* Add devices and "missing". */ j = 0; while (devices[j] != NULL || umissingbitmap != 0) { if (umissingbitmap & 1) ADD_ARG (argv, i, "missing"); else { ADD_ARG (argv, i, devices[j]); j++; } umissingbitmap >>= 1; } ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("mdadm: %s: %s", name, err); free (err); return -1; } free (err); udev_settle (); return 0; }
/* Takes optional arguments, consult optargs_bitmask. */ int do_tune2fs (const char *device, /* only required parameter */ int force, int maxmountcount, int mountcount, const char *errorbehavior, int64_t group, int intervalbetweenchecks, int reservedblockspercentage, const char *lastmounteddirectory, int64_t reservedblockscount, int64_t user) { const char *argv[MAX_ARGS]; size_t i = 0; int r; CLEANUP_FREE char *err = NULL; char maxmountcount_s[64]; char mountcount_s[64]; char group_s[64]; char intervalbetweenchecks_s[64]; char reservedblockspercentage_s[64]; char reservedblockscount_s[64]; char user_s[64]; ADD_ARG (argv, i, str_tune2fs); if (optargs_bitmask & GUESTFS_TUNE2FS_FORCE_BITMASK) { if (force) ADD_ARG (argv, i, "-f"); } if (optargs_bitmask & GUESTFS_TUNE2FS_MAXMOUNTCOUNT_BITMASK) { if (maxmountcount < 0) { reply_with_error ("maxmountcount cannot be negative"); return -1; } ADD_ARG (argv, i, "-c"); snprintf (maxmountcount_s, sizeof maxmountcount_s, "%d", maxmountcount); ADD_ARG (argv, i, maxmountcount_s); } if (optargs_bitmask & GUESTFS_TUNE2FS_MOUNTCOUNT_BITMASK) { if (mountcount < 0) { reply_with_error ("mountcount cannot be negative"); return -1; } ADD_ARG (argv, i, "-C"); snprintf (mountcount_s, sizeof mountcount_s, "%d", mountcount); ADD_ARG (argv, i, mountcount_s); } if (optargs_bitmask & GUESTFS_TUNE2FS_ERRORBEHAVIOR_BITMASK) { if (STRNEQ (errorbehavior, "continue") && STRNEQ (errorbehavior, "remount-ro") && STRNEQ (errorbehavior, "panic")) { reply_with_error ("invalid errorbehavior parameter: %s", errorbehavior); return -1; } ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, errorbehavior); } if (optargs_bitmask & GUESTFS_TUNE2FS_GROUP_BITMASK) { if (group < 0) { reply_with_error ("group cannot be negative"); return -1; } ADD_ARG (argv, i, "-g"); snprintf (group_s, sizeof group_s, "%" PRIi64, group); ADD_ARG (argv, i, group_s); } if (optargs_bitmask & GUESTFS_TUNE2FS_INTERVALBETWEENCHECKS_BITMASK) { if (intervalbetweenchecks < 0) { reply_with_error ("intervalbetweenchecks cannot be negative"); return -1; } ADD_ARG (argv, i, "-i"); if (intervalbetweenchecks > 0) { /* -i <NN>s is not documented in the man page, but has been * supported in tune2fs for several years. */ snprintf (intervalbetweenchecks_s, sizeof intervalbetweenchecks_s, "%ds", intervalbetweenchecks); ADD_ARG (argv, i, intervalbetweenchecks_s); } else ADD_ARG (argv, i, "0"); } if (optargs_bitmask & GUESTFS_TUNE2FS_RESERVEDBLOCKSPERCENTAGE_BITMASK) { if (reservedblockspercentage < 0) { reply_with_error ("reservedblockspercentage cannot be negative"); return -1; } ADD_ARG (argv, i, "-m"); snprintf (reservedblockspercentage_s, sizeof reservedblockspercentage_s, "%d", reservedblockspercentage); ADD_ARG (argv, i, reservedblockspercentage_s); } if (optargs_bitmask & GUESTFS_TUNE2FS_LASTMOUNTEDDIRECTORY_BITMASK) { ADD_ARG (argv, i, "-M"); ADD_ARG (argv, i, lastmounteddirectory); } if (optargs_bitmask & GUESTFS_TUNE2FS_RESERVEDBLOCKSCOUNT_BITMASK) { if (reservedblockscount < 0) { reply_with_error ("reservedblockscount cannot be negative"); return -1; } ADD_ARG (argv, i, "-r"); snprintf (reservedblockscount_s, sizeof reservedblockscount_s, "%" PRIi64, reservedblockscount); ADD_ARG (argv, i, reservedblockscount_s); } if (optargs_bitmask & GUESTFS_TUNE2FS_USER_BITMASK) { if (user < 0) { reply_with_error ("user cannot be negative"); return -1; } ADD_ARG (argv, i, "-u"); snprintf (user_s, sizeof user_s, "%" PRIi64, user); ADD_ARG (argv, i, user_s); } ADD_ARG (argv, i, device); ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("%s: %s", device, err); return -1; } return 0; }
int do_mke2fs (const char *device, /* 0 */ int64_t blockscount, int64_t blocksize, int64_t fragsize, int64_t blockspergroup, int64_t numberofgroups, /* 5 */ int64_t bytesperinode, int64_t inodesize, int64_t journalsize, int64_t numberofinodes, int64_t stridesize, /* 10 */ int64_t stripewidth, int64_t maxonlineresize, int reservedblockspercentage, int mmpupdateinterval, const char *journaldevice, /* 15 */ const char *label, const char *lastmounteddir, const char *creatoros, const char *fstype, const char *usagetype, /* 20 */ const char *uuid, int forcecreate, int writesbandgrouponly, int lazyitableinit, int lazyjournalinit, /* 25 */ int testfs, int discard, int quotatype, int extent, int filetype, /* 30 */ int flexbg, int hasjournal, int journaldev, int largefile, int quota, /* 35 */ int resizeinode, int sparsesuper, int uninitbg) { int r; CLEANUP_FREE char *err = NULL; const char *argv[MAX_ARGS]; char blockscount_s[64]; char blocksize_s[64]; char fragsize_s[64]; char blockspergroup_s[64]; char numberofgroups_s[64]; char bytesperinode_s[64]; char inodesize_s[64]; char journalsize_s[64]; CLEANUP_FREE char *journaldevice_translated = NULL; CLEANUP_FREE char *journaldevice_s = NULL; char reservedblockspercentage_s[64]; char numberofinodes_s[64]; char mmpupdateinterval_s[84]; char stridesize_s[74]; char stripewidth_s[84]; char maxonlineresize_s[74]; size_t i = 0; ADD_ARG (argv, i, str_mke2fs); if (optargs_bitmask & GUESTFS_MKE2FS_BLOCKSIZE_BITMASK) { if (blocksize < 0) { reply_with_error ("blocksize must be >= 0"); return -1; } snprintf (blocksize_s, sizeof blocksize_s, "%" PRIi64, blocksize); ADD_ARG (argv, i, "-b"); ADD_ARG (argv, i, blocksize_s); } if (optargs_bitmask & GUESTFS_MKE2FS_FRAGSIZE_BITMASK) { if (fragsize < 0) { reply_with_error ("fragsize must be >= 0"); return -1; } snprintf (fragsize_s, sizeof fragsize_s, "%" PRIi64, fragsize); ADD_ARG (argv, i, "-f"); ADD_ARG (argv, i, fragsize_s); } if (optargs_bitmask & GUESTFS_MKE2FS_FORCECREATE_BITMASK) { if (forcecreate) ADD_ARG (argv, i, "-F"); } if (optargs_bitmask & GUESTFS_MKE2FS_BLOCKSPERGROUP_BITMASK) { if (blockspergroup < 0) { reply_with_error ("blockspergroup must be >= 0"); return -1; } snprintf (blockspergroup_s, sizeof blockspergroup_s, "%" PRIi64, blockspergroup); ADD_ARG (argv, i, "-g"); ADD_ARG (argv, i, blockspergroup_s); } if (optargs_bitmask & GUESTFS_MKE2FS_NUMBEROFGROUPS_BITMASK) { if (numberofgroups < 0) { reply_with_error ("numberofgroups must be >= 0"); return -1; } snprintf (numberofgroups_s, sizeof numberofgroups_s, "%" PRIi64, numberofgroups); ADD_ARG (argv, i, "-G"); ADD_ARG (argv, i, numberofgroups_s); } if (optargs_bitmask & GUESTFS_MKE2FS_BYTESPERINODE_BITMASK) { if (bytesperinode < 0) { reply_with_error ("bytesperinode must be >= 0"); return -1; } snprintf (bytesperinode_s, sizeof bytesperinode_s, "%" PRIi64, bytesperinode); ADD_ARG (argv, i, "-i"); ADD_ARG (argv, i, bytesperinode_s); } if (optargs_bitmask & GUESTFS_MKE2FS_INODESIZE_BITMASK) { if (inodesize < 0) { reply_with_error ("inodesize must be >= 0"); return -1; } snprintf (inodesize_s, sizeof inodesize_s, "%" PRIi64, inodesize); ADD_ARG (argv, i, "-I"); ADD_ARG (argv, i, inodesize_s); } if (optargs_bitmask & GUESTFS_MKE2FS_JOURNALSIZE_BITMASK) { if (journalsize < 0) { reply_with_error ("journalsize must be >= 0"); return -1; } snprintf (journalsize_s, sizeof journalsize_s, "size=" "%" PRIi64, journalsize); ADD_ARG (argv, i, "-J"); ADD_ARG (argv, i, journalsize_s); } if (optargs_bitmask & GUESTFS_MKE2FS_JOURNALDEVICE_BITMASK) { if (journaldevice) { /* OString doesn't do device name translation (RHBZ#876579). We * have to do it manually here, but note that LABEL=.. and * UUID=.. are valid strings which do not require translation. */ if (STRPREFIX (journaldevice, "/dev/")) { if (is_root_device (journaldevice)) { reply_with_error ("%s: device not found", journaldevice); return -1; } journaldevice_translated = device_name_translation (journaldevice); if (journaldevice_translated == NULL) { reply_with_perror ("%s", journaldevice); return -1; } journaldevice_s = malloc (strlen (journaldevice_translated) + 8); if (!journaldevice_s) { reply_with_perror ("malloc"); return -1; } sprintf (journaldevice_s, "device=%s", journaldevice_translated); } else { journaldevice_s = malloc (strlen (journaldevice) + 8); if (!journaldevice_s) { reply_with_perror ("malloc"); return -1; } sprintf (journaldevice_s, "device=%s", journaldevice); } ADD_ARG (argv, i, "-J"); ADD_ARG (argv, i, journaldevice_s); } } if (optargs_bitmask & GUESTFS_MKE2FS_LABEL_BITMASK) { if (label) { ADD_ARG (argv, i, "-L"); ADD_ARG (argv, i, label); } } if (optargs_bitmask & GUESTFS_MKE2FS_RESERVEDBLOCKSPERCENTAGE_BITMASK) { if (reservedblockspercentage < 0) { reply_with_error ("reservedblockspercentage must be >= 0"); return -1; } snprintf (reservedblockspercentage_s, sizeof reservedblockspercentage_s, "%" PRIi32, reservedblockspercentage); ADD_ARG (argv, i, "-m"); ADD_ARG (argv, i, reservedblockspercentage_s); } if (optargs_bitmask & GUESTFS_MKE2FS_LASTMOUNTEDDIR_BITMASK) { if (lastmounteddir) { ADD_ARG (argv, i, "-M"); ADD_ARG (argv, i, lastmounteddir); } } if (optargs_bitmask & GUESTFS_MKE2FS_NUMBEROFINODES_BITMASK) { if (numberofinodes < 0) { reply_with_error ("numberofinodes must be >= 0"); return -1; } snprintf (numberofinodes_s, sizeof numberofinodes_s, "%" PRIi64, numberofinodes); ADD_ARG (argv, i, "-N"); ADD_ARG (argv, i, numberofinodes_s); } if (optargs_bitmask & GUESTFS_MKE2FS_CREATOROS_BITMASK) { if (creatoros) { ADD_ARG (argv, i, "-o"); ADD_ARG (argv, i, creatoros); } } if (optargs_bitmask & GUESTFS_MKE2FS_WRITESBANDGROUPONLY_BITMASK) { if (writesbandgrouponly) ADD_ARG (argv, i, "-S"); } if (optargs_bitmask & GUESTFS_MKE2FS_FSTYPE_BITMASK) { if (fstype) { if (!fstype_is_extfs (fstype)) { reply_with_error ("%s: not a valid extended filesystem type", fstype); return -1; } ADD_ARG (argv, i, "-t"); ADD_ARG (argv, i, fstype); } } if (optargs_bitmask & GUESTFS_MKE2FS_USAGETYPE_BITMASK) { if (usagetype) { ADD_ARG (argv, i, "-T"); ADD_ARG (argv, i, usagetype); } } if (optargs_bitmask & GUESTFS_MKE2FS_UUID_BITMASK) { if (uuid) { ADD_ARG (argv, i, "-U"); ADD_ARG (argv, i, uuid); } } if (optargs_bitmask & GUESTFS_MKE2FS_MMPUPDATEINTERVAL_BITMASK) { if (mmpupdateinterval < 0) { reply_with_error ("mmpupdateinterval must be >= 0"); return -1; } snprintf (mmpupdateinterval_s, sizeof mmpupdateinterval_s, "mmp_update_interval=" "%" PRIi32, mmpupdateinterval); ADD_ARG (argv, i, "-E"); ADD_ARG (argv, i, mmpupdateinterval_s); } if (optargs_bitmask & GUESTFS_MKE2FS_STRIDESIZE_BITMASK) { if (stridesize < 0) { reply_with_error ("stridesize must be >= 0"); return -1; } snprintf (stridesize_s, sizeof stridesize_s, "stride=" "%" PRIi64, stridesize); ADD_ARG (argv, i, "-E"); ADD_ARG (argv, i, stridesize_s); } if (optargs_bitmask & GUESTFS_MKE2FS_STRIPEWIDTH_BITMASK) { if (stripewidth< 0) { reply_with_error ("stripewidth must be >= 0"); return -1; } snprintf (stripewidth_s, sizeof stripewidth_s, "stripe_width=" "%" PRIi64, stripewidth); ADD_ARG (argv, i, "-E"); ADD_ARG (argv, i, stripewidth_s); } if (optargs_bitmask & GUESTFS_MKE2FS_MAXONLINERESIZE_BITMASK) { if (maxonlineresize < 0) { reply_with_error ("maxonlineresize must be >= 0"); return -1; } snprintf (maxonlineresize_s, sizeof maxonlineresize_s, "resize=" "%" PRIi64, maxonlineresize); ADD_ARG (argv, i, "-E"); ADD_ARG (argv, i, maxonlineresize_s); } if (optargs_bitmask & GUESTFS_MKE2FS_LAZYITABLEINIT_BITMASK) { ADD_ARG (argv, i, "-E"); if (lazyitableinit) ADD_ARG (argv, i, "lazy_itable_init=1"); else ADD_ARG (argv, i, "lazy_itable_init=0"); } if (optargs_bitmask & GUESTFS_MKE2FS_LAZYJOURNALINIT_BITMASK) { ADD_ARG (argv, i, "-E"); if (lazyjournalinit) ADD_ARG (argv, i, "lazy_journal_init=1"); else ADD_ARG (argv, i, "lazy_journal_init=0"); } if (optargs_bitmask & GUESTFS_MKE2FS_TESTFS_BITMASK) { if (testfs) { ADD_ARG (argv, i, "-E"); ADD_ARG (argv, i, "test_fs"); } } if (optargs_bitmask & GUESTFS_MKE2FS_DISCARD_BITMASK) { ADD_ARG (argv, i, "-E"); if (discard) ADD_ARG (argv, i, "discard"); else ADD_ARG (argv, i, "nodiscard"); } if (optargs_bitmask & GUESTFS_MKE2FS_EXTENT_BITMASK) { ADD_ARG (argv, i, "-O"); if (extent) ADD_ARG (argv, i, "extent"); else ADD_ARG (argv, i, "^extent"); } if (optargs_bitmask & GUESTFS_MKE2FS_FILETYPE_BITMASK) { ADD_ARG (argv, i, "-O"); if (filetype) ADD_ARG (argv, i, "filetype"); else ADD_ARG (argv, i, "^filetype"); } if (optargs_bitmask & GUESTFS_MKE2FS_FLEXBG_BITMASK) { ADD_ARG (argv, i, "-O"); if (flexbg) ADD_ARG (argv, i, "flexbg"); else ADD_ARG (argv, i, "^flexbg"); } if (optargs_bitmask & GUESTFS_MKE2FS_HASJOURNAL_BITMASK) { ADD_ARG (argv, i, "-O"); if (hasjournal) ADD_ARG (argv, i, "has_journal"); else ADD_ARG (argv, i, "^has_journal"); } if (optargs_bitmask & GUESTFS_MKE2FS_JOURNALDEV_BITMASK) { ADD_ARG (argv, i, "-O"); if (journaldev) ADD_ARG (argv, i, "journal_dev"); else ADD_ARG (argv, i, "^journal_dev"); } if (optargs_bitmask & GUESTFS_MKE2FS_LARGEFILE_BITMASK) { ADD_ARG (argv, i, "-O"); if (largefile) ADD_ARG (argv, i, "large_file"); else ADD_ARG (argv, i, "^large_file"); } if (optargs_bitmask & GUESTFS_MKE2FS_QUOTA_BITMASK) { ADD_ARG (argv, i, "-O"); if (quota) ADD_ARG (argv, i, "quota"); else ADD_ARG (argv, i, "^quota"); } if (optargs_bitmask & GUESTFS_MKE2FS_RESIZEINODE_BITMASK) { ADD_ARG (argv, i, "-O"); if (resizeinode) ADD_ARG (argv, i, "resize_inode"); else ADD_ARG (argv, i, "^resize_inode"); } if (optargs_bitmask & GUESTFS_MKE2FS_SPARSESUPER_BITMASK) { ADD_ARG (argv, i, "-O"); if (sparsesuper) ADD_ARG (argv, i, "sparse_super"); else ADD_ARG (argv, i, "^sparse_super"); } if (optargs_bitmask & GUESTFS_MKE2FS_UNINITBG_BITMASK) { ADD_ARG (argv, i, "-O"); if (uninitbg) ADD_ARG (argv, i, "uninit_bg"); else ADD_ARG (argv, i, "^uninit_bg"); } ADD_ARG (argv, i, device); if (optargs_bitmask & GUESTFS_MKE2FS_BLOCKSCOUNT_BITMASK) { if (blockscount < 0) { reply_with_error ("blockscount must be >= 0"); return -1; } snprintf (blockscount_s, sizeof blockscount_s, "%" PRIi64, blockscount); ADD_ARG (argv, i, blockscount_s); } ADD_ARG (argv, i, NULL); wipe_device_before_mkfs (device); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("%s: %s", device, err); return -1; } return 0; }
/* Takes optional arguments, consult optargs_bitmask. */ int do_mkfs_opts (const char *fstype, const char *device, int blocksize, const char *features, int inode, int sectorsize) { const char *argv[MAX_ARGS]; size_t i = 0; char blocksize_str[32]; char inode_str[32]; char sectorsize_str[32]; int r; char *err; char mke2fs[] = "mke2fs"; int extfs = 0; if (STREQ (fstype, "ext2") || STREQ (fstype, "ext3") || STREQ (fstype, "ext4")) extfs = 1; /* For ext2/3/4 run the mke2fs program directly. This is because * the mkfs program "eats" some options, in particular the -F * option. */ if (extfs) { if (e2prog (mke2fs) == -1) return -1; ADD_ARG (argv, i, mke2fs); } else ADD_ARG (argv, i, "mkfs"); ADD_ARG (argv, i, "-t"); ADD_ARG (argv, i, fstype); /* Force mke2fs to create a filesystem, even if it thinks it * shouldn't (RHBZ#690819). */ if (extfs) ADD_ARG (argv, i, "-F"); /* mkfs.ntfs requires the -Q argument otherwise it writes zeroes * to every block and does bad block detection, neither of which * are useful behaviour for virtual devices. */ if (STREQ (fstype, "ntfs")) ADD_ARG (argv, i, "-Q"); /* mkfs.reiserfs produces annoying interactive prompts unless you * tell it to be quiet. * mkfs.jfs is the same * mkfs.xfs must force to make xfs filesystem when the device already * has a filesystem on it */ if (STREQ (fstype, "reiserfs") || STREQ (fstype, "jfs") || STREQ (fstype, "xfs")) ADD_ARG(argv, i, "-f"); /* For GFS, GFS2, assume a single node. */ if (STREQ (fstype, "gfs") || STREQ (fstype, "gfs2")) { ADD_ARG (argv, i, "-p"); ADD_ARG (argv, i, "lock_nolock"); /* The man page says this is default, but it doesn't seem to be: */ ADD_ARG (argv, i, "-j"); ADD_ARG (argv, i, "1"); /* Don't ask questions: */ ADD_ARG (argv, i, "-O"); } /* Process blocksize parameter if set. */ if (optargs_bitmask & GUESTFS_MKFS_OPTS_BLOCKSIZE_BITMASK) { if (blocksize <= 0 || !is_power_of_2 (blocksize)) { reply_with_error ("block size must be > 0 and a power of 2"); return -1; } if (STREQ (fstype, "vfat") || STREQ (fstype, "msdos")) { /* For VFAT map the blocksize into a cluster size. However we * have to determine the block device sector size in order to do * this. */ int sectorsize = do_blockdev_getss (device); if (sectorsize == -1) return -1; int sectors_per_cluster = blocksize / sectorsize; if (sectors_per_cluster < 1 || sectors_per_cluster > 128) { reply_with_error ("unsupported cluster size for %s filesystem (requested cluster size = %d, sector size = %d, trying sectors per cluster = %d)", fstype, blocksize, sectorsize, sectors_per_cluster); return -1; } snprintf (blocksize_str, sizeof blocksize_str, "%d", sectors_per_cluster); ADD_ARG (argv, i, "-s"); ADD_ARG (argv, i, blocksize_str); } else if (STREQ (fstype, "ntfs")) { /* For NTFS map the blocksize into a cluster size. */ snprintf (blocksize_str, sizeof blocksize_str, "%d", blocksize); ADD_ARG (argv, i, "-c"); ADD_ARG (argv, i, blocksize_str); } else { /* For all other filesystem types, try the -b option. */ snprintf (blocksize_str, sizeof blocksize_str, "%d", blocksize); ADD_ARG (argv, i, "-b"); ADD_ARG (argv, i, blocksize_str); } } if (optargs_bitmask & GUESTFS_MKFS_OPTS_FEATURES_BITMASK) { ADD_ARG (argv, i, "-O"); ADD_ARG (argv, i, features); } if (optargs_bitmask & GUESTFS_MKFS_OPTS_INODE_BITMASK) { if (!extfs) { reply_with_error ("inode size (-I) can only be set on ext2/3/4 filesystems"); return -1; } if (inode <= 0) { reply_with_error ("inode size must be larger than zero"); return -1; } snprintf (inode_str, sizeof inode_str, "%d", inode); ADD_ARG (argv, i, "-I"); ADD_ARG (argv, i, inode_str); } if (optargs_bitmask & GUESTFS_MKFS_OPTS_SECTORSIZE_BITMASK) { if (!STREQ (fstype, "ufs")) { reply_with_error ("sector size (-S) can only be set on ufs filesystems"); return -1; } if (sectorsize <= 0) { reply_with_error ("sector size must be larger than zero"); return -1; } snprintf (sectorsize_str, sizeof sectorsize_str, "%d", sectorsize); ADD_ARG (argv, i, "-S"); ADD_ARG (argv, i, sectorsize_str); } ADD_ARG (argv, i, device); ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("%s: %s: %s", fstype, device, err); free (err); return -1; } free (err); return 0; }
char * do_command (char *const *argv) { char *out; CLEANUP_FREE char *err = NULL; int r; CLEANUP_BIND_STATE struct bind_state bind_state = { .mounted = false }; CLEANUP_RESOLVER_STATE struct resolver_state resolver_state = { .mounted = false }; /* We need a root filesystem mounted to do this. */ NEED_ROOT (, return NULL); /* Conveniently, argv is already a NULL-terminated argv-style array * of parameters, so we can pass it straight in to our internal * commandv. We just have to check the list is non-empty. */ if (argv[0] == NULL) { reply_with_error ("passed an empty list"); return NULL; } if (bind_mount (&bind_state) == -1) return NULL; if (enable_network) { if (set_up_etc_resolv_conf (&resolver_state) == -1) return NULL; } CHROOT_IN; r = commandv (&out, &err, (const char * const *) argv); CHROOT_OUT; free_bind_state (&bind_state); free_resolver_state (&resolver_state); if (r == -1) { reply_with_error ("%s", err); free (out); return NULL; } return out; /* Caller frees. */ } char ** do_command_lines (char *const *argv) { CLEANUP_FREE char *out = NULL; char **lines; out = do_command (argv); if (out == NULL) return NULL; lines = split_lines (out); if (lines == NULL) return NULL; return lines; /* Caller frees. */ } char * do_sh (const char *cmd) { const char *argv[] = { "/bin/sh", "-c", cmd, NULL }; return do_command ((char **) argv); } char ** do_sh_lines (const char *cmd) { const char *argv[] = { "/bin/sh", "-c", cmd, NULL }; return do_command_lines ((char **) argv); }
int do_xfs_admin (const char *device, int extunwritten, int imgfile, int v2log, int projid32bit, int lazycounter, const char *label, const char *uuid) { int r; CLEANUP_FREE char *err = NULL; const char *argv[MAX_ARGS]; size_t i = 0; ADD_ARG (argv, i, str_xfs_admin); /* Optional arguments */ if (!(optargs_bitmask & GUESTFS_XFS_ADMIN_EXTUNWRITTEN_BITMASK)) extunwritten = 0; if (!(optargs_bitmask & GUESTFS_XFS_ADMIN_IMGFILE_BITMASK)) imgfile = 0; if (!(optargs_bitmask & GUESTFS_XFS_ADMIN_V2LOG_BITMASK)) v2log = 0; if (!(optargs_bitmask & GUESTFS_XFS_ADMIN_PROJID32BIT_BITMASK)) projid32bit = 0; if (extunwritten) ADD_ARG (argv, i, "-e"); if (imgfile) ADD_ARG (argv, i, "-f"); if (v2log) ADD_ARG (argv, i, "-j"); if (projid32bit) ADD_ARG (argv, i, "-p"); if (optargs_bitmask & GUESTFS_XFS_ADMIN_LAZYCOUNTER_BITMASK) { if (lazycounter) { ADD_ARG (argv, i, "-c"); ADD_ARG (argv, i, "1"); } else { ADD_ARG (argv, i, "-c"); ADD_ARG (argv, i, "0"); } } if (optargs_bitmask & GUESTFS_XFS_ADMIN_LABEL_BITMASK) { if (strlen (label) > XFS_LABEL_MAX) { reply_with_error ("%s: xfs labels are limited to %d bytes", label, XFS_LABEL_MAX); return -1; } ADD_ARG (argv, i, "-L"); ADD_ARG (argv, i, label); } if (optargs_bitmask & GUESTFS_XFS_ADMIN_UUID_BITMASK) { ADD_ARG (argv, i, "-U"); ADD_ARG (argv, i, uuid); } ADD_ARG (argv, i, device); ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("%s: %s", device, err); return -1; } return 0; }
/* Takes optional arguments, consult optargs_bitmask. */ int do_mkfs (const char *fstype, const char *device, int blocksize, const char *features, int inode, int sectorsize, const char *label) { const char *argv[MAX_ARGS]; size_t i = 0; char blocksize_str[32]; char inode_str[32]; char sectorsize_str[32]; int r; CLEANUP_FREE char *err = NULL; int extfs = 0; if (fstype_is_extfs (fstype)) extfs = 1; /* For ext2/3/4 run the mke2fs program directly. This is because * the mkfs program "eats" some options, in particular the -F * option. */ if (extfs) ADD_ARG (argv, i, str_mke2fs); else ADD_ARG (argv, i, str_mkfs); ADD_ARG (argv, i, "-t"); ADD_ARG (argv, i, fstype); /* Force mke2fs to create a filesystem, even if it thinks it * shouldn't (RHBZ#690819). */ if (extfs) ADD_ARG (argv, i, "-F"); /* mkfs.ntfs requires the -Q argument otherwise it writes zeroes to * every block and does bad block detection, neither of which are * useful behaviour for virtual devices. Also recent versions need * to be forced to create filesystems on non-partitions. */ if (STREQ (fstype, "ntfs")) { ADD_ARG (argv, i, "-Q"); ADD_ARG (argv, i, "-F"); } /* mkfs.reiserfs produces annoying interactive prompts unless you * tell it to be quiet. * mkfs.jfs is the same * mkfs.xfs must force to make xfs filesystem when the device already * has a filesystem on it */ if (STREQ (fstype, "reiserfs") || STREQ (fstype, "jfs") || STREQ (fstype, "xfs")) ADD_ARG (argv, i, "-f"); /* For GFS, GFS2, assume a single node. */ if (STREQ (fstype, "gfs") || STREQ (fstype, "gfs2")) { ADD_ARG (argv, i, "-p"); ADD_ARG (argv, i, "lock_nolock"); /* The man page says this is default, but it doesn't seem to be: */ ADD_ARG (argv, i, "-j"); ADD_ARG (argv, i, "1"); /* Don't ask questions: */ ADD_ARG (argv, i, "-O"); } /* Force mkfs.fat to create a whole disk filesystem (RHBZ#1039995). */ if (STREQ (fstype, "fat") || STREQ (fstype, "vfat") || STREQ (fstype, "msdos")) ADD_ARG (argv, i, "-I"); /* Process blocksize parameter if set. */ if (optargs_bitmask & GUESTFS_MKFS_BLOCKSIZE_BITMASK) { if (blocksize <= 0 || !is_power_of_2 (blocksize)) { reply_with_error ("block size must be > 0 and a power of 2"); return -1; } if (STREQ (fstype, "vfat") || STREQ (fstype, "msdos")) { /* For VFAT map the blocksize into a cluster size. However we * have to determine the block device sector size in order to do * this. */ int ss = do_blockdev_getss (device); if (ss == -1) return -1; int sectors_per_cluster = blocksize / ss; if (sectors_per_cluster < 1 || sectors_per_cluster > 128) { reply_with_error ("unsupported cluster size for %s filesystem (requested cluster size = %d, sector size = %d, trying sectors per cluster = %d)", fstype, blocksize, ss, sectors_per_cluster); return -1; } snprintf (blocksize_str, sizeof blocksize_str, "%d", sectors_per_cluster); ADD_ARG (argv, i, "-s"); ADD_ARG (argv, i, blocksize_str); } else if (STREQ (fstype, "ntfs")) { /* For NTFS map the blocksize into a cluster size. */ snprintf (blocksize_str, sizeof blocksize_str, "%d", blocksize); ADD_ARG (argv, i, "-c"); ADD_ARG (argv, i, blocksize_str); } else if (STREQ (fstype, "btrfs")) { /* For btrfs, blocksize cannot be specified (RHBZ#807905). */ reply_with_error ("blocksize cannot be set on btrfs filesystems, use 'mkfs-btrfs'"); return -1; } else if (STREQ (fstype, "xfs")) { /* mkfs -t xfs -b size=<size> (RHBZ#981715). */ snprintf (blocksize_str, sizeof blocksize_str, "size=%d", blocksize); ADD_ARG (argv, i, "-b"); ADD_ARG (argv, i, blocksize_str); } else { /* For all other filesystem types, try the -b option. */ snprintf (blocksize_str, sizeof blocksize_str, "%d", blocksize); ADD_ARG (argv, i, "-b"); ADD_ARG (argv, i, blocksize_str); } } if (optargs_bitmask & GUESTFS_MKFS_FEATURES_BITMASK) { ADD_ARG (argv, i, "-O"); ADD_ARG (argv, i, features); } if (optargs_bitmask & GUESTFS_MKFS_INODE_BITMASK) { if (!extfs) { reply_with_error ("inode size (-I) can only be set on ext2/3/4 filesystems"); return -1; } if (inode <= 0) { reply_with_error ("inode size must be larger than zero"); return -1; } snprintf (inode_str, sizeof inode_str, "%d", inode); ADD_ARG (argv, i, "-I"); ADD_ARG (argv, i, inode_str); } if (optargs_bitmask & GUESTFS_MKFS_SECTORSIZE_BITMASK) { if (!STREQ (fstype, "ufs")) { reply_with_error ("sector size (-S) can only be set on ufs filesystems"); return -1; } if (sectorsize <= 0) { reply_with_error ("sector size must be larger than zero"); return -1; } snprintf (sectorsize_str, sizeof sectorsize_str, "%d", sectorsize); ADD_ARG (argv, i, "-S"); ADD_ARG (argv, i, sectorsize_str); } if (optargs_bitmask & GUESTFS_MKFS_LABEL_BITMASK) { if (extfs) { if (strlen (label) > EXT2_LABEL_MAX) { reply_with_error ("%s: ext2/3/4 labels are limited to %d bytes", label, EXT2_LABEL_MAX); return -1; } ADD_ARG (argv, i, "-L"); ADD_ARG (argv, i, label); } else if (STREQ (fstype, "fat") || STREQ (fstype, "vfat") || STREQ (fstype, "msdos")) { ADD_ARG (argv, i, "-n"); ADD_ARG (argv, i, label); } else if (STREQ (fstype, "ntfs")) { ADD_ARG (argv, i, "-L"); ADD_ARG (argv, i, label); } else if (STREQ (fstype, "xfs")) { if (strlen (label) > XFS_LABEL_MAX) { reply_with_error ("%s: xfs labels are limited to %d bytes", label, XFS_LABEL_MAX); return -1; } ADD_ARG (argv, i, "-L"); ADD_ARG (argv, i, label); } else if (STREQ (fstype, "btrfs")) { ADD_ARG (argv, i, "-L"); ADD_ARG (argv, i, label); } else { reply_with_error ("don't know how to set the label for '%s' filesystems", fstype); return -1; } } ADD_ARG (argv, i, device); ADD_ARG (argv, i, NULL); wipe_device_before_mkfs (device); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("%s: %s: %s", fstype, device, err); return -1; } return 0; }
int do_xfs_growfs (const char *path, int datasec, int logsec, int rtsec, int64_t datasize, int64_t logsize, int64_t rtsize, int64_t rtextsize, int32_t maxpct) { int r; CLEANUP_FREE char *buf = NULL, *err = NULL; const char *argv[MAX_ARGS]; char datasize_s[64]; char logsize_s[64]; char rtsize_s[64]; char rtextsize_s[64]; char maxpct_s[32]; size_t i = 0; buf = sysroot_path (path); if (buf == NULL) { reply_with_perror ("malloc"); return -1; } ADD_ARG (argv, i, str_xfs_growfs); /* Optional arguments */ if (!(optargs_bitmask & GUESTFS_XFS_GROWFS_DATASEC_BITMASK)) datasec = 0; if (!(optargs_bitmask & GUESTFS_XFS_GROWFS_LOGSEC_BITMASK)) logsec = 0; if (!(optargs_bitmask & GUESTFS_XFS_GROWFS_RTSEC_BITMASK)) rtsec = 0; if (datasec) ADD_ARG (argv, i, "-d"); if (logsec) ADD_ARG (argv, i, "-l"); if (rtsec) ADD_ARG (argv, i, "-r"); if (optargs_bitmask & GUESTFS_XFS_GROWFS_DATASIZE_BITMASK) { if (datasize < 0) { reply_with_error ("datasize must be >= 0"); return -1; } snprintf (datasize_s, sizeof datasize_s, "%" PRIi64, datasize); ADD_ARG (argv, i, "-D"); ADD_ARG (argv, i, datasize_s); } if (optargs_bitmask & GUESTFS_XFS_GROWFS_LOGSIZE_BITMASK) { if (logsize < 0) { reply_with_error ("logsize must be >= 0"); return -1; } snprintf (logsize_s, sizeof logsize_s, "%" PRIi64, logsize); ADD_ARG (argv, i, "-L"); ADD_ARG (argv, i, logsize_s); } if (optargs_bitmask & GUESTFS_XFS_GROWFS_RTSIZE_BITMASK) { if (rtsize < 0) { reply_with_error ("rtsize must be >= 0"); return -1; } snprintf (rtsize_s, sizeof rtsize_s, "%" PRIi64, rtsize); ADD_ARG (argv, i, "-R"); ADD_ARG (argv, i, rtsize_s); } if (optargs_bitmask & GUESTFS_XFS_GROWFS_RTEXTSIZE_BITMASK) { if (rtextsize < 0) { reply_with_error ("rtextsize must be >= 0"); return -1; } snprintf (rtextsize_s, sizeof rtextsize_s, "%" PRIi64, rtextsize); ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, rtextsize_s); } if (optargs_bitmask & GUESTFS_XFS_GROWFS_MAXPCT_BITMASK) { if (maxpct < 0) { reply_with_error ("maxpct must be >= 0"); return -1; } snprintf (maxpct_s, sizeof maxpct_s, "%" PRIi32, maxpct); ADD_ARG (argv, i, "-m"); ADD_ARG (argv, i, maxpct_s); } ADD_ARG (argv, i, buf); ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { reply_with_error ("%s: %s", path, err); return -1; } return 0; }