/* * Init function called from dm_table_load_ioctl. * argv: /dev/mapper/my_data_org /dev/mapper/tsc_cow_dev p 64 * snapshot_origin device, cow device, persistent flag, chunk size */ int dm_target_snapshot_init(dm_dev_t * dmv, void **target_config, char *params) { dm_target_snapshot_config_t *tsc; dm_pdev_t *dmp_snap, *dmp_cow; char **ap, *argv[5]; dmp_cow = NULL; if (params == NULL) return EINVAL; /* * Parse a string, containing tokens delimited by white space, * into an argument vector */ for (ap = argv; ap < &argv[4] && (*ap = strsep(¶ms, " \t")) != NULL;) { if (**ap != '\0') ap++; } printf("Snapshot target init function called!!\n"); printf("Snapshotted device: %s, cow device %s,\n\t persistent flag: %s, " "chunk size: %s\n", argv[0], argv[1], argv[2], argv[3]); /* Insert snap device to global pdev list */ if ((dmp_snap = dm_pdev_insert(argv[0])) == NULL) return ENOENT; if ((tsc = kmem_alloc(sizeof(dm_target_snapshot_config_t), KM_NOSLEEP)) == NULL) return 1; tsc->tsc_persistent_dev = 0; /* There is now cow device for nonpersistent snapshot devices */ if (strcmp(argv[2], "p") == 0) { tsc->tsc_persistent_dev = 1; /* Insert cow device to global pdev list */ if ((dmp_cow = dm_pdev_insert(argv[1])) == NULL) return ENOENT; } tsc->tsc_chunk_size = atoi(argv[3]); tsc->tsc_snap_dev = dmp_snap; tsc->tsc_cow_dev = dmp_cow; *target_config = tsc; dmv->dev_type = DM_SNAPSHOT_DEV; dmv->sec_size = dmp_snap->dmp_secsize; return 0; }
/* * Init function called from dm_table_load_ioctl. * * argv: /dev/mapper/my_data_real */ int dm_target_snapshot_orig_init(dm_dev_t * dmv, void **target_config, char *params) { dm_target_snapshot_origin_config_t *tsoc; dm_pdev_t *dmp_real; if (params == NULL) return EINVAL; printf("Snapshot origin target init function called!!\n"); printf("Parent device: %s\n", params); /* Insert snap device to global pdev list */ if ((dmp_real = dm_pdev_insert(params)) == NULL) return ENOENT; if ((tsoc = kmem_alloc(sizeof(dm_target_snapshot_origin_config_t), KM_NOSLEEP)) == NULL) return 1; tsoc->tsoc_real_dev = dmp_real; dmv->dev_type = DM_SNAPSHOT_ORIG_DEV; *target_config = tsoc; return 0; }
/* * Allocate target specific config data, and link them to table. * This function is called only when, flags is not READONLY and * therefore we can add things to pdev list. This should not a * problem because this routine is called only from dm_table_load_ioctl. * @argv[0] is name, * @argv[1] is physical data offset. */ static int dm_target_linear_init(dm_dev_t * dmv, void **target_config, char *params) { dm_target_linear_config_t *tlc; dm_pdev_t *dmp; char **ap, *argv[3]; if (params == NULL) return EINVAL; /* * Parse a string, containing tokens delimited by white space, * into an argument vector */ for (ap = argv; ap < &argv[2] && (*ap = strsep(¶ms, " \t")) != NULL;) { if (**ap != '\0') ap++; } aprint_debug("Linear target init function called %s--%s!!\n", argv[0], argv[1]); /* XXX: temp hack */ if (argv[0] == NULL) return EINVAL; /* Insert dmp to global pdev list */ if ((dmp = dm_pdev_insert(argv[0])) == NULL) return ENOENT; if ((tlc = kmalloc(sizeof(dm_target_linear_config_t), M_DMLINEAR, M_WAITOK)) == NULL) return ENOMEM; tlc->pdev = dmp; tlc->offset = 0; /* default settings */ /* Check user input if it is not leave offset as 0. */ tlc->offset = atoi64(argv[1]); *target_config = tlc; dmv->dev_type = DM_LINEAR_DEV; return 0; }
/* * Init function called from dm_table_load_ioctl. * * Example line sent to dm from lvm tools when using striped target. * start length striped #stripes chunk_size device1 offset1 ... deviceN offsetN * 0 65536 striped 2 512 /dev/hda 0 /dev/hdb 0 */ static int dm_target_stripe_init(dm_dev_t *dmv, void **target_config, char *params) { dm_target_stripe_config_t *tsc; int n; char *ap; if (params == NULL) return EINVAL; /* * nstripes */ ap = strsep(¶ms, " \t"); if (ap == NULL) return EINVAL; n = (int)atoi64(ap); if (n < 0 || n > MAX_STRIPES) { kprintf("dm: Error %d stripes not supported (%d max)\n", n, MAX_STRIPES); return ENOTSUP; } tsc = kmalloc(sizeof(dm_target_stripe_config_t), M_DMSTRIPE, M_WAITOK | M_ZERO); tsc->stripe_num = n; ap = strsep(¶ms, " \t"); if (ap == NULL) return EINVAL; tsc->stripe_chunksize = atoi64(ap); if (tsc->stripe_chunksize < 1 || tsc->stripe_chunksize * DEV_BSIZE > MAXPHYS) { kprintf("dm: Error unsupported chunk size %jdKB\n", (intmax_t)tsc->stripe_chunksize * DEV_BSIZE / 1024); dm_target_stripe_destroy_config(tsc); return EINVAL; } /* * Parse the devices */ kprintf("dm: Stripe %d devices chunk size %dKB\n", (int)tsc->stripe_num, (int)tsc->stripe_chunksize ); for (n = 0; n < tsc->stripe_num; ++n) { ap = strsep(¶ms, " \t"); if (ap == NULL) break; tsc->stripe_devs[n].pdev = dm_pdev_insert(ap); if (tsc->stripe_devs[n].pdev == NULL) break; ap = strsep(¶ms, " \t"); if (ap == NULL) break; tsc->stripe_devs[n].offset = atoi64(ap); } if (n != tsc->stripe_num) { dm_target_stripe_destroy_config(tsc); return (ENOENT); } *target_config = tsc; dmv->dev_type = DM_STRIPE_DEV; return 0; }