Hi cyril,
Sorry for late reply!
On 06/05/2014 07:49 PM, [email protected] wrote:
>
>> + pathbase = SAFE_BASENAME(cleanup_fn, pathc);
>> + if (dir != NULL) {
>> + index = sprintf(filename, "%s/", dir);
>> + } else {
>> + pathdir = dirname(dirc);
>> + index = sprintf(filename, "%s/", pathdir);
>> + }
> Hmm, wouldn't it be easier to pass the directory and filename as
> separate parameters.
>
> Or even better define how are the links this function creates named
> and pass only path to a directory to create the links to.
>
> I.e.
>
> int tst_fs_get_max_hardlinks(void (*cleanup_fn)(void), const char *path);
>
> Which would be called from test setup as:
>
> max_links = tst_fs_get_max_hardlinks(cleanup, "emlink_dir/");
>
> which would create something as:
>
> emlink_dir/test_file00001
> emlink_dir/test_file00002
> emlink_dir/test_file00003
> ...
Sound good and this will simplify the implementation, thanks.
>
>> + for (i = 1; i <= MAX_SANE_HARD_LINKS; i++) {
>> + sprintf(filename + index, "%s%s%d", pathbase,
>> + FILE_BASE_NAME_MAGIC, i);
>> +
>> + if (link(path, filename) < 0) {
>> + if (errno == EMLINK) {
>> + SAFE_STAT(cleanup_fn, path, &s);
>> + tst_resm(TINFO, "the maximum number of hard "
>> + "links to %s is hit: %d",
>> + path, (int)s.st_nlink);
>> + return s.st_nlink;
> Careful here, I would assert here that s.st_nlink == i in this case and
> do tst_brkm(TBROK, ...) if not.
Got it.
>
>> + } else {
>> + fprintf(stderr, "link(%s, %s) failed:%s\n",
>> + path, filename, strerror(errno));
>> + goto max_hardlinks_cleanup;
>
> As we pass the cleanup_fn here, we can do tst_brkm(TBROK, ...) here and
> rely on tst_rmdir() called from the cleanup to remove the files.
>
> The unlimited case (i.e. -1) should IMHO apply only when we happen to
> create maximal number of links and did not get any error.
Here I would like to keep the "remove files" work in this function. Below is my
explanation:
when link(...) fails and errno is ENOSPC or EDQUOT, this is because of the
insufficient disk
free space. I think this condition is OK and is not suitable to terminate the
program by
calling tst_brkm(...). For this condition, the function will remove the already
created files
and returns 0.
If some other errors occur, we call tst_brkm(...) to terminate the program.
If there are no errors at all(have tried 65535 times), we think it is unlimited
and returns 0.
Meanwhile we need remove the created files, because some other part of the
program may
need some disk free space.
>
>> + }
>> + }
>> +
>> + }
>> +
>> +max_hardlinks_cleanup:
>> + for (j = 1; j < i; j++) {
>> + sprintf(filename + index, "%s%s%d", pathbase,
>> + FILE_BASE_NAME_MAGIC, j);
>> + if (unlink(filename) < 0 && errno != ENOENT) {
>> + fprintf(stderr, "unlink(%s) failed: %s", filename,
>> + strerror(errno));
>> + }
>> + }
>> +
>> + return -1;
>> +}
>> +
>> +void tst_fs_get_max_hardlinks_clean(void (*cleanup_fn) (void), const char
>> *path,
>> + const char *dir, int limit)
>> +{
>> + int i, index = 0;
>> + char filename[PATH_MAX], *pathbase, *pathdir;
>> + char *pathc, *dirc;
>> +
>> + pathc = strdup(path);
>> + dirc = strdup(path);
>> +
>> + pathbase = SAFE_BASENAME(cleanup_fn, pathc);
>> + if (dir != NULL) {
>> + index = sprintf(filename, "%s/", dir);
>> + } else {
>> + pathdir = dirname(dirc);
>> + index = sprintf(filename, "%s/", pathdir);
>> + }
>> +
>> + for (i = 1; i < limit; i++) {
>> + sprintf(filename + index, "%s%s%d", pathbase,
>> + FILE_BASE_NAME_MAGIC, i);
>> + if (unlink(filename) < 0 && errno != ENOENT) {
>> + fprintf(stderr, "unlink(%s) failed: %s", filename,
>> + strerror(errno));
>> + }
>> + }
>> +}
> Is there actually use for this function?
>
> Because all files created in test temporary directory are deleted upon
> tst_rmdir().
Yeah, I know.
Tst_fs_get_max_hardlinks_clean() is written to make users able to
call tst_fs_get_max_hardlinks() repeatedly against the same @path and
@dir. So if tst_fs_get_max_hardlinks() is designed to be called only in
setup(), the tst_fs_get_max_hardlinks_clean() will be useless :-)
New version will be sent soon, thanks your reviewing and suggestions.
Regards,
Xiaoguang Wang
>
>> +int tst_fs_max_subdirs_per_dir(void (*cleanup_fn) (void), const char *dir)
>> +{
>> + int i, j;
>> + char dirname[PATH_MAX];
>> + struct stat s;
>> +
>> + for (i = 1; i <= MAX_SANE_HARD_LINKS; i++) {
>> + sprintf(dirname, "%s/%s%d", dir, DIR_BASE_NAME_MAGIC, i);
>> +
>> + if (mkdir(dirname, 0755) < 0) {
>> + if (errno == EMLINK) {
>> + SAFE_STAT(cleanup_fn, dir, &s);
>> + tst_resm(TINFO, "the maximum subdirectories in "
>> + "%s is hit: %d", dir, (int)s.st_nlink);
>> + return s.st_nlink;
>> + } else {
>> + fprintf(stderr, "mkdir(%s, 0755) failed: %s\n",
>> + dirname, strerror(errno));
>> + goto max_subdirs_cleanup;
>> + }
>> + }
>> +
>> + }
>> +
>> +max_subdirs_cleanup:
>> + for (j = 1; j < i; j++) {
>> + sprintf(dirname, "%s/%s%d", dir, DIR_BASE_NAME_MAGIC, j);
>> + if (rmdir(dirname) < 0 && errno != ENOENT) {
>> + fprintf(stderr, "rmdir(%s) failed: %s", dirname,
>> + strerror(errno));
>> + }
>> + }
>> +
>> + return -1;
>> +}
> Here as well.
>
>> +void tst_fs_max_subdirs_per_dir_clean(const char *dir, int limit)
>> +{
>> + int i;
>> + char dirname[PATH_MAX];
>> +
>> + for (i = 1; i < limit; i++) {
>> + sprintf(dirname, "%s/%s%d", dir, DIR_BASE_NAME_MAGIC, i);
>> + if (rmdir(dirname) < 0 && errno != ENOENT) {
>> + fprintf(stderr, "rmdir(%s) failed: %s", dirname,
>> + strerror(errno));
>> + }
>> + }
>> +}
> The same applies here as well, is there a use for this function?
>
------------------------------------------------------------------------------
HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://www.hpccsystems.com
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list