c_cpp Brickstor区域设置脚本
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp Brickstor区域设置脚本相关的知识,希望对你有一定的参考价值。
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
// First, create vnic, naming it netXX where XX is the number
// following the word zone in the name. Example: zone0, in which
// case XX would be 0. All examples below assume 0 in place of XX.
//
// Next, create dataset for housing replicated data and set
// zoned property on dataset to which we are going to be
// replicating data.
// # zfs create -p p01/global/replication/<SERIAL>
// # zfs set zoned=on p01/global/replication/<SERIAL>
//
// Install the zone after creating it from the generated config.
// Use the value of contents below as a template for creating
// new zones.
//
// # zoneadm -z zone0 install
// After zone is installed, the filesystem with sparse contents
// will be created automatically.
//
// Boot the zone with:
// # zoneadm -z zone0 boot
// Login into the zone with:
// # zlogin zone0
//
// Configure network interface inside the zone after logging into zone:
// # ipadm create-addr -T static -a local=192.168.13.10/24 net0/v4
#define MAXPAIRLEN 64
#define ZONEREADYDELAY 10
const char *default_pool = "p01";
const char *config_file = "/tmp/bootstrap.zone";
const char *zonecfg_create_zone = "/usr/sbin/zonecfg -z %s -f %s";
const char *zfs_create_dataset =
"/usr/sbin/zfs create -p %s/global/replication/%s";
const char *zfs_set_prop_zoned =
"/usr/sbin/zfs set zoned=on %s/global/replication/%s";
const char *zfs_set_prop_mountpoint =
"/usr/sbin/zfs set mountpoint=none %s/global/replication/%s";
const char *zfs_list_dataset = "zfs list %s/global/replication/%s";
const char *create_zoned_iface =
"/usr/sbin/zlogin %s ipadm create-if %s";
const char *create_zoned_ip_iface =
"/usr/sbin/zlogin %s ipadm create-addr -T dhcp -w30 %s/v4";
// "/usr/sbin/zlogin %s ipadm create-addr -T static -a local=%s/24 %s/v4";
const char *create_zoned_vnic =
"/usr/sbin/dladm create-vnic -l aggr0 -v 281 %s";
const char *show_mac_address =
"/usr/sbin/dladm show-vnic -p -olink,macaddress %s";
const char *verify_zone_ready = "/usr/sbin/zoneadm -z %s verify";
const char *install_zone = "/usr/sbin/zoneadm -z %s install";
const char *boot_zone = "/usr/sbin/zoneadm -z %s boot";
char *customer = NULL;
char *serial = NULL;
char *vnic = NULL;
char *ipaddr = NULL;
char *pool = NULL;
// KVPair struct holds pairs parsed from from parameters passed
// on the command line in the form of key=value strings.
typedef struct KVPair {
char key[16];
char value[16];
} kvp_t;
int customize_template(const char *customer, const char *vnic, const
char *serial) {
const char *template = "create -b\n" "set zonepath=/storage/p01/zones/%s\n"
"set brand=bsros\n" "set autoboot=true\n" "set ip-type=exclusive\n"
"add net\n" "set physical=%s\n" "end\n" "add dataset\n"
"set name=p01/global/replication/%s\n" "end\n";
FILE *f = fopen("/tmp/bootstrap.zone", "w+");
if (f == NULL)
return -1;
// Output to screen configuration that is being generated
printf("+--------------------------------------------+\n");
printf("| Zone Configuration for Customer (%s) |\n", customer);
printf("+--------------------------------------------+\n");
printf(template, customer, vnic, serial);
printf("+--------------------------------------------+\n");
printf("| ////////////////// END /////////////////// |\n");
printf("+--------------------------------------------+\n");
int res = fprintf(f, template, customer, vnic, serial);
fclose(f);
return res;
}
char *drop_separator(char **str, int offset) {
char *p = *(str)+offset; // this is where interesting part starts
int end = 0; // subtract end from buf to compute starting offset
char *buf = malloc((1+strlen(*str))*sizeof(char));
char *aa = buf;
for (; *p != '\0'; (p)++) {
if (*p != '\\') {
*buf = *p;
(buf)++ ; end++;
}
}
*buf = '\0';
strcpy(*str, buf-end);
free(aa);
return *str;
}
char *mac_address(const char *vnic) {
char *vnic_info;
asprintf(&vnic_info, show_mac_address, vnic);
FILE *fp = popen(vnic_info, "r");
char *buf = malloc(32*sizeof(char));
fgets(buf, 32, fp);
char *p = strtok(buf, ":");
p = strtok(NULL, " ");
char *mac = drop_separator(&buf, p - buf);
pclose(fp);
return mac;
}
int create_zone_func(const char *customer) {
char *create_zone;
asprintf(&create_zone, zonecfg_create_zone, customer, config_file);
return system(create_zone);
}
int create_ds_func(const char *pool, const char *serial) {
char *create_ds;
asprintf(&create_ds, zfs_create_dataset, pool, serial);
return system(create_ds);
}
int list_ds_func(const char *pool, const char *serial) {
char *list_ds;
asprintf(&list_ds, zfs_list_dataset, pool, serial);
return system(list_ds);
}
int set_zoned_func(const char *pool, const char *serial) {
char *set_zoned;
asprintf(&set_zoned, zfs_set_prop_zoned, pool, serial);
return system(set_zoned);
}
int set_mountpoint_func(const char *pool, const char *serial) {
char *set_mountpoint;
asprintf(&set_mountpoint, zfs_set_prop_mountpoint, pool, serial);
return system(set_mountpoint);
}
int create_zoned_ip_iface_func(const char *ipaddr, const char *vnic, const
char *customer) {
int res = 0;
char *zoned_ip;
char *zoned_if;
// We do this in two steps, though technically we are not required to.
// First, we make sure we can create an IP interface, and second,
// we make sure that we can create an IP address over said interface.
asprintf(&zoned_if, create_zoned_iface, customer, vnic);
res = system(zoned_if);
if (res) return res;
asprintf(&zoned_ip, create_zoned_ip_iface, customer, ipaddr, vnic);
res = system(zoned_ip);
if (res) return res;
return 0;
}
int create_zoned_vnic_func(const char *vnic) {
char *zoned_vnic;
asprintf(&zoned_vnic, create_zoned_vnic, vnic);
return system(zoned_vnic);
}
int verify_zone_ready_func(const char *customer) {
char *verify_zone;
asprintf(&verify_zone, verify_zone_ready, customer);
return system(verify_zone);
}
int install_zone_func(const char *customer) {
char *iz;
asprintf(&iz, install_zone, customer);
return system(iz);
}
int boot_zone_func(const char *customer) {
char *bz;
asprintf(&bz, boot_zone, customer);
return system(bz);
}
bool all(const char *a, const char *b, const char *c, const char *d) {
if (a[0] == '\0' || b[0] == '\0' || c[0] == '\0' || d[0] == '\0')
return false;
return true;
}
void handler(int sig) {
if (sig == SIGTERM)
exit(1);
exit(0);
}
int main(int argc, char *argv[]) {
// Setup Signal Handler
if (signal(SIGHUP, handler) == SIG_ERR)
fprintf(stderr, "signal error");
if (signal(SIGTERM, handler) == SIG_ERR)
fprintf(stderr, "signal error");
char pair[MAXPAIRLEN];
char value[32];
char *pair_p = pair;
char *key_p;
char *value_p = value;
// Populate KVPairs array with keys and create pointers
// to value fields for easier manipulation of data later on.
kvp_t pairs[5];
strcpy(pairs[0].key, "cn");
strcpy(pairs[1].key, "serial");
strcpy(pairs[2].key, "vnic");
strcpy(pairs[3].key, "ip");
strcpy(pairs[4].key, "pool");
// We want to have a default value for name of pool, making
// this parameter optional.
customer = pairs[0].value;
serial = pairs[1].value;
vnic = pairs[2].value;
ipaddr = pairs[3].value;
pool = pairs[4].value;
for (int i = 1; i < argc; i++) {
// All arguments passed to command are expected to be in a key=value
// format, where `=` is our separator character.
if (strchr(argv[i], '=') == NULL)
continue;
(void)strncpy(pair_p, argv[i], MAXPAIRLEN); // make a copy of key=value pair
key_p = strsep(&pair_p, "="); // pair_p is updated here to point to value
if (value_p == NULL) {
pair_p = key_p;
continue;
} else {
value_p = pair_p;
// Match key to fields we expect to receive, we need to make sure we
// have a customer number (cn), name of vnic (vnic), and IP Address (ip).
if (strcasecmp("cn", key_p) == 0)
strcpy(customer, value_p);
else if (strcasecmp("serial", key_p) == 0)
strncpy(serial, value_p, 9);
else if (strcasecmp("vnic", key_p) == 0)
strncpy(vnic, value_p, 9);
else if (strcasecmp("pool", key_p) == 0)
strncpy(pool, value_p, 16);
else if (strcasecmp("ip", key_p) == 0)
strncpy(ipaddr, value_p, 16);
}
} // END if
// We want to have a default value for name of pool, making
// this parameter optional.
if (pool == NULL)
strcpy(pool, default_pool);
if (!all(customer, vnic, ipaddr, serial)) {
fprintf(stderr, "error: required keys: cn, serial, vnic, ip\n");
raise(SIGTERM);
} else if (argc < 2) {
fprintf(stderr,
"error: not enough positional parameters; need zone id\n");
raise(SIGTERM);
}
// Create vnic at this point in time
if (create_zoned_vnic_func(vnic) != EXIT_SUCCESS) {
fprintf(stderr, "error: failed to create vnic for zone\n");
raise(SIGTERM);
}
// Show MAC address for newly created vnic
fprintf(stdout, "Zone %s vnic mac addr: %s\n", customer, mac_address(vnic));
// Set zoned property on dataset to which we are going to be replicating.
// # zfs set zoned=on <poolname>/global/replication/<customer_number>
// rc = system(create_zone);
// Create replication dataset, which is where customer's source system
// is going to be sending its snapshots
if (create_ds_func(pool, serial) != EXIT_SUCCESS) {
fprintf(stderr, "error: failed to create dataset\n");
raise(SIGTERM);
}
if (list_ds_func(pool, serial) != EXIT_SUCCESS) {
fprintf(stderr, "error: failed to list dataset, may not be valid\n");
raise(SIGTERM);
}
if (set_zoned_func(pool, serial) != EXIT_SUCCESS) {
fprintf(stderr, "error: failed to enable zoned property on dataset\n");
raise(SIGTERM);
}
if (set_mountpoint_func(pool, serial) != EXIT_SUCCESS) {
fprintf(stderr,
"error: failed to set mountpoint=none property on dataset\n");
raise(SIGTERM);
}
customize_template(customer, vnic, serial);
if (create_zone_func(customer) != EXIT_SUCCESS) {
fprintf(stderr, "error: failed to create zone configuration\n");
raise(SIGTERM);
}
if (install_zone_func(customer) != EXIT_SUCCESS) {
fprintf(stderr, "error: failed to install zone\n");
raise(SIGTERM);
}
if (verify_zone_ready_func(customer) != EXIT_SUCCESS) {
fprintf(stderr, "error: failed to verify zone configuration\n");
raise(SIGTERM);
}
if (boot_zone_func(customer) != EXIT_SUCCESS) {
fprintf(stderr, "error: failed to boot zone\n");
raise(SIGTERM);
}
// Block here for ZONEREADYDELAY seconds to give zone a chance to start-up
sleep(ZONEREADYDELAY);
if (create_zoned_ip_iface_func(ipaddr, vnic, customer) != EXIT_SUCCESS) {
fprintf(stderr,
"error: failed to create zoned IP interface\n");
raise(SIGTERM);
}
exit(0);
}
以上是关于c_cpp Brickstor区域设置脚本的主要内容,如果未能解决你的问题,请参考以下文章
sh [Pseduo manual-HA script]用作将资源池从一台机器移动到另一台机器的临时解决方法的工具#ha #racktop #brickstor