/** * append_unique: append @key or @key=@val pair to @buf only if @key does not * exists * @buf: buffer to hold @key or @key=@val * @prefix: prefix string before @key * @key: key string * @val: value string if it's a @key=@val pair */ static void append_unique(char *buf, char *prefix, char *key, char *val, size_t maxbuflen) { char *anchor, *end; int len; if (key == NULL) return; anchor = end = strstr(buf, key); /* try to find exact match string in @buf */ while (end && *end != '\0' && *end != ',' && *end != ' ' && *end != '=') ++end; len = end - anchor; if (anchor == NULL || strlen(key) != len || strncmp(anchor, key, len) != 0) { if (prefix != NULL) strscat(buf, prefix, maxbuflen); strscat(buf, key, maxbuflen); if (val != NULL) { strscat(buf, "=\"", maxbuflen); strscat(buf, val, maxbuflen); strscat(buf, "\"", maxbuflen); } } }
int ldiskfs_fix_mountopts(struct mkfs_opts *mop, char *mountopts, size_t len) { if (strstr(mountopts, "errors=") == NULL) strscat(mountopts, ",errors=remount-ro", len); return 0; }
/****************************************************************************** * * * Comments: Translate device name to the one used internally by kernel. The * * translation is done based on minor and major device numbers * * listed in INFO_FILE_NAME . If the names differ it is usually an * * LVM device which is listed in kernel device mapper. * * * ******************************************************************************/ static int get_kernel_devname(const char *devname, char *kernel_devname, size_t max_kernel_devname_len) { FILE *f; char tmp[MAX_STRING_LEN], name[MAX_STRING_LEN], dev_path[MAX_STRING_LEN]; int ret = FAIL; zbx_uint64_t ds[ZBX_DSTAT_MAX], rdev_major, rdev_minor; zbx_stat_t dev_st; if ('\0' == *devname) return ret; *dev_path = '\0'; if (0 != strncmp(devname, ZBX_DEV_PFX, ZBX_CONST_STRLEN(ZBX_DEV_PFX))) strscpy(dev_path, ZBX_DEV_PFX); strscat(dev_path, devname); if (zbx_stat(dev_path, &dev_st) < 0 || NULL == (f = fopen(INFO_FILE_NAME, "r"))) return ret; while (NULL != fgets(tmp, sizeof(tmp), f)) { PARSE(tmp); if (major(dev_st.st_rdev) != rdev_major || minor(dev_st.st_rdev) != rdev_minor) continue; zbx_strlcpy(kernel_devname, name, max_kernel_devname_len); ret = SUCCEED; break; } zbx_fclose(f); return ret; }
/** * Helper function to convert an unsigned 64bit integer * into a string representation with fractional digits, * an optional unit and iso-prefixes * @param out pointer to output buffer * @param out_len length of output buffer * @param number number to convert * @param unit unit that should be appended on result * @param fraction number of fractional digits * @param binary true if prefixes should use factor 1024, false if they should * use a factor of 1000 * @param raw true to suppress iso prefixes, false otherwise * @return pointer to output buffer */ static const char * _isonumber_u64_to_string(char *out, size_t out_len, uint64_t number, const char *unit, int fraction, bool binary, bool raw) { static const char symbol[] = " kMGTPE"; uint64_t step, multiplier, print, n; const char *unit_modifier; size_t idx, len; step = binary ? 1024 : 1000; multiplier = 1; unit_modifier = symbol; while (fraction-- > 0) { multiplier *= 10; } while (!raw && *unit_modifier != 0 && number >= multiplier * step) { multiplier *= step; unit_modifier++; } /* print whole */ idx = snprintf(out, out_len, "%"PRIu64, number / multiplier); len = idx; out[len++] = '.'; n = number; if (*unit_modifier != ' ') { fraction = 3; } while (true) { n = n % multiplier; if (n == 0 || fraction == 0) { break; } fraction--; multiplier /= 10; print = n / multiplier; assert (print < 10); out[len++] = (char)'0' + (char)(print); if (print) { idx = len; } } out[idx++] = ' '; out[idx++] = *unit_modifier; out[idx++] = 0; if (unit) { strscat(out, unit, out_len); } return out; }
int get_diskstat(const char *devname, zbx_uint64_t *dstat) { FILE *f; char tmp[MAX_STRING_LEN], name[MAX_STRING_LEN], dev_path[MAX_STRING_LEN]; int i, ret = FAIL, dev_exists = FAIL; zbx_uint64_t ds[ZBX_DSTAT_MAX], rdev_major, rdev_minor; zbx_stat_t dev_st; int found = 0; for (i = 0; i < ZBX_DSTAT_MAX; i++) dstat[i] = (zbx_uint64_t)__UINT64_C(0); if (NULL != devname && '\0' != *devname && 0 != strcmp(devname, "all")) { *dev_path = '\0'; if (0 != strncmp(devname, ZBX_DEV_PFX, ZBX_CONST_STRLEN(ZBX_DEV_PFX))) strscpy(dev_path, ZBX_DEV_PFX); strscat(dev_path, devname); if (zbx_stat(dev_path, &dev_st) == 0) dev_exists = SUCCEED; } if (NULL == (f = fopen(INFO_FILE_NAME, "r"))) return FAIL; while (NULL != fgets(tmp, sizeof(tmp), f)) { PARSE(tmp); if (NULL != devname && '\0' != *devname && 0 != strcmp(devname, "all")) { if (0 != strcmp(name, devname)) { if (SUCCEED != dev_exists || major(dev_st.st_rdev) != rdev_major || minor(dev_st.st_rdev) != rdev_minor) continue; } else found = 1; } dstat[ZBX_DSTAT_R_OPER] += ds[ZBX_DSTAT_R_OPER]; dstat[ZBX_DSTAT_R_SECT] += ds[ZBX_DSTAT_R_SECT]; dstat[ZBX_DSTAT_W_OPER] += ds[ZBX_DSTAT_W_OPER]; dstat[ZBX_DSTAT_W_SECT] += ds[ZBX_DSTAT_W_SECT]; ret = SUCCEED; if (1 == found) break; } zbx_fclose(f); return ret; }
int ldiskfs_prepare_lustre(struct mkfs_opts *mop, char *wanted_mountopts, size_t len) { struct lustre_disk_data *ldd = &mop->mo_ldd; int ret; /* Set MO_IS_LOOP to indicate a loopback device is needed */ ret = is_block(mop->mo_device); if (ret < 0) { return errno; } else if (ret == 0) { mop->mo_flags |= MO_IS_LOOP; } if (IS_MDT(ldd) || IS_MGS(ldd)) strscat(wanted_mountopts, ",user_xattr", len); return 0; }
/** * do initialization */ void name_constructor(void) { int i; #ifdef WIN32 int len; GetWindowsDirectory(my_hosts_file, MAX_FILE - 12); GetWindowsDirectory(my_services_file, MAX_FILE - 12); GetWindowsDirectory(my_resolv_file, MAX_FILE - 12); len = strlen(my_hosts_file); if (my_hosts_file[len - 1] != '\\') strscat(my_hosts_file, "\\", sizeof(my_host_file)); strscat(my_hosts_file, "hosts_olsr", sizeof(my_host_file)); len = strlen(my_services_file); if (my_services_file[len - 1] != '\\') strscat(my_services_file, "\\", sizeof(my_services_file)); strscat(my_services_file, "services_olsr", sizeof(my_services_file)); len = strlen(my_resolv_file); if (my_resolv_file[len - 1] != '\\') strscat(my_resolv_file, "\\", sizeof(my_resolv_file)); strscat(my_resolv_file, "resolvconf_olsr", sizeof(my_resolv_file)); #else strscpy(my_hosts_file, "/var/run/hosts_olsr", sizeof(my_hosts_file)); strscpy(my_services_file, "/var/run/services_olsr", sizeof(my_services_file)); strscpy(my_resolv_file, "/var/run/resolvconf_olsr", sizeof(my_resolv_file)); *my_sighup_pid_file = 0; #endif my_suffix[0] = '\0'; my_add_hosts[0] = '\0'; my_latlon_file[0] = '\0'; latlon_in_file[0] = '\0'; my_name_change_script[0] = '\0'; my_services_change_script[0] = '\0'; /* init the lists heads */ for(i = 0; i < HASHSIZE; i++) { list_head_init(&name_list[i]); list_head_init(&forwarder_list[i]); list_head_init(&service_list[i]); list_head_init(&latlon_list[i]); } }
/* Build fs according to type */ int ldiskfs_make_lustre(struct mkfs_opts *mop) { char mkfs_cmd[PATH_MAX]; char buf[64]; char *start; char *dev; int ret = 0, ext_opts = 0; bool enable_64bit = false; long inode_size = 0; size_t maxbuflen; mop->mo_blocksize_kb = 4; start = strstr(mop->mo_mkfsopts, "-b"); if (start) { char *end = NULL; long blocksize; blocksize = strtol(start + 2, &end, 0); if (end && (*end == 'k' || *end == 'K')) blocksize *= 1024; /* EXT4_MIN_BLOCK_SIZE || EXT4_MAX_BLOCK_SIZE */ if (blocksize < 1024 || blocksize > 65536) { fprintf(stderr, "%s: blocksize %lu not in 1024-65536 bytes, normally 4096 bytes\n", progname, blocksize); return EINVAL; } if ((blocksize & (blocksize - 1)) != 0) { fprintf(stderr, "%s: blocksize %lu not a power-of-two value\n", progname, blocksize); return EINVAL; } mop->mo_blocksize_kb = blocksize >> 10; } if (!(mop->mo_flags & MO_IS_LOOP)) { __u64 device_kb = get_device_size(mop->mo_device); if (device_kb == 0) return ENODEV; /* Compare to real size */ if (mop->mo_device_kb == 0 || device_kb < mop->mo_device_kb) mop->mo_device_kb = device_kb; } if (mop->mo_device_kb != 0) { __u64 block_count; if (mop->mo_device_kb < 32384) { fprintf(stderr, "%s: size of filesystem must be larger " "than 32MB, but is set to %lldKB\n", progname, (long long)mop->mo_device_kb); return EINVAL; } block_count = mop->mo_device_kb / mop->mo_blocksize_kb; if (block_count > 0xffffffffULL) { /* If the LUN size is just over 2^32 blocks, limit the * filesystem size to 2^32-1 blocks to avoid problems * with ldiskfs/mkfs not handling this well. b=22906 */ if (block_count < 0x100002000ULL) mop->mo_device_kb = 0xffffffffULL * mop->mo_blocksize_kb; else enable_64bit = true; } } if ((mop->mo_ldd.ldd_mount_type != LDD_MT_EXT3) && (mop->mo_ldd.ldd_mount_type != LDD_MT_LDISKFS) && (mop->mo_ldd.ldd_mount_type != LDD_MT_LDISKFS2)) { fprintf(stderr, "%s: unsupported fs type: %d (%s)\n", progname, mop->mo_ldd.ldd_mount_type, MT_STR(&mop->mo_ldd)); return EINVAL; } /* Journal size in MB */ if (strstr(mop->mo_mkfsopts, "-J") == NULL && mop->mo_device_kb > 1024 * 1024) { /* Choose our own default journal size */ long journal_mb = 0, max_mb; /* cap journal size at 4GB for MDT, leave at 1GB for OSTs */ if (IS_MDT(&mop->mo_ldd)) max_mb = 4096; else if (IS_OST(&mop->mo_ldd)) max_mb = 1024; else /* Use mke2fs default size for MGS */ max_mb = 0; /* Use at most 4% of device for journal */ journal_mb = mop->mo_device_kb * 4 / (1024 * 100); if (journal_mb > max_mb) journal_mb = max_mb; if (journal_mb) { snprintf(buf, sizeof(buf), " -J size=%ld", journal_mb); strscat(mop->mo_mkfsopts, buf, sizeof(mop->mo_mkfsopts)); } } /* * The inode size is constituted by following elements * (assuming all files are in composite layout and has * 3 components): * * ldiskfs inode size: 160 * MDT extended attributes size, including: * ext4_xattr_header: 32 * LOV EA size: 32(lov_comp_md_v1) + * 3 * 40(lov_comp_md_entry_v1) + * 3 * 32(lov_mds_md) + * stripes * 24(lov_ost_data) + * 16(xattr_entry) + 4("lov") * LMA EA size: 24(lustre_mdt_attrs) + * 16(xattr_entry) + 4("lma") * SOM EA size: 24(lustre_som_attrs) + * 16(xattr_entry) + 4("som") * link EA size: 24(link_ea_header) + 18(link_ea_entry) + * 16(filename) + 16(xattr_entry) + 4("link") * and some margin for 4-byte alignment, ACLs and other EAs. * * If we say the average filename length is about 32 bytes, * the calculation looks like: * 160 + 32 + (32+3*(40+32)+24*stripes+20) + (24+20) + (24+20) + * (24+20) + (~42+16+20) + other <= 512*2^m, {m=0,1,2,3} */ if (strstr(mop->mo_mkfsopts, "-I") == NULL) { if (IS_MDT(&mop->mo_ldd)) { if (mop->mo_stripe_count > 59) inode_size = 512; /* bz 7241 */ /* see also "-i" below for EA blocks */ else if (mop->mo_stripe_count > 16) inode_size = 2048; else inode_size = 1024; } else if (IS_OST(&mop->mo_ldd)) { /* We store MDS FID and necessary composite * layout information in the OST object EA: * ldiskfs inode size: 160 * OST extended attributes size, including: * ext4_xattr_header: 32 * LMA EA size: 24(lustre_mdt_attrs) + * 16(xattr_entry) + 4("lma") * FID EA size: 52(filter_fid) + * 16(xattr_entry) + 4("fid") * 160 + 32 + (24+20) + (52+20) = 308 */ inode_size = 512; } if (inode_size > 0) { snprintf(buf, sizeof(buf), " -I %ld", inode_size); strscat(mop->mo_mkfsopts, buf, sizeof(mop->mo_mkfsopts)); } } /* Bytes_per_inode: disk size / num inodes */ if (strstr(mop->mo_mkfsopts, "-i") == NULL && strstr(mop->mo_mkfsopts, "-N") == NULL) { long bytes_per_inode = 0; /* Allocate more inodes on MDT devices. There is * no data stored on the MDT, and very little extra * metadata beyond the inode. It could go down as * low as 1024 bytes, but this is conservative. * Account for external EA blocks for wide striping. */ if (IS_MDT(&mop->mo_ldd)) { bytes_per_inode = inode_size + 1536; if (mop->mo_stripe_count > 59) { int extra = mop->mo_stripe_count * 24; extra = ((extra - 1) | 4095) + 1; bytes_per_inode += extra; } } /* Allocate fewer inodes on large OST devices. Most * filesystems can be much more aggressive than even * this, but it is impossible to know in advance. */ if (IS_OST(&mop->mo_ldd)) { /* OST > 16TB assume average file size 1MB */ if (mop->mo_device_kb > (16ULL << 30)) bytes_per_inode = 1024 * 1024; /* OST > 4TB assume average file size 512kB */ else if (mop->mo_device_kb > (4ULL << 30)) bytes_per_inode = 512 * 1024; /* OST > 1TB assume average file size 256kB */ else if (mop->mo_device_kb > (1ULL << 30)) bytes_per_inode = 256 * 1024; /* OST > 10GB assume average file size 64kB, * plus a bit so that inodes will fit into a * 256x flex_bg without overflowing. */ else if (mop->mo_device_kb > (10ULL << 20)) bytes_per_inode = 69905; } if (bytes_per_inode > 0) { snprintf(buf, sizeof(buf), " -i %ld", bytes_per_inode); strscat(mop->mo_mkfsopts, buf, sizeof(mop->mo_mkfsopts)); mop->mo_inode_size = bytes_per_inode; } } if (verbose < 2) strscat(mop->mo_mkfsopts, " -q", sizeof(mop->mo_mkfsopts)); /* start handle -O mkfs options */ start = strstr(mop->mo_mkfsopts, "-O"); if (start) { if (strstr(start + 2, "-O") != NULL) { fprintf(stderr, "%s: don't specify multiple -O options\n", progname); return EINVAL; } start = moveopts_to_end(start); maxbuflen = sizeof(mop->mo_mkfsopts) - (start - mop->mo_mkfsopts) - strlen(start); ret = enable_default_ext4_features(mop, start, maxbuflen, 1); } else { start = mop->mo_mkfsopts + strlen(mop->mo_mkfsopts); maxbuflen = sizeof(mop->mo_mkfsopts) - strlen(mop->mo_mkfsopts); ret = enable_default_ext4_features(mop, start, maxbuflen, 0); } if (ret) return ret; /* end handle -O mkfs options */ /* start handle -E mkfs options */ start = strstr(mop->mo_mkfsopts, "-E"); if (start) { if (strstr(start + 2, "-E") != NULL) { fprintf(stderr, "%s: don't specify multiple -E options\n", progname); return EINVAL; } start = moveopts_to_end(start); maxbuflen = sizeof(mop->mo_mkfsopts) - (start - mop->mo_mkfsopts) - strlen(start); ext_opts = 1; } else { start = mop->mo_mkfsopts + strlen(mop->mo_mkfsopts); maxbuflen = sizeof(mop->mo_mkfsopts) - strlen(mop->mo_mkfsopts); } /* In order to align the filesystem metadata on 1MB boundaries, * give a resize value that will reserve a power-of-two group * descriptor blocks, but leave one block for the superblock. * Only useful for filesystems with < 2^32 blocks due to resize * limitations. */ if (!enable_64bit && strstr(mop->mo_mkfsopts, "meta_bg") == NULL && IS_OST(&mop->mo_ldd) && mop->mo_device_kb > 100 * 1024) { unsigned int group_blocks = mop->mo_blocksize_kb * 8192; unsigned int desc_per_block = mop->mo_blocksize_kb * 1024 / 32; unsigned int resize_blks; resize_blks = (1ULL<<32) - desc_per_block*group_blocks; snprintf(buf, sizeof(buf), "%u", resize_blks); append_unique(start, ext_opts ? "," : " -E ", "resize", buf, maxbuflen); ext_opts = 1; } /* Avoid zeroing out the full journal - speeds up mkfs */ if (is_e2fsprogs_feature_supp("-E lazy_journal_init")) append_unique(start, ext_opts ? "," : " -E ", "lazy_journal_init", NULL, maxbuflen); /* end handle -E mkfs options */ /* Allow reformat of full devices (as opposed to partitions). * We already checked for mounted dev. */ strscat(mop->mo_mkfsopts, " -F", sizeof(mop->mo_mkfsopts)); snprintf(mkfs_cmd, sizeof(mkfs_cmd), "%s -j -b %d -L %s ", MKE2FS, mop->mo_blocksize_kb * 1024, mop->mo_ldd.ldd_svname); /* For loop device format the dev, not the filename */ dev = mop->mo_device; if (mop->mo_flags & MO_IS_LOOP) dev = mop->mo_loopdev; vprint("formatting backing filesystem %s on %s\n", MT_STR(&mop->mo_ldd), dev); vprint("\ttarget name %s\n", mop->mo_ldd.ldd_svname); vprint("\tkilobytes %llu\n", mop->mo_device_kb); vprint("\toptions %s\n", mop->mo_mkfsopts); /* mkfs_cmd's trailing space is important! */ strscat(mkfs_cmd, mop->mo_mkfsopts, sizeof(mkfs_cmd)); strscat(mkfs_cmd, " ", sizeof(mkfs_cmd)); strscat(mkfs_cmd, dev, sizeof(mkfs_cmd)); if (mop->mo_device_kb != 0) { snprintf(buf, sizeof(buf), " %lluk", (unsigned long long)mop->mo_device_kb); strscat(mkfs_cmd, buf, sizeof(mkfs_cmd)); } vprint("mkfs_cmd = %s\n", mkfs_cmd); ret = run_command(mkfs_cmd, sizeof(mkfs_cmd)); if (ret) { fatal(); fprintf(stderr, "Unable to build fs %s (%d)\n", dev, ret); } return ret; }
static int enable_default_ext4_features(struct mkfs_opts *mop, char *anchor, size_t maxbuflen, bool user_spec) { unsigned long long blocks = mop->mo_device_kb / mop->mo_blocksize_kb; bool enable_64bit = false; /* Enable large block addresses if the LUN is over 2^32 blocks. */ if (blocks > 0xffffffffULL && is_e2fsprogs_feature_supp("-O 64bit")) enable_64bit = true; if (IS_OST(&mop->mo_ldd)) { append_unique(anchor, user_spec ? "," : " -O ", "extents", NULL, maxbuflen); append_unique(anchor, ",", "uninit_bg", NULL, maxbuflen); } else if (IS_MDT(&mop->mo_ldd)) { append_unique(anchor, user_spec ? "," : " -O ", "dirdata", NULL, maxbuflen); append_unique(anchor, ",", "uninit_bg", NULL, maxbuflen); if (enable_64bit) append_unique(anchor, ",", "extents", NULL, maxbuflen); else append_unique(anchor, ",", "^extents", NULL, maxbuflen); } else { append_unique(anchor, user_spec ? "," : " -O ", "uninit_bg", NULL, maxbuflen); } /* Multiple mount protection enabled only if failover node specified */ if (mop->mo_flags & MO_FAILOVER) { if (is_e2fsprogs_feature_supp("-O mmp")) append_unique(anchor, ",", "mmp", NULL, maxbuflen); else disp_old_e2fsprogs_msg("mmp", 1); } /* Allow more than 65000 subdirectories */ if (is_e2fsprogs_feature_supp("-O dir_nlink")) append_unique(anchor, ",", "dir_nlink", NULL, maxbuflen); /* The following options are only valid for ext4-based ldiskfs. * If --backfstype=ext3 is specified, do not enable them. */ if (mop->mo_ldd.ldd_mount_type == LDD_MT_EXT3) return 0; /* Enable quota by default */ if (is_e2fsprogs_feature_supp("-O quota")) { append_unique(anchor, ",", "quota", NULL, maxbuflen); } else { fatal(); fprintf(stderr, "\"-O quota\" must be supported by " "e2fsprogs, please upgrade your e2fsprogs.\n"); return EINVAL; } /* Allow files larger than 2TB. Also needs LU-16, but not harmful. */ if (is_e2fsprogs_feature_supp("-O huge_file")) append_unique(anchor, ",", "huge_file", NULL, maxbuflen); if (enable_64bit) append_unique(anchor, ",", "64bit", NULL, maxbuflen); if (blocks >= 0x1000000000 && is_e2fsprogs_feature_supp("-O meta_bg")) append_unique(anchor, ",", "meta_bg", NULL, maxbuflen); if (enable_64bit || strstr(mop->mo_mkfsopts, "meta_bg")) append_unique(anchor, ",", "^resize_inode", NULL, maxbuflen); /* Cluster inode/block bitmaps and inode table for more efficient IO. * Align the flex groups on a 1MB boundary for better performance. */ /* This -O feature needs to go last, since it adds the "-G" option. */ if (is_e2fsprogs_feature_supp("-O flex_bg")) { char tmp_buf[64]; append_unique(anchor, ",", "flex_bg", NULL, maxbuflen); if (IS_OST(&mop->mo_ldd) && strstr(mop->mo_mkfsopts, "-G") == NULL) { snprintf(tmp_buf, sizeof(tmp_buf), " -G %u", 1024 / mop->mo_blocksize_kb); strscat(anchor, tmp_buf, maxbuflen); } } /* Don't add any more "-O" options here, see last comment above */ return 0; }
int zfs_make_lustre(struct mkfs_opts *mop) { zfs_handle_t *zhp; zpool_handle_t *php; char *pool = NULL; char *mkfs_cmd = NULL; char *mkfs_tmp = NULL; char *ds = mop->mo_device; int pool_exists = 0, ret; if (osd_check_zfs_setup() == 0) return EINVAL; /* no automatic index with zfs backend */ if (mop->mo_ldd.ldd_flags & LDD_F_NEED_INDEX) { fatal(); fprintf(stderr, "The target index must be specified with " "--index\n"); return EINVAL; } pool = strdup(ds); if (pool == NULL) return ENOMEM; mkfs_cmd = malloc(PATH_MAX); if (mkfs_cmd == NULL) { ret = ENOMEM; goto out; } mkfs_tmp = malloc(PATH_MAX); if (mkfs_tmp == NULL) { ret = ENOMEM; goto out; } /* Due to zfs_prepare_lustre() check the '/' must exist */ strchr(pool, '/')[0] = '\0'; /* If --reformat was given attempt to destroy the previous dataset */ if ((mop->mo_flags & MO_FORCEFORMAT) && ((zhp = zfs_open(g_zfs, ds, ZFS_TYPE_FILESYSTEM)) != NULL)) { ret = zfs_destroy(zhp, 0); if (ret) { zfs_close(zhp); fprintf(stderr, "Failed destroy zfs dataset %s (%d)\n", ds, ret); goto out; } zfs_close(zhp); } /* * Create the zpool if the vdevs have been specified and the pool * does not already exists. The pool creation itself will be done * with the zpool command rather than the zpool_create() library call * so the existing zpool error handling can be leveraged. */ php = zpool_open(g_zfs, pool); if (php) { pool_exists = 1; zpool_close(php); } if ((mop->mo_pool_vdevs != NULL) && (pool_exists == 0)) { memset(mkfs_cmd, 0, PATH_MAX); snprintf(mkfs_cmd, PATH_MAX, "zpool create -f -O canmount=off %s", pool); /* Append the vdev config and create file vdevs as required */ while (*mop->mo_pool_vdevs != NULL) { strscat(mkfs_cmd, " ", PATH_MAX); strscat(mkfs_cmd, *mop->mo_pool_vdevs, PATH_MAX); ret = zfs_create_vdev(mop, *mop->mo_pool_vdevs); if (ret) goto out; mop->mo_pool_vdevs++; } vprint("mkfs_cmd = %s\n", mkfs_cmd); ret = run_command(mkfs_cmd, PATH_MAX); if (ret) { fatal(); fprintf(stderr, "Unable to create pool %s (%d)\n", pool, ret); goto out; } } /* * Create the ZFS filesystem with any required mkfs options: * - canmount=off is set to prevent zfs automounting * - version=4 is set because SA are not yet handled by the osd */ memset(mkfs_cmd, 0, PATH_MAX); snprintf(mkfs_cmd, PATH_MAX, "zfs create -o canmount=off -o xattr=sa%s %s", zfs_mkfs_opts(mop, mkfs_tmp, PATH_MAX), ds); vprint("mkfs_cmd = %s\n", mkfs_cmd); ret = run_command(mkfs_cmd, PATH_MAX); if (ret) { fatal(); fprintf(stderr, "Unable to create filesystem %s (%d)\n", ds, ret); goto out; } out: if (pool != NULL) free(pool); if (mkfs_cmd != NULL) free(mkfs_cmd); if (mkfs_tmp != NULL) free(mkfs_tmp); return ret; }
char *strscpy(char *dst, char *src, int buflen) { dst[0] = 0; return strscat(dst, src, buflen); }
/** * last initialization * * we have to do this here because some things like main_addr * or the dns suffix (for validation) are not known before * * this is beause of the order in which the plugin is initialized * by the plugin loader: * - first the parameters are sent * - then register_olsr_data() from olsrd_plugin.c is called * which sets up main_addr and some other variables * - register_olsr_data() then then finally calls this function */ int name_init(void) { struct name_entry *name; union olsr_ip_addr ipz; int ret; //regex string for validating the hostnames const char *regex_name = "^[[:alnum:]_.-]+$"; //regex string for the service line size_t regex_size = 256 * sizeof(char) + strlen(my_suffix); char *regex_service = olsr_malloc(regex_size, "new *char from name_init for regex_service"); memset(&ipz, 0, sizeof(ipz)); //compile the regex from the string if ((ret = regcomp(®ex_t_name, regex_name , REG_EXTENDED)) != 0) { /* #2: call regerror() if regcomp failed * commented out, because only for debuggin needed * int errmsgsz = regerror(ret, ®ex_t_name, NULL, 0); char *errmsg = malloc(errmsgsz); regerror(ret, ®ex_t_name, errmsg, errmsgsz); fprintf(stderr, "regcomp: %s", errmsg); free(errmsg); regfree(®ex_t_name); * */ OLSR_PRINTF(0, "compilation of regex \"%s\" for hostname failed", regex_name); } // a service line is something like prot://hostname.suffix:port|tcp|my little description about this service // for example http://router.olsr:80|tcp|my homepage // prot :// (hostname.suffix OR ip) //regex_service = "^[[:alnum:]]+://(([[:alnum:]_.-]+.olsr)|([[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3})) // : port /path |(tcp OR udp) |short description // :[[:digit:]]+[[:alnum:]/?._=#-]*\\|(tcp|udp)\\|[^|[:cntrl:]]+$"; strscpy(regex_service, "^[[:alnum:]]+://(([[:alnum:]_.-]+", regex_size); strscat(regex_service, my_suffix, regex_size); strscat(regex_service, ")|([[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3})):[[:digit:]]+[[:alnum:]/?._=#-]*\\|(tcp|udp)\\|[^|[:cntrl:]]+$", regex_size); /* #1: call regcomp() to compile the regex */ if ((ret = regcomp(®ex_t_service, regex_service , REG_EXTENDED )) != 0) { /* #2: call regerror() if regcomp failed * commented out, because only for debuggin needed * int errmsgsz = regerror(ret, ®ex_t_service, NULL, 0); char *errmsg = malloc(errmsgsz); regerror(ret, ®ex_t_service, errmsg, errmsgsz); fprintf(stderr, "regcomp: %s", errmsg); free(errmsg); regfree(®ex_t_service); * */ OLSR_PRINTF(0, "compilation of regex \"%s\" for hostname failed", regex_name); } free(regex_service); regex_service = NULL; //fill in main addr for all entries with ip==0 //this does not matter for service, because the ip does not matter //for service for (name = my_names; name != NULL; name = name->next) { if (ipequal(&name->ip, &ipz)) { OLSR_PRINTF(2, "NAME PLUGIN: insert main addr for name %s \n", name->name); name->ip = olsr_cnf->main_addr; } } for (name = my_forwarders; name != NULL; name = name->next) { if (name->ip.v4.s_addr == 0) { OLSR_PRINTF(2, "NAME PLUGIN: insert main addr for name %s \n", name->name); name->ip = olsr_cnf->main_addr; } } //check if entries I want to announce myself are valid and allowed my_names = remove_nonvalid_names_from_list(my_names, NAME_HOST); my_forwarders = remove_nonvalid_names_from_list(my_forwarders, NAME_FORWARDER); my_services = remove_nonvalid_names_from_list(my_services, NAME_SERVICE); /* register functions with olsrd */ olsr_parser_add_function(&olsr_parser, PARSER_TYPE, 1); /* periodic message generation */ msg_gen_timer = olsr_start_timer(my_interval * MSEC_PER_SEC, EMISSION_JITTER, OLSR_TIMER_PERIODIC, &olsr_namesvc_gen, NULL, 0); mapwrite_init(my_latlon_file); return 1; }