183425a0fShaad /*
283425a0fShaad * Copyright (c) 2010 The NetBSD Foundation, Inc.
383425a0fShaad * All rights reserved.
483425a0fShaad *
583425a0fShaad * This code is derived from software contributed to The NetBSD Foundation
683425a0fShaad * by Adam Hamsik.
783425a0fShaad *
883425a0fShaad * Redistribution and use in source and binary forms, with or without
983425a0fShaad * modification, are permitted provided that the following conditions
1083425a0fShaad * are met:
1183425a0fShaad * 1. Redistributions of source code must retain the above copyright
1283425a0fShaad * notice, this list of conditions and the following disclaimer.
1383425a0fShaad * 2. Redistributions in binary form must reproduce the above copyright
1483425a0fShaad * notice, this list of conditions and the following disclaimer in the
1583425a0fShaad * documentation and/or other materials provided with the distribution.
1683425a0fShaad *
1783425a0fShaad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1883425a0fShaad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1983425a0fShaad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2083425a0fShaad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2183425a0fShaad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2283425a0fShaad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2383425a0fShaad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2483425a0fShaad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2583425a0fShaad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2683425a0fShaad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2783425a0fShaad * POSSIBILITY OF SUCH DAMAGE.
2883425a0fShaad */
2983425a0fShaad
3083425a0fShaad #include <sys/types.h>
3183425a0fShaad #include <sys/param.h>
3283425a0fShaad
3383425a0fShaad #include <ctype.h>
3483425a0fShaad #include <err.h>
3583425a0fShaad #include <errno.h>
3683425a0fShaad #include <stdio.h>
3783425a0fShaad #include <stdlib.h>
3883425a0fShaad #include <string.h>
3983425a0fShaad
4083425a0fShaad #include <prop/proplib.h>
4183425a0fShaad
4283425a0fShaad #include <dm.h>
4383425a0fShaad
4483425a0fShaad #ifdef RUMP_ACTION
4583425a0fShaad #include <rump/rump.h>
4683425a0fShaad #include <rump/rumpclient.h>
4783425a0fShaad #include <rump/rump_syscalls.h>
4883425a0fShaad #endif
4983425a0fShaad
5083425a0fShaad /* dmctl command is used to communicate with device-mapper driver in NetBSD
5183425a0fShaad * it uses libdm library to create and send required data to kernel.
5283425a0fShaad *
53*100a3398Sandvar * Main purpose of dmctl is to add possibility to use device-mapper driver
5483425a0fShaad * from outside of LVM scope.
5583425a0fShaad */
5683425a0fShaad
5783425a0fShaad #define DMCTL_CMD_REQ_NODEVNAME 0 /* Command do not require device name */
5883425a0fShaad #define DMCTL_CMD_REQ_DEVNAME 1 /* Command require device name to work */
5983425a0fShaad #define DMCTL_CMD_REQ_NEWNAME 2 /* Command require device name and
6083425a0fShaad newname to work */
6183425a0fShaad struct command {
6283425a0fShaad const char *cmd_name;
6383425a0fShaad const char *cmd_help;
6483425a0fShaad const char *ioctl_cmd_name;
6583425a0fShaad int min_args;
6683425a0fShaad int (*cmd_func)(int, char *[], libdm_task_t);
6783425a0fShaad };
6883425a0fShaad
699f300e34Sjoerg static const char *dvname; /* device name */
709f300e34Sjoerg static const char *cmdname; /* command user issued */
7183425a0fShaad
7283425a0fShaad static char * parse_stdin(char *);
7383425a0fShaad
7483425a0fShaad static int dmctl_get_version(int, char *[], libdm_task_t);
7583425a0fShaad static int dmctl_get_targets(int, char *[], libdm_task_t);
7683425a0fShaad static int dmctl_get_device_info(int, char *[], libdm_task_t);
7783425a0fShaad static int dmctl_create_dev(int, char *[], libdm_task_t);
7883425a0fShaad static int dmctl_dev_rename(int, char *[], libdm_task_t);
7983425a0fShaad static int dmctl_dev_remove(int, char *[], libdm_task_t);
8083425a0fShaad static int dmctl_dev_resume(int, char *[], libdm_task_t);
8183425a0fShaad static int dmctl_dev_suspend(int, char *[], libdm_task_t);
8283425a0fShaad static int dmctl_dev_deps(int, char *[], libdm_task_t);
8383425a0fShaad static int dmctl_list_devices(int, char *[], libdm_task_t);
8483425a0fShaad static int dmctl_table_reload(int, char *[], libdm_task_t);
8583425a0fShaad static int dmctl_table_status(int, char *[], libdm_task_t);
869f300e34Sjoerg __dead static void usage(void);
8783425a0fShaad
889f300e34Sjoerg static struct command commands[] = {
8983425a0fShaad { "version",
9083425a0fShaad "Print driver and lib version.",
9183425a0fShaad NULL, DMCTL_CMD_REQ_NODEVNAME,
9283425a0fShaad dmctl_get_version },
9383425a0fShaad { "targets",
9483425a0fShaad "List available kernel targets.",
9583425a0fShaad NULL, DMCTL_CMD_REQ_NODEVNAME,
9683425a0fShaad dmctl_get_targets },
9783425a0fShaad { "create",
9883425a0fShaad "Create device with [dm device name].",
9983425a0fShaad NULL, DMCTL_CMD_REQ_DEVNAME,
10083425a0fShaad dmctl_create_dev },
10183425a0fShaad { "ls",
10283425a0fShaad "List existing dm devices.",
10383425a0fShaad "names", DMCTL_CMD_REQ_NODEVNAME,
10483425a0fShaad dmctl_list_devices },
10583425a0fShaad { "info",
10683425a0fShaad "Get info about device with [dm device name].",
10783425a0fShaad NULL, DMCTL_CMD_REQ_DEVNAME,
10883425a0fShaad dmctl_get_device_info },
10983425a0fShaad { "rename",
11083425a0fShaad "Rename device with [dm device name] to [dm device new name].",
11183425a0fShaad NULL, DMCTL_CMD_REQ_NEWNAME,
11283425a0fShaad dmctl_dev_rename },
11383425a0fShaad { "remove",
11483425a0fShaad "Remove device with [dm device name].",
11583425a0fShaad NULL, DMCTL_CMD_REQ_DEVNAME,
11683425a0fShaad dmctl_dev_remove },
11783425a0fShaad { "resume",
11883425a0fShaad "Resume IO on dm device [dm device name].",
11983425a0fShaad NULL, DMCTL_CMD_REQ_DEVNAME,
12083425a0fShaad dmctl_dev_resume },
12183425a0fShaad { "suspend",
12283425a0fShaad "Suspend IO on dm device [dm device name].",
12383425a0fShaad NULL, DMCTL_CMD_REQ_DEVNAME,
12483425a0fShaad dmctl_dev_suspend },
12583425a0fShaad { "deps",
126*100a3398Sandvar "Print physical dependencies for dm device [dm device name].",
12783425a0fShaad NULL, DMCTL_CMD_REQ_DEVNAME,
12883425a0fShaad dmctl_dev_deps },
12983425a0fShaad { "reload",
13083425a0fShaad "Switch active and passive tables for device with [dm device name].",
13183425a0fShaad NULL, DMCTL_CMD_REQ_DEVNAME,
13283425a0fShaad dmctl_table_reload },
13383425a0fShaad { "status",
13483425a0fShaad "Print status for device with [dm device name].",
13583425a0fShaad "table", DMCTL_CMD_REQ_DEVNAME,
13683425a0fShaad dmctl_table_status },
13783425a0fShaad { "table",
13883425a0fShaad "Print active table for device with [dm device name].",
13983425a0fShaad NULL, DMCTL_CMD_REQ_DEVNAME,
14083425a0fShaad dmctl_table_status },
14183425a0fShaad { NULL,
14283425a0fShaad NULL,
14383425a0fShaad NULL, 0,
14483425a0fShaad NULL },
14583425a0fShaad };
14683425a0fShaad
14783425a0fShaad int
main(int argc,char * argv[])14883425a0fShaad main(int argc, char *argv[])
14983425a0fShaad {
15083425a0fShaad int i;
15183425a0fShaad int oargc;
15283425a0fShaad libdm_task_t task;
15383425a0fShaad
15483425a0fShaad oargc = 0;
15583425a0fShaad
15683425a0fShaad #ifdef RUMP_ACTION
15783425a0fShaad if (rumpclient_init() == -1)
15883425a0fShaad err(EXIT_FAILURE, "rump client init failed");
15983425a0fShaad #endif
16083425a0fShaad
16183425a0fShaad /* Must have at least: device command */
16283425a0fShaad if (argc < 2)
16383425a0fShaad usage();
16483425a0fShaad
16583425a0fShaad /* Skip program name, get and skip device name and command. */
16683425a0fShaad cmdname = argv[1];
16783425a0fShaad if (argc > 2) {
16883425a0fShaad oargc = 1;
16983425a0fShaad dvname = argv[2];
17083425a0fShaad }
17183425a0fShaad
17283425a0fShaad if (argc > 3) {
17383425a0fShaad argv += 3;
17483425a0fShaad argc -= 3;
17583425a0fShaad oargc = 2;
17683425a0fShaad } else {
17783425a0fShaad argv = 0;
17883425a0fShaad argc = 0;
17983425a0fShaad }
18083425a0fShaad
18183425a0fShaad for (i = 0; commands[i].cmd_name != NULL; i++)
18283425a0fShaad if (strcmp(cmdname, commands[i].cmd_name) == 0)
18383425a0fShaad break;
18483425a0fShaad
18583425a0fShaad if (commands[i].cmd_name == NULL)
18683425a0fShaad errx(EXIT_FAILURE, "unknown command: %s", cmdname);
18783425a0fShaad
18883425a0fShaad if (commands[i].ioctl_cmd_name != NULL)
18983425a0fShaad cmdname = commands[i].ioctl_cmd_name;
19083425a0fShaad
19183425a0fShaad if (oargc != commands[i].min_args) {
19283425a0fShaad (void)fprintf(stderr, "Insufficient number of arguments for "
19383425a0fShaad "command: %s specified\n", commands[i].cmd_name);
19483425a0fShaad usage();
19583425a0fShaad }
19683425a0fShaad
19783425a0fShaad /*
19883425a0fShaad * Create libdm task, and pass it to command handler later.
19983425a0fShaad * Don't release it here because it will be replaced by different
20083425a0fShaad * dictionary received from kernel after libdm_task_run.
20183425a0fShaad */
20283425a0fShaad task = libdm_task_create(cmdname);
20383425a0fShaad
20483425a0fShaad (*commands[i].cmd_func)(argc, argv, task);
20583425a0fShaad
20683425a0fShaad return 0;
20783425a0fShaad }
20883425a0fShaad
20983425a0fShaad /*
21083425a0fShaad * Print library and kernel driver versions if command can be used only when
21183425a0fShaad * major, minor number of library version is <= kernel.
21283425a0fShaad */
21383425a0fShaad static int
dmctl_get_version(int argc __unused,char * argv[]__unused,libdm_task_t task)21483425a0fShaad dmctl_get_version(int argc __unused, char *argv[] __unused, libdm_task_t task)
21583425a0fShaad {
2163e4993b3Schristos uint32_t ver[3];
21783425a0fShaad
2183e4993b3Schristos (void)libdm_task_get_cmd_version(task, ver, sizeof(ver));
21983425a0fShaad
22083425a0fShaad printf("Library protocol version %d:%d:%d\n", ver[0], ver[1], ver[2]);
22183425a0fShaad
22283425a0fShaad if (libdm_task_run(task) != 0)
22383425a0fShaad err(EXIT_FAILURE, "dmctl_get_version: libdm_task_run failed.");
22483425a0fShaad
2253e4993b3Schristos (void)libdm_task_get_cmd_version(task, ver, 3);
22683425a0fShaad printf("Kernel protocol version %d:%d:%d\n",ver[0], ver[1], ver[2]);
22783425a0fShaad
22883425a0fShaad libdm_task_destroy(task);
22983425a0fShaad return 0;
23083425a0fShaad }
23183425a0fShaad
23283425a0fShaad /*
23383425a0fShaad * Get list of available targets from kernel and print them.
23483425a0fShaad */
23583425a0fShaad static int
dmctl_get_targets(int argc __unused,char * argv[]__unused,libdm_task_t task)23683425a0fShaad dmctl_get_targets(int argc __unused, char *argv[] __unused, libdm_task_t task)
23783425a0fShaad {
23883425a0fShaad libdm_cmd_t cmd;
23983425a0fShaad libdm_iter_t iter;
24083425a0fShaad libdm_target_t target;
24183425a0fShaad uint32_t ver[3];
24283425a0fShaad
24383425a0fShaad if (libdm_task_run(task) != 0)
24483425a0fShaad err(EXIT_FAILURE, "dmctl_get_targets: libdm_task_run failed.");
24583425a0fShaad
24683425a0fShaad if ((cmd = libdm_task_get_cmd(task)) == NULL)
24783425a0fShaad return ENOENT;
24883425a0fShaad
24983425a0fShaad iter = libdm_cmd_iter_create(cmd);
25083425a0fShaad
25183425a0fShaad while((target = libdm_cmd_get_target(iter)) != NULL){
25283425a0fShaad printf("Target name: %s\n", libdm_target_get_name(target));
25383425a0fShaad
25483425a0fShaad libdm_target_get_version(target, ver, sizeof(ver));
25583425a0fShaad printf("Target version %d.%d.%d\n\n", ver[0], ver[1], ver[2]);
25683425a0fShaad
25783425a0fShaad libdm_target_destroy(target);
25883425a0fShaad }
25983425a0fShaad
26083425a0fShaad libdm_iter_destroy(iter);
26183425a0fShaad libdm_cmd_destroy(cmd);
26283425a0fShaad libdm_task_destroy(task);
26383425a0fShaad
26483425a0fShaad return 0;
26583425a0fShaad }
26683425a0fShaad
26783425a0fShaad /*
26883425a0fShaad * Create device with name used as second parameter.
26983425a0fShaad * TODO: Support for UUIDs here.
27083425a0fShaad */
27183425a0fShaad static int
dmctl_create_dev(int argc __unused,char * argv[]__unused,libdm_task_t task)27283425a0fShaad dmctl_create_dev(int argc __unused, char *argv[] __unused, libdm_task_t task)
27383425a0fShaad {
27483425a0fShaad
27583425a0fShaad libdm_task_set_name(dvname, task);
27683425a0fShaad
27783425a0fShaad if (libdm_task_run(task) != 0)
27883425a0fShaad err(EXIT_FAILURE, "dmctl_create_dev: libdm_task_run failed.");
27983425a0fShaad
28083425a0fShaad libdm_task_destroy(task);
28183425a0fShaad return 0;
28283425a0fShaad }
28383425a0fShaad
28483425a0fShaad /*
28583425a0fShaad * Get basic device info from device-mapper driver.
28683425a0fShaad */
28783425a0fShaad static int
dmctl_get_device_info(int argc __unused,char * argv[]__unused,libdm_task_t task)28883425a0fShaad dmctl_get_device_info(int argc __unused, char *argv[] __unused, libdm_task_t task)
28983425a0fShaad {
29083425a0fShaad
29183425a0fShaad libdm_task_set_name(dvname, task);
29283425a0fShaad
29383425a0fShaad if (libdm_task_run(task) != 0)
294d3037dbaSchristos err(EXIT_FAILURE, "%s: libdm_task_run failed", __func__);
29583425a0fShaad
29683425a0fShaad printf("Printing Device info for:\n");
29783425a0fShaad printf("Device name: \t\t%s\n", libdm_task_get_name(task));
29883425a0fShaad printf("Device uuid: \t\t%s\n", libdm_task_get_uuid(task));
29983425a0fShaad printf("Device minor: \t\t%d\n", libdm_task_get_minor(task));
30083425a0fShaad printf("Device target number: \t%d\n", libdm_task_get_target_num(task));
30183425a0fShaad printf("Device flags: \t\t%d\n", libdm_task_get_flags(task));
30283425a0fShaad
30383425a0fShaad libdm_task_destroy(task);
30483425a0fShaad return 0;
30583425a0fShaad }
30683425a0fShaad
30783425a0fShaad /*
30883425a0fShaad * List all device in device-mapper driver.
30983425a0fShaad */
31083425a0fShaad static int
dmctl_list_devices(int argc __unused,char * argv[]__unused,libdm_task_t task)31183425a0fShaad dmctl_list_devices(int argc __unused, char *argv[] __unused, libdm_task_t task)
31283425a0fShaad {
31383425a0fShaad libdm_cmd_t cmd;
31483425a0fShaad libdm_iter_t iter;
31583425a0fShaad libdm_dev_t dev;
31683425a0fShaad
31783425a0fShaad if (libdm_task_run(task) != 0)
31883425a0fShaad err(EXIT_FAILURE, "dmctl_list_devices: libdm_task_run failed.");
31983425a0fShaad
32083425a0fShaad if ((cmd = libdm_task_get_cmd(task)) == NULL)
32183425a0fShaad return ENOENT;
32283425a0fShaad
32383425a0fShaad iter = libdm_cmd_iter_create(cmd);
32483425a0fShaad
32583425a0fShaad while((dev = libdm_cmd_get_dev(iter)) != NULL){
32683425a0fShaad printf("Device name: %s, device minor: %d \n",
32783425a0fShaad libdm_dev_get_name(dev), libdm_dev_get_minor(dev));
32883425a0fShaad libdm_dev_destroy(dev);
32983425a0fShaad }
33083425a0fShaad
33183425a0fShaad libdm_iter_destroy(iter);
33283425a0fShaad libdm_cmd_destroy(cmd);
33383425a0fShaad libdm_task_destroy(task);
33483425a0fShaad
33583425a0fShaad return 0;
33683425a0fShaad }
33783425a0fShaad
33883425a0fShaad /*
33983425a0fShaad * Rename device to new name
34083425a0fShaad */
34183425a0fShaad static int
dmctl_dev_rename(int argc __unused,char * argv[],libdm_task_t task)34283425a0fShaad dmctl_dev_rename(int argc __unused, char *argv[], libdm_task_t task)
34383425a0fShaad {
34483425a0fShaad libdm_cmd_t cmd;
34583425a0fShaad
34683425a0fShaad libdm_task_set_name(dvname, task);
34783425a0fShaad
34883425a0fShaad cmd = libdm_cmd_create();
34983425a0fShaad libdm_dev_set_newname(argv[0], cmd);
35083425a0fShaad libdm_task_set_cmd(cmd, task);
35183425a0fShaad
35283425a0fShaad if (libdm_task_run(task) != 0)
35383425a0fShaad err(EXIT_FAILURE, "dmctl_dev_rename: libdm_task_run failed.");
35483425a0fShaad
35583425a0fShaad libdm_cmd_destroy(cmd);
35683425a0fShaad libdm_task_destroy(task);
35783425a0fShaad
35883425a0fShaad return 0;
35983425a0fShaad }
36083425a0fShaad
36183425a0fShaad /*
36283425a0fShaad * Remove device from dm device list.
36383425a0fShaad */
36483425a0fShaad static int
dmctl_dev_remove(int argc __unused,char * argv[]__unused,libdm_task_t task)36583425a0fShaad dmctl_dev_remove(int argc __unused, char *argv[] __unused, libdm_task_t task)
36683425a0fShaad {
36783425a0fShaad
36883425a0fShaad if (dvname == NULL)
36983425a0fShaad return (ENOENT);
37083425a0fShaad
37183425a0fShaad libdm_task_set_name(dvname, task);
37283425a0fShaad
37383425a0fShaad if (libdm_task_run(task) != 0)
37483425a0fShaad err(EXIT_FAILURE, "dmctl_dev_remove: libdm_task_run failed.");
37583425a0fShaad
37683425a0fShaad libdm_task_destroy(task);
37783425a0fShaad return 0;
37883425a0fShaad }
37983425a0fShaad
38083425a0fShaad /*
38183425a0fShaad * Resume device which was suspended or created right now.
382*100a3398Sandvar * Replace table in "active slot" with table in "inactive slot".
38383425a0fShaad */
38483425a0fShaad static int
dmctl_dev_resume(int argc __unused,char * argv[]__unused,libdm_task_t task)38583425a0fShaad dmctl_dev_resume(int argc __unused, char *argv[] __unused, libdm_task_t task)
38683425a0fShaad {
38783425a0fShaad
38883425a0fShaad libdm_task_set_name(dvname, task);
38983425a0fShaad
39083425a0fShaad if (libdm_task_run(task) != 0)
39183425a0fShaad err(EXIT_FAILURE, "dmctl_dev_resume: libdm_task_run failed.");
39283425a0fShaad
39383425a0fShaad libdm_task_destroy(task);
39483425a0fShaad return 0;
39583425a0fShaad }
39683425a0fShaad
39783425a0fShaad /*
39883425a0fShaad * Resume device which was suspended or created right now.
39983425a0fShaad * Replace table in "active slot" with table in "inactive slot".
40083425a0fShaad */
40183425a0fShaad static int
dmctl_dev_suspend(int argc __unused,char * argv[]__unused,libdm_task_t task)40283425a0fShaad dmctl_dev_suspend(int argc __unused, char *argv[] __unused, libdm_task_t task)
40383425a0fShaad {
40483425a0fShaad
40583425a0fShaad libdm_task_set_name(dvname, task);
40683425a0fShaad libdm_task_set_suspend_flag(task);
40783425a0fShaad
40883425a0fShaad if (libdm_task_run(task) != 0)
40983425a0fShaad err(EXIT_FAILURE, "dmctl_dev_suspend: libdm_task_run failed.");
41083425a0fShaad
41183425a0fShaad libdm_task_destroy(task);
41283425a0fShaad return 0;
41383425a0fShaad }
41483425a0fShaad
41583425a0fShaad /*
416*100a3398Sandvar * Get device dependencies from device-mapper. Device dependency is physical
41783425a0fShaad * device on which dm device depends.
41883425a0fShaad */
41983425a0fShaad static int
dmctl_dev_deps(int argc __unused,char * argv[]__unused,libdm_task_t task)42083425a0fShaad dmctl_dev_deps(int argc __unused, char *argv[] __unused, libdm_task_t task)
42183425a0fShaad {
42283425a0fShaad libdm_cmd_t cmd;
42383425a0fShaad libdm_iter_t iter;
42483425a0fShaad dev_t dev_deps;
42583425a0fShaad
42683425a0fShaad libdm_task_set_name(dvname, task);
42783425a0fShaad
42883425a0fShaad if (libdm_task_run(task) != 0)
42983425a0fShaad err(EXIT_FAILURE, "dmctl_dev_deps: libdm_task_run failed.");
43083425a0fShaad
43183425a0fShaad if ((cmd = libdm_task_get_cmd(task)) == NULL)
43283425a0fShaad return ENOENT;
43383425a0fShaad
43483425a0fShaad iter = libdm_cmd_iter_create(cmd);
43583425a0fShaad
436*100a3398Sandvar printf("Device %s dependencies \n", dvname);
43783425a0fShaad
43883425a0fShaad while((dev_deps = libdm_cmd_get_deps(iter)) != 0)
43983425a0fShaad printf("major: %d minor: %d\n", major(dev_deps), minor(dev_deps));
44083425a0fShaad
44183425a0fShaad libdm_iter_destroy(iter);
44283425a0fShaad libdm_cmd_destroy(cmd);
44383425a0fShaad libdm_task_destroy(task);
44483425a0fShaad
44583425a0fShaad return 0;
44683425a0fShaad }
44783425a0fShaad
44883425a0fShaad /*
44983425a0fShaad * Reload device table to get new one to use.
45083425a0fShaad */
45183425a0fShaad static int
dmctl_table_reload(int argc,char * argv[],libdm_task_t task)45283425a0fShaad dmctl_table_reload(int argc, char *argv[], libdm_task_t task)
45383425a0fShaad {
45483425a0fShaad libdm_cmd_t cmd;
45583425a0fShaad libdm_table_t table;
45683425a0fShaad
45783425a0fShaad char *params;
45883425a0fShaad char *file_path;
45983425a0fShaad char target[128];
46083425a0fShaad int len;
46183425a0fShaad uint64_t start, length;
46283425a0fShaad
46383425a0fShaad file_path = NULL;
46483425a0fShaad params = NULL;
46583425a0fShaad
46683425a0fShaad cmd = libdm_cmd_create();
46783425a0fShaad
46883425a0fShaad libdm_task_set_name(dvname, task);
46983425a0fShaad
47083425a0fShaad if (argc != 0)
47183425a0fShaad file_path = argv[0];
47283425a0fShaad
47383425a0fShaad while ((params = parse_stdin(file_path)) != NULL) {
47483425a0fShaad table = libdm_table_create();
47583425a0fShaad
4764f8abcabSpgoyette sscanf(params, "%"PRIu64" %"PRIu64" %s %n", &start, &length, target, &len);
47783425a0fShaad
47883425a0fShaad libdm_table_set_start(start, table);
47983425a0fShaad libdm_table_set_length(length, table);
48083425a0fShaad libdm_table_set_target(target, table);
48183425a0fShaad libdm_table_set_params(params + len, table);
48283425a0fShaad libdm_cmd_set_table(table, cmd);
48383425a0fShaad
48483425a0fShaad libdm_table_destroy(table);
48583425a0fShaad
48683425a0fShaad free(params);
48783425a0fShaad }
48883425a0fShaad
48983425a0fShaad libdm_task_set_cmd(cmd, task);
49083425a0fShaad
49183425a0fShaad if (libdm_task_run(task) != 0)
49283425a0fShaad err(EXIT_FAILURE, "libdm_task_run: from dmctl_table_reload failed.");
49383425a0fShaad
49483425a0fShaad libdm_cmd_destroy(cmd);
49583425a0fShaad libdm_task_destroy(task);
49683425a0fShaad free(params);
49783425a0fShaad
49883425a0fShaad return 0;
49983425a0fShaad }
50083425a0fShaad
50183425a0fShaad /*
50283425a0fShaad * Get table status from device.
50383425a0fShaad */
50483425a0fShaad static int
dmctl_table_status(int argc __unused,char * argv[]__unused,libdm_task_t task)50583425a0fShaad dmctl_table_status(int argc __unused, char *argv[] __unused, libdm_task_t task)
50683425a0fShaad {
50783425a0fShaad libdm_cmd_t cmd;
50883425a0fShaad libdm_table_t table;
50983425a0fShaad libdm_iter_t iter;
51083425a0fShaad
51183425a0fShaad libdm_task_set_name(dvname, task);
51283425a0fShaad libdm_task_set_status_flag(task);
51383425a0fShaad
51483425a0fShaad if (libdm_task_run(task) != 0)
51583425a0fShaad err(EXIT_FAILURE, "libdm_task_run");
51683425a0fShaad
51783425a0fShaad if ((cmd = libdm_task_get_cmd(task)) == NULL)
51883425a0fShaad return ENOENT;
51983425a0fShaad
52083425a0fShaad iter = libdm_cmd_iter_create(cmd);
52183425a0fShaad
52283425a0fShaad printf("Getting device table for device %s\n", dvname);
52383425a0fShaad
52483425a0fShaad while ((table = libdm_cmd_get_table(iter)) != NULL) {
52583425a0fShaad printf("%10"PRIu64" %10"PRIu64" %s\n",
52683425a0fShaad libdm_table_get_start(table),
52783425a0fShaad libdm_table_get_length(table),
52883425a0fShaad libdm_table_get_target(table));
52983425a0fShaad libdm_table_destroy(table);
53083425a0fShaad }
53183425a0fShaad
53283425a0fShaad libdm_iter_destroy(iter);
53383425a0fShaad libdm_cmd_destroy(cmd);
53483425a0fShaad libdm_task_destroy(task);
53583425a0fShaad
53683425a0fShaad return 0;
53783425a0fShaad }
53883425a0fShaad
5399f300e34Sjoerg static void
usage(void)54083425a0fShaad usage(void)
54183425a0fShaad {
54283425a0fShaad int i;
54383425a0fShaad
54483425a0fShaad (void)fprintf(stderr, "usage: %s command [dm device name]\n"
54583425a0fShaad "Available commands are:\n ", getprogname());
54683425a0fShaad for (i = 0; commands[i].cmd_name != NULL; i++)
54783425a0fShaad (void)fprintf(stderr, "\t%s\t%s\n", commands[i].cmd_name, commands[i].cmd_help);
54883425a0fShaad exit(EXIT_FAILURE);
54983425a0fShaad }
55083425a0fShaad
55183425a0fShaad static char *
parse_stdin(char * file_path)55283425a0fShaad parse_stdin(char *file_path)
55383425a0fShaad {
55483425a0fShaad char *buf, *lbuf;
55583425a0fShaad size_t len;
55683425a0fShaad FILE *fp;
55783425a0fShaad
55883425a0fShaad lbuf = NULL;
55983425a0fShaad
56083425a0fShaad if (file_path) {
56183425a0fShaad if ((fp = fopen(file_path, "r")) == NULL)
562d3037dbaSchristos err(ENOENT, "Cannot open table file");
56383425a0fShaad } else
56483425a0fShaad fp = stdin;
56583425a0fShaad
56683425a0fShaad if ((buf = fgetln(fp, &len)) == NULL)
56783425a0fShaad return NULL;
56883425a0fShaad
56983425a0fShaad if (buf[len - 1] != '\n')
57083425a0fShaad len++;
57183425a0fShaad
57283425a0fShaad if ((lbuf = malloc(len)) == NULL)
57383425a0fShaad err(EXIT_FAILURE, "malloc");
57483425a0fShaad
57583425a0fShaad memcpy(lbuf, buf, len);
57683425a0fShaad lbuf[len - 1] = '\0';
57783425a0fShaad
57883425a0fShaad return lbuf;
57983425a0fShaad }
580