1 /* libguestfs - the guestfsd daemon
2 * Copyright (C) 2011 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "optgroups.h"
32 optgroup_mdadm_available (void)
34 return prog_exists ("mdadm");
38 count_bits (uint64_t bitmap)
45 c = bitmap & 1 ? 1 : 0;
47 return c + count_bits (bitmap);
50 /* Takes optional arguments, consult optargs_bitmask. */
52 do_mdadm_create (const char *name, char *const *devices,
53 int64_t missingbitmap, int nrdevices, int spare,
54 int64_t chunk, const char *level)
62 uint64_t umissingbitmap = (uint64_t) missingbitmap;
64 /* Check the optional parameters and set defaults where appropriate. */
65 if (!(optargs_bitmask & GUESTFS_MDADM_CREATE_MISSINGBITMAP_BITMASK))
68 if (optargs_bitmask & GUESTFS_MDADM_CREATE_SPARE_BITMASK) {
70 reply_with_error ("spare must not be negative");
77 if (optargs_bitmask & GUESTFS_MDADM_CREATE_NRDEVICES_BITMASK) {
79 reply_with_error ("nrdevices is less than 2");
84 nrdevices = count_strings (devices) + count_bits (umissingbitmap);
86 if (optargs_bitmask & GUESTFS_MDADM_CREATE_LEVEL_BITMASK) {
87 if (STRNEQ (level, "linear") && STRNEQ (level, "raid0") &&
88 STRNEQ (level, "0") && STRNEQ (level, "stripe") &&
89 STRNEQ (level, "raid1") && STRNEQ (level, "1") &&
90 STRNEQ (level, "mirror") &&
91 STRNEQ (level, "raid4") && STRNEQ (level, "4") &&
92 STRNEQ (level, "raid5") && STRNEQ (level, "5") &&
93 STRNEQ (level, "raid6") && STRNEQ (level, "6") &&
94 STRNEQ (level, "raid10") && STRNEQ (level, "10")) {
95 reply_with_error ("unknown level parameter: %s", level);
102 if (optargs_bitmask & GUESTFS_MDADM_CREATE_CHUNK_BITMASK) {
103 /* chunk is bytes in the libguestfs API, but K when we pass it to mdadm */
104 if ((chunk & 1023) != 0) {
105 reply_with_error ("chunk size must be a multiple of 1024 bytes");
110 /* Check invariant. */
111 if (count_strings (devices) + count_bits (umissingbitmap) !=
112 (size_t) (nrdevices + spare)) {
113 reply_with_error ("devices (%zu) + bits set in missingbitmap (%zu) is not equal to nrdevices (%d) + spare (%d)",
114 count_strings (devices), count_bits (umissingbitmap),
119 size_t MAX_ARGS = nrdevices + 16;
120 const char *argv[MAX_ARGS];
123 ADD_ARG (argv, i, "mdadm");
124 ADD_ARG (argv, i, "--create");
125 /* --run suppresses "Continue creating array" question */
126 ADD_ARG (argv, i, "--run");
127 ADD_ARG (argv, i, name);
128 ADD_ARG (argv, i, "--level");
129 ADD_ARG (argv, i, level);
130 ADD_ARG (argv, i, "--raid-devices");
131 snprintf (nrdevices_s, sizeof nrdevices_s, "%d", nrdevices);
132 ADD_ARG (argv, i, nrdevices_s);
133 if (optargs_bitmask & GUESTFS_MDADM_CREATE_SPARE_BITMASK) {
134 ADD_ARG (argv, i, "--spare-devices");
135 snprintf (spare_s, sizeof spare_s, "%d", spare);
136 ADD_ARG (argv, i, spare_s);
138 if (optargs_bitmask & GUESTFS_MDADM_CREATE_CHUNK_BITMASK) {
139 ADD_ARG (argv, i, "--chunk");
140 snprintf (chunk_s, sizeof chunk_s, "%" PRIi64, chunk / 1024);
141 ADD_ARG (argv, i, chunk_s);
144 /* Add devices and "missing". */
146 while (devices[j] != NULL || umissingbitmap != 0) {
147 if (umissingbitmap & 1)
148 ADD_ARG (argv, i, "missing");
150 ADD_ARG (argv, i, devices[j]);
153 umissingbitmap >>= 1;
156 ADD_ARG (argv, i, NULL);
158 r = commandv (NULL, &err, argv);
160 reply_with_error ("mdadm: %s: %s", name, err);